diff --git a/Minecraft.Client/Minecraft.cpp b/Minecraft.Client/Minecraft.cpp index a42a51feb..499766dfd 100644 --- a/Minecraft.Client/Minecraft.cpp +++ b/Minecraft.Client/Minecraft.cpp @@ -65,6 +65,7 @@ #include "../Minecraft.World/Entities/Mobs/Villager.h" #include "../Minecraft.World/Level/Storage/SparseLightStorage.h" #include "../Minecraft.World/Level/Storage/SparseDataStorage.h" +#include "../Minecraft.World/Blocks/TileEntities/ChestTileEntity.h" #include "Textures/TextureManager.h" #ifdef _XBOX #include "Platform/Xbox/Network/NetworkPlayerXbox.h" @@ -77,6 +78,7 @@ #include "Platform/Orbis/Network/PsPlusUpsellWrapper_Orbis.h" #endif +// #define DISABLE_SPU_CODE // 4J Turning this on will change the graph at the bottom of the debug overlay // to show the number of packets of each type added per fram // #define DEBUG_RENDER_SHOWS_PACKETS 1 @@ -88,10 +90,10 @@ #define DISABLE_LEVELTICK_THREAD Minecraft* Minecraft::m_instance = NULL; -__int64 Minecraft::frameTimes[512]; -__int64 Minecraft::tickTimes[512]; +int64_t Minecraft::frameTimes[512]; +int64_t Minecraft::tickTimes[512]; int Minecraft::frameTimePos = 0; -__int64 Minecraft::warezTime = 0; +int64_t Minecraft::warezTime = 0; File Minecraft::workDir = File(L""); #ifdef __PSVITA__ @@ -103,8 +105,17 @@ TOUCHSCREENRECT QuickSelectRect[3] = { }; int QuickSelectBoxWidth[3] = {89, 111, 142}; + +// 4J - TomK ToDo: these really shouldn't be magic numbers, it should read the +// hud position from flash. +int iToolTipOffset = 85; + #endif +ResourceLocation Minecraft::DEFAULT_FONT_LOCATION = + ResourceLocation(TN_DEFAULT_FONT); +ResourceLocation Minecraft::ALT_FONT_LOCATION = ResourceLocation(TN_ALT_FONT); + Minecraft::Minecraft(Component* mouseComponent, Canvas* parent, MinecraftApplet* minecraftApplet, int width, int height, bool fullscreen) { @@ -321,10 +332,11 @@ void Minecraft::init() { textures = new Textures(skins, options); // renderLoadingScreen(); - font = new Font(options, L"font/Default.png", textures, false, - TN_DEFAULT_FONT, 23, 20, 8, 8, SFontData::Codepoints); + font = + new Font(options, L"font/Default.png", textures, false, + &DEFAULT_FONT_LOCATION, 23, 20, 8, 8, SFontData::Codepoints); altFont = new Font(options, L"font/alternate.png", textures, false, - TN_ALT_FONT, 16, 16, 8, 8); + &ALT_FONT_LOCATION, 16, 16, 8, 8); // if (options.languageCode != null) { // Language.getInstance().loadLanguage(options.languageCode); @@ -394,6 +406,10 @@ void Minecraft::init() { // openGLCapabilities = new OpenGLCapabilities(); // 4J - removed levelRenderer = new LevelRenderer(this, textures); + // textures->register(&TextureAtlas::LOCATION_BLOCKS, new + // TextureAtlas(Icon::TYPE_TERRAIN, TN_TERRAIN)); + // textures->register(&TextureAtlas::LOCATION_ITEMS, new + // TextureAtlas(Icon::TYPE_ITEM, TN_GUI_ITEMS)); textures->stitch(); glViewport(0, 0, width, height); @@ -713,7 +729,7 @@ void Minecraft::run() return; } - __int64 lastTime = System::currentTimeMillis(); + int64_t lastTime = System::currentTimeMillis(); int frames = 0; while (running) @@ -738,7 +754,7 @@ void Minecraft::run() timer->advanceTime(); } - __int64 beforeTickTime = System::nanoTime(); + int64_t beforeTickTime = System::nanoTime(); for (int i = 0; i < timer->ticks; i++) { ticks++; @@ -750,7 +766,7 @@ void Minecraft::run() // setScreen(new LevelConflictScreen()); // } } - __int64 tickDuraction = System::nanoTime() - beforeTickTime; + int64_t tickDuraction = System::nanoTime() - beforeTickTime; checkGlError(L"Pre render"); TileRenderer::fancy = options->fancyGraphics; @@ -1203,7 +1219,7 @@ void Minecraft::removeLocalPlayerIdx(int idx) { #endif // 4J Stu - Adding this back in for exactly the reason my comment above // suggests it was added in the first place -#ifdef _XBOX_ONE +#if defined(_XBOX_ONE) || defined(__ORBIS__) g_NetworkManager.RemoveLocalPlayerByUserIndex(idx); #endif } @@ -1247,7 +1263,7 @@ void Minecraft::createPrimaryLocalPlayer(int iPad) { } void Minecraft::run_middle() { - static __int64 lastTime = 0; + static int64_t lastTime = 0; static bool bFirstTimeIntoGame = true; static bool bAutosaveTimerSet = false; static unsigned int uiAutosaveTimer = 0; @@ -1783,41 +1799,38 @@ void Minecraft::run_middle() { // because of age restriction if (npAvailability == SCE_NP_ERROR_AGE_RESTRICTION) { - unsigned int uiIDA[1]; + UINT uiIDA[1]; uiIDA[0] = IDS_OK; - ui.RequestMessageBox( + ui.RequestErrorMessage( IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, - uiIDA, 1, i, NULL, NULL, - app.GetStringTable()); + uiIDA, 1, i); } else if (ProfileManager .IsSignedIn(i) && !ProfileManager .IsSignedInLive( i)) { // You're not signed in to PSN! - unsigned int uiIDA[2]; + UINT uiIDA[2]; uiIDA[0] = IDS_PRO_NOTONLINE_ACCEPT; uiIDA[1] = IDS_CANCEL; - ui.RequestMessageBox( + ui.RequestAlertMessage( IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, i, &Minecraft:: MustSignInReturnedPSN, - this, app.GetStringTable(), - NULL, 0, false); + this); } else #endif { - unsigned int uiIDA[1]; + UINT uiIDA[1]; uiIDA[0] = IDS_CONFIRM_OK; - ui.RequestMessageBox( + ui.RequestErrorMessage( IDS_NO_MULTIPLAYER_PRIVILEGE_TITLE, IDS_NO_MULTIPLAYER_PRIVILEGE_JOIN_TEXT, - uiIDA, 1, i, NULL, NULL, - app.GetStringTable()); + uiIDA, 1, i); } } // else @@ -1871,10 +1884,11 @@ void Minecraft::run_middle() { for (unsigned int iPad = XUSER_MAX_COUNT; iPad < (XUSER_MAX_COUNT + InputManager.MAX_GAMEPADS); ++iPad) { - if (InputManager.IsPadLocked(iPad) || - !InputManager.IsPadConnected(iPad)) + bool isPadLocked = InputManager.IsPadLocked(iPad), + isPadConnected = InputManager.IsPadConnected(iPad), + buttonPressed = InputManager.ButtonPressed(iPad); + if (isPadLocked || !isPadConnected || !buttonPressed) continue; - if (!InputManager.ButtonPressed(iPad)) continue; if (!ui.PressStartPlaying(firstEmptyUser)) { ui.ShowPressStart(firstEmptyUser); @@ -1907,7 +1921,7 @@ void Minecraft::run_middle() { timer->advanceTime(); } - //__int64 beforeTickTime = System::nanoTime(); + //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 @@ -1996,7 +2010,7 @@ void Minecraft::run_middle() { // SparseDataStorage::tick(); // // 4J added } - //__int64 tickDuraction = System::nanoTime() - beforeTickTime; + //int64_t tickDuraction = System::nanoTime() - beforeTickTime; MemSect(31); checkGlError(L"Pre render"); MemSect(0); @@ -2115,17 +2129,13 @@ void Minecraft::run_middle() { } */ - /* 4J - removed - if (!Display::isActive()) - { - if (fullscreen) - { - this->toggleFullScreen(); - } - Sleep(10); - } - */ +#if PACKET_ENABLE_STAT_TRACKING + Packet::updatePacketStatsPIX(); +#endif + if (options->renderDebug) { + // renderFpsMeter(tickDuraction); + #if DEBUG_RENDER_SHOWS_PACKETS // To show data for only one packet type // Packet::renderPacketStats(31); @@ -2165,10 +2175,10 @@ void Minecraft::run_middle() { if (width <= 0) width = 1; if (height <= 0) height = 1; - resize(width, height); - } - } - */ + resize(width, height); + } + } + */ MemSect(31); checkGlError(L"Post render"); MemSect(0); @@ -2230,12 +2240,12 @@ void Minecraft::emergencySave() { setLevel(NULL); } -void Minecraft::renderFpsMeter(__int64 tickTime) { +void Minecraft::renderFpsMeter(int64_t tickTime) { int nsPer60Fps = 1000000000l / 60; if (lastTimer == -1) { lastTimer = System::nanoTime(); } - __int64 now = System::nanoTime(); + int64_t now = System::nanoTime(); Minecraft::tickTimes[(Minecraft::frameTimePos) & (Minecraft::frameTimes_length - 1)] = tickTime; Minecraft::frameTimes[(Minecraft::frameTimePos++) & @@ -2273,7 +2283,7 @@ void Minecraft::renderFpsMeter(__int64 tickTime) { (float)(0)); t->end(); - __int64 totalTime = 0; + int64_t totalTime = 0; for (int i = 0; i < Minecraft::frameTimes_length; i++) { totalTime += Minecraft::frameTimes[i]; } @@ -2302,8 +2312,8 @@ void Minecraft::renderFpsMeter(__int64 tickTime) { t->color(0xff000000 + cc * 256); } - __int64 time = Minecraft::frameTimes[i] / 200000; - __int64 time2 = Minecraft::tickTimes[i] / 200000; + int64_t time = Minecraft::frameTimes[i] / 200000; + int64_t time2 = Minecraft::tickTimes[i] / 200000; t->vertex((float)(i + 0.5f), (float)(height - time + 0.5f), (float)(0)); t->vertex((float)(i + 0.5f), (float)(height + 0.5f), (float)(0)); @@ -2415,8 +2425,7 @@ void Minecraft::levelTickThreadInitFunc() { // textures are to be updated - this will be true for the last time this tick // runs with bFirst true void Minecraft::tick(bool bFirst, bool bUpdateTextures) { - int iPad = -1; - if (player) iPad = player->GetXboxPad(); + int iPad = player->GetXboxPad(); // OutputDebugString("Minecraft::tick\n"); // 4J-PB - only tick this player's stats @@ -2482,27 +2491,24 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { setScreen(NULL); } - // if (screen != NULL) { - // player->missTime = 10000; - // player->lastClickTick[0] = ticks + 10000; - // player->lastClickTick[1] = ticks + 10000; - // } + if (screen != NULL) { + player->missTime = 10000; + player->lastClickTick[0] = ticks + 10000; + player->lastClickTick[1] = ticks + 10000; + } if (screen != NULL) { - InputManager.SetMenuDisplayed(player->GetXboxPad(), true); screen->updateEvents(); if (screen != NULL) { screen->particles->tick(); screen->tick(); } - } else { - InputManager.SetMenuDisplayed(player->GetXboxPad(), false); } if (screen == NULL && !ui.GetMenuDisplayed(iPad)) { // 4J-PB - add some tooltips if required int iA = -1, iB = -1, iX, iY = IDS_CONTROLS_INVENTORY, iLT = -1, - iRT = -1, iLB = -1, iRB = -1; + iRT = -1, iLB = -1, iRB = -1, iLS = -1, iRS = -1; if (player->abilities.instabuild) { iX = IDS_TOOLTIPS_CREATIVE; @@ -2514,6 +2520,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { int* piAction; int* piJump; int* piUse; + int* piAlt; unsigned int uiAction = InputManager.GetGameJoypadMaps( InputManager.GetJoypadMapVal(iPad), MINECRAFT_ACTION_ACTION); @@ -2521,6 +2528,8 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { InputManager.GetJoypadMapVal(iPad), MINECRAFT_ACTION_JUMP); unsigned int uiUse = InputManager.GetGameJoypadMaps( InputManager.GetJoypadMapVal(iPad), MINECRAFT_ACTION_USE); + unsigned int uiAlt = InputManager.GetGameJoypadMaps( + InputManager.GetJoypadMapVal(iPad), MINECRAFT_ACTION_SNEAK_TOGGLE); // Also need to handle PS3 having swapped triggers/bumpers switch (uiAction) { @@ -2577,6 +2586,15 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { break; } + switch (uiAlt) { + default: + case _360_JOY_BUTTON_LSTICK_RIGHT: + piAlt = &iRS; + break; + + // TODO + } + if (player->isUnderLiquid(Material::water)) { *piJump = IDS_TOOLTIPS_SWIMUP; } else { @@ -2585,11 +2603,23 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { *piUse = -1; *piAction = -1; + *piAlt = -1; // 4J-PB another special case for when the player is sleeping in a bed if (player->isSleeping() && (level != NULL) && level->isClientSide) { *piUse = IDS_TOOLTIPS_WAKEUP; } else { + if (player->isRiding()) { + std::shared_ptr mount = player->riding; + + if (mount->instanceof(eTYPE_MINECART) || + mount->instanceof(eTYPE_BOAT)) { + *piAlt = IDS_TOOLTIPS_EXIT; + } else { + *piAlt = IDS_TOOLTIPS_DISMOUNT; + } + } + // no hit result, but we may have something in our hand that we can // do something with std::shared_ptr itemInstance = @@ -2637,11 +2667,12 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { } break; - case Item::milk_Id: + case Item::bucket_milk_Id: *piUse = IDS_TOOLTIPS_DRINK; break; case Item::fishingRod_Id: // use + case Item::emptyMap_Id: *piUse = IDS_TOOLTIPS_USE; break; @@ -2673,6 +2704,11 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { if (bUseItem) *piUse = IDS_TOOLTIPS_COLLECT; break; + case Item::bucket_lava_Id: + case Item::bucket_water_Id: + *piUse = IDS_TOOLTIPS_EMPTY; + break; + case Item::boat_Id: case Tile::waterLily_Id: if (bUseItem) *piUse = IDS_TOOLTIPS_PLACE; @@ -2740,8 +2776,8 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { */ if (bUseItemOn && itemInstance != NULL) { switch (itemInstance->getItem()->id) { - case Tile::mushroom1_Id: - case Tile::mushroom2_Id: + case Tile::mushroom_brown_Id: + case Tile::mushroom_red_Id: case Tile::tallgrass_Id: case Tile::cactus_Id: case Tile::sapling_Id: @@ -2761,38 +2797,20 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { break; case Item::seeds_wheat_Id: - case Item::netherStalkSeeds_Id: + case Item::netherwart_seeds_Id: *piUse = IDS_TOOLTIPS_PLANT; break; - case Item::bucket_empty_Id: - switch (iTileID) { - // can collect lava or water in the - // empty bucket - case Tile::water_Id: - case Tile::calmWater_Id: - case Tile::lava_Id: - case Tile::calmLava_Id: - *piUse = IDS_TOOLTIPS_COLLECT; - break; - } - break; - - case Item::bucket_lava_Id: - case Item::bucket_water_Id: - *piUse = IDS_TOOLTIPS_EMPTY; - break; - case Item::dye_powder_Id: // bonemeal grows various plants if (itemInstance->getAuxValue() == DyePowderItem::WHITE) { switch (iTileID) { case Tile::sapling_Id: - case Tile::crops_Id: + case Tile::wheat_Id: case Tile::grass_Id: - case Tile::mushroom1_Id: - case Tile::mushroom2_Id: + case Tile::mushroom_brown_Id: + case Tile::mushroom_red_Id: case Tile::melonStem_Id: case Tile::pumpkinStem_Id: case Tile::carrots_Id: @@ -2812,6 +2830,14 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { *piUse = IDS_TOOLTIPS_IGNITE; break; + case Item::fireworks_Id: + *piUse = IDS_TOOLTIPS_FIREWORK_LAUNCH; + break; + + case Item::lead_Id: + *piUse = IDS_TOOLTIPS_ATTACH; + break; + default: *piUse = IDS_TOOLTIPS_PLACE; break; @@ -2832,10 +2858,28 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { case Tile::button_wood_Id: case Tile::trapdoor_Id: case Tile::fenceGate_Id: + case Tile::beacon_Id: *piAction = IDS_TOOLTIPS_MINE; *piUse = IDS_TOOLTIPS_USE; break; + case Tile::chest_Id: + *piAction = IDS_TOOLTIPS_MINE; + *piUse = (Tile::chest->getContainer(level, x, y, + z) != NULL) + ? IDS_TOOLTIPS_OPEN + : -1; + break; + + case Tile::enderChest_Id: + case Tile::chest_trap_Id: + case Tile::dropper_Id: + case Tile::hopper_Id: + *piUse = IDS_TOOLTIPS_OPEN; + *piAction = IDS_TOOLTIPS_MINE; + break; + + case Tile::activatorRail_Id: case Tile::goldenRail_Id: case Tile::detectorRail_Id: case Tile::rail_Id: @@ -2843,18 +2887,12 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { *piAction = IDS_TOOLTIPS_MINE; break; - case Tile::chest_Id: - case Tile::enderChest_Id: - *piUse = IDS_TOOLTIPS_OPEN; - *piAction = IDS_TOOLTIPS_MINE; - break; - case Tile::bed_Id: if (bUseItemOn) *piUse = IDS_TOOLTIPS_SLEEP; *piAction = IDS_TOOLTIPS_MINE; break; - case Tile::musicBlock_Id: + case Tile::noteblock_Id: // if in creative mode, we will mine if (player->abilities.instabuild) *piAction = IDS_TOOLTIPS_MINE; @@ -2901,7 +2939,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { } break; - case Tile::recordPlayer_Id: + case Tile::jukebox_Id: if (!bUseItemOn && itemInstance != NULL) { int iID = itemInstance->getItem()->id; if ((iID >= Item::record_01_Id) && @@ -2910,7 +2948,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { } *piAction = IDS_TOOLTIPS_MINE; } else { - if (Tile::recordPlayer->TestUse( + if (Tile::jukebox->TestUse( level, x, y, z, player)) // means we can eject { @@ -2930,8 +2968,8 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { case Tile::flower_Id: case Tile::rose_Id: case Tile::sapling_Id: - case Tile::mushroom1_Id: - case Tile::mushroom2_Id: + case Tile::mushroom_brown_Id: + case Tile::mushroom_red_Id: case Tile::cactus_Id: case Tile::deadBush_Id: *piUse = IDS_TOOLTIPS_PLANT; @@ -2949,6 +2987,30 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { *piAction = IDS_TOOLTIPS_MINE; break; + case Tile::comparator_off_Id: + case Tile::comparator_on_Id: + *piUse = IDS_TOOLTIPS_USE; + *piAction = IDS_TOOLTIPS_MINE; + break; + + case Tile::diode_off_Id: + case Tile::diode_on_Id: + *piUse = IDS_TOOLTIPS_USE; + *piAction = IDS_TOOLTIPS_MINE; + break; + + case Tile::redStoneOre_Id: + if (bUseItemOn) *piUse = IDS_TOOLTIPS_USE; + *piAction = IDS_TOOLTIPS_MINE; + break; + + case Tile::door_iron_Id: + if (*piUse == IDS_TOOLTIPS_PLACE) { + *piUse = -1; + } + *piAction = IDS_TOOLTIPS_MINE; + break; + default: *piAction = IDS_TOOLTIPS_MINE; break; @@ -2958,305 +3020,323 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { case HitResult::ENTITY: eINSTANCEOF entityType = hitResult->entity->GetType(); - if (gameMode != NULL && - gameMode->getTutorial() != NULL) { + if ((gameMode != NULL) && + (gameMode->getTutorial() != NULL)) { // 4J Stu - For the tutorial we want to be able to // record what items we look at so that we can give // hints - gameMode->getTutorial()->onLookAtEntity(entityType); + gameMode->getTutorial()->onLookAtEntity( + hitResult->entity); } + std::shared_ptr heldItem = nullptr; + if (player->inventory->IsHeldItem()) { + heldItem = player->inventory->getSelected(); + } + int heldItemId = + heldItem != NULL ? heldItem->getItem()->id : -1; + switch (entityType) { - case eTYPE_CHICKEN: + case eTYPE_CHICKEN: { if (player->isAllowedToAttackAnimals()) *piAction = IDS_TOOLTIPS_HIT; - // is there an object in hand? - if (player->inventory->IsHeldItem()) { - std::shared_ptr heldItem = - player->inventory->getSelected(); - int iID = heldItem->getItem()->id; - switch (iID) { - default: { - std::shared_ptr animal = - std::dynamic_pointer_cast< - Animal>(hitResult->entity); + std::shared_ptr animal = + std::dynamic_pointer_cast( + hitResult->entity); - if (!animal->isBaby() && - !animal->isInLove() && - (animal->getAge() == 0) && - animal->isFood(heldItem)) { - *piUse = IDS_TOOLTIPS_LOVEMODE; - } - } break; - } + if (animal->isLeashed() && + animal->getLeashHolder() == player) { + *piUse = IDS_TOOLTIPS_UNLEASH; + break; } - break; - case eTYPE_COW: + switch (heldItemId) { + case Item::nameTag_Id: + *piUse = IDS_TOOLTIPS_NAME; + break; + + case Item::lead_Id: + if (!animal->isLeashed()) + *piUse = IDS_TOOLTIPS_LEASH; + break; + + default: { + if (!animal->isBaby() && + !animal->isInLove() && + (animal->getAge() == 0) && + animal->isFood(heldItem)) { + *piUse = IDS_TOOLTIPS_LOVEMODE; + } + } break; + + case -1: + break; // 4J-JEV: Empty hand. + } + } break; + + case eTYPE_COW: { if (player->isAllowedToAttackAnimals()) *piAction = IDS_TOOLTIPS_HIT; - // is there an object in hand? - if (player->inventory->IsHeldItem()) { - std::shared_ptr heldItem = - player->inventory->getSelected(); - int iID = heldItem->getItem()->id; - // It's an item - switch (iID) { - // Things to USE - case Item::bucket_empty_Id: - *piUse = IDS_TOOLTIPS_MILK; - break; - default: { - std::shared_ptr animal = - std::dynamic_pointer_cast< - Animal>(hitResult->entity); + std::shared_ptr animal = + std::dynamic_pointer_cast( + hitResult->entity); - if (!animal->isBaby() && - !animal->isInLove() && - (animal->getAge() == 0) && - animal->isFood(heldItem)) { - *piUse = IDS_TOOLTIPS_LOVEMODE; - } - } break; - } + if (animal->isLeashed() && + animal->getLeashHolder() == player) { + *piUse = IDS_TOOLTIPS_UNLEASH; + break; } - break; - case eTYPE_MUSHROOMCOW: - // is there an object in hand? - if (player->inventory->IsHeldItem()) { - if (player->isAllowedToAttackAnimals()) - *piAction = IDS_TOOLTIPS_HIT; - std::shared_ptr heldItem = - player->inventory->getSelected(); - int iID = heldItem->getItem()->id; + switch (heldItemId) { + // Things to USE + case Item::nameTag_Id: + *piUse = IDS_TOOLTIPS_NAME; + break; + case Item::lead_Id: + if (!animal->isLeashed()) + *piUse = IDS_TOOLTIPS_LEASH; + break; + case Item::bucket_empty_Id: + *piUse = IDS_TOOLTIPS_MILK; + break; + default: { + if (!animal->isBaby() && + !animal->isInLove() && + (animal->getAge() == 0) && + animal->isFood(heldItem)) { + *piUse = IDS_TOOLTIPS_LOVEMODE; + } + } break; - // It's an item - switch (iID) { - // Things to USE - case Item::bowl_Id: - case Item:: - bucket_empty_Id: // You can milk a - // mooshroom with - // either a bowl - // (mushroom soup) - // or a bucket - // (milk)! - *piUse = IDS_TOOLTIPS_MILK; - break; - case Item::shears_Id: { - if (player - ->isAllowedToAttackAnimals()) - *piAction = IDS_TOOLTIPS_HIT; - std::shared_ptr animal = - std::dynamic_pointer_cast< - Animal>(hitResult->entity); - if (!animal->isBaby()) - *piUse = IDS_TOOLTIPS_SHEAR; - } break; - default: { - std::shared_ptr animal = - std::dynamic_pointer_cast< - Animal>(hitResult->entity); - - if (!animal->isBaby() && - !animal->isInLove() && - (animal->getAge() == 0) && - animal->isFood(heldItem)) { - *piUse = IDS_TOOLTIPS_LOVEMODE; - } - } break; - } - } else { - // 4J-PB - Fix for #13081 - No tooltip is - // displayed for hitting a cow when you have - // nothing in your hand nothing in your hand - if (player->isAllowedToAttackAnimals()) - *piAction = IDS_TOOLTIPS_HIT; + case -1: + break; // 4J-JEV: Empty hand. } - break; + } break; + case eTYPE_MUSHROOMCOW: { + // 4J-PB - Fix for #13081 - No tooltip is + // displayed for hitting a cow when you have + // nothing in your hand + if (player->isAllowedToAttackAnimals()) + *piAction = IDS_TOOLTIPS_HIT; + + std::shared_ptr animal = + std::dynamic_pointer_cast( + hitResult->entity); + + if (animal->isLeashed() && + animal->getLeashHolder() == player) { + *piUse = IDS_TOOLTIPS_UNLEASH; + break; + } + + // It's an item + switch (heldItemId) { + // Things to USE + case Item::nameTag_Id: + *piUse = IDS_TOOLTIPS_NAME; + break; + + case Item::lead_Id: + if (!animal->isLeashed()) + *piUse = IDS_TOOLTIPS_LEASH; + break; + + case Item::bowl_Id: + case Item:: + bucket_empty_Id: // You can milk a + // mooshroom with + // either a bowl + // (mushroom soup) or + // a bucket (milk)! + *piUse = IDS_TOOLTIPS_MILK; + break; + case Item::shears_Id: { + if (player->isAllowedToAttackAnimals()) + *piAction = IDS_TOOLTIPS_HIT; + if (!animal->isBaby()) + *piUse = IDS_TOOLTIPS_SHEAR; + } break; + default: { + if (!animal->isBaby() && + !animal->isInLove() && + (animal->getAge() == 0) && + animal->isFood(heldItem)) { + *piUse = IDS_TOOLTIPS_LOVEMODE; + } + } break; + + case -1: + break; // 4J-JEV: Empty hand. + } + } break; case eTYPE_BOAT: *piAction = IDS_TOOLTIPS_MINE; - - // are we in the boat already? - if (std::dynamic_pointer_cast( - player->riding) != NULL) { - *piUse = IDS_TOOLTIPS_EXIT; - } else { - *piUse = IDS_TOOLTIPS_SAIL; - } + *piUse = IDS_TOOLTIPS_SAIL; break; - case eTYPE_MINECART: + + case eTYPE_MINECART_RIDEABLE: *piAction = IDS_TOOLTIPS_MINE; - // are we in the minecart already? - if (std::dynamic_pointer_cast( - player->riding) != NULL) { - *piUse = IDS_TOOLTIPS_EXIT; - } else { - switch (std::dynamic_pointer_cast( - hitResult->entity) - ->type) { - case Minecart::RIDEABLE: - *piUse = IDS_TOOLTIPS_RIDE; - break; - case Minecart::CHEST: - *piUse = IDS_TOOLTIPS_OPEN; - break; - case Minecart::FURNACE: - // if you have coal, it'll go - // is there an object in hand? - if (player->inventory - ->IsHeldItem()) { - std::shared_ptr - heldItem = - player->inventory - ->getSelected(); - int iID = - heldItem->getItem()->id; - - if (iID == Item::coal->id) { - *piUse = IDS_TOOLTIPS_USE; - } else { - *piUse = IDS_TOOLTIPS_HIT; - } - } - break; - } - } - + *piUse = + IDS_TOOLTIPS_RIDE; // are we in the + // minecart already? - + // 4J-JEV: Doesn't + // matter anymore. break; - case eTYPE_SHEEP: + + case eTYPE_MINECART_FURNACE: + *piAction = IDS_TOOLTIPS_MINE; + + // if you have coal, it'll go. Is there an + // object in hand? + if (heldItemId == Item::coal_Id) + *piUse = IDS_TOOLTIPS_USE; + break; + + case eTYPE_MINECART_CHEST: + case eTYPE_MINECART_HOPPER: + *piAction = IDS_TOOLTIPS_MINE; + *piUse = IDS_TOOLTIPS_OPEN; + break; + + case eTYPE_MINECART_SPAWNER: + case eTYPE_MINECART_TNT: + *piUse = IDS_TOOLTIPS_MINE; + break; + + case eTYPE_SHEEP: { // can dye a sheep if (player->isAllowedToAttackAnimals()) *piAction = IDS_TOOLTIPS_HIT; - if (player->inventory->IsHeldItem()) { - std::shared_ptr heldItem = - player->inventory->getSelected(); - int iID = heldItem->getItem()->id; - switch (iID) { - case Item::dye_powder_Id: { - std::shared_ptr sheep = - std::dynamic_pointer_cast< - Sheep>(hitResult->entity); - // convert to tile-based color value - // (0 is white instead of black) - int newColor = ClothTile:: - getTileDataForItemAuxValue( - heldItem->getAuxValue()); + std::shared_ptr sheep = + std::dynamic_pointer_cast( + hitResult->entity); - // can only use a dye on sheep that - // haven't been sheared - if (!(sheep->isSheared() && - sheep->getColor() != - newColor)) { - *piUse = IDS_TOOLTIPS_DYE; - } - } break; - case Item::shears_Id: { - std::shared_ptr sheep = - std::dynamic_pointer_cast< - Sheep>(hitResult->entity); - - // can only shear a sheep that - // hasn't been sheared - if (!sheep->isSheared()) { - *piUse = IDS_TOOLTIPS_SHEAR; - } - } - - break; - default: { - std::shared_ptr animal = - std::dynamic_pointer_cast< - Animal>(hitResult->entity); - - if (!animal->isBaby() && - !animal->isInLove() && - (animal->getAge() == 0) && - animal->isFood(heldItem)) { - *piUse = IDS_TOOLTIPS_LOVEMODE; - } - } break; - } + if (sheep->isLeashed() && + sheep->getLeashHolder() == player) { + *piUse = IDS_TOOLTIPS_UNLEASH; + break; } - break; - case eTYPE_PIG: + switch (heldItemId) { + case Item::nameTag_Id: + *piUse = IDS_TOOLTIPS_NAME; + break; + + case Item::lead_Id: + if (!sheep->isLeashed()) + *piUse = IDS_TOOLTIPS_LEASH; + break; + + case Item::dye_powder_Id: { + // convert to tile-based color value (0 + // is white instead of black) + int newColor = ColoredTile:: + getTileDataForItemAuxValue( + heldItem->getAuxValue()); + + // can only use a dye on sheep that + // haven't been sheared + if (!(sheep->isSheared() && + sheep->getColor() != newColor)) { + *piUse = IDS_TOOLTIPS_DYE; + } + } break; + case Item::shears_Id: { + // can only shear a sheep that hasn't + // been sheared + if (!sheep->isBaby() && + !sheep->isSheared()) { + *piUse = IDS_TOOLTIPS_SHEAR; + } + } + + break; + default: { + if (!sheep->isBaby() && + !sheep->isInLove() && + (sheep->getAge() == 0) && + sheep->isFood(heldItem)) { + *piUse = IDS_TOOLTIPS_LOVEMODE; + } + } break; + + case -1: + break; // 4J-JEV: Empty hand. + } + } break; + + case eTYPE_PIG: { // can ride a pig if (player->isAllowedToAttackAnimals()) *piAction = IDS_TOOLTIPS_HIT; - if (std::dynamic_pointer_cast( - player->riding) != NULL) { - *piUse = IDS_TOOLTIPS_EXIT; - } else { - // does the pig have a saddle? - if (std::dynamic_pointer_cast( - hitResult->entity) - ->hasSaddle()) { - *piUse = IDS_TOOLTIPS_RIDE; - } else if (!std::dynamic_pointer_cast( - hitResult->entity) - ->isBaby()) { - if (player->inventory->IsHeldItem()) { - std::shared_ptr - heldItem = player->inventory - ->getSelected(); - int iID = heldItem->getItem()->id; - switch (iID) { - case Item::saddle_Id: + std::shared_ptr pig = + std::dynamic_pointer_cast( + hitResult->entity); + + if (pig->isLeashed() && + pig->getLeashHolder() == player) { + *piUse = IDS_TOOLTIPS_UNLEASH; + } else if (heldItemId == Item::lead_Id) { + if (!pig->isLeashed()) + *piUse = IDS_TOOLTIPS_LEASH; + } else if (heldItemId == Item::nameTag_Id) { + *piUse = IDS_TOOLTIPS_NAME; + } else if (pig->hasSaddle()) // does the pig + // have a saddle? + { + *piUse = IDS_TOOLTIPS_MOUNT; + } else if (!pig->isBaby()) { + if (player->inventory->IsHeldItem()) { + switch (heldItemId) { + case Item::saddle_Id: + *piUse = IDS_TOOLTIPS_SADDLE; + break; + + default: { + if (!pig->isInLove() && + (pig->getAge() == 0) && + pig->isFood(heldItem)) { *piUse = - IDS_TOOLTIPS_SADDLE; - break; - default: { - std::shared_ptr - animal = std:: - dynamic_pointer_cast< - Animal>( - hitResult - ->entity); - - if (!animal->isBaby() && - !animal->isInLove() && - (animal->getAge() == - 0) && - animal->isFood( - heldItem)) { - *piUse = - IDS_TOOLTIPS_LOVEMODE; - } - } break; - } + IDS_TOOLTIPS_LOVEMODE; + } + } break; } } } + } break; - break; case eTYPE_WOLF: // can be tamed, fed, and made to sit/stand, or // enter love mode { - int iID = -1; - std::shared_ptr heldItem = - nullptr; std::shared_ptr wolf = std::dynamic_pointer_cast( hitResult->entity); - if (player->inventory->IsHeldItem()) { - heldItem = - player->inventory->getSelected(); - iID = heldItem->getItem()->id; - } - if (player->isAllowedToAttackAnimals()) *piAction = IDS_TOOLTIPS_HIT; - switch (iID) { + if (wolf->isLeashed() && + wolf->getLeashHolder() == player) { + *piUse = IDS_TOOLTIPS_UNLEASH; + break; + } + + switch (heldItemId) { + case Item::nameTag_Id: + *piUse = IDS_TOOLTIPS_NAME; + break; + + case Item::lead_Id: + if (!wolf->isLeashed()) + *piUse = IDS_TOOLTIPS_LEASH; + break; + case Item::bone_Id: if (!wolf->isAngry() && !wolf->isTame()) { @@ -3280,7 +3360,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { break; case Item::dye_powder_Id: if (wolf->isTame()) { - if (ClothTile:: + if (ColoredTile:: getTileDataForItemAuxValue( heldItem ->getAuxValue()) != @@ -3331,23 +3411,23 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { } } break; - case eTYPE_OZELOT: { - int iID = -1; - std::shared_ptr heldItem = - nullptr; - std::shared_ptr ocelot = - std::dynamic_pointer_cast( + case eTYPE_OCELOT: { + std::shared_ptr ocelot = + std::dynamic_pointer_cast( hitResult->entity); - if (player->inventory->IsHeldItem()) { - heldItem = player->inventory->getSelected(); - iID = heldItem->getItem()->id; - } - if (player->isAllowedToAttackAnimals()) *piAction = IDS_TOOLTIPS_HIT; - if (ocelot->isTame()) { + if (ocelot->isLeashed() && + ocelot->getLeashHolder() == player) { + *piUse = IDS_TOOLTIPS_UNLEASH; + } else if (heldItemId == Item::lead_Id) { + if (!ocelot->isLeashed()) + *piUse = IDS_TOOLTIPS_LEASH; + } else if (heldItemId == Item::nameTag_Id) { + *piUse = IDS_TOOLTIPS_NAME; + } else if (ocelot->isTame()) { // 4J-PB - if you have a raw fish in your // hand, you will feed the ocelot rather // than have it sit/follow @@ -3365,24 +3445,19 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { } else if (equalsIgnoreCase( player->getUUID(), - ocelot->getOwnerUUID())) { + ocelot->getOwnerUUID()) && + !ocelot->isSittingOnTile()) { if (ocelot->isSitting()) { *piUse = IDS_TOOLTIPS_FOLLOWME; } else { *piUse = IDS_TOOLTIPS_SIT; } } - } else if (iID != -1) { - switch (iID) { - default: { - if (ocelot->isFood(heldItem)) - *piUse = IDS_TOOLTIPS_TAME; - } break; - } + } else if (heldItemId >= 0) { + if (ocelot->isFood(heldItem)) + *piUse = IDS_TOOLTIPS_TAME; } - } - - break; + } break; case eTYPE_PLAYER: { // Fix for #58576 - TU6: Content: Gameplay: Hit @@ -3410,6 +3485,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { } } } break; + case eTYPE_ITEM_FRAME: { std::shared_ptr itemFrame = std::dynamic_pointer_cast( @@ -3421,14 +3497,16 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { *piUse = IDS_TOOLTIPS_ROTATE; } else { // is there an object in hand? - if (player->inventory->IsHeldItem()) { + if (heldItemId >= 0) *piUse = IDS_TOOLTIPS_PLACE; - } } *piAction = IDS_TOOLTIPS_HIT; } break; + case eTYPE_VILLAGER: { + // 4J-JEV: Cannot leash villagers. + std::shared_ptr villager = std::dynamic_pointer_cast( hitResult->entity); @@ -3437,29 +3515,144 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { } *piAction = IDS_TOOLTIPS_HIT; } break; + case eTYPE_ZOMBIE: { std::shared_ptr zomb = std::dynamic_pointer_cast( hitResult->entity); - std::shared_ptr heldItem = - nullptr; + static GoldenAppleItem* goldapple = + (GoldenAppleItem*)Item::apple_gold; - if (player->inventory->IsHeldItem()) { - heldItem = player->inventory->getSelected(); - } - - if (zomb->isVillager() && - zomb->isWeakened() // zomb->hasEffect(MobEffect::weakness) - // - not present on - // client. - && heldItem != NULL && - heldItem->getItem()->id == - Item::apple_gold_Id) { + // zomb->hasEffect(MobEffect::weakness) - not + // present on client. + if (zomb->isVillager() && zomb->isWeakened() && + (heldItemId == Item::apple_gold_Id) && + !goldapple->isFoil(heldItem)) { *piUse = IDS_TOOLTIPS_CURE; } *piAction = IDS_TOOLTIPS_HIT; } break; + + case eTYPE_HORSE: { + std::shared_ptr horse = + std::dynamic_pointer_cast( + hitResult->entity); + + bool heldItemIsFood = false, + heldItemIsLove = false, + heldItemIsArmour = false; + + switch (heldItemId) { + case Item::wheat_Id: + case Item::sugar_Id: + case Item::bread_Id: + case Tile::hayBlock_Id: + case Item::apple_Id: + heldItemIsFood = true; + break; + case Item::carrotGolden_Id: + case Item::apple_gold_Id: + heldItemIsLove = true; + heldItemIsFood = true; + break; + case Item::horseArmorDiamond_Id: + case Item::horseArmorGold_Id: + case Item::horseArmorMetal_Id: + heldItemIsArmour = true; + break; + } + + if (horse->isLeashed() && + horse->getLeashHolder() == player) { + *piUse = IDS_TOOLTIPS_UNLEASH; + } else if (heldItemId == Item::lead_Id) { + if (!horse->isLeashed()) + *piUse = IDS_TOOLTIPS_LEASH; + } else if (heldItemId == Item::nameTag_Id) { + *piUse = IDS_TOOLTIPS_NAME; + } else if (horse->isBaby()) // 4J-JEV: Can't + // ride baby horses + // due to morals. + { + if (heldItemIsFood) { + // 4j - Can feed foles to speed growth. + *piUse = IDS_TOOLTIPS_FEED; + } + } else if (!horse->isTamed()) { + if (heldItemId == -1) { + // 4j - Player not holding anything, + // ride and attempt to break untamed + // horse. + *piUse = IDS_TOOLTIPS_TAME; + } else if (heldItemIsFood) { + // 4j - Attempt to make it like you more + // by feeding it. + *piUse = IDS_TOOLTIPS_FEED; + } + } else if (player->isSneaking() || + (heldItemId == Item::saddle_Id) || + (horse->canWearArmor() && + heldItemIsArmour)) { + // 4j - Access horses inventory + if (*piUse == -1) + *piUse = IDS_TOOLTIPS_OPEN; + } else if (horse->canWearBags() && + !horse->isChestedHorse() && + (heldItemId == Tile::chest_Id)) { + // 4j - Attach saddle-bags (chest) to donkey + // or mule. + *piUse = IDS_TOOLTIPS_ATTACH; + } else if (horse->isReadyForParenting() && + heldItemIsLove) { + // 4j - Different food to mate horses. + *piUse = IDS_TOOLTIPS_LOVEMODE; + } else if (heldItemIsFood && + (horse->getHealth() < + horse->getMaxHealth())) { + // 4j - Horse is damaged and can eat held + // item to heal + *piUse = IDS_TOOLTIPS_HEAL; + } else { + // 4j - Ride tamed horse. + *piUse = IDS_TOOLTIPS_MOUNT; + } + + if (player->isAllowedToAttackAnimals()) + *piAction = IDS_TOOLTIPS_HIT; + } break; + + case eTYPE_ENDERDRAGON: + // 4J-JEV: Enderdragon cannot be named. + *piAction = IDS_TOOLTIPS_HIT; + break; + + case eTYPE_LEASHFENCEKNOT: + *piAction = IDS_TOOLTIPS_UNLEASH; + if (heldItemId == Item::lead_Id && + LeashItem::bindPlayerMobsTest( + player, level, player->x, player->y, + player->z)) { + *piUse = IDS_TOOLTIPS_ATTACH; + } else { + *piUse = IDS_TOOLTIPS_UNLEASH; + } + break; + default: + if (hitResult->entity->instanceof(eTYPE_MOB)) { + std::shared_ptr mob = + std::dynamic_pointer_cast( + hitResult->entity); + if (mob->isLeashed() && + mob->getLeashHolder() == player) { + *piUse = IDS_TOOLTIPS_UNLEASH; + } else if (heldItemId == Item::lead_Id) { + if (!mob->isLeashed()) + *piUse = IDS_TOOLTIPS_LEASH; + } else if (heldItemId == Item::nameTag_Id) { + *piUse = IDS_TOOLTIPS_NAME; + } + } *piAction = IDS_TOOLTIPS_HIT; break; } @@ -3468,7 +3661,10 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { } } - ui.SetTooltips(iPad, iA, iB, iX, iY, iLT, iRT, iLB, iRB); + // 4J-JEV: Don't set tooltips when we're reloading the skin, it'll + // crash. + if (!ui.IsReloadingSkin()) + ui.SetTooltips(iPad, iA, iB, iX, iY, iLT, iRT, iLB, iRB, iLS, iRS); int wheel = 0; unsigned int leftTicks = @@ -3502,6 +3698,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { options->flySpeed += wheel * .25f; } } + if (gameMode->isInputAllowed(MINECRAFT_ACTION_ACTION)) { if ((player->ullButtonsPressed & (1LL << MINECRAFT_ACTION_ACTION))) // if(InputManager.ButtonPressed(iPad, MINECRAFT_ACTION_ACTION) ) @@ -3640,9 +3837,9 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { if ((player->ullButtonsPressed & (1LL << MINECRAFT_ACTION_SPAWN_CREEPER)) && app.GetMobsDontAttackEnabled()) { - // std::shared_ptr mob = + // shared_ptr mob = // std::dynamic_pointer_cast(Creeper::_class->newInstance( - // level )); std::shared_ptr mob = + // level )); shared_ptr mob = // std::dynamic_pointer_cast(Wolf::_class->newInstance( // level )); std::shared_ptr mob = std::dynamic_pointer_cast( @@ -3678,9 +3875,8 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { if ((player->ullButtonsPressed & (1LL << MINECRAFT_ACTION_INVENTORY)) && gameMode->isInputAllowed(MINECRAFT_ACTION_INVENTORY)) { - std::shared_ptr player = - std::dynamic_pointer_cast( - Minecraft::GetInstance()->player); + std::shared_ptr player = + Minecraft::GetInstance()->player; ui.PlayUISFX(eSFX_Press); #ifdef ENABLE_JAVA_GUIS setScreen(new InventoryScreen(player)); @@ -3691,9 +3887,8 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { if ((player->ullButtonsPressed & (1LL << MINECRAFT_ACTION_CRAFTING)) && gameMode->isInputAllowed(MINECRAFT_ACTION_CRAFTING)) { - std::shared_ptr player = - std::dynamic_pointer_cast( - Minecraft::GetInstance()->player); + std::shared_ptr player = + Minecraft::GetInstance()->player; // 4J-PB - reordered the if statement so creative mode doesn't bring // up the crafting table Fix for #39014 - TU5: Creative Mode: @@ -3748,20 +3943,25 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { player->drop(); } - __uint64 ullButtonsPressed = player->ullButtonsPressed; + uint64_t ullButtonsPressed = player->ullButtonsPressed; bool selected = false; - #ifdef __PSVITA__ // 4J-PB - use the touchscreen for quickselect SceTouchData* pTouchData = InputManager.GetTouchPadData(iPad, false); if (pTouchData->reportNum == 1) { int iHudSize = app.GetGameSettings(iPad, eGameSetting_UISize); + int iYOffset = (app.GetGameSettings(ProfileManager.GetPrimaryPad(), + eGameSetting_Tooltips) == 0) + ? iToolTipOffset + : 0; if ((pTouchData->report[0].x > QuickSelectRect[iHudSize].left) && (pTouchData->report[0].x < QuickSelectRect[iHudSize].right) && - (pTouchData->report[0].y > QuickSelectRect[iHudSize].top) && - (pTouchData->report[0].y < QuickSelectRect[iHudSize].bottom)) { + (pTouchData->report[0].y > + QuickSelectRect[iHudSize].top + iYOffset) && + (pTouchData->report[0].y < + QuickSelectRect[iHudSize].bottom + iYOffset)) { player->inventory->selected = (pTouchData->report[0].x - QuickSelectRect[iHudSize].left) / QuickSelectBoxWidth[iHudSize]; @@ -3834,14 +4034,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { int wheel = Mouse.getEventDWheel(); if (wheel != 0) { player->inventory.swapPaint(wheel); - { - int hotbarSlot = InputManager.GetHotbarSlotPressed(iPad); - if (hotbarSlot >= 0 && gameMode->isInputAllowed(MINECRAFT_ACTION_LEFT_SCROLL)) - { - player->inventory->selected = hotbarSlot; - selected = true; - } - } + if (options.isFlying) { if (wheel > 0) wheel = 1; if (wheel < 0) wheel = -1; @@ -4045,8 +4238,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { // } if (levels[i] != NULL) { if (!pause) { - if (levels[i]->lightningBoltTime > 0) - levels[i]->lightningBoltTime--; + if (levels[i]->skyFlashTime > 0) levels[i]->skyFlashTime--; PIXBeginNamedEvent(0, "Level entity tick"); levels[i]->tickEntities(); PIXEndNamedEvent(); @@ -4065,7 +4257,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures) { Camera::prepare( localplayers[idx], localplayers[idx]->ThirdPersonView() == 2); - std::shared_ptr cameraEntity = + std::shared_ptr cameraEntity = cameraTargetPlayer; double xOff = cameraEntity->xOld + @@ -4194,9 +4386,9 @@ MultiPlayerLevel* Minecraft::getLevel(int dimension) { //} // Also causing ambiguous call for some reason -// as it is matching std::shared_ptr from the func below with bool from -// this one -// void Minecraft::setLevel(Level *level, const std::wstring& message, bool +// as it is matching shared_ptr from the func below with bool from this +// one +// void Minecraft::setLevel(Level *level, const wstring& message, bool // doForceStatsSave /*= true*/) //{ // setLevel(level, message, NULL, doForceStatsSave); @@ -4727,34 +4919,32 @@ void Minecraft::main() { #endif // 4J Stu - This block generates XML for the game rules schema - // for(unsigned int i = 0; i < Item::items.length; ++i) - //{ - // if(Item::items[i] != NULL) - // { - // wprintf(L"%ls\n", - // i, app.GetString( Item::items[i]->getDescriptionId() )); - // } - //} +#if 0 + for(unsigned int i = 0; i < Item::items.length; ++i) + { + if(Item::items[i] != NULL) + { + app.DebugPrintf("%ls\n", i, app.GetString( Item::items[i]->getDescriptionId() )); + } + } - // wprintf(L"\n\n\n\n\n"); - // - // for(unsigned int i = 0; i < 256; ++i) - //{ - // if(Tile::tiles[i] != NULL) - // { - // wprintf(L"%ls\n", - // i, app.GetString( Tile::tiles[i]->getDescriptionId() )); - // } - // } - //__debugbreak(); + app.DebugPrintf("\n\n\n\n\n"); + + for(unsigned int i = 0; i < 256; ++i) + { + if(Tile::tiles[i] != NULL) + { + app.DebugPrintf("%ls\n", i, app.GetString( Tile::tiles[i]->getDescriptionId() )); + } + } + __debugbreak(); +#endif // 4J-PB - Can't call this for the first 5 seconds of a game - MS rule // if (ProfileManager.IsFullVersion()) { name = - L"Player" + _toString<__int64>(System::currentTimeMillis() % 1000); + L"Player" + _toString(System::currentTimeMillis() % 1000); sessionId = L"-"; /* 4J - TODO - get a session ID from somewhere? if (args.length > 0) name = args[0]; @@ -4786,7 +4976,8 @@ bool Minecraft::useFancyGraphics() { } bool Minecraft::useAmbientOcclusion() { - return (m_instance != NULL && m_instance->options->ambientOcclusion); + return (m_instance != NULL && + m_instance->options->ambientOcclusion != Options::AO_OFF); } bool Minecraft::renderDebug() { @@ -4794,43 +4985,6 @@ bool Minecraft::renderDebug() { } bool Minecraft::handleClientSideCommand(const std::wstring& chatMessage) { - /* 4J - TODO - if (chatMessage.startsWith("/")) { - if (DEADMAU5_CAMERA_CHEATS) { - if (chatMessage.startsWith("/follow")) { - String[] tokens = chatMessage.split(" "); - if (tokens.length >= 2) { - String playerName = tokens[1]; - - boolean found = false; - for (Player player : level.players) { - if (playerName.equalsIgnoreCase(player.name)) { - cameraTargetPlayer = player; - found = true; - break; - } - } - - if (!found) { - try { - int entityId = Integer.parseInt(playerName); - for (Entity e : level.entities) { - if (e.entityId == entityId && e instanceof Mob) { - cameraTargetPlayer = (Mob) e; - found = true; - break; - } - } - } catch (NumberFormatException e) { - } - } - } - - return true; - } - } - } - */ return false; } @@ -4851,7 +5005,7 @@ int Minecraft::maxSupportedTextureSize() { void Minecraft::delayTextureReload() { reloadTextures = true; } -__int64 Minecraft::currentTimeMillis() { +int64_t Minecraft::currentTimeMillis() { return System::currentTimeMillis(); //(Sys.getTime() * 1000) / // Sys.getTimerResolution(); } @@ -4898,7 +5052,7 @@ game - we need to wake up, and we don't have the inbedchatscreen with a button if(button==1 && (player->isSleeping() && level != NULL && level->isClientSide)) { -std::shared_ptr mplp = +shared_ptr mplp = std::dynamic_pointer_cast( player ); if(mplp) mplp->StopSleeping(); @@ -4951,7 +5105,7 @@ gameMode->startDestroyBlock(x, y, z, hitResult->f); } else { -std::shared_ptr item = player->inventory->getSelected(); +shared_ptr item = player->inventory->getSelected(); int oldCount = item != NULL ? item->count : 0; if (gameMode->useItemOn(player, level, item, x, y, z, face)) { @@ -4977,7 +5131,7 @@ gameRenderer->itemInHandRenderer->itemPlaced(); if (mayUse && button == 1) { -std::shared_ptr item = player->inventory->getSelected(); +shared_ptr item = player->inventory->getSelected(); if (item != NULL) { if (gameMode->useItem(player, level, item)) @@ -5052,8 +5206,8 @@ void Minecraft::inGameSignInCheckAllPrivilegesCallback(void* lpParam, if (!g_NetworkManager.SessionHasSpace()) { unsigned int uiIDA[1]; uiIDA[0] = IDS_OK; - ui.RequestMessageBox(IDS_MULTIPLAYER_FULL_TITLE, - IDS_MULTIPLAYER_FULL_TEXT, uiIDA, 1); + ui.RequestErrorMessage(IDS_MULTIPLAYER_FULL_TITLE, + IDS_MULTIPLAYER_FULL_TEXT, uiIDA, 1); ProfileManager.RemoveGamepadFromGame(iPad); } else if (ProfileManager.IsSignedInLive(iPad) && ProfileManager.AllowedToPlayMultiplayer(iPad)) { @@ -5080,7 +5234,13 @@ void Minecraft::inGameSignInCheckAllPrivilegesCallback(void* lpParam, } #endif -int Minecraft::InGame_SignInReturned(void* pParam, bool bContinue, int iPad) { +#ifdef _XBOX_ONE +int Minecraft::InGame_SignInReturned(void* pParam, bool bContinue, int iPad, + int iController) +#else +int Minecraft::InGame_SignInReturned(void* pParam, bool bContinue, int iPad) +#endif +{ Minecraft* pMinecraftClass = (Minecraft*)pParam; if (g_NetworkManager.IsInSession()) { @@ -5112,8 +5272,8 @@ int Minecraft::InGame_SignInReturned(void* pParam, bool bContinue, int iPad) { if (!g_NetworkManager.SessionHasSpace()) { unsigned int uiIDA[1]; uiIDA[0] = IDS_OK; - ui.RequestMessageBox(IDS_MULTIPLAYER_FULL_TITLE, - IDS_MULTIPLAYER_FULL_TEXT, uiIDA, 1); + ui.RequestErrorMessage(IDS_MULTIPLAYER_FULL_TITLE, + IDS_MULTIPLAYER_FULL_TEXT, uiIDA, 1); #ifdef _DURANGO ProfileManager.RemoveGamepadFromGame(iPad); #endif @@ -5165,10 +5325,9 @@ int Minecraft::InGame_SignInReturned(void* pParam, bool bContinue, int iPad) { // &Minecraft::InGame_SignInReturned, pMinecraftClass,iPad); unsigned int uiIDA[1]; uiIDA[0] = IDS_CONFIRM_OK; - ui.RequestMessageBox(IDS_NO_MULTIPLAYER_PRIVILEGE_TITLE, - IDS_NO_MULTIPLAYER_PRIVILEGE_JOIN_TEXT, - uiIDA, 1, iPad, NULL, NULL, - app.GetStringTable()); + ui.RequestErrorMessage(IDS_NO_MULTIPLAYER_PRIVILEGE_TITLE, + IDS_NO_MULTIPLAYER_PRIVILEGE_JOIN_TEXT, + uiIDA, 1, iPad); #ifdef _DURANGO ProfileManager.RemoveGamepadFromGame(iPad); #endif diff --git a/Minecraft.Client/Minecraft.h b/Minecraft.Client/Minecraft.h index 876801683..1651bd5c6 100644 --- a/Minecraft.Client/Minecraft.h +++ b/Minecraft.Client/Minecraft.h @@ -41,12 +41,15 @@ class PsPlusUpsellWrapper; #include "../Minecraft.World/IO/Files/File.h" #include "../Minecraft.World/Network/Packets/DisconnectPacket.h" #include "../Minecraft.World/Util/C4JThread.h" - -#ifdef linux -#undef linux -#endif +#include "Textures/ResourceLocation.h" class Minecraft { +private: + enum OS { linux, solaris, windows, macos, unknown, xbox }; + + static ResourceLocation DEFAULT_FONT_LOCATION; + static ResourceLocation ALT_FONT_LOCATION; + public: static const std::wstring VERSION_STRING; Minecraft(Component* mouseComponent, Canvas* parent, @@ -128,7 +131,8 @@ public: void updatePlayerViewportAssignments(); int unoccupiedQuadrant; // 4J - added - std::shared_ptr cameraTargetPlayer; + std::shared_ptr cameraTargetPlayer; + std::shared_ptr crosshairPickMob; ParticleEngine* particleEngine; User* user; std::wstring serverDomain; @@ -183,11 +187,11 @@ private: public: static const int frameTimes_length = 512; - static __int64 frameTimes[frameTimes_length]; + static int64_t frameTimes[frameTimes_length]; static const int tickTimes_length = 512; - static __int64 tickTimes[tickTimes_length]; + static int64_t tickTimes[tickTimes_length]; static int frameTimePos; - static __int64 warezTime; + static int64_t warezTime; private: int rightClickDelay; @@ -249,9 +253,9 @@ private: // ssWidth, int ssHeight); // 4J - removed // 4J - per player thing? - __int64 lastTimer; + int64_t lastTimer; - void renderFpsMeter(__int64 tickTime); + void renderFpsMeter(int64_t tickTime); public: void stop(); @@ -275,7 +279,7 @@ public: // bool isRaining ; // 4J - Moved to per player - //__int64 lastTickTime; + //int64_t lastTickTime; private: // 4J- per player? @@ -336,14 +340,17 @@ public: static int maxSupportedTextureSize(); void delayTextureReload(); - static __int64 currentTimeMillis(); + static int64_t currentTimeMillis(); #ifdef _DURANGO static void inGameSignInCheckAllPrivilegesCallback(void* lpParam, bool hasPrivileges, int iPad); -#endif + static int InGame_SignInReturned(void* pParam, bool bContinue, int iPad, + int iController); +#else static int InGame_SignInReturned(void* pParam, bool bContinue, int iPad); +#endif // 4J-PB Screen* getScreen(); @@ -355,7 +362,7 @@ public: private: // A bit field that store whether a particular quadrant is in the full // tutorial or not - std::uint8_t m_inFullTutorialBits; + BYTE m_inFullTutorialBits; public: bool isTutorial(); diff --git a/Minecraft.Client/MinecraftServer.cpp b/Minecraft.Client/MinecraftServer.cpp index 6411e4446..1fa59b821 100644 --- a/Minecraft.Client/MinecraftServer.cpp +++ b/Minecraft.Client/MinecraftServer.cpp @@ -3,17 +3,19 @@ #include -#include "GameState/Options.h" -#include "MinecraftServer.h" #include "Input/ConsoleInput.h" -#include "Network/PlayerList.h" -#include "Level/ServerLevel.h" #include "Level/DerivedServerLevel.h" +#include "GameState/DispenserBootstrap.h" #include "Player/EntityTracker.h" -#include "Network/ServerConnection.h" -#include "GameState/Settings.h" +#include "MinecraftServer.h" +#include "GameState/Options.h" +#include "Network/PlayerList.h" #include "Network/ServerChunkCache.h" +#include "Network/ServerConnection.h" +#include "Level/ServerLevel.h" #include "Level/ServerLevelListener.h" +#include "GameState/Settings.h" +#include "../Minecraft.World/Commands/Command.h" #include "../Minecraft.World/Util/AABB.h" #include "../Minecraft.World/Util/Vec3.h" #include "../Minecraft.World/Headers/net.minecraft.network.h" @@ -54,15 +56,21 @@ // 4J Added MinecraftServer* MinecraftServer::server = NULL; bool MinecraftServer::setTimeAtEndOfTick = false; -__int64 MinecraftServer::setTime = 0; +int64_t MinecraftServer::setTime = 0; bool MinecraftServer::setTimeOfDayAtEndOfTick = false; -__int64 MinecraftServer::setTimeOfDay = 0; +int64_t MinecraftServer::setTimeOfDay = 0; bool MinecraftServer::m_bPrimaryPlayerSignedOut = false; bool MinecraftServer::s_bServerHalted = false; bool MinecraftServer::s_bSaveOnExitAnswered = false; +#ifdef _ACK_CHUNK_SEND_THROTTLING +bool MinecraftServer::s_hasSentEnoughPackets = false; +int64_t MinecraftServer::s_tickStartTime = 0; +std::vector MinecraftServer::s_sentTo; +#else int MinecraftServer::s_slowQueuePlayerIndex = 0; int MinecraftServer::s_slowQueueLastTime = 0; bool MinecraftServer::s_slowQueuePacketSent = false; +#endif std::unordered_map MinecraftServer::ironTimers; @@ -89,9 +97,13 @@ MinecraftServer::MinecraftServer() { m_ugcPlayersVersion = 0; m_texturePackId = 0; maxBuildHeight = Level::maxBuildHeight; + playerIdleTimeout = 0; m_postUpdateThread = NULL; + forceGameType = false; commandDispatcher = new ServerCommandDispatcher(); + + DispenserBootstrap::bootStrap(); } MinecraftServer::~MinecraftServer() {} @@ -100,34 +112,34 @@ bool MinecraftServer::initServer(__int64 seed, NetworkGameInitData* initData, std::uint32_t initSettings, bool findSeed) { // 4J - removed #if 0 - commands = new ConsoleCommands(this); + commands = new ConsoleCommands(this); - Thread t = new Thread() { - public void run() { - BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); - String line = null; - try { - while (!stopped && running && (line = br.readLine()) != null) { - handleConsoleInput(line, MinecraftServer.this); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - }; - t.setDaemon(true); - t.start(); + Thread t = new Thread() { + public void run() { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + String line = null; + try { + while (!stopped && running && (line = br.readLine()) != null) { + handleConsoleInput(line, MinecraftServer.this); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + }; + t.setDaemon(true); + t.start(); - LogConfigurator.initLogger(); - logger.info("Starting minecraft server version " + VERSION); + LogConfigurator.initLogger(); + logger.info("Starting minecraft server version " + VERSION); - if (Runtime.getRuntime().maxMemory() / 1024 / 1024 < 512) { - logger.warning("**** NOT ENOUGH RAM!"); - logger.warning("To start the server with more ram, launch it as \"java -Xmx1024M -Xms1024M -jar minecraft_server.jar\""); - } + if (Runtime.getRuntime().maxMemory() / 1024 / 1024 < 512) { + logger.warning("**** NOT ENOUGH RAM!"); + logger.warning("To start the server with more ram, launch it as \"java -Xmx1024M -Xms1024M -jar minecraft_server.jar\""); + } - logger.info("Loading properties"); + logger.info("Loading properties"); #endif settings = new Settings(new File(L"server.properties")); @@ -183,7 +195,7 @@ bool MinecraftServer::initServer(__int64 seed, NetworkGameInitData* initData, connection = new ServerConnection(this); Socket::Initialise(connection); // 4J - added #else - // 4J - removed + // 4J - removed InetAddress localAddress = null; if (localIp.length() > 0) localAddress = InetAddress.getByName(localIp); port = settings.getInt("server-port", DEFAULT_MINECRAFT_PORT); @@ -225,7 +237,7 @@ bool MinecraftServer::initServer(__int64 seed, NetworkGameInitData* initData, // TODO: Stop loading, add error message. } - __int64 levelNanoTime = System::nanoTime(); + int64_t levelNanoTime = System::nanoTime(); std::wstring levelName = settings->getString(L"level-name", L"world"); std::wstring levelTypeString; @@ -266,22 +278,21 @@ bool MinecraftServer::initServer(__int64 seed, NetworkGameInitData* initData, // settings->setProperty(L"max-build-height", maxBuildHeight); #if 0 - std::wstring levelSeedString = settings->getString(L"level-seed", L""); - __int64 levelSeed = (new Random())->nextLong(); - if (levelSeedString.length() > 0) - { - long newSeed = _fromString<__int64>(levelSeedString); - if (newSeed != 0) { - levelSeed = newSeed; - } - } + std::wstring levelSeedString = settings->getString(L"level-seed", L""); + int64_t levelSeed = (new Random())->nextLong(); + if (levelSeedString.length() > 0) + { + long newSeed = _fromString(levelSeedString); + if (newSeed != 0) { + levelSeed = newSeed; + } + } #endif // logger.info("Preparing level \"" + levelName + "\""); m_bLoaded = loadLevel(new McRegionLevelStorageSource(File(L".")), levelName, seed, pLevelType, initData); // logger.info("Done (" + (System.nanoTime() - levelNanoTime) + "ns)! // For help, type \"help\" or \"?\""); - app.DebugPrintf("[SRV] loadLevel returned %d\n", m_bLoaded); // 4J delete passed in save data now - this is only required for the // tutorial which is loaded by passing data directly in rather than using @@ -292,10 +303,7 @@ bool MinecraftServer::initServer(__int64 seed, NetworkGameInitData* initData, initData->saveData->fileSize = 0; } - app.DebugPrintf("[SRV] Signaling ServerReady\n"); g_NetworkManager.ServerReady(); // 4J added - app.DebugPrintf("[SRV] ServerReady signaled, returning m_bLoaded=%d\n", - m_bLoaded); return m_bLoaded; } @@ -488,7 +496,7 @@ bool MinecraftServer::loadLevel(LevelStorageSource* storageSource, } // McRegionLevelStorage *storage = new McRegionLevelStorage(new - //ConsoleSaveFile( L"" ), L"", L"", 0); // original + // ConsoleSaveFile( L"" ), L"", L"", 0); // original // McRegionLevelStorage *storage = new McRegionLevelStorage(File(L"."), // name, true); // TODO for (unsigned int i = 0; i < levels.length; i++) { @@ -540,6 +548,14 @@ bool MinecraftServer::loadLevel(LevelStorageSource* storageSource, settings->getBoolean(L"spawn-monsters", true), animals); #endif levels[i]->getLevelData()->setGameType(gameType); + + if (app.getLevelGenerationOptions() != NULL) { + LevelGenerationOptions* mapOptions = + app.getLevelGenerationOptions(); + levels[i]->getLevelData()->setHasBeenInCreative( + mapOptions->getLevelHasBeenInCreative()); + } + players->setLevel(levels); } @@ -559,7 +575,10 @@ bool MinecraftServer::loadLevel(LevelStorageSource* storageSource, // 4J - Make a new thread to do post processing InitializeCriticalSection(&m_postProcessCS); - app.DebugPrintf("[SRV] Starting post-processing thread\n"); + // 4J-PB - fix for 108310 - TCR #001 BAS Game Stability: TU12: Code: + // Compliance: Crash after creating world on "journey" seed. Stack gets very + // deep with some sand tower falling, so increased the stacj to 256K from + // 128k on other platforms (was already set to that on PS3 and Orbis) m_postUpdateThread = new C4JThread(runPostUpdate, this, "Post processing", 256 * 1024); @@ -568,9 +587,8 @@ bool MinecraftServer::loadLevel(LevelStorageSource* storageSource, m_postUpdateThread->SetProcessor(CPU_CORE_POST_PROCESSING); m_postUpdateThread->SetPriority(THREAD_PRIORITY_ABOVE_NORMAL); m_postUpdateThread->Run(); - app.DebugPrintf("[SRV] Post-processing thread started\n"); - __int64 startTime = System::currentTimeMillis(); + int64_t startTime = System::currentTimeMillis(); // 4J Stu - Added this to temporarily make starting games on vita faster #ifdef __PSVITA__ @@ -600,7 +618,20 @@ bool MinecraftServer::loadLevel(LevelStorageSource* storageSource, csf->closeHandle(fe); } - __int64 lastTime = System::currentTimeMillis(); + int64_t lastTime = System::currentTimeMillis(); +#ifdef _LARGE_WORLDS + if (app.GetGameNewWorldSize() > levels[0]->getLevelData()->getXZSizeOld()) { + if (!app.GetGameNewWorldSizeUseMoat()) // check the moat settings to + // see if we should be + // overwriting the edge tiles + { + overwriteBordersForNewWorldSize(levels[0]); + } + // we're always overwriting hell edges + int oldHellSize = levels[0]->getLevelData()->getXZHellSizeOld(); + overwriteHellBordersForNewWorldSize(levels[1], oldHellSize); + } +#endif // 4J Stu - This loop is changed in 1.0.1 to only process the first level // (ie the overworld), but I think we still want to do them all @@ -614,7 +645,7 @@ bool MinecraftServer::loadLevel(LevelStorageSource* storageSource, } #if 0 - __int64 lastStorageTickTime = System::currentTimeMillis(); + int64_t lastStorageTickTime = System::currentTimeMillis(); // Test code to enable full creation of levels at start up int halfsidelen = ( i == 0 ) ? 27 : 9; @@ -637,14 +668,11 @@ bool MinecraftServer::loadLevel(LevelStorageSource* storageSource, } } #else - __int64 lastStorageTickTime = System::currentTimeMillis(); + int64_t lastStorageTickTime = System::currentTimeMillis(); Pos* spawnPos = level->getSharedSpawnPos(); - app.DebugPrintf("[SRV] dim=%d spawn=(%d,%d) r=%d\n", i, spawnPos->x, - spawnPos->z, r); int twoRPlusOne = r * 2 + 1; int total = twoRPlusOne * twoRPlusOne; - int chunksDone = 0; for (int x = -r; x <= r && running; x += 16) { for (int z = -r; z <= r && running; z += 16) { if (s_bServerHalted || !g_NetworkManager.IsInSession()) { @@ -655,7 +683,7 @@ bool MinecraftServer::loadLevel(LevelStorageSource* storageSource, } // printf(">>>%d %d //%d\n",i,x,z); - // __int64 now = + // int64_t now = // System::currentTimeMillis(); if (now < // lastTime) lastTime = now; if (now > // lastTime + 1000) @@ -674,10 +702,6 @@ bool MinecraftServer::loadLevel(LevelStorageSource* storageSource, true); // 4J - added parameter to // disable postprocessing here PIXEndNamedEvent(); - chunksDone++; - if (chunksDone % 50 == 0) - app.DebugPrintf("[SRV] dim=%d chunk %d/%d\n", i, - chunksDone, total); // while (level->updateLights() && // running) // ; @@ -696,9 +720,9 @@ bool MinecraftServer::loadLevel(LevelStorageSource* storageSource, // spawn area too #if 0 // 4J - added this code to propagate lighting properly in the spawn area before we go sharing it with the local client or across the network - for (int x = -r; x <= r && running; x += 16) + for (int x = -r; x <= r && running; x += 16) { - for (int z = -r; z <= r && running; z += 16) + for (int z = -r; z <= r && running; z += 16) { PIXBeginNamedEvent(0,"Lighting gaps for %d %d",x,z); level->getChunkAt(spawnPos->x + x, spawnPos->z + z)->recheckGaps(true); @@ -712,15 +736,13 @@ bool MinecraftServer::loadLevel(LevelStorageSource* storageSource, } } // printf("Main thread complete at %dms\n",System::currentTimeMillis() - - //startTime); + // startTime); - app.DebugPrintf("[SRV] All chunk loops done, waiting for postProcess\n"); // Wait for post processing, then lighting threads, to end (post-processing // may make more lighting changes) m_postUpdateTerminate = true; postProcessTerminate(mcprogress); - app.DebugPrintf("[SRV] postProcessTerminate done\n"); // stronghold position? if (levels[0]->dimension->id == 0) { @@ -753,7 +775,7 @@ bool MinecraftServer::loadLevel(LevelStorageSource* storageSource, //- startTime); // printf("Lighting complete at %dms\n",System::currentTimeMillis() - - //startTime); + // startTime); if (s_bServerHalted || !g_NetworkManager.IsInSession()) return false; @@ -774,17 +796,13 @@ bool MinecraftServer::loadLevel(LevelStorageSource* storageSource, if (levels[0]->isNew) saveGameRules(); if (levels[0]->isNew) { - app.DebugPrintf("[SRV] Saving level 0...\n"); levels[0]->save(true, mcprogress); - app.DebugPrintf("[SRV] Level 0 saved\n"); } if (s_bServerHalted || !g_NetworkManager.IsInSession()) return false; if (levels[0]->isNew || levels[1]->isNew || levels[2]->isNew) { - app.DebugPrintf("[SRV] Saving to disc...\n"); levels[0]->saveToDisc(mcprogress, false); - app.DebugPrintf("[SRV] saveToDisc done\n"); } if (s_bServerHalted || !g_NetworkManager.IsInSession()) return false; @@ -802,7 +820,77 @@ bool MinecraftServer::loadLevel(LevelStorageSource* storageSource, return true; } -void MinecraftServer::setProgress(const std::wstring& status, int progress) { +#ifdef _LARGE_WORLDS +void MinecraftServer::overwriteBordersForNewWorldSize(ServerLevel* level) { + // recreate the chunks round the border (2 chunks or 32 blocks deep), + // deleting any player data from them + app.DebugPrintf("Expanding level size\n"); + int oldSize = level->getLevelData()->getXZSizeOld(); + // top + int minVal = -oldSize / 2; + int maxVal = (oldSize / 2) - 1; + for (int xVal = minVal; xVal <= maxVal; xVal++) { + int zVal = minVal; + level->cache->overwriteLevelChunkFromSource(xVal, zVal); + level->cache->overwriteLevelChunkFromSource(xVal, zVal + 1); + } + // bottom + for (int xVal = minVal; xVal <= maxVal; xVal++) { + int zVal = maxVal; + level->cache->overwriteLevelChunkFromSource(xVal, zVal); + level->cache->overwriteLevelChunkFromSource(xVal, zVal - 1); + } + // left + for (int zVal = minVal; zVal <= maxVal; zVal++) { + int xVal = minVal; + level->cache->overwriteLevelChunkFromSource(xVal, zVal); + level->cache->overwriteLevelChunkFromSource(xVal + 1, zVal); + } + // right + for (int zVal = minVal; zVal <= maxVal; zVal++) { + int xVal = maxVal; + level->cache->overwriteLevelChunkFromSource(xVal, zVal); + level->cache->overwriteLevelChunkFromSource(xVal - 1, zVal); + } +} + +void MinecraftServer::overwriteHellBordersForNewWorldSize(ServerLevel* level, + int oldHellSize) { + // recreate the chunks round the border (1 chunk or 16 blocks deep), + // deleting any player data from them + app.DebugPrintf("Expanding level size\n"); + // top + int minVal = -oldHellSize / 2; + int maxVal = (oldHellSize / 2) - 1; + for (int xVal = minVal; xVal <= maxVal; xVal++) { + int zVal = minVal; + level->cache->overwriteHellLevelChunkFromSource(xVal, zVal, minVal, + maxVal); + } + // bottom + for (int xVal = minVal; xVal <= maxVal; xVal++) { + int zVal = maxVal; + level->cache->overwriteHellLevelChunkFromSource(xVal, zVal, minVal, + maxVal); + } + // left + for (int zVal = minVal; zVal <= maxVal; zVal++) { + int xVal = minVal; + level->cache->overwriteHellLevelChunkFromSource(xVal, zVal, minVal, + maxVal); + } + // right + for (int zVal = minVal; zVal <= maxVal; zVal++) { + int xVal = maxVal; + level->cache->overwriteHellLevelChunkFromSource(xVal, zVal, minVal, + maxVal); + } +} + +#endif + +void MinecraftServer::setProgress(consstd::t std::wstring& status, + int progress) { progressStatus = status; this->progress = progress; // logger.info(status + ": " + progress + "%"); @@ -920,7 +1008,7 @@ void MinecraftServer::Suspend() { bool MinecraftServer::IsSuspending() { return m_suspending; } -void MinecraftServer::stopServer() { +void MinecraftServer::stopServer(bool didInit) { // 4J-PB - need to halt the rendering of the data, since we're about to // remove it #ifdef __PS3__ @@ -953,9 +1041,11 @@ void MinecraftServer::stopServer() { // Always save on exit! Except if saves are disabled. if (!saveOnExitAnswered()) m_saveOnExit = true; #endif - // if trial version or saving is disabled, then don't save anything + // if trial version or saving is disabled, then don't save anything. + // Also don't save anything if we didn't actually get through the server + // initialisation. if (m_saveOnExit && ProfileManager.IsFullVersion() && - (!StorageManager.GetSaveDisabled())) { + (!StorageManager.GetSaveDisabled()) && didInit) { if (players != NULL) { players->saveAll(Minecraft::GetInstance()->progressRenderer, true); @@ -1059,18 +1149,67 @@ void MinecraftServer::setFlightAllowed(bool allowFlight) { this->allowFlight = allowFlight; } +bool MinecraftServer::isCommandBlockEnabled() { + return false; // settings.getBoolean("enable-command-block", false); +} + bool MinecraftServer::isNetherEnabled() { return true; // settings.getBoolean("allow-nether", true); } bool MinecraftServer::isHardcore() { return false; } +int MinecraftServer::getOperatorUserPermissionLevel() { + return Command::LEVEL_OWNERS; // settings.getInt("op-permission-level", + // Command.LEVEL_OWNERS); +} + CommandDispatcher* MinecraftServer::getCommandDispatcher() { return commandDispatcher; } +Pos* MinecraftServer::getCommandSenderWorldPosition() { + return new Pos(0, 0, 0); +} + +Level* MinecraftServer::getCommandSenderWorld() { return levels[0]; } + +int MinecraftServer::getSpawnProtectionRadius() { return 16; } + +bool MinecraftServer::isUnderSpawnProtection(Level* level, int x, int y, + int zstd::, + std::shared_ptr player) { + if (level->dimension->id != 0) return false; + // if (getPlayers()->getOps()->empty()) return false; + if (getPlayers()->isOp(player->getName())) return false; + if (getSpawnProtectionRadius() <= 0) return false; + + Pos* spawnPos = level->getSharedSpawnPos(); + int xd = Mth::abs(x - spawnPos->x); + int zd = Mth::abs(z - spawnPos->z); + int dist = std::max(xd, zd); + + return dist <= getSpawnProtectionRadius(); +} + +void MinecraftServer::setForceGameType(bool forceGameType) { + this->forceGameType = forceGameType; +} + +bool MinecraftServer::getForceGameType() { return forceGameType; } + +int64_t MinecraftServer::getCurrentTimeMillis() { + return System::currentTimeMillis(); +} + +int MinecraftServer::getPlayerIdleTimeout() { return playerIdleTimeout; } + +void MinecraftServer::setPlayerIdleTimeout(int playerIdleTimeout) { + this->playerIdleTimeout = playerIdleTimeout; +} + extern int c0a, c0b, c1a, c1b, c1c, c2a, c2b; -void MinecraftServer::run(__int64 seed, void* lpParameter) { +void MinecraftServer::run(int64_t seed, void* lpParameter) { NetworkGameInitData* initData = NULL; std::uint32_t initSettings = 0; bool findSeed = false; @@ -1081,7 +1220,9 @@ void MinecraftServer::run(__int64 seed, void* lpParameter) { m_texturePackId = initData->texturePackId; } // try { // 4J - removed try/catch/finally + bool didInit = false; if (initServer(seed, initData, initSettings, findSeed)) { + didInit = true; ServerLevel* levelNormalDimension = levels[0]; // 4J-PB - Set the Stronghold position in the leveldata if there isn't // one in there @@ -1098,10 +1239,10 @@ void MinecraftServer::run(__int64 seed, void* lpParameter) { } } - __int64 lastTime = System::currentTimeMillis(); - __int64 unprocessedTime = 0; + int64_t lastTime = getCurrentTimeMillis(); + int64_t unprocessedTime = 0; while (running && !s_bServerHalted) { - __int64 now = System::currentTimeMillis(); + int64_t now = getCurrentTimeMillis(); // 4J Stu - When we pause the server, we don't want to count that as // time passed 4J Stu - TU-1 hotifx - Remove this line. We want to @@ -1110,7 +1251,7 @@ void MinecraftServer::run(__int64 seed, void* lpParameter) { // them that the connection to the server has been lost // if(m_isServerPaused) lastTime = now; - __int64 passedTime = now - lastTime; + int64_t passedTime = now - lastTime; if (passedTime > MS_PER_TICK * 40) { // logger.warning("Can't keep up! Did the system // time change, or is the server overloaded?"); @@ -1132,46 +1273,27 @@ void MinecraftServer::run(__int64 seed, void* lpParameter) { unprocessedTime = 0; } else { // int tickcount = 0; - // __int64 beforeall = - //System::currentTimeMillis(); + // int64_t beforeall = + // System::currentTimeMillis(); while (unprocessedTime > MS_PER_TICK) { unprocessedTime -= MS_PER_TICK; - // __int64 - //before = System::currentTimeMillis(); + chunkPacketManagement_PreTick(); + // int64_t + // before = System::currentTimeMillis(); tick(); - // __int64 - //after = System::currentTimeMillis(); + // int64_t + // after = System::currentTimeMillis(); // PIXReportCounter(L"Server - //time",(float)(after-before)); + // time",(float)(after-before)); - // 4J Ensure that the slow queue owner keeps cycling if - // it's not been used in a while - int time = GetTickCount(); - if ((s_slowQueuePacketSent) || - ((time - s_slowQueueLastTime) > - (2 * MINECRAFT_SERVER_SLOW_QUEUE_DELAY))) { - // app.DebugPrintf("Considering - //cycling: (%d) %d - %d -> %d > - //%d\n",s_slowQueuePacketSent, time, - //s_slowQueueLastTime, (time - s_slowQueueLastTime), - //(2*MINECRAFT_SERVER_SLOW_QUEUE_DELAY)); - MinecraftServer::cycleSlowQueueIndex(); - s_slowQueuePacketSent = false; - s_slowQueueLastTime = time; - } - // else - // { - // app.DebugPrintf("Not - //considering cycling: %d - %d -> %d > %d\n",time, - //s_slowQueueLastTime, (time - s_slowQueueLastTime), - //(2*MINECRAFT_SERVER_SLOW_QUEUE_DELAY)); - // } + chunkPacketManagement_PostTick(); } - // __int64 afterall = - //System::currentTimeMillis(); PIXReportCounter(L"Server - //time all",(float)(afterall-beforeall)); + // int64_t afterall = + // System::currentTimeMillis(); + // PIXReportCounter(L"Server time + // all",(float)(afterall-beforeall)); // PIXReportCounter(L"Server - //ticks",(float)tickcount); + // ticks",(float)tickcount); } } else { // 4J Stu - TU1-hotfix @@ -1190,12 +1312,11 @@ void MinecraftServer::run(__int64 seed, void* lpParameter) { MinecraftServer::setTimeAtEndOfTick = false; for (unsigned int i = 0; i < levels.length; i++) { // if (i == 0 || - //settings->getBoolean(L"allow-nether", true)) + // settings->getBoolean(L"allow-nether", true)) //// 4J removed - we always have nether { ServerLevel* level = levels[i]; - level->setTime(MinecraftServer::setTime); - level->setOverrideTimeOfDay(-1); + level->setGameTime(MinecraftServer::setTime); } } } @@ -1204,9 +1325,7 @@ void MinecraftServer::run(__int64 seed, void* lpParameter) { for (unsigned int i = 0; i < levels.length; i++) { if (i == 0 || settings->getBoolean(L"allow-nether", true)) { ServerLevel* level = levels[i]; - // level->setTime( MinecraftServer::setTime ); - level->setOverrideTimeOfDay( - MinecraftServer::setTimeOfDay); + level->setDayTime(MinecraftServer::setTimeOfDay); } } } @@ -1219,8 +1338,6 @@ void MinecraftServer::run(__int64 seed, void* lpParameter) { param = app.GetXuiServerActionParam(i); switch (eAction) { - case eXuiServerAction_Idle: - break; case eXuiServerAction_AutoSaveGame: #if defined(_XBOX_ONE) || defined(__ORBIS__) { @@ -1397,7 +1514,7 @@ void MinecraftServer::run(__int64 seed, void* lpParameter) { app.EnterSaveNotificationSection(); // players->broadcastAll( - // std::shared_ptr( new + // shared_ptr( new // UpdateProgressPacket(20) ) ); if (!s_bServerHalted) { @@ -1475,38 +1592,38 @@ void MinecraftServer::run(__int64 seed, void* lpParameter) { } // else //{ - // while (running) + // while (running) // { - // handleConsoleInputs(); + // handleConsoleInputs(); // Sleep(10); - // } - //} + // } + // } #if 0 +} catch (Throwable t) { + t.printStackTrace(); + logger.log(Level.SEVERE, "Unexpected exception", t); + while (running) { + handleConsoleInputs(); + try { + Thread.sleep(10); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } + } +} finally { + try { + stopServer(); + stopped = true; } catch (Throwable t) { - t.printStackTrace(); - logger.log(Level.SEVERE, "Unexpected exception", t); - while (running) { - handleConsoleInputs(); - try { - Thread.sleep(10); - } catch (InterruptedException e1) { - e1.printStackTrace(); - } - } - } finally { - try { - stopServer(); - stopped = true; - } catch (Throwable t) { - t.printStackTrace(); - } finally { - System::exit(0); - } - } + t.printStackTrace(); + } finally { + System::exit(0); + } +} #endif // 4J Stu - Stop the server when the loops complete, as the finally would do - stopServer(); + stopServer(didInit); stopped = true; } @@ -1547,14 +1664,12 @@ void MinecraftServer::tick() { Minecraft* pMinecraft = Minecraft::GetInstance(); // 4J-PB - sending this on the host changing the difficulty in the menus /* if(m_lastSentDifficulty != pMinecraft->options->difficulty) - { - m_lastSentDifficulty = pMinecraft->options->difficulty; - players->broadcastAll( - std::shared_ptr( new - ServerSettingsChangedPacket( - ServerSettingsChangedPacket::HOST_DIFFICULTY, - pMinecraft->options->difficulty) ) ); - }*/ + { + m_lastSentDifficulty = pMinecraft->options->difficulty; + players->broadcastAll( shared_ptr( new + ServerSettingsChangedPacket( ServerSettingsChangedPacket::HOST_DIFFICULTY, + pMinecraft->options->difficulty) ) ); + }*/ for (unsigned int i = 0; i < levels.length; i++) { // if (i == 0 || settings->getBoolean(L"allow-nether", true)) @@ -1576,26 +1691,23 @@ void MinecraftServer::tick() { #endif if (tickCount % 20 == 0) { - players->broadcastAll(std::shared_ptr( - new SetTimePacket(level->getTime())), - level->dimension->id); + players->broadcastAll( + std::shared_ptr(new SetTimePacket( + level->getGameTime(), level->getDayTime(), + level->getGameRules()->getBoolean( + GameRules::RULE_DAYLIGHT))), + level->dimension->id); } // #ifndef __PS3__ - static __int64 stc = 0; - __int64 st0 = System::currentTimeMillis(); + static int64_t stc = 0; + int64_t st0 = System::currentTimeMillis(); PIXBeginNamedEvent(0, "Level tick %d", i); ((Level*)level)->tick(); - __int64 st1 = System::currentTimeMillis(); + int64_t st1 = System::currentTimeMillis(); PIXEndNamedEvent(); PIXBeginNamedEvent(0, "Update lights %d", i); - // 4J - used to be in a while loop, but we don't want the server - // locking up for a big chunk of time (could end up trying to - // process 1,000,000 lights...) Instead call this once, which will - // try and process up to 2000 lights per tick - // printf("lights: - //%d\n",level->getLightsToUpdate()); - while (level->updateLights()); - __int64 st2 = System::currentTimeMillis(); + + int64_t st2 = System::currentTimeMillis(); PIXEndNamedEvent(); PIXBeginNamedEvent(0, "Entity tick %d", i); // 4J added to stop ticking entities in levels when players are not @@ -1633,7 +1745,7 @@ void MinecraftServer::tick() { level->getTracker()->tick(); PIXEndNamedEvent(); - __int64 st3 = System::currentTimeMillis(); + int64_t st3 = System::currentTimeMillis(); // printf(">>>>>>>>>>>>>>>>>>>>>> Tick %d %d %d : //%d\n", st1 - st0, st2 - st1, st3 - st2, st0 - stc ); stc = st0; @@ -1651,9 +1763,9 @@ void MinecraftServer::tick() { // 4J - removed #if 0 - for (int i = 0; i < tickables.size(); i++) { - tickables.get(i)-tick(); - } + for (int i = 0; i < tickables.size(); i++) { + tickables.get(i)-tick(); + } #endif // try { // 4J - removed try/catch @@ -1664,7 +1776,7 @@ void MinecraftServer::tick() { // } } -void MinecraftServer::handleConsoleInput(const std::wstring& msg, +void MinecraftServer::handleConsoleInput(consstd::t std::wstring& msg, ConsoleInputSource* source) { consoleInput.push_back(new ConsoleInput(msg, source)); } @@ -1679,7 +1791,7 @@ void MinecraftServer::handleConsoleInputs() { } } -void MinecraftServer::main(__int64 seed, void* lpParameter) { +void MinecraftServer::main(int64_t seed, void* lpParameter) { #if __PS3__ ShutdownManager::HasStarted(ShutdownManager::eServerThread); #endif @@ -1704,9 +1816,13 @@ File* MinecraftServer::getFile(const std::wstring& name) { void MinecraftServer::info(const std::wstring& string) {} -void MinecraftServer::warn(const std::wstring& string) {} +void MinecraftServer::warn(consstd::t std::wstring& std::string) {} +std:: -std::wstring MinecraftServer::getConsoleName() { return L"CONSOLE"; } + std::wstring + MinecraftServer::getConsoleName() { + return L"CONSOLE"; +} ServerLevel* MinecraftServer::getLevel(int dimension) { if (dimension == -1) @@ -1727,21 +1843,121 @@ void MinecraftServer::setLevel(int dimension, ServerLevel* level) { levels[0] = level; } +#if defined _ACK_CHUNK_SEND_THROTTLING +bool MinecraftServer::chunkPacketManagement_CanSendTo(INetworkPlayer* player) { + if (s_hasSentEnoughPackets) return false; + if (player == NULL) return false; + + for (int i = 0; i < s_sentTo.size(); i++) { + if (s_sentTo[i]->IsSameSystem(player)) { + return false; + } + } + +#if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__) + return (player->GetOutstandingAckCount() < 3); +#else + return (player->GetOutstandingAckCount() < 2); +#endif +} + +void MinecraftServer::chunkPacketManagement_DidSendTo(INetworkPlayer* player) { + int64_t currentTime = System::currentTimeMillis(); + + if ((currentTime - s_tickStartTime) >= MAX_TICK_TIME_FOR_PACKET_SENDS) { + s_hasSentEnoughPackets = true; + // app.DebugPrintf("Sending, setting enough packet flag: + //%dms\n",currentTime - s_tickStartTime); + } else { + // app.DebugPrintf("Sending, more time: %dms\n",currentTime + //- s_tickStartTime); + } + + player->SentChunkPacket(); + + s_sentTo.push_back(player); +} + +void MinecraftServer::chunkPacketManagement_PreTick() { + // app.DebugPrintf("*************************************************************************************************************************************************************************\n"); + s_hasSentEnoughPackets = false; + s_tickStartTime = System::currentTimeMillis(); + s_sentTo.clear(); + + std::vector >* players = + connection->getPlayers(); + + if (players->size()) { + std::vector > playersOrig = *players; + players->clear(); + + do { + int longestTime = 0; + AUTO_VAR(playerConnectionBest, playersOrig.begin()); + for (AUTO_VAR(it, playersOrig.begin()); it != playersOrig.end(); + it++) { + int thisTime = 0; + INetworkPlayer* np = (*it)->getNetworkPlayer(); + if (np) { + thisTime = np->GetTimeSinceLastChunkPacket_ms(); + } + + if (thisTime > longestTime) { + playerConnectionBest = it; + longestTime = thisTime; + } + } + players->push_back(*playerConnectionBest); + playersOrig.erase(playerConnectionBest); + } while (playersOrig.size() > 0); + } +} + +void MinecraftServer::chunkPacketManagement_PostTick() {} + +#else // 4J Added -bool MinecraftServer::canSendOnSlowQueue(INetworkPlayer* player) { +bool MinecraftServer::chunkPacketManagement_CanSendTo(INetworkPlayer* player) { if (player == NULL) return false; int time = GetTickCount(); if (player->GetSessionIndex() == s_slowQueuePlayerIndex && (time - s_slowQueueLastTime) > MINECRAFT_SERVER_SLOW_QUEUE_DELAY) { // app.DebugPrintf("Slow queue OK for player #%d\n", - //player->GetSessionIndex()); + // player->GetSessionIndex()); return true; } return false; } +void MinecraftServer::chunkPacketManagement_DidSendTo(INetworkPlayer* player) { + s_slowQueuePacketSent = true; +} + +void MinecraftServer::chunkPacketManagement_PreTick() {} + +void MinecraftServer::chunkPacketManagement_PostTick() { + // 4J Ensure that the slow queue owner keeps cycling if it's not been used + // in a while + int time = GetTickCount(); + if ((s_slowQueuePacketSent) || ((time - s_slowQueueLastTime) > + (2 * MINECRAFT_SERVER_SLOW_QUEUE_DELAY))) { + // app.DebugPrintf("Considering cycling: (%d) %d - %d -> %d + //> %d\n",s_slowQueuePacketSent, time, s_slowQueueLastTime, (time - + // s_slowQueueLastTime), (2*MINECRAFT_SERVER_SLOW_QUEUE_DELAY)); + MinecraftServer::cycleSlowQueueIndex(); + s_slowQueuePacketSent = false; + s_slowQueueLastTime = time; + } + // else + // { + // app.DebugPrintf("Not considering cycling: %d - %d -> %d > + //%d\n",time, s_slowQueueLastTime, (time - s_slowQueueLastTime), + //(2*MINECRAFT_SERVER_SLOW_QUEUE_DELAY)); + // } +} + void MinecraftServer::cycleSlowQueueIndex() { if (!g_NetworkManager.IsInSession()) return; @@ -1768,8 +1984,9 @@ void MinecraftServer::cycleSlowQueueIndex() { s_slowQueuePlayerIndex != startingIndex && currentPlayer != NULL && currentPlayer->IsLocal()); // app.DebugPrintf("Cycled slow queue index to %d\n", - //s_slowQueuePlayerIndex); + // s_slowQueuePlayerIndex); } +#endif // 4J added - sets up a vector of flags to indicate which entities (with small // Ids) have been removed from the level, but are still haven't constructed a diff --git a/Minecraft.Client/MinecraftServer.h b/Minecraft.Client/MinecraftServer.h index 597b3bab7..6b2b5a809 100644 --- a/Minecraft.Client/MinecraftServer.h +++ b/Minecraft.Client/MinecraftServer.h @@ -22,6 +22,11 @@ class CommandDispatcher; #define MINECRAFT_SERVER_SLOW_QUEUE_DELAY 250 +#if defined _XBOX_ONE || defined _XBOX || defined __ORBIS__ || \ + defined __PS3__ || defined __PSVITA__ +#define _ACK_CHUNK_SEND_THROTTLING +#endif + typedef struct _LoadSaveDataThreadParam { void* data; __int64 fileSize; @@ -32,7 +37,7 @@ typedef struct _LoadSaveDataThreadParam { } LoadSaveDataThreadParam; typedef struct _NetworkGameInitData { - __int64 seed; + int64_t seed; LoadSaveDataThreadParam* saveData; std::uint32_t settings; LevelGenerationOptions* levelGen; @@ -99,7 +104,7 @@ public: private: // std::vector tickables = new ArrayList(); // 4J - - //removed + // removed CommandDispatcher* commandDispatcher; std::vector consoleInput; // 4J - was synchronizedList - TODO - investigate @@ -111,6 +116,8 @@ public: bool allowFlight; std::wstring motd; int maxBuildHeight; + int playerIdleTimeout; + bool forceGameType; private: // 4J Added @@ -142,8 +149,13 @@ private: void endProgress(); void saveAllChunks(); void saveGameRules(); - void stopServer(); + void stopServer(bool didInit); +#ifdef _LARGE_WORLDS + void overwriteBordersForNewWorldSize(ServerLevel* level); + void overwriteHellBordersForNewWorldSize(ServerLevel* level, + int oldHellSize); +#endif public: void setMaxBuildHeight(int maxBuildHeight); int getMaxBuildHeight(); @@ -158,9 +170,21 @@ public: void setPvpAllowed(bool pvp); bool isFlightAllowed(); void setFlightAllowed(bool allowFlight); + bool isCommandBlockEnabled(); bool isNetherEnabled(); bool isHardcore(); + int getOperatorUserPermissionLevel(); CommandDispatcher* getCommandDispatcher(); + Pos* getCommandSenderWorldPosition(); + Level* getCommandSenderWorld(); + int getSpawnProtectionRadius(); + bool isUnderSpawnProtection(Level* level, int x, int y, int z, + std::shared_ptr player); + void setForceGameType(bool forceGameType); + bool getForceGameType(); + static int64_t getCurrentTimeMillis(); + int getPlayerIdleTimeout(); + void setPlayerIdleTimeout(int playerIdleTimeout); public: void halt(); @@ -177,7 +201,7 @@ public: ConsoleInputSource* source); void handleConsoleInputs(); // void addTickable(Tickable tickable); // 4J removed - static void main(__int64 seed, void* lpParameter); + static void main(int64_t seed, void* lpParameter); static void HaltServer(bool bPrimaryPlayerSignedOut = false); File* getFile(const std::wstring& name); @@ -200,9 +224,9 @@ private: static MinecraftServer* server; static bool setTimeOfDayAtEndOfTick; - static __int64 setTimeOfDay; + static int64_t setTimeOfDay; static bool setTimeAtEndOfTick; - static __int64 setTime; + static int64_t setTime; static bool m_bPrimaryPlayerSignedOut; // 4J-PB added to tell the stopserver not to @@ -239,11 +263,11 @@ public: else return NULL; } - static void SetTimeOfDay(__int64 time) { + static void SetTimeOfDay(int64_t time) { setTimeOfDayAtEndOfTick = true; setTimeOfDay = time; } - static void SetTime(__int64 time) { + static void SetTime(int64_t time) { setTimeAtEndOfTick = true; setTime = time; } @@ -256,11 +280,16 @@ private: // 4J Added - A static that stores the QNet index of the player that is next // allowed to send a packet in the slow queue +#ifdef _ACK_CHUNK_SEND_THROTTLING + static bool s_hasSentEnoughPackets; + static int64_t s_tickStartTime; + static std::vector s_sentTo; + static const int MAX_TICK_TIME_FOR_PACKET_SENDS = 35; +#else static int s_slowQueuePlayerIndex; static int s_slowQueueLastTime; - -public: static bool s_slowQueuePacketSent; +#endif bool IsServerPaused() { return m_isServerPaused; } @@ -270,9 +299,14 @@ private: bool m_suspending; public: - // static int getSlowQueueIndex() { return s_slowQueuePlayerIndex; } - static bool canSendOnSlowQueue(INetworkPlayer* player); + static bool chunkPacketManagement_CanSendTo(INetworkPlayer* player); + static void chunkPacketManagement_DidSendTo(INetworkPlayer* player); +#ifndef _ACK_CHUNK_SEND_THROTTLING static void cycleSlowQueueIndex(); +#endif + + void chunkPacketManagement_PreTick(); + void chunkPacketManagement_PostTick(); void setSaveOnExit(bool save) { m_saveOnExit = save;