From ca6ef58b1ee8521e4b940ee4883dee714960e413 Mon Sep 17 00:00:00 2001 From: LogicParrot Date: Fri, 5 Feb 2016 23:45:45 +0200 Subject: Bulk clearing of whitespace --- src/AllocationPool.h | 20 +- src/Bindings/LuaChunkStay.cpp | 22 +- src/Bindings/LuaChunkStay.h | 20 +- src/Bindings/LuaState.cpp | 102 ++++---- src/Bindings/LuaState.h | 98 ++++---- src/Bindings/LuaWindow.cpp | 18 +- src/Bindings/LuaWindow.h | 30 +-- src/Bindings/ManualBindings.cpp | 224 ++++++++--------- src/Bindings/ManualBindings.h | 2 +- src/Bindings/ManualBindings_Network.cpp | 44 ++-- src/Bindings/ManualBindings_RankManager.cpp | 264 ++++++++++----------- src/Bindings/ManualBindings_World.cpp | 22 +- src/Bindings/Plugin.h | 16 +- src/Bindings/PluginLua.cpp | 34 +-- src/Bindings/PluginLua.h | 46 ++-- src/Bindings/PluginManager.cpp | 6 +- src/Bindings/PluginManager.h | 56 ++--- src/Bindings/WebPlugin.h | 2 +- src/BiomeDef.cpp | 10 +- src/BiomeDef.h | 8 +- src/BlockArea.cpp | 76 +++--- src/BlockArea.h | 128 +++++----- src/BlockEntities/BlockEntity.h | 32 +-- src/BlockEntities/BlockEntityWithItems.h | 16 +- src/BlockEntities/ChestEntity.h | 12 +- src/BlockEntities/CommandBlockEntity.cpp | 4 +- src/BlockEntities/CommandBlockEntity.h | 12 +- src/BlockEntities/DispenserEntity.h | 6 +- src/BlockEntities/DropSpenserEntity.cpp | 12 +- src/BlockEntities/DropSpenserEntity.h | 20 +- src/BlockEntities/DropperEntity.h | 8 +- src/BlockEntities/EnderChestEntity.h | 8 +- src/BlockEntities/FlowerPotEntity.h | 18 +- src/BlockEntities/FurnaceEntity.cpp | 2 +- src/BlockEntities/FurnaceEntity.h | 70 +++--- src/BlockEntities/HopperEntity.h | 28 +-- src/BlockEntities/JukeboxEntity.h | 16 +- src/BlockEntities/MobHeadEntity.h | 22 +- src/BlockEntities/MobSpawnerEntity.h | 2 +- src/BlockEntities/NoteEntity.cpp | 8 +- src/BlockEntities/NoteEntity.h | 8 +- src/BlockEntities/SignEntity.h | 14 +- src/BlockID.cpp | 40 ++-- src/BlockID.h | 84 +++---- src/BlockInfo.h | 2 +- src/BlockTracer.h | 28 +-- src/Blocks/BlockAnvil.h | 4 +- src/Blocks/BlockBed.h | 4 +- src/Blocks/BlockBigFlower.h | 6 +- src/Blocks/BlockButton.h | 8 +- src/Blocks/BlockCake.h | 4 +- src/Blocks/BlockCarpet.h | 4 +- src/Blocks/BlockChest.h | 16 +- src/Blocks/BlockComparator.h | 4 +- src/Blocks/BlockCrops.h | 2 +- src/Blocks/BlockDirt.h | 12 +- src/Blocks/BlockDoor.cpp | 4 +- src/Blocks/BlockDoor.h | 6 +- src/Blocks/BlockDropSpenser.h | 4 +- src/Blocks/BlockEnderchest.h | 2 +- src/Blocks/BlockEntity.h | 4 +- src/Blocks/BlockFenceGate.h | 2 +- src/Blocks/BlockFire.h | 2 +- src/Blocks/BlockFluid.h | 16 +- src/Blocks/BlockFurnace.h | 6 +- src/Blocks/BlockHandler.cpp | 10 +- src/Blocks/BlockHandler.h | 42 ++-- src/Blocks/BlockHopper.h | 2 +- src/Blocks/BlockIce.h | 4 +- src/Blocks/BlockLadder.h | 2 +- src/Blocks/BlockLeaves.h | 4 +- src/Blocks/BlockLever.h | 8 +- src/Blocks/BlockMelon.h | 2 +- src/Blocks/BlockMobHead.h | 4 +- src/Blocks/BlockMobSpawner.h | 4 +- src/Blocks/BlockMushroom.h | 4 +- src/Blocks/BlockPiston.h | 10 +- src/Blocks/BlockPlanks.h | 2 +- src/Blocks/BlockPluginInterface.h | 2 +- src/Blocks/BlockPortal.h | 2 +- src/Blocks/BlockPumpkin.h | 4 +- src/Blocks/BlockRail.h | 30 +-- src/Blocks/BlockRedstone.h | 2 +- src/Blocks/BlockRedstoneLamp.h | 2 +- src/Blocks/BlockRedstoneRepeater.h | 2 +- src/Blocks/BlockSapling.h | 6 +- src/Blocks/BlockSideways.h | 2 +- src/Blocks/BlockSignPost.h | 6 +- src/Blocks/BlockSlab.h | 10 +- src/Blocks/BlockSlime.h | 2 +- src/Blocks/BlockSnow.h | 8 +- src/Blocks/BlockStems.h | 2 +- src/Blocks/BlockSugarcane.h | 2 +- src/Blocks/BlockTorch.h | 4 +- src/Blocks/BlockTrapdoor.h | 2 +- src/Blocks/BlockVine.h | 8 +- src/Blocks/BlockWorkbench.h | 2 +- src/Blocks/BroadcastInterface.h | 2 +- src/Blocks/ChunkInterface.h | 16 +- src/Blocks/ClearMetaOnDrop.h | 2 +- src/Blocks/MetaRotator.h | 2 +- src/Blocks/WorldInterface.h | 14 +- src/ByteBuffer.cpp | 28 +-- src/ByteBuffer.h | 36 +-- src/ChatColor.h | 2 +- src/ChunkData.cpp | 34 +-- src/ChunkData.h | 16 +- src/ChunkDataCallback.h | 12 +- src/ChunkDef.h | 2 +- src/ChunkMap.cpp | 96 ++++---- src/ChunkMap.h | 134 +++++------ src/ChunkSender.h | 22 +- src/ChunkStay.cpp | 6 +- src/ChunkStay.h | 30 +-- src/ClientHandle.h | 108 ++++----- src/CommandOutput.cpp | 2 +- src/CommandOutput.h | 8 +- src/CompositeChat.cpp | 34 +-- src/CompositeChat.h | 78 +++--- src/CraftingRecipes.cpp | 56 ++--- src/CraftingRecipes.h | 50 ++-- src/Cuboid.cpp | 8 +- src/Cuboid.h | 22 +- src/DeadlockDetect.cpp | 12 +- src/DeadlockDetect.h | 24 +- src/Enchantments.cpp | 4 +- src/Enchantments.h | 34 +-- src/Entities/ArrowEntity.h | 46 ++-- src/Entities/Boat.cpp | 8 +- src/Entities/Boat.h | 6 +- src/Entities/EnderCrystal.cpp | 2 +- src/Entities/EntityEffect.cpp | 50 ++-- src/Entities/EntityEffect.h | 72 +++--- src/Entities/ExpBottleEntity.h | 14 +- src/Entities/ExpOrb.cpp | 6 +- src/Entities/ExpOrb.h | 4 +- src/Entities/FallingBlock.cpp | 10 +- src/Entities/FallingBlock.h | 6 +- src/Entities/FireChargeEntity.h | 16 +- src/Entities/FireworkEntity.cpp | 10 +- src/Entities/FireworkEntity.h | 18 +- src/Entities/Floater.cpp | 8 +- src/Entities/Floater.h | 4 +- src/Entities/GhastFireballEntity.h | 18 +- src/Entities/HangingEntity.h | 2 +- src/Entities/Minecart.cpp | 20 +- src/Entities/Minecart.h | 38 +-- src/Entities/Pickup.cpp | 8 +- src/Entities/SplashPotionEntity.cpp | 8 +- src/Entities/SplashPotionEntity.h | 22 +- src/Entities/TNTEntity.cpp | 2 +- src/Entities/TNTEntity.h | 16 +- src/Entities/ThrownEggEntity.h | 16 +- src/Entities/ThrownEnderPearlEntity.cpp | 6 +- src/Entities/ThrownEnderPearlEntity.h | 16 +- src/Entities/ThrownSnowballEntity.h | 14 +- src/Entities/WitherSkullEntity.cpp | 4 +- src/Entities/WitherSkullEntity.h | 14 +- src/FastRandom.h | 4 +- src/ForEachChunkProvider.h | 4 +- src/FurnaceRecipe.cpp | 4 +- src/FurnaceRecipe.h | 4 +- src/Generating/BioGen.cpp | 52 ++-- src/Generating/BioGen.h | 72 +++--- src/Generating/Caves.h | 10 +- src/Generating/ChunkDesc.cpp | 4 +- src/Generating/ChunkDesc.h | 40 ++-- src/Generating/ChunkGenerator.cpp | 2 +- src/Generating/ChunkGenerator.h | 46 ++-- src/Generating/CompoGen.cpp | 38 +-- src/Generating/CompoGen.h | 28 +-- src/Generating/CompoGenBiomal.cpp | 36 +-- src/Generating/ComposableGenerator.cpp | 20 +- src/Generating/ComposableGenerator.h | 32 +-- src/Generating/DistortedHeightmap.cpp | 10 +- src/Generating/DistortedHeightmap.h | 26 +- src/Generating/EndGen.h | 14 +- src/Generating/FinishGen.cpp | 8 +- src/Generating/FinishGen.h | 2 +- src/Generating/GridStructGen.cpp | 4 +- src/Generating/GridStructGen.h | 42 ++-- src/Generating/HeiGen.cpp | 48 ++-- src/Generating/HeiGen.h | 26 +- src/Generating/MineShafts.cpp | 2 +- src/Generating/MineShafts.h | 6 +- src/Generating/Noise3DGenerator.h | 36 +-- src/Generating/PieceGenerator.cpp | 28 +-- src/Generating/PieceGenerator.h | 62 ++--- src/Generating/PieceStructuresGen.h | 2 +- src/Generating/Prefab.cpp | 44 ++-- src/Generating/Prefab.h | 82 +++---- src/Generating/PrefabPiecePool.h | 20 +- src/Generating/Ravines.cpp | 38 +-- src/Generating/Ravines.h | 6 +- src/Generating/RoughRavines.cpp | 44 ++-- src/Generating/RoughRavines.h | 26 +- src/Generating/ShapeGen.cpp | 6 +- src/Generating/StructGen.cpp | 54 ++--- src/Generating/StructGen.h | 18 +- src/Generating/Trees.cpp | 98 ++++---- src/Generating/VillageGen.cpp | 70 +++--- src/Generating/VillageGen.h | 10 +- src/Globals.h | 12 +- src/HTTPServer/EnvelopeParser.cpp | 14 +- src/HTTPServer/EnvelopeParser.h | 26 +- src/HTTPServer/HTTPConnection.cpp | 10 +- src/HTTPServer/HTTPConnection.h | 36 +-- src/HTTPServer/HTTPFormParser.cpp | 6 +- src/HTTPServer/HTTPFormParser.h | 42 ++-- src/HTTPServer/HTTPMessage.cpp | 10 +- src/HTTPServer/HTTPMessage.h | 66 +++--- src/HTTPServer/HTTPServer.cpp | 32 +-- src/HTTPServer/HTTPServer.h | 30 +-- src/HTTPServer/MultipartParser.cpp | 28 +-- src/HTTPServer/MultipartParser.h | 32 +-- src/HTTPServer/NameValueParser.cpp | 30 +-- src/HTTPServer/NameValueParser.h | 24 +- src/HTTPServer/SslHTTPConnection.cpp | 8 +- src/HTTPServer/SslHTTPConnection.h | 10 +- src/IniFile.cpp | 6 +- src/IniFile.h | 34 +-- src/Inventory.cpp | 32 +-- src/Inventory.h | 50 ++-- src/Item.h | 56 ++--- src/ItemGrid.cpp | 26 +- src/ItemGrid.h | 68 +++--- src/Items/ItemArmor.h | 6 +- src/Items/ItemBed.h | 2 +- src/Items/ItemBoat.h | 16 +- src/Items/ItemBow.h | 14 +- src/Items/ItemBucket.h | 24 +- src/Items/ItemChest.h | 6 +- src/Items/ItemEmptyMap.h | 2 +- src/Items/ItemFishingRod.h | 2 +- src/Items/ItemFood.h | 2 +- src/Items/ItemGoldenApple.h | 2 +- src/Items/ItemHandler.cpp | 44 ++-- src/Items/ItemHandler.h | 22 +- src/Items/ItemLeaves.h | 2 +- src/Items/ItemLighter.h | 2 +- src/Items/ItemMap.h | 2 +- src/Items/ItemMilk.h | 4 +- src/Items/ItemMinecart.h | 12 +- src/Items/ItemMobHead.h | 6 +- src/Items/ItemNetherWart.h | 2 +- src/Items/ItemPickaxe.h | 8 +- src/Items/ItemPotion.h | 24 +- src/Items/ItemSeeds.h | 6 +- src/Items/ItemShears.h | 8 +- src/Items/ItemShovel.h | 2 +- src/Items/ItemSign.h | 2 +- src/Items/ItemSpawnEgg.h | 6 +- src/Items/ItemSword.h | 2 +- src/Items/ItemThrowable.h | 8 +- src/LightingThread.cpp | 60 ++--- src/LightingThread.h | 60 ++--- src/LineBlockTracer.cpp | 10 +- src/LineBlockTracer.h | 26 +- src/LinearInterpolation.cpp | 20 +- src/Logger.h | 2 +- src/LoggerListeners.cpp | 36 +-- src/Map.cpp | 2 +- src/Matrix4.h | 4 +- src/MemoryLeak.h | 2 +- src/MemorySettingsRepository.h | 2 +- src/MobCensus.h | 6 +- src/Mobs/Bat.h | 4 +- src/Mobs/Blaze.h | 4 +- src/Mobs/CaveSpider.h | 2 +- src/Mobs/Chicken.h | 2 +- src/Mobs/Cow.h | 2 +- src/Mobs/Creeper.h | 2 +- src/Mobs/EnderDragon.h | 4 +- src/Mobs/Ghast.h | 2 +- src/Mobs/Giant.h | 4 +- src/Mobs/Guardian.h | 4 +- src/Mobs/IronGolem.h | 4 +- src/Mobs/MagmaCube.h | 4 +- src/Mobs/MonsterTypes.h | 2 +- src/Mobs/Mooshroom.h | 2 +- src/Mobs/Ocelot.h | 2 +- src/Mobs/Pig.h | 4 +- src/Mobs/Rabbit.h | 2 +- src/Mobs/Sheep.h | 2 +- src/Mobs/Silverfish.h | 2 +- src/Mobs/Slime.cpp | 2 +- src/Mobs/Slime.h | 6 +- src/Mobs/Squid.h | 4 +- src/Mobs/Villager.h | 2 +- src/Mobs/Witch.h | 2 +- src/Mobs/Wither.h | 6 +- src/Mobs/ZombiePigman.cpp | 2 +- src/Mobs/ZombiePigman.h | 4 +- src/MonsterConfig.cpp | 4 +- src/MonsterConfig.h | 4 +- src/Noise/InterpolNoise.h | 26 +- src/Noise/Noise.cpp | 54 ++--- src/Noise/OctavedNoise.h | 2 +- src/OSSupport/CriticalSection.cpp | 4 +- src/OSSupport/CriticalSection.h | 12 +- src/OSSupport/Errors.cpp | 18 +- src/OSSupport/Event.h | 2 +- src/OSSupport/File.cpp | 42 ++-- src/OSSupport/File.h | 50 ++-- src/OSSupport/GZipFile.cpp | 4 +- src/OSSupport/GZipFile.h | 14 +- src/OSSupport/IsThread.h | 2 +- src/OSSupport/Queue.h | 12 +- src/OSSupport/TCPLinkImpl.cpp | 2 +- src/OverridesSettingsRepository.cpp | 4 +- src/OverridesSettingsRepository.h | 2 +- src/PolarSSL++/AesCfb128Decryptor.cpp | 4 +- src/PolarSSL++/AesCfb128Decryptor.h | 16 +- src/PolarSSL++/AesCfb128Encryptor.cpp | 4 +- src/PolarSSL++/AesCfb128Encryptor.h | 14 +- src/PolarSSL++/BlockingSslClientSocket.cpp | 18 +- src/PolarSSL++/BlockingSslClientSocket.h | 28 +-- src/PolarSSL++/BufferedSslContext.h | 12 +- src/PolarSSL++/CallbackSslContext.h | 12 +- src/PolarSSL++/CryptoKey.cpp | 8 +- src/PolarSSL++/CryptoKey.h | 22 +- src/PolarSSL++/CtrDrbgContext.cpp | 2 +- src/PolarSSL++/CtrDrbgContext.h | 12 +- src/PolarSSL++/EntropyContext.h | 2 +- src/PolarSSL++/RsaPrivateKey.cpp | 8 +- src/PolarSSL++/RsaPrivateKey.h | 20 +- src/PolarSSL++/Sha1Checksum.cpp | 6 +- src/PolarSSL++/Sha1Checksum.h | 16 +- src/PolarSSL++/SslContext.cpp | 36 +-- src/PolarSSL++/SslContext.h | 52 ++-- src/PolarSSL++/X509Cert.h | 6 +- src/ProbabDistrib.cpp | 8 +- src/ProbabDistrib.h | 20 +- src/Protocol/Authenticator.cpp | 2 +- src/Protocol/Authenticator.h | 6 +- src/Protocol/ChunkDataSerializer.cpp | 20 +- src/Protocol/ChunkDataSerializer.h | 10 +- src/Protocol/MojangAPI.h | 54 ++--- src/Protocol/Protocol.h | 8 +- src/Protocol/Protocol17x.cpp | 222 ++++++++--------- src/Protocol/Protocol17x.h | 36 +-- src/Protocol/Protocol18x.cpp | 160 ++++++------- src/Protocol/Protocol18x.h | 34 +-- src/Protocol/ProtocolRecognizer.cpp | 2 +- src/Protocol/ProtocolRecognizer.h | 14 +- src/RCONServer.cpp | 28 +-- src/RCONServer.h | 36 +-- src/RankManager.cpp | 254 ++++++++++---------- src/RankManager.h | 104 ++++---- src/Scoreboard.cpp | 4 +- src/Server.h | 80 +++---- src/SetChunkData.cpp | 8 +- src/SetChunkData.h | 32 +-- src/SettingsRepositoryInterface.h | 2 +- src/Simulator/DelayedFluidSimulator.cpp | 10 +- src/Simulator/DelayedFluidSimulator.h | 16 +- src/Simulator/FireSimulator.cpp | 22 +- src/Simulator/FireSimulator.h | 14 +- src/Simulator/FloodyFluidSimulator.cpp | 18 +- src/Simulator/FloodyFluidSimulator.h | 10 +- src/Simulator/FluidSimulator.cpp | 6 +- src/Simulator/FluidSimulator.h | 16 +- .../IncrementalRedstoneSimulator.h | 4 +- .../TripwireHookHandler.h | 2 +- src/Simulator/NoopFluidSimulator.h | 2 +- src/Simulator/NoopRedstoneSimulator.h | 2 +- src/Simulator/SandSimulator.cpp | 10 +- src/Simulator/SandSimulator.h | 16 +- src/Simulator/Simulator.h | 6 +- src/Simulator/SimulatorManager.h | 6 +- src/Simulator/VanillaFluidSimulator.h | 4 +- src/Simulator/VaporizeFluidSimulator.h | 2 +- src/SpawnPrepare.cpp | 2 +- src/SpawnPrepare.h | 2 +- src/StringCompression.cpp | 26 +- src/Tracer.cpp | 10 +- src/Tracer.h | 2 +- src/UI/BeaconWindow.h | 2 +- src/UI/ChestWindow.h | 2 +- src/UI/InventoryWindow.h | 2 +- src/UI/SlotArea.cpp | 56 ++--- src/UI/SlotArea.h | 78 +++--- src/UI/Window.cpp | 42 ++-- src/UI/Window.h | 64 ++--- src/Vector3.h | 8 +- src/VoronoiMap.cpp | 8 +- src/VoronoiMap.h | 18 +- src/WebAdmin.cpp | 6 +- src/WebAdmin.h | 6 +- src/World.h | 254 ++++++++++---------- src/WorldStorage/EnchantmentSerializer.cpp | 14 +- src/WorldStorage/EnchantmentSerializer.h | 4 +- src/WorldStorage/FastNBT.cpp | 44 ++-- src/WorldStorage/FastNBT.h | 70 +++--- src/WorldStorage/MapSerializer.cpp | 6 +- src/WorldStorage/NBTChunkSerializer.cpp | 16 +- src/WorldStorage/NBTChunkSerializer.h | 18 +- src/WorldStorage/SchematicFileSerializer.cpp | 28 +-- src/WorldStorage/SchematicFileSerializer.h | 10 +- src/WorldStorage/ScoreboardSerializer.cpp | 8 +- src/WorldStorage/WSSAnvil.cpp | 240 +++++++++---------- src/WorldStorage/WSSAnvil.h | 70 +++--- src/WorldStorage/WorldStorage.cpp | 26 +- src/WorldStorage/WorldStorage.h | 24 +- src/XMLParser.h | 78 +++--- src/main.cpp | 14 +- 406 files changed, 4497 insertions(+), 4497 deletions(-) diff --git a/src/AllocationPool.h b/src/AllocationPool.h index 4815ab414..799930708 100644 --- a/src/AllocationPool.h +++ b/src/AllocationPool.h @@ -15,23 +15,23 @@ public: { public: virtual ~cStarvationCallbacks() {} - + /** Is called when the reserve buffer starts to be used */ virtual void OnStartUsingReserve() = 0; - + /** Is called once the reserve buffer has returned to normal size */ virtual void OnEndUsingReserve() = 0; - + /** Is called when the allocation pool is unable to allocate memory. Will be repeatedly called if it does not free sufficient memory */ virtual void OnOutOfReserve() = 0; }; - + virtual ~cAllocationPool() {} - + /** Allocates a pointer to T */ virtual T * Allocate() = 0; - + /** Frees the pointer passed in a_ptr, invalidating it */ virtual void Free(T * a_ptr) = 0; }; @@ -47,7 +47,7 @@ class cListAllocationPool: public cAllocationPool { public: - + cListAllocationPool(std::unique_ptr::cStarvationCallbacks> a_Callbacks): m_Callbacks(std::move(a_Callbacks)) { @@ -62,7 +62,7 @@ public: m_FreeList.push_front(space); } } - + virtual ~cListAllocationPool() { @@ -72,7 +72,7 @@ public: m_FreeList.pop_front(); } } - + virtual T * Allocate() override { @@ -115,7 +115,7 @@ public: m_Callbacks->OnEndUsingReserve(); } } - + private: std::list m_FreeList; std::unique_ptr::cStarvationCallbacks> m_Callbacks; diff --git a/src/Bindings/LuaChunkStay.cpp b/src/Bindings/LuaChunkStay.cpp index 1afd09d11..d8d7da5d0 100644 --- a/src/Bindings/LuaChunkStay.cpp +++ b/src/Bindings/LuaChunkStay.cpp @@ -25,10 +25,10 @@ bool cLuaChunkStay::AddChunks(int a_ChunkCoordTableStackPos) { // This function is expected to be called just once, with all the coords in a table ASSERT(m_Chunks.empty()); - + cPluginLua::cOperation Op(m_Plugin); cLuaState & L = Op(); - + // Check that we got a table: if (!lua_istable(L, a_ChunkCoordTableStackPos)) { @@ -38,7 +38,7 @@ bool cLuaChunkStay::AddChunks(int a_ChunkCoordTableStackPos) L.LogStackTrace(); return false; } - + // Add each set of coords: int NumChunks = luaL_getn(L, a_ChunkCoordTableStackPos); m_Chunks.reserve(static_cast(NumChunks)); @@ -58,7 +58,7 @@ bool cLuaChunkStay::AddChunks(int a_ChunkCoordTableStackPos) AddChunkCoord(L, idx); lua_pop(L, 1); } - + // If there are no chunks, log a warning and return failure: if (m_Chunks.empty()) { @@ -66,7 +66,7 @@ bool cLuaChunkStay::AddChunks(int a_ChunkCoordTableStackPos) L.LogStackTrace(); return false; } - + // All ok return true; } @@ -86,14 +86,14 @@ void cLuaChunkStay::AddChunkCoord(cLuaState & L, int a_Index) ); return; } - + // Read the two coords from the element: lua_rawgeti(L, -1, 1); lua_rawgeti(L, -2, 2); int ChunkX = luaL_checkint(L, -2); int ChunkZ = luaL_checkint(L, -1); lua_pop(L, 2); - + // Check that a coord is not yet present: for (cChunkCoordsVector::iterator itr = m_Chunks.begin(), end = m_Chunks.end(); itr != end; ++itr) { @@ -105,7 +105,7 @@ void cLuaChunkStay::AddChunkCoord(cLuaState & L, int a_Index) return; } } // for itr - m_Chunks[] - + m_Chunks.push_back(cChunkCoords(ChunkX, ChunkZ)); } @@ -119,7 +119,7 @@ void cLuaChunkStay::Enable(cChunkMap & a_ChunkMap, int a_OnChunkAvailableStackPo m_LuaState = &m_Plugin.GetLuaState(); m_OnChunkAvailable.RefStack(*m_LuaState, a_OnChunkAvailableStackPos); m_OnAllChunksAvailable.RefStack(*m_LuaState, a_OnAllChunksAvailableStackPos); - + // Enable the ChunkStay: super::Enable(a_ChunkMap); } @@ -148,12 +148,12 @@ bool cLuaChunkStay::OnAllChunksAvailable(void) // Call the callback: cPluginLua::cOperation Op(m_Plugin); Op().Call(static_cast(m_OnAllChunksAvailable)); - + // Remove the callback references - they won't be needed anymore m_OnChunkAvailable.UnRef(); m_OnAllChunksAvailable.UnRef(); } - + // Disable the ChunkStay by returning true return true; } diff --git a/src/Bindings/LuaChunkStay.h b/src/Bindings/LuaChunkStay.h index d76b67de9..a455d2502 100644 --- a/src/Bindings/LuaChunkStay.h +++ b/src/Bindings/LuaChunkStay.h @@ -28,38 +28,38 @@ class cLuaChunkStay : public cChunkStay { typedef cChunkStay super; - + public: cLuaChunkStay(cPluginLua & a_Plugin); - + ~cLuaChunkStay() { } /** Adds chunks in the specified on-stack Lua table. Returns true if any chunk added, false (plus log warning) if none. */ bool AddChunks(int a_ChunkCoordTableStackPos); - + /** Enables the ChunkStay for the specified chunkmap, with the specified Lua callbacks. */ void Enable(cChunkMap & a_ChunkMap, int a_OnChunkAvailableStackPos, int a_OnAllChunksAvailableStackPos); - + protected: /** The plugin which has created the ChunkStay, via cWorld:ChunkStay() binding method. */ cPluginLua & m_Plugin; - + /** The Lua state associated with the callbacks. Only valid when enabled. */ cLuaState * m_LuaState; - + /** The Lua function to call in OnChunkAvailable. Only valid when enabled. */ cLuaState::cRef m_OnChunkAvailable; - + /** The Lua function to call in OnAllChunksAvailable. Only valid when enabled. */ cLuaState::cRef m_OnAllChunksAvailable; - - + + // cChunkStay overrides: virtual void OnChunkAvailable(int a_ChunkX, int a_ChunkZ) override; virtual bool OnAllChunksAvailable(void) override; virtual void OnDisabled(void) override; - + /** Adds a single chunk coord from the table at the top of the Lua stack. Expects the top element to be a table, checks that it contains two numbers. Uses those two numbers as chunk coords appended to m_Chunks. diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index b03dccad0..200878cf7 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -267,12 +267,12 @@ void cLuaState::AddPackagePath(const AString & a_PathVariable, const AString & a lua_getfield(m_LuaState, -1, a_PathVariable.c_str()); // Stk: size_t len = 0; const char * PackagePath = lua_tolstring(m_LuaState, -1, &len); - + // Append the new path: AString NewPackagePath(PackagePath, len); NewPackagePath.append(LUA_PATHSEP); NewPackagePath.append(a_Path); - + // Set the new path to the environment: lua_pop(m_LuaState, 1); // Stk: lua_pushlstring(m_LuaState, NewPackagePath.c_str(), NewPackagePath.length()); // Stk: @@ -382,10 +382,10 @@ bool cLuaState::PushFunction(const char * a_FunctionName) // This happens if cPlugin::Initialize() fails with an error return false; } - + // Push the error handler for lua_pcall() lua_pushcfunction(m_LuaState, &ReportFnCallErrors); - + lua_getglobal(m_LuaState, a_FunctionName); if (!lua_isfunction(m_LuaState, -1)) { @@ -406,10 +406,10 @@ bool cLuaState::PushFunction(int a_FnRef) { ASSERT(IsValid()); ASSERT(m_NumCurrentFunctionArgs == -1); // If not, there's already something pushed onto the stack - + // Push the error handler for lua_pcall() lua_pushcfunction(m_LuaState, &ReportFnCallErrors); - + lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, a_FnRef); // same as lua_getref() if (!lua_isfunction(m_LuaState, -1)) { @@ -429,10 +429,10 @@ bool cLuaState::PushFunction(const cTableRef & a_TableRef) { ASSERT(IsValid()); ASSERT(m_NumCurrentFunctionArgs == -1); // If not, there's already something pushed onto the stack - + // Push the error handler for lua_pcall() lua_pushcfunction(m_LuaState, &ReportFnCallErrors); - + lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, a_TableRef.GetTableRef()); // Get the table ref if (!lua_istable(m_LuaState, -1)) { @@ -447,10 +447,10 @@ bool cLuaState::PushFunction(const cTableRef & a_TableRef) lua_pop(m_LuaState, 3); return false; } - + // Pop the table off the stack: lua_remove(m_LuaState, -2); - + Printf(m_CurrentFunctionName, "", a_TableRef.GetFnName()); m_NumCurrentFunctionArgs = 0; return true; @@ -1005,13 +1005,13 @@ bool cLuaState::CallFunction(int a_NumResults) ASSERT (m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first ASSERT(lua_isfunction(m_LuaState, -m_NumCurrentFunctionArgs - 1)); // The function to call ASSERT(lua_isfunction(m_LuaState, -m_NumCurrentFunctionArgs - 2)); // The error handler - + // Save the current "stack" state and reset, in case the callback calls another function: AString CurrentFunctionName; std::swap(m_CurrentFunctionName, CurrentFunctionName); int NumArgs = m_NumCurrentFunctionArgs; m_NumCurrentFunctionArgs = -1; - + // Call the function: int s = lua_pcall(m_LuaState, NumArgs, a_NumResults, -NumArgs - 2); if (s != 0) @@ -1020,10 +1020,10 @@ bool cLuaState::CallFunction(int a_NumResults) LOGWARNING("Error in %s calling function %s()", m_SubsystemName.c_str(), CurrentFunctionName.c_str()); return false; } - + // Remove the error handler from the stack: lua_remove(m_LuaState, -a_NumResults - 1); - + return true; } @@ -1034,12 +1034,12 @@ bool cLuaState::CallFunction(int a_NumResults) bool cLuaState::CheckParamUserTable(int a_StartParam, const char * a_UserTable, int a_EndParam) { ASSERT(IsValid()); - + if (a_EndParam < 0) { a_EndParam = a_StartParam; } - + tolua_Error tolua_err; for (int i = a_StartParam; i <= a_EndParam; i++) { @@ -1055,7 +1055,7 @@ bool cLuaState::CheckParamUserTable(int a_StartParam, const char * a_UserTable, tolua_error(m_LuaState, ErrMsg.c_str(), &tolua_err); return false; } // for i - Param - + // All params checked ok return true; } @@ -1067,12 +1067,12 @@ bool cLuaState::CheckParamUserTable(int a_StartParam, const char * a_UserTable, bool cLuaState::CheckParamUserType(int a_StartParam, const char * a_UserType, int a_EndParam) { ASSERT(IsValid()); - + if (a_EndParam < 0) { a_EndParam = a_StartParam; } - + tolua_Error tolua_err; for (int i = a_StartParam; i <= a_EndParam; i++) { @@ -1088,7 +1088,7 @@ bool cLuaState::CheckParamUserType(int a_StartParam, const char * a_UserType, in tolua_error(m_LuaState, ErrMsg.c_str(), &tolua_err); return false; } // for i - Param - + // All params checked ok return true; } @@ -1100,12 +1100,12 @@ bool cLuaState::CheckParamUserType(int a_StartParam, const char * a_UserType, in bool cLuaState::CheckParamTable(int a_StartParam, int a_EndParam) { ASSERT(IsValid()); - + if (a_EndParam < 0) { a_EndParam = a_StartParam; } - + tolua_Error tolua_err; for (int i = a_StartParam; i <= a_EndParam; i++) { @@ -1124,7 +1124,7 @@ bool cLuaState::CheckParamTable(int a_StartParam, int a_EndParam) tolua_error(m_LuaState, ErrMsg.c_str(), &tolua_err); return false; } // for i - Param - + // All params checked ok return true; } @@ -1136,12 +1136,12 @@ bool cLuaState::CheckParamTable(int a_StartParam, int a_EndParam) bool cLuaState::CheckParamNumber(int a_StartParam, int a_EndParam) { ASSERT(IsValid()); - + if (a_EndParam < 0) { a_EndParam = a_StartParam; } - + tolua_Error tolua_err; for (int i = a_StartParam; i <= a_EndParam; i++) { @@ -1157,7 +1157,7 @@ bool cLuaState::CheckParamNumber(int a_StartParam, int a_EndParam) tolua_error(m_LuaState, ErrMsg.c_str(), &tolua_err); return false; } // for i - Param - + // All params checked ok return true; } @@ -1169,12 +1169,12 @@ bool cLuaState::CheckParamNumber(int a_StartParam, int a_EndParam) bool cLuaState::CheckParamBool(int a_StartParam, int a_EndParam) { ASSERT(IsValid()); - + if (a_EndParam < 0) { a_EndParam = a_StartParam; } - + tolua_Error tolua_err; for (int i = a_StartParam; i <= a_EndParam; i++) { @@ -1190,7 +1190,7 @@ bool cLuaState::CheckParamBool(int a_StartParam, int a_EndParam) tolua_error(m_LuaState, ErrMsg.c_str(), &tolua_err); return false; } // for i - Param - + // All params checked ok return true; } @@ -1202,12 +1202,12 @@ bool cLuaState::CheckParamBool(int a_StartParam, int a_EndParam) bool cLuaState::CheckParamString(int a_StartParam, int a_EndParam) { ASSERT(IsValid()); - + if (a_EndParam < 0) { a_EndParam = a_StartParam; } - + tolua_Error tolua_err; for (int i = a_StartParam; i <= a_EndParam; i++) { @@ -1226,7 +1226,7 @@ bool cLuaState::CheckParamString(int a_StartParam, int a_EndParam) tolua_error(m_LuaState, ErrMsg.c_str(), &tolua_err); return false; } // for i - Param - + // All params checked ok return true; } @@ -1238,12 +1238,12 @@ bool cLuaState::CheckParamString(int a_StartParam, int a_EndParam) bool cLuaState::CheckParamFunction(int a_StartParam, int a_EndParam) { ASSERT(IsValid()); - + if (a_EndParam < 0) { a_EndParam = a_StartParam; } - + for (int i = a_StartParam; i <= a_EndParam; i++) { if (lua_isfunction(m_LuaState, i)) @@ -1259,7 +1259,7 @@ bool cLuaState::CheckParamFunction(int a_StartParam, int a_EndParam) ); return false; } // for i - Param - + // All params checked ok return true; } @@ -1271,12 +1271,12 @@ bool cLuaState::CheckParamFunction(int a_StartParam, int a_EndParam) bool cLuaState::CheckParamFunctionOrNil(int a_StartParam, int a_EndParam) { ASSERT(IsValid()); - + if (a_EndParam < 0) { a_EndParam = a_StartParam; } - + for (int i = a_StartParam; i <= a_EndParam; i++) { if (lua_isfunction(m_LuaState, i) || lua_isnil(m_LuaState, i)) @@ -1292,7 +1292,7 @@ bool cLuaState::CheckParamFunctionOrNil(int a_StartParam, int a_EndParam) ); return false; } // for i - Param - + // All params checked ok return true; } @@ -1324,7 +1324,7 @@ bool cLuaState::CheckParamEnd(int a_Param) bool cLuaState::IsParamUserType(int a_Param, AString a_UserType) { ASSERT(IsValid()); - + tolua_Error tolua_err; return (tolua_isusertype(m_LuaState, a_Param, a_UserType.c_str(), 0, &tolua_err) == 1); } @@ -1336,7 +1336,7 @@ bool cLuaState::IsParamUserType(int a_Param, AString a_UserType) bool cLuaState::IsParamNumber(int a_Param) { ASSERT(IsValid()); - + tolua_Error tolua_err; return (tolua_isnumber(m_LuaState, a_Param, 0, &tolua_err) == 1); } @@ -1361,7 +1361,7 @@ bool cLuaState::ReportErrors(lua_State * a_LuaState, int a_Status) // No error to report return false; } - + LOGWARNING("LUA: %d - %s", a_Status, lua_tostring(a_LuaState, -1)); lua_pop(a_LuaState, 1); return true; @@ -1416,10 +1416,10 @@ int cLuaState::CallFunctionWithForeignParams( { ASSERT(IsValid()); ASSERT(a_SrcLuaState.IsValid()); - + // Store the stack position before any changes int OldTop = lua_gettop(m_LuaState); - + // Push the function to call, including the error handler: if (!PushFunction(a_FunctionName.c_str())) { @@ -1437,7 +1437,7 @@ int cLuaState::CallFunctionWithForeignParams( m_CurrentFunctionName.clear(); return -1; } - + // Call the function, with an error handler: int s = lua_pcall(m_LuaState, a_SrcParamEnd - a_SrcParamStart + 1, LUA_MULTRET, OldTop + 1); if (ReportErrors(s)) @@ -1445,23 +1445,23 @@ int cLuaState::CallFunctionWithForeignParams( LOGWARN("Error while calling function '%s' in '%s'", a_FunctionName.c_str(), m_SubsystemName.c_str()); // Reset the stack: lua_settop(m_LuaState, OldTop); - + // Reset the internal checking mechanisms: m_NumCurrentFunctionArgs = -1; m_CurrentFunctionName.clear(); - + // Make Lua think everything is okay and return 0 values, so that plugins continue executing. // The failure is indicated by the zero return values. return 0; } - + // Reset the internal checking mechanisms: m_NumCurrentFunctionArgs = -1; m_CurrentFunctionName.clear(); - + // Remove the error handler from the stack: lua_remove(m_LuaState, OldTop + 1); - + // Return the number of return values: return lua_gettop(m_LuaState) - OldTop; } @@ -1520,7 +1520,7 @@ int cLuaState::CopyStackFrom(cLuaState & a_SrcLuaState, int a_SrcStart, int a_Sr lua_rawget(a_SrcLuaState, LUA_REGISTRYINDEX); // Stack +1 type = lua_tostring(a_SrcLuaState, -1); lua_pop(a_SrcLuaState, 1); // Stack -1 - + // Copy the value: void * ud = tolua_touserdata(a_SrcLuaState, i, nullptr); tolua_pushusertype(m_LuaState, ud, type); @@ -1693,7 +1693,7 @@ void cLuaState::cRef::RefStack(cLuaState & a_LuaState, int a_StackPos) void cLuaState::cRef::UnRef(void) { ASSERT(m_LuaState->IsValid()); // The reference should be destroyed before destroying the LuaState - + if (IsValid()) { luaL_unref(*m_LuaState, LUA_REGISTRYINDEX, m_Ref); diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index f66605332..215980033 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -57,26 +57,26 @@ public: public: /** Creates an unbound reference object. */ cRef(void); - + /** Creates a reference in the specified LuaState for object at the specified StackPos */ cRef(cLuaState & a_LuaState, int a_StackPos); /** Moves the reference from the specified instance into a newly created instance. The old instance is then "!IsValid()". */ cRef(cRef && a_FromRef); - + ~cRef(); - + /** Creates a reference to Lua object at the specified stack pos, binds this object to it. Calls UnRef() first if previously bound to another reference. */ void RefStack(cLuaState & a_LuaState, int a_StackPos); - + /** Removes the bound reference, resets the object to Unbound state. */ void UnRef(void); - + /** Returns true if the reference is valid */ bool IsValid(void) const {return (m_Ref != LUA_REFNIL); } - + /** Allows to use this class wherever an int (i. e. ref) is to be used */ explicit operator int(void) const { return m_Ref; } @@ -87,8 +87,8 @@ public: // Remove the copy-constructor: cRef(const cRef &) = delete; } ; - - + + /** Used for calling functions stored in a reference-stored table */ class cTableRef { @@ -100,7 +100,7 @@ public: m_FnName(a_FnName) { } - + cTableRef(const cRef & a_TableRef, const char * a_FnName) : m_TableRef(static_cast(a_TableRef)), m_FnName(a_FnName) @@ -110,13 +110,13 @@ public: int GetTableRef(void) const { return m_TableRef; } const char * GetFnName(void) const { return m_FnName; } } ; - - + + /** A dummy class that's used only to delimit function args from return values for cLuaState::Call() */ class cRet { } ; - + static const cRet Return; // Use this constant to delimit function args from return values for cLuaState::Call() @@ -180,31 +180,31 @@ public: or "LuaScript" for the cLuaScript template */ cLuaState(const AString & a_SubsystemName); - + /** Creates a new instance. The a_AttachState is attached. Subsystem name is set to "". */ explicit cLuaState(lua_State * a_AttachState); - + ~cLuaState(); - + /** Allows this object to be used in the same way as a lua_State *, for example in the LuaLib functions */ operator lua_State * (void) { return m_LuaState; } - + /** Creates the m_LuaState, if not closed already. This state will be automatically closed in the destructor. The regular Lua libs are registered, but the MCS API is not registered (so that Lua can be used as lite-config as well), use RegisterAPILibs() to do that. */ void Create(void); - + /** Registers all the API libraries that MCS provides into m_LuaState. */ void RegisterAPILibs(void); - + /** Closes the m_LuaState, if not closed already */ void Close(void); - + /** Attaches the specified state. Operations will be carried out on this state, but it will not be closed in the destructor */ void Attach(lua_State * a_State); - + /** Detaches a previously attached state. */ void Detach(void); @@ -260,7 +260,7 @@ public: void Push(long a_Value); void Push(const UInt32 a_Value); void Push(std::chrono::milliseconds a_time); - + // GetStackValue() retrieves the value at a_StackPos, if it is a valid type. If not, a_Value is unchanged. // Returns whether value was changed // Enum values are checked for their allowed values and fail if the value is not assigned. @@ -335,7 +335,7 @@ public: // Include the auto-generated Push and GetStackValue() functions: #include "LuaState_Declaration.inc" - + /** Call the specified Lua function. Returns true if call succeeded, false if there was an error. A special param of cRet & signifies the end of param list and the start of return values. @@ -364,50 +364,50 @@ public: /** Returns true if the specified parameters on the stack are of the specified usertable type; also logs warning if not. Used for static functions */ bool CheckParamUserTable(int a_StartParam, const char * a_UserTable, int a_EndParam = -1); - + /** Returns true if the specified parameters on the stack are of the specified usertype; also logs warning if not. Used for regular functions */ bool CheckParamUserType(int a_StartParam, const char * a_UserType, int a_EndParam = -1); - + /** Returns true if the specified parameters on the stack are tables; also logs warning if not */ bool CheckParamTable(int a_StartParam, int a_EndParam = -1); - + /** Returns true if the specified parameters on the stack are numbers; also logs warning if not */ bool CheckParamNumber(int a_StartParam, int a_EndParam = -1); - + /** Returns true if the specified parameters on the stack are bools; also logs warning if not */ bool CheckParamBool(int a_StartParam, int a_EndParam = -1); - + /** Returns true if the specified parameters on the stack are strings; also logs warning if not */ bool CheckParamString(int a_StartParam, int a_EndParam = -1); - + /** Returns true if the specified parameters on the stack are functions; also logs warning if not */ bool CheckParamFunction(int a_StartParam, int a_EndParam = -1); - + /** Returns true if the specified parameters on the stack are functions or nils; also logs warning if not */ bool CheckParamFunctionOrNil(int a_StartParam, int a_EndParam = -1); - + /** Returns true if the specified parameter on the stack is nil (indicating an end-of-parameters) */ bool CheckParamEnd(int a_Param); - + bool IsParamUserType(int a_Param, AString a_UserType); bool IsParamNumber(int a_Param); /** If the status is nonzero, prints the text on the top of Lua stack and returns true */ bool ReportErrors(int status); - + /** If the status is nonzero, prints the text on the top of Lua stack and returns true */ static bool ReportErrors(lua_State * a_LuaState, int status); - + /** Logs all items in the current stack trace to the server console */ void LogStackTrace(int a_StartingDepth = 0); - + /** Logs all items in the current stack trace to the server console */ static void LogStackTrace(lua_State * a_LuaState, int a_StartingDepth = 0); - + /** Returns the type of the item on the specified position in the stack */ AString GetTypeText(int a_StackPos); - + /** Calls the function specified by its name, with arguments copied off the foreign state. If successful, keeps the return values on the stack and returns their number. If unsuccessful, returns a negative number and keeps the stack position unchanged. */ @@ -417,37 +417,37 @@ public: int a_SrcParamStart, int a_SrcParamEnd ); - + /** Copies objects on the stack from the specified state. Only numbers, bools, strings and userdatas are copied. If successful, returns the number of objects copied. If failed, returns a negative number and rewinds the stack position. */ int CopyStackFrom(cLuaState & a_SrcLuaState, int a_SrcStart, int a_SrcEnd); - + /** Reads the value at the specified stack position as a string and sets it to a_String. */ void ToString(int a_StackPos, AString & a_String); /** Logs all the elements' types on the API stack, with an optional header for the listing. */ void LogStack(const char * a_Header = nullptr); - + /** Logs all the elements' types on the API stack, with an optional header for the listing. */ static void LogStack(lua_State * a_LuaState, const char * a_Header = nullptr); - + protected: lua_State * m_LuaState; - + /** If true, the state is owned by this object and will be auto-Closed. False => attached state */ bool m_IsOwned; - + /** The subsystem name is used for reporting errors to the console, it is either "plugin %s" or "LuaScript" whatever is given to the constructor */ AString m_SubsystemName; - + /** Name of the currently pushed function (for the Push / Call chain) */ AString m_CurrentFunctionName; - + /** Number of arguments currently pushed (for the Push / Call chain) */ int m_NumCurrentFunctionArgs; @@ -499,12 +499,12 @@ protected: Returns true if successful. Logs a warning on failure (incl. m_SubsystemName) */ bool PushFunction(const char * a_FunctionName); - + /** Pushes a function that has been saved into the global registry, identified by a_FnRef. Returns true if successful. Logs a warning on failure */ bool PushFunction(int a_FnRef); - + /** Pushes a function that has been saved as a reference. Returns true if successful. Logs a warning on failure */ @@ -512,12 +512,12 @@ protected: { return PushFunction(static_cast(a_FnRef)); } - + /** Pushes a function that is stored in a referenced table by name Returns true if successful. Logs a warning on failure */ bool PushFunction(const cTableRef & a_TableRef); - + /** Pushes a usertype of the specified class type onto the stack */ // void PushUserType(void * a_Object, const char * a_Type); @@ -527,7 +527,7 @@ protected: Returns true if successful, logs a warning on failure. */ bool CallFunction(int a_NumReturnValues); - + /** Used as the error reporting function for function calls */ static int ReportFnCallErrors(lua_State * a_LuaState); diff --git a/src/Bindings/LuaWindow.cpp b/src/Bindings/LuaWindow.cpp index 5f7832ef5..706397a27 100644 --- a/src/Bindings/LuaWindow.cpp +++ b/src/Bindings/LuaWindow.cpp @@ -25,7 +25,7 @@ cLuaWindow::cLuaWindow(cWindow::WindowType a_WindowType, int a_SlotsX, int a_Slo { m_Contents.AddListener(*this); m_SlotAreas.push_back(new cSlotAreaItemGrid(m_Contents, *this)); - + // If appropriate, add an Armor slot area: switch (a_WindowType) { @@ -93,13 +93,13 @@ void cLuaWindow::SetOnClosing(cPluginLua * a_Plugin, int a_FnRef) { // Either m_Plugin is not set or equal to the passed plugin; only one plugin can use one cLuaWindow object ASSERT((m_Plugin == nullptr) || (m_Plugin == a_Plugin)); - + // If there already was a function, unreference it first if (m_OnClosingFnRef != LUA_REFNIL) { m_Plugin->Unreference(m_OnClosingFnRef); } - + // Store the new reference m_Plugin = a_Plugin; m_OnClosingFnRef = a_FnRef; @@ -113,13 +113,13 @@ void cLuaWindow::SetOnSlotChanged(cPluginLua * a_Plugin, int a_FnRef) { // Either m_Plugin is not set or equal to the passed plugin; only one plugin can use one cLuaWindow object ASSERT((m_Plugin == nullptr) || (m_Plugin == a_Plugin)); - + // If there already was a function, unreference it first if (m_OnSlotChangedFnRef != LUA_REFNIL) { m_Plugin->Unreference(m_OnSlotChangedFnRef); } - + // Store the new reference m_Plugin = a_Plugin; m_OnSlotChangedFnRef = a_FnRef; @@ -141,7 +141,7 @@ bool cLuaWindow::ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse) return false; } } - + return super::ClosedByPlayer(a_Player, a_CanRefuse); } @@ -152,13 +152,13 @@ bool cLuaWindow::ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse) void cLuaWindow::Destroy(void) { super::Destroy(); - + if ((m_LuaRef != LUA_REFNIL) && (m_Plugin != nullptr)) { // The object is referenced by Lua, un-reference it m_Plugin->Unreference(m_LuaRef); } - + // Lua will take care of this object, it will garbage-collect it, so we must not delete it! m_IsDestroyed = false; } @@ -192,7 +192,7 @@ void cLuaWindow::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) ASSERT(!"Invalid ItemGrid in callback"); return; } - + // If an OnSlotChanged callback has been registered, call it: if (m_OnSlotChangedFnRef != LUA_REFNIL) { diff --git a/src/Bindings/LuaWindow.h b/src/Bindings/LuaWindow.h index 60d4f5792..f292a5154 100644 --- a/src/Bindings/LuaWindow.h +++ b/src/Bindings/LuaWindow.h @@ -40,52 +40,52 @@ class cLuaWindow : // tolua_begin { typedef cWindow super; - + public: /** Create a window of the specified type, with a slot grid of a_SlotsX * a_SlotsY size */ cLuaWindow(cWindow::WindowType a_WindowType, int a_SlotsX, int a_SlotsY, const AString & a_Title); - + virtual ~cLuaWindow(); - + /** Returns the internal representation of the contents that are manipulated by Lua */ cItemGrid & GetContents(void) { return m_Contents; } - + // tolua_end - + /** Sets the plugin reference and the internal Lua object reference index used for preventing Lua's GC to collect this class while the window is open. */ void SetLuaRef(cPluginLua * a_Plugin, int a_LuaRef); - + /** Returns true if SetLuaRef() has been called */ bool IsLuaReferenced(void) const; - + /** Sets the callback function (Lua reference) to call when the window is about to close */ void SetOnClosing(cPluginLua * a_Plugin, int a_FnRef); - + /** Sets the callback function (Lua reference) to call when a slot is changed */ void SetOnSlotChanged(cPluginLua * a_Plugin, int a_FnRef); - + protected: /** Contents of the non-inventory part */ cItemGrid m_Contents; - + /** The plugin that has opened the window and owns the m_LuaRef */ cPluginLua * m_Plugin; - + /** The Lua object reference, used for keeping the object alive as long as any player has the window open */ int m_LuaRef; - + /** The Lua reference for the callback to call when the window is closing for any player */ int m_OnClosingFnRef; - + /** The Lua reference for the callback to call when a slot has changed */ int m_OnSlotChangedFnRef; - + // cWindow overrides: virtual bool ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse) override; virtual void Destroy(void) override; virtual void DistributeStack(cItem & a_ItemStack, int a_Slot, cPlayer & a_Player, cSlotArea * a_ClickedArea, bool a_ShouldApply) override; - + // cItemGrid::cListener overrides: virtual void OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) override; } ; // tolua_export diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 42e7e9bd2..110f22f1c 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -356,7 +356,7 @@ static int tolua_LOG(lua_State * tolua_S) { LogLevel = cCompositeChat::MessageTypeToLogLevel(reinterpret_cast(tolua_tousertype(tolua_S, 1, nullptr))->GetMessageType()); } - + // Log the message: cLogger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), LogLevel); return 0; @@ -430,7 +430,7 @@ static int tolua_Base64Encode(lua_State * tolua_S) { return 0; } - + AString Src; L.GetStackValue(1, Src); AString res = Base64Encode(Src); @@ -452,7 +452,7 @@ static int tolua_Base64Decode(lua_State * tolua_S) { return 0; } - + AString Src; L.GetStackValue(1, Src); AString res = Base64Decode(Src); @@ -476,7 +476,7 @@ cPluginLua * cManualBindings::GetLuaPlugin(lua_State * L) } cPluginLua * Plugin = reinterpret_cast(const_cast(lua_topointer(L, -1))); lua_pop(L, 1); - + return Plugin; } @@ -746,7 +746,7 @@ static int tolua_cFile_GetFolderContents(lua_State * tolua_S) { return 0; } - + // Get params: AString Folder; ASSERT(LuaState.GetStackValues(2, Folder)); @@ -883,7 +883,7 @@ static int tolua_cFile_ReadWholeFile(lua_State * tolua_S) { return 0; } - + // Get params: AString FileName; ASSERT(LuaState.GetStackValues(2, FileName)); @@ -982,7 +982,7 @@ static int tolua_cPluginManager_AddHook_FnRef(cPluginManager * a_PluginManager, // Helper function for cPluginmanager:AddHook() binding // Takes care of the new case (#121): args are HOOK_TYPE and CallbackFunction // The arg types have already been checked - + // Retrieve the cPlugin from the LuaState: cPluginLua * Plugin = cManualBindings::GetLuaPlugin(S); if (Plugin == nullptr) @@ -990,7 +990,7 @@ static int tolua_cPluginManager_AddHook_FnRef(cPluginManager * a_PluginManager, // An error message has been already printed in GetLuaPlugin() return 0; } - + // Retrieve and check the hook type int HookType = static_cast(tolua_tonumber(S, a_ParamIdx, -1)); if (!a_PluginManager->IsValidHookType(HookType)) @@ -999,7 +999,7 @@ static int tolua_cPluginManager_AddHook_FnRef(cPluginManager * a_PluginManager, S.LogStackTrace(); return 0; } - + // Add the hook to the plugin if (!Plugin->AddHookRef(HookType, a_ParamIdx + 1)) { @@ -1008,7 +1008,7 @@ static int tolua_cPluginManager_AddHook_FnRef(cPluginManager * a_PluginManager, return 0; } a_PluginManager->AddHook(Plugin, HookType); - + // Success return 0; } @@ -1022,7 +1022,7 @@ static int tolua_cPluginManager_AddHook_DefFn(cPluginManager * a_PluginManager, // Helper function for cPluginmanager:AddHook() binding // Takes care of the old case (#121): args are cPluginLua and HOOK_TYPE // The arg types have already been checked - + // Retrieve and check the cPlugin parameter cPluginLua * Plugin = reinterpret_cast(tolua_tousertype(S, a_ParamIdx, nullptr)); if (Plugin == nullptr) @@ -1038,7 +1038,7 @@ static int tolua_cPluginManager_AddHook_DefFn(cPluginManager * a_PluginManager, S.LogStackTrace(); return 0; } - + // Retrieve and check the hook type int HookType = static_cast(tolua_tonumber(S, a_ParamIdx + 1, -1)); if (!a_PluginManager->IsValidHookType(HookType)) @@ -1047,7 +1047,7 @@ static int tolua_cPluginManager_AddHook_DefFn(cPluginManager * a_PluginManager, S.LogStackTrace(); return 0; } - + // Get the standard name for the callback function: const char * FnName = cPluginLua::GetHookFnName(HookType); if (FnName == nullptr) @@ -1068,7 +1068,7 @@ static int tolua_cPluginManager_AddHook_DefFn(cPluginManager * a_PluginManager, return 0; } a_PluginManager->AddHook(Plugin, HookType); - + // Success return 0; } @@ -1087,7 +1087,7 @@ static int tolua_cPluginManager_AddHook(lua_State * tolua_S) cPluginManager:Get():AddHook(Plugin, HOOK_TYPE) -- (4) old style (#121), accepted but complained about in the console cPluginManager.AddHook(Plugin, HOOK_TYPE) -- (5) old style (#121) mangled, accepted but complained about in the console */ - + cLuaState S(tolua_S); cPluginManager * PlgMgr = cPluginManager::Get(); @@ -1111,7 +1111,7 @@ static int tolua_cPluginManager_AddHook(lua_State * tolua_S) // Style 1, use the global PlgMgr, but increment ParamIdx ParamIdx++; } - + if (lua_isnumber(S, ParamIdx) && lua_isfunction(S, ParamIdx + 1)) { // The next params are a number and a function, assume style 1 or 2 @@ -1124,7 +1124,7 @@ static int tolua_cPluginManager_AddHook(lua_State * tolua_S) S.LogStackTrace(); return tolua_cPluginManager_AddHook_DefFn(PlgMgr, S, ParamIdx); } - + AString ParamDesc; Printf(ParamDesc, "%s, %s, %s", S.GetTypeText(1).c_str(), S.GetTypeText(2).c_str(), S.GetTypeText(3).c_str()); LOGWARNING("cPluginManager:AddHook(): bad parameters. Expected HOOK_TYPE and CallbackFunction, got %s. Hook not added.", ParamDesc.c_str()); @@ -1264,7 +1264,7 @@ static int tolua_cPluginManager_BindCommand(lua_State * L) { return 0; } - + // Read the arguments to this API call: tolua_Error tolua_err; int idx = 1; @@ -1294,7 +1294,7 @@ static int tolua_cPluginManager_BindCommand(lua_State * L) AString Command (tolua_tocppstring(L, idx, "")); AString Permission(tolua_tocppstring(L, idx + 1, "")); AString HelpString(tolua_tocppstring(L, idx + 3, "")); - + // Store the function reference: lua_pop(L, 1); // Pop the help string off the stack int FnRef = luaL_ref(L, LUA_REGISTRYINDEX); // Store function reference @@ -1303,7 +1303,7 @@ static int tolua_cPluginManager_BindCommand(lua_State * L) LOGERROR("\"BindCommand\": Cannot create a function reference. Command \"%s\" not bound.", Command.c_str()); return 0; } - + if (!self->BindCommand(Command, Plugin, Permission, HelpString)) { // Refused. Possibly already bound. Error message has been given, display the callstack: @@ -1311,7 +1311,7 @@ static int tolua_cPluginManager_BindCommand(lua_State * L) LS.LogStackTrace(); return 0; } - + Plugin->BindCommand(Command, FnRef); lua_pushboolean(L, true); return 1; @@ -1327,14 +1327,14 @@ static int tolua_cPluginManager_BindConsoleCommand(lua_State * L) cPluginManager:BindConsoleCommand(Command, Function, HelpString) cPluginManager.BindConsoleCommand(Command, Function, HelpString) -- without the "self" param */ - + // Get the plugin identification out of LuaState: cPluginLua * Plugin = cManualBindings::GetLuaPlugin(L); if (Plugin == nullptr) { return 0; } - + // Read the arguments to this API call: tolua_Error tolua_err; int idx = 1; @@ -1362,7 +1362,7 @@ static int tolua_cPluginManager_BindConsoleCommand(lua_State * L) cPluginManager * self = cPluginManager::Get(); AString Command (tolua_tocppstring(L, idx, "")); AString HelpString(tolua_tocppstring(L, idx + 2, "")); - + // Store the function reference: lua_pop(L, 1); // Pop the help string off the stack int FnRef = luaL_ref(L, LUA_REGISTRYINDEX); // Store function reference @@ -1371,7 +1371,7 @@ static int tolua_cPluginManager_BindConsoleCommand(lua_State * L) LOGERROR("\"BindConsoleCommand\": Cannot create a function reference. Console Command \"%s\" not bound.", Command.c_str()); return 0; } - + if (!self->BindConsoleCommand(Command, Plugin, HelpString)) { // Refused. Possibly already bound. Error message has been given, display the callstack: @@ -1379,7 +1379,7 @@ static int tolua_cPluginManager_BindConsoleCommand(lua_State * L) LS.LogStackTrace(); return 0; } - + Plugin->BindConsoleCommand(Command, FnRef); lua_pushboolean(L, true); return 1; @@ -1395,7 +1395,7 @@ static int tolua_cPluginManager_CallPlugin(lua_State * tolua_S) Function signature: cPluginManager:CallPlugin("PluginName", "FunctionName", args...) */ - + // Check the parameters: cLuaState L(tolua_S); if ( @@ -1404,7 +1404,7 @@ static int tolua_cPluginManager_CallPlugin(lua_State * tolua_S) { return 0; } - + // Retrieve the plugin name and function name AString PluginName, FunctionName; L.ToString(2, PluginName); @@ -1415,7 +1415,7 @@ static int tolua_cPluginManager_CallPlugin(lua_State * tolua_S) L.LogStackTrace(); return 0; } - + // If requesting calling the current plugin, refuse: cPluginLua * ThisPlugin = cManualBindings::GetLuaPlugin(L); if (ThisPlugin == nullptr) @@ -1428,7 +1428,7 @@ static int tolua_cPluginManager_CallPlugin(lua_State * tolua_S) L.LogStackTrace(); return 0; } - + // Call the destination plugin using a plugin callback: class cCallback : public cPluginManager::cPluginCallback @@ -1445,7 +1445,7 @@ static int tolua_cPluginManager_CallPlugin(lua_State * tolua_S) protected: const AString & m_FunctionName; cLuaState & m_SrcLuaState; - + virtual bool Item(cPlugin * a_Plugin) override { if (!a_Plugin->IsLoaded()) @@ -1544,7 +1544,7 @@ static int tolua_cPlayer_GetPermissions(lua_State * tolua_S) LOGWARNING("%s: invalid self (%p)", __FUNCTION__, static_cast(self)); return 0; } - + // Push the permissions: L.Push(self->GetPermissions()); return 1; @@ -1575,7 +1575,7 @@ static int tolua_cPlayer_GetRestrictions(lua_State * tolua_S) LOGWARNING("%s: invalid self (%p)", __FUNCTION__, static_cast(self)); return 0; } - + // Push the permissions: L.Push(self->GetRestrictions()); return 1; @@ -1604,7 +1604,7 @@ static int tolua_cPlayer_OpenWindow(lua_State * tolua_S) LOGWARNING("%s: invalid self (%p) or wnd (%p)", __FUNCTION__, static_cast(self), static_cast(wnd)); return 0; } - + // If cLuaWindow, add a reference, so that Lua won't delete the cLuaWindow object mid-processing tolua_Error err; if (tolua_isusertype(tolua_S, 2, "cLuaWindow", 0, &err)) @@ -1624,7 +1624,7 @@ static int tolua_cPlayer_OpenWindow(lua_State * tolua_S) LuaWnd->SetLuaRef(Plugin, LuaRef); } } - + // Open the window self->OpenWindow(wnd); return 0; @@ -1652,7 +1652,7 @@ static int tolua_cPlayer_PermissionMatches(lua_State * tolua_S) // Get the params: AString Permission, Template; L.GetStackValues(2, Permission, Template); - + // Push the result of the match: L.Push(cPlayer::PermissionMatches(StringSplit(Permission, "."), StringSplit(Template, "."))); return 1; @@ -1691,7 +1691,7 @@ static int tolua_SetObjectCallback(lua_State * tolua_S) LOGERROR("%s: Cannot create a function reference. Callback not set.", __FUNCTION__); return 0; } - + // Set the callback (self->*SetCallback)(Plugin, FnRef); return 0; @@ -1711,7 +1711,7 @@ static int tolua_cPluginLua_AddWebTab(lua_State * tolua_S) LOGWARNING("cPluginLua:AddWebTab: invalid self as first argument"); return 0; } - + tolua_Error tolua_err; tolua_err.array = 0; tolua_err.index = 3; @@ -1752,14 +1752,14 @@ static int tolua_cPluginLua_AddWebTab(lua_State * tolua_S) static int tolua_cPlugin_GetDirectory(lua_State * tolua_S) { cLuaState L(tolua_S); - + // Log the obsoletion warning: LOGWARNING("cPlugin:GetDirectory() is obsolete, use cPlugin:GetFolderName() instead."); L.LogStackTrace(); - + // Retrieve the params: cPlugin * Plugin = static_cast(tolua_tousertype(tolua_S, 1, nullptr)); - + // Get the folder name: L.Push(Plugin->GetFolderName()); return 1; @@ -1772,14 +1772,14 @@ static int tolua_cPlugin_GetDirectory(lua_State * tolua_S) static int tolua_cPlugin_GetLocalDirectory(lua_State * tolua_S) { cLuaState L(tolua_S); - + // Log the obsoletion warning: LOGWARNING("cPlugin:GetLocalDirectory() is obsolete, use cPlugin:GetLocalFolder() instead."); L.LogStackTrace(); - + // Retrieve the params: cPlugin * Plugin = static_cast(tolua_tousertype(tolua_S, 1, nullptr)); - + // Get the folder: L.Push(Plugin->GetLocalFolder()); return 1; @@ -2145,11 +2145,11 @@ static int tolua_AllToLua_cWebAdmin_GetHTMLEscapedString(lua_State * tolua_S) { return 0; } - + // Get the parameters: AString Input; S.GetStackValue(2, Input); - + // Convert and return: S.Push(cWebAdmin::GetHTMLEscapedString(Input)); return 1; @@ -2173,11 +2173,11 @@ static int tolua_AllToLua_cWebAdmin_GetURLEncodedString(lua_State * tolua_S) { return 0; } - + // Get the parameters: AString Input; S.GetStackValue(2, Input); - + // Convert and return: S.Push(cWebAdmin::GetURLEncodedString(Input)); return 1; @@ -2249,12 +2249,12 @@ static int tolua_cMojangAPI_AddPlayerNameToUUIDMapping(lua_State * L) { return 0; } - + // Retrieve the parameters: AString UUID, PlayerName; S.GetStackValue(2, PlayerName); S.GetStackValue(3, UUID); - + // Store in the cache: cRoot::Get()->GetMojangAPI().AddPlayerNameToUUIDMapping(PlayerName, UUID); return 0; @@ -2275,10 +2275,10 @@ static int tolua_cMojangAPI_GetPlayerNameFromUUID(lua_State * L) { return 0; } - + AString UUID; S.GetStackValue(2, UUID); - + // If the UseOnlyCached param was given, read it; default to false bool ShouldUseCacheOnly = false; if (lua_gettop(L) == 3) @@ -2308,10 +2308,10 @@ static int tolua_cMojangAPI_GetUUIDFromPlayerName(lua_State * L) { return 0; } - + AString PlayerName; S.GetStackValue(2, PlayerName); - + // If the UseOnlyCached param was given, read it; default to false bool ShouldUseCacheOnly = false; if (lua_gettop(L) == 3) @@ -2341,7 +2341,7 @@ static int tolua_cMojangAPI_GetUUIDsFromPlayerNames(lua_State * L) { return 0; } - + // Convert the input table into AStringVector: AStringVector PlayerNames; int NumNames = luaL_getn(L, 2); @@ -2357,7 +2357,7 @@ static int tolua_cMojangAPI_GetUUIDsFromPlayerNames(lua_State * L) } lua_pop(L, 1); } - + // If the UseOnlyCached param was given, read it; default to false bool ShouldUseCacheOnly = false; if (lua_gettop(L) == 3) @@ -2368,7 +2368,7 @@ static int tolua_cMojangAPI_GetUUIDsFromPlayerNames(lua_State * L) // Push the output table onto the stack: lua_newtable(L); - + // Get the UUIDs: AStringVector UUIDs = cRoot::Get()->GetMojangAPI().GetUUIDsFromPlayerNames(PlayerNames, ShouldUseCacheOnly); if (UUIDs.size() != PlayerNames.size()) @@ -2376,7 +2376,7 @@ static int tolua_cMojangAPI_GetUUIDsFromPlayerNames(lua_State * L) // A hard error has occured while processing the request, no UUIDs were returned. Return an empty table: return 1; } - + // Convert to output table, PlayerName -> UUID: size_t len = UUIDs.size(); for (size_t i = 0; i < len; i++) @@ -2410,7 +2410,7 @@ static int tolua_cMojangAPI_MakeUUIDDashed(lua_State * L) { return 0; } - + // Get the params: AString UUID; S.GetStackValue(2, UUID); @@ -2438,7 +2438,7 @@ static int tolua_cMojangAPI_MakeUUIDShort(lua_State * L) { return 0; } - + // Get the params: AString UUID; S.GetStackValue(2, UUID); @@ -2478,7 +2478,7 @@ static int Lua_ItemGrid_GetSlotCoords(lua_State * L) tolua_pushnumber(L, static_cast(Y)); return 2; } - + tolua_lerror: tolua_error(L, "#ferror in function 'cItemGrid:GetSlotCoords'.", &tolua_err); return 0; @@ -2498,7 +2498,7 @@ public: m_TableRef(a_LuaState, a_ParamNum) { } - + virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override { bool res = false; @@ -2513,7 +2513,7 @@ public: } return res; } - + virtual bool OnNextBlockNoData(int a_BlockX, int a_BlockY, int a_BlockZ, char a_EntryFace) override { bool res = false; @@ -2528,7 +2528,7 @@ public: } return res; } - + virtual bool OnOutOfWorld(double a_BlockX, double a_BlockY, double a_BlockZ) override { bool res = false; @@ -2543,7 +2543,7 @@ public: } return res; } - + virtual bool OnIntoWorld(double a_BlockX, double a_BlockY, double a_BlockZ) override { bool res = false; @@ -2558,12 +2558,12 @@ public: } return res; } - + virtual void OnNoMoreHits(void) override { m_LuaState.Call(cLuaState::cTableRef(m_TableRef, "OnNoMoreHits")); } - + virtual void OnNoChunk(void) override { m_LuaState.Call(cLuaState::cTableRef(m_TableRef, "OnNoChunk")); @@ -2584,7 +2584,7 @@ static int tolua_cLineBlockTracer_Trace(lua_State * tolua_S) cLineBlockTracer:Trace(World, Callbacks, StartX, StartY, StartZ, EndX, EndY, EndZ) // Canonical cLineBlockTracer.Trace(World, Callbacks, StartX, StartY, StartZ, EndX, EndY, EndZ) */ - + // If the first param is the cLineBlockTracer class, shift param index by one: int idx = 1; tolua_Error err; @@ -2592,7 +2592,7 @@ static int tolua_cLineBlockTracer_Trace(lua_State * tolua_S) { idx = 2; } - + // Check params: cLuaState L(tolua_S); if ( @@ -2726,7 +2726,7 @@ static int tolua_cRoot_GetFurnaceRecipe(lua_State * tolua_S) { return 0; } - + // Check the input param: cItem * Input = nullptr; L.GetStackValue(2, Input); @@ -2735,7 +2735,7 @@ static int tolua_cRoot_GetFurnaceRecipe(lua_State * tolua_S) LOGWARNING("cRoot:GetFurnaceRecipe: the Input parameter is nil or missing."); return 0; } - + // Get the recipe for the input cFurnaceRecipe * FR = cRoot::Get()->GetFurnaceRecipe(); const cFurnaceRecipe::cRecipe * Recipe = FR->GetRecipeFrom(*Input); @@ -2744,7 +2744,7 @@ static int tolua_cRoot_GetFurnaceRecipe(lua_State * tolua_S) // There is no such furnace recipe for this input, return no value return 0; } - + // Push the output, number of ticks and input as the three return values: L.Push(Recipe->Out); L.Push(Recipe->CookTime); @@ -2760,7 +2760,7 @@ static int tolua_cHopperEntity_GetOutputBlockPos(lua_State * tolua_S) { // function cHopperEntity::GetOutputBlockPos() // Exported manually because tolua would require meaningless params - + cLuaState L(tolua_S); if ( !L.CheckParamUserType(1, "cHopperEntity") || @@ -2800,7 +2800,7 @@ static int tolua_cBlockArea_GetBlockTypeMeta(lua_State * tolua_S) { // function cBlockArea::GetBlockTypeMeta() // Exported manually because tolua generates extra input params for the outputs - + cLuaState L(tolua_S); if ( !L.CheckParamUserType(1, "cBlockArea") || @@ -2809,7 +2809,7 @@ static int tolua_cBlockArea_GetBlockTypeMeta(lua_State * tolua_S) { return 0; } - + cBlockArea * self = reinterpret_cast(tolua_tousertype(tolua_S, 1, nullptr)); if (self == nullptr) { @@ -2837,20 +2837,20 @@ static int tolua_cBlockArea_GetOrigin(lua_State * tolua_S) // Returns all three coords of the origin point // Exported manually because there's no direct C++ equivalent, // plus tolua would generate extra input params for the outputs - + cLuaState L(tolua_S); if (!L.CheckParamUserType(1, "cBlockArea")) { return 0; } - + cBlockArea * self = reinterpret_cast(tolua_tousertype(tolua_S, 1, nullptr)); if (self == nullptr) { tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea:GetOrigin'", nullptr); return 0; } - + // Push the three origin coords: lua_pushnumber(tolua_S, self->GetOriginX()); lua_pushnumber(tolua_S, self->GetOriginY()); @@ -2866,13 +2866,13 @@ static int tolua_cBlockArea_GetNonAirCropRelCoords(lua_State * tolua_S) { // function cBlockArea::GetNonAirCropRelCoords() // Exported manually because tolua would generate extra input params for the outputs - + cLuaState L(tolua_S); if (!L.CheckParamUserType(1, "cBlockArea")) { return 0; } - + cBlockArea * self = nullptr; BLOCKTYPE IgnoreBlockType = E_BLOCK_AIR; L.GetStackValues(1, self, IgnoreBlockType); @@ -2881,7 +2881,7 @@ static int tolua_cBlockArea_GetNonAirCropRelCoords(lua_State * tolua_S) tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea:GetNonAirCropRelCoords'", nullptr); return 0; } - + // Calculate the crop coords: int MinRelX, MinRelY, MinRelZ, MaxRelX, MaxRelY, MaxRelZ; self->GetNonAirCropRelCoords(MinRelX, MinRelY, MinRelZ, MaxRelX, MaxRelY, MaxRelZ, IgnoreBlockType); @@ -2904,7 +2904,7 @@ static int tolua_cBlockArea_GetRelBlockTypeMeta(lua_State * tolua_S) { // function cBlockArea::GetRelBlockTypeMeta() // Exported manually because tolua generates extra input params for the outputs - + cLuaState L(tolua_S); if ( !L.CheckParamUserType(1, "cBlockArea") || @@ -2913,7 +2913,7 @@ static int tolua_cBlockArea_GetRelBlockTypeMeta(lua_State * tolua_S) { return 0; } - + cBlockArea * self = reinterpret_cast(tolua_tousertype(tolua_S, 1, nullptr)); if (self == nullptr) { @@ -2941,20 +2941,20 @@ static int tolua_cBlockArea_GetSize(lua_State * tolua_S) // Returns all three sizes of the area // Exported manually because there's no direct C++ equivalent, // plus tolua would generate extra input params for the outputs - + cLuaState L(tolua_S); if (!L.CheckParamUserType(1, "cBlockArea")) { return 0; } - + cBlockArea * self = reinterpret_cast(tolua_tousertype(tolua_S, 1, nullptr)); if (self == nullptr) { tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea:GetSize'", nullptr); return 0; } - + // Push the three origin coords: lua_pushnumber(tolua_S, self->GetSizeX()); lua_pushnumber(tolua_S, self->GetSizeY()); @@ -2972,20 +2972,20 @@ static int tolua_cBlockArea_GetCoordRange(lua_State * tolua_S) // Returns all three sizes of the area, miuns one, so that they represent the maximum coord value // Exported manually because there's no direct C++ equivalent, // plus tolua would generate extra input params for the outputs - + cLuaState L(tolua_S); if (!L.CheckParamUserType(1, "cBlockArea")) { return 0; } - + cBlockArea * self = reinterpret_cast(tolua_tousertype(tolua_S, 1, nullptr)); if (self == nullptr) { tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea:GetSize'", nullptr); return 0; } - + // Push the three origin coords: lua_pushnumber(tolua_S, self->GetSizeX() - 1); lua_pushnumber(tolua_S, self->GetSizeY() - 1); @@ -3105,7 +3105,7 @@ static int tolua_cBlockArea_SaveToSchematicString(lua_State * tolua_S) tolua_error(tolua_S, "invalid 'self' in function 'cBlockArea::SaveToSchematicFile'", nullptr); return 0; } - + AString Data; if (cSchematicFileSerializer::SaveToSchematicString(*self, Data)) { @@ -3123,7 +3123,7 @@ static int tolua_cCompositeChat_AddRunCommandPart(lua_State * tolua_S) { // function cCompositeChat:AddRunCommandPart(Message, Command, [Style]) // Exported manually to support call-chaining (return *this) - + // Check params: cLuaState L(tolua_S); if ( @@ -3139,14 +3139,14 @@ static int tolua_cCompositeChat_AddRunCommandPart(lua_State * tolua_S) tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:AddRunCommandPart'", nullptr); return 0; } - + // Add the part: AString Text, Command, Style; L.GetStackValue(2, Text); L.GetStackValue(3, Command); L.GetStackValue(4, Style); self->AddRunCommandPart(Text, Command, Style); - + // Cut away everything from the stack except for the cCompositeChat instance; return that: lua_settop(L, 1); return 1; @@ -3160,7 +3160,7 @@ static int tolua_cCompositeChat_AddSuggestCommandPart(lua_State * tolua_S) { // function cCompositeChat:AddSuggestCommandPart(Message, Command, [Style]) // Exported manually to support call-chaining (return *this) - + // Check params: cLuaState L(tolua_S); if ( @@ -3176,14 +3176,14 @@ static int tolua_cCompositeChat_AddSuggestCommandPart(lua_State * tolua_S) tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:AddSuggestCommandPart'", nullptr); return 0; } - + // Add the part: AString Text, Command, Style; L.GetStackValue(2, Text); L.GetStackValue(3, Command); L.GetStackValue(4, Style); self->AddSuggestCommandPart(Text, Command, Style); - + // Cut away everything from the stack except for the cCompositeChat instance; return that: lua_settop(L, 1); return 1; @@ -3197,7 +3197,7 @@ static int tolua_cCompositeChat_AddTextPart(lua_State * tolua_S) { // function cCompositeChat:AddTextPart(Message, [Style]) // Exported manually to support call-chaining (return *this) - + // Check params: cLuaState L(tolua_S); if ( @@ -3213,13 +3213,13 @@ static int tolua_cCompositeChat_AddTextPart(lua_State * tolua_S) tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:AddTextPart'", nullptr); return 0; } - + // Add the part: AString Text, Style; L.GetStackValue(2, Text); L.GetStackValue(3, Style); self->AddTextPart(Text, Style); - + // Cut away everything from the stack except for the cCompositeChat instance; return that: lua_settop(L, 1); return 1; @@ -3233,7 +3233,7 @@ static int tolua_cCompositeChat_AddUrlPart(lua_State * tolua_S) { // function cCompositeChat:AddTextPart(Message, Url, [Style]) // Exported manually to support call-chaining (return *this) - + // Check params: cLuaState L(tolua_S); if ( @@ -3249,14 +3249,14 @@ static int tolua_cCompositeChat_AddUrlPart(lua_State * tolua_S) tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:AddUrlPart'", nullptr); return 0; } - + // Add the part: AString Text, Url, Style; L.GetStackValue(2, Text); L.GetStackValue(3, Url); L.GetStackValue(4, Style); self->AddUrlPart(Text, Url, Style); - + // Cut away everything from the stack except for the cCompositeChat instance; return that: lua_settop(L, 1); return 1; @@ -3270,7 +3270,7 @@ static int tolua_cCompositeChat_ParseText(lua_State * tolua_S) { // function cCompositeChat:ParseText(TextMessage) // Exported manually to support call-chaining (return *this) - + // Check params: cLuaState L(tolua_S); if ( @@ -3286,12 +3286,12 @@ static int tolua_cCompositeChat_ParseText(lua_State * tolua_S) tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:ParseText'", nullptr); return 0; } - + // Parse the text: AString Text; L.GetStackValue(2, Text); self->ParseText(Text); - + // Cut away everything from the stack except for the cCompositeChat instance; return that: lua_settop(L, 1); return 1; @@ -3305,7 +3305,7 @@ static int tolua_cCompositeChat_SetMessageType(lua_State * tolua_S) { // function cCompositeChat:SetMessageType(MessageType) // Exported manually to support call-chaining (return *this) - + // Check params: cLuaState L(tolua_S); if ( @@ -3321,12 +3321,12 @@ static int tolua_cCompositeChat_SetMessageType(lua_State * tolua_S) tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:SetMessageType'", nullptr); return 0; } - + // Set the type: int MessageType = mtCustom; L.GetStackValue(2, MessageType); self->SetMessageType(static_cast(MessageType)); - + // Cut away everything from the stack except for the cCompositeChat instance; return that: lua_settop(L, 1); return 1; @@ -3340,7 +3340,7 @@ static int tolua_cCompositeChat_UnderlineUrls(lua_State * tolua_S) { // function cCompositeChat:UnderlineUrls() // Exported manually to support call-chaining (return *this) - + // Check params: cLuaState L(tolua_S); if (!L.CheckParamUserType(1, "cCompositeChat")) @@ -3353,10 +3353,10 @@ static int tolua_cCompositeChat_UnderlineUrls(lua_State * tolua_S) tolua_error(tolua_S, "invalid 'self' in function 'cCompositeChat:UnderlineUrls'", nullptr); return 0; } - + // Call the processing self->UnderlineUrls(); - + // Cut away everything from the stack except for the cCompositeChat instance; return that: lua_settop(L, 1); return 1; @@ -3494,7 +3494,7 @@ void cManualBindings::Bind(lua_State * tolua_S) tolua_function(tolua_S, "GetDirectory", tolua_cPlugin_GetDirectory); tolua_function(tolua_S, "GetLocalDirectory", tolua_cPlugin_GetLocalDirectory); tolua_endmodule(tolua_S); - + tolua_beginmodule(tolua_S, "cPluginLua"); tolua_function(tolua_S, "AddWebTab", tolua_cPluginLua_AddWebTab); tolua_endmodule(tolua_S); diff --git a/src/Bindings/ManualBindings.h b/src/Bindings/ManualBindings.h index f124084a9..98e3e88ef 100644 --- a/src/Bindings/ManualBindings.h +++ b/src/Bindings/ManualBindings.h @@ -27,7 +27,7 @@ class cManualBindings public: /** Binds all the manually implemented functions to tolua_S. */ static void Bind(lua_State * tolua_S); - + protected: /** Binds the manually implemented cNetwork-related API to tolua_S. Implemented in ManualBindings_Network.cpp. */ diff --git a/src/Bindings/ManualBindings_Network.cpp b/src/Bindings/ManualBindings_Network.cpp index 1631cdfec..576fe94b7 100644 --- a/src/Bindings/ManualBindings_Network.cpp +++ b/src/Bindings/ManualBindings_Network.cpp @@ -37,7 +37,7 @@ static int tolua_cNetwork_Connect(lua_State * L) { return 0; } - + // Get the plugin instance: cPluginLua * Plugin = cManualBindings::GetLuaPlugin(L); if (Plugin == nullptr) @@ -90,7 +90,7 @@ static int tolua_cNetwork_CreateUDPEndpoint(lua_State * L) { return 0; } - + // Get the plugin instance: cPluginLua * Plugin = cManualBindings::GetLuaPlugin(L); if (Plugin == nullptr) @@ -142,7 +142,7 @@ static int tolua_cNetwork_EnumLocalIPAddresses(lua_State * L) { return 0; } - + // Push the enumerated addresses: S.Push(cNetwork::EnumLocalIPAddresses()); return 1; @@ -168,7 +168,7 @@ static int tolua_cNetwork_HostnameToIP(lua_State * L) { return 0; } - + // Get the plugin instance: cPluginLua * Plugin = cManualBindings::GetLuaPlugin(L); if (Plugin == nullptr) @@ -209,7 +209,7 @@ static int tolua_cNetwork_IPToHostname(lua_State * L) { return 0; } - + // Get the plugin instance: cPluginLua * Plugin = cManualBindings::GetLuaPlugin(L); if (Plugin == nullptr) @@ -250,7 +250,7 @@ static int tolua_cNetwork_Listen(lua_State * L) { return 0; } - + // Get the plugin instance: cPluginLua * Plugin = cManualBindings::GetLuaPlugin(L); if (Plugin == nullptr) @@ -320,7 +320,7 @@ static int tolua_cServerHandle_Close(lua_State * L) { return 0; } - + // Get the server handle: cLuaServerHandle * Srv; if (lua_isnil(L, 1)) @@ -354,7 +354,7 @@ static int tolua_cServerHandle_IsListening(lua_State * L) { return 0; } - + // Get the server handle: cLuaServerHandle * Srv; if (lua_isnil(L, 1)) @@ -391,7 +391,7 @@ static int tolua_cTCPLink_Close(lua_State * L) { return 0; } - + // Get the link: cLuaTCPLink * Link; if (lua_isnil(L, 1)) @@ -425,7 +425,7 @@ static int tolua_cTCPLink_GetLocalIP(lua_State * L) { return 0; } - + // Get the link: cLuaTCPLink * Link; if (lua_isnil(L, 1)) @@ -459,7 +459,7 @@ static int tolua_cTCPLink_GetLocalPort(lua_State * L) { return 0; } - + // Get the link: cLuaTCPLink * Link; if (lua_isnil(L, 1)) @@ -493,7 +493,7 @@ static int tolua_cTCPLink_GetRemoteIP(lua_State * L) { return 0; } - + // Get the link: cLuaTCPLink * Link; if (lua_isnil(L, 1)) @@ -527,7 +527,7 @@ static int tolua_cTCPLink_GetRemotePort(lua_State * L) { return 0; } - + // Get the link: cLuaTCPLink * Link; if (lua_isnil(L, 1)) @@ -562,7 +562,7 @@ static int tolua_cTCPLink_Send(lua_State * L) { return 0; } - + // Get the link: cLuaTCPLink * Link; if (lua_isnil(L, 1)) @@ -600,7 +600,7 @@ static int tolua_cTCPLink_Shutdown(lua_State * L) { return 0; } - + // Get the link: cLuaTCPLink * Link; if (lua_isnil(L, 1)) @@ -671,7 +671,7 @@ static int tolua_cTCPLink_StartTLSServer(lua_State * L) { return 0; } - + // Get the link: cLuaTCPLink * Link; if (lua_isnil(L, 1)) @@ -732,7 +732,7 @@ static int tolua_cUDPEndpoint_Close(lua_State * L) { return 0; } - + // Get the endpoint: if (lua_isnil(L, 1)) { @@ -765,7 +765,7 @@ static int tolua_cUDPEndpoint_EnableBroadcasts(lua_State * L) { return 0; } - + // Get the endpoint: if (lua_isnil(L, 1)) { @@ -798,7 +798,7 @@ static int tolua_cUDPEndpoint_GetPort(lua_State * L) { return 0; } - + // Get the endpoint: if (lua_isnil(L, 1)) { @@ -831,7 +831,7 @@ static int tolua_cUDPEndpoint_IsOpen(lua_State * L) { return 0; } - + // Get the endpoint: if (lua_isnil(L, 1)) { @@ -866,7 +866,7 @@ static int tolua_cUDPEndpoint_Send(lua_State * L) { return 0; } - + // Get the link: if (lua_isnil(L, 1)) { @@ -913,7 +913,7 @@ void cManualBindings::BindNetwork(lua_State * tolua_S) tolua_cclass(tolua_S, "cServerHandle", "cServerHandle", "", tolua_collect_cServerHandle); tolua_cclass(tolua_S, "cTCPLink", "cTCPLink", "", nullptr); tolua_cclass(tolua_S, "cUDPEndpoint", "cUDPEndpoint", "", tolua_collect_cUDPEndpoint); - + // Fill in the functions (alpha-sorted): tolua_beginmodule(tolua_S, "cNetwork"); tolua_function(tolua_S, "Connect", tolua_cNetwork_Connect); diff --git a/src/Bindings/ManualBindings_RankManager.cpp b/src/Bindings/ManualBindings_RankManager.cpp index 7797d1887..99c0cc63f 100644 --- a/src/Bindings/ManualBindings_RankManager.cpp +++ b/src/Bindings/ManualBindings_RankManager.cpp @@ -28,11 +28,11 @@ static int tolua_cRankManager_AddGroup(lua_State * L) { return 0; } - + // Read the params: AString GroupName; S.GetStackValue(2, GroupName); - + // Add the group: cRoot::Get()->GetRankManager()->AddGroup(GroupName); return 0; @@ -57,11 +57,11 @@ static int tolua_cRankManager_AddGroupToRank(lua_State * L) { return 0; } - + // Read the params: AString GroupName, RankName; S.GetStackValues(2, GroupName, RankName); - + // Add the group to the rank: S.Push(cRoot::Get()->GetRankManager()->AddGroupToRank(GroupName, RankName)); return 1; @@ -86,11 +86,11 @@ static int tolua_cRankManager_AddPermissionToGroup(lua_State * L) { return 0; } - + // Read the params: AString GroupName, Permission; S.GetStackValues(2, Permission, GroupName); - + // Add the group to the rank: S.Push(cRoot::Get()->GetRankManager()->AddPermissionToGroup(Permission, GroupName)); return 1; @@ -115,11 +115,11 @@ static int tolua_cRankManager_AddRestrictionToGroup(lua_State * L) { return 0; } - + // Read the params: AString GroupName, Permission; S.GetStackValues(2, Permission, GroupName); - + // Add the group to the rank: S.Push(cRoot::Get()->GetRankManager()->AddRestrictionToGroup(Permission, GroupName)); return 1; @@ -134,7 +134,7 @@ static int tolua_cRankManager_AddRank(lua_State * L) { // Function signature: // cRankManager:AddRank(RankName) - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -144,11 +144,11 @@ static int tolua_cRankManager_AddRank(lua_State * L) { return 0; } - + // Read the params: AString RankName, MsgPrefix, MsgSuffix, MsgNameColorCode; S.GetStackValues(2, RankName, MsgPrefix, MsgSuffix, MsgNameColorCode); - + // Add the rank: cRoot::Get()->GetRankManager()->AddRank(RankName, MsgPrefix, MsgSuffix, MsgNameColorCode); return 0; @@ -184,7 +184,7 @@ static int tolua_cRankManager_GetAllGroups(lua_State * L) { // Function signature: // cRankManager:GetAllGroups() -> arraytable of GroupNames - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -193,10 +193,10 @@ static int tolua_cRankManager_GetAllGroups(lua_State * L) { return 0; } - + // Get the groups: AStringVector Groups = cRoot::Get()->GetRankManager()->GetAllGroups(); - + // Push the results: S.Push(Groups); return 1; @@ -211,7 +211,7 @@ static int tolua_cRankManager_GetAllPermissions(lua_State * L) { // Function signature: // cRankManager:GetAllPermissions() -> arraytable of Permissions - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -220,10 +220,10 @@ static int tolua_cRankManager_GetAllPermissions(lua_State * L) { return 0; } - + // Get the permissions: AStringVector Permissions = cRoot::Get()->GetRankManager()->GetAllPermissions(); - + // Push the results: S.Push(Permissions); return 1; @@ -238,7 +238,7 @@ static int tolua_cRankManager_GetAllRestrictions(lua_State * L) { // Function signature: // cRankManager:GetAllRestrictions() -> arraytable of Permissions - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -247,10 +247,10 @@ static int tolua_cRankManager_GetAllRestrictions(lua_State * L) { return 0; } - + // Get the permissions: AStringVector Permissions = cRoot::Get()->GetRankManager()->GetAllRestrictions(); - + // Push the results: S.Push(Permissions); return 1; @@ -265,7 +265,7 @@ static int tolua_cRankManager_GetAllPermissionsRestrictions(lua_State * L) { // Function signature: // cRankManager:GetAllPermissionsRestrictions() -> arraytable of Permissions and Restrictions - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -274,10 +274,10 @@ static int tolua_cRankManager_GetAllPermissionsRestrictions(lua_State * L) { return 0; } - + // Get the permissions: AStringVector Permissions = cRoot::Get()->GetRankManager()->GetAllPermissionsRestrictions(); - + // Push the results: S.Push(Permissions); return 1; @@ -319,7 +319,7 @@ static int tolua_cRankManager_GetAllRanks(lua_State * L) { // Function signature: // cRankManager:GetAllRanks() -> arraytable of RankNames - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -328,10 +328,10 @@ static int tolua_cRankManager_GetAllRanks(lua_State * L) { return 0; } - + // Get the ranks: AStringVector Ranks = cRoot::Get()->GetRankManager()->GetAllRanks(); - + // Push the results: S.Push(Ranks); return 1; @@ -346,7 +346,7 @@ static int tolua_cRankManager_GetDefaultRank(lua_State * L) { // Function signature: // cRankManager:GetDefaultRank() -> string - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -355,7 +355,7 @@ static int tolua_cRankManager_GetDefaultRank(lua_State * L) { return 0; } - + // Return the rank name: S.Push(cRoot::Get()->GetRankManager()->GetDefaultRank()); return 1; @@ -370,7 +370,7 @@ static int tolua_cRankManager_GetGroupPermissions(lua_State * L) { // Function signature: // cRankManager:GetGroupPermissions(GroupName) -> arraytable of permissions - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -380,14 +380,14 @@ static int tolua_cRankManager_GetGroupPermissions(lua_State * L) { return 0; } - + // Get the params: AString GroupName; S.GetStackValue(2, GroupName); - + // Get the permissions: AStringVector Permissions = cRoot::Get()->GetRankManager()->GetGroupPermissions(GroupName); - + // Push the results: S.Push(Permissions); return 1; @@ -402,7 +402,7 @@ static int tolua_cRankManager_GetGroupRestrictions(lua_State * L) { // Function signature: // cRankManager:GetGroupRestrictions(GroupName) -> arraytable of restrictions - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -412,14 +412,14 @@ static int tolua_cRankManager_GetGroupRestrictions(lua_State * L) { return 0; } - + // Get the params: AString GroupName; S.GetStackValue(2, GroupName); - + // Get the restrictions: AStringVector Restrictions = cRoot::Get()->GetRankManager()->GetGroupRestrictions(GroupName); - + // Push the results: S.Push(Restrictions); return 1; @@ -434,7 +434,7 @@ static int tolua_cRankManager_GetPlayerGroups(lua_State * L) { // Function signature: // cRankManager:GetPlayerGroups(PlayerUUID) -> arraytable of GroupNames - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -444,14 +444,14 @@ static int tolua_cRankManager_GetPlayerGroups(lua_State * L) { return 0; } - + // Get the params: AString PlayerUUID; S.GetStackValue(2, PlayerUUID); - + // Get the groups: AStringVector Groups = cRoot::Get()->GetRankManager()->GetPlayerGroups(PlayerUUID); - + // Push the results: S.Push(Groups); return 1; @@ -466,7 +466,7 @@ static int tolua_cRankManager_GetPlayerMsgVisuals(lua_State * L) { // Function signature: // cRankManager:GetPlayerMsgVisuals(PlayerUUID) -> string, string, string - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -476,18 +476,18 @@ static int tolua_cRankManager_GetPlayerMsgVisuals(lua_State * L) { return 0; } - + // Get the params: AString PlayerUUID; S.GetStackValue(2, PlayerUUID); - + // Get the permissions: AString MsgPrefix, MsgSuffix, MsgNameColorCode; if (!cRoot::Get()->GetRankManager()->GetPlayerMsgVisuals(PlayerUUID, MsgPrefix, MsgSuffix, MsgNameColorCode)) { return 0; } - + // Push the results: S.Push(MsgPrefix); S.Push(MsgSuffix); @@ -504,7 +504,7 @@ static int tolua_cRankManager_GetPlayerPermissions(lua_State * L) { // Function signature: // cRankManager:GetPlayerPermissions(PlayerUUID) -> arraytable of permissions - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -514,14 +514,14 @@ static int tolua_cRankManager_GetPlayerPermissions(lua_State * L) { return 0; } - + // Get the params: AString PlayerUUID; S.GetStackValue(2, PlayerUUID); - + // Get the permissions: AStringVector Permissions = cRoot::Get()->GetRankManager()->GetPlayerPermissions(PlayerUUID); - + // Push the results: S.Push(Permissions); return 1; @@ -536,7 +536,7 @@ static int tolua_cRankManager_GetPlayerRestrictions(lua_State * L) { // Function signature: // cRankManager:GetPlayerRestrictions(PlayerUUID) -> arraytable of restrictions - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -546,14 +546,14 @@ static int tolua_cRankManager_GetPlayerRestrictions(lua_State * L) { return 0; } - + // Get the params: AString PlayerUUID; S.GetStackValue(2, PlayerUUID); - + // Get the permissions: AStringVector Restrictions = cRoot::Get()->GetRankManager()->GetPlayerRestrictions(PlayerUUID); - + // Push the results: S.Push(Restrictions); return 1; @@ -568,7 +568,7 @@ static int tolua_cRankManager_GetPlayerRankName(lua_State * L) { // Function signature: // cRankManager:GetPlayerRankName(PlayerUUID) -> string - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -578,14 +578,14 @@ static int tolua_cRankManager_GetPlayerRankName(lua_State * L) { return 0; } - + // Get the params: AString PlayerUUID; S.GetStackValue(2, PlayerUUID); - + // Get the rank name: AString RankName = cRoot::Get()->GetRankManager()->GetPlayerRankName(PlayerUUID); - + // Push the result: S.Push(RankName); return 1; @@ -632,7 +632,7 @@ static int tolua_cRankManager_GetRankGroups(lua_State * L) { // Function signature: // cRankManager:GetRankGroups(RankName) -> arraytable of groupnames - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -642,14 +642,14 @@ static int tolua_cRankManager_GetRankGroups(lua_State * L) { return 0; } - + // Get the params: AString RankName; S.GetStackValue(2, RankName); - + // Get the groups: AStringVector Groups = cRoot::Get()->GetRankManager()->GetRankGroups(RankName); - + // Push the results: S.Push(Groups); return 1; @@ -664,7 +664,7 @@ static int tolua_cRankManager_GetRankPermissions(lua_State * L) { // Function signature: // cRankManager:GetRankPermissions(RankName) -> arraytable of permissions - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -674,14 +674,14 @@ static int tolua_cRankManager_GetRankPermissions(lua_State * L) { return 0; } - + // Get the params: AString RankName; S.GetStackValue(2, RankName); - + // Get the permissions: AStringVector Permissions = cRoot::Get()->GetRankManager()->GetRankPermissions(RankName); - + // Push the results: S.Push(Permissions); return 1; @@ -696,7 +696,7 @@ static int tolua_cRankManager_GetRankRestrictions(lua_State * L) { // Function signature: // cRankManager:GetRankRestrictions(RankName) -> arraytable of restrictions - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -706,14 +706,14 @@ static int tolua_cRankManager_GetRankRestrictions(lua_State * L) { return 0; } - + // Get the params: AString RankName; S.GetStackValue(2, RankName); - + // Get the permissions: AStringVector Restrictions = cRoot::Get()->GetRankManager()->GetRankRestrictions(RankName); - + // Push the results: S.Push(Restrictions); return 1; @@ -728,7 +728,7 @@ static int tolua_cRankManager_GetRankVisuals(lua_State * L) { // Function signature: // cRankManager:GetRankVisuals(RankName) -> MsgPrefix, MsgSuffix, MsgNameColorCode - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -738,11 +738,11 @@ static int tolua_cRankManager_GetRankVisuals(lua_State * L) { return 0; } - + // Get the params: AString RankName; S.GetStackValue(2, RankName); - + // Get the visuals: AString MsgPrefix, MsgSuffix, MsgNameColorCode; if (!cRoot::Get()->GetRankManager()->GetRankVisuals(RankName, MsgPrefix, MsgSuffix, MsgNameColorCode)) @@ -750,7 +750,7 @@ static int tolua_cRankManager_GetRankVisuals(lua_State * L) // No such rank, return nothing: return 0; } - + // Push the results: S.Push(MsgPrefix); S.Push(MsgSuffix); @@ -767,7 +767,7 @@ static int tolua_cRankManager_GroupExists(lua_State * L) { // Function signature: // cRankManager:GroupExists(GroupName) -> bool - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -777,14 +777,14 @@ static int tolua_cRankManager_GroupExists(lua_State * L) { return 0; } - + // Get the params: AString GroupName; S.GetStackValue(2, GroupName); - + // Get the response: bool res = cRoot::Get()->GetRankManager()->GroupExists(GroupName); - + // Push the result: S.Push(res); return 1; @@ -799,7 +799,7 @@ static int tolua_cRankManager_IsGroupInRank(lua_State * L) { // Function signature: // cRankManager:IsGroupInRank(GroupName, RankName) -> bool - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -809,14 +809,14 @@ static int tolua_cRankManager_IsGroupInRank(lua_State * L) { return 0; } - + // Get the params: AString GroupName, RankName; S.GetStackValues(2, GroupName, RankName); - + // Get the response: bool res = cRoot::Get()->GetRankManager()->IsGroupInRank(GroupName, RankName); - + // Push the result: S.Push(res); return 1; @@ -831,7 +831,7 @@ static int tolua_cRankManager_IsPermissionInGroup(lua_State * L) { // Function signature: // cRankManager:IsPermissionInGroup(Permission, GroupName) -> bool - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -841,14 +841,14 @@ static int tolua_cRankManager_IsPermissionInGroup(lua_State * L) { return 0; } - + // Get the params: AString GroupName, Permission; S.GetStackValues(2, Permission, GroupName); - + // Get the response: bool res = cRoot::Get()->GetRankManager()->IsPermissionInGroup(Permission, GroupName); - + // Push the result: S.Push(res); return 1; @@ -863,7 +863,7 @@ static int tolua_cRankManager_IsRestrictionInGroup(lua_State * L) { // Function signature: // cRankManager:IsRestrictionInGroup(Restriction, GroupName) -> bool - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -873,14 +873,14 @@ static int tolua_cRankManager_IsRestrictionInGroup(lua_State * L) { return 0; } - + // Get the params: AString GroupName, Restriction; S.GetStackValues(2, Restriction, GroupName); - + // Get the response: bool res = cRoot::Get()->GetRankManager()->IsRestrictionInGroup(Restriction, GroupName); - + // Push the result: S.Push(res); return 1; @@ -895,7 +895,7 @@ static int tolua_cRankManager_IsPlayerRankSet(lua_State * L) { // Function signature: // cRankManager:IsPlayerRankSet(PlayerUUID) -> bool - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -905,14 +905,14 @@ static int tolua_cRankManager_IsPlayerRankSet(lua_State * L) { return 0; } - + // Get the params: AString PlayerUUID; S.GetStackValue(2, PlayerUUID); - + // Get the response: bool res = cRoot::Get()->GetRankManager()->IsPlayerRankSet(PlayerUUID); - + // Push the result: S.Push(res); return 1; @@ -927,7 +927,7 @@ static int tolua_cRankManager_RankExists(lua_State * L) { // Function signature: // cRankManager:RankExists(RankName) -> bool - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -937,14 +937,14 @@ static int tolua_cRankManager_RankExists(lua_State * L) { return 0; } - + // Get the params: AString RankName; S.GetStackValue(2, RankName); - + // Get the response: bool res = cRoot::Get()->GetRankManager()->RankExists(RankName); - + // Push the result: S.Push(res); return 1; @@ -959,7 +959,7 @@ static int tolua_cRankManager_RemoveGroup(lua_State * L) { // Function signature: // cRankManager:RemoveGroup(GroupName) - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -969,11 +969,11 @@ static int tolua_cRankManager_RemoveGroup(lua_State * L) { return 0; } - + // Get the params: AString GroupName; S.GetStackValue(2, GroupName); - + // Remove the group: cRoot::Get()->GetRankManager()->RemoveGroup(GroupName); return 0; @@ -988,7 +988,7 @@ static int tolua_cRankManager_RemoveGroupFromRank(lua_State * L) { // Function signature: // cRankManager:RemoveGroupFromRank(GroupName, RankName) - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -998,11 +998,11 @@ static int tolua_cRankManager_RemoveGroupFromRank(lua_State * L) { return 0; } - + // Get the params: AString GroupName, RankName; S.GetStackValues(2, GroupName, RankName); - + // Remove the group: cRoot::Get()->GetRankManager()->RemoveGroupFromRank(GroupName, RankName); return 0; @@ -1017,7 +1017,7 @@ static int tolua_cRankManager_RemovePermissionFromGroup(lua_State * L) { // Function signature: // cRankManager:RemovePermissionFromGroup(Permission, GroupName) - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -1027,11 +1027,11 @@ static int tolua_cRankManager_RemovePermissionFromGroup(lua_State * L) { return 0; } - + // Get the params: AString GroupName, Permission; S.GetStackValues(2, Permission, GroupName); - + // Remove the permission: cRoot::Get()->GetRankManager()->RemovePermissionFromGroup(Permission, GroupName); return 0; @@ -1046,7 +1046,7 @@ static int tolua_cRankManager_RemoveRestrictionFromGroup(lua_State * L) { // Function signature: // cRankManager:RemoveRestrictionFromGroup(Restriction, GroupName) - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -1056,11 +1056,11 @@ static int tolua_cRankManager_RemoveRestrictionFromGroup(lua_State * L) { return 0; } - + // Get the params: AString GroupName, Restriction; S.GetStackValues(2, Restriction, GroupName); - + // Remove the restriction: cRoot::Get()->GetRankManager()->RemoveRestrictionFromGroup(Restriction, GroupName); return 0; @@ -1075,7 +1075,7 @@ static int tolua_cRankManager_RemovePlayerRank(lua_State * L) { // Function signature: // cRankManager:RemovePlayerRank(PlayerUUID) - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -1085,11 +1085,11 @@ static int tolua_cRankManager_RemovePlayerRank(lua_State * L) { return 0; } - + // Get the params: AString PlayerUUID; S.GetStackValue(2, PlayerUUID); - + // Remove the player's rank: cRoot::Get()->GetRankManager()->RemovePlayerRank(PlayerUUID); return 0; @@ -1104,7 +1104,7 @@ static int tolua_cRankManager_RemoveRank(lua_State * L) { // Function signature: // cRankManager:RemoveRank(RankName, [ReplacementRankName]) - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -1115,11 +1115,11 @@ static int tolua_cRankManager_RemoveRank(lua_State * L) { return 0; } - + // Get the params: AString RankName, ReplacementRankName; S.GetStackValues(2, RankName, ReplacementRankName); - + // Remove the rank: cRoot::Get()->GetRankManager()->RemoveRank(RankName, ReplacementRankName); return 0; @@ -1134,7 +1134,7 @@ static int tolua_cRankManager_RenameGroup(lua_State * L) { // Function signature: // cRankManager:RenameGroup(OldName, NewName) - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -1144,14 +1144,14 @@ static int tolua_cRankManager_RenameGroup(lua_State * L) { return 0; } - + // Get the params: AString OldName, NewName; S.GetStackValues(2, OldName, NewName); - + // Remove the group: bool res = cRoot::Get()->GetRankManager()->RenameGroup(OldName, NewName); - + // Push the result: S.Push(res); return 1; @@ -1166,7 +1166,7 @@ static int tolua_cRankManager_RenameRank(lua_State * L) { // Function signature: // cRankManager:RenameRank(OldName, NewName) - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -1176,14 +1176,14 @@ static int tolua_cRankManager_RenameRank(lua_State * L) { return 0; } - + // Get the params: AString OldName, NewName; S.GetStackValues(2, OldName, NewName); - + // Remove the rank: bool res = cRoot::Get()->GetRankManager()->RenameRank(OldName, NewName); - + // Push the result: S.Push(res); return 1; @@ -1198,7 +1198,7 @@ static int tolua_cRankManager_SetDefaultRank(lua_State * L) { // Function signature: // cRankManager:SetDefaultRank(RankName) -> bool - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -1208,11 +1208,11 @@ static int tolua_cRankManager_SetDefaultRank(lua_State * L) { return 0; } - + // Get the params: AString RankName; S.GetStackValue(2, RankName); - + // Set the rank, return the result: S.Push(cRoot::Get()->GetRankManager()->SetDefaultRank(RankName)); return 1; @@ -1227,7 +1227,7 @@ static int tolua_cRankManager_SetPlayerRank(lua_State * L) { // Function signature: // cRankManager:SetPlayerRank(PlayerUUID, PlayerName, RankName) - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -1237,11 +1237,11 @@ static int tolua_cRankManager_SetPlayerRank(lua_State * L) { return 0; } - + // Get the params: AString PlayerUUID, PlayerName, RankName; S.GetStackValues(2, PlayerUUID, PlayerName, RankName); - + // Set the rank: cRoot::Get()->GetRankManager()->SetPlayerRank(PlayerUUID, PlayerName, RankName); return 0; @@ -1256,7 +1256,7 @@ static int tolua_cRankManager_SetRankVisuals(lua_State * L) { // Function signature: // cRankManager:SetRankVisuals(RankName, MsgPrefix, MsgSuffix, MsgNameColorCode) - + cLuaState S(L); if ( !S.CheckParamUserTable(1, "cRankManager") || @@ -1266,11 +1266,11 @@ static int tolua_cRankManager_SetRankVisuals(lua_State * L) { return 0; } - + // Get the params: AString RankName, MsgPrefix, MsgSuffix, MsgNameColorCode; S.GetStackValues(2, RankName, MsgPrefix, MsgSuffix, MsgNameColorCode); - + // Set the visuals: cRoot::Get()->GetRankManager()->SetRankVisuals(RankName, MsgPrefix, MsgSuffix, MsgNameColorCode); return 0; @@ -1285,7 +1285,7 @@ void cManualBindings::BindRankManager(lua_State * tolua_S) // Create the cRankManager class in the API: tolua_usertype(tolua_S, "cRankManager"); tolua_cclass(tolua_S, "cRankManager", "cRankManager", "", nullptr); - + // Fill in the functions (alpha-sorted): tolua_beginmodule(tolua_S, "cRankManager"); tolua_function(tolua_S, "AddGroup", tolua_cRankManager_AddGroup); diff --git a/src/Bindings/ManualBindings_World.cpp b/src/Bindings/ManualBindings_World.cpp index f40af9778..00d2169d8 100644 --- a/src/Bindings/ManualBindings_World.cpp +++ b/src/Bindings/ManualBindings_World.cpp @@ -30,7 +30,7 @@ static int tolua_cWorld_BroadcastParticleEffect(lua_State * tolua_S) { return 0; } - + // Read the params: cWorld * World = nullptr; AString Name; @@ -68,7 +68,7 @@ static int tolua_cWorld_ChunkStay(lua_State * tolua_S) World:ChunkStay(ChunkCoordTable, OnChunkAvailable, OnAllChunksAvailable) ChunkCoordTable == { {Chunk1x, Chunk1z}, {Chunk2x, Chunk2z}, ... } */ - + cLuaState L(tolua_S); if ( !L.CheckParamUserType (1, "cWorld") || @@ -78,13 +78,13 @@ static int tolua_cWorld_ChunkStay(lua_State * tolua_S) { return 0; } - + cPluginLua * Plugin = cManualBindings::GetLuaPlugin(tolua_S); if (Plugin == nullptr) { return 0; } - + // Read the params: cWorld * World = reinterpret_cast(tolua_tousertype(tolua_S, 1, nullptr)); if (World == nullptr) @@ -116,7 +116,7 @@ static int tolua_cWorld_DoExplosionAt(lua_State * tolua_S) /* Function signature: World:DoExplosionAt(ExplosionSize, BlockX, BlockY, BlockZ, CanCauseFire, SourceType, [SourceData]) */ - + cLuaState L(tolua_S); if ( !L.CheckParamUserType (1, "cWorld") || @@ -128,7 +128,7 @@ static int tolua_cWorld_DoExplosionAt(lua_State * tolua_S) { return 0; } - + // Read the params: cWorld * World; double ExplosionSize; @@ -405,7 +405,7 @@ static int tolua_cWorld_PrepareChunk(lua_State * tolua_S) /* Function signature: World:PrepareChunk(ChunkX, ChunkZ, Callback) */ - + // Check the param types: cLuaState L(tolua_S); if ( @@ -416,7 +416,7 @@ static int tolua_cWorld_PrepareChunk(lua_State * tolua_S) { return 0; } - + // Read the params: cWorld * world = nullptr; int chunkX = 0; @@ -497,7 +497,7 @@ static int tolua_cWorld_QueueTask(lua_State * tolua_S) { // Binding for cWorld::QueueTask // Params: function - + // Retrieve the cPlugin from the LuaState: cPluginLua * Plugin = cManualBindings::GetLuaPlugin(tolua_S); if (Plugin == nullptr) @@ -578,7 +578,7 @@ static int tolua_cWorld_ScheduleTask(lua_State * tolua_S) { // Binding for cWorld::ScheduleTask // Params: function, Ticks - + // Retrieve the cPlugin from the LuaState: cPluginLua * Plugin = cManualBindings::GetLuaPlugin(tolua_S); if (Plugin == nullptr) @@ -609,7 +609,7 @@ static int tolua_cWorld_ScheduleTask(lua_State * tolua_S) { return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #1"); } - + auto ResettableTask = std::make_shared(*Plugin, FnRef); Plugin->AddResettable(ResettableTask); World->ScheduleTask(static_cast(tolua_tonumber(tolua_S, 2, 0)), std::bind(&cLuaWorldTask::Run, ResettableTask, std::placeholders::_1)); diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index b8fc97a06..3ee417361 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -20,14 +20,14 @@ class cPlugin { public: // tolua_end - + /** Creates a new instance. a_FolderName is the name of the folder (in the Plugins folder) from which the plugin is loaded. The plugin's name defaults to the folder name. */ cPlugin(const AString & a_FolderName); virtual ~cPlugin(); - + /** Called as the last call into the plugin before it is unloaded. */ virtual void OnDisable(void) {} @@ -109,22 +109,22 @@ public: virtual bool OnWeatherChanging (cWorld & a_World, eWeather & a_NewWeather) = 0; virtual bool OnWorldStarted (cWorld & a_World) = 0; virtual bool OnWorldTick (cWorld & a_World, std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_LastTickDurationMSec) = 0; - + /** Handles the command split into a_Split, issued by player a_Player. Command permissions have already been checked. Returns true if command handled successfully. */ virtual bool HandleCommand(const AStringVector & a_Split, cPlayer & a_Player, const AString & a_FullCommand) = 0; - + /** Handles the console command split into a_Split. Returns true if command handled successfully. Output is to be sent to the a_Output callback. */ virtual bool HandleConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output, const AString & a_FullCommand) = 0; - + /** All bound commands are to be removed, do any language-dependent cleanup here */ virtual void ClearCommands(void) {} - + /** All bound console commands are to be removed, do any language-dependent cleanup here */ virtual void ClearConsoleCommands(void) {} - + // tolua_begin const AString & GetName(void) const { return m_Name; } void SetName(const AString & a_Name) { m_Name = a_Name; } @@ -145,7 +145,7 @@ public: bool IsLoaded(void) const { return (m_Status == cPluginManager::psLoaded); } // tolua_end - + // Needed for ManualBindings' tolua_ForEach<> static const char * GetClassStatic(void) { return "cPlugin"; } diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index 1b7a18ff1..a266e6223 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -105,13 +105,13 @@ bool cPluginLua::Load(void) { m_LuaState.Create(); m_LuaState.RegisterAPILibs(); - + // Inject the identification global variables into the state: lua_pushlightuserdata(m_LuaState, this); lua_setglobal(m_LuaState, LUA_PLUGIN_INSTANCE_VAR_NAME); lua_pushstring(m_LuaState, GetName().c_str()); lua_setglobal(m_LuaState, LUA_PLUGIN_NAME_VAR_NAME); - + // Add the plugin's folder to the package.path and package.cpath variables (#693): m_LuaState.AddPackagePath("path", FILE_IO_PREFIX + GetLocalFolder() + "/?.lua"); #ifdef _WIN32 @@ -119,7 +119,7 @@ bool cPluginLua::Load(void) #else m_LuaState.AddPackagePath("cpath", FILE_IO_PREFIX + GetLocalFolder() + "/?.so"); #endif - + tolua_pushusertype(m_LuaState, this, "cPluginLua"); lua_setglobal(m_LuaState, "g_Plugin"); } @@ -145,7 +145,7 @@ bool cPluginLua::Load(void) } } std::sort(LuaFiles.begin(), LuaFiles.end()); - + // Warn if there are no Lua files in the plugin folder: if (LuaFiles.empty()) { @@ -1879,7 +1879,7 @@ bool cPluginLua::HandleCommand(const AStringVector & a_Split, cPlayer & a_Player LOGWARNING("Command handler is registered in cPluginManager but not in cPlugin, wtf? Command \"%s\".", a_Split[0].c_str()); return false; } - + cCSLock Lock(m_CriticalSection); bool res = false; m_LuaState.Call(cmd->second, a_Split, &a_Player, a_FullCommand, cLuaState::Return, res); @@ -1901,7 +1901,7 @@ bool cPluginLua::HandleConsoleCommand(const AStringVector & a_Split, cCommandOut ); return false; } - + cCSLock Lock(m_CriticalSection); bool res = false; AString str; @@ -1967,13 +1967,13 @@ bool cPluginLua::CanAddOldStyleHook(int a_HookType) m_LuaState.LogStackTrace(); return false; } - + // Check if the function is available if (m_LuaState.HasFunction(FnName)) { return true; } - + LOGWARNING("Plugin %s wants to add a hook (%d), but it doesn't provide the callback function \"%s\" for it. The plugin need not work properly.", GetName().c_str(), a_HookType, FnName ); @@ -2042,7 +2042,7 @@ const char * cPluginLua::GetHookFnName(int a_HookType) case cPluginManager::HOOK_WEATHER_CHANGED: return "OnWeatherChanged"; case cPluginManager::HOOK_WEATHER_CHANGING: return "OnWeatherChanging"; case cPluginManager::HOOK_WORLD_TICK: return "OnWorldTick"; - + case cPluginManager::HOOK_NUM_HOOKS: { // Satisfy a warning that all enum values should be used in a switch @@ -2062,7 +2062,7 @@ const char * cPluginLua::GetHookFnName(int a_HookType) bool cPluginLua::AddHookRef(int a_HookType, int a_FnRefIdx) { ASSERT(m_CriticalSection.IsLockedByCurrentThread()); // It probably has to be, how else would we have a LuaState? - + // Check if the function reference is valid: cLuaState::cRef * Ref = new cLuaState::cRef(m_LuaState, a_FnRefIdx); if ((Ref == nullptr) || !Ref->IsValid()) @@ -2073,7 +2073,7 @@ bool cPluginLua::AddHookRef(int a_HookType, int a_FnRefIdx) Ref = nullptr; return false; } - + m_HookMap[a_HookType].push_back(Ref); return true; } @@ -2090,7 +2090,7 @@ int cPluginLua::CallFunctionFromForeignState( ) { cCSLock Lock(m_CriticalSection); - + // Call the function: int NumReturns = m_LuaState.CallFunctionWithForeignParams(a_FunctionName, a_ForeignState, a_ParamStart, a_ParamEnd); if (NumReturns < 0) @@ -2098,17 +2098,17 @@ int cPluginLua::CallFunctionFromForeignState( // The call has failed, an error has already been output to the log, so just silently bail out with the same error return NumReturns; } - + // Copy all the return values: int Top = lua_gettop(m_LuaState); int res = a_ForeignState.CopyStackFrom(m_LuaState, Top - NumReturns + 1, Top); - + // Remove the return values off this stack: if (NumReturns > 0) { lua_pop(m_LuaState, NumReturns); } - + return res; } @@ -2204,7 +2204,7 @@ void cPluginLua::Unreference(int a_LuaRef) bool cPluginLua::CallbackWindowClosing(int a_FnRef, cWindow & a_Window, cPlayer & a_Player, bool a_CanRefuse) { ASSERT(a_FnRef != LUA_REFNIL); - + cCSLock Lock(m_CriticalSection); bool res = false; m_LuaState.Call(a_FnRef, &a_Window, &a_Player, a_CanRefuse, cLuaState::Return, res); @@ -2218,7 +2218,7 @@ bool cPluginLua::CallbackWindowClosing(int a_FnRef, cWindow & a_Window, cPlayer void cPluginLua::CallbackWindowSlotChanged(int a_FnRef, cWindow & a_Window, int a_SlotNum) { ASSERT(a_FnRef != LUA_REFNIL); - + cCSLock Lock(m_CriticalSection); m_LuaState.Call(a_FnRef, &a_Window, a_SlotNum); } diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 59e56c0e7..db6612671 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -36,7 +36,7 @@ class cPluginLua : public: // tolua_end - + /** A RAII-style mutex lock for accessing the internal LuaState. This will be the only way to retrieve the plugin's LuaState; therefore it directly supports accessing the LuaState of the locked plugin. @@ -54,10 +54,10 @@ public: } cLuaState & operator ()(void) { return m_Plugin.m_LuaState; } - + protected: cPluginLua & m_Plugin; - + /** RAII lock for m_Plugin.m_CriticalSection */ cCSLock m_Lock; } ; @@ -92,8 +92,8 @@ public: typedef SharedPtr cResettablePtr; typedef std::vector cResettablePtrs; - - + + cPluginLua(const AString & a_PluginDirectory); ~cPluginLua(); @@ -169,18 +169,18 @@ public: virtual bool OnWeatherChanging (cWorld & a_World, eWeather & a_NewWeather) override; virtual bool OnWorldStarted (cWorld & a_World) override; virtual bool OnWorldTick (cWorld & a_World, std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_LastTickDurationMSec) override; - + virtual bool HandleCommand(const AStringVector & a_Split, cPlayer & a_Player, const AString & a_FullCommand) override; - + virtual bool HandleConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output, const AString & a_FullCommand) override; virtual void ClearCommands(void) override; - + virtual void ClearConsoleCommands(void) override; /** Returns true if the plugin contains the function for the specified hook type, using the old-style registration (#121) */ bool CanAddOldStyleHook(int a_HookType); - + // cWebPlugin overrides virtual const AString GetWebTitle(void) const override {return GetName(); } virtual AString HandleWebRequest(const HTTPRequest & a_Request) override; @@ -188,7 +188,7 @@ public: /** Adds a new web tab to webadmin. Displaying the tab calls the referenced function. */ bool AddWebTab(const AString & a_Title, lua_State * a_LuaState, int a_FunctionReference); // Exported in ManualBindings.cpp - + /** Binds the command to call the function specified by a Lua function reference. Simply adds to CommandMap. */ void BindCommand(const AString & a_Command, int a_FnRef); @@ -198,25 +198,25 @@ public: cLuaState & GetLuaState(void) { return m_LuaState; } cCriticalSection & GetCriticalSection(void) { return m_CriticalSection; } - + /** Removes a previously referenced object (luaL_unref()) */ void Unreference(int a_LuaRef); - + /** Calls the plugin-specified "cLuaWindow closing" callback. Returns true only if the callback returned true */ bool CallbackWindowClosing(int a_FnRef, cWindow & a_Window, cPlayer & a_Player, bool a_CanRefuse); - + /** Calls the plugin-specified "cLuaWindow slot changed" callback. */ void CallbackWindowSlotChanged(int a_FnRef, cWindow & a_Window, int a_SlotNum); - + /** Returns the name of Lua function that should handle the specified hook type in the older (#121) API */ static const char * GetHookFnName(int a_HookType); - + /** Adds a Lua function to be called for the specified hook. The function has to be on the Lua stack at the specified index a_FnRefIdx Returns true if the hook was added successfully. */ bool AddHookRef(int a_HookType, int a_FnRefIdx); - + /** Calls a function in this plugin's LuaState with parameters copied over from a_ForeignState. The values that the function returns are placed onto a_ForeignState. Returns the number of values returned, if successful, or negative number on failure. */ @@ -226,7 +226,7 @@ public: int a_ParamStart, int a_ParamEnd ); - + /** Call a Lua function residing in the plugin. */ template bool Call(FnT a_Fn, Args && ... a_Args) @@ -241,20 +241,20 @@ public: protected: /** Maps command name into Lua function reference */ typedef std::map CommandMap; - + /** Provides an array of Lua function references */ typedef std::vector cLuaRefs; - + /** Maps hook types into arrays of Lua function references to call for each hook type */ typedef std::map cHookMap; - + /** The mutex protecting m_LuaState and each of the m_Resettables[] against multithreaded use. */ cCriticalSection m_CriticalSection; /** The plugin's Lua state. */ cLuaState m_LuaState; - + /** Objects that need notification when the plugin is about to be unloaded. */ cResettablePtrs m_Resettables; @@ -263,10 +263,10 @@ protected: /** Console commands that the plugin has registered. */ CommandMap m_ConsoleCommands; - + /** Hooks that the plugin has registered. */ cHookMap m_HookMap; - + /** Releases all Lua references, notifies and removes all m_Resettables[] and closes the m_LuaState. */ void Close(void); diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index bf907b31d..5b3ef7803 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -317,21 +317,21 @@ bool cPluginManager::CallHookChat(cPlayer & a_Player, AString & a_Message) // The command has executed successfully return true; } - + case crBlocked: { // The command was blocked by a plugin using HOOK_EXECUTE_COMMAND // The plugin has most likely sent a message to the player already return true; } - + case crError: { // An error in the plugin has prevented the command from executing. Report the error to the player: a_Player.SendMessageFailure(Printf("Something went wrong while executing command \"%s\"", a_Message.c_str())); return true; } - + case crNoPermission: { // The player is not allowed to execute this command diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index 58ec74f53..f3f0b6d0b 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -143,10 +143,10 @@ public: HOOK_WORLD_TICK, // tolua_end - + // Note that if a hook type is added, it may need processing in cPlugin::CanAddHook() descendants, // and it definitely needs adding in cPluginLua::GetHookFnName() ! - + // Keep these two as the last items, they are used for validity checking and get their values automagically HOOK_NUM_HOOKS, HOOK_MAX = HOOK_NUM_HOOKS - 1, @@ -157,22 +157,22 @@ public: { public: virtual ~cCommandEnumCallback() {} - + /** Called for each command; return true to abort enumeration For console commands, a_Permission is not used (set to empty string) */ virtual bool Command(const AString & a_Command, const cPlugin * a_Plugin, const AString & a_Permission, const AString & a_HelpString) = 0; } ; - + /** The interface used for enumerating and extern-calling plugins */ typedef cItemCallback cPluginCallback; - + typedef std::list PluginList; /** Called each tick, calls the plugins' OnTick hook, as well as processes plugin events (addition, removal) */ void Tick(float a_Dt); - + /** Returns the instance of the Plugin Manager (there is only ever one) */ static cPluginManager * Get(void); // tolua_export @@ -182,7 +182,7 @@ public: /** Schedules a reload of the plugins to happen within the next call to Tick(). */ void ReloadPlugins(); // tolua_export - + /** Adds the plugin to the list of plugins called for the specified hook type. If a plugin adds multiple handlers for a single hook, it is added only once (ignore-duplicates). */ void AddHook(cPlugin * a_Plugin, int a_HookType); @@ -192,7 +192,7 @@ public: /** Returns the number of plugins that are psLoaded. */ size_t GetNumLoadedPlugins(void) const; // tolua_export - + // Calls for individual hooks. Each returns false if the action is to continue or true if the plugin wants to abort bool CallHookBlockSpread (cWorld & a_World, int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source); bool CallHookBlockToPickups (cWorld & a_World, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups); @@ -260,7 +260,7 @@ public: bool CallHookWeatherChanging (cWorld & a_World, eWeather & a_NewWeather); bool CallHookWorldStarted (cWorld & a_World); bool CallHookWorldTick (cWorld & a_World, std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_LastTickDurationMSec); - + /** Queues the specified plugin to be unloaded in the next call to Tick(). Note that this function returns before the plugin is unloaded, to avoid deadlocks. */ void UnloadPlugin(const AString & a_PluginFolder); // tolua_export @@ -271,10 +271,10 @@ public: /** Removes all hooks the specified plugin has registered */ void RemoveHooks(cPlugin * a_Plugin); - + /** Removes the plugin of the specified name from the internal structures and deletes its object. */ void RemovePlugin(const AString & a_PluginName); - + /** Removes all command bindings that the specified plugin has made */ void RemovePluginCommands(cPlugin * a_Plugin); @@ -283,47 +283,47 @@ public: /** Binds a command to the specified plugin. Returns true if successful, false if command already bound. */ bool BindCommand(const AString & a_Command, cPlugin * a_Plugin, const AString & a_Permission, const AString & a_HelpString); // Exported in ManualBindings.cpp, without the a_Plugin param - + /** Calls a_Callback for each bound command, returns true if all commands were enumerated */ bool ForEachCommand(cCommandEnumCallback & a_Callback); // Exported in ManualBindings.cpp - + /** Returns true if the command is in the command map */ bool IsCommandBound(const AString & a_Command); // tolua_export - + /** Returns the permission needed for the specified command; empty string if command not found */ AString GetCommandPermission(const AString & a_Command); // tolua_export - + /** Executes the command, as if it was requested by a_Player. Checks permissions first. Returns crExecuted if executed. */ CommandResult ExecuteCommand(cPlayer & a_Player, const AString & a_Command); // tolua_export - + /** Executes the command, as if it was requested by a_Player. Permisssions are not checked. Returns crExecuted if executed. */ CommandResult ForceExecuteCommand(cPlayer & a_Player, const AString & a_Command); // tolua_export - + /** Removes all console command bindings that the specified plugin has made */ void RemovePluginConsoleCommands(cPlugin * a_Plugin); - + /** Binds a console command to the specified plugin. Returns true if successful, false if command already bound. */ bool BindConsoleCommand(const AString & a_Command, cPlugin * a_Plugin, const AString & a_HelpString); // Exported in ManualBindings.cpp, without the a_Plugin param - + /** Calls a_Callback for each bound console command, returns true if all commands were enumerated */ bool ForEachConsoleCommand(cCommandEnumCallback & a_Callback); // Exported in ManualBindings.cpp - + /** Returns true if the console command is in the command map */ bool IsConsoleCommandBound(const AString & a_Command); // tolua_export - + /** Executes the command split into a_Split, as if it was given on the console. Returns true if executed. Output is sent to the a_Output callback Exported in ManualBindings.cpp with a different signature. */ bool ExecuteConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output, const AString & a_Command); - + /** Appends all commands beginning with a_Text (case-insensitive) into a_Results. If a_Player is not nullptr, only commands for which the player has permissions are added. */ void TabCompleteCommand(const AString & a_Text, AStringVector & a_Results, cPlayer * a_Player); - + /** Returns true if the specified hook type is within the allowed range */ static bool IsValidHookType(int a_HookType); - + /** Calls the specified callback with the plugin object of the specified plugin. Returns false if plugin not found, otherwise returns the value that the callback has returned. */ bool DoWithPlugin(const AString & a_PluginName, cPluginCallback & a_Callback); @@ -331,14 +331,14 @@ public: /** Calls the specified callback for each plugin in m_Plugins. Returns true if all plugins have been reported, false if the callback has aborted the enumeration by returning true. */ bool ForEachPlugin(cPluginCallback & a_Callback); - + /** Returns the path where individual plugins' folders are expected. The path doesn't end in a slash. */ static AString GetPluginsPath(void) { return FILE_IO_PREFIX + AString("Plugins"); } // tolua_export - + private: friend class cRoot; - + class cCommandReg { public: @@ -346,7 +346,7 @@ private: AString m_Permission; // Not used for console commands AString m_HelpString; } ; - + typedef std::map HookMap; typedef std::map CommandMap; diff --git a/src/Bindings/WebPlugin.h b/src/Bindings/WebPlugin.h index ade4f4359..6dc8db801 100644 --- a/src/Bindings/WebPlugin.h +++ b/src/Bindings/WebPlugin.h @@ -40,7 +40,7 @@ public: /** Returns the title of the plugin, as it should be presented in the webadmin's pages tree. */ virtual const AString GetWebTitle(void) const = 0; - + /** Sanitizes the input string, replacing spaces with underscores. */ static AString SafeString(const AString & a_String); diff --git a/src/BiomeDef.cpp b/src/BiomeDef.cpp index 9dbdf05a2..f5c96ad4e 100644 --- a/src/BiomeDef.cpp +++ b/src/BiomeDef.cpp @@ -42,7 +42,7 @@ static struct {biExtremeHillsEdge, "ExtremeHillsEdge"}, {biJungle, "Jungle"}, {biJungleHills, "JungleHills"}, - + // Release 1.7 biomes: {biJungleEdge, "JungleEdge"}, {biDeepOcean, "DeepOcean"}, @@ -61,7 +61,7 @@ static struct {biMesa, "Mesa"}, {biMesaPlateauF, "MesaPlateauF"}, {biMesaPlateau, "MesaPlateau"}, - + // Release 1.7 variants: {biSunflowerPlains, "SunflowerPlains"}, {biDesertM, "DesertM"}, @@ -107,7 +107,7 @@ EMCSBiome StringToBiome(const AString & a_BiomeString) // It was an invalid number return biInvalidBiome; } - + for (size_t i = 0; i < ARRAYCOUNT(g_BiomeMap); i++) { if (NoCaseCompare(g_BiomeMap[i].m_String, a_BiomeString) == 0) @@ -239,7 +239,7 @@ int GetSnowStartHeight(EMCSBiome a_Biome) // Always snow return 0; } - + case biExtremeHills: case biExtremeHillsM: case biExtremeHillsPlus: @@ -338,7 +338,7 @@ int GetSnowStartHeight(EMCSBiome a_Biome) // These biomes don't actualy have any downfall. return 1000; } - + case biNether: case biEnd: { diff --git a/src/BiomeDef.h b/src/BiomeDef.h index 0fad23100..1c561bb8c 100644 --- a/src/BiomeDef.h +++ b/src/BiomeDef.h @@ -49,7 +49,7 @@ enum EMCSBiome biExtremeHillsEdge = 20, biJungle = 21, biJungleHills = 22, - + // Release 1.7 biomes: biJungleEdge = 23, biDeepOcean = 24, @@ -68,14 +68,14 @@ enum EMCSBiome biMesa = 37, biMesaPlateauF = 38, biMesaPlateau = 39, - + // Automatically capture the maximum consecutive biome value into biMaxBiome: biNumBiomes, // True number of biomes, since they are zero-based biMaxBiome = biNumBiomes - 1, // The maximum biome value - + // Add this number to the biomes to get the variant biVariant = 128, - + // Release 1.7 biome variants: biFirstVariantBiome = 129, biSunflowerPlains = 129, diff --git a/src/BlockArea.cpp b/src/BlockArea.cpp index 34d3bf54a..2ac41a721 100644 --- a/src/BlockArea.cpp +++ b/src/BlockArea.cpp @@ -146,7 +146,7 @@ void MergeCombinatorLake(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE } return; } - + // Water and lava are never overwritten switch (a_DstType) { @@ -158,7 +158,7 @@ void MergeCombinatorLake(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE return; } } - + // Water and lava always overwrite switch (a_SrcType) { @@ -175,7 +175,7 @@ void MergeCombinatorLake(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE return; } } - + if (a_SrcType == E_BLOCK_STONE) { switch (a_DstType) @@ -342,7 +342,7 @@ void cBlockArea::Create(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes) { LOGWARNING("Creating a cBlockArea with height larger than world height (%d). Continuing, but the area may misbehave.", a_SizeY); } - + Clear(); int BlockCount = a_SizeX * a_SizeY * a_SizeZ; if ((a_DataTypes & baTypes) != 0) @@ -445,12 +445,12 @@ bool cBlockArea::Read(cForEachChunkProvider * a_ForEachChunkProvider, int a_MinB { std::swap(a_MinBlockZ, a_MaxBlockZ); } - + // Include the Max coords: a_MaxBlockX += 1; a_MaxBlockY += 1; a_MaxBlockZ += 1; - + // Check coords validity: if (a_MinBlockY < 0) { @@ -480,7 +480,7 @@ bool cBlockArea::Read(cForEachChunkProvider * a_ForEachChunkProvider, int a_MinB ); a_MaxBlockY = cChunkDef::Height; } - + // Allocate the needed memory: Clear(); if (!SetSize(a_MaxBlockX - a_MinBlockX, a_MaxBlockY - a_MinBlockY, a_MaxBlockZ - a_MinBlockZ, a_DataTypes)) @@ -489,20 +489,20 @@ bool cBlockArea::Read(cForEachChunkProvider * a_ForEachChunkProvider, int a_MinB } m_Origin.Set(a_MinBlockX, a_MinBlockY, a_MinBlockZ); cChunkReader Reader(*this); - + // Convert block coords to chunks coords: int MinChunkX, MaxChunkX; int MinChunkZ, MaxChunkZ; cChunkDef::AbsoluteToRelative(a_MinBlockX, a_MinBlockY, a_MinBlockZ, MinChunkX, MinChunkZ); cChunkDef::AbsoluteToRelative(a_MaxBlockX, a_MaxBlockY, a_MaxBlockZ, MaxChunkX, MaxChunkZ); - + // Query block data: if (!a_ForEachChunkProvider->ForEachChunkInRect(MinChunkX, MaxChunkX, MinChunkZ, MaxChunkZ, Reader)) { Clear(); return false; } - + return true; } @@ -584,7 +584,7 @@ void cBlockArea::CopyTo(cBlockArea & a_Into) const LOGWARNING("Trying to copy a cBlockArea into self, ignoring."); return; } - + a_Into.Clear(); a_Into.SetSize(m_Size.x, m_Size.y, m_Size.z, GetDataTypes()); a_Into.m_Origin = m_Origin; @@ -684,7 +684,7 @@ void cBlockArea::Crop(int a_AddMinX, int a_SubMaxX, int a_AddMinY, int a_SubMaxY ); return; } - + if (HasBlockTypes()) { CropBlockTypes(a_AddMinX, a_SubMaxX, a_AddMinY, a_SubMaxY, a_AddMinZ, a_SubMaxZ); @@ -744,9 +744,9 @@ void cBlockArea::Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_R const NIBBLETYPE * SrcMetas = a_Src.GetBlockMetas(); NIBBLETYPE * DstMetas = m_BlockMetas; - + bool IsDummyMetas = ((SrcMetas == nullptr) || (DstMetas == nullptr)); - + if (IsDummyMetas) { MergeByStrategy(a_Src, a_RelX, a_RelY, a_RelZ, a_Strategy, SrcMetas, DstMetas); @@ -779,7 +779,7 @@ void cBlockArea::Fill(int a_DataTypes, BLOCKTYPE a_BlockType, NIBBLETYPE a_Block ); a_DataTypes = a_DataTypes & GetDataTypes(); } - + size_t BlockCount = GetBlockCount(); if ((a_DataTypes & baTypes) != 0) { @@ -827,7 +827,7 @@ void cBlockArea::FillRelCuboid(int a_MinRelX, int a_MaxRelX, int a_MinRelY, int ); a_DataTypes = a_DataTypes & GetDataTypes(); } - + if ((a_DataTypes & baTypes) != 0) { for (int y = a_MinRelY; y <= a_MaxRelY; y++) for (int z = a_MinRelZ; z <= a_MaxRelZ; z++) for (int x = a_MinRelX; x <= a_MaxRelX; x++) @@ -983,7 +983,7 @@ void cBlockArea::RelLine(int a_RelX1, int a_RelY1, int a_RelZ1, int a_RelX2, int a_RelY1 += sy; yd -= dz; } - + // move along z a_RelZ1 += sz; xd += dx; @@ -1019,14 +1019,14 @@ void cBlockArea::RotateCCW(void) LOGWARNING("cBlockArea: Cannot rotate blockmeta without blocktypes!"); return; } - + if (!HasBlockMetas()) { // There are no blockmetas to rotate, just use the NoMeta function RotateCCWNoMeta(); return; } - + // We are guaranteed that both blocktypes and blockmetas exist; rotate both at the same time: BLOCKTYPE * NewTypes = new BLOCKTYPE[GetBlockCount()]; NIBBLETYPE * NewMetas = new NIBBLETYPE[GetBlockCount()]; @@ -1071,7 +1071,7 @@ void cBlockArea::RotateCW(void) RotateCWNoMeta(); return; } - + // We are guaranteed that both blocktypes and blockmetas exist; rotate both at the same time: BLOCKTYPE * NewTypes = new BLOCKTYPE[GetBlockCount()]; NIBBLETYPE * NewMetas = new NIBBLETYPE[GetBlockCount()]; @@ -1109,7 +1109,7 @@ void cBlockArea::MirrorXY(void) LOGWARNING("cBlockArea: Cannot mirror meta without blocktypes!"); return; } - + if (!HasBlockMetas()) { // There are no blockmetas to mirror, just use the NoMeta function @@ -1329,7 +1329,7 @@ void cBlockArea::MirrorXYNoMeta(void) } // for z } // for y } // if (HasBlockTypes) - + if (HasBlockMetas()) { for (int y = 0; y < m_Size.y; y++) @@ -1366,7 +1366,7 @@ void cBlockArea::MirrorXZNoMeta(void) } // for z } // for y } // if (HasBlockTypes) - + if (HasBlockMetas()) { for (int y = 0; y < HalfY; y++) @@ -1403,7 +1403,7 @@ void cBlockArea::MirrorYZNoMeta(void) } // for z } // for y } // if (HasBlockTypes) - + if (HasBlockMetas()) { for (int y = 0; y < m_Size.y; y++) @@ -1632,7 +1632,7 @@ void cBlockArea::GetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTY { a_BlockType = m_BlockTypes[idx]; } - + if (m_BlockMetas == nullptr) { LOGWARNING("cBlockArea: BlockMetas have not been read!"); @@ -1834,7 +1834,7 @@ int cBlockArea::GetDataTypes(void) const bool cBlockArea::SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes) { ASSERT(m_BlockTypes == nullptr); // Has been cleared - + if (a_DataTypes & baTypes) { m_BlockTypes = new BLOCKTYPE[a_SizeX * a_SizeY * a_SizeZ]; @@ -1895,7 +1895,7 @@ int cBlockArea::MakeIndex(int a_RelX, int a_RelY, int a_RelZ) const ASSERT(a_RelY < m_Size.y); ASSERT(a_RelZ >= 0); ASSERT(a_RelZ < m_Size.z); - + return a_RelX + a_RelZ * m_Size.x + a_RelY * m_Size.x * m_Size.z; } @@ -1969,7 +1969,7 @@ void cBlockArea::cChunkReader::CopyNibbles(NIBBLETYPE * a_AreaDst, const NIBBLET { int SizeY = m_Area.m_Size.y; int MinY = m_Origin.y; - + // SizeX, SizeZ are the dmensions of the block data to copy from the current chunk (size of the geometric union) // OffX, OffZ are the offsets of the current chunk data from the area origin // BaseX, BaseZ are the offsets of the area data within the current chunk from the chunk borders @@ -2085,7 +2085,7 @@ void cBlockArea::cChunkReader::ChunkData(const cChunkData & a_BlockBuffer) { SizeZ -= (m_CurrentChunkZ + 1) * cChunkDef::Width - (m_Origin.z + m_Area.m_Size.z); } - + // Copy the blocktypes: if (m_Area.m_BlockTypes != nullptr) { @@ -2323,7 +2323,7 @@ void cBlockArea::MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_Rel LOGWARNING("%s: cannot merge because one of the areas doesn't have blocktypes.", __FUNCTION__); return; } - + // Dst is *this, Src is a_Src int SrcOffX = std::max(0, -a_RelX); // Offset in Src where to start reading int DstOffX = std::max(0, a_RelX); // Offset in Dst where to start writing @@ -2336,7 +2336,7 @@ void cBlockArea::MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_Rel int SrcOffZ = std::max(0, -a_RelZ); // Offset in Src where to start reading int DstOffZ = std::max(0, a_RelZ); // Offset in Dst where to start writing int SizeZ = std::min(a_Src.GetSizeZ() - SrcOffZ, GetSizeZ() - DstOffZ); // How many blocks to copy - + switch (a_Strategy) { case cBlockArea::msOverwrite: @@ -2352,7 +2352,7 @@ void cBlockArea::MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_Rel ); return; } // case msOverwrite - + case cBlockArea::msFillAir: { InternalMergeBlocks >( @@ -2366,7 +2366,7 @@ void cBlockArea::MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_Rel ); return; } // case msFillAir - + case cBlockArea::msImprint: { InternalMergeBlocks >( @@ -2380,7 +2380,7 @@ void cBlockArea::MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_Rel ); return; } // case msImprint - + case cBlockArea::msLake: { InternalMergeBlocks >( @@ -2394,7 +2394,7 @@ void cBlockArea::MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_Rel ); return; } // case msLake - + case cBlockArea::msSpongePrint: { InternalMergeBlocks >( @@ -2422,7 +2422,7 @@ void cBlockArea::MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_Rel ); return; } // case msDifference - + case cBlockArea::msSimpleCompare: { InternalMergeBlocks >( @@ -2436,7 +2436,7 @@ void cBlockArea::MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_Rel ); return; } // case msSimpleCompare - + case cBlockArea::msMask: { InternalMergeBlocks >( @@ -2451,7 +2451,7 @@ void cBlockArea::MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_Rel return; } // case msMask } // switch (a_Strategy) - + LOGWARNING("Unknown block area merge strategy: %d", a_Strategy); ASSERT(!"Unknown block area merge strategy"); return; diff --git a/src/BlockArea.h b/src/BlockArea.h index a9963b4ef..fe83122c9 100644 --- a/src/BlockArea.h +++ b/src/BlockArea.h @@ -32,7 +32,7 @@ class cBlockArea // tolua_end DISALLOW_COPY_AND_ASSIGN(cBlockArea); // tolua_begin - + public: /** What data is to be queried (bit-mask) */ @@ -43,7 +43,7 @@ public: baLight = 4, baSkyLight = 8, } ; - + /** The per-block strategy to use when merging another block area into this object. See the Merge function for the description of these */ enum eMergeStrategy @@ -57,64 +57,64 @@ public: msSimpleCompare, msMask, } ; - + cBlockArea(void); ~cBlockArea(); - + /** Clears the data stored to reclaim memory */ void Clear(void); - + /** Creates a new area of the specified size and contents. Origin is set to all zeroes. BlockTypes are set to air, block metas to zero, blocklights to zero and skylights to full light. */ void Create(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes = baTypes | baMetas); - + /** Creates a new area of the specified size and contents. Origin is set to all zeroes. BlockTypes are set to air, block metas to zero, blocklights to zero and skylights to full light. */ void Create(const Vector3i & a_Size, int a_DataTypes = baTypes | baMetas); - + /** Resets the origin. No other changes are made, contents are untouched. */ void SetOrigin(int a_OriginX, int a_OriginY, int a_OriginZ); - + /** Resets the origin. No other changes are made, contents are untouched. */ void SetOrigin(const Vector3i & a_Origin); - + /** Reads an area of blocks specified. Returns true if successful. All coords are inclusive. */ bool Read(cForEachChunkProvider * a_ForEachChunkProvider, int a_MinBlockX, int a_MaxBlockX, int a_MinBlockY, int a_MaxBlockY, int a_MinBlockZ, int a_MaxBlockZ, int a_DataTypes = baTypes | baMetas); - + /** Reads an area of blocks specified. Returns true if successful. The bounds are included in the read area. */ bool Read(cForEachChunkProvider * a_ForEachChunkProvider, const cCuboid & a_Bounds, int a_DataTypes = baTypes | baMetas); - + /** Reads an area of blocks specified. Returns true if successful. The bounds are included in the read area. */ bool Read(cForEachChunkProvider * a_ForEachChunkProvider, const Vector3i & a_Point1, const Vector3i & a_Point2, int a_DataTypes = baTypes | baMetas); - + // TODO: Write() is not too good an interface: if it fails, there's no way to repeat only for the parts that didn't write // A better way may be to return a list of cBlockAreas for each part that didn't succeed writing, so that the caller may try again - + /** Writes the area back into cWorld at the coords specified. Returns true if successful in all chunks, false if only partially / not at all */ bool Write(cForEachChunkProvider * a_ForEachChunkProvider, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes = baTypes | baMetas); - + /** Writes the area back into cWorld at the coords specified. Returns true if successful in all chunks, false if only partially / not at all */ bool Write(cForEachChunkProvider * a_ForEachChunkProvider, const Vector3i & a_MinCoords, int a_DataTypes = baTypes | baMetas); - + /** Copies this object's contents into the specified BlockArea. */ void CopyTo(cBlockArea & a_Into) const; - + /** Copies the contents from the specified BlockArea into this object. */ void CopyFrom(const cBlockArea & a_From); - + /** For testing purposes only, dumps the area into a file. */ void DumpToRawFile(const AString & a_FileName); - + /** Crops the internal contents by the specified amount of blocks from each border. */ void Crop(int a_AddMinX, int a_SubMaxX, int a_AddMinY, int a_SubMaxY, int a_AddMinZ, int a_SubMaxZ); - + /** Expands the internal contents by the specified amount of blocks from each border */ void Expand(int a_SubMinX, int a_AddMaxX, int a_SubMinY, int a_AddMaxY, int a_SubMinZ, int a_AddMaxZ); - + /** Merges another block area into this one, using the specified block combinating strategy This function combines another BlockArea into the current object. The strategy parameter specifies how individual blocks are combined together, using the table below. @@ -126,7 +126,7 @@ public: | A | air | air | A | A | | air | B | B | B | B | | A | B | B | A | B | - + So to sum up: - msOverwrite completely overwrites all blocks with the Src's blocks - msFillAir overwrites only those blocks that were air @@ -148,7 +148,7 @@ public: | mycelium | stone | stone | ... and mycelium | A | stone | A | ... but nothing else | A | * | A | Everything else is left as it is - + msSpongePrint: Used for most generators, it allows carving out air pockets, too, and uses the Sponge as the NOP block | area block | | @@ -156,7 +156,7 @@ public: +----------+--------+--------+ | A | sponge | A | Sponge is the NOP block | * | B | B | Everything else overwrites anything - + msDifference: Used to determine the differences between two areas. Only the differring blocks are preserved: | area block | | @@ -183,68 +183,68 @@ public: */ void Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy); - + /** Merges another block area into this one, using the specified block combinating strategy. See Merge() above for details. */ void Merge(const cBlockArea & a_Src, const Vector3i & a_RelMinCoords, eMergeStrategy a_Strategy); - + /** Fills the entire block area with the specified data */ void Fill(int a_DataTypes, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta = 0, NIBBLETYPE a_BlockLight = 0, NIBBLETYPE a_BlockSkyLight = 0x0f); - + /** Fills a cuboid inside the block area with the specified data */ void FillRelCuboid(int a_MinRelX, int a_MaxRelX, int a_MinRelY, int a_MaxRelY, int a_MinRelZ, int a_MaxRelZ, int a_DataTypes, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta = 0, NIBBLETYPE a_BlockLight = 0, NIBBLETYPE a_BlockSkyLight = 0x0f ); - + /** Fills a cuboid inside the block area with the specified data. a_Cuboid must be sorted. */ void FillRelCuboid(const cCuboid & a_RelCuboid, int a_DataTypes, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta = 0, NIBBLETYPE a_BlockLight = 0, NIBBLETYPE a_BlockSkyLight = 0x0f ); - + /** Draws a line from between two points with the specified data */ void RelLine(int a_RelX1, int a_RelY1, int a_RelZ1, int a_RelX2, int a_RelY2, int a_RelZ2, int a_DataTypes, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta = 0, NIBBLETYPE a_BlockLight = 0, NIBBLETYPE a_BlockSkyLight = 0x0f ); - + /** Draws a line from between two points with the specified data */ void RelLine(const Vector3i & a_Point1, const Vector3i & a_Point2, int a_DataTypes, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta = 0, NIBBLETYPE a_BlockLight = 0, NIBBLETYPE a_BlockSkyLight = 0x0f ); - + /** Rotates the entire area counter-clockwise around the Y axis */ void RotateCCW(void); - + /** Rotates the entire area clockwise around the Y axis */ void RotateCW(void); - + /** Mirrors the entire area around the XY plane */ void MirrorXY(void); - + /** Mirrors the entire area around the XZ plane */ void MirrorXZ(void); - + /** Mirrors the entire area around the YZ plane */ void MirrorYZ(void); - + /** Rotates the entire area counter-clockwise around the Y axis, doesn't use blockhandlers for block meta */ void RotateCCWNoMeta(void); - + /** Rotates the entire area clockwise around the Y axis, doesn't use blockhandlers for block meta */ void RotateCWNoMeta(void); - + /** Mirrors the entire area around the XY plane, doesn't use blockhandlers for block meta */ void MirrorXYNoMeta(void); - + /** Mirrors the entire area around the XZ plane, doesn't use blockhandlers for block meta */ void MirrorXZNoMeta(void); - + /** Mirrors the entire area around the YZ plane, doesn't use blockhandlers for block meta */ void MirrorYZNoMeta(void); - + // Setters: void SetRelBlockType (int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType); void SetBlockType (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType); @@ -270,35 +270,35 @@ public: void SetBlockTypeMeta (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); void SetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); - + // tolua_end - + // These need manual exporting, tolua generates the binding as requiring 2 extra input params void GetBlockTypeMeta (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const; void GetRelBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const; - + // GetSize() is already exported manually to return 3 numbers, can't auto-export const Vector3i & GetSize(void) const { return m_Size; } - + // GetOrigin() is already exported manually to return 3 numbers, can't auto-export const Vector3i & GetOrigin(void) const { return m_Origin; } - + // tolua_begin - + int GetSizeX(void) const { return m_Size.x; } int GetSizeY(void) const { return m_Size.y; } int GetSizeZ(void) const { return m_Size.z; } - + /** Returns the volume of the area, as number of blocks */ int GetVolume(void) const { return m_Size.x * m_Size.y * m_Size.z; } - + int GetOriginX(void) const { return m_Origin.x; } int GetOriginY(void) const { return m_Origin.y; } int GetOriginZ(void) const { return m_Origin.z; } - + /** Returns the datatypes that are stored in the object (bitmask of baXXX values) */ int GetDataTypes(void) const; - + bool HasBlockTypes (void) const { return (m_BlockTypes != nullptr); } bool HasBlockMetas (void) const { return (m_BlockMetas != nullptr); } bool HasBlockLights (void) const { return (m_BlockLight != nullptr); } @@ -323,7 +323,7 @@ public: If there are no non-ignored blocks within the area, or blocktypes are not present, the returned values are reverse-ranges (MinX <- m_RangeX, MaxX <- 0 etc.) Exported to Lua in ManualBindings.cpp. */ void GetNonAirCropRelCoords(int & a_MinRelX, int & a_MinRelY, int & a_MinRelZ, int & a_MaxRelX, int & a_MaxRelY, int & a_MaxRelZ, BLOCKTYPE a_IgnoreBlockType = E_BLOCK_AIR); - + // Clients can use these for faster access to all blocktypes. Be careful though! /** Returns the internal pointer to the block types */ BLOCKTYPE * GetBlockTypes (void) const { return m_BlockTypes; } @@ -336,32 +336,32 @@ public: protected: friend class cChunkDesc; friend class cSchematicFileSerializer; - + class cChunkReader : public cChunkDataCallback { public: cChunkReader(cBlockArea & a_Area); - + protected: cBlockArea & m_Area; Vector3i m_Origin; int m_CurrentChunkX; int m_CurrentChunkZ; - + void CopyNibbles(NIBBLETYPE * a_AreaDst, const NIBBLETYPE * a_ChunkSrc); - + // cChunkDataCallback overrides: virtual bool Coords(int a_ChunkX, int a_ChunkZ) override; virtual void ChunkData(const cChunkData & a_BlockTypes) override; } ; - + typedef NIBBLETYPE * NIBBLEARRAY; - - + + Vector3i m_Origin; Vector3i m_Size; - + /** An extra data value sometimes stored in the .schematic file. Used mainly by the WorldEdit plugin. cBlockArea doesn't use this value in any way. */ Vector3i m_WEOffset; @@ -370,10 +370,10 @@ protected: NIBBLETYPE * m_BlockMetas; // Each meta is stored as a separate byte for faster access NIBBLETYPE * m_BlockLight; // Each light value is stored as a separate byte for faster access NIBBLETYPE * m_BlockSkyLight; // Each light value is stored as a separate byte for faster access - + /** Clears the data stored and prepares a fresh new block area with the specified dimensions */ bool SetSize(int a_SizeX, int a_SizeY, int a_SizeZ, int a_DataTypes); - + // Basic Setters: void SetRelNibble(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Value, NIBBLETYPE * a_Array); void SetNibble (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_Value, NIBBLETYPE * a_Array); @@ -381,11 +381,11 @@ protected: // Basic Getters: NIBBLETYPE GetRelNibble(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE * a_Array) const; NIBBLETYPE GetNibble (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE * a_Array) const; - + // Crop helpers: void CropBlockTypes(int a_AddMinX, int a_SubMaxX, int a_AddMinY, int a_SubMaxY, int a_AddMinZ, int a_SubMaxZ); void CropNibbles (NIBBLEARRAY & a_Array, int a_AddMinX, int a_SubMaxX, int a_AddMinY, int a_SubMaxY, int a_AddMinZ, int a_SubMaxZ); - + // Expand helpers: void ExpandBlockTypes(int a_SubMinX, int a_AddMaxX, int a_SubMinY, int a_AddMaxY, int a_SubMinZ, int a_AddMaxZ); void ExpandNibbles (NIBBLEARRAY & a_Array, int a_SubMinX, int a_AddMaxX, int a_SubMinY, int a_AddMaxY, int a_SubMinZ, int a_AddMaxZ); @@ -396,7 +396,7 @@ protected: int a_DataTypes, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, NIBBLETYPE a_BlockLight, NIBBLETYPE a_BlockSkyLight ); - + template void MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy, const NIBBLETYPE * SrcMetas, NIBBLETYPE * DstMetas); // tolua_begin diff --git a/src/BlockEntities/BlockEntity.h b/src/BlockEntities/BlockEntity.h index 183210e25..65079508d 100644 --- a/src/BlockEntities/BlockEntity.h +++ b/src/BlockEntities/BlockEntity.h @@ -53,21 +53,21 @@ protected: public: // tolua_end - + virtual ~cBlockEntity() {} // force a virtual destructor in all descendants - + virtual void Destroy(void) {} - + void SetWorld(cWorld * a_World) { m_World = a_World; } - + /** Creates a new block entity for the specified block type If a_World is valid, then the entity is created bound to that world Returns nullptr for unknown block types. */ static cBlockEntity * CreateByBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World = nullptr); - + static const char * GetClassStatic(void) // Needed for ManualBindings's ForEach templates { return "cBlockEntity"; @@ -81,9 +81,9 @@ public: /** Returns the name of the parent class, or empty string if no parent class. */ virtual const char * GetParentClass(void) const { return ""; } - + // tolua_begin - + // Position, in absolute block coordinates: Vector3i GetPos(void) const { return Vector3i{m_PosX, m_PosY, m_PosZ}; } int GetPosX(void) const { return m_PosX; } @@ -91,25 +91,25 @@ public: int GetPosZ(void) const { return m_PosZ; } BLOCKTYPE GetBlockType(void) const { return m_BlockType; } - + cWorld * GetWorld(void) const { return m_World; } - + int GetChunkX(void) const { return FAST_FLOOR_DIV(m_PosX, cChunkDef::Width); } int GetChunkZ(void) const { return FAST_FLOOR_DIV(m_PosZ, cChunkDef::Width); } - + int GetRelX(void) const { return m_RelX; } int GetRelZ(void) const { return m_RelZ; } - + // tolua_end - + /** Called when a player uses this entity; should open the UI window. returns true if the use was successful, return false to use the block as a "normal" block */ virtual bool UsedBy( cPlayer * a_Player) = 0; - + /** Sends the packet defining the block entity to the client specified. To send to all eligible clients, use cWorld::BroadcastBlockEntity() */ virtual void SendTo(cClientHandle & a_Client) = 0; - + /** Ticks the entity; returns true if the chunk should be marked as dirty as a result of this ticking. By default does nothing. */ virtual bool Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { @@ -120,12 +120,12 @@ public: protected: /** Position in absolute block coordinates */ int m_PosX, m_PosY, m_PosZ; - + /** Position relative to the chunk, used to speed up ticking */ int m_RelX, m_RelZ; BLOCKTYPE m_BlockType; - + cWorld * m_World; } ; // tolua_export diff --git a/src/BlockEntities/BlockEntityWithItems.h b/src/BlockEntities/BlockEntityWithItems.h index 3810f4f04..39540d630 100644 --- a/src/BlockEntities/BlockEntityWithItems.h +++ b/src/BlockEntities/BlockEntityWithItems.h @@ -30,9 +30,9 @@ class cBlockEntityWithItems : public: // tolua_end - + BLOCKENTITY_PROTODEF(cBlockEntityWithItems) - + cBlockEntityWithItems( BLOCKTYPE a_BlockType, // Type of the block that the entity represents int a_BlockX, int a_BlockY, int a_BlockZ, // Position of the block entity @@ -45,7 +45,7 @@ public: { m_Contents.AddListener(*this); } - + virtual void Destroy(void) override { // Drop the contents as pickups: @@ -55,12 +55,12 @@ public: m_Contents.Clear(); m_World->SpawnItemPickups(Pickups, m_PosX + 0.5, m_PosY + 0.5, m_PosZ + 0.5); // Spawn in centre of block } - + // tolua_begin - + const cItem & GetSlot(int a_SlotNum) const { return m_Contents.GetSlot(a_SlotNum); } const cItem & GetSlot(int a_X, int a_Y) const { return m_Contents.GetSlot(a_X, a_Y); } - + void SetSlot(int a_SlotNum, const cItem & a_Item) { m_Contents.SetSlot(a_SlotNum, a_Item); } void SetSlot(int a_X, int a_Y, const cItem & a_Item) { m_Contents.SetSlot(a_X, a_Y, a_Item); } @@ -68,13 +68,13 @@ public: cItemGrid & GetContents(void) { return m_Contents; } // tolua_end - + /** Const version of the GetContents() function for C++ type-safety */ const cItemGrid & GetContents(void) const { return m_Contents; } protected: cItemGrid m_Contents; - + // cItemGrid::cListener overrides: virtual void OnSlotChanged(cItemGrid * a_Grid, int a_SlotNum) override { diff --git a/src/BlockEntities/ChestEntity.h b/src/BlockEntities/ChestEntity.h index 72e1c20e8..fac3dcdae 100644 --- a/src/BlockEntities/ChestEntity.h +++ b/src/BlockEntities/ChestEntity.h @@ -18,27 +18,27 @@ class cChestEntity : public cBlockEntityWithItems { typedef cBlockEntityWithItems super; - + public: enum { ContentsHeight = 3, ContentsWidth = 9, } ; - + // tolua_end - + BLOCKENTITY_PROTODEF(cChestEntity) - + /** Constructor used for normal operation */ cChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World, BLOCKTYPE a_Type); - + virtual ~cChestEntity(); // cBlockEntity overrides: virtual void SendTo(cClientHandle & a_Client) override; virtual bool UsedBy(cPlayer * a_Player) override; - + /** Opens a new chest window for this chest. Scans for neighbors to open a double chest window, if appropriate. */ void OpenNewWindow(void); diff --git a/src/BlockEntities/CommandBlockEntity.cpp b/src/BlockEntities/CommandBlockEntity.cpp index c4a742bc0..5a273d56f 100644 --- a/src/BlockEntities/CommandBlockEntity.cpp +++ b/src/BlockEntities/CommandBlockEntity.cpp @@ -120,7 +120,7 @@ bool cCommandBlockEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { return false; } - + m_ShouldExecute = false; Execute(); return true; @@ -142,7 +142,7 @@ void cCommandBlockEntity::SendTo(cClientHandle & a_Client) void cCommandBlockEntity::Execute() { ASSERT(m_World != nullptr); // Execute should not be called before the command block is attached to a world - + if (!m_World->AreCommandBlocksEnabled()) { return; diff --git a/src/BlockEntities/CommandBlockEntity.h b/src/BlockEntities/CommandBlockEntity.h index 184211ce0..716cb3b79 100644 --- a/src/BlockEntities/CommandBlockEntity.h +++ b/src/BlockEntities/CommandBlockEntity.h @@ -21,13 +21,13 @@ class cCommandBlockEntity : public cBlockEntity { typedef cBlockEntity super; - + public: // tolua_end - + BLOCKENTITY_PROTODEF(cCommandBlockEntity) - + /** Creates a new empty command block entity */ cCommandBlockEntity(int a_X, int a_Y, int a_Z, cWorld * a_World); @@ -43,7 +43,7 @@ public: /** Sets the command block to execute a command in the next tick */ void Activate(void); - + /** Sets the command */ void SetCommand(const AString & a_Cmd); @@ -55,9 +55,9 @@ public: /** Retrieves the result (signal strength) of the last operation */ NIBBLETYPE GetResult(void) const; - + // tolua_end - + private: /** Executes the associated command */ diff --git a/src/BlockEntities/DispenserEntity.h b/src/BlockEntities/DispenserEntity.h index 62072d43b..c9b553017 100644 --- a/src/BlockEntities/DispenserEntity.h +++ b/src/BlockEntities/DispenserEntity.h @@ -18,19 +18,19 @@ public: // tolua_end BLOCKENTITY_PROTODEF(cDispenserEntity) - + /** Constructor used for normal operation */ cDispenserEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); // tolua_begin - + /** Spawns a projectile of the given kind in front of the dispenser with the specified speed. Returns the UniqueID of the spawned projectile, or 0 on failure. */ UInt32 SpawnProjectileFromDispenser(int a_BlockX, int a_BlockY, int a_BlockZ, cProjectileEntity::eKind a_Kind, const Vector3d & a_Speed); /** Returns a unit vector in the cardinal direction of where the dispenser is facing. */ Vector3d GetShootVector(NIBBLETYPE a_Meta); - + // tolua_end private: diff --git a/src/BlockEntities/DropSpenserEntity.cpp b/src/BlockEntities/DropSpenserEntity.cpp index 7270c9586..8dddf85de 100644 --- a/src/BlockEntities/DropSpenserEntity.cpp +++ b/src/BlockEntities/DropSpenserEntity.cpp @@ -71,19 +71,19 @@ void cDropSpenserEntity::DropSpense(cChunk & a_Chunk) SlotsCnt++; } } // for i - m_Contents[] - + if (SlotsCnt == 0) { // Nothing in the dropspenser, play the click sound m_World->BroadcastSoundEffect("random.click", static_cast(m_PosX), static_cast(m_PosY), static_cast(m_PosZ), 1.0f, 1.2f); return; } - + int RandomSlot = m_World->GetTickRandomNumber(SlotsCnt - 1); - + // DropSpense the item, using the specialized behavior in the subclasses: DropSpenseFromSlot(a_Chunk, OccupiedSlots[RandomSlot]); - + // Broadcast a smoke and click effects: NIBBLETYPE Meta = a_Chunk.GetMeta(m_RelX, m_PosY, m_RelZ); int SmokeDir = 0; @@ -120,7 +120,7 @@ bool cDropSpenserEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { return false; } - + m_ShouldDropSpense = false; DropSpense(a_Chunk); return true; @@ -148,7 +148,7 @@ bool cDropSpenserEntity::UsedBy(cPlayer * a_Player) OpenWindow(new cDropSpenserWindow(m_PosX, m_PosY, m_PosZ, this)); Window = GetWindow(); } - + if (Window != nullptr) { if (a_Player->GetWindow() != Window) diff --git a/src/BlockEntities/DropSpenserEntity.h b/src/BlockEntities/DropSpenserEntity.h index fa1f37454..a009067f0 100644 --- a/src/BlockEntities/DropSpenserEntity.h +++ b/src/BlockEntities/DropSpenserEntity.h @@ -34,38 +34,38 @@ public: ContentsHeight = 3, ContentsWidth = 3, } ; - + // tolua_end - + BLOCKENTITY_PROTODEF(cDropSpenserEntity) - + cDropSpenserEntity(BLOCKTYPE a_BlockType, int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); virtual ~cDropSpenserEntity(); - + // cBlockEntity overrides: virtual bool Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; virtual void SendTo(cClientHandle & a_Client) override; virtual bool UsedBy(cPlayer * a_Player) override; - + // tolua_begin - + /** Modifies the block coords to match the dropspenser direction given (where the dropspensed pickups should materialize) */ void AddDropSpenserDir(int & a_BlockX, int & a_BlockY, int & a_BlockZ, NIBBLETYPE a_Direction); /** Sets the dropspenser to dropspense an item in the next tick */ void Activate(void); - + // tolua_end protected: bool m_ShouldDropSpense; ///< If true, the dropspenser will dropspense an item in the next tick - + /** Does the actual work on dropspensing an item. Chooses the slot, calls DropSpenseFromSlot() and handles smoke / sound effects */ void DropSpense(cChunk & a_Chunk); - + /** Override this function to provide the specific behavior for item dropspensing (drop / shoot / pour / ...) */ virtual void DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) = 0; - + /** Helper function, drops one item from the specified slot (like a dropper) */ void DropFromSlot(cChunk & a_Chunk, int a_SlotNum); } ; // tolua_export diff --git a/src/BlockEntities/DropperEntity.h b/src/BlockEntities/DropperEntity.h index 1ca396eb7..e6ce34f0d 100644 --- a/src/BlockEntities/DropperEntity.h +++ b/src/BlockEntities/DropperEntity.h @@ -20,20 +20,20 @@ class cDropperEntity : public cDropSpenserEntity { typedef cDropSpenserEntity super; - + public: // tolua_end - + BLOCKENTITY_PROTODEF(cDropperEntity) - + /** Constructor used for normal operation */ cDropperEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); protected: // cDropSpenserEntity overrides: virtual void DropSpenseFromSlot(cChunk & a_Chunk, int a_SlotNum) override; - + /** Takes an item from slot a_SlotNum and puts it into the container in front of the dropper. Called when there's a container directly in front of the dropper, so the dropper should store items there, rather than dropping. */ diff --git a/src/BlockEntities/EnderChestEntity.h b/src/BlockEntities/EnderChestEntity.h index ba207aaa8..d79e0ee68 100644 --- a/src/BlockEntities/EnderChestEntity.h +++ b/src/BlockEntities/EnderChestEntity.h @@ -14,12 +14,12 @@ class cEnderChestEntity : public cBlockEntityWindowOwner { typedef cBlockEntity super; - + public: // tolua_end - + BLOCKENTITY_PROTODEF(cEnderChestEntity) - + cEnderChestEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); virtual ~cEnderChestEntity(); @@ -29,7 +29,7 @@ public: static void LoadFromJson(const Json::Value & a_Value, cItemGrid & a_Grid); static void SaveToJson(Json::Value & a_Value, const cItemGrid & a_Grid); - + /** Opens a new enderchest window for this enderchest */ void OpenNewWindow(void); } ; // tolua_export diff --git a/src/BlockEntities/FlowerPotEntity.h b/src/BlockEntities/FlowerPotEntity.h index c7aa02c15..c9d330673 100644 --- a/src/BlockEntities/FlowerPotEntity.h +++ b/src/BlockEntities/FlowerPotEntity.h @@ -21,31 +21,31 @@ class cFlowerPotEntity : public cBlockEntity { typedef cBlockEntity super; - + public: // tolua_end - + BLOCKENTITY_PROTODEF(cFlowerPotEntity) - + /** Creates a new flowerpot entity at the specified block coords. a_World may be nullptr */ cFlowerPotEntity(int a_BlocX, int a_BlockY, int a_BlockZ, cWorld * a_World); - + virtual void Destroy(void) override; // tolua_begin - + /** Is a flower in the pot? */ bool IsItemInPot(void) { return !m_Item.IsEmpty(); } - + /** Get the item in the flower pot */ cItem GetItem(void) const { return m_Item; } - + /** Set the item in the flower pot */ void SetItem(const cItem & a_Item) { m_Item = a_Item; } - + // tolua_end - + /** Called when the player is using the entity; returns true if it was a successful use, return false if it should be treated as a normal block */ virtual bool UsedBy(cPlayer * a_Player) override; virtual void SendTo(cClientHandle & a_Client) override; diff --git a/src/BlockEntities/FurnaceEntity.cpp b/src/BlockEntities/FurnaceEntity.cpp index 7aeede620..b2ac093c0 100644 --- a/src/BlockEntities/FurnaceEntity.cpp +++ b/src/BlockEntities/FurnaceEntity.cpp @@ -365,7 +365,7 @@ void cFurnaceEntity::UpdateProgressBars(bool a_ForceUpdate) int CurFuel = (m_FuelBurnTime > 0) ? 200 - (200 * m_TimeBurned / m_FuelBurnTime) : 0; BroadcastProgress(PROGRESSBAR_FUEL, static_cast(CurFuel)); - + int CurCook = (m_NeedCookTime > 0) ? (200 * m_TimeCooked / m_NeedCookTime) : 0; BroadcastProgress(PROGRESSBAR_SMELTING_CONFIRM, 200); // Post 1.8, Mojang requires a random packet with an ID of three and value of 200. Wat. Wat. Wat. BroadcastProgress(PROGRESSBAR_SMELTING, static_cast(CurCook)); diff --git a/src/BlockEntities/FurnaceEntity.h b/src/BlockEntities/FurnaceEntity.h index 52d81353c..a0cd54a37 100644 --- a/src/BlockEntities/FurnaceEntity.h +++ b/src/BlockEntities/FurnaceEntity.h @@ -19,25 +19,25 @@ class cFurnaceEntity : public cBlockEntityWithItems { typedef cBlockEntityWithItems super; - + public: enum { fsInput = 0, // Input slot number fsFuel = 1, // Fuel slot number fsOutput = 2, // Output slot number - + ContentsWidth = 3, ContentsHeight = 1, }; - + // tolua_end - + BLOCKENTITY_PROTODEF(cFurnaceEntity) - + /** Constructor used for normal operation */ cFurnaceEntity(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cWorld * a_World); - + virtual ~cFurnaceEntity(); // cBlockEntity overrides: @@ -54,41 +54,41 @@ public: Used after the furnace is loaded from storage to set up the internal variables so that cooking continues, if it was active Returns true if cooking */ bool ContinueCooking(void); - + // tolua_begin - + /** Returns the item in the input slot */ const cItem & GetInputSlot(void) const { return GetSlot(fsInput); } - + /** Returns the item in the fuel slot */ const cItem & GetFuelSlot(void) const { return GetSlot(fsFuel); } - + /** Returns the item in the output slot */ const cItem & GetOutputSlot(void) const { return GetSlot(fsOutput); } - + /** Sets the item in the input slot */ void SetInputSlot(const cItem & a_Item) { SetSlot(fsInput, a_Item); } - + /** Sets the item in the fuel slot */ void SetFuelSlot(const cItem & a_Item) { SetSlot(fsFuel, a_Item); } - + /** Sets the item in the output slot */ void SetOutputSlot(const cItem & a_Item) { SetSlot(fsOutput, a_Item); } - + /** Returns the time that the current item has been cooking, in ticks */ int GetTimeCooked(void) const { return m_TimeCooked; } - + /** Returns the time until the current item finishes cooking, in ticks */ int GetCookTimeLeft(void) const { return m_NeedCookTime - m_TimeCooked; } - + /** Returns the time until the current fuel is depleted, in ticks */ int GetFuelBurnTimeLeft(void) const { return m_FuelBurnTime - m_TimeBurned; } - + /** Returns true if there's time left before the current fuel is depleted */ bool HasFuelTimeLeft(void) const { return (GetFuelBurnTimeLeft() > 0); } - + // tolua_end - + void SetBurnTimes(int a_FuelBurnTime, int a_TimeBurned) { m_FuelBurnTime = a_FuelBurnTime; @@ -100,29 +100,29 @@ public: m_NeedCookTime = a_NeedCookTime; m_TimeCooked = a_TimeCooked; } - + void SetLoading(bool a_IsLoading) { m_IsLoading = a_IsLoading; } protected: - + /** Block meta of the block currently represented by this entity */ NIBBLETYPE m_BlockMeta; /** The recipe for the current input slot */ const cFurnaceRecipe::cRecipe * m_CurrentRecipe; - + /** The item that is being smelted */ cItem m_LastInput; /** Set to true when the furnace entity has been destroyed to prevent the block being set again */ bool m_IsDestroyed; - + /** Set to true if the furnace is cooking an item */ bool m_IsCooking; - + /** Amount of ticks needed to fully cook current item */ int m_NeedCookTime; @@ -137,37 +137,37 @@ protected: /** Is the block currently being loaded into the world? */ bool m_IsLoading; - + /** Sends the specified progressbar value to all clients of the window */ void BroadcastProgress(short a_ProgressbarID, short a_Value); - + /** One item finished cooking */ void FinishOne(); - + /** Starts burning a new fuel, if possible */ void BurnNewFuel(void); - + /** Updates the recipe, based on the current input */ void UpdateInput(void); - + /** Called when the fuel slot changes or when the fuel is spent, burns another piece of fuel if appropriate */ void UpdateFuel(void); - + /** Called when the output slot changes */ void UpdateOutput(void); - + /** Returns true if the input can be cooked into output and the item counts allow for another cooking operation */ bool CanCookInputToOutput(void) const; - + /** Broadcasts progressbar updates, if needed */ void UpdateProgressBars(bool a_ForceUpdate = false); - + /** Sets the m_IsCooking variable, updates the furnace block type based on the value */ void SetIsCooking(bool a_IsCooking); - + // cItemGrid::cListener overrides: virtual void OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) override; - + } ; // tolua_export diff --git a/src/BlockEntities/HopperEntity.h b/src/BlockEntities/HopperEntity.h index 59645ebb7..5c0ef139d 100644 --- a/src/BlockEntities/HopperEntity.h +++ b/src/BlockEntities/HopperEntity.h @@ -30,17 +30,17 @@ public: } ; // tolua_end - + BLOCKENTITY_PROTODEF(cHopperEntity) - + /** Constructor used for normal operation */ cHopperEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); - + /** Returns the block coords of the block receiving the output items, based on the meta Returns false if unattached. Exported in ManualBindings.cpp. */ bool GetOutputBlockPos(NIBBLETYPE a_BlockMeta, int & a_OutputX, int & a_OutputY, int & a_OutputZ); - + protected: Int64 m_LastMoveItemsInTick; @@ -50,37 +50,37 @@ protected: virtual bool Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; virtual void SendTo(cClientHandle & a_Client) override; virtual bool UsedBy(cPlayer * a_Player) override; - + /** Opens a new chest window for this chest. Scans for neighbors to open a double chest window, if appropriate. */ void OpenNewWindow(void); /** Moves items from the container above it into this hopper. Returns true if the contents have changed. */ bool MoveItemsIn(cChunk & a_Chunk, Int64 a_CurrentTick); - + /** Moves pickups from above this hopper into it. Returns true if the contents have changed. */ bool MovePickupsIn(cChunk & a_Chunk, Int64 a_CurrentTick); - + /** Moves items out from this hopper into the destination. Returns true if the contents have changed. */ bool MoveItemsOut(cChunk & a_Chunk, Int64 a_CurrentTick); - + /** Moves items from a chest (dblchest) above the hopper into this hopper. Returns true if contents have changed. */ bool MoveItemsFromChest(cChunk & a_Chunk); - + /** Moves items from a furnace above the hopper into this hopper. Returns true if contents have changed. */ bool MoveItemsFromFurnace(cChunk & a_Chunk); - + /** Moves items from the specified a_Entity's Contents into this hopper. Returns true if contents have changed. */ bool MoveItemsFromGrid(cBlockEntityWithItems & a_Entity); - + /** Moves one piece from the specified itemstack into this hopper. Returns true if contents have changed. Doesn't change the itemstack. */ bool MoveItemsFromSlot(cBlockEntityWithItems & a_Entity, int a_SrcSlotNum); - + /** Moves items to the chest at the specified coords. Returns true if contents have changed */ bool MoveItemsToChest(cChunk & a_Chunk, int a_BlockX, int a_BlockY, int a_BlockZ); - + /** Moves items to the furnace at the specified coords. Returns true if contents have changed */ bool MoveItemsToFurnace(cChunk & a_Chunk, int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_HopperMeta); - + /** Moves items to the specified ItemGrid. Returns true if contents have changed */ bool MoveItemsToGrid(cBlockEntityWithItems & a_Entity); diff --git a/src/BlockEntities/JukeboxEntity.h b/src/BlockEntities/JukeboxEntity.h index 3724922ae..6d9f90a2b 100644 --- a/src/BlockEntities/JukeboxEntity.h +++ b/src/BlockEntities/JukeboxEntity.h @@ -16,32 +16,32 @@ class cJukeboxEntity : public: // tolua_end - + BLOCKENTITY_PROTODEF(cJukeboxEntity) - + cJukeboxEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); virtual ~cJukeboxEntity(); // tolua_begin - + int GetRecord(void); void SetRecord(int a_Record); - + /** Plays the specified Record. Return false if a_Record isn't a playable Record (E_ITEM_XXX_DISC). If there is a record already playing, ejects it first. */ bool PlayRecord(int a_Record); - + /** Ejects the currently held record as a pickup. Return false when no record had been inserted. */ bool EjectRecord(void); - + /** Is in the Jukebox a Record? */ bool IsPlayingRecord(void); - + static bool IsRecordItem(int a_Item) { return ((a_Item >= E_ITEM_FIRST_DISC) && (a_Item <= E_ITEM_LAST_DISC)); } - + // tolua_end virtual bool UsedBy(cPlayer * a_Player) override; diff --git a/src/BlockEntities/MobHeadEntity.h b/src/BlockEntities/MobHeadEntity.h index 2eb932068..0aac95536 100644 --- a/src/BlockEntities/MobHeadEntity.h +++ b/src/BlockEntities/MobHeadEntity.h @@ -21,36 +21,36 @@ class cMobHeadEntity : public cBlockEntity { typedef cBlockEntity super; - + public: // tolua_end - + BLOCKENTITY_PROTODEF(cMobHeadEntity) - + /** Creates a new mob head entity at the specified block coords. a_World may be nullptr */ cMobHeadEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); // tolua_begin - + /** Set the type of the mob head */ void SetType(const eMobHeadType & a_SkullType); - + /** Set the rotation of the mob head */ void SetRotation(eMobHeadRotation a_Rotation); - + /** Set the player for mob heads with player type */ void SetOwner(const cPlayer & a_Owner); /** Sets the player components for the mob heads with player type */ void SetOwner(const AString & a_OwnerUUID, const AString & a_OwnerName, const AString & a_OwnerTexture, const AString & a_OwnerTextureSignature); - + /** Returns the type of the mob head */ eMobHeadType GetType(void) const { return m_Type; } - + /** Returns the rotation of the mob head */ eMobHeadRotation GetRotation(void) const { return m_Rotation; } - + /** Returns the player name of the mob head */ AString GetOwnerName(void) const { return m_OwnerName; } @@ -62,9 +62,9 @@ public: /** Returns the texture signature of the mob head */ AString GetOwnerTextureSignature(void) const { return m_OwnerTextureSignature; } - + // tolua_end - + virtual bool UsedBy(cPlayer * a_Player) override; virtual void SendTo(cClientHandle & a_Client) override; diff --git a/src/BlockEntities/MobSpawnerEntity.h b/src/BlockEntities/MobSpawnerEntity.h index e3bb8c634..66cfff2db 100644 --- a/src/BlockEntities/MobSpawnerEntity.h +++ b/src/BlockEntities/MobSpawnerEntity.h @@ -24,7 +24,7 @@ class cMobSpawnerEntity : public: // tolua_end - + cMobSpawnerEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); virtual void SendTo(cClientHandle & a_Client) override; diff --git a/src/BlockEntities/NoteEntity.cpp b/src/BlockEntities/NoteEntity.cpp index 0eef633dc..a1e1d931d 100644 --- a/src/BlockEntities/NoteEntity.cpp +++ b/src/BlockEntities/NoteEntity.cpp @@ -35,7 +35,7 @@ void cNoteEntity::MakeSound(void) { char instrument; AString sampleName; - + switch (m_World->GetBlock(m_PosX, m_PosY - 1, m_PosZ)) { case E_BLOCK_PLANKS: @@ -47,7 +47,7 @@ void cNoteEntity::MakeSound(void) sampleName = "note.bassattack"; break; } - + case E_BLOCK_SAND: case E_BLOCK_GRAVEL: case E_BLOCK_SOULSAND: @@ -56,7 +56,7 @@ void cNoteEntity::MakeSound(void) sampleName = "note.snare"; break; } - + case E_BLOCK_GLASS: case E_BLOCK_GLASS_PANE: case E_BLOCK_GLOWSTONE: @@ -89,7 +89,7 @@ void cNoteEntity::MakeSound(void) } m_World->BroadcastBlockAction(m_PosX, m_PosY, m_PosZ, static_cast(instrument), static_cast(m_Pitch), E_BLOCK_NOTE_BLOCK); - + // TODO: instead of calculating the power function over and over, make a precalculated table - there's only 24 pitches after all float calcPitch = static_cast(pow(2.0f, static_cast(m_Pitch - 12.0f) / 12.0f)); m_World->BroadcastSoundEffect( diff --git a/src/BlockEntities/NoteEntity.h b/src/BlockEntities/NoteEntity.h index 2cd703c52..9b26f7141 100644 --- a/src/BlockEntities/NoteEntity.h +++ b/src/BlockEntities/NoteEntity.h @@ -31,20 +31,20 @@ public: // tolua_end BLOCKENTITY_PROTODEF(cNoteEntity) - + /** Creates a new note entity. a_World may be nullptr */ cNoteEntity(int a_X, int a_Y, int a_Z, cWorld * a_World); virtual ~cNoteEntity() {} // tolua_begin - + char GetPitch(void); void SetPitch(char a_Pitch); void IncrementPitch(void); void MakeSound(void); - + // tolua_end - + virtual bool UsedBy(cPlayer * a_Player) override; virtual void SendTo(cClientHandle &) override {} diff --git a/src/BlockEntities/SignEntity.h b/src/BlockEntities/SignEntity.h index 50b9d7330..c7a2de154 100644 --- a/src/BlockEntities/SignEntity.h +++ b/src/BlockEntities/SignEntity.h @@ -20,29 +20,29 @@ class cSignEntity : public cBlockEntity { typedef cBlockEntity super; - + public: // tolua_end - + BLOCKENTITY_PROTODEF(cSignEntity) - + /** Creates a new empty sign entity at the specified block coords and block type (wall or standing). a_World may be nullptr */ cSignEntity(BLOCKTYPE a_BlockType, int a_X, int a_Y, int a_Z, cWorld * a_World); // tolua_begin - + /** Sets all the sign's lines */ void SetLines(const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4); - + /** Sets individual line (zero-based index) */ void SetLine(int a_Index, const AString & a_Line); /** Retrieves individual line (zero-based index) */ AString GetLine(int a_Index) const; - + // tolua_end - + virtual bool UsedBy(cPlayer * a_Player) override; virtual void SendTo(cClientHandle & a_Client) override; diff --git a/src/BlockID.cpp b/src/BlockID.cpp index b60ac0b4a..357f6a5a4 100644 --- a/src/BlockID.cpp +++ b/src/BlockID.cpp @@ -22,9 +22,9 @@ class cBlockIDMap return (NoCaseCompare(a_Item1, a_Item2) > 0); } } ; - + typedef std::map, Comparator> ItemMap; - + public: static bool m_bHasRunInit; @@ -60,8 +60,8 @@ public: AddToMap(Name, Value); } // for i - Ini.Values[] } - - + + int Resolve(const AString & a_ItemName) { ItemMap::iterator itr = m_Map.find(a_ItemName); @@ -71,8 +71,8 @@ public: } return itr->second.first; } - - + + bool ResolveItem(const AString & a_ItemName, cItem & a_Item) { // Split into parts divided by either ':' or '^' @@ -102,7 +102,7 @@ public: return false; } } - + // Parse the damage, if present: if (Split.size() < 2) { @@ -119,8 +119,8 @@ public: a_Item.m_ItemCount = 1; return true; } - - + + AString Desolve(short a_ItemType, short a_ItemDamage) { // First try an exact match, both ItemType and ItemDamage ("birchplanks=5:2"): @@ -131,7 +131,7 @@ public: return itr->first; } } // for itr - m_Map[] - + // There is no exact match, try matching ItemType only ("planks=5"): if (a_ItemDamage == 0) { @@ -156,12 +156,12 @@ public: } return res; } - - + + protected: ItemMap m_Map; - - + + void AddToMap(const AString & a_Name, const AString & a_Value) { AStringVector Split = StringSplit(a_Value, ":"); @@ -224,7 +224,7 @@ int BlockStringToType(const AString & a_BlockTypeString) // It was a valid number, return that return res; } - + if (!gsBlockIDMap.m_bHasRunInit) { gsBlockIDMap.init(); @@ -300,7 +300,7 @@ eDimension StringToDimension(const AString & a_DimensionString) // It was a valid number return static_cast(res); } - + // Decode using a built-in map: static struct { @@ -323,7 +323,7 @@ eDimension StringToDimension(const AString & a_DimensionString) return DimensionMap[i].m_Dimension; } } // for i - DimensionMap[] - + // Not found LOGWARNING("Unknown dimension: \"%s\". Setting to Overworld", a_DimensionString.c_str()); return dimOverworld; @@ -389,7 +389,7 @@ AString DamageTypeToString(eDamageType a_DamageType) case dtSuffocating: return "dtSuffocation"; case dtExplosion: return "dtExplosion"; } - + // Unknown damage type: ASSERT(!"Unknown DamageType"); return Printf("dtUnknown_%d", static_cast(a_DamageType)); @@ -410,7 +410,7 @@ eDamageType StringToDamageType(const AString & a_DamageTypeString) // It was a valid number return static_cast(res); } - + // Decode using a built-in map: static struct { @@ -467,7 +467,7 @@ eDamageType StringToDamageType(const AString & a_DamageTypeString) return DamageTypeMap[i].m_DamageType; } } // for i - DamageTypeMap[] - + // Not found: return static_cast(-1); } diff --git a/src/BlockID.h b/src/BlockID.h index 1a43d4b64..05dc42f3c 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -163,7 +163,7 @@ enum BLOCKTYPE E_BLOCK_TRAPPED_CHEST = 146, E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE = 147, E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE = 148, - + E_BLOCK_INACTIVE_COMPARATOR = 149, E_BLOCK_ACTIVE_COMPARATOR = 150, E_BLOCK_DAYLIGHT_SENSOR = 151, @@ -174,7 +174,7 @@ enum BLOCKTYPE E_BLOCK_QUARTZ_BLOCK = 155, E_BLOCK_QUARTZ_STAIRS = 156, E_BLOCK_ACTIVATOR_RAIL = 157, - + E_BLOCK_DROPPER = 158, E_BLOCK_STAINED_CLAY = 159, E_BLOCK_STAINED_GLASS_PANE = 160, @@ -215,12 +215,12 @@ enum BLOCKTYPE E_BLOCK_JUNGLE_DOOR = 195, E_BLOCK_ACACIA_DOOR = 196, E_BLOCK_DARK_OAK_DOOR = 197, - + // Keep these two as the last values. Update the last block value when adding another block // IsValidBlock() depends on this E_BLOCK_NUMBER_OF_TYPES = E_BLOCK_DARK_OAK_DOOR + 1, ///< Number of individual (different) blocktypes E_BLOCK_MAX_TYPE_ID = E_BLOCK_NUMBER_OF_TYPES - 1, ///< Maximum BlockType number used - + // Synonym or ID compatibility E_BLOCK_YELLOW_FLOWER = E_BLOCK_DANDELION, E_BLOCK_RED_ROSE = E_BLOCK_FLOWER, @@ -244,7 +244,7 @@ enum ENUM_ITEM_ID E_ITEM_EMPTY = -1, E_ITEM_FIRST = 256, // First true item type - + E_ITEM_IRON_SHOVEL = 256, E_ITEM_IRON_PICKAXE = 257, E_ITEM_IRON_AXE = 258, @@ -422,7 +422,7 @@ enum ENUM_ITEM_ID E_ITEM_JUNGLE_DOOR = 429, E_ITEM_ACACIA_DOOR = 430, E_ITEM_DARK_OAK_DOOR = 431, - + // Keep these two as the last values of the consecutive list, without a number - they will get their correct number assigned automagically by C++ // IsValidItem() depends on this! E_ITEM_NUMBER_OF_CONSECUTIVE_TYPES, ///< Number of individual (different) consecutive itemtypes @@ -441,12 +441,12 @@ enum ENUM_ITEM_ID E_ITEM_WARD_DISC = 2265, E_ITEM_11_DISC = 2266, E_ITEM_WAIT_DISC = 2267, - + // Keep these two as the last values of the disc list, without a number - they will get their correct number assigned automagically by C++ // IsValidItem() depends on this! E_ITEM_LAST_DISC_PLUS_ONE, ///< Useless, really, but needs to be present for the following value E_ITEM_LAST_DISC = E_ITEM_LAST_DISC_PLUS_ONE - 1, ///< Maximum disc itemtype number used - + E_ITEM_LAST = E_ITEM_LAST_DISC, ///< Maximum valid ItemType }; @@ -458,7 +458,7 @@ enum { // Please keep this list alpha-sorted by the blocktype / itemtype part // then number-sorted for the same block / item - + //////////////////////////////////////////////////////////////////////////////// // Block metas: @@ -516,19 +516,19 @@ enum E_META_CARPET_GREEN = 13, E_META_CARPET_RED = 14, E_META_CARPET_BLACK = 15, - + // E_BLOCK_CHEST metas: E_META_CHEST_FACING_ZM = 2, E_META_CHEST_FACING_ZP = 3, E_META_CHEST_FACING_XM = 4, E_META_CHEST_FACING_XP = 5, - + // E_BLOCK_DIRT metas: E_META_DIRT_NORMAL = 0, E_META_DIRT_GRASSLESS = 1, E_META_DIRT_COARSE = 1, E_META_DIRT_PODZOL = 2, - + // E_BLOCK_DISPENSER / E_BLOCK_DROPPER metas: E_META_DROPSPENSER_FACING_YM = 0, E_META_DROPSPENSER_FACING_YP = 1, @@ -549,7 +549,7 @@ enum E_META_DOUBLE_STONE_SLAB_SMOOTH_STONE = 8, E_META_DOUBLE_STONE_SLAB_SMOOTH_SANDSTONE = 9, E_META_DOUBLE_STONE_SLAB_TILE_QUARTZ = 10, - + // E_BLOCK_FLOWER metas: E_META_FLOWER_POPPY = 0, E_META_FLOWER_BLUE_ORCHID = 1, @@ -559,11 +559,11 @@ enum E_META_FLOWER_WHITE_TULIP = 6, E_META_FLOWER_PINK_TULIP = 7, E_META_FLOWER_OXEYE_DAISY = 8, - + // E_BLOCK_JUKEBOX metas: E_META_JUKEBOX_OFF = 0, E_META_JUKEBOX_ON = 1, - + // E_BLOCK_HOPPER metas: E_META_HOPPER_FACING_YM = 0, E_META_HOPPER_UNATTACHED = 1, // Hopper doesn't move items up, there's no YP @@ -593,21 +593,21 @@ enum E_META_NEWLEAVES_DARK_OAK_NO_DECAY = 5, E_META_NEWLEAVES_ACACIA_CHECK_DECAY = 8, E_META_NEWLEAVES_DARK_OAK_CHECK_DECAY = 9, - + // E_BLOCK_LOG metas: E_META_LOG_APPLE = 0, E_META_LOG_CONIFER = 1, E_META_LOG_BIRCH = 2, E_META_LOG_JUNGLE = 3, - + // E_BLOCK_NEW_LEAVES metas: E_META_NEW_LEAVES_ACACIA_WOOD = 0, E_META_NEW_LEAVES_DARK_OAK_WOOD = 1, - + // E_BLOCK_NEW_LOG metas: E_META_NEW_LOG_ACACIA_WOOD = 0, E_META_NEW_LOG_DARK_OAK_WOOD = 1, - + // E_BLOCK_PISTON metas: E_META_PISTON_DOWN = 0, E_META_PISTON_U = 1, @@ -629,12 +629,12 @@ enum // E_BLOCK_(XXX_WEIGHTED)_PRESSURE_PLATE metas: E_META_PRESSURE_PLATE_RAISED = 0, E_META_PRESSURE_PLATE_DEPRESSED = 1, - + // E_BLOCK_PRISMARINE_BLOCK metas: E_META_PRISMARINE_BLOCK_ROUGH = 0, E_META_PRISMARINE_BLOCK_BRICKS = 1, E_META_PRISMARINE_BLOCK_DARK = 2, - + // E_BLOCK_QUARTZ_BLOCK metas: E_META_QUARTZ_NORMAL = 0, E_META_QUARTZ_CHISELLED = 1, @@ -651,21 +651,21 @@ enum E_META_RAIL_CURVED_ZP_XM = 7, E_META_RAIL_CURVED_ZM_XM = 8, E_META_RAIL_CURVED_ZM_XP = 9, - + // E_BLOCK_RED_SANDSTONE metas: E_META_RED_SANDSTONE_NORMAL = 0, E_META_RED_SANDSTONE_ORNAMENT = 1, E_META_RED_SANDSTONE_SMOOTH = 2, - + // E_BLOCK_SAND metas: E_META_SAND_NORMAL = 0, E_META_SAND_RED = 1, - + // E_BLOCK_SANDSTONE metas: E_META_SANDSTONE_NORMAL = 0, E_META_SANDSTONE_ORNAMENT = 1, E_META_SANDSTONE_SMOOTH = 2, - + // E_BLOCK_SAPLING metas (lowest 3 bits): E_META_SAPLING_APPLE = 0, E_META_SAPLING_CONIFER = 1, @@ -673,12 +673,12 @@ enum E_META_SAPLING_JUNGLE = 3, E_META_SAPLING_ACACIA = 4, E_META_SAPLING_DARK_OAK = 5, - + // E_BLOCK_SILVERFISH_EGG metas: E_META_SILVERFISH_EGG_STONE = 0, E_META_SILVERFISH_EGG_COBBLESTONE = 1, E_META_SILVERFISH_EGG_STONE_BRICK = 2, - + // E_BLOCK_SNOW metas: E_META_SNOW_LAYER_ONE = 0, E_META_SNOW_LAYER_TWO = 1, @@ -706,7 +706,7 @@ enum E_META_STAINED_CLAY_GREEN = 13, E_META_STAINED_CLAY_RED = 14, E_META_STAINED_CLAY_BLACK = 15, - + // E_BLOCK_STAINED_GLASS metas: E_META_STAINED_GLASS_WHITE = 0, E_META_STAINED_GLASS_ORANGE = 1, @@ -724,7 +724,7 @@ enum E_META_STAINED_GLASS_GREEN = 13, E_META_STAINED_GLASS_RED = 14, E_META_STAINED_GLASS_BLACK = 15, - + // E_BLOCK_STAINED_GLASS_PANE metas: E_META_STAINED_GLASS_PANE_WHITE = 0, E_META_STAINED_GLASS_PANE_ORANGE = 1, @@ -768,19 +768,19 @@ enum E_META_STONE_SLAB_STONE_BRICK = 5, E_META_STONE_SLAB_NETHER_BRICK = 6, E_META_STONE_SLAB_QUARTZ = 7, - + // E_BLOCK_STONE_BRICKS metas: E_META_STONE_BRICK_NORMAL = 0, E_META_STONE_BRICK_MOSSY = 1, E_META_STONE_BRICK_CRACKED = 2, E_META_STONE_BRICK_ORNAMENT = 3, - + // E_BLOCK_TALL_GRASS metas: E_META_TALL_GRASS_DEAD_SHRUB = 0, E_META_TALL_GRASS_GRASS = 1, E_META_TALL_GRASS_FERN = 2, E_META_TALL_GRASS_BIOME = 3, - + // E_BLOCK_TORCH, E_BLOCK_REDSTONE_TORCH_OFF, E_BLOCK_REDSTONE_TORCH_ON metas: E_META_TORCH_EAST = 1, // east face of the block, pointing east E_META_TORCH_WEST = 2, @@ -827,7 +827,7 @@ enum E_META_WOODEN_DOUBLE_SLAB_JUNGLE = 3, E_META_WOODEN_DOUBLE_SLAB_ACACIA = 4, E_META_WOODEN_DOUBLE_SLAB_DARK_OAK = 5, - + // E_BLOCK_WOODEN_SLAB metas: E_META_WOODEN_SLAB_OAK = 0, E_META_WOODEN_SLAB_SPRUCE = 1, @@ -854,10 +854,10 @@ enum E_META_WOOL_GREEN = 13, E_META_WOOL_RED = 14, E_META_WOOL_BLACK = 15, - + //////////////////////////////////////////////////////////////////////////////// // Item metas: - + // E_ITEM_BANNER metas: E_META_BANNER_BLACK = 0, E_META_BANNER_RED = 1, @@ -875,11 +875,11 @@ enum E_META_BANNER_MAGENTA = 13, E_META_BANNER_ORANGE = 14, E_META_BANNER_WHITE = 15, - + // E_ITEM_COAL metas: E_META_COAL_NORMAL = 0, E_META_COAL_CHARCOAL = 1, - + // E_ITEM_DYE metas: E_META_DYE_BLACK = 0, E_META_DYE_RED = 1, @@ -901,20 +901,20 @@ enum // E_ITEM_GOLDEN_APPLE metas: E_META_GOLDEN_APPLE_NORMAL = 0, E_META_GOLDEN_APPLE_ENCHANTED = 1, - + // E_ITEM_HEAD metas: E_META_HEAD_SKELETON = 0, E_META_HEAD_WITHER = 1, E_META_HEAD_ZOMBIE = 2, E_META_HEAD_PLAYER = 3, E_META_HEAD_CREEPER = 4, - + // E_ITEM_RAW_FISH metas: E_META_RAW_FISH_FISH = 0, E_META_RAW_FISH_SALMON = 1, E_META_RAW_FISH_CLOWNFISH = 2, E_META_RAW_FISH_PUFFERFISH = 3, - + // E_ITEM_COOKED_FISH metas: E_META_COOKED_FISH_FISH = 0, E_META_COOKED_FISH_SALMON = 1, @@ -922,7 +922,7 @@ enum // E_ITEM_MINECART_TRACKS metas: E_META_TRACKS_X = 1, E_META_TRACKS_Z = 0, - + // E_ITEM_SPAWN_EGG metas: // See also cMonster::eType, since monster type and spawn egg meta are the same E_META_SPAWN_EGG_PICKUP = 1, @@ -1022,7 +1022,7 @@ enum eDamageType dtEnderPearl, // Thrown an ender pearl, teleported by it dtAdmin, // Damage applied by an admin command dtExplosion, // Damage applied by an explosion - + // Some common synonyms: dtPawnAttack = dtAttack, dtEntityAttack = dtAttack, diff --git a/src/BlockInfo.h b/src/BlockInfo.h index 9f562e531..c1eb926d1 100644 --- a/src/BlockInfo.h +++ b/src/BlockInfo.h @@ -17,7 +17,7 @@ class cBlockInfo public: /** Returns the associated BlockInfo structure for the specified block type. */ - + /** This accessor makes sure that the cBlockInfo structures are properly initialized exactly once. It does so by using the C++ singleton approximation - storing the actual singleton as the function's static variable. It works only if it is called for the first time before the app spawns other threads. */ diff --git a/src/BlockTracer.h b/src/BlockTracer.h index ebc0668ee..7444af488 100644 --- a/src/BlockTracer.h +++ b/src/BlockTracer.h @@ -30,12 +30,12 @@ public: public: // Force a virtual destructor in descendants: virtual ~cCallbacks() {} - + /** Called on each block encountered along the path, including the first block (path start) When this callback returns true, the tracing is aborted. */ virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) = 0; - + /** Called on each block encountered along the path, including the first block (path start), if chunk data is not loaded When this callback returns true, the tracing is aborted. */ @@ -47,7 +47,7 @@ public: UNUSED(a_EntryFace); return false; } - + /** Called when the path goes out of world, either below (a_BlockY < 0) or above (a_BlockY >= cChunkDef::Height) The coords specify the exact point at which the path exited the world. If this callback returns true, the tracing is aborted. @@ -61,7 +61,7 @@ public: UNUSED(a_BlockZ); return false; } - + /** Called when the path goes into the world, from either below (a_BlockY < 0) or above (a_BlockY >= cChunkDef::Height) The coords specify the exact point at which the path entered the world. If this callback returns true, the tracing is aborted. @@ -75,27 +75,27 @@ public: UNUSED(a_BlockZ); return false; } - + /** Called when the path is sure not to hit any more blocks. Note that for some shapes this might never happen (line with constant Y) */ virtual void OnNoMoreHits(void) {} - + /** Called when the block tracing walks into a chunk that is not allocated. This usually means that the tracing is aborted. */ virtual void OnNoChunk(void) {} } ; - - + + /** Creates the BlockTracer parent with the specified callbacks */ cBlockTracer(cWorld & a_World, cCallbacks & a_Callbacks) : m_World(&a_World), m_Callbacks(&a_Callbacks) { } - - + + /** Sets new world, returns the old one. Note that both need to be valid */ cWorld & SetWorld(cWorld & a_World) { @@ -103,8 +103,8 @@ public: m_World = &a_World; return Old; } - - + + /** Sets new callbacks, returns the old ones. Note that both need to be valid */ cCallbacks & SetCallbacks(cCallbacks & a_NewCallbacks) { @@ -112,11 +112,11 @@ public: m_Callbacks = &a_NewCallbacks; return Old; } - + protected: /** The world upon which to operate */ cWorld * m_World; - + /** The callback to use for reporting */ cCallbacks * m_Callbacks; } ; diff --git a/src/Blocks/BlockAnvil.h b/src/Blocks/BlockAnvil.h index 539316682..28718e316 100644 --- a/src/Blocks/BlockAnvil.h +++ b/src/Blocks/BlockAnvil.h @@ -18,7 +18,7 @@ public: : cBlockHandler(a_BlockType) { } - + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { a_Pickups.push_back(cItem(E_BLOCK_ANVIL, 1, a_BlockMeta >> 2)); @@ -30,7 +30,7 @@ public: a_Player->OpenWindow(Window); return true; } - + virtual bool GetPlacementBlockTypeMeta( cChunkInterface & a_ChunkInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, diff --git a/src/Blocks/BlockBed.h b/src/Blocks/BlockBed.h index c104a7cb5..cfb02ceeb 100644 --- a/src/Blocks/BlockBed.h +++ b/src/Blocks/BlockBed.h @@ -21,7 +21,7 @@ public: : cMetaRotator(a_BlockType) { } - + virtual void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override; @@ -29,7 +29,7 @@ public: { return true; } - + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { // Reset meta to zero diff --git a/src/Blocks/BlockBigFlower.h b/src/Blocks/BlockBigFlower.h index b1aec7385..7a70a7a6b 100644 --- a/src/Blocks/BlockBigFlower.h +++ b/src/Blocks/BlockBigFlower.h @@ -34,12 +34,12 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { NIBBLETYPE Meta = a_BlockMeta & 0x7; - + if ((Meta == E_META_BIG_FLOWER_DOUBLE_TALL_GRASS) || (Meta == E_META_BIG_FLOWER_LARGE_FERN)) { return; } - + a_Pickups.push_back(cItem(E_BLOCK_BIG_FLOWER, 1, Meta)); } @@ -50,7 +50,7 @@ public: { Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY - 1, a_BlockZ); } - + NIBBLETYPE FlowerMeta = Meta & 0x7; if (!a_Player->IsGameModeCreative()) { diff --git a/src/Blocks/BlockButton.h b/src/Blocks/BlockButton.h index 354d563fd..b67ae7c97 100644 --- a/src/Blocks/BlockButton.h +++ b/src/Blocks/BlockButton.h @@ -15,11 +15,11 @@ public: : cMetaRotator(a_BlockType) { } - + virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override { NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - + double x(a_BlockX); double y(a_BlockY); double z(a_BlockZ); @@ -53,7 +53,7 @@ public: return true; } - + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { // Reset meta to 0 @@ -64,7 +64,7 @@ public: { return true; } - + virtual bool GetPlacementBlockTypeMeta( cChunkInterface & a_ChunkInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, diff --git a/src/Blocks/BlockCake.h b/src/Blocks/BlockCake.h index 7c7208b05..88af210a2 100644 --- a/src/Blocks/BlockCake.h +++ b/src/Blocks/BlockCake.h @@ -14,7 +14,7 @@ public: : cBlockHandler(a_BlockType) { } - + virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override { NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); @@ -23,7 +23,7 @@ public: { return false; } - + if (Meta >= 5) { a_ChunkInterface.FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); diff --git a/src/Blocks/BlockCarpet.h b/src/Blocks/BlockCarpet.h index 19be882d0..aa3de131d 100644 --- a/src/Blocks/BlockCarpet.h +++ b/src/Blocks/BlockCarpet.h @@ -22,7 +22,7 @@ public: cBlockHandler(a_BlockType) { } - + virtual bool GetPlacementBlockTypeMeta( cChunkInterface & a_ChunkInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, @@ -34,7 +34,7 @@ public: a_BlockMeta = a_Player->GetEquippedItem().m_ItemDamage & 0x0f; return true; } - + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { a_Pickups.push_back(cItem(E_BLOCK_CARPET, 1, a_BlockMeta)); diff --git a/src/Blocks/BlockChest.h b/src/Blocks/BlockChest.h index df87ca4c7..2c34beeeb 100644 --- a/src/Blocks/BlockChest.h +++ b/src/Blocks/BlockChest.h @@ -18,7 +18,7 @@ public: : cMetaRotator(a_BlockType) { } - + virtual bool GetPlacementBlockTypeMeta( cChunkInterface & a_ChunkInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, @@ -27,14 +27,14 @@ public: ) override { a_BlockType = m_BlockType; - + // Is there a doublechest already next to this block? if (!CanBeAt(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ)) { // Yup, cannot form a triple-chest, refuse: return false; } - + // Check if this forms a doublechest, if so, need to adjust the meta: cBlockArea Area; if (!Area.Read(&a_ChunkInterface, a_BlockX - 1, a_BlockX + 1, a_BlockY, a_BlockY, a_BlockZ - 1, a_BlockZ + 1)) @@ -59,7 +59,7 @@ public: a_BlockMeta = (yaw < 0) ? 4 : 5; return true; } - + // Single chest, get meta from rotation only a_BlockMeta = PlayerYawToMetaData(yaw); return true; @@ -71,7 +71,7 @@ public: int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width; return CanBeAt(a_ChunkInterface, BlockX, a_RelY, BlockZ); } - + virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) { cBlockArea Area; @@ -80,7 +80,7 @@ public: // Cannot read the surroundings, probably at the edge of loaded chunks. Disallow. return false; } - + int NumChestNeighbors = 0; if (Area.GetRelBlockType(1, 0, 2) == m_BlockType) { @@ -136,7 +136,7 @@ public: } return (NumChestNeighbors < 2); } - + /** Translates player yaw when placing a chest into the chest block metadata. Valid for single chests only */ static NIBBLETYPE PlayerYawToMetaData(double a_Yaw) { @@ -163,7 +163,7 @@ public: return 0x03; } } - + /** If there's a chest in the a_Area in the specified coords, modifies its meta to a_NewMeta and returns true. */ bool CheckAndAdjustNeighbor(cChunkInterface & a_ChunkInterface, const cBlockArea & a_Area, int a_RelX, int a_RelZ, NIBBLETYPE a_NewMeta) { diff --git a/src/Blocks/BlockComparator.h b/src/Blocks/BlockComparator.h index 8f1822299..394b53a15 100644 --- a/src/Blocks/BlockComparator.h +++ b/src/Blocks/BlockComparator.h @@ -17,7 +17,7 @@ public: : cMetaRotator(a_BlockType) { } - + virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override { NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); @@ -42,7 +42,7 @@ public: { return true; } - + virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR)); diff --git a/src/Blocks/BlockCrops.h b/src/Blocks/BlockCrops.h index 0751d19f0..cc18a2b18 100644 --- a/src/Blocks/BlockCrops.h +++ b/src/Blocks/BlockCrops.h @@ -72,7 +72,7 @@ public: } } } - + virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override { NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ); diff --git a/src/Blocks/BlockDirt.h b/src/Blocks/BlockDirt.h index 813ff5b24..336fa8c51 100644 --- a/src/Blocks/BlockDirt.h +++ b/src/Blocks/BlockDirt.h @@ -20,7 +20,7 @@ public: : cBlockHandler(a_BlockType) { } - + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { if (a_BlockMeta == E_META_DIRT_COARSE) @@ -33,7 +33,7 @@ public: a_Pickups.Add(E_BLOCK_DIRT, 1, E_META_DIRT_NORMAL); } } - + virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override { if (m_BlockType != E_BLOCK_GRASS) @@ -50,21 +50,21 @@ public: else if ((a_RelY < cChunkDef::Height - 1)) { BLOCKTYPE above = a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ); - + // Grass turns back to dirt when the block above is not transparent if (!cBlockInfo::IsTransparent(above)) { a_Chunk.FastSetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_DIRT, E_META_DIRT_NORMAL); return; } - + NIBBLETYPE light = std::max(a_Chunk.GetBlockLight(a_RelX, a_RelY + 1, a_RelZ), a_Chunk.GetTimeAlteredLight(a_Chunk.GetSkyLight(a_RelX, a_RelY + 1, a_RelZ))); // Source block is not bright enough to spread if (light < 9) { return; } - + } // Grass spreads to adjacent dirt blocks: @@ -74,7 +74,7 @@ public: int OfsX = rand.NextInt(3) - 1; // [-1 .. 1] int OfsY = rand.NextInt(5) - 3; // [-3 .. 1] int OfsZ = rand.NextInt(3) - 1; // [-1 .. 1] - + BLOCKTYPE DestBlock; NIBBLETYPE DestMeta; if (!cChunkDef::IsValidHeight(a_RelY + OfsY)) diff --git a/src/Blocks/BlockDoor.cpp b/src/Blocks/BlockDoor.cpp index 94c49a4b8..6dae5a34d 100644 --- a/src/Blocks/BlockDoor.cpp +++ b/src/Blocks/BlockDoor.cpp @@ -86,10 +86,10 @@ bool cBlockDoorHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterfac void cBlockDoorHandler::OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) { UNUSED(a_ChunkInterface); - + a_WorldInterface.SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player); NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - + if (Meta & 0x8) { // Current block is top of the door diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index a5f2c61c3..a19cbdc40 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -46,7 +46,7 @@ public: { return false; } - + a_BlockType = m_BlockType; a_BlockMeta = PlayerYawToMetaData(a_Player->GetYaw()); return true; @@ -118,7 +118,7 @@ public: { // Vanilla refuses to place doors on transparent blocks, except top-half slabs and other doors // We need to keep the door compatible with itself, otherwise the top half drops while the bottom half stays - + // Doors can be placed on upside-down slabs if (cBlockSlabHandler::IsAnySlabType(a_BlockType) && ((a_BlockMeta & 0x08) != 0)) { @@ -159,7 +159,7 @@ public: inline static NIBBLETYPE PlayerYawToMetaData(double a_Yaw) { ASSERT((a_Yaw >= -180) && (a_Yaw < 180)); - + a_Yaw += 90 + 45; if (a_Yaw > 360) { diff --git a/src/Blocks/BlockDropSpenser.h b/src/Blocks/BlockDropSpenser.h index c572d5d34..235d67380 100644 --- a/src/Blocks/BlockDropSpenser.h +++ b/src/Blocks/BlockDropSpenser.h @@ -29,12 +29,12 @@ public: ) override { a_BlockType = m_BlockType; - + // FIXME: Do not use cPiston class for dispenser placement! a_BlockMeta = cBlockPistonHandler::RotationPitchToMetaData(a_Player->GetYaw(), a_Player->GetPitch()); return true; } - + virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override { // Bit 0x08 is a flag. Lowest three bits are position. 0x08 == 1000 diff --git a/src/Blocks/BlockEnderchest.h b/src/Blocks/BlockEnderchest.h index 0bc67a8f5..b5f015ff4 100644 --- a/src/Blocks/BlockEnderchest.h +++ b/src/Blocks/BlockEnderchest.h @@ -33,7 +33,7 @@ public: a_BlockMeta = RotationToMetaData(a_Player->GetYaw()); return true; } - + static NIBBLETYPE RotationToMetaData(double a_Rotation) { a_Rotation += 90 + 45; // So its not aligned with axis diff --git a/src/Blocks/BlockEntity.h b/src/Blocks/BlockEntity.h index 416e16069..06cd860c5 100644 --- a/src/Blocks/BlockEntity.h +++ b/src/Blocks/BlockEntity.h @@ -14,12 +14,12 @@ public: : cBlockHandler(a_BlockType) { } - + virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer *a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override { return a_ChunkInterface.UseBlockEntity(a_Player, a_BlockX, a_BlockY, a_BlockZ); } - + virtual bool IsUseable() override { return true; diff --git a/src/Blocks/BlockFenceGate.h b/src/Blocks/BlockFenceGate.h index 9e7c10cf5..f80502fb8 100644 --- a/src/Blocks/BlockFenceGate.h +++ b/src/Blocks/BlockFenceGate.h @@ -68,7 +68,7 @@ public: inline static NIBBLETYPE PlayerYawToMetaData(double a_Yaw) { ASSERT((a_Yaw >= -180) && (a_Yaw < 180)); - + a_Yaw += 360 + 45; if (a_Yaw > 360) { diff --git a/src/Blocks/BlockFire.h b/src/Blocks/BlockFire.h index d1c8c17c9..346167a26 100644 --- a/src/Blocks/BlockFire.h +++ b/src/Blocks/BlockFire.h @@ -59,7 +59,7 @@ public: { return 0; } - + for (int newY = Y + 1; newY < cChunkDef::Height; newY++) { BLOCKTYPE Block = a_ChunkInterface.GetBlock(X, newY, Z); diff --git a/src/Blocks/BlockFluid.h b/src/Blocks/BlockFluid.h index 2d9adbab5..df51fb104 100644 --- a/src/Blocks/BlockFluid.h +++ b/src/Blocks/BlockFluid.h @@ -11,24 +11,24 @@ class cBlockFluidHandler : public cBlockHandler { typedef cBlockHandler super; - + public: cBlockFluidHandler(BLOCKTYPE a_BlockType) : cBlockHandler(a_BlockType) { } - + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { // No pickups } - + virtual bool DoesIgnoreBuildCollision(void) override { return true; } - + virtual void Check(cChunkInterface & a_ChunkInterface, cBlockPluginInterface & a_PluginInterface, int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk) override { switch (m_BlockType) @@ -84,7 +84,7 @@ public: super(a_BlockType) { } - + /** Called to tick the block */ virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override { @@ -97,7 +97,7 @@ public: } } } - + /** Tries to start a fire near the lava at given coords. Returns true if fire started. */ static bool TryStartFireNear(int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk) { @@ -106,7 +106,7 @@ public: int x = (rnd % 3) - 1; // -1 .. 1 int y = ((rnd / 4) % 4) - 1; // -1 .. 2 int z = ((rnd / 16) % 3) - 1; // -1 .. 1 - + // Check if it's fuel: BLOCKTYPE BlockType; if ( @@ -117,7 +117,7 @@ public: { return false; } - + // Try to set it on fire: static struct { diff --git a/src/Blocks/BlockFurnace.h b/src/Blocks/BlockFurnace.h index a543a26f4..6310458f8 100644 --- a/src/Blocks/BlockFurnace.h +++ b/src/Blocks/BlockFurnace.h @@ -22,7 +22,7 @@ public: { a_Pickups.push_back(cItem(E_BLOCK_FURNACE, 1, 0)); } - + virtual bool GetPlacementBlockTypeMeta( cChunkInterface & a_ChunkInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, @@ -31,10 +31,10 @@ public: ) override { a_BlockType = m_BlockType; - + // FIXME: Do not use cPiston class for furnace placement! a_BlockMeta = cBlockPistonHandler::RotationPitchToMetaData(a_Player->GetYaw(), 0); - + return true; } diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 22b70f590..be254900d 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -136,7 +136,7 @@ public: // CW rotation of a CCW rotation should produce no change in the meta printf("Handler for blocktype %d (%s) fails CW(CCW) rotation test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta); } - + // Test the mirroring: TestMeta = Handler->MetaMirrorXY(Handler->MetaMirrorXY(Meta)); if (TestMeta != Meta) @@ -156,7 +156,7 @@ public: // Double-mirroring should produce the same meta: printf("Handler for blocktype %d (%s) fails YZ mirror test for meta %d: got back %d\n", Type, BlockName.c_str(), Meta, TestMeta); } - + // Test mirror-rotating: TestMeta = Handler->MetaRotateCW(Handler->MetaRotateCW(Handler->MetaMirrorXY(Handler->MetaMirrorYZ(Meta)))); if (TestMeta != Meta) @@ -331,7 +331,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_WOOL: return new cBlockClothHandler (a_BlockType); case E_BLOCK_WORKBENCH: return new cBlockWorkbenchHandler (a_BlockType); case E_BLOCK_YELLOW_FLOWER: return new cBlockFlowerHandler (a_BlockType); - + default: return new cBlockHandler(a_BlockType); } } @@ -512,7 +512,7 @@ void cBlockHandler::DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterfac // Allow plugins to modify the pickups: a_BlockPluginInterface.CallHookBlockToPickups(a_Digger, a_BlockX, a_BlockY, a_BlockZ, m_BlockType, Meta, Pickups); - + if (!Pickups.empty()) { MTRand r1; @@ -600,7 +600,7 @@ void cBlockHandler::Check(cChunkInterface & a_ChunkInterface, cBlockPluginInterf int BlockZ = a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width; DropBlock(a_ChunkInterface, *a_Chunk.GetWorld(), a_PluginInterface, nullptr, BlockX, a_RelY, BlockZ); } - + a_Chunk.SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_AIR, 0); } else diff --git a/src/Blocks/BlockHandler.h b/src/Blocks/BlockHandler.h index 41fbc5140..24552fb46 100644 --- a/src/Blocks/BlockHandler.h +++ b/src/Blocks/BlockHandler.h @@ -23,7 +23,7 @@ class cBlockHandler { public: cBlockHandler(BLOCKTYPE a_BlockType); - + virtual ~cBlockHandler() {} /** Called when the block gets ticked either by a random tick or by a queued tick. @@ -43,71 +43,71 @@ public: /** Called by cWorld::SetBlock() after the block has been set */ virtual void OnPlaced(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); - + /** Called by cPlayer::PlaceBlocks() for each block after it has been set to the world. Called after OnPlaced(). */ virtual void OnPlacedByPlayer( cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, const sSetBlock & a_BlockChange ); - + /** Called before the player has destroyed a block */ virtual void OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ); - + /** Called before a block gets destroyed / replaced with air */ virtual void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ); - + /** Called when a direct neighbor of this block has been changed (The position is the block's own position, not the changing neighbor's position) a_WhichNeighbor indicates which neighbor has changed. For example, BLOCK_FACE_YP meant the neighbor above has changed. BLOCK_FACE_NONE means that it is a neighbor not directly adjacent (diagonal, etc.) */ virtual void OnNeighborChanged(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_WhichNeighbor) {} - + /** Notifies the specified neighbor that the current block has changed. a_NeighborXYZ coords are the coords of the neighbor a_WhichNeighbor specifies which neighbor (relative to a_NeighborXYZ) has changed. For example BLOCK_FACE_YP means that the block at {a_NeighborX, a_NeighborY + 1, a_NeighborZ} has changed. BLOCK_FACE_NONE means that it is a neighbor not directly adjacent (diagonal, etc.) */ static void NeighborChanged(cChunkInterface & a_ChunkInterface, int a_NeighborX, int a_NeighborY, int a_NeighborZ, eBlockFace a_WhichNeighbor); - + /** Called when the player starts digging the block. */ virtual void OnDigging(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) {} - + /** Called if the user right clicks the block and the block is useable returns true if the use was successful, return false to use the block as a "normal" block */ virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) { return false; } - + /** Called when a right click to this block is cancelled */ virtual void OnCancelRightClick(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) {} - + /** Called when the item is mined to convert it into pickups. Pickups may specify multiple items. Appends items to a_Pickups, preserves its original contents */ virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta); - + /** Handles the dropping, but not destruction, of a block based on what ConvertTo(Verbatim)Pickups() returns, including the spawning of pickups and alertion of plugins @param a_Digger The entity causing the drop; it may be nullptr @param a_CanDrop Informs the handler whether the block should be dropped at all. One example when this is false is when stone is destroyed by hand @param a_DropVerbatim Calls ConvertToVerbatimPickups() instead of its counterpart, meaning the block itself is dropped by default (due to a speical tool or enchantment) */ virtual void DropBlock(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, bool a_CanDrop = true); - + /** Checks if the block can stay at the specified relative coords in the chunk */ virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk); /** Checks whether the block has an effect on growing the plant */ virtual bool CanSustainPlant(BLOCKTYPE a_Plant) { return false; } - + /** Checks if the block can be placed at this point. Default: CanBeAt(...) NOTE: This call doesn't actually place the block */ // virtual bool CanBePlacedAt(cWorld * a_World, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir); - + /** Called to check whether this block supports a rclk action. If it returns true, OnUse() is called */ virtual bool IsUseable(void); - + /** Indicates whether the client will click through this block. For example digging a fire will hit the block below the fire so fire is clicked through */ virtual bool IsClickedThrough(void); - + /** Checks if the player can build "inside" this block. For example blocks placed "on" snow will be placed at the same position. So: Snow ignores Build collision */ @@ -136,15 +136,15 @@ public: /** Returns the base colour ID of the block, as will be represented on a map, as per documentation: http://minecraft.gamepedia.com/Map_item_format */ virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta); - + /** Rotates a given block meta counter-clockwise. Default: no change Returns block meta following rotation */ virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) { return a_Meta; } - + /** Rotates a given block meta clockwise. Default: no change Returns block meta following rotation */ virtual NIBBLETYPE MetaRotateCW(NIBBLETYPE a_Meta) { return a_Meta; } - + /** Mirrors a given block meta around the XY plane. Default: no change Returns block meta following rotation */ virtual NIBBLETYPE MetaMirrorXY(NIBBLETYPE a_Meta) { return a_Meta; } @@ -156,10 +156,10 @@ public: /** Mirros a given block meta around the YZ plane. Default: no change Returns block meta following rotation */ virtual NIBBLETYPE MetaMirrorYZ(NIBBLETYPE a_Meta) { return a_Meta; } - + protected: BLOCKTYPE m_BlockType; - + // Creates a new blockhandler for the given block type. For internal use only, use ::GetBlockHandler() instead. static cBlockHandler * CreateBlockHandler(BLOCKTYPE a_BlockType); diff --git a/src/Blocks/BlockHopper.h b/src/Blocks/BlockHopper.h index 0c0871fdd..6fd8204fd 100644 --- a/src/Blocks/BlockHopper.h +++ b/src/Blocks/BlockHopper.h @@ -24,7 +24,7 @@ public: ) override { a_BlockType = m_BlockType; - + // Convert the blockface into meta: switch (a_BlockFace) { diff --git a/src/Blocks/BlockIce.h b/src/Blocks/BlockIce.h index 337c92022..aae190036 100644 --- a/src/Blocks/BlockIce.h +++ b/src/Blocks/BlockIce.h @@ -21,14 +21,14 @@ public: { // No pickups } - + virtual void OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override { if (a_Player->IsGameModeCreative() || (a_BlockY <= 0)) { return; } - + cEnchantments Enchantments = a_Player->GetInventory().GetEquippedItem().m_Enchantments; if (Enchantments.GetLevel(cEnchantments::enchSilkTouch) == 0) { diff --git a/src/Blocks/BlockLadder.h b/src/Blocks/BlockLadder.h index 5a1a099b7..41d01280b 100644 --- a/src/Blocks/BlockLadder.h +++ b/src/Blocks/BlockLadder.h @@ -29,7 +29,7 @@ public: if (!LadderCanBePlacedAt(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace)) { a_BlockFace = FindSuitableBlockFace(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ); - + if (a_BlockFace == BLOCK_FACE_BOTTOM) { return false; diff --git a/src/Blocks/BlockLeaves.h b/src/Blocks/BlockLeaves.h index 2017c391b..8807a40ef 100644 --- a/src/Blocks/BlockLeaves.h +++ b/src/Blocks/BlockLeaves.h @@ -82,7 +82,7 @@ public: a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta & 0x7); } } - + virtual void OnUpdate(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override { NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ); @@ -159,7 +159,7 @@ bool HasNearLog(cBlockArea & a_Area, int a_BlockX, int a_BlockY, int a_BlockZ) } } } // for i - Types[] - + // Perform a breadth-first search to see if there's a log connected within 4 blocks of the leaves block: // Simply replace all reachable leaves blocks with a sponge block plus iteration (in the Area) and see if we can reach a log in 4 iterations a_Area.SetBlockType(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_SPONGE); diff --git a/src/Blocks/BlockLever.h b/src/Blocks/BlockLever.h index a3bbd54f5..4b52df981 100644 --- a/src/Blocks/BlockLever.h +++ b/src/Blocks/BlockLever.h @@ -10,13 +10,13 @@ class cBlockLeverHandler : public cMetaRotator { typedef cMetaRotator super; - + public: cBlockLeverHandler(BLOCKTYPE a_BlockType) : super(a_BlockType) { } - + virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override { // Flip the ON bit on / off using the XOR bitwise operation @@ -38,7 +38,7 @@ public: { return true; } - + virtual bool GetPlacementBlockTypeMeta( cChunkInterface & a_ChunkInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, @@ -93,7 +93,7 @@ public: virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ); - + eBlockFace Face = BlockMetaDataToBlockFace(Meta); AddFaceDirection(a_RelX, a_RelY, a_RelZ, Face, true); diff --git a/src/Blocks/BlockMelon.h b/src/Blocks/BlockMelon.h index 4743e5c98..a9723dcec 100644 --- a/src/Blocks/BlockMelon.h +++ b/src/Blocks/BlockMelon.h @@ -15,7 +15,7 @@ public: : cBlockHandler(a_BlockType) { } - + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { cFastRandom Random; diff --git a/src/Blocks/BlockMobHead.h b/src/Blocks/BlockMobHead.h index 72face3a2..a271c3b43 100644 --- a/src/Blocks/BlockMobHead.h +++ b/src/Blocks/BlockMobHead.h @@ -39,7 +39,7 @@ public: return false; } cMobHeadEntity * MobHeadEntity = static_cast(a_BlockEntity); - + cItems Pickups; Pickups.Add(E_ITEM_HEAD, 1, static_cast(MobHeadEntity->GetType())); MTRand r1; @@ -58,7 +58,7 @@ public: return false; } } Callback; - + a_WorldInterface.DoWithBlockEntityAt(a_BlockX, a_BlockY, a_BlockZ, Callback); } diff --git a/src/Blocks/BlockMobSpawner.h b/src/Blocks/BlockMobSpawner.h index 67102c78d..a6205490f 100644 --- a/src/Blocks/BlockMobSpawner.h +++ b/src/Blocks/BlockMobSpawner.h @@ -35,8 +35,8 @@ public: { // No pickups } - - + + virtual void OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override { cItemHandler * Handler = a_Player->GetEquippedItem().GetHandler(); diff --git a/src/Blocks/BlockMushroom.h b/src/Blocks/BlockMushroom.h index 65b68b097..d6b726b57 100644 --- a/src/Blocks/BlockMushroom.h +++ b/src/Blocks/BlockMushroom.h @@ -30,9 +30,9 @@ public: { return false; } - + // TODO: Cannot be at too much daylight - + switch (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)) { case E_BLOCK_GLASS: diff --git a/src/Blocks/BlockPiston.h b/src/Blocks/BlockPiston.h index 6a384b85d..30ccc168d 100644 --- a/src/Blocks/BlockPiston.h +++ b/src/Blocks/BlockPiston.h @@ -14,7 +14,7 @@ class cBlockPistonHandler : { public: cBlockPistonHandler(BLOCKTYPE a_BlockType); - + virtual void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override; @@ -94,7 +94,7 @@ public: } private: - + typedef std::unordered_set> Vector3iSet; /** Returns true if the piston (specified by blocktype) is a sticky piston */ @@ -153,7 +153,7 @@ private: const Vector3i & a_BlockPos, cWorld * a_World, bool a_RequirePushable, Vector3iSet & a_BlocksPushed, const Vector3i & a_PushDir ); - + /** Moves a list of blocks in a specific direction */ static void PushBlocks(const Vector3iSet & a_BlocksToPush, cWorld * a_World, const Vector3i & a_PushDir @@ -168,10 +168,10 @@ class cBlockPistonHeadHandler : public cBlockHandler { typedef cBlockHandler super; - + public: cBlockPistonHeadHandler(void); - + virtual void OnDestroyedByPlayer(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override diff --git a/src/Blocks/BlockPlanks.h b/src/Blocks/BlockPlanks.h index 52e8c34dc..b84b048c1 100644 --- a/src/Blocks/BlockPlanks.h +++ b/src/Blocks/BlockPlanks.h @@ -14,7 +14,7 @@ public: : cBlockHandler(a_BlockType) { } - + virtual bool GetPlacementBlockTypeMeta( cChunkInterface & a_ChunkInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, diff --git a/src/Blocks/BlockPluginInterface.h b/src/Blocks/BlockPluginInterface.h index 6d49a248d..d97927b36 100644 --- a/src/Blocks/BlockPluginInterface.h +++ b/src/Blocks/BlockPluginInterface.h @@ -28,7 +28,7 @@ class cBlockPluginInterface { public: virtual ~cBlockPluginInterface() {} - + virtual bool CallHookBlockSpread(int a_BlockX, int a_BlockY, int a_BlockZ, eSpreadSource a_Source) = 0; virtual bool CallHookBlockToPickups(cEntity * a_Digger, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, cItems & a_Pickups) = 0; virtual bool CallHookPlayerBreakingBlock(cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0; diff --git a/src/Blocks/BlockPortal.h b/src/Blocks/BlockPortal.h index 4af50984e..504c018fb 100644 --- a/src/Blocks/BlockPortal.h +++ b/src/Blocks/BlockPortal.h @@ -112,7 +112,7 @@ public: } return true; } - + virtual ColourID GetMapBaseColourID(NIBBLETYPE a_Meta) override { UNUSED(a_Meta); diff --git a/src/Blocks/BlockPumpkin.h b/src/Blocks/BlockPumpkin.h index 133a486ac..b5927c1ef 100644 --- a/src/Blocks/BlockPumpkin.h +++ b/src/Blocks/BlockPumpkin.h @@ -15,7 +15,7 @@ public: super(a_BlockType) { } - + virtual bool GetPlacementBlockTypeMeta( cChunkInterface & a_ChunkInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, @@ -31,7 +31,7 @@ public: inline static NIBBLETYPE PlayerYawToMetaData(double a_Yaw) { ASSERT((a_Yaw >= -180) && (a_Yaw < 180)); - + a_Yaw += 180 + 45; if (a_Yaw > 360) { diff --git a/src/Blocks/BlockRail.h b/src/Blocks/BlockRail.h index 734ee93c7..dda9af60d 100644 --- a/src/Blocks/BlockRail.h +++ b/src/Blocks/BlockRail.h @@ -22,13 +22,13 @@ class cBlockRailHandler : public cBlockHandler { typedef cBlockHandler super; - + public: cBlockRailHandler(BLOCKTYPE a_BlockType) : cBlockHandler(a_BlockType) { } - + virtual bool GetPlacementBlockTypeMeta( cChunkInterface & a_ChunkInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, @@ -85,7 +85,7 @@ public: { super::ConvertToPickups(a_Pickups, 0); } - + virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { if (a_RelY <= 0) @@ -279,7 +279,7 @@ public: } break; } - + case E_META_RAIL_XM_XP: { if ( @@ -291,7 +291,7 @@ public: } break; } - + case E_META_RAIL_ASCEND_XP: { if ( @@ -303,7 +303,7 @@ public: } break; } - + case E_META_RAIL_ASCEND_XM: { if ( @@ -315,7 +315,7 @@ public: } break; } - + case E_META_RAIL_ASCEND_ZM: { if ( @@ -327,7 +327,7 @@ public: } break; } - + case E_META_RAIL_ASCEND_ZP: { if ( @@ -339,7 +339,7 @@ public: } break; } - + case E_META_RAIL_CURVED_ZP_XP: { if ( @@ -351,7 +351,7 @@ public: } break; } - + case E_META_RAIL_CURVED_ZP_XM: { if ( @@ -363,7 +363,7 @@ public: } break; } - + case E_META_RAIL_CURVED_ZM_XM: { if ( @@ -375,7 +375,7 @@ public: } break; } - + case E_META_RAIL_CURVED_ZM_XP: { if ( @@ -417,7 +417,7 @@ public: { Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); } - + switch (a_BlockFace) { case BLOCK_FACE_NORTH: @@ -434,7 +434,7 @@ public: } break; } - + case BLOCK_FACE_SOUTH: { if ( @@ -449,7 +449,7 @@ public: } break; } - + case BLOCK_FACE_EAST: { if ( diff --git a/src/Blocks/BlockRedstone.h b/src/Blocks/BlockRedstone.h index ec661b1f0..47c90bfd9 100644 --- a/src/Blocks/BlockRedstone.h +++ b/src/Blocks/BlockRedstone.h @@ -43,7 +43,7 @@ public: } return false; } - + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { // Reset meta to zero diff --git a/src/Blocks/BlockRedstoneLamp.h b/src/Blocks/BlockRedstoneLamp.h index 8545d5ca6..5ac98de87 100644 --- a/src/Blocks/BlockRedstoneLamp.h +++ b/src/Blocks/BlockRedstoneLamp.h @@ -15,7 +15,7 @@ public: : cBlockHandler(a_BlockType) { } - + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { a_Pickups.push_back(cItem(E_BLOCK_REDSTONE_LAMP_OFF, 1, 0)); diff --git a/src/Blocks/BlockRedstoneRepeater.h b/src/Blocks/BlockRedstoneRepeater.h index 033ba82de..54e87bb32 100644 --- a/src/Blocks/BlockRedstoneRepeater.h +++ b/src/Blocks/BlockRedstoneRepeater.h @@ -52,7 +52,7 @@ public: { return true; } - + virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { if (a_RelY <= 0) diff --git a/src/Blocks/BlockSapling.h b/src/Blocks/BlockSapling.h index ea10d5c20..b7d2f163b 100644 --- a/src/Blocks/BlockSapling.h +++ b/src/Blocks/BlockSapling.h @@ -17,18 +17,18 @@ public: : cBlockHandler(a_BlockType) { } - + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { // Only the first 2 bits contain the display information and the 4th bit is for the growth indicator, but, we use 0x07 for forward compatibility a_Pickups.push_back(cItem(E_BLOCK_SAPLING, 1, a_BlockMeta & 0x07)); } - + virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { return (a_RelY > 0) && IsBlockTypeOfDirt(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)); } - + virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override { NIBBLETYPE Meta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ); diff --git a/src/Blocks/BlockSideways.h b/src/Blocks/BlockSideways.h index c3fa5b3da..c9d157d11 100644 --- a/src/Blocks/BlockSideways.h +++ b/src/Blocks/BlockSideways.h @@ -15,7 +15,7 @@ public: { } - + virtual bool GetPlacementBlockTypeMeta( cChunkInterface & a_ChunkInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, diff --git a/src/Blocks/BlockSignPost.h b/src/Blocks/BlockSignPost.h index 0b122af98..51e034081 100644 --- a/src/Blocks/BlockSignPost.h +++ b/src/Blocks/BlockSignPost.h @@ -13,7 +13,7 @@ class cBlockSignPostHandler : public cBlockHandler { typedef cBlockHandler super; - + public: cBlockSignPostHandler(BLOCKTYPE a_BlockType) : super(a_BlockType) @@ -43,9 +43,9 @@ public: { a_Rotation -= 360; } - + a_Rotation = (a_Rotation / 360) * 16; - + return (static_cast(a_Rotation)) % 16; } diff --git a/src/Blocks/BlockSlab.h b/src/Blocks/BlockSlab.h index bc7f79099..c75dee50d 100644 --- a/src/Blocks/BlockSlab.h +++ b/src/Blocks/BlockSlab.h @@ -39,7 +39,7 @@ public: { a_BlockType = m_BlockType; NIBBLETYPE Meta = static_cast(a_Player->GetEquippedItem().m_ItemDamage); - + // Set the correct metadata based on player equipped item (i.e. a_BlockMeta not initialised yet) switch (a_BlockFace) { @@ -84,7 +84,7 @@ public: return true; } - + /** Returns true if the specified blocktype is one of the slabs handled by this handler */ static bool IsAnySlabType(BLOCKTYPE a_BlockType) { @@ -101,7 +101,7 @@ public: // Sends the slab back to the client. It's to refuse a doubleslab placement. */ a_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, a_Player); } - + /** Converts the single-slab blocktype to its equivalent double-slab blocktype */ static BLOCKTYPE GetDoubleSlabType(BLOCKTYPE a_SingleSlabBlockType) { @@ -114,7 +114,7 @@ public: ASSERT(!"Unhandled slab type!"); return E_BLOCK_AIR; } - + virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override { // Toggle the 4th bit - up / down: @@ -203,7 +203,7 @@ public: BLOCKTYPE Block = GetSingleSlabType(m_BlockType); a_Pickups.push_back(cItem(Block, 2, a_BlockMeta & 0x7)); } - + inline static BLOCKTYPE GetSingleSlabType(BLOCKTYPE a_BlockType) { switch (a_BlockType) diff --git a/src/Blocks/BlockSlime.h b/src/Blocks/BlockSlime.h index e785a6a13..8302c0bf4 100644 --- a/src/Blocks/BlockSlime.h +++ b/src/Blocks/BlockSlime.h @@ -14,7 +14,7 @@ public: : cBlockHandler(a_BlockType) { } - + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { a_Pickups.push_back(cItem(m_BlockType, 1, 0)); diff --git a/src/Blocks/BlockSnow.h b/src/Blocks/BlockSnow.h index c49aa7161..d11c444b9 100644 --- a/src/Blocks/BlockSnow.h +++ b/src/Blocks/BlockSnow.h @@ -36,7 +36,7 @@ public: // - Height is smaller than 7, the maximum possible height MetaBeforePlacement++; } - + a_BlockMeta = MetaBeforePlacement; return true; } @@ -67,17 +67,17 @@ public: { BLOCKTYPE BlockBelow = a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ); NIBBLETYPE MetaBelow = a_Chunk.GetMeta(a_RelX, a_RelY - 1, a_RelZ); - + if (cBlockInfo::IsSnowable(BlockBelow) || ((BlockBelow == E_BLOCK_SNOW) && (MetaBelow == 7))) { // If block below is snowable, or it is a thin slow block and has a meta of 7 (full thin snow block), say yay return true; } } - + return false; } - + virtual bool DoesDropOnUnsuitable(void) override { return false; diff --git a/src/Blocks/BlockStems.h b/src/Blocks/BlockStems.h index df832c55a..388da5874 100644 --- a/src/Blocks/BlockStems.h +++ b/src/Blocks/BlockStems.h @@ -23,7 +23,7 @@ public: short ItemType = (m_BlockType == E_BLOCK_MELON_STEM) ? E_ITEM_MELON_SEEDS : E_ITEM_PUMPKIN_SEEDS; a_Pickups.push_back(cItem(ItemType, 1, 0)); } - + virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override { auto Action = CanGrow(a_Chunk, a_RelX, a_RelY, a_RelZ); diff --git a/src/Blocks/BlockSugarcane.h b/src/Blocks/BlockSugarcane.h index 2b4c9e583..7e2a0c0a5 100644 --- a/src/Blocks/BlockSugarcane.h +++ b/src/Blocks/BlockSugarcane.h @@ -71,7 +71,7 @@ public: } return false; } - + virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override { if (CanGrow(a_Chunk, a_RelX, a_RelY, a_RelZ) == paGrowth) diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h index db66259e9..6fd2ca231 100644 --- a/src/Blocks/BlockTorch.h +++ b/src/Blocks/BlockTorch.h @@ -16,7 +16,7 @@ public: : cMetaRotator(a_BlockType) { } - + virtual bool GetPlacementBlockTypeMeta( cChunkInterface & a_ChunkInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, @@ -142,7 +142,7 @@ public: } } } - + /** Finds a suitable face to place the torch, returning BLOCK_FACE_NONE on failure */ static eBlockFace FindSuitableFace(cChunkInterface & a_ChunkInterface, int a_BlockX, int a_BlockY, int a_BlockZ) { diff --git a/src/Blocks/BlockTrapdoor.h b/src/Blocks/BlockTrapdoor.h index bd10a63da..e9e1f7794 100644 --- a/src/Blocks/BlockTrapdoor.h +++ b/src/Blocks/BlockTrapdoor.h @@ -39,7 +39,7 @@ public: // Flip the ON bit on / off using the XOR bitwise operation NIBBLETYPE Meta = (a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x04); a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta); - + cWorld * World = static_cast(&a_WorldInterface); World->BroadcastSoundParticleEffect(EffectID::SFX_RANDOM_DOOR_OPEN_CLOSE, a_BlockX, a_BlockY, a_BlockZ, 0, a_Player->GetClientHandle()); diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index 575273cde..dc04bee60 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -14,7 +14,7 @@ public: : cBlockHandler(a_BlockType) { } - + virtual bool GetPlacementBlockTypeMeta( cChunkInterface & a_ChunkInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, @@ -117,18 +117,18 @@ public: } return res; } - + void Check(cChunkInterface & a_ChunkInterface, cBlockPluginInterface & a_PluginInterface, int a_RelX, int a_RelY, int a_RelZ, cChunk & a_Chunk) override { NIBBLETYPE CurMeta = a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ); NIBBLETYPE MaxMeta = GetMaxMeta(a_Chunk, a_RelX, a_RelY, a_RelZ); - + // Check if vine above us, add its meta to MaxMeta if ((a_RelY < cChunkDef::Height - 1) && (a_Chunk.GetBlock(a_RelX, a_RelY + 1, a_RelZ) == m_BlockType)) { MaxMeta |= a_Chunk.GetMeta(a_RelX, a_RelY + 1, a_RelZ); } - + NIBBLETYPE Common = CurMeta & MaxMeta; // Neighbors that we have and are legal if (Common != CurMeta) { diff --git a/src/Blocks/BlockWorkbench.h b/src/Blocks/BlockWorkbench.h index cafc11af8..eb75647ff 100644 --- a/src/Blocks/BlockWorkbench.h +++ b/src/Blocks/BlockWorkbench.h @@ -17,7 +17,7 @@ public: : cBlockHandler(a_BlockType) { } - + virtual bool OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override { cWindow * Window = new cCraftingWindow(a_BlockX, a_BlockY, a_BlockZ); diff --git a/src/Blocks/BroadcastInterface.h b/src/Blocks/BroadcastInterface.h index bf464627d..ab101e1f6 100644 --- a/src/Blocks/BroadcastInterface.h +++ b/src/Blocks/BroadcastInterface.h @@ -5,7 +5,7 @@ class cBroadcastInterface { public: virtual ~cBroadcastInterface() {} - + virtual void BroadcastUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) = 0; virtual void BroadcastSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = nullptr) = 0; virtual void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = nullptr) = 0; diff --git a/src/Blocks/ChunkInterface.h b/src/Blocks/ChunkInterface.h index ee9bf9da7..33413ca1a 100644 --- a/src/Blocks/ChunkInterface.h +++ b/src/Blocks/ChunkInterface.h @@ -21,32 +21,32 @@ public: NIBBLETYPE GetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ); bool GetBlockTypeMeta(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); - + /** Sets the block at the specified coords to the specified value. Full processing, incl. updating neighbors, is performed. */ void SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); - + void SetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_MetaData); - + /** Sets the block at the specified coords to the specified value. The replacement doesn't trigger block updates. The replaced blocks aren't checked for block entities (block entity is leaked if it exists at this block) */ void FastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); - + void FastSetBlock(const Vector3i & a_Pos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); /** Use block entity on coordinate. returns true if the use was successful, return false to use the block as a "normal" block */ bool UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ); - + virtual bool ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback) override; - + virtual bool WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes) override; - + bool DigBlock(cWorldInterface & a_WorldInterface, int a_X, int a_Y, int a_Z); - + private: cChunkMap * m_ChunkMap; }; diff --git a/src/Blocks/ClearMetaOnDrop.h b/src/Blocks/ClearMetaOnDrop.h index aa4f23848..91e932454 100644 --- a/src/Blocks/ClearMetaOnDrop.h +++ b/src/Blocks/ClearMetaOnDrop.h @@ -15,7 +15,7 @@ public: cClearMetaOnDrop(BLOCKTYPE a_BlockType) : Base(a_BlockType) {} - + virtual ~cClearMetaOnDrop() {} virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { diff --git a/src/Blocks/MetaRotator.h b/src/Blocks/MetaRotator.h index 4c268077a..67066efff 100644 --- a/src/Blocks/MetaRotator.h +++ b/src/Blocks/MetaRotator.h @@ -28,7 +28,7 @@ public: cMetaRotator(BLOCKTYPE a_BlockType) : Base(a_BlockType) {} - + virtual ~cMetaRotator() {} virtual NIBBLETYPE MetaRotateCCW(NIBBLETYPE a_Meta) override; diff --git a/src/Blocks/WorldInterface.h b/src/Blocks/WorldInterface.h index ede0837a4..c6cf070a0 100644 --- a/src/Blocks/WorldInterface.h +++ b/src/Blocks/WorldInterface.h @@ -17,22 +17,22 @@ class cWorldInterface { public: virtual ~cWorldInterface() {} - + virtual int GetTimeOfDay(void) const = 0; virtual Int64 GetWorldAge(void) const = 0; - + virtual eDimension GetDimension(void) const = 0; - + virtual cBroadcastInterface & GetBroadcastManager() = 0; - + virtual void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void * a_SourceData) = 0; - + /** Spawns item pickups for each item in the list. May compress pickups if too many entities: */ virtual void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_FlyAwaySpeed = 1.0, bool IsPlayerCreated = false) = 0; - + /** Spawns item pickups for each item in the list. May compress pickups if too many entities. All pickups get the speed specified. */ virtual void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_SpeedX, double a_SpeedY, double a_SpeedZ, bool IsPlayerCreated = false) = 0; - + /** Spawns a mob of the specified type. Returns the mob's UniqueID if recognized and spawned, or cEntity::INVALID_ID on failure. */ virtual UInt32 SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterType a_MonsterType, bool a_Baby) = 0; diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp index 7999226e8..526b8b754 100644 --- a/src/ByteBuffer.cpp +++ b/src/ByteBuffer.cpp @@ -66,7 +66,7 @@ public: cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestWrite), "ByteBuffer write"); cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestWrap), "ByteBuffer wraparound"); } - + static void TestRead(void) { cByteBuffer buf(50); @@ -78,7 +78,7 @@ public: UInt32 v3; assert_test(buf.ReadVarInt(v3) && (v3 == 0)); } - + static void TestWrite(void) { cByteBuffer buf(50); @@ -90,7 +90,7 @@ public: assert_test(All.size() == 4); assert_test(memcmp(All.data(), "\x05\xac\x02\x00", All.size()) == 0); } - + static void TestWrap(void) { cByteBuffer buf(3); @@ -110,7 +110,7 @@ public: assert_test(buf.GetFreeSpace() == FreeSpace); // We're back to normal } } - + } g_ByteBufferTest; #endif @@ -203,7 +203,7 @@ bool cByteBuffer::Write(const void * a_Bytes, size_t a_Count) size_t CurFreeSpace = GetFreeSpace(); size_t CurReadableSpace = GetReadableSpace(); size_t WrittenBytes = 0; - + if (CurFreeSpace < a_Count) { return false; @@ -223,7 +223,7 @@ bool cByteBuffer::Write(const void * a_Bytes, size_t a_Count) } m_WritePos = 0; } - + // We're guaranteed that we'll fit in a single write op if (a_Count > 0) { @@ -231,7 +231,7 @@ bool cByteBuffer::Write(const void * a_Bytes, size_t a_Count) m_WritePos += a_Count; WrittenBytes += a_Count; } - + ASSERT(GetFreeSpace() == CurFreeSpace - WrittenBytes); ASSERT(GetReadableSpace() == CurReadableSpace + WrittenBytes); return true; @@ -543,12 +543,12 @@ bool cByteBuffer::ReadLEInt(int & a_Value) CheckValid(); NEEDBYTES(4); ReadBuf(&a_Value, 4); - + #ifdef IS_BIG_ENDIAN // Convert: a_Value = ((a_Value >> 24) & 0xff) | ((a_Value >> 16) & 0xff00) | ((a_Value >> 8) & 0xff0000) | (a_Value & 0xff000000); #endif - + return true; } @@ -569,7 +569,7 @@ bool cByteBuffer::ReadPosition64(int & a_BlockX, int & a_BlockY, int & a_BlockZ) UInt32 BlockXRaw = (Value >> 38) & 0x03ffffff; // Top 26 bits UInt32 BlockYRaw = (Value >> 26) & 0x0fff; // Middle 12 bits UInt32 BlockZRaw = (Value & 0x03ffffff); // Bottom 26 bits - + // If the highest bit in the number's range is set, convert the number into negative: a_BlockX = ((BlockXRaw & 0x02000000) == 0) ? static_cast(BlockXRaw) : -(0x04000000 - static_cast(BlockXRaw)); a_BlockY = ((BlockYRaw & 0x0800) == 0) ? static_cast(BlockYRaw) : -(0x0800 - static_cast(BlockYRaw)); @@ -728,7 +728,7 @@ bool cByteBuffer::WriteVarInt32(UInt32 a_Value) { CHECK_THREAD CheckValid(); - + // A 32-bit integer can be encoded by at most 5 bytes: unsigned char b[5]; size_t idx = 0; @@ -750,7 +750,7 @@ bool cByteBuffer::WriteVarInt64(UInt64 a_Value) { CHECK_THREAD CheckValid(); - + // A 64-bit integer can be encoded by at most 10 bytes: unsigned char b[10]; size_t idx = 0; @@ -835,7 +835,7 @@ bool cByteBuffer::ReadBuf(void * a_Buffer, size_t a_Count) } m_ReadPos = 0; } - + // Read the rest of the bytes in a single read (guaranteed to fit): if (a_Count > 0) { @@ -865,7 +865,7 @@ bool cByteBuffer::WriteBuf(const void * a_Buffer, size_t a_Count) a_Count -= BytesToEndOfBuffer; m_WritePos = 0; } - + // Read the rest of the bytes in a single read (guaranteed to fit): if (a_Count > 0) { diff --git a/src/ByteBuffer.h b/src/ByteBuffer.h index cec85a404..df8443dd2 100644 --- a/src/ByteBuffer.h +++ b/src/ByteBuffer.h @@ -29,22 +29,22 @@ class cByteBuffer public: cByteBuffer(size_t a_BufferSize); ~cByteBuffer(); - + /** Writes the bytes specified to the ringbuffer. Returns true if successful, false if not */ bool Write(const void * a_Bytes, size_t a_Count); - + /** Returns the number of bytes that can be successfully written to the ringbuffer */ size_t GetFreeSpace(void) const; - + /** Returns the number of bytes that are currently in the ringbuffer. Note GetReadableBytes() */ size_t GetUsedSpace(void) const; - + /** Returns the number of bytes that are currently available for reading (may be less than UsedSpace due to some data having been read already) */ size_t GetReadableSpace(void) const; - + /** Returns the current data start index. For debugging purposes. */ size_t GetDataStart(void) const { return m_DataStart; } - + /** Returns true if the specified amount of bytes are available for reading */ bool CanReadBytes(size_t a_Count) const; @@ -98,41 +98,41 @@ public: bool WriteVarUTF8String (const AString & a_Value); // string length as VarInt, then string as UTF-8 bool WriteLEInt32 (Int32 a_Value); bool WritePosition64 (Int32 a_BlockX, Int32 a_BlockY, Int32 a_BlockZ); - + /** Reads a_Count bytes into a_Buffer; returns true if successful */ bool ReadBuf(void * a_Buffer, size_t a_Count); - + /** Writes a_Count bytes into a_Buffer; returns true if successful */ bool WriteBuf(const void * a_Buffer, size_t a_Count); - + /** Reads a_Count bytes into a_String; returns true if successful */ bool ReadString(AString & a_String, size_t a_Count); - + /** Skips reading by a_Count bytes; returns false if not enough bytes in the ringbuffer */ bool SkipRead(size_t a_Count); - + /** Reads all available data into a_Data */ void ReadAll(AString & a_Data); - + /** Reads the specified number of bytes and writes it into the destinatio bytebuffer. Returns true on success. */ bool ReadToByteBuffer(cByteBuffer & a_Dst, size_t a_NumBytes); - + /** Removes the bytes that have been read from the ringbuffer */ void CommitRead(void); - + /** Restarts next reading operation at the start of the ringbuffer */ void ResetRead(void); - + /** Re-reads the data that has been read since the last commit to the current readpos. Used by ProtoProxy to duplicate communication */ void ReadAgain(AString & a_Out); - + /** Checks if the internal state is valid (read and write positions in the correct bounds) using ASSERTs */ void CheckValid(void) const; protected: char * m_Buffer; size_t m_BufferSize; // Total size of the ringbuffer - + size_t m_DataStart; // Where the data starts in the ringbuffer size_t m_WritePos; // Where the data ends in the ringbuffer size_t m_ReadPos; // Where the next read will start in the ringbuffer @@ -142,7 +142,7 @@ protected: Used for checking that only one thread accesses the object at a time, via cSingleThreadAccessChecker. */ mutable std::thread::id m_ThreadID; #endif - + /** Advances the m_ReadPos by a_Count bytes */ void AdvanceReadPos(size_t a_Count); } ; diff --git a/src/ChatColor.h b/src/ChatColor.h index 21377e27f..0f39db844 100644 --- a/src/ChatColor.h +++ b/src/ChatColor.h @@ -10,7 +10,7 @@ class cChatColor { public: static const char * Delimiter; - + /** @deprecated use ChatColor::Delimiter instead */ static const char * Color; diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index ca11602a6..88cb9fdd8 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -89,7 +89,7 @@ cChunkData::~cChunkData() { return *this; } - + // Free any currently held contents: if (m_IsOwner) { @@ -110,7 +110,7 @@ cChunkData::~cChunkData() ASSERT(&m_Pool == &a_Other.m_Pool); return *this; } - + #else // unique_ptr style interface for memory management @@ -123,10 +123,10 @@ cChunkData::~cChunkData() other.m_Sections[i] = nullptr; } } - - - - + + + + cChunkData & cChunkData::operator =(cChunkData && other) { @@ -341,7 +341,7 @@ cChunkData cChunkData::Copy(void) const void cChunkData::CopyBlockTypes(BLOCKTYPE * a_Dest, size_t a_Idx, size_t a_Length) const { size_t ToSkip = a_Idx; - + for (size_t i = 0; i < NumSections; i++) { size_t StartPos = 0; @@ -431,7 +431,7 @@ void cChunkData::CopySkyLight(NIBBLETYPE * a_Dest) const void cChunkData::SetBlockTypes(const BLOCKTYPE * a_Src) { ASSERT(a_Src != nullptr); - + for (size_t i = 0; i < NumSections; i++) { // If the section is already allocated, copy the data into it: @@ -447,7 +447,7 @@ void cChunkData::SetBlockTypes(const BLOCKTYPE * a_Src) // No need for the section, the data is all-air continue; } - + // Allocate the section and copy the data into it: m_Sections[i] = Allocate(); memcpy(m_Sections[i]->m_BlockTypes, &a_Src[i * SectionBlockCount], sizeof(m_Sections[i]->m_BlockTypes)); @@ -463,7 +463,7 @@ void cChunkData::SetBlockTypes(const BLOCKTYPE * a_Src) void cChunkData::SetMetas(const NIBBLETYPE * a_Src) { ASSERT(a_Src != nullptr); - + for (size_t i = 0; i < NumSections; i++) { // If the section is already allocated, copy the data into it: @@ -472,14 +472,14 @@ void cChunkData::SetMetas(const NIBBLETYPE * a_Src) memcpy(m_Sections[i]->m_BlockMetas, &a_Src[i * SectionBlockCount / 2], sizeof(m_Sections[i]->m_BlockMetas)); continue; } - + // The section doesn't exist, find out if it is needed: if (IsAllValue(a_Src + i * SectionBlockCount / 2, SectionBlockCount / 2, static_cast(0))) { // No need for the section, the data is all zeroes continue; } - + // Allocate the section and copy the data into it: m_Sections[i] = Allocate(); memcpy(m_Sections[i]->m_BlockMetas, &a_Src[i * SectionBlockCount / 2], sizeof(m_Sections[i]->m_BlockMetas)); @@ -499,7 +499,7 @@ void cChunkData::SetBlockLight(const NIBBLETYPE * a_Src) { return; } - + for (size_t i = 0; i < NumSections; i++) { // If the section is already allocated, copy the data into it: @@ -508,14 +508,14 @@ void cChunkData::SetBlockLight(const NIBBLETYPE * a_Src) memcpy(m_Sections[i]->m_BlockLight, &a_Src[i * SectionBlockCount / 2], sizeof(m_Sections[i]->m_BlockLight)); continue; } - + // The section doesn't exist, find out if it is needed: if (IsAllValue(a_Src + i * SectionBlockCount / 2, SectionBlockCount / 2, static_cast(0))) { // No need for the section, the data is all zeroes continue; } - + // Allocate the section and copy the data into it: m_Sections[i] = Allocate(); memcpy(m_Sections[i]->m_BlockLight, &a_Src[i * SectionBlockCount / 2], sizeof(m_Sections[i]->m_BlockLight)); @@ -534,7 +534,7 @@ void cChunkData::SetSkyLight(const NIBBLETYPE * a_Src) { return; } - + for (size_t i = 0; i < NumSections; i++) { // If the section is already allocated, copy the data into it: @@ -550,7 +550,7 @@ void cChunkData::SetSkyLight(const NIBBLETYPE * a_Src) // No need for the section, the data is all zeroes continue; } - + // Allocate the section and copy the data into it: m_Sections[i] = Allocate(); memcpy(m_Sections[i]->m_BlockSkyLight, &a_Src[i * SectionBlockCount / 2], sizeof(m_Sections[i]->m_BlockSkyLight)); diff --git a/src/ChunkData.h b/src/ChunkData.h index 60eeca816..792e610b1 100644 --- a/src/ChunkData.h +++ b/src/ChunkData.h @@ -39,7 +39,7 @@ public: cChunkData(cAllocationPool & a_Pool); ~cChunkData(); - + #if __cplusplus < 201103L // auto_ptr style interface for memory management cChunkData(const cChunkData & a_Other); @@ -55,11 +55,11 @@ public: NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) const; bool SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Nibble); - + NIBBLETYPE GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) const; - + NIBBLETYPE GetSkyLight(int a_RelX, int a_RelY, int a_RelZ) const; - + /** Creates a (deep) copy of self. */ cChunkData Copy(void) const; @@ -75,7 +75,7 @@ public: /** Copies the skylight data into the specified flat array. */ void CopySkyLight (NIBBLETYPE * a_Dest) const; - + /** Copies the blocktype data from the specified flat array into the internal representation. Allocates sections that are needed for the operation. Requires that a_Src is a valid pointer. */ @@ -103,7 +103,7 @@ public: NIBBLETYPE m_BlockLight [SectionHeight * 16 * 16 / 2]; NIBBLETYPE m_BlockSkyLight[SectionHeight * 16 * 16 / 2]; }; - + private: #if __cplusplus < 201103L // auto_ptr style interface for memory management @@ -113,14 +113,14 @@ private: sChunkSection * m_Sections[NumSections]; cAllocationPool & m_Pool; - + /** Allocates a new section. Entry-point to custom allocators. */ sChunkSection * Allocate(void); /** Frees the specified section, previously allocated using Allocate(). Note that a_Section may be nullptr. */ void Free(sChunkSection * a_Section); - + /** Sets the data in the specified section to their default values. */ void ZeroSection(sChunkSection * a_Section) const; diff --git a/src/ChunkDataCallback.h b/src/ChunkDataCallback.h index 1a36fd56e..4841dad03 100644 --- a/src/ChunkDataCallback.h +++ b/src/ChunkDataCallback.h @@ -28,22 +28,22 @@ public: (only in processes where multiple chunks can be processed, such as cWorld::ForEachChunkInRect()). If false is returned, the chunk is skipped. */ virtual bool Coords(int a_ChunkX, int a_ChunkZ) { UNUSED(a_ChunkX); UNUSED(a_ChunkZ); return true; } - + /** Called once to provide heightmap data */ virtual void HeightMap(const cChunkDef::HeightMap * a_HeightMap) { UNUSED(a_HeightMap); } - + /** Called once to provide biome data */ virtual void BiomeData(const cChunkDef::BiomeMap * a_BiomeMap) { UNUSED(a_BiomeMap); } - + /** Called once to let know if the chunk lighting is valid. Return value is ignored */ virtual void LightIsValid(bool a_IsLightValid) { UNUSED(a_IsLightValid); } - + /** Called once to export block info */ virtual void ChunkData(const cChunkData & a_Buffer) { UNUSED(a_Buffer); } - + /** Called for each entity in the chunk */ virtual void Entity(cEntity * a_Entity) { UNUSED(a_Entity); } - + /** Called for each blockentity in the chunk */ virtual void BlockEntity(cBlockEntity * a_Entity) { UNUSED(a_Entity); } } ; diff --git a/src/ChunkDef.h b/src/ChunkDef.h index ae4e9393b..b3cf9049f 100644 --- a/src/ChunkDef.h +++ b/src/ChunkDef.h @@ -120,7 +120,7 @@ public: { return ((a_Height >= 0) && (a_Height < Height)); } - + /** Validates a width-coordinate. Returns false if width-coordiante is out of width bounds */ inline static bool IsValidWidth(int a_Width) { diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 705f0bed5..935f03c10 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -85,7 +85,7 @@ cChunkMap::cChunkLayer * cChunkMap::GetLayer(int a_LayerX, int a_LayerZ) return *itr; } } - + // Not found, create new: cChunkLayer * Layer = new cChunkLayer(a_LayerX, a_LayerZ, this, *m_Pool); if (Layer == nullptr) @@ -123,7 +123,7 @@ cChunkMap::cChunkLayer * cChunkMap::FindLayer(int a_LayerX, int a_LayerZ) return *itr; } } // for itr - m_Layers[] - + // Not found return nullptr; } @@ -153,7 +153,7 @@ cChunkPtr cChunkMap::GetChunk(int a_ChunkX, int a_ChunkZ) // An error must have occurred, since layers are automatically created if they don't exist return nullptr; } - + cChunkPtr Chunk = Layer->GetChunk(a_ChunkX, a_ChunkZ); if (Chunk == nullptr) { @@ -182,7 +182,7 @@ cChunkPtr cChunkMap::GetChunkNoGen(int a_ChunkX, int a_ChunkZ) // An error must have occurred, since layers are automatically created if they don't exist return nullptr; } - + cChunkPtr Chunk = Layer->GetChunk(a_ChunkX, a_ChunkZ); if (Chunk == nullptr) { @@ -193,7 +193,7 @@ cChunkPtr cChunkMap::GetChunkNoGen(int a_ChunkX, int a_ChunkZ) Chunk->SetPresence(cChunk::cpQueued); m_World->GetStorage().QueueLoadChunk(a_ChunkX, a_ChunkZ); } - + return Chunk; } @@ -211,7 +211,7 @@ cChunkPtr cChunkMap::GetChunkNoLoad( int a_ChunkX, int a_ChunkZ) // An error must have occurred, since layers are automatically created if they don't exist return nullptr; } - + return Layer->GetChunk(a_ChunkX, a_ChunkZ); } @@ -231,7 +231,7 @@ bool cChunkMap::LockedGetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTY { return false; } - + a_BlockType = Chunk->GetBlock(a_BlockX, a_BlockY, a_BlockZ); a_BlockMeta = Chunk->GetMeta(a_BlockX, a_BlockY, a_BlockZ); return true; @@ -253,7 +253,7 @@ bool cChunkMap::LockedGetBlockType(int a_BlockX, int a_BlockY, int a_BlockZ, BLO { return false; } - + a_BlockType = Chunk->GetBlock(a_BlockX, a_BlockY, a_BlockZ); return true; } @@ -266,7 +266,7 @@ bool cChunkMap::LockedGetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIB { // We already have m_CSLayers locked since this can be called only from within the tick thread ASSERT(m_CSLayers.IsLockedByCurrentThread()); - + int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); @@ -274,7 +274,7 @@ bool cChunkMap::LockedGetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIB { return false; } - + a_BlockMeta = Chunk->GetMeta(a_BlockX, a_BlockY, a_BlockZ); return true; } @@ -293,7 +293,7 @@ bool cChunkMap::LockedSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTY { return false; } - + Chunk->SetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); return true; } @@ -312,7 +312,7 @@ bool cChunkMap::LockedFastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLO { return false; } - + Chunk->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); return true; } @@ -324,7 +324,7 @@ bool cChunkMap::LockedFastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLO cChunk * cChunkMap::FindChunk(int a_ChunkX, int a_ChunkZ) { ASSERT(m_CSLayers.IsLockedByCurrentThread()); - + cChunkLayer * Layer = FindLayerForChunk(a_ChunkX, a_ChunkZ); if (Layer == nullptr) { @@ -623,7 +623,7 @@ void cChunkMap::BroadcastParticleEffect(const AString & a_ParticleName, float a_ void cChunkMap::BroadcastRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude) { cCSLock Lock(m_CSLayers); - + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkZ()); if (Chunk == nullptr) { @@ -785,7 +785,7 @@ bool cChunkMap::DoWithChunkAt(Vector3i a_BlockPos, std::function m_Callback(a_InnerCallback) { } - + virtual bool Item(cChunk * a_Chunk) { return m_Callback(*a_Chunk); @@ -822,7 +822,7 @@ void cChunkMap::WakeUpSimulatorsInArea(int a_MinBlockX, int a_MaxBlockX, int a_M // Limit the Y coords: a_MinBlockY = std::max(a_MinBlockY, 0); a_MaxBlockY = std::min(a_MaxBlockY, cChunkDef::Height - 1); - + cSimulatorManager * SimMgr = m_World->GetSimulatorManager(); int MinChunkX, MinChunkZ, MaxChunkX, MaxChunkZ; cChunkDef::BlockToChunk(a_MinBlockX, a_MinBlockZ, MinChunkX, MinChunkZ); @@ -935,12 +935,12 @@ void cChunkMap::SetChunkData(cSetChunkData & a_SetChunkData) return; } Chunk->SetAllData(a_SetChunkData); - + if (a_SetChunkData.ShouldMarkDirty()) { Chunk->MarkDirty(); } - + // Notify relevant ChunkStays: cChunkStays ToBeDisabled; for (cChunkStays::iterator itr = m_ChunkStays.begin(), end = m_ChunkStays.end(); itr != end; ++itr) @@ -951,7 +951,7 @@ void cChunkMap::SetChunkData(cSetChunkData & a_SetChunkData) ToBeDisabled.push_back(*itr); } } // for itr - m_ChunkStays[] - + // Disable (and possibly remove) the chunkstays that chose to get disabled: for (cChunkStays::iterator itr = ToBeDisabled.begin(), end = ToBeDisabled.end(); itr != end; ++itr) { @@ -1064,7 +1064,7 @@ int cChunkMap::GetHeight(int a_BlockX, int a_BlockZ) { return 0; } - + if (Chunk->IsValid()) { return Chunk->GetHeight(a_BlockX, a_BlockZ); @@ -1136,10 +1136,10 @@ void cChunkMap::CollectPickupsByPlayer(cPlayer & a_Player) cChunkDef::AbsoluteToRelative(BlockX, BlockY, BlockZ, ChunkX, ChunkZ); int OtherChunkX = ChunkX + ((BlockX > 8) ? 1 : -1); int OtherChunkZ = ChunkZ + ((BlockZ > 8) ? 1 : -1); - + // We suppose that each player keeps their chunks in memory, therefore it makes little sense to try to re-load or even generate them. // The only time the chunks are not valid is when the player is downloading the initial world and they should not call this at that moment - + cCSLock Lock(m_CSLayers); GetChunkNoLoad(ChunkX, ChunkZ)->CollectPickupsByPlayer(a_Player); @@ -1411,7 +1411,7 @@ bool cChunkMap::SetAreaBiome(int a_MinX, int a_MaxX, int a_MinZ, int a_MaxZ, EMC int MaxChunkX, MaxChunkZ, MaxX = a_MaxX, MaxZ = a_MaxZ; cChunkDef::AbsoluteToRelative(MinX, Y, MinZ, MinChunkX, MinChunkZ); cChunkDef::AbsoluteToRelative(MaxX, Y, MaxZ, MaxChunkX, MaxChunkZ); - + // Go through all chunks, set: bool res = true; cCSLock Lock(m_CSLayers); @@ -1480,7 +1480,7 @@ bool cChunkMap::DigBlock(int a_BlockX, int a_BlockY, int a_BlockZ) { return false; } - + DestChunk->SetBlock(PosX, PosY, PosZ, E_BLOCK_AIR, 0); m_World->GetSimulatorManager()->WakeUp(a_BlockX, a_BlockY, a_BlockZ, DestChunk); } @@ -1496,7 +1496,7 @@ void cChunkMap::SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player) { int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_X, a_Y, a_Z, ChunkX, ChunkZ); - + cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunk(ChunkX, ChunkZ); if ((Chunk != nullptr) && (Chunk->IsValid())) @@ -1522,7 +1522,7 @@ void cChunkMap::CompareChunkClients(int a_ChunkX1, int a_ChunkZ1, int a_ChunkX2, { return; } - + CompareChunkClients(Chunk1, Chunk2, a_Callback); } @@ -1534,7 +1534,7 @@ void cChunkMap::CompareChunkClients(cChunk * a_Chunk1, cChunk * a_Chunk2, cClien { cClientHandleList Clients1(a_Chunk1->GetAllClients()); cClientHandleList Clients2(a_Chunk2->GetAllClients()); - + // Find "removed" clients: for (cClientHandleList::iterator itr1 = Clients1.begin(); itr1 != Clients1.end(); ++itr1) { @@ -1552,7 +1552,7 @@ void cChunkMap::CompareChunkClients(cChunk * a_Chunk1, cChunk * a_Chunk2, cClien a_Callback.Removed(*itr1); } } // for itr1 - Clients1[] - + // Find "added" clients: for (cClientHandleList::iterator itr2 = Clients2.begin(); itr2 != Clients2.end(); ++itr2) { @@ -1609,7 +1609,7 @@ void cChunkMap::RemoveChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle * a_ void cChunkMap::RemoveClientFromChunks(cClientHandle * a_Client) { cCSLock Lock(m_CSLayers); - + for (cChunkLayerList::const_iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) { (*itr)->RemoveClient(a_Client); @@ -1738,7 +1738,7 @@ bool cChunkMap::ForEachEntityInBox(const cBoundingBox & a_Box, cEntityCallback & int MinChunkZ = FloorC(a_Box.GetMinZ() / cChunkDef::Width); int MaxChunkX = FloorC((a_Box.GetMaxX() + cChunkDef::Width) / cChunkDef::Width); int MaxChunkZ = FloorC((a_Box.GetMaxZ() + cChunkDef::Width) / cChunkDef::Width); - + // Iterate over each chunk in the range: cCSLock Lock(m_CSLayers); for (int z = MinChunkZ; z <= MaxChunkZ; z++) @@ -1797,7 +1797,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ { return; } - + for (int x = -ExplosionSizeInt; x < ExplosionSizeInt; x++) { for (int y = -ExplosionSizeInt; y < ExplosionSizeInt; y++) @@ -1827,7 +1827,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ a_BlocksAffected.push_back(Vector3i(bx + x, by + y, bz + z)); break; } - + case E_BLOCK_OBSIDIAN: case E_BLOCK_BEACON: case E_BLOCK_BEDROCK: @@ -1912,7 +1912,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ } Vector3d DistanceFromExplosion = a_Entity->GetPosition() - m_ExplosionPos; - + if (!a_Entity->IsTNT() && !a_Entity->IsFallingBlock()) // Don't apply damage to other TNT entities and falling blocks, they should be invincible { cBoundingBox bbEntity(a_Entity->GetPosition(), a_Entity->GetWidth() / 2, a_Entity->GetHeight()); @@ -1930,7 +1930,7 @@ void cChunkMap::DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_ DistanceFromExplosion.Normalize(); DistanceFromExplosion *= m_ExplosionSize * m_ExplosionSize; a_Entity->AddSpeed(DistanceFromExplosion); - + return false; } @@ -2557,7 +2557,7 @@ bool cChunkMap::WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBl int MaxBlockZ = a_MinBlockZ + a_Area.GetSizeZ(); cChunkDef::AbsoluteToRelative(MinBlockX, MinBlockY, MinBlockZ, MinChunkX, MinChunkZ); cChunkDef::AbsoluteToRelative(MaxBlockX, MaxBlockY, MaxBlockZ, MaxChunkX, MaxChunkZ); - + // Iterate over chunks, write data into each: bool Result = true; cCSLock Lock(m_CSLayers); @@ -2604,7 +2604,7 @@ void cChunkMap::GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCK { int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); - + cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); if (Chunk != nullptr) @@ -2621,7 +2621,7 @@ void cChunkMap::GrowSugarcane(int a_BlockX, int a_BlockY, int a_BlockZ, int a_Nu { int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); - + cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); if (Chunk != nullptr) @@ -2638,7 +2638,7 @@ void cChunkMap::GrowCactus(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBl { int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); - + cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); if (Chunk != nullptr) @@ -2655,7 +2655,7 @@ void cChunkMap::SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ) { int ChunkX, ChunkZ; cChunkDef::AbsoluteToRelative(a_BlockX, a_BlockY, a_BlockZ, ChunkX, ChunkZ); - + cCSLock Lock(m_CSLayers); cChunkPtr Chunk = GetChunkNoLoad(ChunkX, ChunkZ); if (Chunk != nullptr) @@ -2846,13 +2846,13 @@ cChunkPtr cChunkMap::cChunkLayer::GetChunk( int a_ChunkX, int a_ChunkZ) const int LocalX = a_ChunkX - m_LayerX * LAYER_SIZE; const int LocalZ = a_ChunkZ - m_LayerZ * LAYER_SIZE; - + if (!((LocalX < LAYER_SIZE) && (LocalZ < LAYER_SIZE) && (LocalX > -1) && (LocalZ > -1))) { ASSERT(!"Asking a cChunkLayer for a chunk that doesn't belong to it!"); return nullptr; } - + int Index = LocalX + LocalZ * LAYER_SIZE; if (m_Chunks[Index] == nullptr) { @@ -2873,13 +2873,13 @@ cChunk * cChunkMap::cChunkLayer::FindChunk(int a_ChunkX, int a_ChunkZ) { const int LocalX = a_ChunkX - m_LayerX * LAYER_SIZE; const int LocalZ = a_ChunkZ - m_LayerZ * LAYER_SIZE; - + if (!((LocalX < LAYER_SIZE) && (LocalZ < LAYER_SIZE) && (LocalX > -1) && (LocalZ > -1))) { ASSERT(!"Asking a cChunkLayer for a chunk that doesn't belong to it!"); return nullptr; } - + int Index = LocalX + LocalZ * LAYER_SIZE; return m_Chunks[Index]; } @@ -3112,11 +3112,11 @@ void cChunkMap::FastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE void cChunkMap::AddChunkStay(cChunkStay & a_ChunkStay) { cCSLock Lock(m_CSLayers); - + // Add it to the list: ASSERT(std::find(m_ChunkStays.begin(), m_ChunkStays.end(), &a_ChunkStay) == m_ChunkStays.end()); // Has not yet been added m_ChunkStays.push_back(&a_ChunkStay); - + // Schedule all chunks to be loaded / generated, and mark each as locked: const cChunkCoordsVector & WantedChunks = a_ChunkStay.GetChunks(); for (cChunkCoordsVector::const_iterator itr = WantedChunks.begin(); itr != WantedChunks.end(); ++itr) @@ -3147,7 +3147,7 @@ void cChunkMap::AddChunkStay(cChunkStay & a_ChunkStay) void cChunkMap::DelChunkStay(cChunkStay & a_ChunkStay) { cCSLock Lock(m_CSLayers); - + // Remove from the list of active chunkstays: bool HasFound = false; for (cChunkStays::iterator itr = m_ChunkStays.begin(), end = m_ChunkStays.end(); itr != end; ++itr) @@ -3159,13 +3159,13 @@ void cChunkMap::DelChunkStay(cChunkStay & a_ChunkStay) break; } } // for itr - m_ChunkStays[] - + if (!HasFound) { ASSERT(!"Removing a cChunkStay that hasn't been added!"); return; } - + // Unmark all contained chunks: const cChunkCoordsVector & Chunks = a_ChunkStay.GetChunks(); for (cChunkCoordsVector::const_iterator itr = Chunks.begin(), end = Chunks.end(); itr != end; ++itr) diff --git a/src/ChunkMap.h b/src/ChunkMap.h index 6b7df7610..ef9fe196b 100644 --- a/src/ChunkMap.h +++ b/src/ChunkMap.h @@ -96,14 +96,14 @@ public: void BroadcastSpawnEntity(cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr); void BroadcastThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ, const cClientHandle * a_Exclude = nullptr); void BroadcastUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ); - + /** Sends the block entity, if it is at the coords specified, to a_Client */ void SendBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cClientHandle & a_Client); - + /** a_Player rclked block entity at the coords specified, handle it returns true if the use was successful, return false to use the block as a "normal" block */ bool UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z); - + /** Calls the callback for the chunk specified, with ChunkMapCS locked; returns false if the chunk doesn't exist, otherwise returns the same value as the callback */ bool DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callback); @@ -120,25 +120,25 @@ public: void MarkChunkDirty (int a_ChunkX, int a_ChunkZ, bool a_MarkRedstoneDirty = false); void MarkChunkSaving (int a_ChunkX, int a_ChunkZ); void MarkChunkSaved (int a_ChunkX, int a_ChunkZ); - + /** Sets the chunk data as either loaded from the storage or generated. BlockLight and BlockSkyLight are optional, if not present, chunk will be marked as unlighted. If MarkDirty is set, the chunk is set as dirty (used after generating) Modifies the BlockEntity list in a_SetChunkData - moves the block entities into the chunk. */ void SetChunkData(cSetChunkData & a_SetChunkData); - + void ChunkLighted( int a_ChunkX, int a_ChunkZ, const cChunkDef::BlockNibbles & a_BlockLight, const cChunkDef::BlockNibbles & a_SkyLight ); - + bool GetChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataCallback & a_Callback); - + /** Copies the chunk's blocktypes into a_Blocks; returns true if successful */ bool GetChunkBlockTypes (int a_ChunkX, int a_ChunkZ, BLOCKTYPE * a_Blocks); - + /** Returns true iff the chunk is in the loader / generator queue. */ bool IsChunkQueued(int a_ChunkX, int a_ChunkZ); @@ -154,7 +154,7 @@ public: void SetBlocks(const sSetBlockVector & a_Blocks); void CollectPickupsByPlayer(cPlayer & a_Player); - + BLOCKTYPE GetBlock (int a_BlockX, int a_BlockY, int a_BlockZ); NIBBLETYPE GetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ); NIBBLETYPE GetBlockSkyLight (int a_BlockX, int a_BlockY, int a_BlockZ); @@ -166,21 +166,21 @@ public: /** Replaces world blocks with a_Blocks, if they are of type a_FilterBlockType */ void ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_FilterBlockType); - + /** Special function used for growing trees, replaces only blocks that tree may overwrite */ void ReplaceTreeBlocks(const sSetBlockVector & a_Blocks); - + /** Returns the biome at the specified coords. Reads the biome from the chunk, if loaded, otherwise uses the world generator to provide the biome value */ EMCSBiome GetBiomeAt (int a_BlockX, int a_BlockZ); - + /** Sets the biome at the specified coords. Returns true if successful, false if not (chunk not loaded). Doesn't resend the chunk to clients. */ bool SetBiomeAt(int a_BlockX, int a_BlockZ, EMCSBiome a_Biome); - + /** Sets the biome at the area. Returns true if successful, false if any subarea failed (chunk not loaded). (Re)sends the chunks to their relevant clients if successful. */ bool SetAreaBiome(int a_MinX, int a_MaxX, int a_MinZ, int a_MaxZ, EMCSBiome a_Biome); - + /** Retrieves block types and metas of the specified blocks. If a chunk is not loaded, doesn't modify the block and consults a_ContinueOnFailure whether to process the rest of the array. Returns true if all blocks were read, false if any one failed. */ @@ -195,10 +195,10 @@ public: Uses a blockchange packet to send the block. If the relevant chunk isn't loaded, doesn't do anything. */ void SendBlockTo(int a_BlockX, int a_BlockY, int a_BlockZ, cPlayer * a_Player); - + /** Compares clients of two chunks, calls the callback accordingly */ void CompareChunkClients(int a_ChunkX1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkZ2, cClientDiffCallback & a_Callback); - + /** Compares clients of two chunks, calls the callback accordingly */ void CompareChunkClients(cChunk * a_Chunk1, cChunk * a_Chunk2, cClientDiffCallback & a_Callback); @@ -207,23 +207,23 @@ public: /** Removes the client from the chunk */ void RemoveChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client); - + /** Removes the client from all chunks it is present in */ void RemoveClientFromChunks(cClientHandle * a_Client); /** Adds the entity to its appropriate chunk, takes ownership of the entity pointer */ void AddEntity(cEntity * a_Entity); - + /** Adds the entity to its appropriate chunk, if the entity is not already added. Takes ownership of the entity pointer */ void AddEntityIfNotPresent(cEntity * a_Entity); - + /** Returns true if the entity with specified ID is present in the chunks */ bool HasEntity(UInt32 a_EntityID); - + /** Removes the entity from its appropriate chunk */ void RemoveEntity(cEntity * a_Entity); - + /** Calls the callback for each entity in the entire world; returns true if all entities processed, false if the callback aborted by returning true */ bool ForEachEntity(cEntityCallback & a_Callback); // Lua-accessible @@ -237,7 +237,7 @@ public: /** Destroys and returns a list of blocks destroyed in the explosion at the specified coordinates */ void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, cVector3iArray & a_BlockAffected); - + /** Calls the callback if the entity with the specified ID is found, with the entity object as the callback param. Returns true if entity found and callback returned false. */ bool DoWithEntityByID(UInt32 a_EntityID, cEntityCallback & a_Callback); // Lua-accessible @@ -269,7 +269,7 @@ public: /** Calls the callback for each furnace in the specified chunk. Returns true if all furnaces processed, false if the callback aborted by returning true. */ bool ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback & a_Callback); // Lua-accessible - + /** Calls the callback for the block entity at the specified coords. Returns false if there's no block entity at those coords, true if found. */ bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback); // Lua-acessible @@ -337,39 +337,39 @@ public: Returns true if successful, false if not (possibly an out-of-memory error). If the return value is true, the callback was / will be called. */ bool GenerateChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_CallAfter = nullptr); // Lua-accessible - + /** Marks the chunk as failed-to-load */ void ChunkLoadFailed(int a_ChunkX, int a_ChunkZ); - + /** Sets the sign text. Returns true if sign text changed. */ bool SetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4); - + /** Marks the chunk as being regenerated - all its clients want that chunk again (used by cWorld::RegenerateChunk()) */ void MarkChunkRegenerating(int a_ChunkX, int a_ChunkZ); - + bool IsChunkLighted(int a_ChunkX, int a_ChunkZ); - + /** Calls the callback for each chunk in the coords specified (all cords are inclusive). Returns true if all chunks have been processed successfully */ bool ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback); /** Calls the callback for each loaded chunk. Returns true if all chunks have been processed successfully */ bool ForEachLoadedChunk(std::function a_Callback); - + /** Writes the block area into the specified coords. Returns true if all chunks have been processed. Prefer cBlockArea::Write() instead. */ bool WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes); /** Returns the number of valid chunks and the number of dirty chunks */ void GetChunkStats(int & a_NumChunksValid, int & a_NumChunksDirty); - + /** Grows a melon or a pumpkin next to the block specified (assumed to be the stem) */ void GrowMelonPumpkin(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, MTRand & a_Rand); - + /** Grows a sugarcane present at the block specified by the amount of blocks specified, up to the max height specified in the config */ void GrowSugarcane(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow); - + /** Grows a cactus present at the block specified by the amount of blocks specified, up to the max height specified in the config */ void GrowCactus(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow); - + /** Sets the blockticking to start at the specified block. Only one blocktick per chunk may be set, second call overwrites the first call */ void SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ); @@ -380,7 +380,7 @@ public: void SpawnMobs(cMobSpawner & a_MobSpawner); void Tick(std::chrono::milliseconds a_Dt); - + /** Ticks a single block. Used by cWorld::TickQueuedBlocks() to tick the queued blocks */ void TickBlock(int a_BlockX, int a_BlockY, int a_BlockZ); @@ -390,15 +390,15 @@ public: cWorld * GetWorld(void) { return m_World; } int GetNumChunks(void); - + void ChunkValidated(void); // Called by chunks that have become valid - + /** Queues the specified block for ticking (block update) */ void QueueTickBlock(int a_BlockX, int a_BlockY, int a_BlockZ); - + /** Returns the CS for locking the chunkmap; only cWorld::cLock may use this function! */ cCriticalSection & GetCS(void) { return m_CSLayers; } - + /** Increments (a_AlwaysTicked == true) or decrements (false) the m_AlwaysTicked counter for the specified chunk. If the m_AlwaysTicked counter is greater than zero, the chunk is ticked in the tick-thread regardless of whether it has any clients or not. @@ -410,10 +410,10 @@ private: // The chunks can manipulate neighbors while in their Tick() method, using LockedGetBlock() and LockedSetBlock() friend class cChunk; - + // The chunkstay can (de-)register itself using AddChunkStay() and DelChunkStay() friend class cChunkStay; - + class cChunkLayer { @@ -427,30 +427,30 @@ private: /** Always returns an assigned chunkptr, but the chunk needn't be valid (loaded / generated) - callers must check */ cChunkPtr GetChunk( int a_ChunkX, int a_ChunkZ); - + /** Returns the specified chunk, or nullptr if not created yet */ cChunk * FindChunk(int a_ChunkX, int a_ChunkZ); - + int GetX(void) const {return m_LayerX; } int GetZ(void) const {return m_LayerZ; } - + int GetNumChunksLoaded(void) const ; - + void GetChunkStats(int & a_NumChunksValid, int & a_NumChunksDirty) const; - + void Save(void); void UnloadUnusedChunks(void); - + /** Collect a mob census, of all mobs, their megatype, their chunk and their distance o closest player */ void CollectMobCensus(cMobCensus & a_ToFill); - + /** Try to Spawn Monsters inside all Chunks */ void SpawnMobs(cMobSpawner & a_MobSpawner); void Tick(std::chrono::milliseconds a_Dt); - + void RemoveClient(cClientHandle * a_Client); - + /** Calls the callback for each entity in the entire world; returns true if all entities processed, false if the callback aborted by returning true */ bool ForEachEntity(cEntityCallback & a_Callback); // Lua-accessible @@ -459,18 +459,18 @@ private: /** Returns true if there is an entity with the specified ID within this layer's chunks */ bool HasEntity(UInt32 a_EntityID); - + protected: - + cChunkPtr m_Chunks[LAYER_SIZE * LAYER_SIZE]; int m_LayerX; int m_LayerZ; cChunkMap * m_Parent; int m_NumChunksLoaded; - + cAllocationPool & m_Pool; }; - + class cStarvationCallbacks : public cAllocationPool::cStarvationCallbacks { @@ -487,23 +487,23 @@ private: LOG("Out of Memory"); } }; - + typedef std::list cChunkLayerList; - + typedef std::list cChunkStays; /** Finds the cChunkLayer object responsible for the specified chunk; returns nullptr if not found. Assumes m_CSLayers is locked. */ cChunkLayer * FindLayerForChunk(int a_ChunkX, int a_ChunkZ); - + /** Returns the specified cChunkLayer object; returns nullptr if not found. Assumes m_CSLayers is locked. */ cChunkLayer * FindLayer(int a_LayerX, int a_LayerZ); - + /** Returns the cChunkLayer object responsible for the specified chunk; creates it if not found. */ cChunkLayer * GetLayerForChunk (int a_ChunkX, int a_ChunkZ); - + /** Returns the specified cChunkLayer object; creates it if not found. */ cChunkLayer * GetLayer(int a_LayerX, int a_LayerZ); - + void RemoveLayer(cChunkLayer * a_Layer); cCriticalSection m_CSLayers; @@ -511,7 +511,7 @@ private: cEvent m_evtChunkValid; // Set whenever any chunk becomes valid, via ChunkValidated() cWorld * m_World; - + /** The cChunkStay descendants that are currently enabled in this chunkmap */ cChunkStays m_ChunkStays; @@ -520,33 +520,33 @@ private: cChunkPtr GetChunk (int a_ChunkX, int a_ChunkZ); // Also queues the chunk for loading / generating if not valid cChunkPtr GetChunkNoGen (int a_ChunkX, int a_ChunkZ); // Also queues the chunk for loading if not valid; doesn't generate cChunkPtr GetChunkNoLoad(int a_ChunkX, int a_ChunkZ); // Doesn't load, doesn't generate - + /** Gets a block in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) */ bool LockedGetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); - + /** Gets a block type in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) */ bool LockedGetBlockType(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType); - + /** Gets a block meta in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) */ bool LockedGetBlockMeta(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE & a_BlockMeta); - + /** Sets a block in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) */ bool LockedSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); /** Fast-sets a block in any chunk while in the cChunk's Tick() method; returns true if successful, false if chunk not loaded (doesn't queue load) */ bool LockedFastSetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); - + /** Locates a chunk ptr in the chunkmap; doesn't create it when not found; assumes m_CSLayers is locked. To be called only from cChunkMap. */ cChunk * FindChunk(int a_ChunkX, int a_ChunkZ); /** Adds a new cChunkStay descendant to the internal list of ChunkStays; loads its chunks. To be used only by cChunkStay; others should use cChunkStay::Enable() instead */ void AddChunkStay(cChunkStay & a_ChunkStay); - + /** Removes the specified cChunkStay descendant from the internal list of ChunkStays. To be used only by cChunkStay; others should use cChunkStay::Disable() instead */ void DelChunkStay(cChunkStay & a_ChunkStay); - + }; diff --git a/src/ChunkSender.h b/src/ChunkSender.h index 7a6a56680..a7b1e104b 100644 --- a/src/ChunkSender.h +++ b/src/ChunkSender.h @@ -65,22 +65,22 @@ public: E_CHUNK_PRIORITY_MIDHIGH, E_CHUNK_PRIORITY_MEDIUM, E_CHUNK_PRIORITY_LOW, - + }; - + bool Start(); - + void Stop(void); - + /** Queues a chunk to be sent to a specific client */ void QueueSendChunkTo(int a_ChunkX, int a_ChunkZ, eChunkPriority a_Priority, cClientHandle * a_Client); void QueueSendChunkTo(int a_ChunkX, int a_ChunkZ, eChunkPriority a_Priority, std::list a_Client); - + /** Removes the a_Client from all waiting chunk send operations */ void RemoveClient(cClientHandle * a_Client); - + protected: - + struct sChunkQueue { eChunkPriority m_Priority; @@ -110,9 +110,9 @@ protected: { } }; - + cWorld & m_World; - + cCriticalSection m_CS; std::priority_queue m_SendChunks; std::unordered_map m_ChunkInfo; @@ -124,10 +124,10 @@ protected: unsigned char m_BiomeMap[cChunkDef::Width * cChunkDef::Width]; std::vector m_BlockEntities; // Coords of the block entities to send // TODO: sEntityIDs m_Entities; // Entity-IDs of the entities to send - + // cIsThread override: virtual void Execute(void) override; - + // cChunkDataCollector overrides: // (Note that they are called while the ChunkMap's CS is locked - don't do heavy calculations here!) virtual void BiomeData (const cChunkDef::BiomeMap * a_BiomeMap) override; diff --git a/src/ChunkStay.cpp b/src/ChunkStay.cpp index 0772787de..657682bf8 100644 --- a/src/ChunkStay.cpp +++ b/src/ChunkStay.cpp @@ -80,7 +80,7 @@ void cChunkStay::Remove(int a_ChunkX, int a_ChunkZ) void cChunkStay::Enable(cChunkMap & a_ChunkMap) { ASSERT(m_ChunkMap == nullptr); - + m_OutstandingChunks = m_Chunks; m_ChunkMap = &a_ChunkMap; a_ChunkMap.AddChunkStay(*this); @@ -93,7 +93,7 @@ void cChunkStay::Enable(cChunkMap & a_ChunkMap) void cChunkStay::Disable(void) { ASSERT(m_ChunkMap != nullptr); - + cChunkMap * ChunkMap = m_ChunkMap; m_ChunkMap = nullptr; ChunkMap->DelChunkStay(*this); @@ -120,7 +120,7 @@ bool cChunkStay::ChunkAvailable(int a_ChunkX, int a_ChunkZ) { return false; } - + // Call the appropriate callbacks: OnChunkAvailable(a_ChunkX, a_ChunkZ); if (m_OutstandingChunks.empty()) diff --git a/src/ChunkStay.h b/src/ChunkStay.h index 6572a3a98..a7c038a9c 100644 --- a/src/ChunkStay.h +++ b/src/ChunkStay.h @@ -36,42 +36,42 @@ class cChunkStay { public: cChunkStay(void); - + /** Deletes the object. Note that this calls Clear(), which means that the ChunkStay needs to be disabled. */ virtual ~cChunkStay(); - + /** Clears all the chunks that have been added. To be used only while the ChunkStay object is not enabled. */ void Clear(void); - + /** Adds a chunk to be locked from unloading. To be used only while the ChunkStay object is not enabled. */ void Add(int a_ChunkX, int a_ChunkZ); - + /** Releases the chunk so that it's no longer locked from unloading. To be used only while the ChunkStay object is not enabled. */ void Remove(int a_ChunkX, int a_ChunkZ); - + /** Enables the ChunkStay on the specified chunkmap, causing it to load and generate chunks. All the contained chunks are queued for loading / generating. */ void Enable (cChunkMap & a_ChunkMap); - + /** Disables the ChunkStay, the chunks are released and the ChunkStay object can be edited with Add() and Remove() again */ virtual void Disable(void); - + /** Returns all the chunks that should be kept */ const cChunkCoordsVector & GetChunks(void) const { return m_Chunks; } - + /** Called when a specific chunk become available. */ virtual void OnChunkAvailable(int a_ChunkX, int a_ChunkZ) = 0; - + /** Caled once all of the contained chunks are available. If returns true, the ChunkStay is automatically disabled by the ChunkMap; if it returns false, the ChunkStay is kept. */ virtual bool OnAllChunksAvailable(void) = 0; - + /** Called by the ChunkMap when the ChunkStay is disabled. The object may choose to delete itself. */ virtual void OnDisabled(void) = 0; - + protected: friend class cChunkMap; @@ -80,14 +80,14 @@ protected: /** The chunkmap where the object is enabled. Valid only after call to Enable() and before Disable(). */ cChunkMap * m_ChunkMap; - + /** The list of chunks to lock from unloading. */ cChunkCoordsVector m_Chunks; - + /** The chunks that still need loading */ cChunkCoordsVector m_OutstandingChunks; - - + + /** Called by cChunkMap when a chunk is available, checks m_NumLoaded and triggers the appropriate callbacks. May be called for chunks outside this ChunkStay. Returns true if the ChunkStay is to be automatically disabled by the ChunkMap; returns false to keep the ChunkStay. */ diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 22d052f22..899b0a5ab 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -62,56 +62,56 @@ public: // tolua_export #endif static const int MAX_VIEW_DISTANCE = 32; static const int MIN_VIEW_DISTANCE = 1; - + /** Creates a new client with the specified IP address in its description and the specified initial view distance. */ cClientHandle(const AString & a_IPString, int a_ViewDistance); virtual ~cClientHandle(); const AString & GetIPString(void) const { return m_IPString; } // tolua_export - + /** Sets the IP string that the client is using. Overrides the IP string that was read from the socket. Used mainly by BungeeCord compatibility code. */ void SetIPString(const AString & a_IPString) { m_IPString = a_IPString; } - + cPlayer * GetPlayer(void) { return m_Player; } // tolua_export /** Returns the player's UUID, as used by the protocol, in the short form (no dashes) */ const AString & GetUUID(void) const { return m_UUID; } // tolua_export - + /** Sets the player's UUID, as used by the protocol. Short UUID form (no dashes) is expected. Used mainly by BungeeCord compatibility code - when authenticating is done on the BungeeCord server and the results are passed to MCS running in offline mode. */ void SetUUID(const AString & a_UUID) { ASSERT(a_UUID.size() == 32); m_UUID = a_UUID; } const Json::Value & GetProperties(void) const { return m_Properties; } - + /** Sets the player's properties, such as skin image and signature. Used mainly by BungeeCord compatibility code - property querying is done on the BungeeCord server and the results are passed to MCS running in offline mode. */ void SetProperties(const Json::Value & a_Properties) { m_Properties = a_Properties; } - + /** Generates an UUID based on the username stored for this client, and stores it in the m_UUID member. This is used for the offline (non-auth) mode, when there's no UUID source. Each username generates a unique and constant UUID, so that when the player reconnects with the same name, their UUID is the same. Internally calls the GenerateOfflineUUID static function. */ void GenerateOfflineUUID(void); - + /** Generates an UUID based on the player name provided. This is used for the offline (non-auth) mode, when there's no UUID source. Each username generates a unique and constant UUID, so that when the player reconnects with the same name, their UUID is the same. Returns a 32-char UUID (no dashes). */ static AString GenerateOfflineUUID(const AString & a_Username); // tolua_export - + /** Returns true if the UUID is generated by online auth, false if it is an offline-generated UUID. We use Version-3 UUIDs for offline UUIDs, online UUIDs are Version-4, thus we can tell them apart. Accepts both 32-char and 36-char UUIDs (with and without dashes). If the string given is not a valid UUID, returns false. */ static bool IsUUIDOnline(const AString & a_UUID); // tolua_export - + /** Formats the type of message with the proper color and prefix for sending to the client. */ static AString FormatMessageType(bool ShouldAppendChatPrefixes, eMessageType a_ChatPrefix, const AString & a_AdditionalData); - + static AString FormatChatPrefix(bool ShouldAppendChatPrefixes, AString a_ChatPrefixS, AString m_Color1, AString m_Color2); void Kick(const AString & a_Reason); // tolua_export @@ -124,20 +124,20 @@ public: // tolua_export /** Remove all loaded chunks that are no longer in range */ void UnloadOutOfRangeChunks(void); - + // Removes the client from all chunks. Used when switching worlds or destroying the player void RemoveFromAllChunks(void); - + inline bool IsLoggedIn(void) const { return (m_State >= csAuthenticating); } /** Called while the client is being ticked from the world via its cPlayer object */ void Tick(float a_Dt); - + /** Called while the client is being ticked from the cServer object */ void ServerTick(float a_Dt); void Destroy(void); - + bool IsPlaying (void) const { return (m_State == csPlaying); } bool IsDestroyed (void) const { return (m_State == csDestroyed); } bool IsDestroying(void) const { return (m_State == csDestroying); } @@ -229,9 +229,9 @@ public: // tolua_export // tolua_begin const AString & GetUsername(void) const; void SetUsername( const AString & a_Username); - + inline short GetPing(void) const { return static_cast(std::chrono::duration_cast(m_Ping).count()); } - + /** Sets the maximal view distance. */ void SetViewDistance(int a_ViewDistance); @@ -245,24 +245,24 @@ public: // tolua_export AString GetLocale(void) const { return m_Locale; } int GetUniqueID(void) const { return m_UniqueID; } - + bool HasPluginChannel(const AString & a_PluginChannel); - + /** Called by the protocol when it receives the MC|Brand plugin message. Also callable by plugins. Simply stores the string value. */ void SetClientBrand(const AString & a_ClientBrand) { m_ClientBrand = a_ClientBrand; } - + /** Returns the client brand received in the MC|Brand plugin message or set by a plugin. */ const AString & GetClientBrand(void) const { return m_ClientBrand; } - + // tolua_end - + /** Returns true if the client wants the chunk specified to be sent (in m_ChunksToSend) */ bool WantsSendChunk(int a_ChunkX, int a_ChunkZ); - + /** Adds the chunk specified to the list of chunks wanted for sending (m_ChunksToSend) */ void AddWantedChunk(int a_ChunkX, int a_ChunkZ); - + // Calls that cProtocol descendants use to report state: void PacketBufferFull(void); void PacketUnknown(UInt32 a_PacketType); @@ -270,26 +270,26 @@ public: // tolua_export // Calls that cProtocol descendants use for handling packets: void HandleAnimation(int a_Animation); - + /** Called when the protocol receives a MC|ItemName plugin message, indicating that the player named an item in the anvil UI. */ void HandleAnvilItemName(const AString & a_ItemName); - + /** Called when the protocol receives a MC|Beacon plugin message, indicating that the player set an effect in the beacon UI. */ void HandleBeaconSelection(int a_PrimaryEffect, int a_SecondaryEffect); - + /** Called when the protocol detects a chat packet. */ void HandleChat(const AString & a_Message); - + /** Called when the protocol receives a MC|AdvCdm plugin message, indicating that the player set a new command in the command block UI, for a block-based commandblock. */ void HandleCommandBlockBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_NewCommand); - + /** Called when the protocol receives a MC|AdvCdm plugin message, indicating that the player set a new command in the command block UI, for an entity-based commandblock (minecart?). */ void HandleCommandBlockEntityChange(UInt32 a_EntityID, const AString & a_NewCommand); - + /** Called when the client clicks the creative inventory window. a_ClickAction specifies whether the click was inside the window or not (caLeftClick or caLeftClickOutside). */ void HandleCreativeInventory(Int16 a_SlotNum, const cItem & a_HeldItem, eClickAction a_ClickAction); @@ -300,24 +300,24 @@ public: // tolua_export void HandleEntityCrouch (UInt32 a_EntityID, bool a_IsCrouching); void HandleEntityLeaveBed (UInt32 a_EntityID); void HandleEntitySprinting (UInt32 a_EntityID, bool a_IsSprinting); - + /** Kicks the client if the same username is already logged in. Returns false if the client has been kicked, true otherwise. */ bool CheckMultiLogin(const AString & a_Username); - + /** Called when the protocol handshake has been received (for protocol versions that support it; otherwise the first instant when a username is received). Returns true if the player is to be let in, false if they were disconnected */ bool HandleHandshake (const AString & a_Username); - + void HandleKeepAlive (UInt32 a_KeepAliveID); void HandleLeftClick (int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, UInt8 a_Status); - + /** Called when the protocol receives a MC|TrSel packet, indicating that the player used a trade in the NPC UI. */ void HandleNPCTrade(int a_SlotNum); - + void HandlePing (void); void HandlePlayerAbilities (bool a_CanFly, bool a_IsFlying, float FlyingSpeed, float WalkingSpeed); void HandlePlayerLook (float a_Rotation, float a_Pitch, bool a_IsOnGround); @@ -350,19 +350,19 @@ public: // tolua_export Return true to allow the user in; false to kick them. */ bool HandleLogin(UInt32 a_ProtocolVersion, const AString & a_Username); - + void SendData(const char * a_Data, size_t a_Size); - + /** Called when the player moves into a different world. Sends an UnloadChunk packet for each loaded chunk and resets the streamed chunks. */ void RemoveFromWorld(void); - + /** Called by the protocol recognizer when the protocol version is known. */ void SetProtocolVersion(UInt32 a_ProtocolVersion) { m_ProtocolVersion = a_ProtocolVersion; } /** Returns the protocol version number of the protocol that the client is talking. Returns zero if the protocol version is not (yet) known. */ UInt32 GetProtocolVersion(void) const { return m_ProtocolVersion; } // tolua_export - + private: friend class cServer; // Needs access to SetSelf() @@ -407,7 +407,7 @@ private: Vector3d m_ConfirmPosition; cPlayer * m_Player; - + bool m_HasSentDC; ///< True if a Disconnect packet has been sent in either direction // Chunk position when the last StreamChunks() was called; used to avoid re-streaming while in the same chunk @@ -416,7 +416,7 @@ private: /** Number of ticks since the last network packet was received (increased in Tick(), reset in OnReceivedData()) */ std::atomic m_TicksSinceLastPacket; - + /** Duration of the last completed client ping. */ std::chrono::steady_clock::duration m_Ping; @@ -449,12 +449,12 @@ private: csPlaying, ///< Normal gameplay csDestroying, ///< The client is being destroyed, don't queue any more packets / don't add to chunks csDestroyed, ///< The client has been destroyed, the destructor is to be called from the owner thread - + // TODO: Add Kicking here as well } ; - + std::atomic m_State; - + /** m_State needs to be locked in the Destroy() function so that the destruction code doesn't run twice on two different threads */ cCriticalSection m_CSDestroyingState; @@ -466,15 +466,15 @@ private: /** Number of place or break interactions this tick */ int m_NumBlockChangeInteractionsThisTick; - + static int s_ClientCount; - + /** ID used for identification during authenticating. Assigned sequentially for each new instance. */ int m_UniqueID; - + /** Contains the UUID used by Mojang to identify the player's account. Short UUID stored here (without dashes) */ AString m_UUID; - + /** Set to true when the chunk where the player is is sent to the client. Used for spawning the player */ bool m_HasSentPlayerChunk; @@ -483,10 +483,10 @@ private: /** The positions from the last sign that the player placed. It's needed to verify the sign text change. */ Vector3i m_LastPlacedSign; - + /** The plugin channels that the client has registered. */ cChannels m_PluginChannels; - + /** The brand identification of the client, as received in the MC|Brand plugin message or set from a plugin. */ AString m_ClientBrand; @@ -503,13 +503,13 @@ private: /** Returns true if the rate block interactions is within a reasonable limit (bot protection) */ bool CheckBlockInteractionsRate(void); - + /** Adds a single chunk to be streamed to the client; used by StreamChunks() */ void StreamChunk(int a_ChunkX, int a_ChunkZ, cChunkSender::eChunkPriority a_Priority); - + /** Handles the DIG_STARTED dig packet: */ void HandleBlockDigStarted (int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta); - + /** Handles the DIG_FINISHED dig packet: */ void HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta); @@ -518,10 +518,10 @@ private: /** Converts the protocol-formatted channel list (NUL-separated) into a proper string vector. */ AStringVector BreakApartPluginChannels(const AString & a_PluginChannels); - + /** Adds all of the channels to the list of current plugin channels. Handles duplicates gracefully. */ void RegisterPluginChannels(const AStringVector & a_ChannelList); - + /** Removes all of the channels from the list of current plugin channels. Ignores channels that are not found. */ void UnregisterPluginChannels(const AStringVector & a_ChannelList); diff --git a/src/CommandOutput.cpp b/src/CommandOutput.cpp index 255ec3e9b..663838fac 100644 --- a/src/CommandOutput.cpp +++ b/src/CommandOutput.cpp @@ -64,7 +64,7 @@ void cLogCommandOutputCallback::Finished(void) { LOG("%s", m_Accum.substr(last).c_str()); } - + // Clear the buffer for the next command output: m_Accum.clear(); } diff --git a/src/CommandOutput.h b/src/CommandOutput.h index 0c9641cde..c9aa053c0 100644 --- a/src/CommandOutput.h +++ b/src/CommandOutput.h @@ -14,13 +14,13 @@ class cCommandOutputCallback { public: virtual ~cCommandOutputCallback() {} // Force a virtual destructor in subclasses - + /** Syntax sugar function, calls Out() with Printf()-ed parameters; appends a newline" */ void Out(const char * a_Fmt, ...) FORMATSTRING(2, 3); - + /** Called when the command wants to output anything; may be called multiple times */ virtual void Out(const AString & a_Text) = 0; - + /** Called when the command processing has been finished */ virtual void Finished(void) {} } ; @@ -87,7 +87,7 @@ class cLogCommandDeleteSelfOutputCallback : public cLogCommandOutputCallback { typedef cLogCommandOutputCallback super; - + virtual void Finished(void) override { super::Finished(); diff --git a/src/CompositeChat.cpp b/src/CompositeChat.cpp index 353835039..82e3d09f2 100644 --- a/src/CompositeChat.cpp +++ b/src/CompositeChat.cpp @@ -26,7 +26,7 @@ public: cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestParser4), "CompositeChat parser test 4"); cSelfTests::Get().Register(cSelfTests::SelfTestFunction(&TestParser5), "CompositeChat parser test 5"); } - + static void TestParser1(void) { cCompositeChat Msg; @@ -42,7 +42,7 @@ public: assert_test(Parts[2]->m_Style == "@2"); assert_test(Parts[3]->m_Style == "@2"); } - + static void TestParser2(void) { cCompositeChat Msg; @@ -58,7 +58,7 @@ public: assert_test(Parts[2]->m_Style == "@5"); assert_test(Parts[3]->m_Style == "@5"); } - + static void TestParser3(void) { cCompositeChat Msg; @@ -70,7 +70,7 @@ public: assert_test(Parts[0]->m_Style == ""); assert_test(Parts[1]->m_Style == ""); } - + static void TestParser4(void) { cCompositeChat Msg; @@ -82,7 +82,7 @@ public: assert_test(Parts[0]->m_Style == ""); assert_test(Parts[1]->m_Style == ""); } - + static void TestParser5(void) { cCompositeChat Msg; @@ -92,7 +92,7 @@ public: assert_test(Parts[0]->m_PartType == cCompositeChat::ptUrl); assert_test(Parts[0]->m_Style == ""); } - + } gTest; #endif // SELF_TEST @@ -244,7 +244,7 @@ void cCompositeChat::ParseText(const AString & a_ParseText) } break; } - + case ':': { const char * LinkPrefixes[] = @@ -271,7 +271,7 @@ void cCompositeChat::ParseText(const AString & a_ParseText) AddTextPart(CurrentText, CurrentStyle); CurrentText.clear(); } - + // Go till the last non-whitespace char in the text: for (; i < len; i++) { @@ -419,7 +419,7 @@ AString cCompositeChat::CreateJsonString(bool a_ShouldUseChatPrefixes) const AddChatPartStyle(Part, (*itr)->m_Style); break; } - + case cCompositeChat::ptClientTranslated: { const cCompositeChat::cClientTranslatedPart & p = static_cast(**itr); @@ -436,7 +436,7 @@ AString cCompositeChat::CreateJsonString(bool a_ShouldUseChatPrefixes) const AddChatPartStyle(Part, p.m_Style); break; } - + case cCompositeChat::ptUrl: { const cCompositeChat::cUrlPart & p = static_cast(**itr); @@ -448,7 +448,7 @@ AString cCompositeChat::CreateJsonString(bool a_ShouldUseChatPrefixes) const AddChatPartStyle(Part, p.m_Style); break; } - + case cCompositeChat::ptSuggestCommand: case cCompositeChat::ptRunCommand: { @@ -470,7 +470,7 @@ AString cCompositeChat::CreateJsonString(bool a_ShouldUseChatPrefixes) const Json::Value Ach; Ach["action"] = "show_achievement"; Ach["value"] = p.m_Text; - + Json::Value AchColourAndName; AchColourAndName["color"] = "green"; AchColourAndName["translate"] = p.m_Text; @@ -514,35 +514,35 @@ void cCompositeChat::AddChatPartStyle(Json::Value & a_Value, const AString & a_P a_Value["bold"] = Json::Value(true); break; } - + case 'i': { // italic a_Value["italic"] = Json::Value(true); break; } - + case 'u': { // Underlined a_Value["underlined"] = Json::Value(true); break; } - + case 's': { // strikethrough a_Value["strikethrough"] = Json::Value(true); break; } - + case 'o': { // obfuscated a_Value["obfuscated"] = Json::Value(true); break; } - + case '@': { // Color, specified by the next char: diff --git a/src/CompositeChat.h b/src/CompositeChat.h index becf0a91e..2c1ff5fab 100644 --- a/src/CompositeChat.h +++ b/src/CompositeChat.h @@ -32,7 +32,7 @@ class cCompositeChat { public: // tolua_end - + enum ePartType { ptText, @@ -42,7 +42,7 @@ public: ptSuggestCommand, ptShowAchievement, } ; - + class cBasePart { public: @@ -50,13 +50,13 @@ public: AString m_Text; AString m_Style; AString m_AdditionalStyleData; - + cBasePart(ePartType a_PartType, const AString & a_Text, const AString & a_Style = ""); - + // Force a virtual destructor in descendants virtual ~cBasePart() {} } ; - + class cTextPart : public cBasePart { @@ -64,37 +64,37 @@ public: public: cTextPart(const AString & a_Text, const AString & a_Style = ""); } ; - + class cClientTranslatedPart : public cBasePart { typedef cBasePart super; public: AStringVector m_Parameters; - + cClientTranslatedPart(const AString & a_TranslationID, const AStringVector & a_Parameters, const AString & a_Style = ""); } ; - + class cUrlPart : public cBasePart { typedef cBasePart super; public: AString m_Url; - + cUrlPart(const AString & a_Text, const AString & a_Url, const AString & a_Style = ""); } ; - + class cCommandPart : public cBasePart { typedef cBasePart super; public: AString m_Command; - + cCommandPart(ePartType a_PartType, const AString & a_Text, const AString & a_Command, const AString & a_Style = ""); } ; - + class cRunCommandPart : public cCommandPart { @@ -102,7 +102,7 @@ public: public: cRunCommandPart(const AString & a_Text, const AString & a_Command, const AString & a_Style = ""); } ; - + class cSuggestCommandPart : public cCommandPart { @@ -119,45 +119,45 @@ public: AString m_PlayerName; cShowAchievementPart(const AString & a_PlayerName, const AString & a_Achievement, const AString & a_Style = ""); } ; - + typedef std::vector cParts; - + // tolua_begin - + /** Creates a new empty chat message */ cCompositeChat(void); - + /** Creates a new chat message and parses the text into parts. Recognizes "http:" and "https:" links and @color-codes. Uses ParseText() for the actual parsing. */ cCompositeChat(const AString & a_ParseText, eMessageType a_MessageType = mtCustom); - + ~cCompositeChat(); - + /** Removes all parts from the object. */ void Clear(void); - + // tolua_end // The following are exported in ManualBindings in order to support chaining - they return *this in Lua (#755) - + /** Adds a plain text part, with optional style. The default style is plain white text. */ void AddTextPart(const AString & a_Message, const AString & a_Style = ""); - + /** Adds a part that is translated client-side, with the formatting parameters and optional style. */ void AddClientTranslatedPart(const AString & a_TranslationID, const AStringVector & a_Parameters, const AString & a_Style = ""); - + // tolua_begin - + /** Adds a part that opens an URL when clicked. The default style is underlined light blue text. */ void AddUrlPart(const AString & a_Text, const AString & a_Url, const AString & a_Style = "u@c"); - + /** Adds a part that runs a command when clicked. The default style is underlined light green text. */ void AddRunCommandPart(const AString & a_Text, const AString & a_Command, const AString & a_Style = "u@a"); - + /** Adds a part that suggests a command (enters it into the chat message area, but doesn't send) when clicked. The default style is underlined yellow text. */ void AddSuggestCommandPart(const AString & a_Text, const AString & a_SuggestedCommand, const AString & a_Style = "u@b"); @@ -166,19 +166,19 @@ public: Takes achievement name and player awarded to. Displays as {player} has earned the achievement {achievement_name}. */ void AddShowAchievementPart(const AString & a_PlayerName, const AString & a_Achievement, const AString & a_Style = ""); - + /** Parses text into various parts, adds those. Recognizes "http:" and "https:" URLs and @color-codes. */ void ParseText(const AString & a_ParseText); - + /** Sets the message type, which is indicated by prefixes added to the message when serializing Takes optional AdditionalMessageTypeData to set m_AdditionalMessageTypeData. See said variable for more documentation. */ void SetMessageType(eMessageType a_MessageType, const AString & a_AdditionalMessageTypeData = ""); - + /** Adds the "underline" style to each part that is an URL. */ void UnderlineUrls(void); - + // tolua_begin /** Returns the message type set previously by SetMessageType(). */ @@ -186,36 +186,36 @@ public: /** Returns additional data pertaining to message type, for example, the name of a mtPrivateMsg sender */ AString GetAdditionalMessageTypeData(void) const { return m_AdditionalMessageTypeData; } - + /** Returns the text from the parts that comprises the human-readable data. Used for older protocols that don't support composite chat and for console-logging. */ AString ExtractText(void) const; AString CreateJsonString(bool a_ShouldUseChatPrefixes = true) const; - + // tolua_end - + const cParts & GetParts(void) const { return m_Parts; } - + /** Converts the MessageType to a LogLevel value. Used by the logging bindings when logging a cCompositeChat object. */ static cLogger::eLogLevel MessageTypeToLogLevel(eMessageType a_MessageType); /** Adds the chat part's style (represented by the part's stylestring) into the Json object. */ void AddChatPartStyle(Json::Value & a_Value, const AString & a_PartStyle) const; - + protected: /** All the parts that */ cParts m_Parts; - + /** The message type, as indicated by prefixes. */ eMessageType m_MessageType; - + /** Additional data pertaining to message type, for example, the name of a mtPrivateMsg sender */ AString m_AdditionalMessageTypeData; - - + + /** Adds a_AddStyle to a_Style; overwrites the existing style if appropriate. If the style already contains something that a_AddStyle overrides, it is erased first. */ void AddStyle(AString & a_Style, const AString & a_AddStyle); diff --git a/src/CraftingRecipes.cpp b/src/CraftingRecipes.cpp index d3a28292a..3aa9074e2 100644 --- a/src/CraftingRecipes.cpp +++ b/src/CraftingRecipes.cpp @@ -93,7 +93,7 @@ void cCraftingGrid::SetItem(int x, int y, ENUM_ITEM_ID a_ItemType, char a_ItemCo ); return; } - + m_Items[x + m_Width * y] = cItem(a_ItemType, a_ItemCount, a_ItemHealth); } @@ -111,7 +111,7 @@ void cCraftingGrid::SetItem(int x, int y, const cItem & a_Item) ); return; } - + m_Items[x + m_Width * y] = a_Item; } @@ -294,7 +294,7 @@ void cCraftingRecipes::GetRecipe(cPlayer & a_Player, cCraftingGrid & a_CraftingG { return; } - + // Built-in recipes: std::unique_ptr Recipe(FindRecipe(a_CraftingGrid.GetItems(), a_CraftingGrid.GetWidth(), a_CraftingGrid.GetHeight())); a_Recipe.Clear(); @@ -309,7 +309,7 @@ void cCraftingRecipes::GetRecipe(cPlayer & a_Player, cCraftingGrid & a_CraftingG a_Recipe.SetIngredient(itr->x, itr->y, itr->m_Item); } // for itr a_Recipe.SetResult(Recipe->m_Result); - + // Allow plugins to intercept recipes after they are processed: cRoot::Get()->GetPluginManager()->CallHookPostCrafting(a_Player, a_CraftingGrid, a_Recipe); } @@ -322,7 +322,7 @@ void cCraftingRecipes::LoadRecipes(void) { LOGD("Loading crafting recipes from crafting.txt..."); ClearRecipes(); - + // Load the crafting.txt file: cFile f; if (!f.Open("crafting.txt", cFile::fmRead)) @@ -337,7 +337,7 @@ void cCraftingRecipes::LoadRecipes(void) return; } f.Close(); - + // Split it into lines, then process each line as a single recipe: AStringVector Split = StringSplit(Everything, "\n"); int LineNum = 1; @@ -384,9 +384,9 @@ void cCraftingRecipes::AddRecipeLine(int a_LineNum, const AString & a_RecipeLine LOGINFO("Offending line: \"%s\"", a_RecipeLine.c_str()); return; } - + std::unique_ptr Recipe = cpp14::make_unique(); - + // Parse the result: AStringVector ResultSplit = StringSplit(Sides[0], ","); if (ResultSplit.empty()) @@ -414,7 +414,7 @@ void cCraftingRecipes::AddRecipeLine(int a_LineNum, const AString & a_RecipeLine { Recipe->m_Result.m_ItemCount = 1; } - + // Parse each ingredient: AStringVector Ingredients = StringSplit(Sides[1], "|"); int Num = 1; @@ -427,9 +427,9 @@ void cCraftingRecipes::AddRecipeLine(int a_LineNum, const AString & a_RecipeLine return; } } // for itr - Ingredients[] - + NormalizeIngredients(Recipe.get()); - + m_Recipes.push_back(Recipe.release()); } @@ -440,18 +440,18 @@ void cCraftingRecipes::AddRecipeLine(int a_LineNum, const AString & a_RecipeLine bool cCraftingRecipes::ParseItem(const AString & a_String, cItem & a_Item) { // The caller provides error logging - + AStringVector Split = StringSplit(a_String, "^"); if (Split.empty()) { return false; } - + if (!StringToItem(Split[0], a_Item)) { return false; } - + if (Split.size() > 1) { AString Damage = TrimString(Split[1]); @@ -461,7 +461,7 @@ bool cCraftingRecipes::ParseItem(const AString & a_String, cItem & a_Item) return false; } } - + // Success return true; } @@ -485,7 +485,7 @@ bool cCraftingRecipes::ParseIngredient(const AString & a_String, cRecipe * a_Rec return false; } Item.m_ItemCount = 1; - + cCraftingRecipes::cRecipeSlots TempSlots; for (AStringVector::const_iterator itr = Split.begin() + 1; itr != Split.end(); ++itr) { @@ -536,7 +536,7 @@ bool cCraftingRecipes::ParseIngredient(const AString & a_String, cRecipe * a_Rec } TempSlots.push_back(Slot); } // for itr - Split[] - + // Append the ingredients: a_Recipe->m_Ingredients.insert(a_Recipe->m_Ingredients.end(), TempSlots.begin(), TempSlots.end()); return true; @@ -579,7 +579,7 @@ void cCraftingRecipes::NormalizeIngredients(cCraftingRecipes::cRecipe * a_Recipe } // for itr - a_Recipe->m_Ingredients[] a_Recipe->m_Width = std::max(MaxX - MinX + 1, 1); a_Recipe->m_Height = std::max(MaxY - MinY + 1, 1); - + // TODO: Compress two same ingredients with the same coords into a single ingredient with increased item count } @@ -591,7 +591,7 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::FindRecipe(const cItem * a_Craftin { ASSERT(a_GridWidth <= MAX_GRID_WIDTH); ASSERT(a_GridHeight <= MAX_GRID_HEIGHT); - + // Get the real bounds of the crafting grid: int GridLeft = MAX_GRID_WIDTH, GridTop = MAX_GRID_HEIGHT; int GridRight = 0, GridBottom = 0; @@ -607,7 +607,7 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::FindRecipe(const cItem * a_Craftin } int GridWidth = GridRight - GridLeft + 1; int GridHeight = GridBottom - GridTop + 1; - + // Search in the possibly minimized grid, but keep the stride: const cItem * Grid = a_CraftingGrid + GridLeft + (a_GridWidth * GridTop); cRecipe * Recipe = FindRecipeCropped(Grid, GridWidth, GridHeight, a_GridWidth); @@ -615,14 +615,14 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::FindRecipe(const cItem * a_Craftin { return nullptr; } - + // A recipe has been found, move it to correspond to the original crafting grid: for (cRecipeSlots::iterator itrS = Recipe->m_Ingredients.begin(); itrS != Recipe->m_Ingredients.end(); ++itrS) { itrS->x += GridLeft; itrS->y += GridTop; } // for itrS - Recipe->m_Ingredients[] - + return Recipe; } @@ -639,7 +639,7 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::FindRecipeCropped(const cItem * a_ // E. g. recipe "A, * | B, 1:1 | ..." still needs to check grid for B at 2:2 (in case A was in grid's 1:1) // Calculate the maximum offsets for this recipe relative to the grid size, and iterate through all combinations of offsets. // Also, this calculation automatically filters out recipes that are too large for the current grid - the loop won't be entered at all. - + int MaxOfsX = a_GridWidth - (*itr)->m_Width; int MaxOfsY = a_GridHeight - (*itr)->m_Height; for (int x = 0; x <= MaxOfsX; x++) for (int y = 0; y <= MaxOfsY; y++) @@ -651,7 +651,7 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::FindRecipeCropped(const cItem * a_ } } // for y, for x } // for itr - m_Recipes[] - + // No matching recipe found return nullptr; } @@ -675,7 +675,7 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_Crafti ASSERT(itrS->x + a_OffsetX < a_GridWidth); ASSERT(itrS->y + a_OffsetY < a_GridHeight); int GridID = (itrS->x + a_OffsetX) + a_GridStride * (itrS->y + a_OffsetY); - + const cItem & Item = itrS->m_Item; if ( (itrS->x >= a_GridWidth) || @@ -693,7 +693,7 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_Crafti } HasMatched[itrS->x + a_OffsetX][itrS->y + a_OffsetY] = true; } // for itrS - Recipe->m_Ingredients[] - + // Process the "Anywhere" items now, and only in the cells that haven't matched yet // The "anywhere" items are processed on a first-come-first-served basis. // Do not use a recipe with one horizontal and one vertical "anywhere" ("*:1, 1:*") as it may not match properly! @@ -754,7 +754,7 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_Crafti return nullptr; } } // for itrS - a_Recipe->m_Ingredients[] - + // Check if the whole grid has matched: for (int x = 0; x < a_GridWidth; x++) for (int y = 0; y < a_GridHeight; y++) { @@ -764,7 +764,7 @@ cCraftingRecipes::cRecipe * cCraftingRecipes::MatchRecipe(const cItem * a_Crafti return nullptr; } } // for y, for x - + // The recipe has matched. Create a copy of the recipe and set its coords to match the crafting grid: std::unique_ptr Recipe = cpp14::make_unique(); Recipe->m_Result = a_Recipe->m_Result; diff --git a/src/CraftingRecipes.h b/src/CraftingRecipes.h index 81e3d111c..1c4e87461 100644 --- a/src/CraftingRecipes.h +++ b/src/CraftingRecipes.h @@ -28,7 +28,7 @@ public: cCraftingGrid(int a_Width, int a_Height); // tolua_export cCraftingGrid(const cItem * a_Items, int a_Width, int a_Height); ~cCraftingGrid(); - + // tolua_begin int GetWidth (void) const {return m_Width; } int GetHeight(void) const {return m_Height; } @@ -36,20 +36,20 @@ public: void SetItem (int x, int y, ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemHealth); void SetItem (int x, int y, const cItem & a_Item); void Clear (void); - + /** Removes items in a_Grid from m_Items[] (used by cCraftingRecipe::ConsumeIngredients()) */ void ConsumeGrid(const cCraftingGrid & a_Grid); /** Dumps the entire crafting grid using LOGD() */ void Dump(void); - + // tolua_end - + cItem * GetItems(void) const {return m_Items; } - + /** Copies internal contents into the item array specified. Assumes that the array has the same dimensions as self */ void CopyToItems(cItem * a_Items) const; - + protected: int m_Width; @@ -65,7 +65,7 @@ class cCraftingRecipe // tolua_export { // tolua_export public: cCraftingRecipe(const cCraftingGrid & a_CraftingGrid); - + // tolua_begin void Clear (void); int GetIngredientsWidth (void) const {return m_Ingredients.GetWidth(); } @@ -77,24 +77,24 @@ public: { m_Result = a_Item; } - + void SetIngredient (int x, int y, ENUM_ITEM_ID a_ItemType, char a_ItemCount, short a_ItemHealth) { m_Ingredients.SetItem(x, y, a_ItemType, a_ItemCount, a_ItemHealth); } - + void SetIngredient (int x, int y, const cItem & a_Item) { m_Ingredients.SetItem(x, y, a_Item); } - + /** Consumes ingredients from the crafting grid specified */ void ConsumeIngredients(cCraftingGrid & a_CraftingGrid); /** Dumps the entire recipe using LOGD() */ void Dump(void); // tolua_end - + protected: cCraftingGrid m_Ingredients; // Adjusted to correspond to the input crafting grid! @@ -110,13 +110,13 @@ class cCraftingRecipes public: static const int MAX_GRID_WIDTH = 3; static const int MAX_GRID_HEIGHT = 3; - + cCraftingRecipes(void); ~cCraftingRecipes(); - + /** Returns the recipe for current crafting grid. Doesn't modify the grid. Clears a_Recipe if no recipe found. */ void GetRecipe(cPlayer & a_Player, cCraftingGrid & a_CraftingGrid, cCraftingRecipe & a_Recipe); - + protected: struct cRecipeSlot @@ -125,43 +125,43 @@ protected: int x, y; // 1..3, or -1 for "any" } ; typedef std::vector cRecipeSlots; - + /** A single recipe, stored. Each recipe is normalized right after parsing (NormalizeIngredients()) A normalized recipe starts at (0, 0) */ struct cRecipe { cRecipeSlots m_Ingredients; cItem m_Result; - + // Size of the regular items in the recipe; "anywhere" items are excluded: int m_Width; int m_Height; } ; typedef std::vector cRecipes; - + cRecipes m_Recipes; - + void LoadRecipes(void); void ClearRecipes(void); - + /** Parses the recipe line and adds it into m_Recipes. a_LineNum is used for diagnostic warnings only */ void AddRecipeLine(int a_LineNum, const AString & a_RecipeLine); - + /** Parses an item string in the format "[^]", returns true if successful. */ bool ParseItem(const AString & a_String, cItem & a_Item); - + /** Parses one ingredient and adds it to the specified recipe. Returns true if successful. */ bool ParseIngredient(const AString & a_String, cRecipe * a_Recipe); - + /** Moves the recipe to top-left corner, sets its MinWidth / MinHeight */ void NormalizeIngredients(cRecipe * a_Recipe); - + /** Finds a recipe matching the crafting grid. Returns a newly allocated recipe (with all its coords set) or nullptr if not found. Caller must delete return value! */ cRecipe * FindRecipe(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight); - + /** Same as FindRecipe, but the grid is guaranteed to be of minimal dimensions needed */ cRecipe * FindRecipeCropped(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight, int a_GridStride); - + /** Checks if the grid matches the specified recipe, offset by the specified offsets. Returns a matched cRecipe * if so, or nullptr if not matching. Caller must delete the return value! */ cRecipe * MatchRecipe(const cItem * a_CraftingGrid, int a_GridWidth, int a_GridHeight, int a_GridStride, const cRecipe * a_Recipe, int a_OffsetX, int a_OffsetY); diff --git a/src/Cuboid.cpp b/src/Cuboid.cpp index 0a454a8f3..1aa1e92e1 100644 --- a/src/Cuboid.cpp +++ b/src/Cuboid.cpp @@ -99,7 +99,7 @@ bool cCuboid::DoesIntersect(const cCuboid & a_Other) const { ASSERT(IsSorted()); ASSERT(a_Other.IsSorted()); - + // In order for cuboids to intersect, each of their coord intervals need to intersect return ( DoIntervalsIntersect(p1.x, p2.x, a_Other.p1.x, a_Other.p2.x) && @@ -116,7 +116,7 @@ bool cCuboid::IsCompletelyInside(const cCuboid & a_Outer) const { ASSERT(IsSorted()); ASSERT(a_Outer.IsSorted()); - + return ( (p1.x >= a_Outer.p1.x) && (p2.x <= a_Outer.p2.x) && @@ -158,7 +158,7 @@ void cCuboid::Expand(int a_SubMinX, int a_AddMaxX, int a_SubMinY, int a_AddMaxY, p2.x -= a_SubMinX; p1.x += a_AddMaxX; } - + if (p1.y < p2.y) { p1.y -= a_SubMinY; @@ -169,7 +169,7 @@ void cCuboid::Expand(int a_SubMinX, int a_AddMaxX, int a_SubMinY, int a_AddMaxY, p2.y -= a_SubMinY; p1.y += a_AddMaxY; } - + if (p1.z < p2.z) { p1.z -= a_SubMinZ; diff --git a/src/Cuboid.h b/src/Cuboid.h index c205156ec..0e6a37dfb 100644 --- a/src/Cuboid.h +++ b/src/Cuboid.h @@ -19,27 +19,27 @@ public: cCuboid(const Vector3i & a_p1, const Vector3i & a_p2) : p1(a_p1), p2(a_p2) {} cCuboid(int a_X1, int a_Y1, int a_Z1) : p1(a_X1, a_Y1, a_Z1), p2(a_X1, a_Y1, a_Z1) {} cCuboid(int a_X1, int a_Y1, int a_Z1, int a_X2, int a_Y2, int a_Z2) : p1(a_X1, a_Y1, a_Z1), p2(a_X2, a_Y2, a_Z2) {} - + // tolua_end - + cCuboid & operator =(cCuboid a_Other); - + // tolua_begin void Assign(int a_X1, int a_Y1, int a_Z1, int a_X2, int a_Y2, int a_Z2); void Assign(const cCuboid & a_SrcCuboid); void Sort(void); - + int DifX(void) const { return p2.x - p1.x; } int DifY(void) const { return p2.y - p1.y; } int DifZ(void) const { return p2.z - p1.z; } - + /** Returns the volume of the cuboid, in blocks. Note that the volume considers both coords inclusive. Works on unsorted cuboids, too. */ int GetVolume(void) const; - + /** Returns true if the cuboids have at least one voxel in common. Both coords are considered inclusive. Assumes both cuboids are sorted. */ bool DoesIntersect(const cCuboid & a_Other) const; @@ -70,19 +70,19 @@ public: (v.z >= p1.z) && (v.z <= p2.z) ); } - + /** Returns true if this cuboid is completely inside the specifie cuboid (in all 6 coords). Assumes both cuboids are sorted. */ bool IsCompletelyInside(const cCuboid & a_Outer) const; - + /** Moves the cuboid by the specified offsets in each direction */ void Move(int a_OfsX, int a_OfsY, int a_OfsZ); - + /** Expands the cuboid by the specified amount in each direction. Works on unsorted cuboids as well. Note that this function doesn't check for underflows when using negative amounts. */ void Expand(int a_SubMinX, int a_AddMaxX, int a_SubMinY, int a_AddMaxY, int a_SubMinZ, int a_AddMaxZ); - + /** Clamps both X coords to the specified range. Works on unsorted cuboids, too. */ void ClampX(int a_MinX, int a_MaxX); @@ -94,7 +94,7 @@ public: /** Returns true if the coords are properly sorted (lesser in p1, greater in p2) */ bool IsSorted(void) const; - + /** If needed, expands the cuboid so that it contains the specified point. Assumes sorted. Doesn't contract. */ void Engulf(const Vector3i & a_Point); } ; diff --git a/src/DeadlockDetect.cpp b/src/DeadlockDetect.cpp index 3bb897221..3141020d0 100644 --- a/src/DeadlockDetect.cpp +++ b/src/DeadlockDetect.cpp @@ -33,7 +33,7 @@ cDeadlockDetect::cDeadlockDetect(void) : bool cDeadlockDetect::Start(int a_IntervalSec) { m_IntervalSec = a_IntervalSec; - + // Read the initial world data: class cFillIn : public cWorldListCallback @@ -43,13 +43,13 @@ bool cDeadlockDetect::Start(int a_IntervalSec) m_Detect(a_Detect) { } - + virtual bool Item(cWorld * a_World) override { m_Detect->SetWorldAge(a_World->GetName(), a_World->GetWorldAge()); return false; } - + protected: cDeadlockDetect * m_Detect; } FillIn(this); @@ -75,10 +75,10 @@ void cDeadlockDetect::Execute(void) m_Detect(a_Detect) { } - + protected: cDeadlockDetect * m_Detect; - + virtual bool Item(cWorld * a_World) override { m_Detect->CheckWorldAge(a_World->GetName(), a_World->GetWorldAge()); @@ -86,7 +86,7 @@ void cDeadlockDetect::Execute(void) } } Checker(this); cRoot::Get()->ForEachWorld(Checker); - + std::this_thread::sleep_for(std::chrono::milliseconds(CYCLE_MILLISECONDS)); } // while (should run) } diff --git a/src/DeadlockDetect.h b/src/DeadlockDetect.h index 3d8e49a6d..39d3f8691 100644 --- a/src/DeadlockDetect.h +++ b/src/DeadlockDetect.h @@ -24,41 +24,41 @@ class cDeadlockDetect : public cIsThread { typedef cIsThread super; - + public: cDeadlockDetect(void); - + /** Starts the detection. Hides cIsThread's Start, because we need some initialization */ bool Start(int a_IntervalSec); - + protected: struct sWorldAge { /** Last m_WorldAge that has been detected in this world */ Int64 m_Age; - + /** Number of cycles for which the age has been the same */ int m_NumCyclesSame; } ; - + /** Maps world name -> sWorldAge */ typedef std::map WorldAges; - + WorldAges m_WorldAges; - + /** Number of secods for which the ages must be the same for the detection to trigger */ int m_IntervalSec; - - + + // cIsThread overrides: virtual void Execute(void) override; - + /** Sets the initial world age */ void SetWorldAge(const AString & a_WorldName, Int64 a_Age); - + /** Checks if the world's age has changed, updates the world's stats; calls DeadlockDetected() if deadlock detected */ void CheckWorldAge(const AString & a_WorldName, Int64 a_Age); - + /** Called when a deadlock is detected. Aborts the server. */ NORETURN void DeadlockDetected(void); } ; diff --git a/src/Enchantments.cpp b/src/Enchantments.cpp index 34270b2f3..a8300aabb 100644 --- a/src/Enchantments.cpp +++ b/src/Enchantments.cpp @@ -45,7 +45,7 @@ void cEnchantments::Add(const cEnchantments & a_Other) void cEnchantments::AddFromString(const AString & a_StringSpec) { // Add enchantments in the stringspec; if a specified enchantment already exists, overwrites it - + // Split the StringSpec into separate declarations, each in the form "id=lvl": AStringVector Decls = StringSplit(a_StringSpec, ";"); for (AStringVector::const_iterator itr = Decls.begin(), end = Decls.end(); itr != end; ++itr) @@ -507,7 +507,7 @@ void cEnchantments::AddItemEnchantmentWeights(cWeightedEnchantments & a_Enchantm { AddEnchantmentWeightToVector(a_Enchantments, 5, enchFeatherFalling, 1); } - + // Depth Strider if ((a_EnchantmentLevel >= 30) && (a_EnchantmentLevel <= 45)) { diff --git a/src/Enchantments.h b/src/Enchantments.h index 8c08e7a93..e2f10be63 100644 --- a/src/Enchantments.h +++ b/src/Enchantments.h @@ -42,7 +42,7 @@ class cEnchantments public: /** Individual enchantment IDs, corresponding to their NBT IDs: http://www.minecraftwiki.net/wiki/Data_Values#Enchantment_IDs */ - + enum eEnchantment { enchProtection = 0, @@ -74,38 +74,38 @@ public: /** Creates an empty enchantments container */ cEnchantments(void); - + /** Creates an enchantments container filled with enchantments parsed from stringspec */ cEnchantments(const AString & a_StringSpec); - + /** Adds the enchantments contained in a_Other into this object. Existing enchantments are preserved, unless a_Other specifies a different level, in which case the level is changed. */ void Add(const cEnchantments & a_Other); - + /** Adds enchantments in the stringspec; if a specified enchantment already exists, overwrites it */ void AddFromString(const AString & a_StringSpec); - + /** Get the count of enchantments */ size_t Count(void); - + /** Serializes all the enchantments into a string */ AString ToString(void) const; - + /** Returns the level for the specified enchantment; 0 if not stored */ unsigned int GetLevel(int a_EnchantmentID) const; - + /** Sets the level for the specified enchantment, adding it if not stored before or removing it if level <= 0 */ void SetLevel(int a_EnchantmentID, unsigned int a_Level); - + /** Removes all enchantments */ void Clear(void); - + /** Returns true if there are no enchantments */ bool IsEmpty(void) const; - + /** Converts enchantment name or ID (number in string) to the numeric representation; returns -1 if enchantment name not found; case insensitive */ static int StringToEnchantmentID(const AString & a_EnchantmentName); - + /** Returns true if a_Other contains exactly the same enchantments and levels */ bool operator ==(const cEnchantments & a_Other) const; @@ -116,10 +116,10 @@ public: /** Add a enchantment with weight to the vector */ static void AddEnchantmentWeightToVector(cWeightedEnchantments & a_Enchantments, int a_Weight, int a_EnchantmentID, unsigned int a_EnchantmentLevel); - + /** Remove the entire enchantment (with weight) from the vector */ static void RemoveEnchantmentWeightFromVector(cWeightedEnchantments & a_Enchantments, int a_EnchantmentID); - + /** Remove the entire enchantment (with weight) from the vector */ static void RemoveEnchantmentWeightFromVector(cWeightedEnchantments & a_Enchantments, const cEnchantments & a_Enchantment); @@ -136,17 +136,17 @@ public: /** Returns true if a_Other doesn't contain exactly the same enchantments and levels */ bool operator !=(const cEnchantments & a_Other) const; - + /** Writes the enchantments into the specified NBT writer; begins with the LIST tag of the specified name ("ench" or "StoredEnchantments") */ friend void EnchantmentSerializer::WriteToNBTCompound(const cEnchantments & a_Enchantments, cFastNBTWriter & a_Writer, const AString & a_ListTagName); - + /** Reads the enchantments from the specified NBT list tag (ench or StoredEnchantments) */ friend void EnchantmentSerializer::ParseFromNBT(cEnchantments & a_Enchantments, const cParsedNBT & a_NBT, int a_EnchListTagIdx); protected: /** Maps enchantment ID -> enchantment level */ typedef std::map cMap; - + /** Currently stored enchantments */ cMap m_Enchantments; } ; // tolua_export diff --git a/src/Entities/ArrowEntity.h b/src/Entities/ArrowEntity.h index 2ecc16d1c..7ed99b79e 100644 --- a/src/Entities/ArrowEntity.h +++ b/src/Entities/ArrowEntity.h @@ -22,7 +22,7 @@ class cArrowEntity : public cProjectileEntity { typedef cProjectileEntity super; - + public: /** Determines when the arrow can be picked up (depending on player gamemode). Corresponds to the MCA file "pickup" field */ enum ePickupState @@ -31,78 +31,78 @@ public: psInSurvivalOrCreative = 1, psInCreative = 2, } ; - + // tolua_end - + CLASS_PROTODEF(cArrowEntity) - + /** Creates a new arrow with psNoPickup state and default damage modifier coeff */ cArrowEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed); - + /** Creates a new arrow as shot by a player, initializes it from the player object */ cArrowEntity(cPlayer & a_Player, double a_Force); - + // tolua_begin - + /** Returns whether the arrow can be picked up by players */ ePickupState GetPickupState(void) const { return m_PickupState; } - + /** Sets a new pickup state */ void SetPickupState(ePickupState a_PickupState) { m_PickupState = a_PickupState; } - + /** Returns the damage modifier coeff. */ double GetDamageCoeff(void) const { return m_DamageCoeff; } /** Sets the damage modifier coeff */ void SetDamageCoeff(double a_DamageCoeff) { m_DamageCoeff = a_DamageCoeff; } - + /** Returns true if the specified player can pick the arrow up */ bool CanPickup(const cPlayer & a_Player) const; - + /** Returns true if the arrow is set as critical */ bool IsCritical(void) const { return m_IsCritical; } - + /** Sets the IsCritical flag */ void SetIsCritical(bool a_IsCritical) { m_IsCritical = a_IsCritical; } /** Gets the block arrow is in */ Vector3i GetBlockHit(void) const { return m_HitBlockPos; } - + // tolua_end /** Sets the block arrow is in. To be used by the MCA loader only! */ void SetBlockHit(const Vector3i & a_BlockHit) { m_HitBlockPos = a_BlockHit; } - + protected: - + /** Determines when the arrow can be picked up by players */ ePickupState m_PickupState; - + /** The coefficient applied to the damage that the arrow will deal, based on the bow enchantment. 2.0 for normal arrow */ double m_DamageCoeff; - + /** If true, the arrow deals more damage */ bool m_IsCritical; - + /** Timer for pickup collection animation or five minute timeout */ std::chrono::milliseconds m_Timer; - + /** Timer for client arrow position confirmation via TeleportEntity */ std::chrono::milliseconds m_HitGroundTimer; - + // Whether the arrow has already been teleported into the proper position in the ground. bool m_HasTeleported; - + /** If true, the arrow is in the process of being collected - don't go to anyone else */ bool m_bIsCollected; /** Stores the block position that arrow is lodged into, sets m_IsInGround to false if it becomes air */ Vector3i m_HitBlockPos; - + // cProjectileEntity overrides: virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override; virtual void OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) override; virtual void CollectedBy(cPlayer & a_Player) override; virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; - + }; // tolua_export diff --git a/src/Entities/Boat.cpp b/src/Entities/Boat.cpp index 4ad418be4..e81e57529 100644 --- a/src/Entities/Boat.cpp +++ b/src/Entities/Boat.cpp @@ -74,17 +74,17 @@ void cBoat::OnRightClicked(cPlayer & a_Player) a_Player.Detach(); return; } - + if (m_Attachee->IsPlayer()) { // Another player is already sitting in here, cannot attach return; } - + // Detach whatever is sitting in this boat now: m_Attachee->Detach(); } - + // Attach the player to this boat a_Player.AttachTo(this); } @@ -124,7 +124,7 @@ void cBoat::HandleSpeedFromAttachee(float a_Forward, float a_Sideways) { return; } - + Vector3d ToAddSpeed = m_Attachee->GetLookVector() * (a_Sideways * 0.4) ; ToAddSpeed.y = 0; diff --git a/src/Entities/Boat.h b/src/Entities/Boat.h index a873ff822..d168f5072 100644 --- a/src/Entities/Boat.h +++ b/src/Entities/Boat.h @@ -19,17 +19,17 @@ class cBoat : public cEntity { typedef cEntity super; - + public: CLASS_PROTODEF(cBoat) - + // cEntity overrides: virtual void SpawnOn(cClientHandle & a_ClientHandle) override; virtual void OnRightClicked(cPlayer & a_Player) override; virtual bool DoTakeDamage(TakeDamageInfo & TDI) override; virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; virtual void HandleSpeedFromAttachee(float a_Forward, float a_Sideways) override; - + cBoat(double a_X, double a_Y, double a_Z); } ; diff --git a/src/Entities/EnderCrystal.cpp b/src/Entities/EnderCrystal.cpp index b71d70bdd..79d0c50cb 100644 --- a/src/Entities/EnderCrystal.cpp +++ b/src/Entities/EnderCrystal.cpp @@ -46,7 +46,7 @@ void cEnderCrystal::KilledBy(TakeDamageInfo & a_TDI) m_World->DoExplosionAt(6.0, GetPosX(), GetPosY(), GetPosZ(), true, esEnderCrystal, this); Destroy(); - + m_World->SetBlock(POSX_TOINT, POSY_TOINT, POSZ_TOINT, E_BLOCK_BEDROCK, 0); m_World->SetBlock(POSX_TOINT, POSY_TOINT + 1, POSZ_TOINT, E_BLOCK_FIRE, 0); } diff --git a/src/Entities/EntityEffect.cpp b/src/Entities/EntityEffect.cpp index 214cbcc2b..6d56f4196 100644 --- a/src/Entities/EntityEffect.cpp +++ b/src/Entities/EntityEffect.cpp @@ -69,7 +69,7 @@ int cEntityEffect::GetPotionEffectDuration(short a_ItemDamage) // Base duration in ticks int base = 0; double TierCoeff = 1, ExtCoeff = 1, SplashCoeff = 1; - + switch (GetPotionEffectType(a_ItemDamage)) { case cEntityEffect::effRegeneration: @@ -78,7 +78,7 @@ int cEntityEffect::GetPotionEffectDuration(short a_ItemDamage) base = 900; break; } - + case cEntityEffect::effSpeed: case cEntityEffect::effFireResistance: case cEntityEffect::effNightVision: @@ -89,7 +89,7 @@ int cEntityEffect::GetPotionEffectDuration(short a_ItemDamage) base = 3600; break; } - + case cEntityEffect::effWeakness: case cEntityEffect::effSlowness: { @@ -98,22 +98,22 @@ int cEntityEffect::GetPotionEffectDuration(short a_ItemDamage) } default: break; } - + // If potion is level II, half the duration. If not, stays the same TierCoeff = (GetPotionEffectIntensity(a_ItemDamage) > 0) ? 0.5 : 1; - + // If potion is extended, multiply duration by 8 / 3. If not, stays the same // Extended potion if sixth lowest bit is set ExtCoeff = (a_ItemDamage & 0x40) ? (8.0 / 3.0) : 1; - + // If potion is splash potion, multiply duration by 3 / 4. If not, stays the same SplashCoeff = IsPotionDrinkable(a_ItemDamage) ? 1 : 0.75; - + // Ref.: // http://minecraft.gamepedia.com/Data_values#.22Tier.22_bit // http://minecraft.gamepedia.com/Data_values#.22Extended_duration.22_bit // http://minecraft.gamepedia.com/Data_values#.22Splash_potion.22_bit - + return static_cast(base * TierCoeff * ExtCoeff * SplashCoeff); } @@ -138,7 +138,7 @@ cEntityEffect::cEntityEffect(): m_Intensity(0), m_DistanceModifier(1) { - + } @@ -151,7 +151,7 @@ cEntityEffect::cEntityEffect(int a_Duration, short a_Intensity, double a_Distanc m_Intensity(a_Intensity), m_DistanceModifier(a_DistanceModifier) { - + } @@ -164,7 +164,7 @@ cEntityEffect::cEntityEffect(const cEntityEffect & a_OtherEffect): m_Intensity(a_OtherEffect.m_Intensity), m_DistanceModifier(a_OtherEffect.m_DistanceModifier) { - + } @@ -189,7 +189,7 @@ cEntityEffect * cEntityEffect::CreateEntityEffect(cEntityEffect::eType a_EffectT switch (a_EffectType) { case cEntityEffect::effNoEffect: return new cEntityEffect (a_Duration, a_Intensity, a_DistanceModifier); - + case cEntityEffect::effAbsorption: return new cEntityEffectAbsorption (a_Duration, a_Intensity, a_DistanceModifier); case cEntityEffect::effBlindness: return new cEntityEffectBlindness (a_Duration, a_Intensity, a_DistanceModifier); case cEntityEffect::effFireResistance: return new cEntityEffectFireResistance(a_Duration, a_Intensity, a_DistanceModifier); @@ -214,7 +214,7 @@ cEntityEffect * cEntityEffect::CreateEntityEffect(cEntityEffect::eType a_EffectT case cEntityEffect::effWeakness: return new cEntityEffectWeakness (a_Duration, a_Intensity, a_DistanceModifier); case cEntityEffect::effWither: return new cEntityEffectWither (a_Duration, a_Intensity, a_DistanceModifier); } - + ASSERT(!"Unhandled entity effect type!"); return nullptr; } @@ -326,7 +326,7 @@ void cEntityEffectInstantHealth::OnActivate(cPawn & a_Target) { // Base amount = 6, doubles for every increase in intensity int amount = static_cast(6 * (1 << m_Intensity) * m_DistanceModifier); - + if (a_Target.IsMob() && reinterpret_cast(a_Target).IsUndead()) { a_Target.TakeDamage(dtPotionOfHarming, nullptr, amount, 0); // TODO: Store attacker in a pointer-safe way, pass to TakeDamage @@ -346,7 +346,7 @@ void cEntityEffectInstantDamage::OnActivate(cPawn & a_Target) { // Base amount = 6, doubles for every increase in intensity int amount = static_cast(6 * (1 << m_Intensity) * m_DistanceModifier); - + if (a_Target.IsMob() && reinterpret_cast(a_Target).IsUndead()) { a_Target.Heal(amount); @@ -370,10 +370,10 @@ void cEntityEffectRegeneration::OnTick(cPawn & a_Target) { return; } - + // Regen frequency = 50 ticks, divided by potion level (Regen II = 25 ticks) int frequency = FloorC(50.0 / static_cast(m_Intensity + 1)); - + if ((m_Ticks % frequency) != 0) { return; @@ -392,7 +392,7 @@ void cEntityEffectRegeneration::OnTick(cPawn & a_Target) void cEntityEffectHunger::OnTick(cPawn & a_Target) { super::OnTick(a_Target); - + if (a_Target.IsPlayer()) { cPlayer & Target = reinterpret_cast(a_Target); @@ -410,10 +410,10 @@ void cEntityEffectHunger::OnTick(cPawn & a_Target) void cEntityEffectWeakness::OnTick(cPawn & a_Target) { super::OnTick(a_Target); - + // Damage reduction = 0.5 damage, multiplied by potion level (Weakness II = 1 damage) // double dmg_reduc = 0.5 * (a_Effect.GetIntensity() + 1); - + // TODO: Implement me! // TODO: Weakened villager zombies can be turned back to villagers with the god apple } @@ -428,11 +428,11 @@ void cEntityEffectWeakness::OnTick(cPawn & a_Target) void cEntityEffectPoison::OnTick(cPawn & a_Target) { super::OnTick(a_Target); - + if (a_Target.IsMob()) { cMonster & Target = reinterpret_cast(a_Target); - + // Doesn't effect undead mobs, spiders if ( Target.IsUndead() || @@ -443,10 +443,10 @@ void cEntityEffectPoison::OnTick(cPawn & a_Target) return; } } - + // Poison frequency = 25 ticks, divided by potion level (Poison II = 12 ticks) int frequency = FloorC(25.0 / static_cast(m_Intensity + 1)); - + if ((m_Ticks % frequency) == 0) { // Cannot take poison damage when health is at 1 @@ -467,7 +467,7 @@ void cEntityEffectPoison::OnTick(cPawn & a_Target) void cEntityEffectWither::OnTick(cPawn & a_Target) { super::OnTick(a_Target); - + // Damage frequency = 40 ticks, divided by effect level (Wither II = 20 ticks) int frequency = FloorC(25.0 / static_cast(m_Intensity + 1)); diff --git a/src/Entities/EntityEffect.h b/src/Entities/EntityEffect.h index 7cf9cd3d5..aa18b500e 100644 --- a/src/Entities/EntityEffect.h +++ b/src/Entities/EntityEffect.h @@ -6,7 +6,7 @@ class cPawn; class cEntityEffect { public: - + /** All types of entity effects (numbers correspond to protocol / storage types) */ enum eType { @@ -35,46 +35,46 @@ public: effAbsorption = 22, effSaturation = 23, } ; - + /** Returns the potion color (used by the client for visuals), based on the potion's damage value */ static int GetPotionColor(short a_ItemDamage); - - + + /** Translates the potion's damage value into the entity effect that the potion gives */ static cEntityEffect::eType GetPotionEffectType(short a_ItemDamage); - - + + /** Retrieves the intensity level from the potion's damage value. Returns 0 for level I potions, 1 for level II potions. */ static short GetPotionEffectIntensity(short a_ItemDamage); - - + + /** Returns the effect duration, in ticks, based on the potion's damage value */ static int GetPotionEffectDuration(short a_ItemDamage); - + /** Returns true if the potion with the given damage is drinkable */ static bool IsPotionDrinkable(short a_ItemDamage); - + // tolua_end - + /** Creates an empty entity effect */ cEntityEffect(void); - + /** Creates an entity effect of the specified type @param a_Duration How long this effect will last, in ticks @param a_Intensity How strong the effect will be applied @param a_DistanceModifier The distance modifier for affecting potency, defaults to 1 */ cEntityEffect(int a_Duration, short a_Intensity, double a_DistanceModifier = 1); - + /** Creates an entity effect by copying another @param a_OtherEffect The other effect to copy */ cEntityEffect(const cEntityEffect & a_OtherEffect); - + /** Creates an entity effect by copying another @param a_OtherEffect The other effect to copy */ cEntityEffect & operator =(cEntityEffect a_OtherEffect); - + virtual ~cEntityEffect(void) {} - + /** Creates a pointer to the proper entity effect from the effect type @warning This function creates raw pointers that must be manually managed. @param a_EffectType The effect type to create the effect from @@ -82,44 +82,44 @@ public: @param a_Intensity How strong the effect will be applied @param a_DistanceModifier The distance modifier for affecting potency, defaults to 1 */ static cEntityEffect * CreateEntityEffect(cEntityEffect::eType a_EffectType, int a_Duration, short a_Intensity, double a_DistanceModifier); - + /** Returns how many ticks this effect has been active for */ int GetTicks(void) const { return m_Ticks; } - + /** Returns the duration of the effect */ int GetDuration(void) const { return m_Duration; } - + /** Returns how strong the effect will be applied */ short GetIntensity(void) const { return m_Intensity; } - + /** Returns the distance modifier for affecting potency */ double GetDistanceModifier(void) const { return m_DistanceModifier; } - + void SetTicks(int a_Ticks) { m_Ticks = a_Ticks; } void SetDuration(int a_Duration) { m_Duration = a_Duration; } void SetIntensity(short a_Intensity) { m_Intensity = a_Intensity; } void SetDistanceModifier(double a_DistanceModifier) { m_DistanceModifier = a_DistanceModifier; } - + /** Called on each tick. By default increases the m_Ticks, descendants may override to provide additional processing. */ virtual void OnTick(cPawn & a_Target); - + /** Called when the effect is first added to an entity */ virtual void OnActivate(cPawn & a_Target) { } - + /** Called when the effect is removed from an entity */ virtual void OnDeactivate(cPawn & a_Target) { } - + protected: /** How many ticks this effect has been active for */ int m_Ticks; - + /** How long this effect will last, in ticks */ int m_Duration; - + /** How strong the effect will be applied */ short m_Intensity; - + /** The distance modifier for affecting potency */ double m_DistanceModifier; }; // tolua_export @@ -220,7 +220,7 @@ public: super(a_Duration, a_Intensity, a_DistanceModifier) { } - + virtual void OnActivate(cPawn & a_Target) override; }; @@ -237,7 +237,7 @@ public: super(a_Duration, a_Intensity, a_DistanceModifier) { } - + virtual void OnActivate(cPawn & a_Target) override; }; @@ -284,7 +284,7 @@ public: super(a_Duration, a_Intensity, a_DistanceModifier) { } - + virtual void OnTick(cPawn & a_Target) override; }; @@ -391,7 +391,7 @@ public: super(a_Duration, a_Intensity, a_DistanceModifier) { } - + // cEntityEffect overrides: virtual void OnTick(cPawn & a_Target) override; }; @@ -409,7 +409,7 @@ public: super(a_Duration, a_Intensity, a_DistanceModifier) { } - + // cEntityEffect overrides: virtual void OnTick(cPawn & a_Target) override; }; @@ -427,7 +427,7 @@ public: super(a_Duration, a_Intensity, a_DistanceModifier) { } - + // cEntityEffect overrides: virtual void OnTick(cPawn & a_Target) override; }; @@ -445,7 +445,7 @@ public: super(a_Duration, a_Intensity, a_DistanceModifier) { } - + // cEntityEffect overrides: virtual void OnTick(cPawn & a_Target) override; }; @@ -493,7 +493,7 @@ public: super(a_Duration, a_Intensity, a_DistanceModifier) { } - + virtual void OnTick(cPawn & a_Target) override; }; diff --git a/src/Entities/ExpBottleEntity.h b/src/Entities/ExpBottleEntity.h index 715b9947e..ea0c2b5a9 100644 --- a/src/Entities/ExpBottleEntity.h +++ b/src/Entities/ExpBottleEntity.h @@ -21,17 +21,17 @@ class cExpBottleEntity : public cProjectileEntity { typedef cProjectileEntity super; - + public: - + // tolua_end - + CLASS_PROTODEF(cExpBottleEntity) - + cExpBottleEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed); - + protected: - + // cProjectileEntity overrides: virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override; virtual void OnHitEntity (cEntity & a_EntityHit, const Vector3d & a_HitPos) override; @@ -39,7 +39,7 @@ protected: /** Breaks the bottle, fires its particle effects and sounds @param a_HitPos The position where the bottle will break */ void Break(const Vector3d & a_HitPos); - + }; // tolua_export diff --git a/src/Entities/ExpOrb.cpp b/src/Entities/ExpOrb.cpp index 676370508..f51bbb300 100644 --- a/src/Entities/ExpOrb.cpp +++ b/src/Entities/ExpOrb.cpp @@ -55,9 +55,9 @@ void cExpOrb::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { LOGD("Player %s picked up an ExpOrb. His reward is %i", a_ClosestPlayer->GetName().c_str(), m_Reward); a_ClosestPlayer->DeltaExperience(m_Reward); - + m_World->BroadcastSoundEffect("random.orb", GetPosX(), GetPosY(), GetPosZ(), 0.5f, (0.75f + (static_cast((GetUniqueID() * 23) % 32)) / 64)); - + Destroy(); } a_Distance.Normalize(); @@ -68,7 +68,7 @@ void cExpOrb::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) BroadcastMovementUpdate(); } HandlePhysics(a_Dt, a_Chunk); - + m_Timer += a_Dt; if (m_Timer >= std::chrono::minutes(5)) { diff --git a/src/Entities/ExpOrb.h b/src/Entities/ExpOrb.h index 9aac4f748..bb4c79c8e 100644 --- a/src/Entities/ExpOrb.h +++ b/src/Entities/ExpOrb.h @@ -12,7 +12,7 @@ class cExpOrb : public cEntity { typedef cEntity super; - + public: // tolua_end @@ -39,7 +39,7 @@ public: protected: int m_Reward; - + /** The number of ticks that the entity has existed / timer between collect and destroy; in msec */ std::chrono::milliseconds m_Timer; } ; // tolua_export diff --git a/src/Entities/FallingBlock.cpp b/src/Entities/FallingBlock.cpp index bae13ea66..be98ba44b 100644 --- a/src/Entities/FallingBlock.cpp +++ b/src/Entities/FallingBlock.cpp @@ -36,11 +36,11 @@ void cFallingBlock::SpawnOn(cClientHandle & a_ClientHandle) void cFallingBlock::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { // GetWorld()->BroadcastTeleportEntity(*this); // Test position - + int BlockX = POSX_TOINT; int BlockY = static_cast(GetPosY() - 0.5); int BlockZ = POSZ_TOINT; - + if (BlockY < 0) { // Fallen out of this world, just continue falling until out of sight, then destroy: @@ -50,13 +50,13 @@ void cFallingBlock::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) } return; } - + if (BlockY >= cChunkDef::Height) { // Above the world, just wait for it to fall back down return; } - + BLOCKTYPE BlockBelow = a_Chunk.GetBlock(BlockX - a_Chunk.GetPosX() * cChunkDef::Width, BlockY, BlockZ - a_Chunk.GetPosZ() * cChunkDef::Width); NIBBLETYPE BelowMeta = a_Chunk.GetMeta(BlockX - a_Chunk.GetPosX() * cChunkDef::Width, BlockY, BlockZ - a_Chunk.GetPosZ() * cChunkDef::Width); if (cSandSimulator::DoesBreakFallingThrough(BlockBelow, BelowMeta)) @@ -86,7 +86,7 @@ void cFallingBlock::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) Destroy(true); return; } - + float MilliDt = a_Dt.count() * 0.001f; AddSpeedY(MilliDt * -9.8f); AddPosition(GetSpeed() * MilliDt); diff --git a/src/Entities/FallingBlock.h b/src/Entities/FallingBlock.h index 0027bfa2a..3e80564e5 100644 --- a/src/Entities/FallingBlock.h +++ b/src/Entities/FallingBlock.h @@ -18,7 +18,7 @@ class cFallingBlock : public cEntity { typedef cEntity super; - + public: CLASS_PROTODEF(cFallingBlock) @@ -27,11 +27,11 @@ public: BLOCKTYPE GetBlockType(void) const { return m_BlockType; } NIBBLETYPE GetBlockMeta(void) const { return m_BlockMeta; } - + // cEntity overrides: virtual void SpawnOn(cClientHandle & a_ClientHandle) override; virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; - + private: BLOCKTYPE m_BlockType; NIBBLETYPE m_BlockMeta; diff --git a/src/Entities/FireChargeEntity.h b/src/Entities/FireChargeEntity.h index 25f04cb7c..e17b25903 100644 --- a/src/Entities/FireChargeEntity.h +++ b/src/Entities/FireChargeEntity.h @@ -21,23 +21,23 @@ class cFireChargeEntity : public cProjectileEntity { typedef cProjectileEntity super; - + public: - + // tolua_end - + CLASS_PROTODEF(cFireChargeEntity) - + cFireChargeEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed); - + protected: - + void Explode(Vector3i a_Block); - + // cProjectileEntity overrides: virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override; virtual void OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) override; - + } ; // tolua_export diff --git a/src/Entities/FireworkEntity.cpp b/src/Entities/FireworkEntity.cpp index 89f69f113..552549b7c 100644 --- a/src/Entities/FireworkEntity.cpp +++ b/src/Entities/FireworkEntity.cpp @@ -26,14 +26,14 @@ void cFireworkEntity::HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_C int RelX = POSX_TOINT - a_Chunk.GetPosX() * cChunkDef::Width; int RelZ = POSZ_TOINT - a_Chunk.GetPosZ() * cChunkDef::Width; int PosY = POSY_TOINT; - + if ((PosY < 0) || (PosY >= cChunkDef::Height)) { AddSpeedY(1); AddPosition(GetSpeed() * (static_cast(a_Dt.count()) / 1000)); return; } - + if (m_IsInGround) { if (a_Chunk.GetBlock(RelX, POSY_TOINT + 1, RelZ) == E_BLOCK_AIR) @@ -53,7 +53,7 @@ void cFireworkEntity::HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_C return; } } - + AddSpeedY(1); AddPosition(GetSpeed() * (static_cast(a_Dt.count()) / 1000)); } @@ -65,7 +65,7 @@ void cFireworkEntity::HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_C void cFireworkEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { super::Tick(a_Dt, a_Chunk); - + if (m_TicksToExplosion <= 0) { // TODO: Notify the plugins @@ -73,6 +73,6 @@ void cFireworkEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) Destroy(); return; } - + m_TicksToExplosion -= 1; } diff --git a/src/Entities/FireworkEntity.h b/src/Entities/FireworkEntity.h index c0a38a943..228960fb1 100644 --- a/src/Entities/FireworkEntity.h +++ b/src/Entities/FireworkEntity.h @@ -21,13 +21,13 @@ class cFireworkEntity : public cProjectileEntity { typedef cProjectileEntity super; - + public: - + // tolua_end - + CLASS_PROTODEF(cFireworkEntity) - + cFireworkEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const cItem & a_Item); // tolua_begin @@ -45,18 +45,18 @@ public: void SetTicksToExplosion(int a_TicksToExplosion) { m_TicksToExplosion = a_TicksToExplosion; } // tolua_end - + protected: - + // cProjectileEntity overrides: virtual void HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; - + private: - + int m_TicksToExplosion; cItem m_FireworkItem; - + }; // tolua_export diff --git a/src/Entities/Floater.cpp b/src/Entities/Floater.cpp index 0b96f12df..b405c5f65 100644 --- a/src/Entities/Floater.cpp +++ b/src/Entities/Floater.cpp @@ -49,7 +49,7 @@ public: m_MinCoeff = LineCoeff; m_HitEntity = a_Entity; } - + // Don't break the enumeration, we want all the entities return false; } @@ -91,7 +91,7 @@ public: m_EntityExists = true; return false; } - + bool DoesExist(void) const { return m_EntityExists; } protected: bool m_EntityExists; @@ -153,7 +153,7 @@ void cFloater::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) m_ParticlePos = (m_ParticlePos + (GetPosition() - m_ParticlePos) / 6); m_World->GetBroadcaster().BroadcastParticleEffect("splash", static_cast(m_ParticlePos), Vector3f{}, 0, 15); } - + m_CountDownTime--; if (m_World->GetHeight(POSX_TOINT, POSZ_TOINT) == POSY_TOINT) { @@ -186,7 +186,7 @@ void cFloater::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) if ((GetSpeed().Length() > 4) && (m_AttachedMobID == cEntity::INVALID_ID)) { cFloaterEntityCollisionCallback Callback(this, GetPosition(), GetPosition() + GetSpeed() / 20); - + a_Chunk.ForEachEntity(Callback); if (Callback.HasHit()) { diff --git a/src/Entities/Floater.h b/src/Entities/Floater.h index e7818c915..89ee8cc08 100644 --- a/src/Entities/Floater.h +++ b/src/Entities/Floater.h @@ -12,7 +12,7 @@ class cFloater : public cEntity { typedef cEntity super; - + public: // tolua_end @@ -22,7 +22,7 @@ public: virtual void SpawnOn(cClientHandle & a_Client) override; virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; - + // tolua_begin bool CanPickup(void) const { return m_CanPickupItem; } UInt32 GetOwnerID(void) const { return m_PlayerID; } diff --git a/src/Entities/GhastFireballEntity.h b/src/Entities/GhastFireballEntity.h index dc136dfc2..620efd9e6 100644 --- a/src/Entities/GhastFireballEntity.h +++ b/src/Entities/GhastFireballEntity.h @@ -21,25 +21,25 @@ class cGhastFireballEntity : public cProjectileEntity { typedef cProjectileEntity super; - + public: - + // tolua_end - + CLASS_PROTODEF(cGhastFireballEntity) - + cGhastFireballEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed); - + protected: - + void Explode(Vector3i a_Block); - + // cProjectileEntity overrides: virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override; virtual void OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) override; - + // TODO: Deflecting the fireballs by arrow- or sword- hits - + } ; // tolua_export diff --git a/src/Entities/HangingEntity.h b/src/Entities/HangingEntity.h index 003c22082..113d195f9 100644 --- a/src/Entities/HangingEntity.h +++ b/src/Entities/HangingEntity.h @@ -20,7 +20,7 @@ public: CLASS_PROTODEF(cHangingEntity) cHangingEntity(eEntityType a_EntityType, eBlockFace a_BlockFace, double a_X, double a_Y, double a_Z); - + // tolua_begin /** Returns the direction in which the entity is facing. */ diff --git a/src/Entities/Minecart.cpp b/src/Entities/Minecart.cpp index 7274a7a41..9e91eec59 100644 --- a/src/Entities/Minecart.cpp +++ b/src/Entities/Minecart.cpp @@ -129,7 +129,7 @@ void cMinecart::HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) BroadcastMovementUpdate(); return; } - + int RelPosX = POSX_TOINT - a_Chunk.GetPosX() * cChunkDef::Width; int RelPosZ = POSZ_TOINT - a_Chunk.GetPosZ() * cChunkDef::Width; cChunk * Chunk = a_Chunk.GetRelNeighborChunkAdjustCoords(RelPosX, RelPosZ); @@ -199,7 +199,7 @@ void cMinecart::HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) m_bIsOnDetectorRail = true; m_DetectorRailPosition = Vector3i(POSX_TOINT, POSY_TOINT, POSZ_TOINT); } - + // Broadcast positioning changes to client BroadcastMovementUpdate(); } @@ -214,7 +214,7 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, std::chrono::millisecon NOTE: Please bear in mind that taking away from negatives make them even more negative, adding to negatives make them positive, etc. */ - + switch (a_RailMeta) { case E_META_RAIL_ZM_ZP: // NORTHSOUTH @@ -230,7 +230,7 @@ void cMinecart::HandleRailPhysics(NIBBLETYPE a_RailMeta, std::chrono::millisecon { return; } - + if (GetSpeedZ() != NO_SPEED) // Don't do anything if cart is stationary { if (GetSpeedZ() > 0) @@ -440,7 +440,7 @@ void cMinecart::HandlePoweredRailPhysics(NIBBLETYPE a_RailMeta) { return; } - + if (GetSpeedZ() != NO_SPEED) { if (GetSpeedZ() > NO_SPEED) @@ -1022,7 +1022,7 @@ bool cMinecart::DoTakeDamage(TakeDamageInfo & TDI) if (GetHealth() <= 0) { Destroy(); - + cItems Drops; switch (m_Payload) { @@ -1052,7 +1052,7 @@ bool cMinecart::DoTakeDamage(TakeDamageInfo & TDI) break; } } - + m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ()); } return true; @@ -1100,17 +1100,17 @@ void cRideableMinecart::OnRightClicked(cPlayer & a_Player) a_Player.Detach(); return; } - + if (m_Attachee->IsPlayer()) { // Another player is already sitting in here, cannot attach return; } - + // Detach whatever is sitting in this minecart now: m_Attachee->Detach(); } - + // Attach the player to this minecart a_Player.AttachTo(this); } diff --git a/src/Entities/Minecart.h b/src/Entities/Minecart.h index 1ae4e1359..e48df8fda 100644 --- a/src/Entities/Minecart.h +++ b/src/Entities/Minecart.h @@ -21,10 +21,10 @@ class cMinecart : public cEntity { typedef cEntity super; - + public: CLASS_PROTODEF(cMinecart) - + /** Minecart payload, values correspond to packet subtype */ enum ePayload { @@ -35,22 +35,22 @@ public: mpHopper = 5, // Minecart-with-hopper, can be hopper // TODO: Spawner minecarts, (and possibly any block in a minecart with NBT editing) } ; - + // cEntity overrides: virtual void SpawnOn(cClientHandle & a_ClientHandle) override; virtual void HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; virtual bool DoTakeDamage(TakeDamageInfo & TDI) override; virtual void Destroyed() override; - + int LastDamage(void) const { return m_LastDamage; } ePayload GetPayload(void) const { return m_Payload; } - + protected: ePayload m_Payload; int m_LastDamage; Vector3i m_DetectorRailPosition; bool m_bIsOnDetectorRail; - + cMinecart(ePayload a_Payload, double a_X, double a_Y, double a_Z); /** Handles physics on normal rails @@ -88,10 +88,10 @@ class cRideableMinecart : public cMinecart { typedef cMinecart super; - + public: CLASS_PROTODEF(cRideableMinecart) - + cRideableMinecart(double a_X, double a_Y, double a_Z, const cItem & a_Content, int a_Height); const cItem & GetContent(void) const {return m_Content;} @@ -114,10 +114,10 @@ class cMinecartWithChest : public cEntityWindowOwner { typedef cMinecart super; - + public: CLASS_PROTODEF(cMinecartWithChest) - + cMinecartWithChest(double a_X, double a_Y, double a_Z); enum @@ -125,7 +125,7 @@ public: ContentsHeight = 3, ContentsWidth = 9, }; - + const cItem & GetSlot(int a_Idx) const { return m_Contents.GetSlot(a_Idx); } void SetSlot(int a_Idx, const cItem & a_Item) { m_Contents.SetSlot(a_Idx, a_Item); } @@ -149,7 +149,7 @@ protected: m_World->MarkChunkDirty(GetChunkX(), GetChunkZ()); } } - + // cEntity overrides: virtual void OnRightClicked(cPlayer & a_Player) override; } ; @@ -162,12 +162,12 @@ class cMinecartWithFurnace : public cMinecart { typedef cMinecart super; - + public: CLASS_PROTODEF(cMinecartWithFurnace) - + cMinecartWithFurnace(double a_X, double a_Y, double a_Z); - + // cEntity overrides: virtual void OnRightClicked(cPlayer & a_Player) override; virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; @@ -194,10 +194,10 @@ class cMinecartWithTNT : public cMinecart { typedef cMinecart super; - + public: CLASS_PROTODEF(cMinecartWithTNT) - + cMinecartWithTNT(double a_X, double a_Y, double a_Z); } ; @@ -209,9 +209,9 @@ class cMinecartWithHopper : public cMinecart { typedef cMinecart super; - + public: CLASS_PROTODEF(cMinecartWithHopper) - + cMinecartWithHopper(double a_X, double a_Y, double a_Z); } ; diff --git a/src/Entities/Pickup.cpp b/src/Entities/Pickup.cpp index e4576a8f2..c2bcf3960 100644 --- a/src/Entities/Pickup.cpp +++ b/src/Entities/Pickup.cpp @@ -117,7 +117,7 @@ void cPickup::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) BroadcastMovementUpdate(); // Notify clients of position m_Timer += a_Dt; - + if (!m_bCollected) { int BlockY = POSY_TOINT; @@ -128,10 +128,10 @@ void cPickup::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { // Position might have changed due to physics. So we have to make sure we have the correct chunk. GET_AND_VERIFY_CURRENT_CHUNK(CurrentChunk, BlockX, BlockZ) - + int RelBlockX = BlockX - (CurrentChunk->GetPosX() * cChunkDef::Width); int RelBlockZ = BlockZ - (CurrentChunk->GetPosZ() * cChunkDef::Width); - + // If the pickup is on the bottommost block position, make it think the void is made of air: (#131) BLOCKTYPE BlockBelow = (BlockY > 0) ? CurrentChunk->GetBlock(RelBlockX, BlockY - 1, RelBlockZ) : E_BLOCK_AIR; BLOCKTYPE BlockIn = CurrentChunk->GetBlock(RelBlockX, BlockY, RelBlockZ); @@ -199,7 +199,7 @@ bool cPickup::CollectedBy(cPlayer & a_Dest) // LOG("Pickup %d cannot be collected by \"%s\", because it has already been collected.", m_UniqueID, a_Dest->GetName().c_str()); return false; // It's already collected! } - + // Two seconds if player created the pickup (vomiting), half a second if anything else if (m_Timer < (m_bIsPlayerCreated ? std::chrono::seconds(2) : std::chrono::milliseconds(500))) { diff --git a/src/Entities/SplashPotionEntity.cpp b/src/Entities/SplashPotionEntity.cpp index ba806e50e..e61df0525 100644 --- a/src/Entities/SplashPotionEntity.cpp +++ b/src/Entities/SplashPotionEntity.cpp @@ -34,7 +34,7 @@ public: m_EntityEffect(a_EntityEffect) { } - + /** Called by cWorld::ForEachEntity(), adds the stored entity effect to the entity, if it is close enough. */ virtual bool Item(cEntity * a_Entity) override { @@ -55,7 +55,7 @@ public: // TODO: better equation double Reduction = -0.25 * SplashDistance + 1.0; Reduction = std::max(Reduction, 0.0); - + static_cast(a_Entity)->AddEntityEffect(m_EntityEffectType, m_EntityEffect.GetDuration(), m_EntityEffect.GetIntensity(), Reduction); return false; } @@ -65,7 +65,7 @@ private: cEntityEffect::eType m_EntityEffectType; const cEntityEffect & m_EntityEffect; }; - + @@ -120,7 +120,7 @@ void cSplashPotionEntity::Splash(const Vector3d & a_HitPos) { cSplashPotionCallback Callback(a_HitPos, m_EntityEffectType, m_EntityEffect); m_World->ForEachEntity(Callback); - + m_World->BroadcastSoundParticleEffect( EffectID::PARTICLE_SPLASH_POTION, FloorC(a_HitPos.x), diff --git a/src/Entities/SplashPotionEntity.h b/src/Entities/SplashPotionEntity.h index 264dc0eb9..c9831ce88 100644 --- a/src/Entities/SplashPotionEntity.h +++ b/src/Entities/SplashPotionEntity.h @@ -23,37 +23,37 @@ class cSplashPotionEntity : public cProjectileEntity { typedef cProjectileEntity super; - + public: - + // tolua_end - + CLASS_PROTODEF(cSplashPotionEntity) - + cSplashPotionEntity( cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed, const cItem & a_Item ); - + // tolua_begin cEntityEffect::eType GetEntityEffectType(void) const { return m_EntityEffectType; } cEntityEffect GetEntityEffect(void) const { return m_EntityEffect; } int GetPotionColor(void) const { return m_PotionColor; } - + void SetEntityEffectType(cEntityEffect::eType a_EntityEffectType) { m_EntityEffectType = a_EntityEffectType; } void SetEntityEffect(cEntityEffect a_EntityEffect) { m_EntityEffect = a_EntityEffect; } void SetPotionColor(int a_PotionColor) { m_PotionColor = a_PotionColor; } // tolua_end - + protected: - + cEntityEffect::eType m_EntityEffectType; cEntityEffect m_EntityEffect; int m_PotionColor; - + // cProjectileEntity overrides: virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override; @@ -74,11 +74,11 @@ protected: super::Tick(a_Dt, a_Chunk); } } - + /** Splashes the potion, fires its particle effects and sounds @param a_HitPos The position where the potion will splash */ void Splash(const Vector3d & a_HitPos); - + virtual void SpawnOn(cClientHandle & a_Client) override; private: diff --git a/src/Entities/TNTEntity.cpp b/src/Entities/TNTEntity.cpp index d849bd4c9..4d533ebe4 100644 --- a/src/Entities/TNTEntity.cpp +++ b/src/Entities/TNTEntity.cpp @@ -58,7 +58,7 @@ void cTNTEntity::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { super::Tick(a_Dt, a_Chunk); BroadcastMovementUpdate(); - + m_FuseTicks -= 1; if (m_FuseTicks <= 0) { diff --git a/src/Entities/TNTEntity.h b/src/Entities/TNTEntity.h index 9f894338e..5f1faa6b4 100644 --- a/src/Entities/TNTEntity.h +++ b/src/Entities/TNTEntity.h @@ -11,31 +11,31 @@ class cTNTEntity : public cEntity { typedef cEntity super; - + public: // tolua_end CLASS_PROTODEF(cTNTEntity) cTNTEntity(double a_X, double a_Y, double a_Z, int a_FuseTicks = 80); cTNTEntity(const Vector3d & a_Pos, int a_FuseTicks = 80); - + // cEntity overrides: virtual void SpawnOn(cClientHandle & a_ClientHandle) override; virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; - + // tolua_begin - + /** Explode the tnt */ void Explode(void); - + /** Returns the fuse ticks until the tnt will explode */ int GetFuseTicks(void) const { return m_FuseTicks; } - + /** Set the fuse ticks until the tnt will explode */ void SetFuseTicks(int a_FuseTicks) { m_FuseTicks = a_FuseTicks; } - + // tolua_end - + protected: int m_FuseTicks; ///< How much ticks is left, while the tnt will explode }; // tolua_export diff --git a/src/Entities/ThrownEggEntity.h b/src/Entities/ThrownEggEntity.h index 620927c5d..f20cd41a1 100644 --- a/src/Entities/ThrownEggEntity.h +++ b/src/Entities/ThrownEggEntity.h @@ -21,22 +21,22 @@ class cThrownEggEntity : public cProjectileEntity { typedef cProjectileEntity super; - + public: - + // tolua_end - + CLASS_PROTODEF(cThrownEggEntity) - + cThrownEggEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed); - + protected: - + // cProjectileEntity overrides: virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override; virtual void OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) override; virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; - + // Randomly decides whether to spawn a chicken where the egg lands. void TrySpawnChicken(const Vector3d & a_HitPos); @@ -44,7 +44,7 @@ private: /** Time in ticks to wait for the hit animation to begin before destroying */ int m_DestroyTimer; - + } ; // tolua_export diff --git a/src/Entities/ThrownEnderPearlEntity.cpp b/src/Entities/ThrownEnderPearlEntity.cpp index 12d826042..4b2e2f9ff 100644 --- a/src/Entities/ThrownEnderPearlEntity.cpp +++ b/src/Entities/ThrownEnderPearlEntity.cpp @@ -23,7 +23,7 @@ void cThrownEnderPearlEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockF { // TODO: Tweak a_HitPos based on block face. TeleportCreator(a_HitPos); - + m_DestroyTimer = 2; } @@ -35,10 +35,10 @@ void cThrownEnderPearlEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d { int TotalDamage = 0; // TODO: If entity is Ender Crystal, destroy it - + TeleportCreator(a_HitPos); a_EntityHit.TakeDamage(dtRangedAttack, this, TotalDamage, 1); - + m_DestroyTimer = 5; } diff --git a/src/Entities/ThrownEnderPearlEntity.h b/src/Entities/ThrownEnderPearlEntity.h index 94f3ab5cb..03d54e911 100644 --- a/src/Entities/ThrownEnderPearlEntity.h +++ b/src/Entities/ThrownEnderPearlEntity.h @@ -21,22 +21,22 @@ class cThrownEnderPearlEntity : public cProjectileEntity { typedef cProjectileEntity super; - + public: - + // tolua_end - + CLASS_PROTODEF(cThrownEnderPearlEntity) - + cThrownEnderPearlEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed); - + protected: - + // cProjectileEntity overrides: virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override; virtual void OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) override; virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; - + /** Teleports the creator where the ender pearl lands */ void TeleportCreator(const Vector3d & a_HitPos); @@ -44,7 +44,7 @@ private: /** Time in ticks to wait for the hit animation to begin before destroying */ int m_DestroyTimer; - + } ; // tolua_export diff --git a/src/Entities/ThrownSnowballEntity.h b/src/Entities/ThrownSnowballEntity.h index 391b0c40b..d22930f8f 100644 --- a/src/Entities/ThrownSnowballEntity.h +++ b/src/Entities/ThrownSnowballEntity.h @@ -21,17 +21,17 @@ class cThrownSnowballEntity : public cProjectileEntity { typedef cProjectileEntity super; - + public: - + // tolua_end - + CLASS_PROTODEF(cThrownSnowballEntity) - + cThrownSnowballEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed); - + protected: - + // cProjectileEntity overrides: virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override; virtual void OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) override; @@ -41,7 +41,7 @@ private: /** Time in ticks to wait for the hit animation to begin before destroying */ int m_DestroyTimer; - + } ; // tolua_export diff --git a/src/Entities/WitherSkullEntity.cpp b/src/Entities/WitherSkullEntity.cpp index dc95e3edd..03385b283 100644 --- a/src/Entities/WitherSkullEntity.cpp +++ b/src/Entities/WitherSkullEntity.cpp @@ -39,10 +39,10 @@ void cWitherSkullEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_H { // TODO: If entity is Ender Crystal, destroy it a_EntityHit.TakeDamage(dtRangedAttack, this, 0, 1); - + // TODO: Explode // TODO: Apply wither effect to entity and others nearby - + Destroy(true); } diff --git a/src/Entities/WitherSkullEntity.h b/src/Entities/WitherSkullEntity.h index 43a520388..11b6fe3aa 100644 --- a/src/Entities/WitherSkullEntity.h +++ b/src/Entities/WitherSkullEntity.h @@ -21,21 +21,21 @@ class cWitherSkullEntity : public cProjectileEntity { typedef cProjectileEntity super; - + public: - + // tolua_end - + CLASS_PROTODEF(cWitherSkullEntity) - + cWitherSkullEntity(cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d & a_Speed); - + protected: - + // cProjectileEntity overrides: virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace) override; virtual void OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) override; - + } ; // tolua_export diff --git a/src/FastRandom.h b/src/FastRandom.h index 30395a293..a21da8391 100644 --- a/src/FastRandom.h +++ b/src/FastRandom.h @@ -33,10 +33,10 @@ class cFastRandom public: cFastRandom(void); - + /** Returns a random int in the range [0 .. a_Range - 1]; a_Range must be less than 1M */ int NextInt(int a_Range); - + /** Returns a random float in the range [0 .. a_Range]; a_Range must be less than 1M */ float NextFloat(float a_Range); diff --git a/src/ForEachChunkProvider.h b/src/ForEachChunkProvider.h index 7a6e8c5c6..ed9ba4ebb 100644 --- a/src/ForEachChunkProvider.h +++ b/src/ForEachChunkProvider.h @@ -25,10 +25,10 @@ class cForEachChunkProvider { public: virtual ~cForEachChunkProvider() {} - + /** Calls the callback for each chunk in the specified range. */ virtual bool ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback) = 0; - + /** Writes the block area into the specified coords. Returns true if all chunks have been processed. a_DataTypes is a bitmask of cBlockArea::baXXX constants ORed together. diff --git a/src/FurnaceRecipe.cpp b/src/FurnaceRecipe.cpp index a0c8560f1..2c20eec0f 100644 --- a/src/FurnaceRecipe.cpp +++ b/src/FurnaceRecipe.cpp @@ -61,7 +61,7 @@ void cFurnaceRecipe::ReloadRecipes(void) LOG("Could not open the furnace recipes file \"%s\". No furnace recipes are available.", FURNACE_RECIPE_FILE); return; } - + unsigned int LineNum = 0; AString ParsingLine; @@ -207,7 +207,7 @@ void cFurnaceRecipe::AddRecipeFromLine(const AString & a_Line, unsigned int a_Li bool cFurnaceRecipe::ParseItem(const AString & a_String, cItem & a_Item) { AString ItemString = a_String; - + const AStringVector & SplitAmount = StringSplit(ItemString, ","); ItemString = SplitAmount[0]; diff --git a/src/FurnaceRecipe.h b/src/FurnaceRecipe.h index 912b6aba2..0779e18a4 100644 --- a/src/FurnaceRecipe.h +++ b/src/FurnaceRecipe.h @@ -31,13 +31,13 @@ public: cItem * Out; int CookTime; ///< How long this recipe takes to smelt, in ticks }; - + /** Returns a recipe for the specified input, nullptr if no recipe found */ const cRecipe * GetRecipeFrom(const cItem & a_Ingredient) const; /** Returns true if the item is a fuel, false if not. */ bool IsFuel(const cItem & a_Item) const; - + /** Returns the amount of time that the specified fuel burns, in ticks */ int GetBurnTime(const cItem & a_Fuel) const; diff --git a/src/Generating/BioGen.cpp b/src/Generating/BioGen.cpp index ff8827511..4c58e8547 100644 --- a/src/Generating/BioGen.cpp +++ b/src/Generating/BioGen.cpp @@ -101,26 +101,26 @@ void cBioGenCache::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a } // Found it in the cache size_t Idx = m_CacheOrder[i]; - + // Move to front: for (size_t j = i; j > 0; j--) { m_CacheOrder[j] = m_CacheOrder[j - 1]; } m_CacheOrder[0] = Idx; - + // Use the cached data: memcpy(a_BiomeMap, m_CacheData[Idx].m_BiomeMap, sizeof(a_BiomeMap)); - + m_NumHits++; m_TotalChain += i; return; } // for i - cache - + // Not in the cache: m_NumMisses++; m_BioGenToCache->GenBiomes(a_ChunkX, a_ChunkZ, a_BiomeMap); - + // Insert it as the first item in the MRU order: size_t Idx = m_CacheOrder[m_CacheSize - 1]; for (size_t i = m_CacheSize - 1; i > 0; i--) @@ -346,7 +346,7 @@ void cBioGenDistortedVoronoi::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::B { int BaseZ = cChunkDef::Width * a_ChunkZ; int BaseX = cChunkDef::Width * a_ChunkX; - + // Distortions for linear interpolation: int DistortX[cChunkDef::Width + 1][cChunkDef::Width + 1]; int DistortZ[cChunkDef::Width + 1][cChunkDef::Width + 1]; @@ -354,10 +354,10 @@ void cBioGenDistortedVoronoi::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::B { Distort(BaseX + x * 4, BaseZ + z * 4, DistortX[4 * x][4 * z], DistortZ[4 * x][4 * z]); } - + LinearUpscale2DArrayInPlace(&DistortX[0][0]); LinearUpscale2DArrayInPlace(&DistortZ[0][0]); - + for (int z = 0; z < cChunkDef::Width; z++) { for (int x = 0; x < cChunkDef::Width; x++) @@ -391,7 +391,7 @@ void cBioGenDistortedVoronoi::Distort(int a_BlockX, int a_BlockZ, int & a_Distor double NoiseZ = m_Noise.CubicNoise3D(static_cast(a_BlockX / m_CellSize), static_cast(a_BlockZ / m_CellSize), 4000); NoiseZ += 0.5 * m_Noise.CubicNoise3D(2 * static_cast(a_BlockX / m_CellSize), 2 * static_cast(a_BlockZ / m_CellSize), 5000); NoiseZ += 0.08 * m_Noise.CubicNoise3D(16 * static_cast(a_BlockX / m_CellSize), 16 * static_cast(a_BlockZ / m_CellSize), 6000); - + a_DistortedX = a_BlockX + static_cast(m_CellSize * 0.5 * NoiseX); a_DistortedZ = a_BlockZ + static_cast(m_CellSize * 0.5 * NoiseZ); } @@ -450,7 +450,7 @@ void cBioGenMultiStepMap::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::Biome void cBioGenMultiStepMap::DecideOceanLandMushroom(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) { // Distorted Voronoi over 3 biomes, with mushroom having only a special occurence. - + // Prepare a distortion lookup table, by distorting a 5x5 area and using that as 1:4 zoom (linear interpolate): int BaseZ = cChunkDef::Width * a_ChunkZ; int BaseX = cChunkDef::Width * a_ChunkX; @@ -463,7 +463,7 @@ void cBioGenMultiStepMap::DecideOceanLandMushroom(int a_ChunkX, int a_ChunkZ, cC } LinearUpscale2DArrayInPlace(&DistortX[0][0]); LinearUpscale2DArrayInPlace(&DistortZ[0][0]); - + // Prepare a 9x9 area of neighboring cell seeds // (assuming that 7x7 cell area is larger than a chunk being generated) const int NEIGHBORHOOD_SIZE = 4; // How many seeds in each direction to check @@ -487,7 +487,7 @@ void cBioGenMultiStepMap::DecideOceanLandMushroom(int a_ChunkX, int a_ChunkZ, cC SeedV[xc][zc] = (((m_Noise6.IntNoise3DInt(RealCellX, RealCellX - RealCellZ + 1000, RealCellZ) / 11) % 256) > 90) ? biOcean : (biInvalidBiome); } // for z } // for x - + for (int xc = 1; xc < 2 * NEIGHBORHOOD_SIZE; xc++) for (int zc = 1; zc < 2 * NEIGHBORHOOD_SIZE; zc++) { if ( @@ -505,7 +505,7 @@ void cBioGenMultiStepMap::DecideOceanLandMushroom(int a_ChunkX, int a_ChunkZ, cC SeedV[xc][zc] = biMushroomIsland; } } - + // For each column find the nearest distorted cell and use its value as the biome: int MushroomOceanThreshold = m_OceanCellSize * m_OceanCellSize * m_MushroomIslandSize / 1024; int MushroomShoreThreshold = m_OceanCellSize * m_OceanCellSize * m_MushroomIslandSize / 2048; @@ -562,13 +562,13 @@ void cBioGenMultiStepMap::AddRivers(int a_ChunkX, int a_ChunkZ, cChunkDef::Biome // Biome already set, skip this column continue; } - + float NoiseCoordX = static_cast(a_ChunkX * cChunkDef::Width + x) / m_RiverCellSize; - + double Noise = m_Noise1.CubicNoise2D( NoiseCoordX, NoiseCoordZ); Noise += 0.5 * m_Noise3.CubicNoise2D(2 * NoiseCoordX, 2 * NoiseCoordZ); Noise += 0.1 * m_Noise5.CubicNoise2D(8 * NoiseCoordX, 8 * NoiseCoordZ); - + if ((Noise > 0) && (Noise < m_RiverWidthThreshold)) { cChunkDef::SetBiome(a_BiomeMap, x, z, biRiver); @@ -586,7 +586,7 @@ void cBioGenMultiStepMap::ApplyTemperatureHumidity(int a_ChunkX, int a_ChunkZ, c IntMap TemperatureMap; IntMap HumidityMap; BuildTemperatureHumidityMaps(a_ChunkX, a_ChunkZ, TemperatureMap, HumidityMap); - + FreezeWaterBiomes(a_BiomeMap, TemperatureMap); DecideLandBiomes(a_BiomeMap, TemperatureMap, HumidityMap); } @@ -603,7 +603,7 @@ void cBioGenMultiStepMap::Distort(int a_BlockX, int a_BlockZ, int & a_DistortedX double NoiseZ = m_Noise6.CubicNoise2D( static_cast(a_BlockX / a_CellSize), static_cast(a_BlockZ / a_CellSize)); NoiseZ += 0.5 * m_Noise5.CubicNoise2D(2 * static_cast(a_BlockX / a_CellSize), 2 * static_cast(a_BlockZ / a_CellSize)); NoiseZ += 0.1 * m_Noise4.CubicNoise2D(16 * static_cast(a_BlockX / a_CellSize), 16 * static_cast(a_BlockZ / a_CellSize)); - + a_DistortedX = a_BlockX + static_cast(a_CellSize * 0.5 * NoiseX); a_DistortedZ = a_BlockZ + static_cast(a_CellSize * 0.5 * NoiseZ); } @@ -623,7 +623,7 @@ void cBioGenMultiStepMap::BuildTemperatureHumidityMaps(int a_ChunkX, int a_Chunk for (int x = 0; x < 17; x += 8) { float NoiseCoordX = static_cast(a_ChunkX * cChunkDef::Width + x) / m_LandBiomesSize; - + double NoiseT = m_Noise1.CubicNoise2D( NoiseCoordX, NoiseCoordZ); NoiseT += 0.5 * m_Noise2.CubicNoise2D(2 * NoiseCoordX, 2 * NoiseCoordZ); NoiseT += 0.1 * m_Noise3.CubicNoise2D(8 * NoiseCoordX, 8 * NoiseCoordZ); @@ -637,7 +637,7 @@ void cBioGenMultiStepMap::BuildTemperatureHumidityMaps(int a_ChunkX, int a_Chunk } // for z LinearUpscale2DArrayInPlace<17, 17, 8, 8>(TemperatureMap); LinearUpscale2DArrayInPlace<17, 17, 8, 8>(HumidityMap); - + // Re-map into integral values in [0 .. 255] range: for (size_t idx = 0; idx < ARRAYCOUNT(a_TemperatureMap); idx++) { @@ -756,7 +756,7 @@ void cBioGenTwoLevel::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap { int BaseZ = cChunkDef::Width * a_ChunkZ; int BaseX = cChunkDef::Width * a_ChunkX; - + // Distortions for linear interpolation: int DistortX[cChunkDef::Width + 1][cChunkDef::Width + 1]; int DistortZ[cChunkDef::Width + 1][cChunkDef::Width + 1]; @@ -770,14 +770,14 @@ void cBioGenTwoLevel::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap double NoiseZ = m_AmpZ1 * m_Noise4.CubicNoise2D(BlockX * m_FreqZ1, BlockZ * m_FreqZ1); NoiseZ += m_AmpZ2 * m_Noise5.CubicNoise2D(BlockX * m_FreqZ2, BlockZ * m_FreqZ2); NoiseZ += m_AmpZ3 * m_Noise6.CubicNoise2D(BlockX * m_FreqZ3, BlockZ * m_FreqZ3); - + DistortX[4 * x][4 * z] = static_cast(BlockX + NoiseX); DistortZ[4 * x][4 * z] = static_cast(BlockZ + NoiseZ); } - + LinearUpscale2DArrayInPlace(&DistortX[0][0]); LinearUpscale2DArrayInPlace(&DistortZ[0][0]); - + // Apply distortion to each block coord, then query the voronoi maps for biome group and biome index and choose biome based on that: for (int z = 0; z < cChunkDef::Width; z++) { @@ -804,7 +804,7 @@ EMCSBiome cBioGenTwoLevel::SelectBiome(int a_BiomeGroup, size_t a_BiomeIdx, int EMCSBiome InnerBiome; EMCSBiome OuterBiome; } ; - + static BiomeLevels bgOcean[] = { { biOcean, biOcean, }, @@ -941,7 +941,7 @@ public: cBioGenGrown(int a_Seed) { auto FinalRivers = - + std::make_shared>(a_Seed + 12) | MakeIntGen>(a_Seed + 11) | MakeIntGen>(a_Seed + 6) diff --git a/src/Generating/BioGen.h b/src/Generating/BioGen.h index a5b8cc7e7..576c6b83d 100644 --- a/src/Generating/BioGen.h +++ b/src/Generating/BioGen.h @@ -27,7 +27,7 @@ class cBioGenConstant : { public: cBioGenConstant(void) : m_Biome(biPlains) {} - + protected: EMCSBiome m_Biome; @@ -46,32 +46,32 @@ class cBioGenCache : public cBiomeGen { typedef cBiomeGen super; - + public: cBioGenCache(cBiomeGenPtr a_BioGenToCache, size_t a_CacheSize); virtual ~cBioGenCache(); - + protected: cBiomeGenPtr m_BioGenToCache; - + struct sCacheData { int m_ChunkX; int m_ChunkZ; cChunkDef::BiomeMap m_BiomeMap; } ; - + // To avoid moving large amounts of data for the MRU behavior, we MRU-ize indices to an array of the actual data size_t m_CacheSize; size_t * m_CacheOrder; // MRU-ized order, indices into m_CacheData array sCacheData * m_CacheData; // m_CacheData[m_CacheOrder[0]] is the most recently used - + // Cache statistics size_t m_NumHits; size_t m_NumMisses; size_t m_TotalChain; // Number of cache items walked to get to a hit (only added for hits) - + virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; virtual void InitializeBiomeGen(cIniFile & a_IniFile) override; } ; @@ -117,13 +117,13 @@ class cBiomeGenList : public cBiomeGen { typedef cBiomeGen super; - + protected: // List of biomes that the generator is allowed to generate: typedef std::vector EMCSBiomes; EMCSBiomes m_Biomes; int m_BiomesCount; // Pulled out of m_Biomes for faster access - + /** Parses the INI file setting string into m_Biomes. */ void InitializeBiomes(const AString & a_Biomes); } ; @@ -136,10 +136,10 @@ class cBioGenCheckerboard : public cBiomeGenList { typedef cBiomeGenList super; - + protected: int m_BiomeSize; - + // cBiomeGen overrides: virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; virtual void InitializeBiomeGen(cIniFile & a_IniFile) override; @@ -153,20 +153,20 @@ class cBioGenVoronoi : public cBiomeGenList { typedef cBiomeGenList super; - + public: cBioGenVoronoi(int a_Seed) : m_Voronoi(a_Seed) { } - + protected: cVoronoiMap m_Voronoi; - + // cBiomeGen overrides: virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; virtual void InitializeBiomeGen(cIniFile & a_IniFile) override; - + EMCSBiome VoronoiBiome(int a_BlockX, int a_BlockZ); } ; @@ -178,7 +178,7 @@ class cBioGenDistortedVoronoi : public cBiomeGenList { typedef cBiomeGenList super; - + public: cBioGenDistortedVoronoi(int a_Seed) : m_Noise(a_Seed), @@ -190,17 +190,17 @@ public: protected: /** Noise used for the distortion */ cNoise m_Noise; - + /** The underlying Voronoi map of the biomes */ cVoronoiMap m_Voronoi; - + /** Size of the Voronoi cells, also used for distortion amplitude */ int m_CellSize; - + // cBiomeGen overrides: virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; virtual void InitializeBiomeGen(cIniFile & a_IniFile) override; - + /** Distorts the coords using a Perlin-like noise */ void Distort(int a_BlockX, int a_BlockZ, int & a_DistortedX, int & a_DistortedZ); } ; @@ -213,10 +213,10 @@ class cBioGenMultiStepMap : public cBiomeGen { typedef cBiomeGen super; - + public: cBioGenMultiStepMap(int a_Seed); - + protected: // Noises used for composing the perlin-noise: cNoise m_Noise1; @@ -225,42 +225,42 @@ protected: cNoise m_Noise4; cNoise m_Noise5; cNoise m_Noise6; - + int m_Seed; int m_OceanCellSize; int m_MushroomIslandSize; int m_RiverCellSize; double m_RiverWidthThreshold; float m_LandBiomesSize; - + typedef int IntMap[17 * 17]; // x + 17 * z, expected trimmed into [0..255] range typedef double DblMap[17 * 17]; // x + 17 * z, expected trimmed into [0..1] range - + // cBiomeGen overrides: virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; virtual void InitializeBiomeGen(cIniFile & a_IniFile) override; - + /** Step 1: Decides between ocean, land and mushroom, using a DistVoronoi with special conditions and post-processing for mushroom islands Sets biomes to biOcean, -1 (i.e. land), biMushroomIsland or biMushroomShore. */ void DecideOceanLandMushroom(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap); - + /** Step 2: Add rivers to the land Flips some "-1" biomes into biRiver. */ void AddRivers(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap); - + /** Step 3: Decide land biomes using a temperature / humidity map; freeze ocean / river in low temperatures. Flips all remaining "-1" biomes into land biomes. Also flips some biOcean and biRiver into biFrozenOcean, biFrozenRiver, based on temp map. */ void ApplyTemperatureHumidity(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap); - + /** Distorts the coords using a Perlin-like noise, with a specified cell-size */ void Distort(int a_BlockX, int a_BlockZ, int & a_DistortedX, int & a_DistortedZ, int a_CellSize); - + /** Builds two Perlin-noise maps, one for temperature, the other for humidity. Trims both into [0..255] range */ void BuildTemperatureHumidityMaps(int a_ChunkX, int a_ChunkZ, IntMap & a_TemperatureMap, IntMap & a_HumidityMap); - + /** Flips all remaining "-1" biomes into land biomes using the two maps */ void DecideLandBiomes(cChunkDef::BiomeMap & a_BiomeMap, const IntMap & a_TemperatureMap, const IntMap & a_HumidityMap); - + /** Flips biOcean and biRiver into biFrozenOcean and biFrozenRiver if the temperature is too low */ void FreezeWaterBiomes(cChunkDef::BiomeMap & a_BiomeMap, const IntMap & a_TemperatureMap); } ; @@ -273,17 +273,17 @@ class cBioGenTwoLevel : public cBiomeGen { typedef cBiomeGen super; - + public: cBioGenTwoLevel(int a_Seed); - + protected: /** The Voronoi map that decides the groups of biomes */ cVoronoiMap m_VoronoiLarge; - + /** The Voronoi map that decides biomes inside individual biome groups */ cVoronoiMap m_VoronoiSmall; - + // The noises used for the distortion: cNoise m_Noise1; cNoise m_Noise2; diff --git a/src/Generating/Caves.h b/src/Generating/Caves.h index 691ef3e62..af5e3b5eb 100644 --- a/src/Generating/Caves.h +++ b/src/Generating/Caves.h @@ -23,11 +23,11 @@ class cStructGenMarbleCaves : { public: cStructGenMarbleCaves(int a_Seed) : m_Seed(a_Seed) {} - + protected: int m_Seed; - + // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; @@ -47,13 +47,13 @@ public: m_Threshold(a_Threshold) { } - + protected: cNoise m_Noise1; cNoise m_Noise2; int m_Seed; float m_Threshold; - + // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; @@ -75,7 +75,7 @@ public: m_Grid(a_Grid) { } - + protected: class cCaveSystem; // fwd: Caves.cpp diff --git a/src/Generating/ChunkDesc.cpp b/src/Generating/ChunkDesc.cpp index 07855b1d0..fcbebf1ca 100644 --- a/src/Generating/ChunkDesc.cpp +++ b/src/Generating/ChunkDesc.cpp @@ -185,7 +185,7 @@ void cChunkDesc::GetShapeFromHeight(Shape & a_Shape) const { a_Shape[y + x * 256 + z * 16 * 256] = 1; } - + for (int y = height + 1; y < cChunkDef::Height; y++) { a_Shape[y + x * 256 + z * 16 * 256] = 0; @@ -590,7 +590,7 @@ cBlockEntity * cChunkDesc::GetBlockEntity(int a_RelX, int a_RelY, int a_RelZ) return *itr; } } // for itr - m_BlockEntities[] - + // The block entity is not created yet, try to create it and add to list: cBlockEntity * be = cBlockEntity::CreateByBlockType(GetBlockType(a_RelX, a_RelY, a_RelZ), GetBlockMeta(a_RelX, a_RelY, a_RelZ), AbsX, a_RelY, AbsZ); if (be == nullptr) diff --git a/src/Generating/ChunkDesc.h b/src/Generating/ChunkDesc.h index 1033242f8..aa689fcd6 100644 --- a/src/Generating/ChunkDesc.h +++ b/src/Generating/ChunkDesc.h @@ -35,28 +35,28 @@ public: 1 = solid Indexed as [y + 256 * x + 256 * 16 * z]. */ typedef Byte Shape[256 * 16 * 16]; - + /** Uncompressed block metas, 1 meta per byte */ typedef NIBBLETYPE BlockNibbleBytes[cChunkDef::NumBlocks]; - + cChunkDesc(int a_ChunkX, int a_ChunkZ); ~cChunkDesc(); void SetChunkCoords(int a_ChunkX, int a_ChunkZ); - + // tolua_begin int GetChunkX(void) const { return m_ChunkX; } int GetChunkZ(void) const { return m_ChunkZ; } - + void FillBlocks(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); void SetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); void GetBlockTypeMeta(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); void SetBlockType(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType); BLOCKTYPE GetBlockType(int a_RelX, int a_RelY, int a_RelZ); - + void SetBlockMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_BlockMeta); NIBBLETYPE GetBlockMeta(int a_RelX, int a_RelY, int a_RelZ); @@ -100,7 +100,7 @@ public: /** Returns the minimum height value in the heightmap. */ HEIGHTTYPE GetMinHeight(void) const; - + /** Fills the relative cuboid with specified block; allows cuboid out of range of this chunk */ void FillRelCuboid( int a_MinX, int a_MaxX, @@ -108,7 +108,7 @@ public: int a_MinZ, int a_MaxZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta ); - + /** Fills the relative cuboid with specified block; allows cuboid out of range of this chunk */ void FillRelCuboid(const cCuboid & a_RelCuboid, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { @@ -119,7 +119,7 @@ public: a_BlockType, a_BlockMeta ); } - + /** Replaces the specified src blocks in the cuboid by the dst blocks; allows cuboid out of range of this chunk */ void ReplaceRelCuboid( int a_MinX, int a_MaxX, @@ -128,7 +128,7 @@ public: BLOCKTYPE a_SrcType, NIBBLETYPE a_SrcMeta, BLOCKTYPE a_DstType, NIBBLETYPE a_DstMeta ); - + /** Replaces the specified src blocks in the cuboid by the dst blocks; allows cuboid out of range of this chunk */ void ReplaceRelCuboid( const cCuboid & a_RelCuboid, @@ -152,7 +152,7 @@ public: int a_MinZ, int a_MaxZ, BLOCKTYPE a_DstType, NIBBLETYPE a_DstMeta ); - + /** Replaces the blocks in the cuboid by the dst blocks if they are considered non-floor (air, water); allows cuboid out of range of this chunk */ void FloorRelCuboid( const cCuboid & a_RelCuboid, @@ -166,7 +166,7 @@ public: a_DstType, a_DstMeta ); } - + /** Fills the relative cuboid with specified block with a random chance; allows cuboid out of range of this chunk */ void RandomFillRelCuboid( int a_MinX, int a_MaxX, @@ -175,7 +175,7 @@ public: BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, int a_RandomSeed, int a_ChanceOutOf10k ); - + /** Fills the relative cuboid with specified block with a random chance; allows cuboid out of range of this chunk */ void RandomFillRelCuboid( const cCuboid & a_RelCuboid, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, @@ -190,18 +190,18 @@ public: a_RandomSeed, a_ChanceOutOf10k ); } - + /** Returns the block entity at the specified coords. If there is no block entity at those coords, tries to create one, based on the block type If the blocktype doesn't support a block entity, returns nullptr. */ cBlockEntity * GetBlockEntity(int a_RelX, int a_RelY, int a_RelZ); - + /** Updates the heightmap to match the current contents. Useful for plugins when writing custom block areas into the chunk */ void UpdateHeightmap(void); - + // tolua_end - + // Accessors used by cChunkGenerator::Generator descendants: inline cChunkDef::BiomeMap & GetBiomeMap (void) { return m_BiomeMap; } inline cChunkDef::BlockTypes & GetBlockTypes (void) { return *(reinterpret_cast(m_BlockArea.GetBlockTypes())); } @@ -211,19 +211,19 @@ public: inline cChunkDef::HeightMap & GetHeightMap (void) { return m_HeightMap; } inline cEntityList & GetEntities (void) { return m_Entities; } inline cBlockEntityList & GetBlockEntities (void) { return m_BlockEntities; } - + /** Compresses the metas from the BlockArea format (1 meta per byte) into regular format (2 metas per byte) */ void CompressBlockMetas(cChunkDef::BlockNibbles & a_DestMetas); - + #ifdef _DEBUG /** Verifies that the heightmap corresponds to blocktype contents; if not, asserts on that column */ void VerifyHeightmap(void); #endif // _DEBUG - + private: int m_ChunkX; int m_ChunkZ; - + cChunkDef::BiomeMap m_BiomeMap; cBlockArea m_BlockArea; cChunkDef::HeightMap m_HeightMap; diff --git a/src/Generating/ChunkGenerator.cpp b/src/Generating/ChunkGenerator.cpp index bfa3344b9..50b77363a 100644 --- a/src/Generating/ChunkGenerator.cpp +++ b/src/Generating/ChunkGenerator.cpp @@ -64,7 +64,7 @@ bool cChunkGenerator::Start(cPluginInterface & a_PluginInterface, cChunkSink & a LOGINFO("Chosen a new random seed for world: %d", m_Seed); a_IniFile.SetValueI("Seed", "Seed", m_Seed); } - + // Get the generator engine based on the INI file settings: AString GeneratorName = a_IniFile.GetValueSet("Generator", "Generator", "Composable"); if (NoCaseCompare(GeneratorName, "Noise3D") == 0) diff --git a/src/Generating/ChunkGenerator.h b/src/Generating/ChunkGenerator.h index b7968356f..5c778fda4 100644 --- a/src/Generating/ChunkGenerator.h +++ b/src/Generating/ChunkGenerator.h @@ -37,7 +37,7 @@ class cChunkGenerator : cIsThread { typedef cIsThread super; - + public: /** The interface that a class has to implement to become a generator */ class cGenerator @@ -48,7 +48,7 @@ public: /** Called to initialize the generator on server startup. */ virtual void Initialize(cIniFile & a_IniFile); - + /** Generates the biomes for the specified chunk (directly, not in a separate thread). Used by the world loader if biomes failed loading. */ virtual void GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) = 0; @@ -57,47 +57,47 @@ public: /** Called in a separate thread to do the actual chunk generation. Generator should generate into a_ChunkDesc. */ virtual void DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a_ChunkDesc) = 0; - + protected: cChunkGenerator & m_ChunkGenerator; } ; - - + + /** The interface through which the plugins are called for their OnChunkGenerating / OnChunkGenerated hooks. */ class cPluginInterface { public: // Force a virtual destructor virtual ~cPluginInterface() {} - + /** Called when the chunk is about to be generated. The generator may be partly or fully overriden by the implementation. */ virtual void CallHookChunkGenerating(cChunkDesc & a_ChunkDesc) = 0; - + /** Called after the chunk is generated, before it is handed to the chunk sink. a_ChunkDesc contains the generated chunk data. Implementation may modify this data. */ virtual void CallHookChunkGenerated(cChunkDesc & a_ChunkDesc) = 0; } ; - - + + /** The interface through which the generated chunks are handed to the cWorld or whoever created us. */ class cChunkSink { public: // Force a virtual destructor virtual ~cChunkSink() {} - + /** Called after the chunk has been generated The interface may store the chunk, send it over network, whatever. The chunk is not expected to be modified, but the generator will survive if the implementation changes the data within. All changes are ignored, though. */ virtual void OnChunkGenerated(cChunkDesc & a_ChunkDesc) = 0; - + /** Called just before the chunk generation is started, to verify that it hasn't been generated in the meantime. If this callback returns true, the chunk is not generated. */ virtual bool IsChunkValid(int a_ChunkX, int a_ChunkZ) = 0; - + /** Called when the generator is overloaded to skip chunks that are no longer needed. If this callback returns false, the chunk is not generated. */ virtual bool HasChunkAnyClients(int a_ChunkX, int a_ChunkZ) = 0; @@ -106,7 +106,7 @@ public: Currently used only in Debug-mode asserts. */ virtual bool IsChunkQueued(int a_ChunkX, int a_ChunkZ) = 0; } ; - + cChunkGenerator (void); ~cChunkGenerator(); @@ -120,22 +120,22 @@ public: It is legal to set the callback to nullptr, no callback is called then. If the generator becomes overloaded and skips this chunk, the callback is still called. */ void QueueGenerateChunk(int a_ChunkX, int a_ChunkZ, bool a_ForceGenerate, cChunkCoordCallback * a_Callback = nullptr); - + /** Generates the biomes for the specified chunk (directly, not in a separate thread). Used by the world loader if biomes failed loading. */ void GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap); - + void WaitForQueueEmpty(void); - + int GetQueueLength(void); - + int GetSeed(void) const { return m_Seed; } - + /** Returns the biome at the specified coords. Used by ChunkMap if an invalid chunk is queried for biome */ EMCSBiome GetBiomeAt(int a_BlockX, int a_BlockZ); /** Reads a block type from the ini file; returns the blocktype on success, emits a warning and returns a_Default's representation on failure. */ static BLOCKTYPE GetIniBlock(cIniFile & a_IniFile, const AString & a_SectionName, const AString & a_ValueName, const AString & a_Default); - + private: struct cQueueItem @@ -167,16 +167,16 @@ private: /** Set when an item is removed from the queue. */ cEvent m_evtRemoved; - + /** The actual generator engine used to generate chunks. */ cGenerator * m_Generator; - + /** The plugin interface that may modify the generated chunks */ cPluginInterface * m_PluginInterface; - + /** The destination where the generated chunks are sent */ cChunkSink * m_ChunkSink; - + // cIsThread override: virtual void Execute(void) override; diff --git a/src/Generating/CompoGen.cpp b/src/Generating/CompoGen.cpp index 00a19b72b..22bc05f03 100644 --- a/src/Generating/CompoGen.cpp +++ b/src/Generating/CompoGen.cpp @@ -92,7 +92,7 @@ void cCompoGenDebugBiomes::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunk E_BLOCK_NETHER_BRICK, E_BLOCK_BEDROCK, } ; - + a_ChunkDesc.SetHeightFromShape(a_Shape); a_ChunkDesc.FillBlocks(E_BLOCK_AIR, 0); @@ -153,7 +153,7 @@ void cCompoGenClassic::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc static int PatternLength = ARRAYCOUNT(PatternGround); ASSERT(ARRAYCOUNT(PatternGround) == ARRAYCOUNT(PatternBeach)); ASSERT(ARRAYCOUNT(PatternGround) == ARRAYCOUNT(PatternOcean)); - + for (int z = 0; z < cChunkDef::Width; z++) { for (int x = 0; x < cChunkDef::Width; x++) @@ -172,19 +172,19 @@ void cCompoGenClassic::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc { Pattern = PatternOcean; } - + // Fill water from sealevel down to height (if any): for (int y = m_SeaLevel; y >= Height; --y) { a_ChunkDesc.SetBlockType(x, y, z, m_BlockSea); } - + // Fill from height till the bottom: for (int y = Height; y >= 1; y--) { a_ChunkDesc.SetBlockType(x, y, z, (Height - y < PatternLength) ? Pattern[Height - y] : m_BlockBottom); } - + // The last layer is always bedrock: a_ChunkDesc.SetBlockType(x, 0, z, E_BLOCK_BEDROCK); } // for x @@ -229,21 +229,21 @@ cCompoGenNether::cCompoGenNether(int a_Seed) : void cCompoGenNether::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) { HEIGHTTYPE MaxHeight = a_ChunkDesc.GetMaxHeight(); - + const int SEGMENT_HEIGHT = 8; const int INTERPOL_X = 16; // Must be a divisor of 16 const int INTERPOL_Z = 16; // Must be a divisor of 16 // Interpolate the chunk in 16 * SEGMENT_HEIGHT * 16 "segments", each SEGMENT_HEIGHT blocks high and each linearly interpolated separately. // Have two buffers, one for the lowest floor and one for the highest floor, so that Y-interpolation can be done between them // Then swap the buffers and use the previously-top one as the current-bottom, without recalculating it. - + int FloorBuf1[17 * 17]; int FloorBuf2[17 * 17]; int * FloorHi = FloorBuf1; int * FloorLo = FloorBuf2; int BaseX = a_ChunkDesc.GetChunkX() * cChunkDef::Width; int BaseZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width; - + // Interpolate the lowest floor: for (int z = 0; z <= 16 / INTERPOL_Z; z++) for (int x = 0; x <= 16 / INTERPOL_X; x++) { @@ -259,7 +259,7 @@ void cCompoGenNether::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc: //*/ } // for x, z - FloorLo[] LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorLo); - + // Interpolate segments: for (int Segment = 0; Segment < MaxHeight; Segment += SEGMENT_HEIGHT) { @@ -278,7 +278,7 @@ void cCompoGenNether::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc: //*/ } // for x, z - FloorLo[] LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorHi); - + // Interpolate between FloorLo and FloorHi: for (int z = 0; z < 16; z++) for (int x = 0; x < 16; x++) { @@ -294,11 +294,11 @@ void cCompoGenNether::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc: } } } - + // Swap the floors: std::swap(FloorLo, FloorHi); } - + // Bedrock at the bottom and at the top: for (int z = 0; z < 16; z++) for (int x = 0; x < 16; x++) { @@ -380,10 +380,10 @@ void cCompoGenCache::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc:: LOGD("CompoGenCache: Avg cache chain length: %.2f", static_cast(m_TotalChain) / m_NumHits); } #endif // _DEBUG - + int ChunkX = a_ChunkDesc.GetChunkX(); int ChunkZ = a_ChunkDesc.GetChunkZ(); - + for (int i = 0; i < m_CacheSize; i++) { if ( @@ -395,28 +395,28 @@ void cCompoGenCache::ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc:: } // Found it in the cache int Idx = m_CacheOrder[i]; - + // Move to front: for (int j = i; j > 0; j--) { m_CacheOrder[j] = m_CacheOrder[j - 1]; } m_CacheOrder[0] = Idx; - + // Use the cached data: memcpy(a_ChunkDesc.GetBlockTypes(), m_CacheData[Idx].m_BlockTypes, sizeof(a_ChunkDesc.GetBlockTypes())); memcpy(a_ChunkDesc.GetBlockMetasUncompressed(), m_CacheData[Idx].m_BlockMetas, sizeof(a_ChunkDesc.GetBlockMetasUncompressed())); memcpy(a_ChunkDesc.GetHeightMap(), m_CacheData[Idx].m_HeightMap, sizeof(a_ChunkDesc.GetHeightMap())); - + m_NumHits++; m_TotalChain += i; return; } // for i - cache - + // Not in the cache: m_NumMisses++; m_Underlying->ComposeTerrain(a_ChunkDesc, a_Shape); - + // Insert it as the first item in the MRU order: int Idx = m_CacheOrder[m_CacheSize - 1]; for (int i = m_CacheSize - 1; i > 0; i--) diff --git a/src/Generating/CompoGen.h b/src/Generating/CompoGen.h index d4d38bfdd..b5108bac6 100644 --- a/src/Generating/CompoGen.h +++ b/src/Generating/CompoGen.h @@ -31,12 +31,12 @@ public: m_BlockType(E_BLOCK_STONE), m_IsBedrocked(true) {} - + protected: BLOCKTYPE m_BlockType; bool m_IsBedrocked; - + // cTerrainCompositionGen overrides: virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) override; virtual void InitializeCompoGen(cIniFile & a_IniFile) override; @@ -51,9 +51,9 @@ class cCompoGenDebugBiomes : { public: cCompoGenDebugBiomes(void) {} - + protected: - + // cTerrainCompositionGen overrides: virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) override; } ; @@ -67,7 +67,7 @@ class cCompoGenClassic : { public: cCompoGenClassic(void); - + protected: int m_SeaLevel; @@ -79,7 +79,7 @@ protected: BLOCKTYPE m_BlockBeach; BLOCKTYPE m_BlockBeachBottom; BLOCKTYPE m_BlockSea; - + // cTerrainCompositionGen overrides: virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) override; virtual void InitializeCompoGen(cIniFile & a_IniFile) override; @@ -94,13 +94,13 @@ class cCompoGenNether : { public: cCompoGenNether(int a_Seed); - + protected: cNoise m_Noise1; cNoise m_Noise2; - + double m_MaxThreshold; - + // cTerrainCompositionGen overrides: virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) override; virtual void InitializeCompoGen(cIniFile & a_IniFile) override; @@ -117,15 +117,15 @@ class cCompoGenCache : public: cCompoGenCache(cTerrainCompositionGenPtr a_Underlying, int a_CacheSize); // Doesn't take ownership of a_Underlying ~cCompoGenCache(); - + // cTerrainCompositionGen override: virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) override; virtual void InitializeCompoGen(cIniFile & a_IniFile) override; - + protected: cTerrainCompositionGenPtr m_Underlying; - + struct sCacheData { int m_ChunkX; @@ -134,12 +134,12 @@ protected: cChunkDesc::BlockNibbleBytes m_BlockMetas; // The metas are uncompressed, 1 meta per byte cChunkDef::HeightMap m_HeightMap; } ; - + // To avoid moving large amounts of data for the MRU behavior, we MRU-ize indices to an array of the actual data int m_CacheSize; int * m_CacheOrder; // MRU-ized order, indices into m_CacheData array sCacheData * m_CacheData; // m_CacheData[m_CacheOrder[0]] is the most recently used - + // Cache statistics int m_NumHits; int m_NumMisses; diff --git a/src/Generating/CompoGenBiomal.cpp b/src/Generating/CompoGenBiomal.cpp index 43e98387f..0606477a1 100644 --- a/src/Generating/CompoGenBiomal.cpp +++ b/src/Generating/CompoGenBiomal.cpp @@ -39,7 +39,7 @@ public: { m_Pattern[i] = a_TopBlocks[i]; } - + // Fill the rest with stone: static BlockInfo Stone = {E_BLOCK_STONE, 0}; for (int i = static_cast(a_Count); i < cChunkDef::Height; i++) @@ -47,9 +47,9 @@ public: m_Pattern[i] = Stone; } } - + const BlockInfo * Get(void) const { return m_Pattern; } - + protected: BlockInfo m_Pattern[cChunkDef::Height]; } ; @@ -192,14 +192,14 @@ public: { initMesaPattern(a_Seed); } - + protected: /** The block height at which water is generated instead of air. */ HEIGHTTYPE m_SeaLevel; /** The pattern used for mesa biomes. Initialized by seed on generator creation. */ cPattern::BlockInfo m_MesaPattern[2 * cChunkDef::Height]; - + /** Noise used for selecting between dirt and sand on the ocean floor. */ cNoise m_OceanFloorSelect; @@ -226,7 +226,7 @@ protected: { m_SeaLevel = static_cast(a_IniFile.GetValueSetI("Generator", "SeaLevel", m_SeaLevel)); } - + /** Initializes the m_MesaPattern with a pattern based on the generator's seed. */ @@ -309,7 +309,7 @@ protected: // Frequencies for the podzol floor selecting noise: const NOISE_DATATYPE FrequencyX = 8; const NOISE_DATATYPE FrequencyZ = 8; - + EMCSBiome Biome = a_ChunkDesc.GetBiome(a_RelX, a_RelZ); switch (Biome) { @@ -381,7 +381,7 @@ protected: FillColumnPattern(a_ChunkDesc, a_RelX, a_RelZ, patSand.Get(), a_ShapeColumn); return; } - + case biMushroomIsland: case biMushroomShore: { @@ -426,7 +426,7 @@ protected: } } // switch (Biome) } - + /** Fills the specified column with the specified pattern; restarts the pattern when air is reached, @@ -445,23 +445,23 @@ protected: PatternIdx++; continue; } - + // "air" or "water" part: // Reset the pattern index to zero, so that the pattern is repeated from the top again: PatternIdx = 0; - + if (y >= m_SeaLevel) { // "air" part, do nothing continue; } - + a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STATIONARY_WATER); if (HasHadWater) { continue; } - + // Select the ocean-floor pattern to use: if (a_ChunkDesc.GetBiome(a_RelX, a_RelZ) == biDeepOcean) { @@ -500,7 +500,7 @@ protected: { ClayFloor = Top - 1; } - + if (Top - m_SeaLevel < 5) { // Simple case: top is red sand, then hardened clay down to ClayFloor, then stone: @@ -516,7 +516,7 @@ protected: a_ChunkDesc.SetBlockType(a_RelX, 0, a_RelZ, E_BLOCK_BEDROCK); return; } - + // Difficult case: use the mesa pattern and watch for overhangs: int PatternIdx = cChunkDef::Height - (Top - ClayFloor); // We want the block at index ClayFloor to be pattern's 256th block (first stone) const cPattern::BlockInfo * Pattern = m_MesaPattern; @@ -536,7 +536,7 @@ protected: // "air" part, do nothing continue; } - + // "water" part, fill with water and choose new pattern for ocean floor, if not chosen already: PatternIdx = 0; a_ChunkDesc.SetBlockType(a_RelX, y, a_RelZ, E_BLOCK_STATIONARY_WATER); @@ -544,7 +544,7 @@ protected: { continue; } - + // Select the ocean-floor pattern to use: Pattern = ChooseOceanFloorPattern(a_ChunkDesc.GetChunkX(), a_ChunkDesc.GetChunkZ(), a_RelX, a_RelZ); HasHadWater = true; @@ -567,7 +567,7 @@ protected: } - + /** Returns the pattern to use for an ocean floor in the specified column. The returned pattern is guaranteed to be 256 blocks long. */ const cPattern::BlockInfo * ChooseOceanFloorPattern(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ) diff --git a/src/Generating/ComposableGenerator.cpp b/src/Generating/ComposableGenerator.cpp index 478404d45..e9ab96aec 100644 --- a/src/Generating/ComposableGenerator.cpp +++ b/src/Generating/ComposableGenerator.cpp @@ -47,7 +47,7 @@ cTerrainCompositionGenPtr cTerrainCompositionGen::CreateCompositionGen(cIniFile LOGWARN("[Generator] CompositionGen value not set in world.ini, using \"Biomal\"."); CompoGenName = "Biomal"; } - + // Compositor list is alpha-sorted cTerrainCompositionGenPtr res; if (NoCaseCompare(CompoGenName, "Biomal") == 0) @@ -96,10 +96,10 @@ cTerrainCompositionGenPtr cTerrainCompositionGen::CreateCompositionGen(cIniFile return CreateCompositionGen(a_IniFile, a_BiomeGen, a_ShapeGen, a_Seed); } ASSERT(res != nullptr); - + // Read the settings from the ini file: res->InitializeCompoGen(a_IniFile); - + return cTerrainCompositionGenPtr(res); } @@ -125,7 +125,7 @@ cComposableGenerator::cComposableGenerator(cChunkGenerator & a_ChunkGenerator) : void cComposableGenerator::Initialize(cIniFile & a_IniFile) { super::Initialize(a_IniFile); - + InitBiomeGen(a_IniFile); InitShapeGen(a_IniFile); InitCompositionGen(a_IniFile); @@ -154,7 +154,7 @@ void cComposableGenerator::DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a { m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, a_ChunkDesc.GetBiomeMap()); } - + cChunkDesc::Shape shape; if (a_ChunkDesc.IsUsingDefaultHeight()) { @@ -166,7 +166,7 @@ void cComposableGenerator::DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a // Convert the heightmap in a_ChunkDesc into shape: a_ChunkDesc.GetShapeFromHeight(shape); } - + bool ShouldUpdateHeightmap = false; if (a_ChunkDesc.IsUsingDefaultComposition()) { @@ -181,7 +181,7 @@ void cComposableGenerator::DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a } // for itr - m_FinishGens[] ShouldUpdateHeightmap = true; } - + if (ShouldUpdateHeightmap) { a_ChunkDesc.UpdateHeightmap(); @@ -196,7 +196,7 @@ void cComposableGenerator::InitBiomeGen(cIniFile & a_IniFile) { bool CacheOffByDefault = false; m_BiomeGen = cBiomeGen::CreateBiomeGen(a_IniFile, m_ChunkGenerator.GetSeed(), CacheOffByDefault); - + // Add a cache, if requested: // The default is 16 * 128 caches, which is 2 MiB of RAM. Reasonable, for the amount of work this is saving. int CacheSize = a_IniFile.GetValueSetI("Generator", "BiomeGenCacheSize", CacheOffByDefault ? 0 : 16); @@ -232,7 +232,7 @@ void cComposableGenerator::InitShapeGen(cIniFile & a_IniFile) { bool CacheOffByDefault = false; m_ShapeGen = cTerrainShapeGen::CreateShapeGen(a_IniFile, m_BiomeGen, m_ChunkGenerator.GetSeed(), CacheOffByDefault); - + /* // TODO // Add a cache, if requested: @@ -259,7 +259,7 @@ void cComposableGenerator::InitShapeGen(cIniFile & a_IniFile) void cComposableGenerator::InitCompositionGen(cIniFile & a_IniFile) { m_CompositionGen = cTerrainCompositionGen::CreateCompositionGen(a_IniFile, m_BiomeGen, m_ShapeGen, m_ChunkGenerator.GetSeed()); - + // Add a cache over the composition generator: // Even a cache of size 1 is useful due to the CompositedHeiGen cache after us doing re-composition on its misses int CompoGenCacheSize = a_IniFile.GetValueSetI("Generator", "CompositionGenCacheSize", 64); diff --git a/src/Generating/ComposableGenerator.h b/src/Generating/ComposableGenerator.h index 32345fc79..056303db1 100644 --- a/src/Generating/ComposableGenerator.h +++ b/src/Generating/ComposableGenerator.h @@ -48,10 +48,10 @@ class cBiomeGen { public: virtual ~cBiomeGen() {} // Force a virtual destructor in descendants - + /** Generates biomes for the given chunk */ virtual void GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) = 0; - + /** Reads parameters from the ini file, prepares generator for use. */ virtual void InitializeBiomeGen(cIniFile & a_IniFile) {} @@ -79,13 +79,13 @@ class cTerrainShapeGen { public: virtual ~cTerrainShapeGen() {} // Force a virtual destructor in descendants - + /** Generates the shape for the given chunk */ virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) = 0; - + /** Reads parameters from the ini file, prepares generator for use. */ virtual void InitializeShapeGen(cIniFile & a_IniFile) {} - + /** Creates the correct TerrainShapeGen descendant based on the ini file settings and the seed provided. a_BiomeGen is the underlying biome generator, some shape generators may depend on it providing additional biomes data around the chunk a_CacheOffByDefault gets set to whether the cache should be disabled by default @@ -142,14 +142,14 @@ class cTerrainCompositionGen { public: virtual ~cTerrainCompositionGen() {} // Force a virtual destructor in descendants - + /** Generates the chunk's composition into a_ChunkDesc, using the terrain shape provided in a_Shape. Is expected to fill a_ChunkDesc's heightmap with the data from a_Shape. */ virtual void ComposeTerrain(cChunkDesc & a_ChunkDesc, const cChunkDesc::Shape & a_Shape) = 0; - + /** Reads parameters from the ini file, prepares generator for use. */ virtual void InitializeCompoGen(cIniFile & a_IniFile) {} - + /** Creates the correct TerrainCompositionGen descendant based on the ini file settings and the seed provided. a_BiomeGen is the underlying biome generator, some composition generators may depend on it providing additional biomes around the chunk a_ShapeGen is the underlying shape generator, some composition generators may depend on it providing additional shape around the chunk @@ -172,7 +172,7 @@ class cFinishGen { public: virtual ~cFinishGen() {} // Force a virtual destructor in descendants - + virtual void GenFinish(cChunkDesc & a_ChunkDesc) = 0; } ; @@ -186,10 +186,10 @@ class cComposableGenerator : public cChunkGenerator::cGenerator { typedef cChunkGenerator::cGenerator super; - + public: cComposableGenerator(cChunkGenerator & a_ChunkGenerator); - + // cChunkGenerator::cGenerator overrides: virtual void Initialize(cIniFile & a_IniFile) override; virtual void GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; @@ -211,17 +211,17 @@ protected: /** The finisher generators, in the order in which they are applied. */ cFinishGenList m_FinishGens; - - + + /** Reads the BiomeGen settings from the ini and initializes m_BiomeGen accordingly */ void InitBiomeGen(cIniFile & a_IniFile); - + /** Reads the ShapeGen settings from the ini and initializes m_ShapeGen accordingly */ void InitShapeGen(cIniFile & a_IniFile); - + /** Reads the CompositionGen settings from the ini and initializes m_CompositionGen accordingly */ void InitCompositionGen(cIniFile & a_IniFile); - + /** Reads the finishers from the ini and initializes m_FinishGens accordingly */ void InitFinishGens(cIniFile & a_IniFile); } ; diff --git a/src/Generating/DistortedHeightmap.cpp b/src/Generating/DistortedHeightmap.cpp index 835780f95..405f436b0 100644 --- a/src/Generating/DistortedHeightmap.cpp +++ b/src/Generating/DistortedHeightmap.cpp @@ -68,7 +68,7 @@ const cDistortedHeightmap::sGenParam cDistortedHeightmap::m_GenParam[256] = /* biMesa */ { 2.0f, 2.0f}, // 37 /* biMesaPlateauF */ { 2.0f, 2.0f}, // 38 /* biMesaPlateau */ { 2.0f, 2.0f}, // 39 - + // biomes 40 .. 128 are unused, 89 empty placeholders here: {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 40 .. 49 {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 50 .. 59 @@ -79,7 +79,7 @@ const cDistortedHeightmap::sGenParam cDistortedHeightmap::m_GenParam[256] = {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 100 .. 109 {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 110 .. 119 {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 120 .. 128 - + // Release 1.7 biome variants: /* biSunflowerPlains */ { 1.0f, 1.0f}, // 129 /* biDesertM */ { 1.0f, 1.0f}, // 130 @@ -87,12 +87,12 @@ const cDistortedHeightmap::sGenParam cDistortedHeightmap::m_GenParam[256] = /* biFlowerForest */ { 4.0f, 4.0f}, // 132 /* biTaigaM */ { 3.0f, 3.0f}, // 133 /* biSwamplandM */ { 0.0f, 0.0f}, // 134 - + // Biomes 135 .. 139 unused, 5 empty placeholders here: {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 135 .. 139 /* biIcePlainsSpikes */ { 1.0f, 1.0f}, // 140 - + // Biomes 141 .. 148 unused, 8 empty placeholders here: {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, // 141 .. 148 @@ -358,7 +358,7 @@ void cDistortedHeightmap::GetDistortAmpsAt(BiomeNeighbors & a_Neighbors, int a_R { continue; } - + /* // Sanity checks for biome parameters, enable them to check the biome param table in runtime (slow): ASSERT(m_GenParam[i].m_DistortAmpX >= 0); diff --git a/src/Generating/DistortedHeightmap.h b/src/Generating/DistortedHeightmap.h index 79fc35542..eaa6aa8d9 100644 --- a/src/Generating/DistortedHeightmap.h +++ b/src/Generating/DistortedHeightmap.h @@ -27,7 +27,7 @@ class cDistortedHeightmap : { public: cDistortedHeightmap(int a_Seed, cBiomeGenPtr a_BiomeGen); - + protected: typedef cChunkDef::BiomeMap BiomeNeighbors[3][3]; @@ -61,10 +61,10 @@ protected: /** Cache for m_UnderlyingHeiGen. */ cHeiGenCache m_HeightGen; - + /** Heightmap for the current chunk, before distortion (from m_HeightGen). Used for optimization. */ cChunkDef::HeightMap m_CurChunkHeights; - + // Per-biome terrain generator parameters: struct sGenParam { @@ -72,34 +72,34 @@ protected: NOISE_DATATYPE m_DistortAmpZ; } ; static const sGenParam m_GenParam[256]; - + // Distortion amplitudes for each direction, before linear upscaling NOISE_DATATYPE m_DistortAmpX[DIM_X * DIM_Z]; NOISE_DATATYPE m_DistortAmpZ[DIM_X * DIM_Z]; - + /** True if Initialize() has been called. Used to initialize-once even with multiple init entrypoints (HeiGen / CompoGen). */ bool m_IsInitialized; - + /** Unless the LastChunk coords are equal to coords given, prepares the internal state (noise arrays, heightmap). */ void PrepareState(int a_ChunkX, int a_ChunkZ); - + /** Generates the m_DistortedHeightmap array for the current chunk. */ void GenerateHeightArray(void); - + /** Calculates the heightmap value (before distortion) at the specified (floating-point) coords. */ int GetHeightmapAt(NOISE_DATATYPE a_X, NOISE_DATATYPE a_Z); - + /** Updates m_DistortAmpX/Z[] based on m_CurChunkX and m_CurChunkZ. */ void UpdateDistortAmps(void); - + /** Calculates the X and Z distortion amplitudes based on the neighbors' biomes. */ void GetDistortAmpsAt(BiomeNeighbors & a_Neighbors, int a_RelX, int a_RelZ, NOISE_DATATYPE & a_DistortAmpX, NOISE_DATATYPE & a_DistortAmpZ); - + /** Reads the settings from the ini file. Skips reading if already initialized. */ void Initialize(cIniFile & a_IniFile); - - + + // cTerrainShapeGen overrides: virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) override; virtual void InitializeShapeGen(cIniFile & a_IniFile) override; diff --git a/src/Generating/EndGen.h b/src/Generating/EndGen.h index f914dc340..5008c2670 100644 --- a/src/Generating/EndGen.h +++ b/src/Generating/EndGen.h @@ -22,12 +22,12 @@ class cEndGen : { public: cEndGen(int a_Seed); - + protected: /** Seed for the noise */ int m_Seed; - + /** The Perlin noise used for generating */ cPerlinNoise m_Perlin; @@ -35,16 +35,16 @@ protected: int m_IslandSizeX; int m_IslandSizeY; int m_IslandSizeZ; - + // XYZ Frequencies of the noise functions: NOISE_DATATYPE m_FrequencyX; NOISE_DATATYPE m_FrequencyY; NOISE_DATATYPE m_FrequencyZ; - + // Minimum and maximum chunk coords for chunks inside the island area. Chunks outside won't get calculated at all int m_MinChunkX, m_MaxChunkX; int m_MinChunkZ, m_MaxChunkZ; - + // Noise array for the last chunk (in the noise range) int m_LastChunkX; int m_LastChunkZ; @@ -53,10 +53,10 @@ protected: /** Unless the LastChunk coords are equal to coords given, prepares the internal state (noise array) */ void PrepareState(int a_ChunkX, int a_ChunkZ); - + /** Generates the m_NoiseArray array for the current chunk */ void GenerateNoiseArray(void); - + /** Returns true if the chunk is outside of the island's dimensions */ bool IsChunkOutsideRange(int a_ChunkX, int a_ChunkZ); diff --git a/src/Generating/FinishGen.cpp b/src/Generating/FinishGen.cpp index f3a62e8e3..d35d77eac 100644 --- a/src/Generating/FinishGen.cpp +++ b/src/Generating/FinishGen.cpp @@ -186,7 +186,7 @@ void cFinishGenGlowStone::GenFinish(cChunkDesc & a_ChunkDesc) { int ChunkX = a_ChunkDesc.GetChunkX(); int ChunkZ = a_ChunkDesc.GetChunkZ(); - + // Change the number of attempts to create a vein depending on the maximum height of the chunk. A standard Nether could have 5 veins at most. int NumGlowStone = m_Noise.IntNoise2DInt(ChunkX, ChunkZ) % a_ChunkDesc.GetMaxHeight() / 23; @@ -198,7 +198,7 @@ void cFinishGenGlowStone::GenFinish(cChunkDesc & a_ChunkDesc) // Generate X / Z coordinates. int X = Size + (m_Noise.IntNoise2DInt(i, Size) % (cChunkDef::Width - Size * 2)); int Z = Size + (m_Noise.IntNoise2DInt(X, i) % (cChunkDef::Width - Size * 2)); - + int Height = a_ChunkDesc.GetHeight(X, Z); for (int y = Height; y > Size; y--) { @@ -234,14 +234,14 @@ void cFinishGenGlowStone::TryPlaceGlowstone(cChunkDesc & a_ChunkDesc, int a_RelX { // The starting point of every glowstone string Vector3i StartPoint = Vector3i(a_RelX, a_RelY, a_RelZ); - + // Array with possible directions for a string of glowstone to go to. const Vector3i AvailableDirections[] = { { -1, 0, 0 }, { 1, 0, 0 }, { 0, -1, 0 }, // Don't let the glowstone go up { 0, 0, -1 }, { 0, 0, 1 }, - + // Diagonal direction. Only X or Z with Y. // If all were changed the glowstone string looks awkward { 0, -1, 1 }, { 1, -1, 0 }, diff --git a/src/Generating/FinishGen.h b/src/Generating/FinishGen.h index 464ed209f..8e90f9f2a 100644 --- a/src/Generating/FinishGen.h +++ b/src/Generating/FinishGen.h @@ -372,7 +372,7 @@ class cFinishGenPassiveMobs : public cFinishGen { public: - + cFinishGenPassiveMobs(int a_Seed, cIniFile & a_IniFile, eDimension a_Dimension); protected: diff --git a/src/Generating/GridStructGen.cpp b/src/Generating/GridStructGen.cpp index bcf66795c..0068783eb 100644 --- a/src/Generating/GridStructGen.cpp +++ b/src/Generating/GridStructGen.cpp @@ -20,13 +20,13 @@ class cEmptyStructure : public cGridStructGen::cStructure { typedef cGridStructGen::cStructure super; - + public: cEmptyStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) : super(a_GridX, a_GridZ, a_OriginX, a_OriginZ) { } - + protected: virtual void DrawIntoChunk(cChunkDesc & a_ChunkDesc) override { diff --git a/src/Generating/GridStructGen.h b/src/Generating/GridStructGen.h index b27f218f4..30cb9d670 100644 --- a/src/Generating/GridStructGen.h +++ b/src/Generating/GridStructGen.h @@ -51,11 +51,11 @@ public: public: /** The grid point for which the structure is generated. */ int m_GridX, m_GridZ; - + /** The origin (the coords for which the structure is generated) */ int m_OriginX, m_OriginZ; - - + + /** Creates a structure that has its origin set at the specified coords. */ cStructure (int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) : m_GridX(a_GridX), @@ -64,20 +64,20 @@ public: m_OriginZ(a_OriginZ) { } - + // Force a virtual destructor in descendants: virtual ~cStructure() {} - + /** Draws self into the specified chunk */ virtual void DrawIntoChunk(cChunkDesc & a_ChunkDesc) = 0; - + /** Returns the cost of keeping this structure in the cache */ virtual size_t GetCacheCost(void) const { return 1; } } ; typedef SharedPtr cStructurePtr; typedef std::list cStructurePtrs; - - + + cGridStructGen( int a_Seed, int a_GridSizeX, int a_GridSizeZ, @@ -96,7 +96,7 @@ public: // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; - + protected: /** Base seed of the world for which the generator generates chunk. */ int m_BaseSeed; @@ -104,43 +104,43 @@ protected: /** Seed for generating grid offsets and also available for descendants. Calculated from m_BaseSeed by adding the SeedOffset parameter loaded from the cubeset file (if applicable); otherwise the same as m_BaseSeed. */ int m_Seed; - + /** The noise used for generating grid offsets. */ cNoise m_Noise; - + /** The size of each grid's cell in the X axis */ int m_GridSizeX; - + /** The size of each grid's cell in the Z axis */ int m_GridSizeZ; - + /** The maximum offset of the structure's origin from the grid midpoint, in X coord. */ int m_MaxOffsetX; - + /** The maximum offset of the structure's origin from the grid midpoint, in Z coord. */ int m_MaxOffsetZ; - + /** Maximum theoretical size of the structure in the X axis. This limits the structures considered for a single chunk, so the lesser the number, the better performance. Structures large than this may get cropped. */ int m_MaxStructureSizeX; - + /** Maximum theoretical size of the structure in the Z axis. This limits the structures considered for a single chunk, so the lesser the number, the better performance. Structures large than this may get cropped. */ int m_MaxStructureSizeZ; - + /** Maximum allowed sum of costs for items in the cache. Items that are over this cost are removed from the cache, oldest-first */ size_t m_MaxCacheSize; - + /** Cache for the most recently generated structures, ordered by the recentness. */ cStructurePtrs m_Cache; - - + + /** Clears everything from the cache */ void ClearCache(void); - + /** Returns all structures that may intersect the given chunk. The structures are considered as intersecting iff their bounding box (defined by m_MaxStructureSize) around their gridpoint intersects the chunk. */ diff --git a/src/Generating/HeiGen.cpp b/src/Generating/HeiGen.cpp index 2b3f342bb..b724a1dde 100644 --- a/src/Generating/HeiGen.cpp +++ b/src/Generating/HeiGen.cpp @@ -144,7 +144,7 @@ void cHeiGenCache::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap LOGD("HeiGenCache: Avg cache chain length: %.2f", static_cast(m_TotalChain) / m_NumHits); } //*/ - + for (size_t i = 0; i < m_CacheSize; i++) { if ( @@ -156,26 +156,26 @@ void cHeiGenCache::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap } // Found it in the cache auto Idx = m_CacheOrder[i]; - + // Move to front: for (size_t j = i; j > 0; j--) { m_CacheOrder[j] = m_CacheOrder[j - 1]; } m_CacheOrder[0] = Idx; - + // Use the cached data: memcpy(a_HeightMap, m_CacheData[Idx].m_HeightMap, sizeof(a_HeightMap)); - + m_NumHits++; m_TotalChain += i; return; } // for i - cache - + // Not in the cache: m_NumMisses++; m_HeiGenToCache->GenHeightMap(a_ChunkX, a_ChunkZ, a_HeightMap); - + // Insert it as the first item in the MRU order: auto Idx = m_CacheOrder[m_CacheSize - 1]; for (auto i = m_CacheSize - 1; i > 0; i--) @@ -341,7 +341,7 @@ void cHeiGenClassic::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightM for (int x = 0; x < cChunkDef::Width; x++) { const float xx = static_cast(a_ChunkX * cChunkDef::Width + x); - + HEIGHTTYPE hei = static_cast(Clamp(static_cast(64 + (GetNoise(xx * 0.05f, zz * 0.05f) * 16)), 10, 250)); cChunkDef::SetHeight(a_HeightMap, x, z, hei); } // for x @@ -474,7 +474,7 @@ const cHeiGenBiomal::sGenParam cHeiGenBiomal::m_GenParam[256] = /* biMesa */ { 0.2f, 2.0f, 0.05f, 10.0f, 0.01f, 8.0f, 70}, // 165 /* biMesaPlateauF */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 80}, /* biMesaPlateau */ { 0.1f, 1.0f, 0.05f, 1.5f, 0.01f, 4.0f, 80}, - + // biomes 40 .. 128 are unused, 89 empty placeholders here: {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 40 .. 49 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 50 .. 59 @@ -485,22 +485,22 @@ const cHeiGenBiomal::sGenParam cHeiGenBiomal::m_GenParam[256] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 100 .. 109 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 110 .. 119 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 120 .. 128 - + /* biSunflowerPlains */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 129 /* biDesertM */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 130 /* biExtremeHillsM */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 131 /* biFlowerForest */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 132 /* biTaigaM */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 133 /* biSwamplandM */ { 1.0f, 3.0f, 1.10f, 7.0f, 0.01f, 0.01f, 60}, // 134 - + // Biomes 135 .. 139 unused, 5 empty placeholders here: {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 135 .. 139 - + /* biIcePlainsSpikes */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 140 - + // Biomes 141 .. 148 unused, 8 empty placeholders here: {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 141 .. 148 - + /* biJungleM */ { 0.1f, 3.0f, 0.05f, 6.0f, 0.01f, 6.0f, 70}, // 149 {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0}, // 150 /* biJungleEdgeM */ { 0.1f, 3.0f, 0.05f, 6.0f, 0.01f, 6.0f, 70}, // 151 @@ -535,13 +535,13 @@ void cHeiGenBiomal::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMa m_BiomeGen->GenBiomes(a_ChunkX + x, a_ChunkZ + z, Biomes[x + 1][z + 1]); } // for x } // for z - + /* _X 2013_04_22: There's no point in precalculating the entire perlin noise arrays, too many values are calculated uselessly, resulting in speed DEcrease. */ - + //* // Linearly interpolate 4x4 blocks of heightmap: // Must be done on a floating point datatype, else the results are ugly! @@ -556,7 +556,7 @@ void cHeiGenBiomal::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMa } } LinearUpscale2DArrayInPlace<17, 17, STEPX, STEPZ>(Height); - + // Copy into the heightmap for (int z = 0; z < cChunkDef::Width; z++) { @@ -566,7 +566,7 @@ void cHeiGenBiomal::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMa } } //*/ - + /* // For each height, go through neighboring biomes and add up their idea of height: for (int z = 0; z < cChunkDef::Width; z++) @@ -615,7 +615,7 @@ NOISE_DATATYPE cHeiGenBiomal::GetHeightAt(int a_RelX, int a_RelZ, int a_ChunkX, Sum += WeightX + WeightZ; } // for x } // for z - + // For each biome type that has a nonzero count, calc its height and add it: if (Sum > 0) { @@ -628,7 +628,7 @@ NOISE_DATATYPE cHeiGenBiomal::GetHeightAt(int a_RelX, int a_RelZ, int a_ChunkX, { continue; } - + /* // Sanity checks for biome parameters, enable them to check the biome param table in runtime (slow): ASSERT(m_GenParam[i].m_HeightFreq1 >= 0); @@ -638,7 +638,7 @@ NOISE_DATATYPE cHeiGenBiomal::GetHeightAt(int a_RelX, int a_RelZ, int a_ChunkX, ASSERT(m_GenParam[i].m_HeightFreq3 >= 0); ASSERT(m_GenParam[i].m_HeightFreq3 < 1000); */ - + NOISE_DATATYPE oct1 = m_Noise.CubicNoise2D(BlockX * m_GenParam[i].m_HeightFreq1, BlockZ * m_GenParam[i].m_HeightFreq1) * m_GenParam[i].m_HeightAmp1; NOISE_DATATYPE oct2 = m_Noise.CubicNoise2D(BlockX * m_GenParam[i].m_HeightFreq2, BlockZ * m_GenParam[i].m_HeightFreq2) * m_GenParam[i].m_HeightAmp2; NOISE_DATATYPE oct3 = m_Noise.CubicNoise2D(BlockX * m_GenParam[i].m_HeightFreq3, BlockZ * m_GenParam[i].m_HeightFreq3) * m_GenParam[i].m_HeightAmp3; @@ -647,7 +647,7 @@ NOISE_DATATYPE cHeiGenBiomal::GetHeightAt(int a_RelX, int a_RelZ, int a_ChunkX, NOISE_DATATYPE res = Height / Sum; return std::min(static_cast(250), std::max(res, static_cast(5))); } - + // No known biome around? Weird. Return a bogus value: ASSERT(!"cHeiGenBiomal: Biome sum failed, no known biome around"); return 5; @@ -756,7 +756,7 @@ public: } } - + virtual void InitializeHeightGen(cIniFile & a_IniFile) { // No settings available @@ -872,7 +872,7 @@ cTerrainHeightGenPtr cTerrainHeightGen::CreateHeightGen(cIniFile & a_IniFile, cB LOGWARN("[Generator] HeightGen value not set in world.ini, using \"Biomal\"."); HeightGenName = "Biomal"; } - + a_CacheOffByDefault = false; cTerrainHeightGenPtr res; if (NoCaseCompare(HeightGenName, "Flat") == 0) @@ -944,7 +944,7 @@ cTerrainHeightGenPtr cTerrainHeightGen::CreateHeightGen(cIniFile & a_IniFile, cB a_IniFile.SetValue("Generator", "HeightGen", "Biomal"); return CreateHeightGen(a_IniFile, a_BiomeGen, a_Seed, a_CacheOffByDefault); } - + // Read the settings: res->InitializeHeightGen(a_IniFile); diff --git a/src/Generating/HeiGen.h b/src/Generating/HeiGen.h index e3b951b44..67c6c00cd 100644 --- a/src/Generating/HeiGen.h +++ b/src/Generating/HeiGen.h @@ -30,14 +30,14 @@ class cHeiGenCache : public: cHeiGenCache(cTerrainHeightGenPtr a_HeiGenToCache, size_t a_CacheSize); ~cHeiGenCache(); - + // cTerrainHeightGen overrides: virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; virtual HEIGHTTYPE GetHeightAt(int a_BlockX, int a_BlockZ) override; - + /** Retrieves height at the specified point in the cache, returns true if found, false if not found */ bool GetHeightAt(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ, HEIGHTTYPE & a_Height); - + protected: struct sCacheData { @@ -45,15 +45,15 @@ protected: int m_ChunkZ; cChunkDef::HeightMap m_HeightMap; } ; - + /** The terrain height generator that is being cached. */ cTerrainHeightGenPtr m_HeiGenToCache; - + // To avoid moving large amounts of data for the MRU behavior, we MRU-ize indices to an array of the actual data size_t m_CacheSize; size_t * m_CacheOrder; // MRU-ized order, indices into m_CacheData array sCacheData * m_CacheData; // m_CacheData[m_CacheOrder[0]] is the most recently used - + // Cache statistics size_t m_NumHits; size_t m_NumMisses; @@ -74,7 +74,7 @@ public: // cTerrainHeightGen overrides: virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; virtual HEIGHTTYPE GetHeightAt(int a_BlockX, int a_BlockZ) override; - + /** Retrieves height at the specified point in the cache, returns true if found, false if not found */ bool GetHeightAt(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_RelZ, HEIGHTTYPE & a_Height); @@ -102,7 +102,7 @@ class cHeiGenFlat : { public: cHeiGenFlat(void) : m_Height(5) {} - + protected: HEIGHTTYPE m_Height; @@ -121,7 +121,7 @@ class cHeiGenClassic : { public: cHeiGenClassic(int a_Seed); - + protected: int m_Seed; @@ -129,7 +129,7 @@ protected: float m_HeightFreq1, m_HeightAmp1; float m_HeightFreq2, m_HeightAmp2; float m_HeightFreq3, m_HeightAmp3; - + float GetNoise(float x, float y); // cTerrainHeightGen overrides: @@ -146,14 +146,14 @@ class cHeiGenMountains : { public: cHeiGenMountains(int a_Seed); - + protected: int m_Seed; cRidgedMultiNoise m_MountainNoise; cRidgedMultiNoise m_DitchNoise; cPerlinNoise m_Perlin; - + // cTerrainHeightGen overrides: virtual void GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMap & a_HeightMap) override; virtual void InitializeHeightGen(cIniFile & a_IniFile) override; @@ -189,7 +189,7 @@ protected: cNoise m_Noise; cBiomeGenPtr m_BiomeGen; - + // Per-biome terrain generator parameters: struct sGenParam { diff --git a/src/Generating/MineShafts.cpp b/src/Generating/MineShafts.cpp index ef06285ad..a9f2d1568 100644 --- a/src/Generating/MineShafts.cpp +++ b/src/Generating/MineShafts.cpp @@ -64,7 +64,7 @@ public: m_BoundingBox(a_BoundingBox) { } - + virtual ~cMineShaft() {} /** Returns true if this mineshaft intersects the specified cuboid */ diff --git a/src/Generating/MineShafts.h b/src/Generating/MineShafts.h index efb11cfee..401b1d31e 100644 --- a/src/Generating/MineShafts.h +++ b/src/Generating/MineShafts.h @@ -25,7 +25,7 @@ public: int a_Seed, int a_GridSize, int a_MaxOffset, int a_MaxSystemSize, int a_ChanceCorridor, int a_ChanceCrossing, int a_ChanceStaircase ); - + protected: friend class cMineShaft; friend class cMineShaftDirtRoom; @@ -33,14 +33,14 @@ protected: friend class cMineShaftCrossing; friend class cMineShaftStaircase; class cMineShaftSystem; // fwd: MineShafts.cpp - + cNoise m_Noise; int m_GridSize; ///< Average spacing of the systems int m_MaxSystemSize; ///< Maximum blcok size of a mineshaft system int m_ProbLevelCorridor; ///< Probability level of a branch object being the corridor int m_ProbLevelCrossing; ///< Probability level of a branch object being the crossing, minus Corridor int m_ProbLevelStaircase; ///< Probability level of a branch object being the staircase, minus Crossing - + // cGridStructGen overrides: virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override; } ; diff --git a/src/Generating/Noise3DGenerator.h b/src/Generating/Noise3DGenerator.h index f9317abe2..1bbae2584 100644 --- a/src/Generating/Noise3DGenerator.h +++ b/src/Generating/Noise3DGenerator.h @@ -24,21 +24,21 @@ class cNoise3DGenerator : public cChunkGenerator::cGenerator { typedef cChunkGenerator::cGenerator super; - + public: cNoise3DGenerator(cChunkGenerator & a_ChunkGenerator); virtual ~cNoise3DGenerator(); - + virtual void Initialize(cIniFile & a_IniFile) override; virtual void GenerateBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_BiomeMap) override; virtual void DoGenerate(int a_ChunkX, int a_ChunkZ, cChunkDesc & a_ChunkDesc) override; - + protected: // Linear interpolation step sizes, must be divisors of cChunkDef::Width and cChunkDef::Height, respectively: static const int UPSCALE_X = 4; static const int UPSCALE_Y = 8; static const int UPSCALE_Z = 4; - + // Linear interpolation buffer dimensions, calculated from the step sizes: static const int DIM_X = 1 + cChunkDef::Width / UPSCALE_X; static const int DIM_Y = 1 + cChunkDef::Height / UPSCALE_Y; @@ -49,7 +49,7 @@ protected: /** The noise used for heightmap directing. */ cOctavedNoise m_Cubic; - + int m_SeaLevel; NOISE_DATATYPE m_HeightAmplification; NOISE_DATATYPE m_MidPoint; // Where the vertical "center" of the noise should be @@ -57,13 +57,13 @@ protected: NOISE_DATATYPE m_FrequencyY; NOISE_DATATYPE m_FrequencyZ; NOISE_DATATYPE m_AirThreshold; - + /** Generates the 3D noise array used for terrain generation; a_Noise is of ChunkData-size */ void GenerateNoiseArray(int a_ChunkX, int a_ChunkZ, NOISE_DATATYPE * a_Noise); - + /** Updates heightmap based on the chunk's contents */ void UpdateHeightmap(cChunkDesc & a_ChunkDesc); - + /** Composes terrain - adds dirt, grass and sand */ void ComposeTerrain(cChunkDesc & a_ChunkDesc); } ; @@ -92,7 +92,7 @@ protected: /** Heightmap-like noise used to provide variance for low-amplitude biomes. */ cOctavedNoise> m_BaseNoise; - + /** The main parameter of the generator, specifies the slope of the vertical linear gradient. A higher value means a steeper slope and a smaller total amplitude of the generated terrain. */ NOISE_DATATYPE m_HeightAmplification; @@ -116,16 +116,16 @@ protected: // Threshold for when the values are considered air: NOISE_DATATYPE m_AirThreshold; - + // Cache for the last calculated chunk (reused between heightmap and composition queries): int m_LastChunkX; int m_LastChunkZ; NOISE_DATATYPE m_NoiseArray[17 * 17 * 257]; // x + 17 * z + 17 * 17 * y - - + + /** Generates the 3D noise array used for terrain generation (m_NoiseArray), unless the LastChunk coords are equal to coords given */ void GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ); - + // cTerrainHeightGen overrides: virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) override; virtual void InitializeShapeGen(cIniFile & a_IniFile) override { Initialize(a_IniFile); } @@ -165,7 +165,7 @@ protected: /** The underlying biome generator. */ cBiomeGenPtr m_BiomeGen; - + /** Block height of the sealevel, used for composing the terrain. */ int m_SeaLevel; @@ -185,7 +185,7 @@ protected: // Threshold for when the values are considered air: NOISE_DATATYPE m_AirThreshold; - + // Cache for the last calculated chunk (reused between heightmap and composition queries): int m_LastChunkX; int m_LastChunkZ; @@ -196,8 +196,8 @@ protected: /** The sum of m_Weight[]. */ NOISE_DATATYPE m_WeightSum; - - + + /** Generates the 3D noise array used for terrain generation (m_NoiseArray), unless the LastChunk coords are equal to coords given */ void GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ); @@ -206,7 +206,7 @@ protected: /** Returns the parameters for the specified biome. */ void GetBiomeParams(EMCSBiome a_Biome, NOISE_DATATYPE & a_HeightAmp, NOISE_DATATYPE & a_MidPoint); - + // cTerrainShapeGen overrides: virtual void GenShape(int a_ChunkX, int a_ChunkZ, cChunkDesc::Shape & a_Shape) override; virtual void InitializeShapeGen(cIniFile & a_IniFile) override { Initialize(a_IniFile); } diff --git a/src/Generating/PieceGenerator.cpp b/src/Generating/PieceGenerator.cpp index 1d58157ba..d6204ce85 100644 --- a/src/Generating/PieceGenerator.cpp +++ b/src/Generating/PieceGenerator.cpp @@ -84,7 +84,7 @@ Vector3i cPiece::RotatePos(const Vector3i & a_Pos, int a_NumCCWRotations) const cPiece::cConnector cPiece::RotateMoveConnector(const cConnector & a_Connector, int a_NumCCWRotations, int a_MoveX, int a_MoveY, int a_MoveZ) const { cPiece::cConnector res(a_Connector); - + // Rotate the res connector: switch (a_NumCCWRotations) { @@ -113,12 +113,12 @@ cPiece::cConnector cPiece::RotateMoveConnector(const cConnector & a_Connector, i } } res.m_Pos = RotatePos(a_Connector.m_Pos, a_NumCCWRotations); - + // Move the res connector: res.m_Pos.x += a_MoveX; res.m_Pos.y += a_MoveY; res.m_Pos.z += a_MoveZ; - + return res; } @@ -262,7 +262,7 @@ cPlacedPiece * cPieceGenerator::PlaceStartingPiece(int a_BlockX, int a_BlockZ, c { m_PiecePool.Reset(); int rnd = m_Noise.IntNoise2DInt(a_BlockX, a_BlockZ) / 7; - + // Choose a random one of the starting pieces: cPieces StartingPieces = m_PiecePool.GetStartingPieces(); int Total = 0; @@ -291,7 +291,7 @@ cPlacedPiece * cPieceGenerator::PlaceStartingPiece(int a_BlockX, int a_BlockZ, c StartingPiece = StartingPieces[static_cast(rnd) % StartingPieces.size()]; } rnd = rnd >> 16; - + // Choose a random supported rotation: int Rotations[4] = {0}; int NumRotations = 1; @@ -344,7 +344,7 @@ bool cPieceGenerator::TryPlacePieceAtConnector( /* XM */ { 0, 0, 3, 1, 2, 0}, /* XP */ { 0, 0, 1, 3, 0, 2}, }; - + // Get a list of available connections: const int * RotTable = DirectionRotationTable[a_Connector.m_Direction]; cConnections Connections; @@ -362,7 +362,7 @@ bool cPieceGenerator::TryPlacePieceAtConnector( { continue; } - + // Try fitting each of the piece's connector: cPiece::cConnectors Connectors = (*itrP)->GetConnectors(); auto verticalLimit = (*itrP)->GetVerticalLimit(); @@ -402,7 +402,7 @@ bool cPieceGenerator::TryPlacePieceAtConnector( return false; } ASSERT(WeightTotal > 0); - + // Choose a random connection from the list, based on the weights: int rnd = (m_Noise.IntNoise3DInt(a_Connector.m_Pos.x, a_Connector.m_Pos.y, a_Connector.m_Pos.z) / 7) % WeightTotal; size_t ChosenIndex = 0; @@ -416,13 +416,13 @@ bool cPieceGenerator::TryPlacePieceAtConnector( } } cConnection & Conn = Connections[ChosenIndex]; - + // Place the piece: Vector3i NewPos = Conn.m_Piece->RotatePos(Conn.m_Connector.m_Pos, Conn.m_NumCCWRotations); ConnPos -= NewPos; cPlacedPiece * PlacedPiece = new cPlacedPiece(&a_ParentPiece, *(Conn.m_Piece), ConnPos, Conn.m_NumCCWRotations); a_OutPieces.push_back(PlacedPiece); - + // Add the new piece's connectors to the list of free connectors: cPiece::cConnectors Connectors = Conn.m_Piece->GetConnectors(); for (cPiece::cConnectors::const_iterator itr = Connectors.begin(), end = Connectors.end(); itr != end; ++itr) @@ -434,7 +434,7 @@ bool cPieceGenerator::TryPlacePieceAtConnector( } a_OutConnectors.push_back(cFreeConnector(PlacedPiece, Conn.m_Piece->RotateMoveConnector(*itr, Conn.m_NumCCWRotations, ConnPos.x, ConnPos.y, ConnPos.z))); } - + return true; } @@ -538,10 +538,10 @@ void cBFSPieceGenerator::PlacePieces(int a_BlockX, int a_BlockZ, int a_MaxDepth, { a_OutPieces.clear(); cFreeConnectors ConnectorPool; - + // Place the starting piece: a_OutPieces.push_back(PlaceStartingPiece(a_BlockX, a_BlockZ, ConnectorPool)); - + /* // DEBUG: printf("Placed the starting piece at {%d, %d, %d}\n", a_BlockX, a_BlockY, a_BlockZ); @@ -554,7 +554,7 @@ void cBFSPieceGenerator::PlacePieces(int a_BlockX, int a_BlockZ, int a_MaxDepth, ); DebugConnectorPool(ConnectorPool, 0); //*/ - + // Place pieces at the available connectors: /* Instead of removing them one by one from the pool, we process them sequentially and take note of the last diff --git a/src/Generating/PieceGenerator.h b/src/Generating/PieceGenerator.h index 13ef05e42..1d0e9deda 100644 --- a/src/Generating/PieceGenerator.h +++ b/src/Generating/PieceGenerator.h @@ -33,20 +33,20 @@ class cPiece public: // Force a virtual destructor in all descendants virtual ~cPiece() {} - + struct cConnector { /** Position relative to the piece */ Vector3i m_Pos; - + /** Type of the connector. Any arbitrary number; the generator connects only connectors of opposite (negative) types. */ int m_Type; - + /** Direction in which the connector is facing. Will be matched by the opposite direction for the connecting connector. */ eBlockFace m_Direction; - + cConnector(int a_X, int a_Y, int a_Z, int a_Type, eBlockFace a_Direction); cConnector(const Vector3i & a_Pos, int a_Type, eBlockFace a_Direction); }; @@ -117,15 +117,15 @@ public: /** Returns all of the available connectors that the piece has. Each connector has a (relative) position in the piece, and a type associated with it. */ virtual cConnectors GetConnectors(void) const = 0; - + /** Returns the dimensions of this piece. The dimensions cover the entire piece, there is no block that the piece generates outside of this size. */ virtual Vector3i GetSize(void) const = 0; - + /** Returns the "hitbox" of this piece. A hitbox is what is compared and must not intersect other pieces' hitboxes when generating. */ virtual cCuboid GetHitBox(void) const = 0; - + /** Returns true if the piece can be rotated CCW the specific number of 90-degree turns. */ virtual bool CanRotateCCW(int a_NumRotations) const = 0; @@ -139,7 +139,7 @@ public: } return -1; } - + void SetVerticalStrategy(cVerticalStrategyPtr a_VerticalStrategy) { m_VerticalStrategy = a_VerticalStrategy; @@ -170,10 +170,10 @@ public: /** Returns a copy of the connector that is rotated and then moved by the specified amounts. */ cConnector RotateMoveConnector(const cConnector & a_Connector, int a_NumCCWRotations, int a_MoveX, int a_MoveY, int a_MoveZ) const; - + /** Returns the hitbox after the specified number of rotations and moved so that a_MyConnector is placed at a_ToConnectorPos. */ cCuboid RotateHitBoxToConnector(const cConnector & a_MyConnector, const Vector3i & a_ToConnectorPos, int a_NumCCWRotations) const; - + /** Returns the hitbox after the specified number of CCW rotations and moved by the specified amounts. */ cCuboid RotateMoveHitBox(int a_NumCCWRotations, int a_MoveX, int a_MoveY, int a_MoveZ) const; }; @@ -198,15 +198,15 @@ class cPiecePool public: // Force a virtual destructor in all descendants: virtual ~cPiecePool() {} - + /** Returns a list of pieces that contain the specified connector type. The cPiece pointers returned are managed by the pool and the caller doesn't free them. */ virtual cPieces GetPiecesWithConnector(int a_ConnectorType) = 0; - + /** Returns the pieces that should be used as the starting point. Multiple starting points are supported, one of the returned piece will be chosen. */ virtual cPieces GetStartingPieces(void) = 0; - + /** Returns the relative weight with which the a_NewPiece is to be selected for placing under a_PlacedPiece through a_ExistingConnector. a_ExistingConnector is the original connector, before any movement or rotation is applied to it. This allows the pool to tweak the piece's chances, based on the previous pieces in the tree and the connector used. @@ -219,7 +219,7 @@ public: { return 1; } - + /** Returns the relative weight with which the a_NewPiece is to be selected for placing as the first piece. This allows the pool to tweak the piece's chances. The higher the number returned, the higher the chance the piece will be chosen. 0 means the piece will not be chosen. @@ -232,7 +232,7 @@ public: /** Called after a piece is placed, to notify the pool that it has been used. The pool may adjust the pieces it will return the next time. */ virtual void PiecePlaced(const cPiece & a_Piece) = 0; - + /** Called when the pool has finished the current structure and should reset any piece-counters it has for a new structure. */ virtual void Reset(void) = 0; @@ -247,7 +247,7 @@ class cPlacedPiece { public: cPlacedPiece(const cPlacedPiece * a_Parent, const cPiece & a_Piece, const Vector3i & a_Coords, int a_NumCCWRotations); - + const cPlacedPiece * GetParent (void) const { return m_Parent; } const cPiece & GetPiece (void) const { return *m_Piece; } const Vector3i & GetCoords (void) const { return m_Coords; } @@ -255,23 +255,23 @@ public: const cCuboid & GetHitBox (void) const { return m_HitBox; } int GetDepth (void) const { return m_Depth; } bool HasBeenMovedToGround(void) const { return m_HasBeenMovedToGround; } - + /** Returns the coords as a modifiable object. */ Vector3i & GetCoords(void) { return m_Coords; } - + /** Returns the connector at the specified index, rotated in the actual placement. Undefined behavior if a_Index is out of range. */ cPiece::cConnector GetRotatedConnector(size_t a_Index) const; - + /** Returns a copy of the specified connector, modified to account for the translation and rotation for this placement. */ cPiece::cConnector GetRotatedConnector(const cPiece::cConnector & a_Connector) const; - + /** Moves the placed piece Y-wise by the specified offset. Sets m_HasBeenMovedToGround to true, too. Used eg. by village houses. */ void MoveToGroundBy(int a_OffsetY); - + protected: const cPlacedPiece * m_Parent; const cPiece * m_Piece; @@ -279,7 +279,7 @@ protected: int m_NumCCWRotations; cCuboid m_HitBox; // Hitbox of the placed piece, in world coords int m_Depth; // Depth in the generated piece tree - + /** Set to true once the piece has been moved Y-wise. Used eg. by village houses. */ bool m_HasBeenMovedToGround; @@ -295,11 +295,11 @@ class cPieceGenerator { public: cPieceGenerator(cPiecePool & a_PiecePool, int a_Seed); - + /** Cleans up all the memory used by the placed pieces. Call this utility function instead of freeing the items on your own. */ static void FreePieces(cPlacedPieces & a_PlacedPieces); - + protected: /** The type used for storing a connection from one piece to another, while building the piece tree. */ struct cConnection @@ -308,17 +308,17 @@ protected: cPiece::cConnector m_Connector; // The piece's connector being used (relative non-rotated coords) int m_NumCCWRotations; // Number of rotations necessary to match the two connectors int m_Weight; // Relative chance that this connection will be chosen - + cConnection(cPiece & a_Piece, cPiece::cConnector & a_Connector, int a_NumCCWRotations, int a_Weight); }; typedef std::vector cConnections; - + /** The type used for storing a pool of connectors that will be attempted to expand by another piece. */ struct cFreeConnector { cPlacedPiece * m_Piece; cPiece::cConnector m_Connector; - + cFreeConnector(cPlacedPiece * a_Piece, const cPiece::cConnector & a_Connector); }; typedef std::vector cFreeConnectors; @@ -328,11 +328,11 @@ protected: cNoise m_Noise; int m_Seed; - + /** Selects a starting piece and places it, including its height and rotation. Also puts the piece's connectors in a_OutConnectors. */ cPlacedPiece * PlaceStartingPiece(int a_BlockX, int a_BlockZ, cFreeConnectors & a_OutConnectors); - + /** Tries to place a new piece at the specified (placed) connector. Returns true if successful. */ bool TryPlacePieceAtConnector( const cPlacedPiece & a_ParentPiece, // The existing piece to a new piece should be placed @@ -355,7 +355,7 @@ protected: int a_NumCCWRotations, // Number of rotations for the new piece to align the connector const cPlacedPieces & a_OutPieces // All the already-placed pieces to check ); - + /** DEBUG: Outputs all the connectors in the pool into stdout. a_NumProcessed signals the number of connectors from the pool that should be considered processed (not listed). */ void DebugConnectorPool(const cPieceGenerator::cFreeConnectors & a_ConnectorPool, size_t a_NumProcessed); @@ -388,7 +388,7 @@ class cDFSPieceGenerator : { public: cDFSPieceGenerator(cPiecePool & a_PiecePool, int a_Seed); - + /** Generates a placement for pieces at the specified coords. The Y coord is generated automatically based on the starting piece that is chosen. Caller must free each individual cPlacedPiece in a_OutPieces using cPieceGenerator::FreePieces(). */ diff --git a/src/Generating/PieceStructuresGen.h b/src/Generating/PieceStructuresGen.h index bcad86353..c8e2f2b0c 100644 --- a/src/Generating/PieceStructuresGen.h +++ b/src/Generating/PieceStructuresGen.h @@ -58,7 +58,7 @@ protected: /** The underlying biome generator that defines whether the structure is created or not */ cBiomeGenPtr m_BiomeGen; - + /** The underlying height generator, used to position the prefabs crossing chunk borders if they are set to FitGround. */ cTerrainHeightGenPtr m_HeightGen; diff --git a/src/Generating/Prefab.cpp b/src/Generating/Prefab.cpp index e5e6a1e06..6805167a9 100644 --- a/src/Generating/Prefab.cpp +++ b/src/Generating/Prefab.cpp @@ -26,7 +26,7 @@ static const cPrefab::sDef g_TestPrefabDef = // Hitbox (relative to bounding box): 0, 0, 0, // MinX, MinY, MinZ 6, 5, 6, // MaxX, MaxY, MaxZ - + // Block definitions: ".: 0: 0\n" /* 0 */ "a:112: 0\n" /* netherbrick */ @@ -86,17 +86,17 @@ static const cPrefab::sDef g_TestPrefabDef = "a.....a" "a.....a" "aaaaaaa", - + // Connections: "0: 0, 3, 2: 4\n" "0: 2, 3, 0: 2\n", - + // AllowedRotations: 7, /* 1, 2, 3 CCW rotations */ - + // Merge strategy: cBlockArea::msImprint, - + // ShouldExtendFloor: false, @@ -108,7 +108,7 @@ static const cPrefab::sDef g_TestPrefabDef = // AddWeightIfSame: 1000, - + // MoveToGround: false, }; @@ -139,7 +139,7 @@ cPrefab::cPrefab(const cPrefab::sDef & a_Def) : ParseBlockImage(cm, a_Def.m_Image); ParseConnectors(a_Def.m_Connectors); ParseDepthWeight(a_Def.m_DepthWeight); - + AddRotatedBlockAreas(); } @@ -213,7 +213,7 @@ void cPrefab::AddRotatedBlockAreas(void) m_BlockArea[1].CopyFrom(m_BlockArea[0]); m_BlockArea[1].RotateCCW(); } - + // 2 rotations are the same as mirroring twice; mirroring is faster because it has no reallocations if ((m_AllowedRotations & 0x02) != 0) { @@ -221,7 +221,7 @@ void cPrefab::AddRotatedBlockAreas(void) m_BlockArea[2].MirrorXY(); m_BlockArea[2].MirrorYZ(); } - + // 3 CCW rotations = 1 CW rotation: if ((m_AllowedRotations & 0x04) != 0) { @@ -250,7 +250,7 @@ void cPrefab::Draw(cChunkDesc & a_Dest, const Vector3i & a_Placement, int a_NumR int ChunkStartZ = a_Dest.GetChunkZ() * cChunkDef::Width; Placement.Move(-ChunkStartX, 0, -ChunkStartZ); const cBlockArea & Image = m_BlockArea[a_NumRotations]; - + // If the placement is outside this chunk, bail out: if ( (Placement.x > cChunkDef::Width) || (Placement.x + Image.GetSizeX() < 0) || @@ -259,10 +259,10 @@ void cPrefab::Draw(cChunkDesc & a_Dest, const Vector3i & a_Placement, int a_NumR { return; } - + // Write the image: a_Dest.WriteBlockArea(Image, Placement.x, Placement.y, Placement.z, m_MergeStrategy); - + // If requested, draw the floor (from the bottom of the prefab down to the nearest non-air) if (m_ShouldExtendFloor) { @@ -332,7 +332,7 @@ int cPrefab::GetPieceWeight(const cPlacedPiece & a_PlacedPiece, const cPiece::cC // Use the default or per-depth weight: cDepthWeight::const_iterator itr = m_DepthWeight.find(a_PlacedPiece.GetDepth() + 1); int res = (itr == m_DepthWeight.end()) ? m_DefaultWeight : itr->second; - + // If the piece is the same as the parent, apply the m_AddWeightIfSame modifier: const cPiece * ParentPiece = &a_PlacedPiece.GetPiece(); const cPiece * ThisPiece = this; @@ -378,14 +378,14 @@ void cPrefab::SetAllowedRotations(int a_AllowedRotations) void cPrefab::ParseCharMap(CharMap & a_CharMapOut, const char * a_CharMapDef) { ASSERT(a_CharMapDef != nullptr); - + // Initialize the charmap to all-invalid values: for (size_t i = 0; i < ARRAYCOUNT(a_CharMapOut); i++) { a_CharMapOut[i].m_BlockType = 0; a_CharMapOut[i].m_BlockMeta = 16; // Mark unassigned entries with a meta that is impossible otherwise } - + // Process the lines in the definition: AStringVector Lines = StringSplitAndTrim(a_CharMapDef, "\n"); for (AStringVector::const_iterator itr = Lines.begin(), end = Lines.end(); itr != end; ++itr) @@ -439,7 +439,7 @@ void cPrefab::ParseBlockImage(const CharMap & a_CharMap, const char * a_BlockIma void cPrefab::ParseConnectors(const char * a_ConnectorsDef) { ASSERT(a_ConnectorsDef != nullptr); - + AStringVector Lines = StringSplitAndTrim(a_ConnectorsDef, "\n"); for (AStringVector::const_iterator itr = Lines.begin(), end = Lines.end(); itr != end; ++itr) { @@ -460,7 +460,7 @@ void cPrefab::ParseConnectors(const char * a_ConnectorsDef) LOGWARNING("Bad prefab Connector coords definition: \"%s\", skipping.", Defs[1].c_str()); continue; } - + // Check that the BlockFace is within range: int BlockFace = atoi(Defs[2].c_str()); if ((BlockFace < 0) || (BlockFace >= 6)) @@ -489,10 +489,10 @@ void cPrefab::ParseDepthWeight(const char * a_DepthWeightDef) { return; } - + // Split into individual records: "Record | Record | Record" AStringVector Defs = StringSplitAndTrim(a_DepthWeightDef, "|"); - + // Add each record's contents: for (AStringVector::const_iterator itr = Defs.begin(), end = Defs.end(); itr != end; ++itr) { @@ -503,7 +503,7 @@ void cPrefab::ParseDepthWeight(const char * a_DepthWeightDef) LOGWARNING("Bad prefab DepthWeight record: \"%s\", skipping.", itr->c_str()); continue; } - + // Parse depth: int Depth = atoi(Components[0].c_str()); if ((Depth == 0) && (Components[0] != "0")) @@ -511,7 +511,7 @@ void cPrefab::ParseDepthWeight(const char * a_DepthWeightDef) LOGWARNING("Bad prefab DepthWeight record, cannot parse depth \"%s\", skipping.", Components[0].c_str()); continue; } - + // Parse weight: int Weight = atoi(Components[1].c_str()); if ((Weight == 0) && (Components[1] != "0")) @@ -519,7 +519,7 @@ void cPrefab::ParseDepthWeight(const char * a_DepthWeightDef) LOGWARNING("Bad prefab DepthWeight record, cannot parse weight \"%s\", skipping.", Components[1].c_str()); continue; } - + // Save to map: ASSERT(m_DepthWeight.find(Depth) == m_DepthWeight.end()); // Not a duplicate m_DepthWeight[Depth] = Weight; diff --git a/src/Generating/Prefab.h b/src/Generating/Prefab.h index c62a68f97..5f937260d 100644 --- a/src/Generating/Prefab.h +++ b/src/Generating/Prefab.h @@ -37,31 +37,31 @@ public: int m_SizeX; int m_SizeY; int m_SizeZ; - + /** The hitbox used for collision-checking between prefabs. Relative to the bounds. */ int m_HitboxMinX, m_HitboxMinY, m_HitboxMinZ; int m_HitboxMaxX, m_HitboxMaxY, m_HitboxMaxZ; - + /** The mapping between characters in m_Image and the blocktype / blockmeta. Format: "Char: BlockType: BlockMeta \n Char: BlockType : BlockMeta \n ..." */ const char * m_CharMap; - + /** The actual image to be used for the prefab. Organized YZX (Y changes the least often). Each character represents a single block, the type is mapped through m_CharMap. */ const char * m_Image; - + /** List of connectors. Format: "Type: X, Y, Z : Direction \n Type : X, Y, Z : Direction \n ...". Type is an arbitrary number, Direction is the BlockFace constant value (0 .. 5). */ const char * m_Connectors; - + /** Bitmask specifying the allowed rotations. N rotations CCW are allowed if bit N is set. */ int m_AllowedRotations; - + /** The merge strategy to use while drawing the prefab. */ cBlockArea::eMergeStrategy m_MergeStrategy; - + /** If set to true, the prefab will extend its lowermost blocks until a solid block is found, thus creating a foundation for the prefab. This is used for houses to be "on the ground", as well as nether fortresses not to float. */ @@ -69,7 +69,7 @@ public: /** Chance of this piece being used, if no other modifier is active. */ int m_DefaultWeight; - + /** Chances of this piece being used, per depth of the generated piece tree. The starting piece has a depth of 0, the pieces connected to it are depth 1, etc. The specified depth stands for the depth of the new piece (not the existing already-placed piece), @@ -77,56 +77,56 @@ public: Format: "Depth : Weight | Depth : Weight | Depth : Weight ..." Depths that are not specified will use the m_DefaultWeight value. */ const char * m_DepthWeight; - + /** The weight to add to this piece's base per-depth chance if the previous piece is the same. Can be positive or negative. This is used e. g. to make nether bridges prefer spanning multiple segments or to penalize turrets next to each other. */ int m_AddWeightIfSame; - + /** If true, the piece will be moved Y-wise so that its first connector is sitting on the terrain. This is used e. g. for village houses. */ bool m_MoveToGround; }; - - + + /** Creates a prefab from the provided definition. */ cPrefab(const sDef & a_Def); - + /** Creates a prefab based on the given BlockArea and allowed rotations. */ cPrefab(const cBlockArea & a_Image, int a_AllowedRotations); - + /** Creates a prefab based on the given BlockArea. Allowed rotations can be added later on using SetAllowedRotations(). */ cPrefab(const cBlockArea & a_Image); - + /** Creates a prefab based on the specified block data, using the char-to-block map in a_BlockDefinitions. Allowed rotations can be added later on using SetAllowedRotations(). */ cPrefab(const AString & a_BlockDefinitions, const AString & a_BlockData, int a_SizeX, int a_SizeY, int a_SizeZ); - + /** Draws the prefab into the specified chunk, according to the placement stored in the PlacedPiece. */ void Draw(cChunkDesc & a_Dest, const cPlacedPiece * a_Placement) const; - + /** Draws the prefab into the specified chunks, according to the specified placement and rotations. */ void Draw(cChunkDesc & a_Dest, const Vector3i & a_Placement, int a_NumRotations) const; - + /** Returns true if the prefab has any connector of the specified type. */ bool HasConnectorType(int a_ConnectorType) const; - + /** Returns the weight (chance) of this prefab generating as the next piece after the specified placed piece. PiecePool implementations can use this for their GetPieceWeight() implementations. */ int GetPieceWeight(const cPlacedPiece & a_PlacedPiece, const cPiece::cConnector & a_ExistingConnector) const; - + /** Sets the (unmodified) DefaultWeight property for this piece. */ void SetDefaultWeight(int a_DefaultWeight); - + /** Returns the unmodified DefaultWeight property for the piece. */ int GetDefaultWeight(void) const { return m_DefaultWeight; } - + /** Sets the AddWeightIfSame member, that is used to modify the weight when the previous piece is the same prefab */ void SetAddWeightIfSame(int a_AddWeightIfSame) { m_AddWeightIfSame = a_AddWeightIfSame; } - + /** Adds the specified connector to the list of connectors this piece supports. */ void AddConnector(int a_RelX, int a_RelY, int a_RelZ, eBlockFace a_Direction, int a_Type); - + /** Returns whether the prefab should be moved Y-wise to ground before drawing, rather than staying at the coords governed by the connectors. */ bool ShouldMoveToGround(void) const { return m_MoveToGround; } @@ -156,30 +156,30 @@ protected: BLOCKTYPE m_BlockType; NIBBLETYPE m_BlockMeta; }; - + /** Maps letters in the sDef::m_Image onto a sBlockTypeDef block type definition. */ typedef sBlockTypeDef CharMap[256]; - + /** Maps generator tree depth to weight. */ typedef std::map cDepthWeight; - - + + /** The cBlockArea that contains the block definitions for the prefab. The index identifies the number of CCW rotations applied (0 = no rotation, 1 = 1 CCW rotation, ...). */ cBlockArea m_BlockArea[4]; - + /** The size of the prefab */ Vector3i m_Size; - + /** The hitbox used for collision-checking between prefabs. */ cCuboid m_HitBox; - + /** The connectors through which the piece connects to other pieces */ cConnectors m_Connectors; - + /** Bitmask, bit N set -> N rotations CCW supported */ int m_AllowedRotations; - + /** The merge strategy to use when drawing the prefab into a block area */ cBlockArea::eMergeStrategy m_MergeStrategy; @@ -190,14 +190,14 @@ protected: /** Chance of this piece being used, if no other modifier is active. */ int m_DefaultWeight; - + /** Chances of this piece being used, per depth of the generated piece tree. The starting piece has a depth of 0, the pieces connected to it are depth 1, etc. The specified depth stands for the depth of the new piece (not the existing already-placed piece), so valid depths start at 1. Depths that are not specified will use the m_DefaultWeight value. */ cDepthWeight m_DepthWeight; - + /** The weight to add to this piece's base per-depth chance if the previous piece is the same. Can be positive or negative. This is used e. g. to make nether bridges prefer spanning multiple segments or to penalize turrets next to each other. */ @@ -206,24 +206,24 @@ protected: /** If true, the piece will be moved Y-wise so that its first connector is sitting on the terrain. This is used e. g. for village houses. */ bool m_MoveToGround; - - + + // cPiece overrides: virtual cConnectors GetConnectors(void) const override; virtual Vector3i GetSize(void) const override; virtual cCuboid GetHitBox(void) const override; virtual bool CanRotateCCW(int a_NumRotations) const override; - + /** Based on the m_AllowedRotations, adds rotated cBlockAreas to the m_BlockArea array. To be called only from this class's constructor! */ void AddRotatedBlockAreas(void); - + /** Parses the CharMap in the definition into a CharMap binary data used for translating the definition into BlockArea. */ void ParseCharMap(CharMap & a_CharMapOut, const char * a_CharMapDef); - + /** Parses the Image in the definition into m_BlockArea[0]'s block types and metas, using the specified CharMap. */ void ParseBlockImage(const CharMap & a_CharMap, const char * a_BlockImage); - + /** Parses the connectors definition text into m_Connectors member. */ void ParseConnectors(const char * a_ConnectorsDef); }; diff --git a/src/Generating/PrefabPiecePool.h b/src/Generating/PrefabPiecePool.h index 1c51c4963..af342f023 100644 --- a/src/Generating/PrefabPiecePool.h +++ b/src/Generating/PrefabPiecePool.h @@ -30,7 +30,7 @@ class cPrefabPiecePool : public: /** Creates an empty instance. Prefabs can be added by calling AddPieceDefs() and AddStartingPieceDefs(). */ cPrefabPiecePool(void); - + /** Creates a piece pool with prefabs from the specified definitions. If both a_PieceDefs and a_StartingPieceDefs are given, only the a_StartingPieceDefs are used as starting pieces for the pool, and they do not participate in the generation any further. @@ -44,22 +44,22 @@ public: const cPrefab::sDef * a_StartingPieceDefs, size_t a_NumStartingPieceDefs, int a_DefaultStartingPieceHeight = -1 ); - + /** Creates a pool and loads the contents of the specified file into it. If a_LogWarnings is true, logs a warning to console when loading fails. */ cPrefabPiecePool(const AString & a_FileName, bool a_LogWarnings); /** Destroys the pool, freeing all pieces. */ ~cPrefabPiecePool(); - + /** Removes and frees all pieces from this pool. */ void Clear(void); - + /** Adds pieces from the specified definitions into m_AllPieces. Also adds the pieces into the m_PiecesByConnector map. May be called multiple times with different PieceDefs, will add all such pieces. */ void AddPieceDefs(const cPrefab::sDef * a_PieceDefs, size_t a_NumPieceDefs); - + /** Adds pieces from the specified definitions into m_StartingPieces. Doesn't add them to the m_PiecesByConnector map. May be called multiple times with different PieceDefs, will add all such pieces. @@ -70,7 +70,7 @@ public: size_t a_NumStartingPieceDefs, int a_DefaultPieceHeight = -1 ); - + /** Loads the pieces from the specified file. Returns true if successful, false on error. If a_LogWarnings is true, logs a warning to console when loading fails. */ bool LoadFromFile(const AString & a_FileName, bool a_LogWarnings); @@ -132,11 +132,11 @@ protected: /** All the pieces that are allowed for building. This is the list that's used for memory allocation and deallocation for the pieces. */ cPieces m_AllPieces; - + /** The pieces that are used as starting pieces. This list is not shared and the pieces need deallocation. */ cPieces m_StartingPieces; - + /** The map that has all pieces by their connector types The pieces are copies out of m_AllPieces and shouldn't be ever delete-d. */ cPiecesMap m_PiecesByConnector; @@ -158,7 +158,7 @@ protected: /** The block type used for the village roads if the road is on water. */ BLOCKTYPE m_VillageWaterRoadBlockType; - + /** The block meta used for the village roads if the road is on water. */ NIBBLETYPE m_VillageWaterRoadBlockMeta; @@ -196,7 +196,7 @@ protected: const AString & a_PieceName, bool a_LogWarnings ); - + /** Reads a single piece's connectors from the cubeset file parsed into the specified Lua state. The piece's definition table is expected to be at the top of the Lua stack. Returns true on success, false on failure. diff --git a/src/Generating/Ravines.cpp b/src/Generating/Ravines.cpp index d79697a79..40022aefb 100644 --- a/src/Generating/Ravines.cpp +++ b/src/Generating/Ravines.cpp @@ -22,7 +22,7 @@ struct cRavDefPoint int m_Radius; int m_Top; int m_Bottom; - + cRavDefPoint(int a_BlockX, int a_BlockZ, int a_Radius, int a_Top, int a_Bottom) : m_BlockX(a_BlockX), m_BlockZ(a_BlockZ), @@ -46,23 +46,23 @@ class cStructGenRavines::cRavine : cRavDefPoints m_Points; - + /** Generates the shaping defpoints for the ravine, based on the ravine block coords and noise */ void GenerateBaseDefPoints(int a_BlockX, int a_BlockZ, int a_Size, cNoise & a_Noise); - + /** Refines (adds and smooths) defpoints from a_Src into a_Dst */ void RefineDefPoints(const cRavDefPoints & a_Src, cRavDefPoints & a_Dst); - + /** Does one round of smoothing, two passes of RefineDefPoints() */ void Smooth(void); - + /** Linearly interpolates the points so that the maximum distance between two neighbors is max 1 block */ void FinishLinear(void); - + public: - + cRavine(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ, int a_Size, cNoise & a_Noise); - + #ifdef _DEBUG /** Exports itself as a SVG line definition */ AString ExportAsSVG(int a_Color, int a_OffsetX = 0, int a_OffsetZ = 0) const; @@ -109,11 +109,11 @@ cStructGenRavines::cRavine::cRavine(int a_GridX, int a_GridZ, int a_OriginX, int { // Calculate the ravine shape-defining points: GenerateBaseDefPoints(a_OriginX, a_OriginZ, a_Size, a_Noise); - + // Smooth the ravine. Two passes are needed: Smooth(); Smooth(); - + // Linearly interpolate the neighbors so that they're close enough together: FinishLinear(); } @@ -126,18 +126,18 @@ void cStructGenRavines::cRavine::GenerateBaseDefPoints(int a_BlockX, int a_Block { // Modify the size slightly to have different-sized ravines (1 / 2 to 1 / 1 of a_Size): a_Size = (512 + ((a_Noise.IntNoise3DInt(19 * a_BlockX, 11 * a_BlockZ, a_BlockX + a_BlockZ) / 17) % 512)) * a_Size / 1024; - + // The complete offset of the ravine from its cellpoint, up to 2 * a_Size in each direction int OffsetX = (((a_Noise.IntNoise3DInt(50 * a_BlockX, 30 * a_BlockZ, 0) / 9) % (2 * a_Size)) + ((a_Noise.IntNoise3DInt(30 * a_BlockX, 50 * a_BlockZ, 1000) / 7) % (2 * a_Size)) - 2 * a_Size) / 2; int OffsetZ = (((a_Noise.IntNoise3DInt(50 * a_BlockX, 30 * a_BlockZ, 2000) / 7) % (2 * a_Size)) + ((a_Noise.IntNoise3DInt(30 * a_BlockX, 50 * a_BlockZ, 3000) / 9) % (2 * a_Size)) - 2 * a_Size) / 2; int CenterX = a_BlockX + OffsetX; int CenterZ = a_BlockZ + OffsetZ; - + // Get the base angle in which the ravine "axis" goes: float Angle = static_cast((static_cast((a_Noise.IntNoise3DInt(20 * a_BlockX, 70 * a_BlockZ, 6000) / 9) % 16384)) / 16384.0 * M_PI); float xc = sinf(Angle); float zc = cosf(Angle); - + // Calculate the definition points and radii: int MaxRadius = static_cast(sqrt(12.0 + ((a_Noise.IntNoise2DInt(61 * a_BlockX, 97 * a_BlockZ) / 13) % a_Size) / 16)); int Top = 32 + ((a_Noise.IntNoise2DInt(13 * a_BlockX, 17 * a_BlockZ) / 23) % 32); @@ -234,10 +234,10 @@ void cStructGenRavines::cRavine::FinishLinear(void) // For each segment, use Bresenham's line algorithm to draw a "line" of defpoints // _X 2012_07_20: I tried modifying this algorithm to produce "thick" lines (only one coord change per point) // But the results were about the same as the original, so I disposed of it again - no need to use twice the count of points - + cRavDefPoints Pts; std::swap(Pts, m_Points); - + m_Points.reserve(Pts.size() * 3); int PrevX = Pts.front().m_BlockX; int PrevZ = Pts.front().m_BlockZ; @@ -299,12 +299,12 @@ AString cStructGenRavines::cRavine::ExportAsSVG(int a_Color, int a_OffsetX, int AppendPrintf(SVG, "\n", a_OffsetX + m_OriginX, a_OffsetZ + m_OriginZ - 5, a_OffsetX + m_OriginX, a_OffsetZ + m_OriginZ + 5 ); - + // A gray line from the base point to the first point of the ravine, for identification: AppendPrintf(SVG, "\n", a_OffsetX + m_OriginX, a_OffsetZ + m_OriginZ, a_OffsetX + m_Points.front().m_BlockX, a_OffsetZ + m_Points.front().m_BlockZ ); - + // Offset guides: if (a_OffsetX > 0) { @@ -344,7 +344,7 @@ void cStructGenRavines::cRavine::DrawIntoChunk(cChunkDesc & a_ChunkDesc) // Cannot intersect, bail out early continue; } - + // Carve out a cylinder around the xz point, m_Radius in diameter, from Bottom to Top: int RadiusSq = itr->m_Radius * itr->m_Radius; // instead of doing sqrt for each distance, we do sqr of the radius int DifX = BlockStartX - itr->m_BlockX; // substitution for faster calc @@ -358,7 +358,7 @@ void cStructGenRavines::cRavine::DrawIntoChunk(cChunkDesc & a_ChunkDesc) a_ChunkDesc.SetBlockType(x, 4, z, E_BLOCK_LAPIS_ORE); } #endif // _DEBUG - + int DistSq = (DifX + x) * (DifX + x) + (DifZ + z) * (DifZ + z); if (DistSq <= RadiusSq) { diff --git a/src/Generating/Ravines.h b/src/Generating/Ravines.h index b11037433..0bcdffa3b 100644 --- a/src/Generating/Ravines.h +++ b/src/Generating/Ravines.h @@ -22,13 +22,13 @@ class cStructGenRavines : public: cStructGenRavines(int a_Seed, int a_Size); - + protected: class cRavine; // fwd: Ravines.cpp - + cNoise m_Noise; int m_Size; // Max size, in blocks, of the ravines generated - + // cGridStructGen overrides: virtual cStructurePtr CreateStructure(int a_GridX, int a_GridZ, int a_OriginX, int a_OriginZ) override; diff --git a/src/Generating/RoughRavines.cpp b/src/Generating/RoughRavines.cpp index a7621569d..c8e4fc9dd 100644 --- a/src/Generating/RoughRavines.cpp +++ b/src/Generating/RoughRavines.cpp @@ -18,7 +18,7 @@ class cRoughRavine : public cGridStructGen::cStructure { typedef cGridStructGen::cStructure super; - + public: cRoughRavine( int a_Seed, size_t a_Size, @@ -44,15 +44,15 @@ public: m_DefPoints[0].Set (a_OriginX - OfsX, a_OriginZ - OfsZ, 1, a_CeilingHeightEdge1, a_FloorHeightEdge1); m_DefPoints[Half].Set(static_cast(a_OriginX), static_cast(a_OriginZ), a_CenterWidth, a_CeilingHeightCenter, a_FloorHeightCenter); m_DefPoints[Max].Set (a_OriginX + OfsX, a_OriginZ + OfsZ, 1, a_CeilingHeightEdge2, a_FloorHeightEdge2); - + // Calculate the points in between, recursively: SubdivideLine(0, Half); SubdivideLine(Half, Max); - + // Initialize the per-height radius modifiers: InitPerHeightRadius(a_GridX, a_GridZ); } - + protected: struct sRavineDefPoint { @@ -61,7 +61,7 @@ protected: float m_Radius; float m_Top; float m_Bottom; - + void Set(float a_X, float a_Z, float a_Radius, float a_Top, float a_Bottom) { m_X = a_X; @@ -72,21 +72,21 @@ protected: } }; typedef std::vector sRavineDefPoints; - + int m_Seed; - + cNoise m_Noise; - + int m_MaxSize; - + sRavineDefPoints m_DefPoints; - + float m_Roughness; - + /** Number to add to the radius based on the height. This creates the "ledges" in the ravine walls. */ float m_PerHeightRadius[cChunkDef::Height]; - - + + /** Recursively subdivides the line between the points of the specified index. Sets the midpoint to the center of the line plus or minus a random offset, then calls itself for each half of the new line. */ @@ -116,7 +116,7 @@ protected: } size_t MidIdx = (a_Idx1 + a_Idx2) / 2; m_DefPoints[MidIdx].Set(MidX, MidZ, MidR, MidT, MidB); - + // Recurse the two halves, if they are worth recursing: if (MidIdx - a_Idx1 > 1) { @@ -127,8 +127,8 @@ protected: SubdivideLine(MidIdx, a_Idx2); } } - - + + void InitPerHeightRadius(int a_GridX, int a_GridZ) { int h = 0; @@ -150,8 +150,8 @@ protected: h += NumBlocks; } } - - + + virtual void DrawIntoChunk(cChunkDesc & a_ChunkDesc) override { int BlockStartX = a_ChunkDesc.GetChunkX() * cChunkDef::Width; @@ -170,7 +170,7 @@ protected: // Cannot intersect, bail out early continue; } - + // Carve out a cylinder around the xz point, up to (m_Radius + 2) in diameter, from Bottom to Top: // On each height level, use m_PerHeightRadius[] to modify the actual radius used // EnlargedRadiusSq is the square of the radius enlarged by the maximum m_PerHeightRadius offset - anything outside it will never be touched. @@ -186,14 +186,14 @@ protected: a_ChunkDesc.SetBlockType(x, 4, z, E_BLOCK_LAPIS_ORE); } #endif // _DEBUG - + // If the column is outside the enlarged radius, bail out completely float DistSq = (DifX + x) * (DifX + x) + (DifZ + z) * (DifZ + z); if (DistSq > RadiusSq) { continue; } - + int Top = std::min(static_cast(ceilf(itr->m_Top)), +cChunkDef::Height); for (int y = std::max(static_cast(floorf(itr->m_Bottom)), 1); y <= Top; y++) { @@ -284,7 +284,7 @@ cGridStructGen::cStructurePtr cRoughRavines::CreateStructure(int a_GridX, int a_ float CeilingHeightEdge1 = m_Noise.IntNoise2DInRange(a_GridX + 60, a_GridZ, m_MinCeilingHeightEdge, m_MaxCeilingHeightEdge); float CeilingHeightEdge2 = m_Noise.IntNoise2DInRange(a_GridX + 70, a_GridZ, m_MinCeilingHeightEdge, m_MaxCeilingHeightEdge); float CeilingHeightCenter = m_Noise.IntNoise2DInRange(a_GridX + 80, a_GridZ, m_MinCeilingHeightCenter, m_MaxCeilingHeightCenter); - + // Create a ravine: return cStructurePtr(new cRoughRavine( m_Seed, diff --git a/src/Generating/RoughRavines.h b/src/Generating/RoughRavines.h index 4c905b641..a5ce13357 100644 --- a/src/Generating/RoughRavines.h +++ b/src/Generating/RoughRavines.h @@ -18,7 +18,7 @@ class cRoughRavines : public cGridStructGen { typedef cGridStructGen super; - + public: cRoughRavines( int a_Seed, @@ -31,22 +31,22 @@ public: float a_MaxCeilingHeightCenter, float a_MinCeilingHeightCenter, int a_GridSize, int a_MaxOffset ); - + protected: int m_Seed; - + /** Maximum size of the ravine, in each of the X / Z axis */ int m_MaxSize; - + /** Minimum size of the ravine */ int m_MinSize; /** Maximum width of the ravine's center, in blocks */ float m_MaxCenterWidth; - + /** Minimum width of the ravine's center, in blocks */ float m_MinCenterWidth; - + /** Maximum roughness of the ravine */ float m_MaxRoughness; @@ -55,25 +55,25 @@ protected: /** Maximum floor height at the ravine's edge */ float m_MaxFloorHeightEdge; - + /** Minimum floor height at the ravine's edge */ float m_MinFloorHeightEdge; - + /** Maximum floor height at the ravine's center */ float m_MaxFloorHeightCenter; - + /** Minimum floor height at the ravine's center */ float m_MinFloorHeightCenter; - + /** Maximum ceiling height at the ravine's edge */ float m_MaxCeilingHeightEdge; - + /** Minimum ceiling height at the ravine's edge */ float m_MinCeilingHeightEdge; - + /** Maximum ceiling height at the ravine's center */ float m_MaxCeilingHeightCenter; - + /** Minimum ceiling height at the ravine's center */ float m_MinCeilingHeightCenter; diff --git a/src/Generating/ShapeGen.cpp b/src/Generating/ShapeGen.cpp index 43601ee20..e3de6e733 100644 --- a/src/Generating/ShapeGen.cpp +++ b/src/Generating/ShapeGen.cpp @@ -83,7 +83,7 @@ cTerrainShapeGenPtr cTerrainShapeGen::CreateShapeGen(cIniFile & a_IniFile, cBiom LOGWARN("[Generator] ShapeGen value not set in world.ini, using \"BiomalNoise3D\"."); shapeGenName = "BiomalNoise3D"; } - + // If the shapegen is HeightMap, redirect to older HeightMap-based generators: if (NoCaseCompare(shapeGenName, "HeightMap") == 0) { @@ -133,10 +133,10 @@ cTerrainShapeGenPtr cTerrainShapeGen::CreateShapeGen(cIniFile & a_IniFile, cBiom a_IniFile.SetValue("Generator", "ShapeGen", "BiomalNoise3D"); return CreateShapeGen(a_IniFile, a_BiomeGen, a_Seed, a_CacheOffByDefault); } - + // Read the settings: res->InitializeShapeGen(a_IniFile); - + return res; } diff --git a/src/Generating/StructGen.cpp b/src/Generating/StructGen.cpp index edd2f6b87..9b4eb67ef 100644 --- a/src/Generating/StructGen.cpp +++ b/src/Generating/StructGen.cpp @@ -19,9 +19,9 @@ void cStructGenTrees::GenFinish(cChunkDesc & a_ChunkDesc) { int ChunkX = a_ChunkDesc.GetChunkX(); int ChunkZ = a_ChunkDesc.GetChunkZ(); - + cChunkDesc WorkerDesc(ChunkX, ChunkZ); - + // Generate trees: for (int x = 0; x <= 2; x++) { @@ -29,14 +29,14 @@ void cStructGenTrees::GenFinish(cChunkDesc & a_ChunkDesc) for (int z = 0; z <= 2; z++) { int BaseZ = ChunkZ + z - 1; - + cChunkDesc * Dest; if ((x != 1) || (z != 1)) { Dest = &WorkerDesc; WorkerDesc.SetChunkCoords(BaseX, BaseZ); - + // TODO: This may cause a lot of wasted calculations, instead of pulling data out of a single (cChunkDesc) cache cChunkDesc::Shape workerShape; @@ -66,7 +66,7 @@ void cStructGenTrees::GenFinish(cChunkDesc & a_ChunkDesc) ApplyTreeImage(ChunkX, ChunkZ, a_ChunkDesc, OutsideLogs, IgnoredOverflow); } // for z } // for x - + // Update the heightmap: for (int x = 0; x < cChunkDef::Width; x++) { @@ -97,9 +97,9 @@ void cStructGenTrees::GenerateSingleTree( { int x = (m_Noise.IntNoise3DInt(a_ChunkX + a_ChunkZ, a_ChunkZ, a_Seq) / 19) % cChunkDef::Width; int z = (m_Noise.IntNoise3DInt(a_ChunkX - a_ChunkZ, a_Seq, a_ChunkZ) / 19) % cChunkDef::Width; - + int Height = a_ChunkDesc.GetHeight(x, z); - + if ((Height <= 0) || (Height >= 230)) { return; @@ -111,7 +111,7 @@ void cStructGenTrees::GenerateSingleTree( { return; } - + sSetBlockVector TreeLogs, TreeOther; GetTreeImageByBiome( a_ChunkX * cChunkDef::Width + x, Height + 1, a_ChunkZ * cChunkDef::Width + z, @@ -148,7 +148,7 @@ void cStructGenTrees::GenerateSingleTree( } } } - + ApplyTreeImage(a_ChunkX, a_ChunkZ, a_ChunkDesc, TreeOther, a_OutsideOther); ApplyTreeImage(a_ChunkX, a_ChunkZ, a_ChunkDesc, TreeLogs, a_OutsideLogs); } @@ -185,11 +185,11 @@ void cStructGenTrees::ApplyTreeImage( a_ChunkDesc.SetBlockTypeMeta(itr->m_RelX, itr->m_RelY, itr->m_RelZ, itr->m_BlockType, itr->m_BlockMeta); break; } - + } // switch (GetBlock()) continue; } - + // Outside the chunk, push into a_Overflow. // Don't check if already present there, by separating logs and others we don't need the checks anymore: a_Overflow.push_back(*itr); @@ -279,20 +279,20 @@ void cStructGenLakes::GenFinish(cChunkDesc & a_ChunkDesc) { int ChunkX = a_ChunkDesc.GetChunkX(); int ChunkZ = a_ChunkDesc.GetChunkZ(); - + for (int z = -1; z < 2; z++) for (int x = -1; x < 2; x++) { if (((m_Noise.IntNoise2DInt(ChunkX + x, ChunkZ + z) / 17) % 100) > m_Probability) { continue; } - + cBlockArea Lake; CreateLakeImage(ChunkX + x, ChunkZ + z, a_ChunkDesc.GetMinHeight(), Lake); - + int OfsX = Lake.GetOriginX() + x * cChunkDef::Width; int OfsZ = Lake.GetOriginZ() + z * cChunkDef::Width; - + // Merge the lake into the current data a_ChunkDesc.WriteBlockArea(Lake, OfsX, Lake.GetOriginY(), OfsZ, cBlockArea::msLake); } // for x, z - neighbor chunks @@ -306,7 +306,7 @@ void cStructGenLakes::CreateLakeImage(int a_ChunkX, int a_ChunkZ, int a_MaxLakeH { a_Lake.Create(16, 8, 16); a_Lake.Fill(cBlockArea::baTypes, E_BLOCK_SPONGE); // Sponge is the NOP blocktype for lake merging strategy - + // Make a random position in the chunk by using a random 16 block XZ offset and random height up to chunk's max height minus 6 int MinHeight = std::max(a_MaxLakeHeight - 6, 2); int Rnd = m_Noise.IntNoise3DInt(a_ChunkX, 128, a_ChunkZ) / 11; @@ -318,9 +318,9 @@ void cStructGenLakes::CreateLakeImage(int a_ChunkX, int a_ChunkZ, int a_MaxLakeH Rnd = m_Noise.IntNoise3DInt(a_ChunkX, 512, a_ChunkZ) / 13; // Random height [1 .. MinHeight] with preference to center heights int HeightY = 1 + (((Rnd & 0x1ff) % MinHeight) + (((Rnd >> 9) & 0x1ff) % MinHeight)) / 2; - + a_Lake.SetOrigin(OffsetX, HeightY, OffsetZ); - + // Hollow out a few bubbles inside the blockarea: int NumBubbles = 4 + ((Rnd >> 18) & 0x03); // 4 .. 7 bubbles BLOCKTYPE * BlockTypes = a_Lake.GetBlockTypes(); @@ -371,9 +371,9 @@ void cStructGenLakes::CreateLakeImage(int a_ChunkX, int a_ChunkZ, int a_MaxLakeH } } // for z, x } // for y - + // TODO: Turn sponge next to lava into stone - + // a_Lake.SaveToSchematicFile(Printf("Lake_%d_%d.schematic", a_ChunkX, a_ChunkZ)); } @@ -401,7 +401,7 @@ void cStructGenDirectOverhangs::GenFinish(cChunkDesc & a_ChunkDesc) { return; } - + HEIGHTTYPE MaxHeight = a_ChunkDesc.GetMaxHeight(); const int SEGMENT_HEIGHT = 8; @@ -410,7 +410,7 @@ void cStructGenDirectOverhangs::GenFinish(cChunkDesc & a_ChunkDesc) // Interpolate the chunk in 16 * SEGMENT_HEIGHT * 16 "segments", each SEGMENT_HEIGHT blocks high and each linearly interpolated separately. // Have two buffers, one for the lowest floor and one for the highest floor, so that Y-interpolation can be done between them // Then swap the buffers and use the previously-top one as the current-bottom, without recalculating it. - + int FloorBuf1[17 * 17]; int FloorBuf2[17 * 17]; int * FloorHi = FloorBuf1; @@ -418,7 +418,7 @@ void cStructGenDirectOverhangs::GenFinish(cChunkDesc & a_ChunkDesc) int BaseX = a_ChunkDesc.GetChunkX() * cChunkDef::Width; int BaseZ = a_ChunkDesc.GetChunkZ() * cChunkDef::Width; int BaseY = 63; - + // Interpolate the lowest floor: for (int z = 0; z <= 16 / INTERPOL_Z; z++) for (int x = 0; x <= 16 / INTERPOL_X; x++) { @@ -428,7 +428,7 @@ void cStructGenDirectOverhangs::GenFinish(cChunkDesc & a_ChunkDesc) 256; } // for x, z - FloorLo[] LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorLo); - + // Interpolate segments: for (int Segment = BaseY; Segment < MaxHeight; Segment += SEGMENT_HEIGHT) { @@ -441,12 +441,12 @@ void cStructGenDirectOverhangs::GenFinish(cChunkDesc & a_ChunkDesc) ); } // for x, z - FloorLo[] LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorHi); - + // Interpolate between FloorLo and FloorHi: for (int z = 0; z < 16; z++) for (int x = 0; x < 16; x++) { EMCSBiome biome = a_ChunkDesc.GetBiome(x, z); - + if ((biome == biExtremeHills) || (biome == biExtremeHillsEdge)) { int Lo = FloorLo[x + 17 * z] / 256; @@ -462,7 +462,7 @@ void cStructGenDirectOverhangs::GenFinish(cChunkDesc & a_ChunkDesc) break; } // if (biome) } // for z, x - + // Swap the floors: std::swap(FloorLo, FloorHi); } diff --git a/src/Generating/StructGen.h b/src/Generating/StructGen.h index b5cfcb07c..a9ada6c1e 100644 --- a/src/Generating/StructGen.h +++ b/src/Generating/StructGen.h @@ -31,7 +31,7 @@ public: m_ShapeGen(a_ShapeGen), m_CompositionGen(a_CompositionGen) {} - + protected: int m_Seed; @@ -39,7 +39,7 @@ protected: cBiomeGenPtr m_BiomeGen; cTerrainShapeGenPtr m_ShapeGen; cTerrainCompositionGenPtr m_CompositionGen; - + /** Generates and applies an image of a single tree. Parts of the tree inside the chunk are applied to a_ChunkDesc. Parts of the tree outside the chunk are stored in a_OutsideXYZ @@ -50,7 +50,7 @@ protected: sSetBlockVector & a_OutsideLogs, sSetBlockVector & a_OutsideOther ) ; - + /** Applies an image into chunk blockdata; all blocks outside the chunk will be appended to a_Overflow. */ void ApplyTreeImage( int a_ChunkX, int a_ChunkZ, @@ -63,7 +63,7 @@ protected: int a_ChunkX, int a_ChunkZ, const cChunkDef::BiomeMap & a_Biomes ); - + // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; @@ -84,7 +84,7 @@ public: m_Probability(a_Probability) { } - + protected: cNoise m_Noise; int m_Seed; @@ -93,11 +93,11 @@ protected: /** Chance, [0 .. 100], of a chunk having the lake. */ int m_Probability; - + // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; - + /** Creates a lake image for the specified chunk into a_Lake. */ void CreateLakeImage(int a_ChunkX, int a_ChunkZ, int a_MaxLakeHeight, cBlockArea & a_Lake); } ; @@ -116,7 +116,7 @@ public: protected: cNoise m_Noise1; cNoise m_Noise2; - + // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; @@ -138,7 +138,7 @@ protected: cNoise m_NoiseY; cNoise m_NoiseZ; cNoise m_NoiseH; - + // cFinishGen override: virtual void GenFinish(cChunkDesc & a_ChunkDesc) override; } ; diff --git a/src/Generating/Trees.cpp b/src/Generating/Trees.cpp index 37afaaac6..f2592aa21 100644 --- a/src/Generating/Trees.cpp +++ b/src/Generating/Trees.cpp @@ -171,7 +171,7 @@ void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No } return; } - + case biTaiga: case biIcePlains: case biIceMountains: @@ -181,7 +181,7 @@ void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No GetConiferTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks); return; } - + case biSwamplandM: case biSwampland: { @@ -189,7 +189,7 @@ void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No GetSwampTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks); return; } - + case biJungle: case biJungleHills: case biJungleEdge: @@ -206,7 +206,7 @@ void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No } return; } - + case biBirchForest: case biBirchForestHills: { @@ -259,7 +259,7 @@ void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No GetDarkoakTreeImage(a_BlockX, a_BlockY, a_BlockZ, a_Noise, a_Seq, a_LogBlocks, a_OtherBlocks); return; } - + case biMesa: case biMesaPlateauF: case biMesaPlateau: @@ -288,7 +288,7 @@ void GetTreeImageByBiome(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No return; } } - + ASSERT(!"Invalid biome type!"); } @@ -320,24 +320,24 @@ void GetSmallAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a - 2 layers of BigO2 + random corners (log) - 1 to 3 blocks of trunk */ - + int Random = a_Noise.IntNoise3DInt(a_BlockX + 64 * a_Seq, a_BlockY, a_BlockZ) >> 3; - + HEIGHTTYPE Heights[] = {1, 2, 2, 3} ; HEIGHTTYPE Height = 1 + Heights[Random & 3]; Random >>= 2; - + // Pre-alloc so that we don't realloc too often later: a_LogBlocks.reserve(static_cast(Height + 5)); a_OtherBlocks.reserve(ARRAYCOUNT(BigO2) * 2 + ARRAYCOUNT(BigO1) + ARRAYCOUNT(Corners) * 3 + 3 + 5); - + // Trunk: for (int i = 0; i < Height; i++) { a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE)); } int Hei = a_BlockY + Height; - + // 2 BigO2 + corners layers: for (int i = 0; i < 2; i++) { @@ -346,7 +346,7 @@ void GetSmallAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a a_LogBlocks.push_back(sSetBlock(a_BlockX, Hei, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE)); Hei++; } // for i - 2* - + // Optional BigO1 + corners layer: if ((Random & 1) == 0) { @@ -355,7 +355,7 @@ void GetSmallAppleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a a_LogBlocks.push_back(sSetBlock(a_BlockX, Hei, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE)); Hei++; } - + // Top plus: PushCoordBlocks(a_BlockX, Hei, a_BlockZ, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); a_OtherBlocks.push_back(sSetBlock(a_BlockX, Hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_APPLE)); @@ -479,28 +479,28 @@ NIBBLETYPE GetLogMetaFromDirection(NIBBLETYPE a_BlockMeta, Vector3d a_Direction) void GetBirchTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks) { HEIGHTTYPE Height = 5 + (a_Noise.IntNoise3DInt(a_BlockX + 64 * a_Seq, a_BlockY, a_BlockZ) % 3); - + // Prealloc, so that we don't realloc too often later: a_LogBlocks.reserve(static_cast(Height)); a_OtherBlocks.reserve(80); - + // The entire trunk, out of logs: for (int i = Height - 1; i >= 0; --i) { a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_BIRCH)); } int h = a_BlockY + Height; - + // Top layer - just the Plus: PushCoordBlocks(a_BlockX, h, a_BlockZ, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); a_OtherBlocks.push_back(sSetBlock(a_BlockX, h, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH)); // There's no log at this layer h--; - + // Second layer - log, Plus and maybe Corners: PushCoordBlocks (a_BlockX, h, a_BlockZ, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); PushCornerBlocks(a_BlockX, h, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 1, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); h--; - + // Third and fourth layers - BigO2 and maybe 2 * Corners: for (int Row = 0; Row < 2; Row++) { @@ -518,7 +518,7 @@ void GetAcaciaTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noi { // Calculate a base height int Height = 2 + (a_Noise.IntNoise3DInt(a_BlockX, a_BlockY, a_BlockZ) / 11 % 3); - + // Create the trunk for (int i = 0; i < Height; i++) { @@ -653,28 +653,28 @@ void GetDarkoakTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_No void GetTallBirchTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks) { HEIGHTTYPE Height = 9 + (a_Noise.IntNoise3DInt(a_BlockX + 64 * a_Seq, a_BlockY, a_BlockZ) % 3); - + // Prealloc, so that we don't realloc too often later: a_LogBlocks.reserve(static_cast(Height)); a_OtherBlocks.reserve(80); - + // The entire trunk, out of logs: for (int i = Height - 1; i >= 0; --i) { a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_BIRCH)); } int h = a_BlockY + Height; - + // Top layer - just the Plus: PushCoordBlocks(a_BlockX, h, a_BlockZ, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); a_OtherBlocks.push_back(sSetBlock(a_BlockX, h, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH)); // There's no log at this layer h--; - + // Second layer - log, Plus and maybe Corners: PushCoordBlocks (a_BlockX, h, a_BlockZ, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); PushCornerBlocks(a_BlockX, h, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 1, E_BLOCK_LEAVES, E_META_LEAVES_BIRCH); h--; - + // Third and fourth layers - BigO2 and maybe 2 * Corners: for (int Row = 0; Row < 2; Row++) { @@ -710,11 +710,11 @@ void GetSpruceTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noi // Spruces have a top section with layer sizes of (0, 1, 0) or only (1, 0), // then 1 - 3 sections of ascending sizes (1, 2) [most often], (1, 3) or (1, 2, 3) // and an optional bottom section of size 1, followed by 1 - 3 clear trunk blocks - + // We'll use bits from this number as partial random numbers; but the noise function has mod8 irregularities // (each of the mod8 remainders has a very different chance of occurrence) - that's why we divide by 8 int MyRandom = a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY + 32 * a_Seq, a_BlockZ) / 8; - + static const HEIGHTTYPE sHeights[] = {1, 2, 2, 3}; HEIGHTTYPE Height = sHeights[MyRandom & 3]; MyRandom >>= 2; @@ -722,14 +722,14 @@ void GetSpruceTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noi // Prealloc, so that we don't realloc too often later: a_LogBlocks.reserve(static_cast(Height)); a_OtherBlocks.reserve(180); - + // Clear trunk blocks: for (int i = 0; i < Height; i++) { a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_CONIFER)); } Height += a_BlockY; - + // Optional size-1 bottom leaves layer: if ((MyRandom & 1) == 0) { @@ -738,7 +738,7 @@ void GetSpruceTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noi Height++; } MyRandom >>= 1; - + // 1 to 3 sections of leaves layers: static const int sNumSections[] = {1, 2, 2, 3}; int NumSections = sNumSections[MyRandom & 3]; @@ -780,7 +780,7 @@ void GetSpruceTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noi } // switch (SectionType) MyRandom >>= 2; } // for i - Sections - + if ((MyRandom & 1) == 0) { // (0, 1, 0) top: @@ -806,7 +806,7 @@ void GetPineTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise { // Tall, little leaves on top. The top leaves are arranged in a shape of two cones joined by their bases. // There can be one or two layers representing the cone bases (SameSizeMax) - + int MyRandom = a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) / 8; int TrunkHeight = 8 + (MyRandom % 3); int SameSizeMax = ((MyRandom & 8) == 0) ? 1 : 0; @@ -816,7 +816,7 @@ void GetPineTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise { SameSizeMax = 0; } - + // Pre-allocate the vector: a_LogBlocks.reserve(static_cast(TrunkHeight)); a_OtherBlocks.reserve(static_cast(NumLeavesLayers * 25)); @@ -867,19 +867,19 @@ void GetSwampTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Nois } ; int Height = 3 + (a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) / 8) % 3; - + a_LogBlocks.reserve(static_cast(Height)); a_OtherBlocks.reserve(2 * ARRAYCOUNT(BigO2) + 2 * ARRAYCOUNT(BigO3) + static_cast(Height) * ARRAYCOUNT(Vines) + 20); - + for (int i = 0; i < Height; i++) { a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_APPLE)); } int hei = a_BlockY + Height - 2; - + // Put vines around the lowermost leaves layer: PushSomeColumns(a_BlockX, hei, a_BlockZ, Height, a_Seq, a_Noise, 0x3fffffff, a_OtherBlocks, Vines, ARRAYCOUNT(Vines), E_BLOCK_VINES); - + // The lower two leaves layers are BigO3 with log in the middle and possibly corners: for (int i = 0; i < 2; i++) { @@ -905,16 +905,16 @@ void GetSwampTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Nois void GetAppleBushImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_Noise, int a_Seq, sSetBlockVector & a_LogBlocks, sSetBlockVector & a_OtherBlocks) { a_OtherBlocks.reserve(3 + ARRAYCOUNT(BigO2) + ARRAYCOUNT(BigO1)); - + int hei = a_BlockY; a_LogBlocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LOG, E_META_LOG_JUNGLE)); PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO2, ARRAYCOUNT(BigO2), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); hei++; - + a_OtherBlocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_APPLE)); PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_APPLE); hei++; - + a_OtherBlocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_APPLE)); } @@ -951,12 +951,12 @@ void GetLargeJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & {-5, -2, 8}, {-5, -1, 8}, {-5, 0, 8}, {-5, 1, 8}, {-5, 2, 8}, // West face // TODO: vines around the trunk, proper metas and height } ; - + int Height = 24 + (a_Noise.IntNoise3DInt(a_BlockX + 32 * a_Seq, a_BlockY, a_BlockZ + 32 * a_Seq) / 11) % 24; - + a_LogBlocks.reserve(static_cast(Height) * 4); a_OtherBlocks.reserve(2 * ARRAYCOUNT(BigO4) + ARRAYCOUNT(BigO3) + static_cast(Height) * ARRAYCOUNT(Vines) + 50); - + for (int i = 0; i < Height; i++) { a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_JUNGLE)); @@ -965,10 +965,10 @@ void GetLargeJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & a_LogBlocks.push_back(sSetBlock(a_BlockX + 1, a_BlockY + i, a_BlockZ + 1, E_BLOCK_LOG, E_META_LOG_JUNGLE)); } int hei = a_BlockY + Height - 2; - + // Put vines around the lowermost leaves layer: PushSomeColumns(a_BlockX, hei, a_BlockZ, Height, a_Seq, a_Noise, 0x3fffffff, a_OtherBlocks, Vines, ARRAYCOUNT(Vines), E_BLOCK_VINES); - + // The lower two leaves layers are BigO4 with log in the middle and possibly corners: for (int i = 0; i < 2; i++) { @@ -1000,7 +1000,7 @@ void GetSmallJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & } ; int Height = 7 + (a_Noise.IntNoise3DInt(a_BlockX + 5 * a_Seq, a_BlockY, a_BlockZ + 5 * a_Seq) / 5) % 3; - + a_LogBlocks.reserve(static_cast(Height)); a_OtherBlocks.reserve( 2 * ARRAYCOUNT(BigO3) + // O3 layer, 2x @@ -1009,16 +1009,16 @@ void GetSmallJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & static_cast(Height) * ARRAYCOUNT(Vines) + // Vines 50 // some safety ); - + for (int i = 0; i < Height; i++) { a_LogBlocks.push_back(sSetBlock(a_BlockX, a_BlockY + i, a_BlockZ, E_BLOCK_LOG, E_META_LOG_JUNGLE)); } int hei = a_BlockY + Height - 3; - + // Put vines around the lowermost leaves layer: PushSomeColumns(a_BlockX, hei, a_BlockZ, Height, a_Seq, a_Noise, 0x3fffffff, a_OtherBlocks, Vines, ARRAYCOUNT(Vines), E_BLOCK_VINES); - + // The lower two leaves layers are BigO3 with log in the middle and possibly corners: for (int i = 0; i < 2; i++) { @@ -1034,7 +1034,7 @@ void GetSmallJungleTreeImage(int a_BlockX, int a_BlockY, int a_BlockZ, cNoise & PushCornerBlocks(a_BlockX, hei, a_BlockZ, a_Seq, a_Noise, 0x5fffffff, a_OtherBlocks, 2, E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE); hei++; } // for i - 2* - + // Top plus, all leaves: PushCoordBlocks(a_BlockX, hei, a_BlockZ, a_OtherBlocks, BigO1, ARRAYCOUNT(BigO1), E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE); a_OtherBlocks.push_back(sSetBlock(a_BlockX, hei, a_BlockZ, E_BLOCK_LEAVES, E_META_LEAVES_JUNGLE)); diff --git a/src/Generating/VillageGen.cpp b/src/Generating/VillageGen.cpp index 6ee150209..e0804625a 100644 --- a/src/Generating/VillageGen.cpp +++ b/src/Generating/VillageGen.cpp @@ -67,14 +67,14 @@ public: RoadPiece->AddConnector(0, 0, 1, BLOCK_FACE_XM, -2); RoadPiece->AddConnector(len - 1, 0, 1, BLOCK_FACE_XP, -2); RoadPiece->SetDefaultWeight(100); - + // Add the road connectors: for (int x = 1; x < len; x += 12) { RoadPiece->AddConnector(x, 0, 0, BLOCK_FACE_ZM, 2); RoadPiece->AddConnector(x, 0, 2, BLOCK_FACE_ZP, 2); } - + // Add the buildings connectors: for (int x = 7; x < len; x += 12) { @@ -87,8 +87,8 @@ public: m_PiecesByConnector[2].push_back(RoadPiece); } // for len - roads of varying length } - - + + // cPrefabPiecePool overrides: virtual int GetPieceWeight(const cPlacedPiece & a_PlacedPiece, const cPiece::cConnector & a_ExistingConnector, const cPiece & a_NewPiece) override { @@ -97,7 +97,7 @@ public: { return 0; } - + return static_cast(a_NewPiece).GetPieceWeight(a_PlacedPiece, a_ExistingConnector); } }; @@ -111,7 +111,7 @@ class cVillageGen::cVillage : protected cPiecePool { typedef cGridStructGen::cStructure super; - + public: cVillage( int a_Seed, @@ -140,38 +140,38 @@ public: return; } } - + ~cVillage() { cPieceGenerator::FreePieces(m_Pieces); } - + protected: /** Seed for the random functions */ int m_Seed; - + /** The noise used as a pseudo-random generator */ cNoise m_Noise; - + /** Maximum size, in X / Z blocks, of the village (radius from the origin) */ int m_MaxSize; - + /** The density for this village. Used to refrain from populating all house connectors. Range [0, 100] */ int m_Density; - + /** Borders of the village - no item may reach out of this cuboid. */ cCuboid m_Borders; - + /** Prefabs to use for buildings */ cVillagePiecePool & m_Prefabs; - + /** The underlying height generator, used for placing the structures on top of the terrain. */ cTerrainHeightGenPtr m_HeightGen; - + /** The village pieces, placed by the generator. */ cPlacedPieces m_Pieces; - - + + // cGridStructGen::cStructure overrides: virtual void DrawIntoChunk(cChunkDesc & a_Chunk) override { @@ -213,8 +213,8 @@ protected: int TerrainHeight = cChunkDef::GetHeight(HeightMap, BlockX, BlockZ); a_Piece.MoveToGroundBy(TerrainHeight - FirstConnector.m_Pos.y + 1); } - - + + /** Draws the road into the chunk. The heightmap is not queried from the heightgen, but is given via parameter, so that it may be queried just once for all roads in a chunk. */ @@ -245,21 +245,21 @@ protected: } } } - - + + // cPiecePool overrides: virtual cPieces GetPiecesWithConnector(int a_ConnectorType) override { return m_Prefabs.GetPiecesWithConnector(a_ConnectorType); } - - + + virtual cPieces GetStartingPieces(void) override { return m_Prefabs.GetStartingPieces(); } - - + + virtual int GetPieceWeight( const cPlacedPiece & a_PlacedPiece, const cPiece::cConnector & a_ExistingConnector, @@ -276,30 +276,30 @@ protected: return 0; } } - + // Density check passed, relay to m_Prefabs: return m_Prefabs.GetPieceWeight(a_PlacedPiece, a_ExistingConnector, a_NewPiece); } - - + + virtual int GetStartingPieceWeight(const cPiece & a_NewPiece) override { return m_Prefabs.GetStartingPieceWeight(a_NewPiece); } - - + + virtual void PiecePlaced(const cPiece & a_Piece) override { m_Prefabs.PiecePlaced(a_Piece); } - - + + virtual void Reset(void) override { m_Prefabs.Reset(); } - - + + void MoveAllDescendants(cPlacedPieces & a_PlacedPieces, size_t a_Pivot, int a_HeightDifference) { size_t num = a_PlacedPieces.size(); @@ -416,7 +416,7 @@ cGridStructGen::cStructurePtr cVillageGen::CreateStructure(int a_GridX, int a_Gr { Density = pool->GetMinDensity(); } - + // Create a village based on the chosen prefabs: return cStructurePtr(new cVillage(m_Seed, a_GridX, a_GridZ, a_OriginX, a_OriginZ, m_MaxDepth, m_MaxSize, Density, *pool.get(), m_HeightGen)); } diff --git a/src/Generating/VillageGen.h b/src/Generating/VillageGen.h index 6b7c4a3b4..df68d407d 100644 --- a/src/Generating/VillageGen.h +++ b/src/Generating/VillageGen.h @@ -48,22 +48,22 @@ protected: /** The noise used for generating random numbers */ cNoise m_Noise; - + /** Maximum depth of the generator tree */ int m_MaxDepth; - + /** Maximum size, in X / Z blocks, of the village (radius from the origin) */ int m_MaxSize; - + /** Minimum density - percentage of allowed house connections. Range [0, 100] */ int m_MinDensity; - + /** Maximum density - percentage of allowed house connections. Range [0, 100] */ int m_MaxDensity; /** The underlying biome generator that defines whether the village is created or not */ cBiomeGenPtr m_BiomeGen; - + /** The underlying height generator, used to position the prefabs crossing chunk borders */ cTerrainHeightGenPtr m_HeightGen; diff --git a/src/Globals.h b/src/Globals.h index dc5d27636..5cc323b9e 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -32,7 +32,7 @@ // Disabled because it's useless: #pragma warning(disable: 4512) // 'class': assignment operator could not be generated - reported for each class that has a reference-type member #pragma warning(disable: 4351) // new behavior: elements of array 'member' will be default initialized - + // 2014_01_06 xoft: Disabled this warning because MSVC is stupid and reports it in obviously wrong places // #pragma warning(3 : 4244) // Conversion from 'type1' to 'type2', possible loss of data @@ -41,14 +41,14 @@ // No alignment needed in MSVC #define ALIGN_8 #define ALIGN_16 - + #define FORMATSTRING(formatIndex, va_argsIndex) // MSVC has its own custom version of zu format #define SIZE_T_FMT "%Iu" #define SIZE_T_FMT_PRECISION(x) "%" #x "Iu" #define SIZE_T_FMT_HEX "%Ix" - + #define NORETURN __declspec(noreturn) // Use non-standard defines in @@ -71,7 +71,7 @@ // Some portability macros :) #define stricmp strcasecmp - + #define FORMATSTRING(formatIndex, va_argsIndex) __attribute__((format (printf, formatIndex, va_argsIndex))) #if defined(_WIN32) @@ -92,7 +92,7 @@ #define SIZE_T_FMT_PRECISION(x) "%" #x "zu" #define SIZE_T_FMT_HEX "%zx" #endif - + #define NORETURN __attribute((__noreturn__)) #else @@ -418,7 +418,7 @@ template class cItemCallback { public: virtual ~cItemCallback() {} - + /** Called for each item in the internal list; return true to stop the loop, or false to continue enumerating */ virtual bool Item(Type * a_Type) = 0; } ; diff --git a/src/HTTPServer/EnvelopeParser.cpp b/src/HTTPServer/EnvelopeParser.cpp index fd4f3836d..407e9dcfc 100644 --- a/src/HTTPServer/EnvelopeParser.cpp +++ b/src/HTTPServer/EnvelopeParser.cpp @@ -26,20 +26,20 @@ size_t cEnvelopeParser::Parse(const char * a_Data, size_t a_Size) { return 0; } - + // Start searching 1 char from the end of the already received data, if available: size_t SearchStart = m_IncomingData.size(); SearchStart = (SearchStart > 1) ? SearchStart - 1 : 0; - + m_IncomingData.append(a_Data, a_Size); - + size_t idxCRLF = m_IncomingData.find("\r\n", SearchStart); if (idxCRLF == AString::npos) { // Not a complete line yet, all input consumed: return a_Size; } - + // Parse as many lines as found: size_t Last = 0; do @@ -61,7 +61,7 @@ size_t cEnvelopeParser::Parse(const char * a_Data, size_t a_Size) idxCRLF = m_IncomingData.find("\r\n", idxCRLF + 2); } while (idxCRLF != AString::npos); m_IncomingData.erase(0, Last); - + // Parsed all lines and still expecting more return a_Size; } @@ -110,7 +110,7 @@ bool cEnvelopeParser::ParseLine(const char * a_Data, size_t a_Size) m_LastValue.append(a_Data, a_Size); return true; } - + // This is a line with a new key: NotifyLast(); for (size_t i = 0; i < a_Size; i++) @@ -122,7 +122,7 @@ bool cEnvelopeParser::ParseLine(const char * a_Data, size_t a_Size) return true; } } // for i - a_Data[] - + // No colon was found, key-less header?? return false; } diff --git a/src/HTTPServer/EnvelopeParser.h b/src/HTTPServer/EnvelopeParser.h index fe226d1f8..2fa930539 100644 --- a/src/HTTPServer/EnvelopeParser.h +++ b/src/HTTPServer/EnvelopeParser.h @@ -21,49 +21,49 @@ public: public: // Force a virtual destructor in descendants: virtual ~cCallbacks() {} - + /** Called when a full header line is parsed */ virtual void OnHeaderLine(const AString & a_Key, const AString & a_Value) = 0; } ; - - + + cEnvelopeParser(cCallbacks & a_Callbacks); - + /** Parses the incoming data. Returns the number of bytes consumed from the input. The bytes not consumed are not part of the envelope header. Returns AString::npos on error */ size_t Parse(const char * a_Data, size_t a_Size); - + /** Makes the parser forget everything parsed so far, so that it can be reused for parsing another datastream */ void Reset(void); - + /** Returns true if more input is expected for the envelope header */ bool IsInHeaders(void) const { return m_IsInHeaders; } - + /** Sets the IsInHeaders flag; used by cMultipartParser to simplify the parser initial conditions */ void SetIsInHeaders(bool a_IsInHeaders) { m_IsInHeaders = a_IsInHeaders; } - + public: /** Callbacks to call for the various events */ cCallbacks & m_Callbacks; - + /** Set to true while the parser is still parsing the envelope headers. Once set to true, the parser will not consume any more data. */ bool m_IsInHeaders; - + /** Buffer for the incoming data until it is parsed */ AString m_IncomingData; - + /** Holds the last parsed key; used for line-wrapped values */ AString m_LastKey; - + /** Holds the last parsed value; used for line-wrapped values */ AString m_LastValue; /** Notifies the callback of the key / value stored in m_LastKey / m_LastValue, then erases them */ void NotifyLast(void); - + /** Parses one line of header data. Returns true if successful */ bool ParseLine(const char * a_Data, size_t a_Size); } ; diff --git a/src/HTTPServer/HTTPConnection.cpp b/src/HTTPServer/HTTPConnection.cpp index c6a45e6ed..0db154139 100644 --- a/src/HTTPServer/HTTPConnection.cpp +++ b/src/HTTPServer/HTTPConnection.cpp @@ -104,7 +104,7 @@ void cHTTPConnection::AwaitNextRequest(void) // Nothing has been received yet, or a special response was given (SendStatusAndReason() or SendNeedAuth()) break; } - + case wcsRecvIdle: { // The client is waiting for a response, send an "Internal server error": @@ -112,7 +112,7 @@ void cHTTPConnection::AwaitNextRequest(void) m_State = wcsRecvHeaders; break; } - + case wcsSendingResp: { // The response headers have been sent, we need to terminate the response body: @@ -120,7 +120,7 @@ void cHTTPConnection::AwaitNextRequest(void) m_State = wcsRecvHeaders; break; } - + default: { ASSERT(!"Unhandled state recovery"); @@ -184,7 +184,7 @@ void cHTTPConnection::OnReceivedData(const char * a_Data, size_t a_Size) // The request headers are not yet complete return; } - + // The request has finished parsing its headers successfully, notify of it: m_State = wcsRecvBody; m_HTTPServer.NewRequest(*this, *m_CurrentRequest); @@ -194,7 +194,7 @@ void cHTTPConnection::OnReceivedData(const char * a_Data, size_t a_Size) // The body length was not specified in the request, assume zero m_CurrentRequestBodyRemaining = 0; } - + // Process the rest of the incoming data into the request body: if (a_Size > BytesConsumed) { diff --git a/src/HTTPServer/HTTPConnection.h b/src/HTTPServer/HTTPConnection.h index e1ebeb9ee..414075411 100644 --- a/src/HTTPServer/HTTPConnection.h +++ b/src/HTTPServer/HTTPConnection.h @@ -28,7 +28,7 @@ class cHTTPConnection : public cTCPLink::cCallbacks { public: - + enum eState { wcsRecvHeaders, ///< Receiving request headers (m_CurrentRequest is created if nullptr) @@ -37,48 +37,48 @@ public: wcsSendingResp, ///< Sending response body (m_CurrentRequest == nullptr) wcsInvalid, ///< The request was malformed, the connection is closing } ; - + cHTTPConnection(cHTTPServer & a_HTTPServer); virtual ~cHTTPConnection(); - + /** Sends HTTP status code together with a_Reason (used for HTTP errors). Sends the a_Reason as the body as well, so that browsers display it. */ void SendStatusAndReason(int a_StatusCode, const AString & a_Reason); - + /** Sends the "401 unauthorized" reply together with instructions on authorizing, using the specified realm */ void SendNeedAuth(const AString & a_Realm); - + /** Sends the headers contained in a_Response */ void Send(const cHTTPResponse & a_Response); - + /** Sends the data as the response (may be called multiple times) */ void Send(const void * a_Data, size_t a_Size); /** Sends the data as the response (may be called multiple times) */ void Send(const AString & a_Data) { Send(a_Data.data(), a_Data.size()); } - + /** Indicates that the current response is finished, gets ready for receiving another request (HTTP 1.1 keepalive) */ void FinishResponse(void); - + /** Resets the internal connection state for a new request. Depending on the state, this will send an "InternalServerError" status or a "ResponseEnd" */ void AwaitNextRequest(void); - + /** Terminates the connection; finishes any request being currently processed */ void Terminate(void); - + protected: typedef std::map cNameValueMap; - + /** The parent webserver that is to be notified of events on this connection */ cHTTPServer & m_HTTPServer; - + /** All the incoming data until the entire request header is parsed */ AString m_IncomingHeaderData; - + /** Status in which the request currently is */ eState m_State; - + /** The request being currently received Valid only between having parsed the headers and finishing receiving the body. */ cHTTPRequest * m_CurrentRequest; @@ -89,18 +89,18 @@ protected: /** The network link attached to this connection. */ cTCPLinkPtr m_Link; - - + + // cTCPLink::cCallbacks overrides: /** The link instance has been created, remember it. */ virtual void OnLinkCreated(cTCPLinkPtr a_Link) override; /** Data is received from the client. */ virtual void OnReceivedData(const char * a_Data, size_t a_Size) override; - + /** The socket has been closed for any reason. */ virtual void OnRemoteClosed(void) override; - + /** An error has occurred on the socket. */ virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg) override; diff --git a/src/HTTPServer/HTTPFormParser.cpp b/src/HTTPServer/HTTPFormParser.cpp index 77f98e43b..497f84033 100644 --- a/src/HTTPServer/HTTPFormParser.cpp +++ b/src/HTTPServer/HTTPFormParser.cpp @@ -22,7 +22,7 @@ cHTTPFormParser::cHTTPFormParser(cHTTPRequest & a_Request, cCallbacks & a_Callba if (a_Request.GetMethod() == "GET") { m_Kind = fpkURL; - + // Directly parse the URL in the request: const AString & URL = a_Request.GetURL(); size_t idxQM = URL.find('?'); @@ -74,7 +74,7 @@ void cHTTPFormParser::Parse(const char * a_Data, size_t a_Size) { return; } - + switch (m_Kind) { case fpkURL: @@ -223,7 +223,7 @@ void cHTTPFormParser::OnPartHeader(const AString & a_Key, const AString & a_Valu m_IsValid = false; return; } - + // Parse the field name and optional filename from this header: cNameValueParser Parser(a_Value.data() + ParamsStart, a_Value.size() - ParamsStart); Parser.Finish(); diff --git a/src/HTTPServer/HTTPFormParser.h b/src/HTTPServer/HTTPFormParser.h index e72d4ef10..f6cbe047f 100644 --- a/src/HTTPServer/HTTPFormParser.h +++ b/src/HTTPServer/HTTPFormParser.h @@ -38,36 +38,36 @@ public: public: // Force a virtual destructor in descendants: virtual ~cCallbacks() {} - + /** Called when a new file part is encountered in the form data */ virtual void OnFileStart(cHTTPFormParser & a_Parser, const AString & a_FileName) = 0; - + /** Called when more file data has come for the current file in the form data */ virtual void OnFileData(cHTTPFormParser & a_Parser, const char * a_Data, size_t a_Size) = 0; - + /** Called when the current file part has ended in the form data */ virtual void OnFileEnd(cHTTPFormParser & a_Parser) = 0; } ; - - + + /** Creates a parser that is tied to a request and notifies of various events using a callback mechanism */ cHTTPFormParser(cHTTPRequest & a_Request, cCallbacks & a_Callbacks); - + /** Creates a parser with the specified content type that reads data from a string */ cHTTPFormParser(eKind a_Kind, const char * a_Data, size_t a_Size, cCallbacks & a_Callbacks); - + /** Adds more data into the parser, as the request body is received */ void Parse(const char * a_Data, size_t a_Size); - + /** Notifies that there's no more data incoming and the parser should finish its parsing. Returns true if parsing successful. */ bool Finish(void); - + /** Returns true if the headers suggest the request has form data parseable by this class */ static bool HasFormData(const cHTTPRequest & a_Request); - + protected: - + /** The callbacks to call for incoming file data */ cCallbacks & m_Callbacks; @@ -76,32 +76,32 @@ protected: /** Buffer for the incoming data until it's parsed */ AString m_IncomingData; - + /** True if the information received so far is a valid form; set to false on first problem. Further parsing is skipped when false. */ bool m_IsValid; - + /** The parser for the multipart data, if used */ std::unique_ptr m_MultipartParser; - + /** Name of the currently parsed part in multipart data */ AString m_CurrentPartName; - + /** True if the currently parsed part in multipart data is a file */ bool m_IsCurrentPartFile; - + /** Filename of the current parsed part in multipart data (for file uploads) */ AString m_CurrentPartFileName; - + /** Set to true after m_Callbacks.OnFileStart() has been called, reset to false on PartEnd */ bool m_FileHasBeenAnnounced; - - + + /** Sets up the object for parsing a fpkMultipart request */ void BeginMultipart(const cHTTPRequest & a_Request); - + /** Parses m_IncomingData as form-urlencoded data (fpkURL or fpkFormUrlEncoded kinds) */ void ParseFormUrlEncoded(void); - + // cMultipartParser::cCallbacks overrides: virtual void OnPartStart (void) override; virtual void OnPartHeader(const AString & a_Key, const AString & a_Value) override; diff --git a/src/HTTPServer/HTTPMessage.cpp b/src/HTTPServer/HTTPMessage.cpp index 400625690..360145a9a 100644 --- a/src/HTTPServer/HTTPMessage.cpp +++ b/src/HTTPServer/HTTPMessage.cpp @@ -47,7 +47,7 @@ void cHTTPMessage::AddHeader(const AString & a_Key, const AString & a_Value) itr->second.append(", "); itr->second.append(a_Value); } - + // Special processing for well-known headers: if (Key == "content-type") { @@ -89,7 +89,7 @@ size_t cHTTPRequest::ParseHeaders(const char * a_Data, size_t a_Size) { return AString::npos; } - + if (m_Method.empty()) { // The first line hasn't been processed yet @@ -108,7 +108,7 @@ size_t cHTTPRequest::ParseHeaders(const char * a_Data, size_t a_Size) } return res2 + res; } - + if (m_EnvelopeParser.IsInHeaders()) { size_t res = m_EnvelopeParser.Parse(a_Data, a_Size); @@ -166,7 +166,7 @@ size_t cHTTPRequest::ParseRequestLine(const char * a_Data, size_t a_Size) m_IsValid = false; return AString::npos; } - + int NumSpaces = 0; size_t MethodEnd = 0; size_t URLEnd = 0; @@ -218,7 +218,7 @@ size_t cHTTPRequest::ParseRequestLine(const char * a_Data, size_t a_Size) } } // switch (m_IncomingHeaderData[i]) } // for i - m_IncomingHeaderData[] - + // CRLF hasn't been encountered yet, consider all data consumed return a_Size; } diff --git a/src/HTTPServer/HTTPMessage.h b/src/HTTPServer/HTTPMessage.h index ff657a272..72ecb67d1 100644 --- a/src/HTTPServer/HTTPMessage.h +++ b/src/HTTPServer/HTTPMessage.h @@ -29,26 +29,26 @@ public: mkRequest, mkResponse, } ; - + cHTTPMessage(eKind a_Kind); // Force a virtual destructor in all descendants virtual ~cHTTPMessage() {} - + /** Adds a header into the internal map of headers. Recognizes special headers: Content-Type and Content-Length */ void AddHeader(const AString & a_Key, const AString & a_Value); - + void SetContentType (const AString & a_ContentType) { m_ContentType = a_ContentType; } void SetContentLength(size_t a_ContentLength) { m_ContentLength = a_ContentLength; } - + const AString & GetContentType (void) const { return m_ContentType; } size_t GetContentLength(void) const { return m_ContentLength; } protected: typedef std::map cNameValueMap; - + eKind m_Kind; - + cNameValueMap m_Headers; /** Type of the content; parsed by AddHeader(), set directly by SetContentLength() */ @@ -69,86 +69,86 @@ class cHTTPRequest : protected cEnvelopeParser::cCallbacks { typedef cHTTPMessage super; - + public: cHTTPRequest(void); - + /** Parses the request line and then headers from the received data. Returns the number of bytes consumed or AString::npos number for error */ size_t ParseHeaders(const char * a_Data, size_t a_Size); - + /** Returns true if the request did contain a Content-Length header */ bool HasReceivedContentLength(void) const { return (m_ContentLength != AString::npos); } - + /** Returns the method used in the request */ const AString & GetMethod(void) const { return m_Method; } - + /** Returns the URL used in the request */ const AString & GetURL(void) const { return m_URL; } - + /** Returns the URL used in the request, without any parameters */ AString GetBareURL(void) const; - + /** Sets the UserData pointer that is stored within this request. The request doesn't touch this data (doesn't delete it)! */ void SetUserData(void * a_UserData) { m_UserData = a_UserData; } - + /** Retrieves the UserData pointer that has been stored within this request. */ void * GetUserData(void) const { return m_UserData; } - + /** Returns true if more data is expected for the request headers */ bool IsInHeaders(void) const { return m_EnvelopeParser.IsInHeaders(); } - + /** Returns true if the request did present auth data that was understood by the parser */ bool HasAuth(void) const { return m_HasAuth; } - + /** Returns the username that the request presented. Only valid if HasAuth() is true */ const AString & GetAuthUsername(void) const { return m_AuthUsername; } - + /** Returns the password that the request presented. Only valid if HasAuth() is true */ const AString & GetAuthPassword(void) const { return m_AuthPassword; } - + bool DoesAllowKeepAlive(void) const { return m_AllowKeepAlive; } - + protected: /** Parser for the envelope data */ cEnvelopeParser m_EnvelopeParser; - + /** True if the data received so far is parsed successfully. When false, all further parsing is skipped */ bool m_IsValid; - + /** Bufferred incoming data, while parsing for the request line */ AString m_IncomingHeaderData; - + /** Method of the request (GET / PUT / POST / ...) */ AString m_Method; - + /** Full URL of the request */ AString m_URL; - + /** Data that the HTTPServer callbacks are allowed to store. */ void * m_UserData; - + /** Set to true if the request contains auth data that was understood by the parser */ bool m_HasAuth; - + /** The username used for auth */ AString m_AuthUsername; - + /** The password used for auth */ AString m_AuthPassword; - + /** Set to true if the request indicated that it supports keepalives. If false, the server will close the connection once the request is finished */ bool m_AllowKeepAlive; - - + + /** Parses the incoming data for the first line (RequestLine) Returns the number of bytes consumed, or AString::npos for an error */ size_t ParseRequestLine(const char * a_Data, size_t a_Size); - + // cEnvelopeParser::cCallbacks overrides: virtual void OnHeaderLine(const AString & a_Key, const AString & a_Value) override; } ; @@ -164,7 +164,7 @@ class cHTTPResponse : public: cHTTPResponse(void); - + /** Appends the response to the specified datastream - response line and headers. The body will be sent later directly through cConnection::Send() */ diff --git a/src/HTTPServer/HTTPServer.cpp b/src/HTTPServer/HTTPServer.cpp index bbff5d57a..814a87fe4 100644 --- a/src/HTTPServer/HTTPServer.cpp +++ b/src/HTTPServer/HTTPServer.cpp @@ -31,26 +31,26 @@ class cDebugCallbacks : virtual void OnRequestBegun(cHTTPConnection & a_Connection, cHTTPRequest & a_Request) override { UNUSED(a_Connection); - + if (cHTTPFormParser::HasFormData(a_Request)) { a_Request.SetUserData(new cHTTPFormParser(a_Request, *this)); } } - - + + virtual void OnRequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, size_t a_Size) override { UNUSED(a_Connection); - + cHTTPFormParser * FormParser = reinterpret_cast(a_Request.GetUserData()); if (FormParser != nullptr) { FormParser->Parse(a_Data, a_Size); } } - - + + virtual void OnRequestFinished(cHTTPConnection & a_Connection, cHTTPRequest & a_Request) override { cHTTPFormParser * FormParser = reinterpret_cast(a_Request.GetUserData()); @@ -69,7 +69,7 @@ class cDebugCallbacks : a_Connection.Send(""); return; } - + // Parsing failed: cHTTPResponse Resp; Resp.SetContentType("text/plain"); @@ -77,7 +77,7 @@ class cDebugCallbacks : a_Connection.Send("Form parsing failed"); return; } - + // Test the auth failure and success: if (a_Request.GetURL() == "/auth") { @@ -87,31 +87,31 @@ class cDebugCallbacks : return; } } - + cHTTPResponse Resp; Resp.SetContentType("text/plain"); a_Connection.Send(Resp); a_Connection.Send("Hello, world"); } - - + + virtual void OnFileStart(cHTTPFormParser & a_Parser, const AString & a_FileName) override { // TODO } - - + + virtual void OnFileData(cHTTPFormParser & a_Parser, const char * a_Data, size_t a_Size) override { // TODO } - + virtual void OnFileEnd(cHTTPFormParser & a_Parser) override { // TODO } - + }; static cDebugCallbacks g_DebugCallbacks; @@ -239,7 +239,7 @@ bool cHTTPServer::Start(cCallbacks & a_Callbacks, const AStringVector & a_Ports) m_ServerHandles.push_back(Handle); } } // for port - a_Ports[] - + // Report success if at least one port opened successfully: return !m_ServerHandles.empty(); } diff --git a/src/HTTPServer/HTTPServer.h b/src/HTTPServer/HTTPServer.h index d626fb475..2a094b413 100644 --- a/src/HTTPServer/HTTPServer.h +++ b/src/HTTPServer/HTTPServer.h @@ -39,48 +39,48 @@ public: { public: virtual ~cCallbacks() {} - + /** Called when a new request arrives over a connection and all its headers have been parsed. The request body needn't have arrived yet. */ virtual void OnRequestBegun(cHTTPConnection & a_Connection, cHTTPRequest & a_Request) = 0; - + /** Called when another part of request body has arrived. May be called multiple times for a single request. */ virtual void OnRequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, size_t a_Size) = 0; - + /** Called when the request body has been fully received in previous calls to OnRequestBody() */ virtual void OnRequestFinished(cHTTPConnection & a_Connection, cHTTPRequest & a_Request) = 0; } ; - + cHTTPServer(void); virtual ~cHTTPServer(); - + /** Initializes the server - reads the cert files etc. */ bool Initialize(void); - + /** Starts the server and assigns the callbacks to use for incoming requests */ bool Start(cCallbacks & a_Callbacks, const AStringVector & a_Ports); - + /** Stops the server, drops all current connections */ void Stop(void); - + protected: friend class cHTTPConnection; friend class cSslHTTPConnection; friend class cHTTPServerListenCallbacks; - + /** The cNetwork API handle for the listening socket. */ cServerHandlePtrs m_ServerHandles; - + /** The callbacks to call for various events */ cCallbacks * m_Callbacks; - + /** The server certificate to use for the SSL connections */ cX509CertPtr m_Cert; - + /** The private key for m_Cert. */ cCryptoKeyPtr m_CertPrivKey; - + /** Called by cHTTPServerListenCallbacks when there's a new incoming connection. Returns the connection instance to be used as the cTCPLink callbacks. */ @@ -88,11 +88,11 @@ protected: /** Called by cHTTPConnection when it finishes parsing the request header */ void NewRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Request); - + /** Called by cHTTPConenction when it receives more data for the request body. May be called multiple times for a single request. */ void RequestBody(cHTTPConnection & a_Connection, cHTTPRequest & a_Request, const char * a_Data, size_t a_Size); - + /** Called by cHTTPConnection when it detects that the request has finished (all of its body has been received) */ void RequestFinished(cHTTPConnection & a_Connection, cHTTPRequest & a_Request); } ; diff --git a/src/HTTPServer/MultipartParser.cpp b/src/HTTPServer/MultipartParser.cpp index 09732c5f7..09f4fd02a 100644 --- a/src/HTTPServer/MultipartParser.cpp +++ b/src/HTTPServer/MultipartParser.cpp @@ -56,25 +56,25 @@ ThisIsIgnoredEpilogue"; // DEBUG: Check if the onscreen output corresponds with the data above printf("Multipart parsing test finished\n"); } - + virtual void OnPartStart(void) override { printf("Starting a new part\n"); } - - + + virtual void OnPartHeader(const AString & a_Key, const AString & a_Value) override { printf(" Hdr: \"%s\"=\"%s\"\n", a_Key.c_str(), a_Value.c_str()); } - - + + virtual void OnPartData(const char * a_Data, int a_Size) override { printf(" Data: %d bytes, \"%.*s\"\n", a_Size, a_Size, a_Data); } - - + + virtual void OnPartEnd(void) override { printf("Part end\n"); @@ -110,7 +110,7 @@ cMultipartParser::cMultipartParser(const AString & a_ContentType, cCallbacks & a m_IsValid = false; return; } - + // Find the multipart boundary: ContentType.erase(0, idxSC + 1); cNameValueParser CTParser(ContentType.c_str(), ContentType.size()); @@ -126,13 +126,13 @@ cMultipartParser::cMultipartParser(const AString & a_ContentType, cCallbacks & a { return; } - + // Set the envelope parser for parsing the body, so that our Parse() function parses the ignored prefix data as a body m_EnvelopeParser.SetIsInHeaders(false); // Append an initial CRLF to the incoming data, so that a body starting with the boundary line will get caught m_IncomingData.assign("\r\n"); - + /* m_Boundary = AString("\r\n--") + m_Boundary m_BoundaryEnd = m_Boundary + "--\r\n"; @@ -151,7 +151,7 @@ void cMultipartParser::Parse(const char * a_Data, size_t a_Size) { return; } - + // Append to buffer, then parse it: m_IncomingData.append(a_Data, a_Size); for (;;) @@ -213,7 +213,7 @@ void cMultipartParser::Parse(const char * a_Data, size_t a_Size) m_IncomingData.erase(0, LineEnd); continue; } - + if (strncmp(m_IncomingData.c_str() + idxBoundary, m_Boundary.c_str(), m_Boundary.size()) == 0) { // Boundary or BoundaryEnd found: @@ -228,12 +228,12 @@ void cMultipartParser::Parse(const char * a_Data, size_t a_Size) } m_Callbacks.OnPartStart(); m_IncomingData.erase(0, LineEnd + 2); - + // Keep parsing for the headers that may have come with this data: m_EnvelopeParser.Reset(); continue; } - + // It's a line, but not a boundary. It can be fully sent to the data receiver, since a boundary cannot cross lines m_Callbacks.OnPartData(m_IncomingData.c_str(), LineEnd); m_IncomingData.erase(0, LineEnd); diff --git a/src/HTTPServer/MultipartParser.h b/src/HTTPServer/MultipartParser.h index ad76ad650..4f20b2bed 100644 --- a/src/HTTPServer/MultipartParser.h +++ b/src/HTTPServer/MultipartParser.h @@ -24,52 +24,52 @@ public: public: // Force a virtual destructor in descendants: virtual ~cCallbacks() {} - + /** Called when a new part starts */ virtual void OnPartStart(void) = 0; - + /** Called when a complete header line is received for a part */ virtual void OnPartHeader(const AString & a_Key, const AString & a_Value) = 0; - + /** Called when body for a part is received */ virtual void OnPartData(const char * a_Data, size_t a_Size) = 0; - + /** Called when the current part ends */ virtual void OnPartEnd(void) = 0; } ; - + /** Creates the parser, expects to find the boundary in a_ContentType */ cMultipartParser(const AString & a_ContentType, cCallbacks & a_Callbacks); - + /** Parses more incoming data */ void Parse(const char * a_Data, size_t a_Size); - + protected: /** The callbacks to call for various parsing events */ cCallbacks & m_Callbacks; - + /** True if the data parsed so far is valid; if false, further parsing is skipped */ bool m_IsValid; - + /** Parser for each part's envelope */ cEnvelopeParser m_EnvelopeParser; - + /** Buffer for the incoming data until it is parsed */ AString m_IncomingData; - + /** The boundary, excluding both the initial "--" and the terminating CRLF */ AString m_Boundary; - + /** Set to true if some data for the current part has already been signalized to m_Callbacks. Used for proper CRLF inserting. */ bool m_HasHadData; - - + + /** Parse one line of incoming data. The CRLF has already been stripped from a_Data / a_Size */ void ParseLine(const char * a_Data, size_t a_Size); - + /** Parse one line of incoming data in the headers section of a part. The CRLF has already been stripped from a_Data / a_Size */ void ParseHeaderLine(const char * a_Data, size_t a_Size); - + // cEnvelopeParser overrides: virtual void OnHeaderLine(const AString & a_Key, const AString & a_Value) override; } ; diff --git a/src/HTTPServer/NameValueParser.cpp b/src/HTTPServer/NameValueParser.cpp index b345fef88..f759c4d21 100644 --- a/src/HTTPServer/NameValueParser.cpp +++ b/src/HTTPServer/NameValueParser.cpp @@ -29,18 +29,18 @@ public: Parser2.Parse(Data + i, 1); } Parser2.Finish(); - + // Parse as a single chunk of data: cNameValueParser Parser(Data, sizeof(Data) - 1); - + // Use the debugger to inspect the Parser variable - + // Check that the two parsers have the same content: for (cNameValueParser::const_iterator itr = Parser.begin(), end = Parser.end(); itr != end; ++itr) { ASSERT(Parser2[itr->first] == itr->second); } // for itr - Parser[] - + // Try parsing in 2-char chunks: cNameValueParser Parser3; for (int i = 0; i < sizeof(Data) - 2; i += 2) @@ -52,13 +52,13 @@ public: Parser3.Parse(Data + sizeof(Data) - 2, 1); } Parser3.Finish(); - + // Check that the third parser has the same content: for (cNameValueParser::const_iterator itr = Parser.begin(), end = Parser.end(); itr != end; ++itr) { ASSERT(Parser3[itr->first] == itr->second); } // for itr - Parser[] - + printf("cNameValueParserTest done"); } } g_Test; @@ -96,7 +96,7 @@ cNameValueParser::cNameValueParser(const char * a_Data, size_t a_Size, bool a_Al void cNameValueParser::Parse(const char * a_Data, size_t a_Size) { ASSERT(m_State != psFinished); // Calling Parse() after Finish() is wrong! - + size_t Last = 0; for (size_t i = 0; i < a_Size;) { @@ -107,7 +107,7 @@ void cNameValueParser::Parse(const char * a_Data, size_t a_Size) { return; } - + case psKeySpace: { // Skip whitespace until a non-whitespace is found, then start the key: @@ -122,7 +122,7 @@ void cNameValueParser::Parse(const char * a_Data, size_t a_Size) } break; } - + case psKey: { // Read the key until whitespace or an equal sign: @@ -174,7 +174,7 @@ void cNameValueParser::Parse(const char * a_Data, size_t a_Size) } break; } - + case psEqualSpace: { // The space before the expected equal sign; the current key is already assigned @@ -211,7 +211,7 @@ void cNameValueParser::Parse(const char * a_Data, size_t a_Size) } // while (i < a_Size) break; } // case psEqualSpace - + case psEqual: { // just parsed the equal-sign @@ -256,7 +256,7 @@ void cNameValueParser::Parse(const char * a_Data, size_t a_Size) } // while (i < a_Size) break; } // case psEqual - + case psValueInDQuotes: { while (i < a_Size) @@ -280,7 +280,7 @@ void cNameValueParser::Parse(const char * a_Data, size_t a_Size) } break; } // case psValueInDQuotes - + case psValueInSQuotes: { while (i < a_Size) @@ -304,7 +304,7 @@ void cNameValueParser::Parse(const char * a_Data, size_t a_Size) } break; } // case psValueInSQuotes - + case psValueRaw: { while (i < a_Size) @@ -328,7 +328,7 @@ void cNameValueParser::Parse(const char * a_Data, size_t a_Size) } break; } // case psValueRaw - + case psAfterValue: { // Between the closing DQuote or SQuote and the terminating semicolon diff --git a/src/HTTPServer/NameValueParser.h b/src/HTTPServer/NameValueParser.h index c0643b139..e205079db 100644 --- a/src/HTTPServer/NameValueParser.h +++ b/src/HTTPServer/NameValueParser.h @@ -19,22 +19,22 @@ class cNameValueParser : public: /** Creates an empty parser */ cNameValueParser(bool a_AllowsKeyOnly = true); - + /** Creates an empty parser, then parses the data given. Doesn't call Finish(), so more data can be parsed later */ cNameValueParser(const char * a_Data, size_t a_Size, bool a_AllowsKeyOnly = true); - + /** Parses the data given */ void Parse(const char * a_Data, size_t a_Size); - + /** Notifies the parser that no more data will be coming. Returns true if the parser state is valid */ bool Finish(void); - + /** Returns true if the data parsed so far was valid */ bool IsValid(void) const { return (m_State != psInvalid); } - + /** Returns true if the parser expects no more data */ bool IsFinished(void) const { return ((m_State == psInvalid) || (m_State == psFinished)); } - + protected: enum eState { @@ -49,20 +49,20 @@ protected: psInvalid, ///< The parser has encountered an invalid input; further parsing is skipped psFinished, ///< The parser has already been instructed to finish and doesn't expect any more data } ; - + /** The current state of the parser */ eState m_State; - + /** If true, the parser will accept keys without an equal sign and the value */ bool m_AllowsKeyOnly; - + /** Buffer for the current Key */ AString m_CurrentKey; - + /** Buffer for the current Value; */ AString m_CurrentValue; - - + + } ; diff --git a/src/HTTPServer/SslHTTPConnection.cpp b/src/HTTPServer/SslHTTPConnection.cpp index 1e862466c..1cbe02312 100644 --- a/src/HTTPServer/SslHTTPConnection.cpp +++ b/src/HTTPServer/SslHTTPConnection.cpp @@ -49,7 +49,7 @@ void cSslHTTPConnection::OnReceivedData(const char * a_Data, size_t a_Size) Data += BytesWritten; Size -= BytesWritten; } - + // Try to read as many bytes from SSL's decryption as possible: char Buffer[32000]; int NumRead = m_Ssl.ReadPlain(Buffer, sizeof(Buffer)); @@ -64,7 +64,7 @@ void cSslHTTPConnection::OnReceivedData(const char * a_Data, size_t a_Size) // SSL requires us to send data to peer first, do so by "sending" empty data: SendData(nullptr, 0); } - + // If both failed, bail out: if ((BytesWritten == 0) && (NumRead <= 0)) { @@ -93,7 +93,7 @@ void cSslHTTPConnection::SendData(const void * a_Data, size_t a_Size) pos += static_cast(NumWritten); } } - + // Read as many bytes from SSL's "outgoing" buffer as possible: char Buffer[32000]; size_t NumBytes = m_Ssl.ReadOutgoing(Buffer, sizeof(Buffer)); @@ -101,7 +101,7 @@ void cSslHTTPConnection::SendData(const void * a_Data, size_t a_Size) { m_Link->Send(Buffer, NumBytes); } - + // If both failed, bail out: if ((NumWritten <= 0) && (NumBytes == 0)) { diff --git a/src/HTTPServer/SslHTTPConnection.h b/src/HTTPServer/SslHTTPConnection.h index c461a3a24..b35bd8ba0 100644 --- a/src/HTTPServer/SslHTTPConnection.h +++ b/src/HTTPServer/SslHTTPConnection.h @@ -20,23 +20,23 @@ class cSslHTTPConnection : public cHTTPConnection { typedef cHTTPConnection super; - + public: /** Creates a new connection on the specified server. Sends the specified cert as the server certificate, uses the private key for decryption. */ cSslHTTPConnection(cHTTPServer & a_HTTPServer, const cX509CertPtr & a_Cert, const cCryptoKeyPtr & a_PrivateKey); ~cSslHTTPConnection(); - + protected: cBufferedSslContext m_Ssl; - + /** The certificate to send to the client */ cX509CertPtr m_Cert; - + /** The private key used for the certificate */ cCryptoKeyPtr m_PrivateKey; - + // cHTTPConnection overrides: virtual void OnReceivedData(const char * a_Data, size_t a_Size) override; // Data is received from the client virtual void SendData(const void * a_Data, size_t a_Size) override; // Data is to be sent to client diff --git a/src/IniFile.cpp b/src/IniFile.cpp index 2efa9064b..1e5416813 100644 --- a/src/IniFile.cpp +++ b/src/IniFile.cpp @@ -213,13 +213,13 @@ bool cIniFile::WriteFile(const AString & a_FileName) const for (size_t keyID = 0; keyID < keys.size(); ++keyID) { f << '[' << names[keyID] << ']' << iniEOL; - + // Comments. for (size_t commentID = 0; commentID < keys[keyID].comments.size(); ++commentID) { f << ';' << keys[keyID].comments[commentID] << iniEOL; } - + // Values. for (size_t valueID = 0; valueID < keys[keyID].names.size(); ++valueID) { @@ -662,7 +662,7 @@ bool cIniFile::HasValue(const AString & a_KeyName, const AString & a_ValueName) { return false; } - + // Find the value: int valueID = FindValue(keyID, a_ValueName); return (valueID != noID); diff --git a/src/IniFile.h b/src/IniFile.h index 00c4eea6e..2eb81c879 100644 --- a/src/IniFile.h +++ b/src/IniFile.h @@ -36,26 +36,26 @@ private: bool m_IsCaseInsensitive; AString m_Filename; - + struct key { std::vector names; std::vector values; std::vector comments; } ; - + std::vector keys; std::vector names; std::vector comments; - + /** If the object is case-insensitive, returns s as lowercase; otherwise returns s as-is */ AString CheckCase(const AString & s) const; /** Removes the UTF-8 BOMs (Byte order makers), if present. */ void RemoveBom(AString & a_line) const; - + public: - + /** Creates a new instance with no data */ cIniFile(void); @@ -86,7 +86,7 @@ public: /** Deletes all stored ini data (but doesn't touch the file) */ void Clear(void); - + /** Returns true iff the specified value exists. */ bool HasValue(const AString & a_KeyName, const AString & a_ValueName) const override; @@ -124,7 +124,7 @@ public: { return (GetValueI(keyname, valuename, defValue ? 1 : 0) != 0); } - + // Gets the value; if not found, write the default to the INI file AString GetValueSet (const AString & keyname, const AString & valuename, const AString & defValue = "") override; double GetValueSetF(const AString & keyname, const AString & valuename, const double defValue = 0.0); @@ -144,7 +144,7 @@ public: return AddValueI(a_KeyName, a_ValueName, a_Value ? 1 : 0); } void AddValueF(const AString & a_KeyName, const AString & a_ValueName, const double a_Value); - + // Overwrites the value of [keyname].valuename // Specify the optional parameter as false (0) if you do not want the value created if it doesn't exist. // Returns true if value set, false otherwise. @@ -158,7 +158,7 @@ public: return SetValueI(a_KeyName, a_ValueName, int(a_Value), a_CreateIfNotExists); } bool SetValueF(const AString & a_KeyName, const AString & a_ValueName, const double a_Value, const bool a_CreateIfNotExists = true); - + // Deletes specified value. // Returns true if value existed and deleted, false otherwise. bool DeleteValueByID(const int keyID, const int valueID); @@ -173,16 +173,16 @@ public: /** Returns the number of header comments */ int GetNumHeaderComments(void) {return static_cast(comments.size());} - + /** Adds a header comment */ void AddHeaderComment(const AString & comment); - + /** Returns a header comment, or empty string if out of range */ AString GetHeaderComment(const int commentID) const; - + /** Deletes a header comment. Returns true if successful */ bool DeleteHeaderComment(int commentID); - + /** Deletes all header comments */ void DeleteHeaderComments(void) {comments.clear();} @@ -198,21 +198,21 @@ public: /** Get number of key comments */ int GetNumKeyComments(const AString & keyname) const; - + /** Add a key comment */ bool AddKeyComment(const int keyID, const AString & comment); /** Add a key comment */ bool AddKeyComment(const AString & keyname, const AString & comment) override; - + /** Return a key comment */ AString GetKeyComment(const int keyID, const int commentID) const; AString GetKeyComment(const AString & keyname, const int commentID) const override; - + // Delete a key comment. bool DeleteKeyComment(const int keyID, const int commentID); bool DeleteKeyComment(const AString & keyname, const int commentID) override; - + // Delete all comments for a key. bool DeleteKeyComments(const int keyID); bool DeleteKeyComments(const AString & keyname); diff --git a/src/Inventory.cpp b/src/Inventory.cpp index 37d4c0af2..35f087d79 100644 --- a/src/Inventory.cpp +++ b/src/Inventory.cpp @@ -27,7 +27,7 @@ cInventory::cInventory(cPlayer & a_Owner) : m_ArmorSlots.AddListener(*this); m_InventorySlots.AddListener(*this); m_HotbarSlots.AddListener(*this); - + SetEquippedSlotNum(0); } @@ -143,7 +143,7 @@ int cInventory::AddItem(const cItem & a_Item, bool a_AllowNewStacks) { return res; } - + res += m_InventorySlots.AddItem(ToAdd, a_AllowNewStacks); return res; } @@ -200,7 +200,7 @@ bool cInventory::RemoveOneEquippedItem(void) { return false; } - + m_HotbarSlots.ChangeSlotCount(m_EquippedSlotNum, -1); return true; } @@ -416,7 +416,7 @@ bool cInventory::DamageItem(int a_SlotNum, short a_Amount) { return false; } - + int GridSlotNum = 0; cItemGrid * Grid = GetGridForSlotNum(a_SlotNum, GridSlotNum); if (Grid == nullptr) @@ -430,7 +430,7 @@ bool cInventory::DamageItem(int a_SlotNum, short a_Amount) SendSlot(a_SlotNum); return false; } - + // The item has broken, remove it: Grid->EmptySlot(GridSlotNum); return true; @@ -600,7 +600,7 @@ void cInventory::SaveToJson(Json::Value & a_Value) { a_Value.append(EmptyItemJson); } - + // The 4 armor slots follow: for (int i = 0; i < invArmorCount; i++) { @@ -633,24 +633,24 @@ void cInventory::SaveToJson(Json::Value & a_Value) bool cInventory::LoadFromJson(Json::Value & a_Value) { int SlotIdx = 0; - + for (Json::Value::iterator itr = a_Value.begin(); itr != a_Value.end(); ++itr, SlotIdx++) { cItem Item; Item.FromJson(*itr); - + // The JSON originally included the 4 crafting slots and the result slot, so we need to skip the first 5 items: if (SlotIdx < 5) { continue; } - + // If we loaded all the slots, stop now, even if the JSON has more: if (SlotIdx - 5 >= invNumSlots) { break; } - + int GridSlotNum = 0; cItemGrid * Grid = GetGridForSlotNum(SlotIdx - 5, GridSlotNum); ASSERT(Grid != nullptr); @@ -666,7 +666,7 @@ bool cInventory::LoadFromJson(Json::Value & a_Value) const cItemGrid * cInventory::GetGridForSlotNum(int a_SlotNum, int & a_GridSlotNum) const { ASSERT(a_SlotNum >= 0); - + if (a_SlotNum < invArmorCount) { a_GridSlotNum = a_SlotNum; @@ -689,7 +689,7 @@ const cItemGrid * cInventory::GetGridForSlotNum(int a_SlotNum, int & a_GridSlotN cItemGrid * cInventory::GetGridForSlotNum(int a_SlotNum, int & a_GridSlotNum) { ASSERT(a_SlotNum >= 0); - + if (a_SlotNum < invArmorCount) { a_GridSlotNum = a_SlotNum; @@ -712,13 +712,13 @@ cItemGrid * cInventory::GetGridForSlotNum(int a_SlotNum, int & a_GridSlotNum) void cInventory::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) { // Send the neccessary updates to whoever needs them - + if (m_Owner.IsDestroyed()) { // Owner is not (yet) valid, skip for now return; } - + // Armor update needs broadcast to other players: cWorld * World = m_Owner.GetWorld(); if ((a_ItemGrid == &m_ArmorSlots) && (World != nullptr)) @@ -734,7 +734,7 @@ void cInventory::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) { m_Owner.GetWorld()->BroadcastEntityEquipment(m_Owner, 0, GetEquippedItem(), m_Owner.GetClientHandle()); } - + // Convert the grid-local a_SlotNum to our global SlotNum: int Base = 0; if (a_ItemGrid == &m_ArmorSlots) @@ -754,7 +754,7 @@ void cInventory::OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) ASSERT(!"Unknown ItemGrid calling OnSlotChanged()"); return; } - + SendSlot(Base + a_SlotNum); } diff --git a/src/Inventory.h b/src/Inventory.h index 5501399bd..adad2fcbb 100644 --- a/src/Inventory.h +++ b/src/Inventory.h @@ -36,14 +36,14 @@ class cInventory : // tolua_begin { public: - + // Counts and offsets to individual parts of the inventory, as used by GetSlot() / SetSlot() / HowManyCanFit(): enum { invArmorCount = 4, invInventoryCount = 9 * 3, invHotbarCount = 9, - + invArmorOffset = 0, invInventoryOffset = invArmorOffset + invArmorCount, invHotbarOffset = invInventoryOffset + invInventoryCount, @@ -51,11 +51,11 @@ public: } ; // tolua_end - + cInventory(cPlayer & a_Owner); - + virtual ~cInventory() {} - + // tolua_begin /** Removes all items from the entire inventory */ @@ -66,7 +66,7 @@ public: /** Returns how many items of the specified type would fit into the slot range specified */ int HowManyCanFit(const cItem & a_ItemStack, int a_BeginSlotNum, int a_EndSlotNum, bool a_ConsiderEmptySlots); - + /** Adds as many items out of a_ItemStack as can fit. If a_AllowNewStacks is set to false, only existing stacks can be topped up; if a_AllowNewStacks is set to true, empty slots can be used for the rest. @@ -88,38 +88,38 @@ public: /** Removes one item out of the currently equipped item stack, returns true if successful, false if empty-handed */ bool RemoveOneEquippedItem(void); - + /** Returns the number of items of type a_Item that are stored */ int HowManyItems(const cItem & a_Item); - + /** Returns true if there are at least as many items of type a_ItemStack as in a_ItemStack */ bool HasItems(const cItem & a_ItemStack); /** Sends the equipped item slot to the client */ void SendEquippedSlot(); - + /** Returns the cItemGrid object representing the armor slots */ cItemGrid & GetArmorGrid(void) { return m_ArmorSlots; } - + /** Returns the cItemGrid object representing the main inventory slots */ cItemGrid & GetInventoryGrid(void) { return m_InventorySlots; } - + /** Returns the cItemGrid object representing the hotbar slots */ cItemGrid & GetHotbarGrid(void) { return m_HotbarSlots; } - + /** Returns the player associated with this inventory */ cPlayer & GetOwner(void) { return m_Owner; } - + /** Copies the non-empty slots into a_ItemStacks; preserves the original a_Items contents */ void CopyToItems(cItems & a_Items); - + // tolua_end /** Returns the player associated with this inventory (const version) */ const cPlayer & GetOwner(void) const { return m_Owner; } - + // tolua_begin - + const cItem & GetSlot(int a_SlotNum) const; const cItem & GetArmorSlot(int a_ArmorSlotNum) const; const cItem & GetInventorySlot(int a_InventorySlotNum) const; @@ -129,29 +129,29 @@ public: void SetArmorSlot(int a_ArmorSlotNum, const cItem & a_Item); void SetInventorySlot(int a_InventorySlotNum, const cItem & a_Item); void SetHotbarSlot(int a_HotBarSlotNum, const cItem & a_Item); - + void SetEquippedSlotNum(int a_SlotNum); int GetEquippedSlotNum(void) { return m_EquippedSlotNum; } - + /** Adds (or subtracts, if a_AddToCount is negative) to the count of items in the specified slot. If the slot is empty, ignores the call. Returns the new count, or -1 if the slot number is invalid. */ int ChangeSlotCount(int a_SlotNum, int a_AddToCount); - + /** Adds the specified damage to the specified item; deletes the item and returns true if the item broke. */ bool DamageItem(int a_SlotNum, short a_Amount); /** Adds the specified damage to the currently held item; deletes the item and returns true if the item broke. */ bool DamageEquippedItem(short a_Amount = 1); - + const cItem & GetEquippedHelmet (void) const { return m_ArmorSlots.GetSlot(0); } const cItem & GetEquippedChestplate(void) const { return m_ArmorSlots.GetSlot(1); } const cItem & GetEquippedLeggings (void) const { return m_ArmorSlots.GetSlot(2); } const cItem & GetEquippedBoots (void) const { return m_ArmorSlots.GetSlot(3); } // tolua_end - + /** Sends the slot contents to the owner */ void SendSlot(int a_SlotNum); @@ -166,7 +166,7 @@ public: protected: bool AddToBar(cItem & a_Item, const int a_Offset, const int a_Size, bool * a_bChangedSlots, int a_Mode = 0); - + cItemGrid m_ArmorSlots; cItemGrid m_InventorySlots; cItemGrid m_HotbarSlots; @@ -174,13 +174,13 @@ protected: int m_EquippedSlotNum; cPlayer & m_Owner; - + /** Returns the ItemGrid and the (grid-local) slot number for a (global) slot number; return nullptr for invalid SlotNum */ const cItemGrid * GetGridForSlotNum(int a_SlotNum, int & a_GridSlotNum) const; - + /** Returns the ItemGrid and the (grid-local) slot number for a (global) slot number; return nullptr for invalid SlotNum */ cItemGrid * GetGridForSlotNum(int a_SlotNum, int & a_GridSlotNum); - + // cItemGrid::cListener override: virtual void OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) override; }; // tolua_export diff --git a/src/Item.h b/src/Item.h index 46b3c2ef1..fb52c75fa 100644 --- a/src/Item.h +++ b/src/Item.h @@ -47,8 +47,8 @@ public: m_ItemColor() { } - - + + /** Creates an item of the specified type, by default 1 piece with no damage and no enchantments */ cItem( short a_ItemType, @@ -77,12 +77,12 @@ public: Empty(); } } - - + + // The constructor is disabled in code, because the compiler generates it anyway, // but it needs to stay because ToLua needs to generate the binding for it #if 0 - + /** Creates an exact copy of the item */ cItem(const cItem & a_CopyFrom) : m_ItemType (a_CopyFrom.m_ItemType), @@ -95,10 +95,10 @@ public: m_FireworkItem(a_CopyFrom.m_FireworkItem) { } - + #endif - - + + void Empty(void) { m_ItemType = E_ITEM_EMPTY; @@ -111,8 +111,8 @@ public: m_FireworkItem.EmptyData(); m_ItemColor.Clear(); } - - + + void Clear(void) { m_ItemType = E_ITEM_EMPTY; @@ -121,13 +121,13 @@ public: m_RepairCost = 0; m_ItemColor.Clear(); } - - + + bool IsEmpty(void) const { return ((m_ItemType <= 0) || (m_ItemCount <= 0)); } - + /* Returns true if this itemstack can stack with the specified stack (types match, enchantments etc.) ItemCounts are ignored. */ bool IsEqual(const cItem & a_Item) const @@ -141,8 +141,8 @@ public: m_FireworkItem.IsEqualTo(a_Item.m_FireworkItem) ); } - - + + bool IsSameType(const cItem & a_Item) const { return (m_ItemType == a_Item.m_ItemType) || (IsEmpty() && a_Item.IsEmpty()); @@ -160,35 +160,35 @@ public: /** Returns a copy of this item with m_ItemCount set to 1. Useful to preserve enchantments etc. on stacked items */ cItem CopyOne(void) const; - + /** Adds the specified count to this object and returns the reference to self (useful for chaining) */ cItem & AddCount(char a_AmountToAdd); - + /** Returns the maximum damage value that this item can have; zero if damage is not applied */ short GetMaxDamage(void) const; - + /** Damages a weapon / tool. Returns true when damage reaches max value and the item should be destroyed */ bool DamageItem(short a_Amount = 1); inline bool IsDamageable(void) const { return (GetMaxDamage() > 0); } - + /** Returns true if the item is stacked up to its maximum stacking. */ bool IsFullStack(void) const; - + /** Returns the maximum amount of stacked items of this type. */ char GetMaxStackSize(void) const; // tolua_end - + /** Returns the cItemHandler responsible for this item type */ cItemHandler * GetHandler(void) const; - + /** Saves the item data into JSON representation */ void GetJson(Json::Value & a_OutValue) const; - + /** Loads the item data from JSON representation */ void FromJson(const Json::Value & a_Value); - + /** Returns true if the specified item type is enchantable. If WithBook is true, the function is used in the anvil inventory with book enchantments. So it checks the "only book enchantments" too. Example: You can only enchant a hoe with a book. */ @@ -202,7 +202,7 @@ public: bool EnchantByXPLevels(int a_NumXPLevels); // tolua_export // tolua_begin - + short m_ItemType; char m_ItemCount; short m_ItemDamage; @@ -228,10 +228,10 @@ class cItems // tolua_export { // tolua_export public: // tolua_begin - + /** Need a Lua-accessible constructor */ cItems(void) {} - + cItem * Get (int a_Idx); void Set (int a_Idx, const cItem & a_Item); void Add (const cItem & a_Item) {push_back(a_Item); } @@ -246,7 +246,7 @@ public: { push_back(cItem(a_ItemType, a_ItemCount, a_ItemDamage)); } - + // tolua_end } ; // tolua_export diff --git a/src/ItemGrid.cpp b/src/ItemGrid.cpp index 9585ace8f..e97a53f68 100644 --- a/src/ItemGrid.cpp +++ b/src/ItemGrid.cpp @@ -160,13 +160,13 @@ void cItemGrid::EmptySlot(int a_SlotNum) ); return; } - + // Check if already empty: if (m_Slots[a_SlotNum].IsEmpty()) { return; } - + // Empty and notify m_Slots[a_SlotNum].Empty(); TriggerListeners(a_SlotNum); @@ -296,12 +296,12 @@ int cItemGrid::AddItem(cItem & a_ItemStack, bool a_AllowNewStacks, int a_Priorit return a_ItemStack.m_ItemCount; } } // for i - m_Slots[] - + if (!a_AllowNewStacks) { return (a_ItemStack.m_ItemCount - NumLeft); } - + for (int i = 0; i < m_NumSlots; i++) { if (m_Slots[i].IsEmpty()) @@ -393,7 +393,7 @@ int cItemGrid::ChangeSlotCount(int a_SlotNum, int a_AddToCount) // The item is empty, it's not gonna change return 0; } - + if (m_Slots[a_SlotNum].m_ItemCount <= -a_AddToCount) { // Trying to remove more items than there already are, make the item empty @@ -401,7 +401,7 @@ int cItemGrid::ChangeSlotCount(int a_SlotNum, int a_AddToCount) TriggerListeners(a_SlotNum); return 0; } - + m_Slots[a_SlotNum].m_ItemCount += a_AddToCount; cItemHandler * Handler = cItemHandler::GetItemHandler(m_Slots[a_SlotNum].m_ItemType); @@ -436,27 +436,27 @@ cItem cItemGrid::RemoveOneItem(int a_SlotNum) ); return cItem(); } - + // If the slot is empty, return an empty item if (m_Slots[a_SlotNum].IsEmpty()) { return cItem(); } - + // Make a copy of the item in slot, set count to 1 and remove one from the slot cItem res = m_Slots[a_SlotNum]; res.m_ItemCount = 1; m_Slots[a_SlotNum].m_ItemCount -= 1; - + // Emptying the slot correctly if appropriate if (m_Slots[a_SlotNum].m_ItemCount == 0) { m_Slots[a_SlotNum].Empty(); } - + // Notify everyone of the change TriggerListeners(a_SlotNum); - + // Return the stored one item return res; } @@ -629,7 +629,7 @@ void cItemGrid::GenerateRandomLootWithBooks(const cLootProbab * a_LootProbabs, s { TotalProbab += a_LootProbabs[i].m_Weight; } - + // Pick the loot items: cNoise Noise(a_Seed); for (int i = 0; i < a_NumSlots; i++) @@ -643,7 +643,7 @@ void cItemGrid::GenerateRandomLootWithBooks(const cLootProbab * a_LootProbabs, s cWeightedEnchantments Enchantments; cEnchantments::AddItemEnchantmentWeights(Enchantments, E_ITEM_BOOK, 24 + Noise.IntNoise2DInt(a_Seed, TotalProbab) % 7); int NumEnchantments = Noise.IntNoise3DInt(TotalProbab, Rnd, a_Seed) % 5; // The number of enchantments this book wil get. - + for (int j = 0; j <= NumEnchantments; j++) { cEnchantments Enchantment = cEnchantments::SelectEnchantmentFromVector(Enchantments, Noise.IntNoise2DInt(NumEnchantments, i)); diff --git a/src/ItemGrid.h b/src/ItemGrid.h index 8d6544792..090649c44 100644 --- a/src/ItemGrid.h +++ b/src/ItemGrid.h @@ -19,63 +19,63 @@ class cItemGrid { public: // tolua_end - + /** This class is used as a callback for when a slot changes */ class cListener { public: virtual ~cListener() {} - + /** Called whenever a slot changes */ virtual void OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) = 0; } ; typedef std::vector cListeners; - + cItemGrid(int a_Width, int a_Height); - + ~cItemGrid(); - + // tolua_begin int GetWidth (void) const { return m_Width; } int GetHeight (void) const { return m_Height; } int GetNumSlots(void) const { return m_NumSlots; } - + /** Converts XY coords into slot number; returns -1 on invalid coords */ int GetSlotNum(int a_X, int a_Y) const; - + // tolua_end /** Converts slot number into XY coords; sets coords to -1 on invalid slot number. Exported in ManualBindings.cpp */ void GetSlotCoords(int a_SlotNum, int & a_X, int & a_Y) const; // tolua_begin - + // Retrieve slots by coords or slot number; Logs warning and returns the first slot on invalid coords / slotnum const cItem & GetSlot(int a_X, int a_Y) const; const cItem & GetSlot(int a_SlotNum) const; - + // Set slot by coords or slot number; Logs warning and doesn't set on invalid coords / slotnum void SetSlot(int a_X, int a_Y, const cItem & a_Item); void SetSlot(int a_X, int a_Y, short a_ItemType, char a_ItemCount, short a_ItemDamage); void SetSlot(int a_SlotNum, const cItem & a_Item); void SetSlot(int a_SlotNum, short a_ItemType, char a_ItemCount, short a_ItemDamage); - + // Empty the specified slot; Logs warning and doesn't set on invalid coords / slotnum void EmptySlot(int a_X, int a_Y); void EmptySlot(int a_SlotNum); - + /** Returns true if the specified slot is empty or the slot doesn't exist */ bool IsSlotEmpty(int a_SlotNum) const; - + /** Returns true if the specified slot is empty or the slot doesn't exist */ bool IsSlotEmpty(int a_X, int a_Y) const; - + /** Sets all items as empty */ void Clear(void); - + /** Returns number of items out of a_ItemStack that can fit in the storage */ int HowManyCanFit(const cItem & a_ItemStack, bool a_AllowNewStacks = true); - + /** Adds as many items out of a_ItemStack as can fit. If a_AllowNewStacks is set to false, only existing stacks can be topped up; if a_AllowNewStacks is set to true, empty slots can be used for the rest. @@ -85,7 +85,7 @@ public: Returns the number of items that fit. */ int AddItem(cItem & a_ItemStack, bool a_AllowNewStacks = true, int a_PrioritarySlot = -1); - + /** Same as AddItem, but works on an entire list of item stacks. The a_ItemStackList is modified to reflect the leftover items. If a_AllowNewStacks is set to false, only existing stacks can be topped up; @@ -100,35 +100,35 @@ public: /** Removes the specified item from the grid, as many as possible, up to a_ItemStack.m_ItemCount. Returns the number of items that were removed. */ int RemoveItem(const cItem & a_ItemStack); - + /** Adds (or subtracts, if a_AddToCount is negative) to the count of items in the specified slot. If the slot is empty, ignores the call. Returns the new count. */ int ChangeSlotCount(int a_SlotNum, int a_AddToCount); - + /** Adds (or subtracts, if a_AddToCount is negative) to the count of items in the specified slot. If the slot is empty, ignores the call. Returns the new count. */ int ChangeSlotCount(int a_X, int a_Y, int a_AddToCount); - + /** Removes one item from the stack in the specified slot, and returns it. If the slot was empty, returns an empty item */ cItem RemoveOneItem(int a_SlotNum); - + /** Removes one item from the stack in the specified slot, and returns it. If the slot was empty, returns an empty item */ cItem RemoveOneItem(int a_X, int a_Y); - + /** Returns the number of items of type a_Item that are stored */ int HowManyItems(const cItem & a_Item); - + /** Returns true if there are at least as many items of type a_ItemStack as in a_ItemStack */ bool HasItems(const cItem & a_ItemStack); - + /** Returns the index of the first empty slot; -1 if all full */ int GetFirstEmptySlot(void) const; @@ -137,37 +137,37 @@ public: /** Returns the index of the last empty slot; -1 if all full */ int GetLastEmptySlot(void) const; - + /** Returns the index of the last used slot; -1 if all empty */ int GetLastUsedSlot(void) const; /** Returns the index of the first empty slot following a_StartFrom (a_StartFrom is not checked) */ int GetNextEmptySlot(int a_StartFrom) const; - + /** Returns the index of the first used slot following a_StartFrom (a_StartFrom is not checked) */ int GetNextUsedSlot(int a_StartFrom) const; - + /** Copies the contents into a cItems object; preserves the original a_Items contents */ void CopyToItems(cItems & a_Items) const; /** Adds the specified damage to the specified item; returns true if the item broke (but the item is left intact) */ bool DamageItem(int a_SlotNum, short a_Amount); - + /** Adds the specified damage to the specified item; returns true if the item broke (but the item is left intact) */ bool DamageItem(int a_X, int a_Y, short a_Amount); - + // tolua_end - - + + /** Generates random loot from the specified loot probability table, with a chance of enchanted books added. A total of a_NumSlots are taken by the loot. Cannot export to Lua due to raw array a_LootProbabs. TODO: Make this exportable / export through ManualBindings.cpp with a Lua table as LootProbabs */ void GenerateRandomLootWithBooks(const cLootProbab * a_LootProbabs, size_t a_CountLootProbabs, int a_NumSlots, int a_Seed); - + /** Adds a callback that gets called whenever a slot changes. Must not be called from within the listener callback! */ void AddListener(cListener & a_Listener); - + /** Removes a slot-change-callback. Must not be called from within the listener callback! */ void RemoveListener(cListener & a_Listener); @@ -178,11 +178,11 @@ protected: int m_Height; int m_NumSlots; // m_Width * m_Height, for easier validity checking in the access functions cItem * m_Slots; // x + m_Width * y - + cListeners m_Listeners; ///< Listeners which should be notified on slot changes; the pointers are not owned by this object cCriticalSection m_CSListeners; ///< CS that guards the m_Listeners against multi-thread access bool m_IsInTriggerListeners; ///< Set to true while TriggerListeners is running, to detect attempts to manipulate listener list while triggerring - + /** Calls all m_Listeners for the specified slot number */ void TriggerListeners(int a_SlotNum); diff --git a/src/Items/ItemArmor.h b/src/Items/ItemArmor.h index 252b94df9..906993a5b 100644 --- a/src/Items/ItemArmor.h +++ b/src/Items/ItemArmor.h @@ -47,14 +47,14 @@ public: LOGWARNING("Used unknown armor: %i", a_Item.m_ItemType); return false; } - + if (!a_Player->GetInventory().GetArmorSlot(SlotNum).IsEmpty()) { return false; } - + a_Player->GetInventory().SetArmorSlot(SlotNum, a_Item.CopyOne()); - + cItem Item(a_Item); Item.m_ItemCount--; if (Item.m_ItemCount <= 0) diff --git a/src/Items/ItemBed.h b/src/Items/ItemBed.h index 15b924a08..7f30a65c5 100644 --- a/src/Items/ItemBed.h +++ b/src/Items/ItemBed.h @@ -41,7 +41,7 @@ public: // The "foot" block: NIBBLETYPE BlockMeta = cBlockBedHandler::RotationToMetaData(a_Player.GetYaw()); a_BlocksToPlace.emplace_back(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_BED, BlockMeta); - + // Check if there is empty space for the "head" block: // (Vanilla only allows beds to be placed into air) Vector3i Direction = cBlockBedHandler::MetaDataToDirection(BlockMeta); diff --git a/src/Items/ItemBoat.h b/src/Items/ItemBoat.h index 452d86775..208904130 100644 --- a/src/Items/ItemBoat.h +++ b/src/Items/ItemBoat.h @@ -19,15 +19,15 @@ class cItemBoatHandler : public cItemHandler { typedef cItemHandler super; - + public: cItemBoatHandler(int a_ItemType) : super(a_ItemType) { } - - - + + + virtual bool OnItemUse( cWorld * a_World, cPlayer * a_Player, cBlockPluginInterface & a_PluginInterface, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace @@ -44,12 +44,12 @@ public: public: Vector3d m_Pos; bool m_HasFound; - + cCallbacks(void) : m_HasFound(false) { } - + virtual bool OnNextBlock(int a_CBBlockX, int a_CBBlockY, int a_CBBlockZ, BLOCKTYPE a_CBBlockType, NIBBLETYPE a_CBBlockMeta, char a_CBEntryFace) override { if (a_CBBlockType != E_BLOCK_AIR) @@ -61,7 +61,7 @@ public: return false; } } Callbacks; - + cLineBlockTracer Tracer(*a_World, Callbacks); Vector3d Start(a_Player->GetEyePosition() + a_Player->GetLookVector()); Vector3d End(a_Player->GetEyePosition() + a_Player->GetLookVector() * 5); @@ -76,7 +76,7 @@ public: double x = Callbacks.m_Pos.x; double y = Callbacks.m_Pos.y; double z = Callbacks.m_Pos.z; - + cBoat * Boat = new cBoat(x + 0.5, y + 1, z + 0.5); Boat->Initialize(*a_World); diff --git a/src/Items/ItemBow.h b/src/Items/ItemBow.h index 8bbaa3d8c..fc0ee8434 100644 --- a/src/Items/ItemBow.h +++ b/src/Items/ItemBow.h @@ -19,22 +19,22 @@ class cItemBowHandler : public cItemHandler { typedef cItemHandler super; - + public: cItemBowHandler(void) : super(E_ITEM_BOW) { } - - + + virtual bool OnItemUse( cWorld * a_World, cPlayer * a_Player, cBlockPluginInterface & a_PluginInterface, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace ) override { ASSERT(a_Player != nullptr); - + // Check if the player has an arrow in the inventory, or is in Creative: if (!(a_Player->IsGameModeCreative() || a_Player->GetInventory().HasItems(cItem(E_ITEM_ARROW)))) { @@ -45,8 +45,8 @@ public: return true; } - - + + virtual void OnItemShoot(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) override { // Actual shot - produce the arrow with speed based on the ticks that the bow was charged @@ -98,7 +98,7 @@ public: { Arrow->SetPickupState(cArrowEntity::psNoPickup); } - + a_Player->UseEquippedItem(); } diff --git a/src/Items/ItemBucket.h b/src/Items/ItemBucket.h index 4d39bde82..180a363ec 100644 --- a/src/Items/ItemBucket.h +++ b/src/Items/ItemBucket.h @@ -42,9 +42,9 @@ public: } } } - - - + + + bool ScoopUpFluid(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) { if (a_BlockFace != BLOCK_FACE_NONE) @@ -79,7 +79,7 @@ public: { return false; } - + // Check to see if destination block is too far away // Reach Distance Multiplayer = 5 Blocks if ((BlockPos.x - a_Player->GetPosX() > 5) || (BlockPos.z - a_Player->GetPosZ() > 5)) @@ -124,7 +124,7 @@ public: { return false; } - + BLOCKTYPE CurrentBlockType; NIBBLETYPE CurrentBlockMeta; eBlockFace EntryFace; @@ -140,7 +140,7 @@ public: { return false; } - + if (a_Player->GetGameMode() != gmCreative) { // Remove fluid bucket, add empty bucket: @@ -156,7 +156,7 @@ public: return false; } } - + // Wash away anything that was there prior to placing: if (cFluidSimulator::CanWashAway(CurrentBlockType)) { @@ -189,13 +189,13 @@ public: public: Vector3i m_Pos; bool m_HasHitFluid; - + cCallbacks(void) : m_HasHitFluid(false) { } - + virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override { if (IsBlockWater(a_BlockType) || IsBlockLava(a_BlockType)) @@ -227,8 +227,8 @@ public: a_BlockPos = Callbacks.m_Pos; return true; } - - + + bool GetPlacementCoordsFromTrace(cWorld * a_World, cPlayer * a_Player, Vector3i & a_BlockPos, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta, eBlockFace & a_BlockFace) { @@ -240,7 +240,7 @@ public: BLOCKTYPE m_ReplacedBlockType; NIBBLETYPE m_ReplacedBlockMeta; eBlockFace m_EntryFace; - + virtual bool OnNextBlock(int a_CBBlockX, int a_CBBlockY, int a_CBBlockZ, BLOCKTYPE a_CBBlockType, NIBBLETYPE a_CBBlockMeta, char a_CBEntryFace) override { if (a_CBBlockType != E_BLOCK_AIR) diff --git a/src/Items/ItemChest.h b/src/Items/ItemChest.h index 3dd112c91..786ed1067 100644 --- a/src/Items/ItemChest.h +++ b/src/Items/ItemChest.h @@ -40,7 +40,7 @@ public: // Clicked in air return false; } - + if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height)) { // The clicked block is outside the world, ignore this call altogether (#128) @@ -62,13 +62,13 @@ public: else { AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); - + if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height)) { // The block is being placed outside the world, ignore this packet altogether (#128) return false; } - + NIBBLETYPE PlaceMeta; BLOCKTYPE PlaceBlock; a_World.GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, PlaceBlock, PlaceMeta); diff --git a/src/Items/ItemEmptyMap.h b/src/Items/ItemEmptyMap.h index f26f915c4..78d037313 100644 --- a/src/Items/ItemEmptyMap.h +++ b/src/Items/ItemEmptyMap.h @@ -20,7 +20,7 @@ class cItemEmptyMapHandler : typedef cItemHandler super; static const unsigned int DEFAULT_SCALE = 0; - + public: cItemEmptyMapHandler() : super(E_ITEM_EMPTY_MAP) diff --git a/src/Items/ItemFishingRod.h b/src/Items/ItemFishingRod.h index 355ff2eae..3a2ef0275 100644 --- a/src/Items/ItemFishingRod.h +++ b/src/Items/ItemFishingRod.h @@ -86,7 +86,7 @@ class cItemFishingRodHandler : public cItemHandler { typedef cItemHandler super; - + public: cItemFishingRodHandler(int a_ItemType) : super(a_ItemType) diff --git a/src/Items/ItemFood.h b/src/Items/ItemFood.h index 2fbbb2528..cfdac26c6 100644 --- a/src/Items/ItemFood.h +++ b/src/Items/ItemFood.h @@ -11,7 +11,7 @@ class cItemFoodHandler : public cItemHandler { typedef cItemHandler super; - + public: cItemFoodHandler(int a_ItemType) : super(a_ItemType) diff --git a/src/Items/ItemGoldenApple.h b/src/Items/ItemGoldenApple.h index 5f6f1de6c..c6bd7e470 100644 --- a/src/Items/ItemGoldenApple.h +++ b/src/Items/ItemGoldenApple.h @@ -10,7 +10,7 @@ class cItemGoldenAppleHandler : public cItemFoodHandler { typedef cItemFoodHandler super; - + public: cItemGoldenAppleHandler() : super(E_ITEM_GOLDEN_APPLE) diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index 5d088dfcd..8a05149b0 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -104,7 +104,7 @@ cItemHandler * cItemHandler::CreateItemHandler(int a_ItemType) switch (a_ItemType) { default: return new cItemHandler(a_ItemType); - + // Single item per handler, alphabetically sorted: case E_BLOCK_BIG_FLOWER: return new cItemBigFlowerHandler; case E_BLOCK_CHEST: return new cItemChestHandler(a_ItemType); @@ -152,7 +152,7 @@ cItemHandler * cItemHandler::CreateItemHandler(int a_ItemType) case E_ITEM_SPAWN_EGG: return new cItemSpawnEggHandler(a_ItemType); case E_ITEM_STRING: return new cItemStringHandler(a_ItemType); case E_ITEM_SUGARCANE: return new cItemSugarcaneHandler(a_ItemType); - + case E_ITEM_WOODEN_HOE: case E_ITEM_STONE_HOE: case E_ITEM_IRON_HOE: @@ -161,7 +161,7 @@ cItemHandler * cItemHandler::CreateItemHandler(int a_ItemType) { return new cItemHoeHandler(a_ItemType); } - + case E_ITEM_WOODEN_PICKAXE: case E_ITEM_STONE_PICKAXE: case E_ITEM_IRON_PICKAXE: @@ -170,7 +170,7 @@ cItemHandler * cItemHandler::CreateItemHandler(int a_ItemType) { return new cItemPickaxeHandler(a_ItemType); } - + case E_ITEM_WOODEN_SHOVEL: case E_ITEM_STONE_SHOVEL: case E_ITEM_IRON_SHOVEL: @@ -179,7 +179,7 @@ cItemHandler * cItemHandler::CreateItemHandler(int a_ItemType) { return new cItemShovelHandler(a_ItemType); } - + case E_ITEM_WOODEN_SWORD: case E_ITEM_STONE_SWORD: case E_ITEM_IRON_SWORD: @@ -188,14 +188,14 @@ cItemHandler * cItemHandler::CreateItemHandler(int a_ItemType) { return new cItemSwordHandler(a_ItemType); } - + case E_ITEM_BUCKET: case E_ITEM_WATER_BUCKET: case E_ITEM_LAVA_BUCKET: { return new cItemBucketHandler(a_ItemType); } - + case E_ITEM_CARROT: case E_ITEM_MELON_SEEDS: case E_ITEM_POTATO: @@ -204,7 +204,7 @@ cItemHandler * cItemHandler::CreateItemHandler(int a_ItemType) { return new cItemSeedsHandler(a_ItemType); } - + case E_ITEM_ACACIA_DOOR: case E_ITEM_BIRCH_DOOR: case E_ITEM_DARK_OAK_DOOR: @@ -215,7 +215,7 @@ cItemHandler * cItemHandler::CreateItemHandler(int a_ItemType) { return new cItemDoorHandler(a_ItemType); } - + case E_ITEM_MINECART: case E_ITEM_CHEST_MINECART: case E_ITEM_FURNACE_MINECART: @@ -224,7 +224,7 @@ cItemHandler * cItemHandler::CreateItemHandler(int a_ItemType) { return new cItemMinecartHandler(a_ItemType); } - + // Food (please keep alpha-sorted): // (carrots and potatoes handled separately in SeedHandler as they're both seed and food) case E_ITEM_BAKED_POTATO: @@ -321,13 +321,13 @@ bool cItemHandler::OnPlayerPlace( // Clicked in air return false; } - + if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height)) { // The clicked block is outside the world, ignore this call altogether (#128) return false; } - + BLOCKTYPE ClickedBlock; NIBBLETYPE ClickedBlockMeta; @@ -345,13 +345,13 @@ bool cItemHandler::OnPlayerPlace( else { AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); - + if ((a_BlockY < 0) || (a_BlockY >= cChunkDef::Height)) { // The block is being placed outside the world, ignore this packet altogether (#128) return false; } - + NIBBLETYPE PlaceMeta; BLOCKTYPE PlaceBlock; a_World.GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, PlaceBlock, PlaceMeta); @@ -382,7 +382,7 @@ bool cItemHandler::OnPlayerPlace( a_Player.GetInventory().SendEquippedSlot(); return false; } - + // Try to place the blocks: if (!a_Player.PlaceBlocks(blocks)) { @@ -477,7 +477,7 @@ bool cItemHandler::OnDiggingBlock(cWorld * a_World, cPlayer * a_Player, const cI UNUSED(a_BlockY); UNUSED(a_BlockZ); UNUSED(a_Dir); - + return false; } @@ -488,7 +488,7 @@ bool cItemHandler::OnDiggingBlock(cWorld * a_World, cPlayer * a_Player, const cI void cItemHandler::OnBlockDestroyed(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ) { UNUSED(a_Item); - + BLOCKTYPE Block = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); cBlockHandler * Handler = cBlockInfo::GetHandler(Block); @@ -537,7 +537,7 @@ short cItemHandler::GetDurabilityLossByAction(eDurabilityLostAction a_Action) case dlaAttackEntity: return 2; case dlaBreakBlock: return 1; } - + #ifndef __clang__ return 0; #endif @@ -554,7 +554,7 @@ char cItemHandler::GetMaxStackSize(void) // All blocks can stack up to 64 return 64; } - + switch (m_ItemType) { case E_ITEM_ACACIA_DOOR: return 64; @@ -693,7 +693,7 @@ bool cItemHandler::IsFood(void) bool cItemHandler::IsDrinkable(short a_ItemDamage) { UNUSED(a_ItemDamage); - + return false; } @@ -793,13 +793,13 @@ bool cItemHandler::GetPlacementBlockTypeMeta( ) { ASSERT(m_ItemType < 256); // Items with IDs above 255 should all be handled by specific handlers - + if (m_ItemType >= 256) { LOGERROR("%s: Item %d is not eligible for direct block placement!", __FUNCTION__, m_ItemType); return false; } - + cBlockHandler * BlockH = BlockHandler(static_cast(m_ItemType)); cChunkInterface ChunkInterface(a_World->GetChunkMap()); return BlockH->GetPlacementBlockTypeMeta( diff --git a/src/Items/ItemHandler.h b/src/Items/ItemHandler.h index be2e2fade..a2b825fb7 100644 --- a/src/Items/ItemHandler.h +++ b/src/Items/ItemHandler.h @@ -29,7 +29,7 @@ public: }; cItemHandler(int a_ItemType); - + /** Force virtual destructor */ virtual ~cItemHandler() {} @@ -45,7 +45,7 @@ public: int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ ); - + /** Called from OnPlayerPlace() to determine the blocks that the current placement operation should set. The block coords are where the new (main) block should be placed. @@ -69,7 +69,7 @@ public: int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta ); - + /** Called when the player tries to use the item (right mouse button). Return false to abort the usage. DEFAULT: False */ @@ -77,7 +77,7 @@ public: cWorld * a_World, cPlayer * a_Player, cBlockPluginInterface & a_PluginInterface, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace ); - + /** Called when the client sends the SHOOT status in the lclk packet */ virtual void OnItemShoot(cPlayer *, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace) @@ -95,16 +95,16 @@ public: UNUSED(a_Player); UNUSED(a_Item); } - + /** Called while the player diggs a block using this item */ virtual bool OnDiggingBlock(cWorld * a_World, cPlayer * a_Player, const cItem & a_HeldItem, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace); - + /** Called when the player destroys a block using this item. This also calls the drop function for the destroyed block */ virtual void OnBlockDestroyed(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ); /** Called when a player attacks a other entity. */ virtual void OnEntityAttack(cPlayer * a_Attacker, cEntity * a_AttackedEntity); - + /** Called after the player has eaten this item. */ virtual void OnFoodEaten(cWorld *a_World, cPlayer *a_Player, cItem *a_Item); @@ -137,13 +137,13 @@ public: /** Indicates if this item is a tool */ virtual bool IsTool(void); - + /** Indicates if this item is food */ virtual bool IsFood(void); - + /** Indicates if this item is drinkable */ virtual bool IsDrinkable(short a_ItemDamage); - + /** Blocks simply get placed */ virtual bool IsPlaceable(void); @@ -158,7 +158,7 @@ public: static cItemHandler * GetItemHandler(const cItem & a_Item) { return GetItemHandler(a_Item.m_ItemType); } static void Deinit(); - + protected: int m_ItemType; static cItemHandler * CreateItemHandler(int m_ItemType); diff --git a/src/Items/ItemLeaves.h b/src/Items/ItemLeaves.h index f48126dc5..57f1fa365 100644 --- a/src/Items/ItemLeaves.h +++ b/src/Items/ItemLeaves.h @@ -11,7 +11,7 @@ class cItemLeavesHandler : public cItemHandler { typedef cItemHandler super; - + public: cItemLeavesHandler(int a_ItemType) : cItemHandler(a_ItemType) diff --git a/src/Items/ItemLighter.h b/src/Items/ItemLighter.h index a1b4b871b..eda7ed64c 100644 --- a/src/Items/ItemLighter.h +++ b/src/Items/ItemLighter.h @@ -30,7 +30,7 @@ public: { return false; } - + if (!a_Player->IsGameModeCreative()) { switch (m_ItemType) diff --git a/src/Items/ItemMap.h b/src/Items/ItemMap.h index 19b974767..afce4ba01 100644 --- a/src/Items/ItemMap.h +++ b/src/Items/ItemMap.h @@ -20,7 +20,7 @@ class cItemMapHandler : typedef cItemHandler super; static const unsigned int DEFAULT_RADIUS = 128; - + public: cItemMapHandler() : super(E_ITEM_MAP) diff --git a/src/Items/ItemMilk.h b/src/Items/ItemMilk.h index c9a90865a..c426c0057 100644 --- a/src/Items/ItemMilk.h +++ b/src/Items/ItemMilk.h @@ -10,13 +10,13 @@ public: super(E_ITEM_MILK) { } - + virtual bool IsDrinkable(short a_ItemDamage) override { UNUSED(a_ItemDamage); return true; } - + virtual bool EatItem(cPlayer * a_Player, cItem * a_Item) override { UNUSED(a_Item); diff --git a/src/Items/ItemMinecart.h b/src/Items/ItemMinecart.h index 2cf42507b..6344c0178 100644 --- a/src/Items/ItemMinecart.h +++ b/src/Items/ItemMinecart.h @@ -18,15 +18,15 @@ class cItemMinecartHandler : public cItemHandler { typedef cItemHandler super; - + public: cItemMinecartHandler(int a_ItemType) : super(a_ItemType) { } - - - + + + virtual bool OnItemUse( cWorld * a_World, cPlayer * a_Player, cBlockPluginInterface & a_PluginInterface, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace @@ -36,7 +36,7 @@ public: { return false; } - + // Check that there's rail in there: BLOCKTYPE Block = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); switch (Block) @@ -55,7 +55,7 @@ public: return false; } } - + double x = static_cast(a_BlockX) + 0.5; double y = static_cast(a_BlockY) + 0.5; double z = static_cast(a_BlockZ) + 0.5; diff --git a/src/Items/ItemMobHead.h b/src/Items/ItemMobHead.h index e0f72be9b..fdecabbbf 100644 --- a/src/Items/ItemMobHead.h +++ b/src/Items/ItemMobHead.h @@ -68,7 +68,7 @@ public: cPlayer & m_Player; eMobHeadType m_HeadType; NIBBLETYPE m_BlockMeta; - + virtual bool Item(cBlockEntity * a_BlockEntity) { if (a_BlockEntity->GetBlockType() != E_BLOCK_HEAD) @@ -88,7 +88,7 @@ public: MobHeadEntity->GetWorld()->BroadcastBlockEntity(MobHeadEntity->GetPosX(), MobHeadEntity->GetPosY(), MobHeadEntity->GetPosZ()); return false; } - + public: cCallback (cPlayer & a_CBPlayer, eMobHeadType a_HeadType, NIBBLETYPE a_BlockMeta) : m_Player(a_CBPlayer), @@ -334,7 +334,7 @@ public: return true; } - + virtual bool GetPlacementBlockTypeMeta( cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, diff --git a/src/Items/ItemNetherWart.h b/src/Items/ItemNetherWart.h index 10a0864b5..3586231b3 100644 --- a/src/Items/ItemNetherWart.h +++ b/src/Items/ItemNetherWart.h @@ -35,7 +35,7 @@ public: // Only allow planting nether wart from the top side of the block return false; } - + // Only allow placement on farmland int X = a_BlockX; int Y = a_BlockY; diff --git a/src/Items/ItemPickaxe.h b/src/Items/ItemPickaxe.h index 1d5abddb6..e69f47ae0 100644 --- a/src/Items/ItemPickaxe.h +++ b/src/Items/ItemPickaxe.h @@ -29,7 +29,7 @@ public: default: return 0; } } - + virtual bool CanHarvestBlock(BLOCKTYPE a_BlockType) override { switch (a_BlockType) @@ -38,7 +38,7 @@ public: { return PickaxeLevel() >= 4; } - + case E_BLOCK_DIAMOND_BLOCK: case E_BLOCK_DIAMOND_ORE: case E_BLOCK_EMERALD_ORE: @@ -49,7 +49,7 @@ public: { return PickaxeLevel() >= 3; } - + case E_BLOCK_IRON_BLOCK: case E_BLOCK_IRON_ORE: case E_BLOCK_LAPIS_ORE: @@ -57,7 +57,7 @@ public: { return PickaxeLevel() >= 2; } - + case E_BLOCK_ANVIL: case E_BLOCK_BRICK: case E_BLOCK_CAULDRON: diff --git a/src/Items/ItemPotion.h b/src/Items/ItemPotion.h index a176c591e..01c011fa3 100644 --- a/src/Items/ItemPotion.h +++ b/src/Items/ItemPotion.h @@ -8,14 +8,14 @@ class cItemPotionHandler: public cItemHandler { typedef cItemHandler super; - + public: cItemPotionHandler(): super(E_ITEM_POTION) { } - + // cItemHandler overrides: virtual bool IsDrinkable(short a_ItemDamage) override @@ -25,47 +25,47 @@ public: return cEntityEffect::IsPotionDrinkable(a_ItemDamage); } - + virtual bool OnItemUse( cWorld * a_World, cPlayer * a_Player, cBlockPluginInterface & a_PluginInterface, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace ) override { short PotionDamage = a_Item.m_ItemDamage; - + // Do not throw non-splash potions: if (cEntityEffect::IsPotionDrinkable(PotionDamage)) { return false; } - + Vector3d Pos = a_Player->GetThrowStartPos(); Vector3d Speed = a_Player->GetLookVector() * 7; - + if (a_World->CreateProjectile(Pos.x, Pos.y, Pos.z, cProjectileEntity::pkSplashPotion, a_Player, &a_Player->GetEquippedItem(), &Speed) == cEntity::INVALID_ID) { return false; } - + if (!a_Player->IsGameModeCreative()) { a_Player->GetInventory().RemoveOneEquippedItem(); } - + return true; } - - + + virtual bool EatItem(cPlayer * a_Player, cItem * a_Item) override { short PotionDamage = a_Item->m_ItemDamage; - + // Do not drink undrinkable potions: if (!cEntityEffect::IsPotionDrinkable(a_Item->m_ItemDamage)) { return false; } - + a_Player->AddEntityEffect( cEntityEffect::GetPotionEffectType(PotionDamage), cEntityEffect::GetPotionEffectDuration(PotionDamage), diff --git a/src/Items/ItemSeeds.h b/src/Items/ItemSeeds.h index e1db7c5f4..408899a78 100644 --- a/src/Items/ItemSeeds.h +++ b/src/Items/ItemSeeds.h @@ -42,7 +42,7 @@ public: default: return FoodInfo(0, 0); } } - + virtual bool GetPlacementBlockTypeMeta( cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, @@ -55,7 +55,7 @@ public: // Only allow planting seeds from the top side of the block return false; } - + // Only allow placement on farmland int X = a_BlockX; int Y = a_BlockY; @@ -65,7 +65,7 @@ public: { return false; } - + a_BlockMeta = 0; switch (m_ItemType) { diff --git a/src/Items/ItemShears.h b/src/Items/ItemShears.h index 73343f629..c8034b112 100644 --- a/src/Items/ItemShears.h +++ b/src/Items/ItemShears.h @@ -18,14 +18,14 @@ public: cItemHandler(a_ItemType) { } - - + + virtual bool IsTool(void) override { return true; } - - + + virtual bool OnDiggingBlock(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Dir) override { BLOCKTYPE Block; diff --git a/src/Items/ItemShovel.h b/src/Items/ItemShovel.h index cd235678d..739ed833e 100644 --- a/src/Items/ItemShovel.h +++ b/src/Items/ItemShovel.h @@ -36,7 +36,7 @@ public: } return false; } - + virtual bool CanHarvestBlock(BLOCKTYPE a_BlockType) override { if (a_BlockType == E_BLOCK_SNOW) diff --git a/src/Items/ItemSign.h b/src/Items/ItemSign.h index 3da93e2f1..d8d0197d3 100644 --- a/src/Items/ItemSign.h +++ b/src/Items/ItemSign.h @@ -45,7 +45,7 @@ public: return true; } - + virtual bool GetPlacementBlockTypeMeta( cWorld * a_World, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, diff --git a/src/Items/ItemSpawnEgg.h b/src/Items/ItemSpawnEgg.h index 85dd2d245..52317a6cb 100644 --- a/src/Items/ItemSpawnEgg.h +++ b/src/Items/ItemSpawnEgg.h @@ -29,7 +29,7 @@ public: { return false; } - + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); if (a_BlockFace == BLOCK_FACE_YM) @@ -49,11 +49,11 @@ public: } return true; } - + return false; } - + /** Converts the Spawn egg item damage to the monster type to spawn. Returns mtInvalidType for invalid damage values. */ static eMonsterType ItemDamageToMonsterType(short a_ItemDamage) diff --git a/src/Items/ItemSword.h b/src/Items/ItemSword.h index 3b0db7b21..a15a9e3db 100644 --- a/src/Items/ItemSword.h +++ b/src/Items/ItemSword.h @@ -51,7 +51,7 @@ public: case dlaAttackEntity: return 1; case dlaBreakBlock: return 2; } - + #ifndef __clang__ return 0; #endif diff --git a/src/Items/ItemThrowable.h b/src/Items/ItemThrowable.h index 0e06623fc..d5a109887 100644 --- a/src/Items/ItemThrowable.h +++ b/src/Items/ItemThrowable.h @@ -24,7 +24,7 @@ public: m_SpeedCoeff(a_SpeedCoeff) { } - + virtual bool OnItemUse( @@ -51,7 +51,7 @@ public: return true; } - + protected: cProjectileEntity::eKind m_ProjectileKind; double m_SpeedCoeff; @@ -79,7 +79,7 @@ class cItemSnowballHandler : public cItemThrowableHandler { typedef cItemThrowableHandler super; - + public: cItemSnowballHandler(void) : super(E_ITEM_SNOWBALL, cProjectileEntity::pkSnowball, 30) @@ -95,7 +95,7 @@ class cItemEnderPearlHandler : public cItemThrowableHandler { typedef cItemThrowableHandler super; - + public: cItemEnderPearlHandler(void) : super(E_ITEM_ENDER_PEARL, cProjectileEntity::pkEnderPearl, 30) diff --git a/src/LightingThread.cpp b/src/LightingThread.cpp index 25956ae86..4e2826778 100644 --- a/src/LightingThread.cpp +++ b/src/LightingThread.cpp @@ -37,8 +37,8 @@ class cReader : OutputIdx += cChunkDef::Width * 6; } // for y } // BlockTypes() - - + + virtual void HeightMap(const cChunkDef::HeightMap * a_Heightmap) override { // Copy the entire heightmap, distribute it into the 3x3 chunk blob: @@ -64,14 +64,14 @@ class cReader : } m_MaxHeight = MaxHeight; } - + public: int m_ReadingChunkX; // 0, 1 or 2; x-offset of the chunk we're reading from the BlockTypes start int m_ReadingChunkZ; // 0, 1 or 2; z-offset of the chunk we're reading from the BlockTypes start HEIGHTTYPE m_MaxHeight; // Maximum value in this chunk's heightmap BLOCKTYPE * m_BlockTypes; // 3x3 chunks of block types, organized as a single XZY blob of data (instead of 3x3 XZY blobs) HEIGHTTYPE * m_HeightMap; // 3x3 chunks of height map, organized as a single XZY blob of data (instead of 3x3 XZY blobs) - + cReader(BLOCKTYPE * a_BlockTypes, HEIGHTTYPE * a_HeightMap) : m_ReadingChunkX(0), m_ReadingChunkZ(0), @@ -114,7 +114,7 @@ bool cLightingThread::Start(cWorld * a_World) { ASSERT(m_World == nullptr); // Not started yet m_World = a_World; - + return super::Start(); } @@ -141,7 +141,7 @@ void cLightingThread::Stop(void) } m_ShouldTerminate = true; m_evtItemAdded.Set(); - + Wait(); } @@ -152,7 +152,7 @@ void cLightingThread::Stop(void) void cLightingThread::QueueChunk(int a_ChunkX, int a_ChunkZ, std::unique_ptr a_CallbackAfter) { ASSERT(m_World != nullptr); // Did you call Start() properly? - + cChunkStay * ChunkStay = new cLightingChunkStay(*this, a_ChunkX, a_ChunkZ, std::move(a_CallbackAfter)); { // The ChunkStay will enqueue itself using the QueueChunkStay() once it is fully loaded @@ -203,12 +203,12 @@ void cLightingThread::Execute(void) m_evtItemAdded.Wait(); } } - + if (m_ShouldTerminate) { return; } - + // Process one items from the queue: cLightingChunkStay * Item; { @@ -224,7 +224,7 @@ void cLightingThread::Execute(void) m_evtQueueEmpty.Set(); } } // CSLock(m_CS) - + LightChunk(*Item); Item->Disable(); delete Item; @@ -249,14 +249,14 @@ void cLightingThread::LightChunk(cLightingChunkStay & a_Item) } cChunkDef::BlockNibbles BlockLight, SkyLight; - + ReadChunks(a_Item.m_ChunkX, a_Item.m_ChunkZ); - + PrepareBlockLight(); CalcLight(m_BlockLight); - + PrepareSkyLight(); - + /* // DEBUG: Save chunk data with highlighted seeds for visual inspection: cFile f4; @@ -283,9 +283,9 @@ void cLightingThread::LightChunk(cLightingChunkStay & a_Item) f4.Close(); } //*/ - + CalcLight(m_SkyLight); - + /* // DEBUG: Save XY slices of the chunk data and lighting for visual inspection: cFile f1, f2, f3; @@ -316,10 +316,10 @@ void cLightingThread::LightChunk(cLightingChunkStay & a_Item) f3.Close(); } //*/ - + CompressLight(m_BlockLight, BlockLight); CompressLight(m_SkyLight, SkyLight); - + m_World->ChunkLighted(a_Item.m_ChunkX, a_Item.m_ChunkZ, BlockLight, SkyLight); if (a_Item.m_CallbackAfter != nullptr) @@ -335,7 +335,7 @@ void cLightingThread::LightChunk(cLightingChunkStay & a_Item) void cLightingThread::ReadChunks(int a_ChunkX, int a_ChunkZ) { cReader Reader(m_BlockTypes, m_HeightMap); - + for (int z = 0; z < 3; z++) { Reader.m_ReadingChunkZ = z; @@ -345,7 +345,7 @@ void cLightingThread::ReadChunks(int a_ChunkX, int a_ChunkZ) VERIFY(m_World->GetChunkData(a_ChunkX + x - 1, a_ChunkZ + z - 1, Reader)); } // for z } // for x - + memset(m_BlockLight, 0, sizeof(m_BlockLight)); memset(m_SkyLight, 0, sizeof(m_SkyLight)); m_MaxHeight = Reader.m_MaxHeight; @@ -360,7 +360,7 @@ void cLightingThread::PrepareSkyLight(void) // Clear seeds: memset(m_IsSeed1, 0, sizeof(m_IsSeed1)); m_NumSeeds = 0; - + // Walk every column that has all XZ neighbors for (int z = 1; z < cChunkDef::Width * 3 - 1; z++) { @@ -374,13 +374,13 @@ void cLightingThread::PrepareSkyLight(void) int Neighbor3 = m_HeightMap[idx + cChunkDef::Width * 3] + 1; // Z + 1 int Neighbor4 = m_HeightMap[idx - cChunkDef::Width * 3] + 1; // Z - 1 int MaxNeighbor = std::max(std::max(Neighbor1, Neighbor2), std::max(Neighbor3, Neighbor4)); // Maximum of the four neighbors - + // Fill the column from the top down to Current with all-light: for (int y = cChunkDef::Height - 1, Index = idx + y * BlocksPerYLayer; y >= Current; y--, Index -= BlocksPerYLayer) { m_SkyLight[Index] = 15; } - + // Add Current as a seed: if (Current < cChunkDef::Height) { @@ -388,7 +388,7 @@ void cLightingThread::PrepareSkyLight(void) m_IsSeed1[CurrentIdx] = true; m_SeedIdx1[m_NumSeeds++] = static_cast(CurrentIdx); } - + // Add seed from Current up to the highest neighbor: for (int y = Current + 1, Index = idx + y * BlocksPerYLayer; y < MaxNeighbor; y++, Index += BlocksPerYLayer) { @@ -423,7 +423,7 @@ void cLightingThread::PrepareBlockLight(void) { continue; } - + // Add current block as a seed: m_IsSeed1[Index] = true; m_SeedIdx1[m_NumSeeds++] = static_cast(Index); @@ -445,7 +445,7 @@ void cLightingThread::PrepareBlockLight2(void) memset(m_IsSeed1, 0, sizeof(m_IsSeed1)); memset(m_IsSeed2, 0, sizeof(m_IsSeed2)); m_NumSeeds = 0; - + // Add each emissive block into the seeds: for (int y = 0; y < m_MaxHeight; y++) { @@ -467,7 +467,7 @@ void cLightingThread::PrepareBlockLight2(void) // Not a light-emissive block continue; } - + // Add current block as a seed: m_IsSeed1[idx] = true; m_SeedIdx1[m_NumSeeds++] = static_cast(idx); @@ -496,7 +496,7 @@ void cLightingThread::CalcLight(NIBBLETYPE * a_Light) { return; } - + // Buffer 2 -> buffer 1 memset(m_IsSeed1, 0, sizeof(m_IsSeed1)); m_NumSeeds = 0; @@ -522,7 +522,7 @@ void cLightingThread::CalcLightStep( int SeedX = SeedIdx % (cChunkDef::Width * 3); int SeedZ = (SeedIdx / (cChunkDef::Width * 3)) % (cChunkDef::Width * 3); int SeedY = SeedIdx / BlocksPerYLayer; - + // Propagate seed: if (SeedX < cChunkDef::Width * 3 - 1) { @@ -623,7 +623,7 @@ cLightingThread::cLightingChunkStay::cLightingChunkStay(cLightingThread & a_Ligh bool cLightingThread::cLightingChunkStay::OnAllChunksAvailable(void) { m_LightingThread.QueueChunkStay(*this); - + // Keep the ChunkStay alive: return false; } diff --git a/src/LightingThread.h b/src/LightingThread.h index 138c40002..d95214a3c 100644 --- a/src/LightingThread.h +++ b/src/LightingThread.h @@ -50,25 +50,25 @@ class cLightingThread : public cIsThread { typedef cIsThread super; - + public: - + cLightingThread(void); ~cLightingThread(); - + bool Start(cWorld * a_World); - + void Stop(void); - + /** Queues the entire chunk for lighting. The callback, if specified, is called after the lighting has been processed. */ void QueueChunk(int a_ChunkX, int a_ChunkZ, std::unique_ptr a_CallbackAfter); - + /** Blocks until the queue is empty or the thread is terminated */ void WaitForQueueEmpty(void); - + size_t GetQueueLength(void); - + protected: class cLightingChunkStay : @@ -79,9 +79,9 @@ protected: int m_ChunkX; int m_ChunkZ; std::unique_ptr m_CallbackAfter; - + cLightingChunkStay(cLightingThread & a_LightingThread, int a_ChunkX, int a_ChunkZ, std::unique_ptr a_CallbackAfter); - + protected: virtual void OnChunkAvailable(int a_ChunkX, int a_ChunkZ) override { @@ -91,15 +91,15 @@ protected: virtual bool OnAllChunksAvailable(void) override; virtual void OnDisabled(void) override; } ; - + typedef std::list cChunkStays; - - + + cWorld * m_World; - + /** The mutex to protect m_Queue and m_PendingQueue */ cCriticalSection m_CS; - + /** The ChunkStays that are loaded and are waiting to be lit. */ cChunkStays m_Queue; @@ -108,11 +108,11 @@ protected: cEvent m_evtItemAdded; // Set when queue is appended, or to stop the thread cEvent m_evtQueueEmpty; // Set when the queue gets empty - + /** The highest block in the current 3x3 chunk data */ HEIGHTTYPE m_MaxHeight; - - + + // Buffers for the 3x3 chunk data // These buffers alone are 1.7 MiB in size, therefore they cannot be located on the stack safely - some architectures may have only 1 MiB for stack, or even less // Placing the buffers into the object means that this object can light chunks only in one thread! @@ -123,7 +123,7 @@ protected: NIBBLETYPE m_BlockLight[BlocksPerYLayer * cChunkDef::Height]; NIBBLETYPE m_SkyLight [BlocksPerYLayer * cChunkDef::Height]; HEIGHTTYPE m_HeightMap [BlocksPerYLayer]; - + // Seed management (5.7 MiB) // Two buffers, in each calc step one is set as input and the other as output, then in the next step they're swapped // Each seed is represented twice in this structure - both as a "list" and as a "position". @@ -139,33 +139,33 @@ protected: /** Lights the entire chunk. If neighbor chunks don't exist, touches them and re-queues the chunk */ void LightChunk(cLightingChunkStay & a_Item); - + /** Prepares m_BlockTypes and m_HeightMap data; zeroes out the light arrays */ void ReadChunks(int a_ChunkX, int a_ChunkZ); - + /** Uses m_HeightMap to initialize the m_SkyLight[] data; fills in seeds for the skylight */ void PrepareSkyLight(void); - + /** Uses m_BlockTypes to initialize the m_BlockLight[] data; fills in seeds for the blocklight */ void PrepareBlockLight(void); - + /** Same as PrepareBlockLight(), but uses a different traversal scheme; possibly better perf cache-wise. To be compared in perf benchmarks. */ void PrepareBlockLight2(void); - + /** Calculates light in the light array specified, using stored seeds */ void CalcLight(NIBBLETYPE * a_Light); - + /** Does one step in the light calculation - one seed propagation and seed recalculation */ void CalcLightStep( NIBBLETYPE * a_Light, size_t a_NumSeedsIn, unsigned char * a_IsSeedIn, unsigned int * a_SeedIdxIn, size_t & a_NumSeedsOut, unsigned char * a_IsSeedOut, unsigned int * a_SeedIdxOut ); - + /** Compresses from 1-block-per-byte (faster calc) into 2-blocks-per-byte (MC storage): */ void CompressLight(NIBBLETYPE * a_LightArray, NIBBLETYPE * a_ChunkLight); - + inline void PropagateLight( NIBBLETYPE * a_Light, unsigned int a_SrcIdx, unsigned int a_DstIdx, @@ -174,7 +174,7 @@ protected: { ASSERT(a_SrcIdx < ARRAYCOUNT(m_SkyLight)); ASSERT(a_DstIdx < ARRAYCOUNT(m_BlockTypes)); - + if (a_Light[a_SrcIdx] <= a_Light[a_DstIdx] + cBlockInfo::GetSpreadLightFalloff(m_BlockTypes[a_DstIdx])) { // We're not offering more light than the dest block already has @@ -188,11 +188,11 @@ protected: a_SeedIdxOut[a_NumSeedsOut++] = a_DstIdx; } } - + /** Queues a chunkstay that has all of its chunks loaded. Called by cLightingChunkStay when all of its chunks are loaded. */ void QueueChunkStay(cLightingChunkStay & a_ChunkStay); - + } ; diff --git a/src/LineBlockTracer.cpp b/src/LineBlockTracer.cpp index 587fa0e7c..c2e078faf 100644 --- a/src/LineBlockTracer.cpp +++ b/src/LineBlockTracer.cpp @@ -72,7 +72,7 @@ bool cLineBlockTracer::Trace(double a_StartX, double a_StartY, double a_StartZ, m_DirY = (m_StartY < m_EndY) ? 1 : -1; m_DirZ = (m_StartZ < m_EndZ) ? 1 : -1; m_CurrentFace = BLOCK_FACE_NONE; - + // Check the start coords, adjust into the world: if (m_StartY < 0) { @@ -99,11 +99,11 @@ bool cLineBlockTracer::Trace(double a_StartX, double a_StartY, double a_StartZ, m_CurrentX = FloorC(m_StartX); m_CurrentY = FloorC(m_StartY); m_CurrentZ = FloorC(m_StartZ); - + m_DiffX = m_EndX - m_StartX; m_DiffY = m_EndY - m_StartY; m_DiffZ = m_EndZ - m_StartZ; - + // The actual trace is handled with ChunkMapCS locked by calling our Item() for the specified chunk int BlockX = FloorC(m_StartX); int BlockZ = FloorC(m_StartZ); @@ -197,7 +197,7 @@ bool cLineBlockTracer::MoveToNextBlock(void) Direction = dirZ; } } - + // Based on the wall hit, adjust the current coords switch (Direction) { @@ -216,7 +216,7 @@ bool cLineBlockTracer::MoveToNextBlock(void) bool cLineBlockTracer::Item(cChunk * a_Chunk) { ASSERT((m_CurrentY >= 0) && (m_CurrentY < cChunkDef::Height)); // This should be provided by FixStartAboveWorld() / FixStartBelowWorld() - + // This is the actual line tracing loop. for (;;) { diff --git a/src/LineBlockTracer.h b/src/LineBlockTracer.h index 155b3ab2a..37493ce5c 100644 --- a/src/LineBlockTracer.h +++ b/src/LineBlockTracer.h @@ -31,10 +31,10 @@ class cLineBlockTracer : public cChunkCallback { typedef cBlockTracer super; - + public: cLineBlockTracer(cWorld & a_World, cCallbacks & a_Callbacks); - + /** Traces one line between Start and End; returns true if the entire line was traced (until OnNoMoreHits()) */ bool Trace(double a_StartX, double a_StartY, double a_StartZ, double a_EndX, double a_EndY, double a_EndZ); @@ -45,39 +45,39 @@ public: /** Traces one line between Start and End; returns true if the entire line was traced (until OnNoMoreHits()) */ static bool Trace(cWorld & a_World, cCallbacks & a_Callbacks, const Vector3d & a_Start, const Vector3d & a_End); - + protected: /** The start point of the trace */ double m_StartX, m_StartY, m_StartZ; - + /** The end point of the trace */ double m_EndX, m_EndY, m_EndZ; - + /** The difference in coords, End - Start */ double m_DiffX, m_DiffY, m_DiffZ; - + /** The increment at which the block coords are going from Start to End; either +1 or -1 */ int m_DirX, m_DirY, m_DirZ; - + /** The current block */ int m_CurrentX, m_CurrentY, m_CurrentZ; - + /** The face through which the current block has been entered */ char m_CurrentFace; - + /** Adjusts the start point above the world to just at the world's top */ void FixStartAboveWorld(void); - + /** Adjusts the start point below the world to just at the world's bottom */ void FixStartBelowWorld(void); - + /** Calculates the XZ coords of an intersection with the specified Yconst plane; assumes that such an intersection exists */ void CalcXZIntersection(double a_Y, double & a_IntersectX, double & a_IntersectZ); - + /** Moves m_Current to the next block on the line; returns false if no move is possible (reached the end) */ bool MoveToNextBlock(void); - + // cChunkCallback overrides: virtual bool Item(cChunk * a_Chunk) override; } ; diff --git a/src/LinearInterpolation.cpp b/src/LinearInterpolation.cpp index 38404147f..f0465385d 100644 --- a/src/LinearInterpolation.cpp +++ b/src/LinearInterpolation.cpp @@ -23,8 +23,8 @@ public: // DoTest1(); DoTest2(); } - - + + void DoTest1(void) { float In[8] = {0, 1, 2, 3, 1, 2, 2, 2}; @@ -34,8 +34,8 @@ public: LinearInterpolate3DArray(In, 2, 2, 2, Out, 3, 3, 3); LOGD("Out[0]: %f", Out[0]); } - - + + void DoTest2(void) { float In[3 * 3 * 3]; @@ -94,7 +94,7 @@ void LinearInterpolate2DArray( ASSERT(a_DstSizeX < MAX_INTERPOL_SIZEX); ASSERT(a_DstSizeY > 0); ASSERT(a_DstSizeY < MAX_INTERPOL_SIZEY); - + // Calculate interpolation ratios and src indices along each axis: float RatioX[MAX_INTERPOL_SIZEX]; float RatioY[MAX_INTERPOL_SIZEY]; @@ -110,7 +110,7 @@ void LinearInterpolate2DArray( SrcIdxY[y] = y * (a_SrcSizeY - 1) / (a_DstSizeY - 1); RatioY[y] = (static_cast(y * (a_SrcSizeY - 1)) / (a_DstSizeY - 1)) - SrcIdxY[y]; } - + // Special values at the ends. Notice especially the last indices being (size - 2) with ratio set to 1, to avoid index overflow: SrcIdxX[0] = 0; RatioX[0] = 0; @@ -120,7 +120,7 @@ void LinearInterpolate2DArray( RatioX[a_DstSizeX - 1] = 1; SrcIdxY[a_DstSizeY - 1] = a_SrcSizeY - 2; RatioY[a_DstSizeY - 1] = 1; - + // Output all the dst array values using the indices and ratios: int idx = 0; for (int y = 0; y < a_DstSizeY; y++) @@ -135,11 +135,11 @@ void LinearInterpolate2DArray( float HiXLoY = a_Src[SrcIdxX[x] + 1 + idxLoY]; float LoXHiY = a_Src[SrcIdxX[x] + idxHiY]; float HiXHiY = a_Src[SrcIdxX[x] + 1 + idxHiY]; - + // Linear interpolation along the X axis: float InterpXLoY = LoXLoY + (HiXLoY - LoXLoY) * RatioX[x]; float InterpXHiY = LoXHiY + (HiXHiY - LoXHiY) * RatioX[x]; - + // Linear interpolation along the Y axis: a_Dst[idx] = InterpXLoY + (InterpXHiY - InterpXLoY) * ry; idx += 1; @@ -235,7 +235,7 @@ void LinearInterpolate3DArray( // Linear interpolation along the Y axis: float LoXInYInZ = LoXLoYInZ + (LoXHiYInZ - LoXLoYInZ) * ry; float HiXInYInZ = HiXLoYInZ + (HiXHiYInZ - HiXLoYInZ) * ry; - + // Linear interpolation along the X axis: a_Dst[idx] = LoXInYInZ + (HiXInYInZ - LoXInYInZ) * RatioX[x]; idx += 1; diff --git a/src/Logger.h b/src/Logger.h index a0c2917a9..649c11ded 100644 --- a/src/Logger.h +++ b/src/Logger.h @@ -52,7 +52,7 @@ public: void LogSimple(AString a_Message, eLogLevel a_LogLevel = llRegular); cAttachment AttachListener(std::unique_ptr a_Listener); - + static cLogger & GetInstance(void); // Must be called before calling GetInstance in a multithreaded context static void InitiateMultithreading(); diff --git a/src/LoggerListeners.cpp b/src/LoggerListeners.cpp index ed10e648c..1d6d9c6ce 100644 --- a/src/LoggerListeners.cpp +++ b/src/LoggerListeners.cpp @@ -20,10 +20,10 @@ : public cLogger::cListener { protected: - + virtual void SetLogColour(cLogger::eLogLevel a_LogLevel) = 0; virtual void SetDefaultLogColour() = 0; - + virtual void Log(AString a_Message, cLogger::eLogLevel a_LogLevel) override { SetLogColour(a_LogLevel); @@ -48,7 +48,7 @@ m_DefaultConsoleAttrib(a_DefaultConsoleAttrib) { } - + #ifdef _DEBUG virtual void Log(AString a_Message, cLogger::eLogLevel a_LogLevel) override { @@ -92,21 +92,21 @@ } SetConsoleTextAttribute(m_Console, Attrib); } - - + + virtual void SetDefaultLogColour() override { SetConsoleTextAttribute(m_Console, m_DefaultConsoleAttrib); } - + private: - + HANDLE m_Console; WORD m_DefaultConsoleAttrib; }; - - - + + + #elif defined (__linux) && !defined(ANDROID_NDK) @@ -145,17 +145,17 @@ } } } - - + + virtual void SetDefaultLogColour() override { // Whatever the console default is printf("\x1b[0m"); } }; - - - + + + #elif defined(ANDROID_NDK) @@ -193,7 +193,7 @@ __android_log_print(AndroidLogLevel, "Cuberite", "%s", a_Message.c_str()); } }; - + #endif @@ -273,7 +273,7 @@ std::unique_ptr MakeConsoleListener(bool a_IsService) { return cpp14::make_unique(); } - + #elif defined (__linux) && !defined(ANDROID_NDK) // TODO: lookup terminal in terminfo if (isatty(fileno(stdout))) @@ -354,7 +354,7 @@ public: m_File.Flush(); } } - + private: cFile m_File; diff --git a/src/Map.cpp b/src/Map.cpp index a79a6bd0c..1ba27038e 100644 --- a/src/Map.cpp +++ b/src/Map.cpp @@ -291,7 +291,7 @@ const cMapDecorator cMap::CreateDecorator(const cEntity * a_TrackedEntity) { int InsideWidth = (GetWidth() / 2) - 1; int InsideHeight = (GetHeight() / 2) - 1; - + // Center of pixel int PixelX = static_cast(a_TrackedEntity->GetPosX() - GetCenterX()) / static_cast(GetPixelWidth()); int PixelZ = static_cast(a_TrackedEntity->GetPosZ() - GetCenterZ()) / static_cast(GetPixelWidth()); diff --git a/src/Matrix4.h b/src/Matrix4.h index a5d6017d0..03ea6a93b 100644 --- a/src/Matrix4.h +++ b/src/Matrix4.h @@ -34,7 +34,7 @@ public: { *this = a_Rhs; } - + // tolua_end inline Matrix4 & operator = (const Matrix4 & a_Rhs) @@ -45,7 +45,7 @@ public: } return *this; } - + // tolua_begin inline T & operator [] (int a_N) diff --git a/src/MemoryLeak.h b/src/MemoryLeak.h index e9c0c34e3..441429c23 100644 --- a/src/MemoryLeak.h +++ b/src/MemoryLeak.h @@ -6,7 +6,7 @@ #define _CRTDBG_MAP_ALLOC #include #include - + // This works only in MSVC 2010+: #if _MSC_VER >= 1600 // Map the new operator diff --git a/src/MemorySettingsRepository.h b/src/MemorySettingsRepository.h index 335bc4513..aee4bafd4 100644 --- a/src/MemorySettingsRepository.h +++ b/src/MemorySettingsRepository.h @@ -16,7 +16,7 @@ public: virtual int AddKeyName(const AString & keyname) override; virtual bool AddKeyComment(const AString & keyname, const AString & comment) override; - + virtual AString GetKeyComment(const AString & keyname, const int commentID) const override; virtual bool DeleteKeyComment(const AString & keyname, const int commentID) override; diff --git a/src/MobCensus.h b/src/MobCensus.h index 259f987ce..1d1123cfa 100644 --- a/src/MobCensus.h +++ b/src/MobCensus.h @@ -31,16 +31,16 @@ public: // collect an elligible Chunk for Mob Spawning // MG TODO : code the correct rule (not loaded chunk but short distant from players) void CollectSpawnableChunk(cChunk & a_Chunk); - + /** Collect a mob - its distance to player, its family ... */ void CollectMob(cMonster & a_Monster, cChunk & a_Chunk, double a_Distance); /** Returns true if the family is capped (i.e. there are more mobs of this family than max) */ bool IsCapped(cMonster::eFamily a_MobFamily); - + /** log the results of census to server console */ void Logd(void); - + protected : cMobProximityCounter m_ProximityCounter; cMobFamilyCollecter m_MobFamilyCollecter; diff --git a/src/Mobs/Bat.h b/src/Mobs/Bat.h index 6b06aeb4f..2da2dc3f2 100644 --- a/src/Mobs/Bat.h +++ b/src/Mobs/Bat.h @@ -11,12 +11,12 @@ class cBat : public cPassiveMonster { typedef cPassiveMonster super; - + public: cBat(void); CLASS_PROTODEF(cBat) - + bool IsHanging(void) const {return false; } } ; diff --git a/src/Mobs/Blaze.h b/src/Mobs/Blaze.h index 8265deffa..ca755b626 100644 --- a/src/Mobs/Blaze.h +++ b/src/Mobs/Blaze.h @@ -11,12 +11,12 @@ class cBlaze : public cAggressiveMonster { typedef cAggressiveMonster super; - + public: cBlaze(void); CLASS_PROTODEF(cBlaze) - + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; virtual bool Attack(std::chrono::milliseconds a_Dt) override; } ; diff --git a/src/Mobs/CaveSpider.h b/src/Mobs/CaveSpider.h index 7fbafeb54..cf4b8e17c 100644 --- a/src/Mobs/CaveSpider.h +++ b/src/Mobs/CaveSpider.h @@ -10,7 +10,7 @@ class cCaveSpider : public cAggressiveMonster { typedef cAggressiveMonster super; - + public: cCaveSpider(void); diff --git a/src/Mobs/Chicken.h b/src/Mobs/Chicken.h index ca70657b4..3be338b15 100644 --- a/src/Mobs/Chicken.h +++ b/src/Mobs/Chicken.h @@ -10,7 +10,7 @@ class cChicken : public cPassiveMonster { typedef cPassiveMonster super; - + public: cChicken(void); diff --git a/src/Mobs/Cow.h b/src/Mobs/Cow.h index 6ce51e806..569c6e619 100644 --- a/src/Mobs/Cow.h +++ b/src/Mobs/Cow.h @@ -11,7 +11,7 @@ class cCow : public cPassiveMonster { typedef cPassiveMonster super; - + public: cCow(); diff --git a/src/Mobs/Creeper.h b/src/Mobs/Creeper.h index ac8b7cf35..73243d11e 100644 --- a/src/Mobs/Creeper.h +++ b/src/Mobs/Creeper.h @@ -11,7 +11,7 @@ class cCreeper : public cAggressiveMonster { typedef cAggressiveMonster super; - + public: cCreeper(void); diff --git a/src/Mobs/EnderDragon.h b/src/Mobs/EnderDragon.h index e4ca9dcf9..43acdcd54 100644 --- a/src/Mobs/EnderDragon.h +++ b/src/Mobs/EnderDragon.h @@ -11,12 +11,12 @@ class cEnderDragon : public cAggressiveMonster { typedef cAggressiveMonster super; - + public: cEnderDragon(void); CLASS_PROTODEF(cEnderDragon) - + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; } ; diff --git a/src/Mobs/Ghast.h b/src/Mobs/Ghast.h index f74150169..a41a72ddc 100644 --- a/src/Mobs/Ghast.h +++ b/src/Mobs/Ghast.h @@ -11,7 +11,7 @@ class cGhast : public cAggressiveMonster { typedef cAggressiveMonster super; - + public: cGhast(void); diff --git a/src/Mobs/Giant.h b/src/Mobs/Giant.h index 8d3060940..70e93894c 100644 --- a/src/Mobs/Giant.h +++ b/src/Mobs/Giant.h @@ -11,12 +11,12 @@ class cGiant : public cAggressiveMonster { typedef cAggressiveMonster super; - + public: cGiant(void); CLASS_PROTODEF(cGiant) - + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; } ; diff --git a/src/Mobs/Guardian.h b/src/Mobs/Guardian.h index 6bc17947c..289654f57 100644 --- a/src/Mobs/Guardian.h +++ b/src/Mobs/Guardian.h @@ -11,14 +11,14 @@ class cGuardian : public cAggressiveMonster { typedef cAggressiveMonster super; - + public: cGuardian(); virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; CLASS_PROTODEF(cGuardian) - + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; // Guardians do not drown (or float) diff --git a/src/Mobs/IronGolem.h b/src/Mobs/IronGolem.h index 721ca2701..7d35686e7 100644 --- a/src/Mobs/IronGolem.h +++ b/src/Mobs/IronGolem.h @@ -11,12 +11,12 @@ class cIronGolem : public cPassiveAggressiveMonster { typedef cPassiveAggressiveMonster super; - + public: cIronGolem(void); CLASS_PROTODEF(cIronGolem) - + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; // Iron golems do not drown nor float diff --git a/src/Mobs/MagmaCube.h b/src/Mobs/MagmaCube.h index 3cd77f3e3..5fc8105ba 100644 --- a/src/Mobs/MagmaCube.h +++ b/src/Mobs/MagmaCube.h @@ -10,7 +10,7 @@ class cMagmaCube : public cAggressiveMonster { typedef cAggressiveMonster super; - + public: /** Creates a MagmaCube of the specified size; with 1 being the smallest */ cMagmaCube(int a_Size); @@ -23,7 +23,7 @@ public: /** Returns the text describing the slime's size, as used by the client's resource subsystem for sounds. Returns either "big" or "small". */ static AString GetSizeName(int a_Size); - + protected: /** Size of the MagmaCube, with 1 being the smallest */ diff --git a/src/Mobs/MonsterTypes.h b/src/Mobs/MonsterTypes.h index d48005d2e..96b4d0df0 100644 --- a/src/Mobs/MonsterTypes.h +++ b/src/Mobs/MonsterTypes.h @@ -10,7 +10,7 @@ enum eMonsterType { mtInvalidType = -1, - + mtBat = E_META_SPAWN_EGG_BAT, mtBlaze = E_META_SPAWN_EGG_BLAZE, mtCaveSpider = E_META_SPAWN_EGG_CAVE_SPIDER, diff --git a/src/Mobs/Mooshroom.h b/src/Mobs/Mooshroom.h index 61cbfc083..625963190 100644 --- a/src/Mobs/Mooshroom.h +++ b/src/Mobs/Mooshroom.h @@ -11,7 +11,7 @@ class cMooshroom : public cPassiveMonster { typedef cPassiveMonster super; - + public: cMooshroom(void); diff --git a/src/Mobs/Ocelot.h b/src/Mobs/Ocelot.h index 796af2050..1f513a6d6 100644 --- a/src/Mobs/Ocelot.h +++ b/src/Mobs/Ocelot.h @@ -11,7 +11,7 @@ class cOcelot : public cPassiveMonster { typedef cPassiveMonster super; - + public: cOcelot(void) : super("Ocelot", mtOcelot, "mob.cat.hitt", "mob.cat.hitt", 0.6, 0.8) diff --git a/src/Mobs/Pig.h b/src/Mobs/Pig.h index 56c9f7ed6..ed0685e5f 100644 --- a/src/Mobs/Pig.h +++ b/src/Mobs/Pig.h @@ -11,7 +11,7 @@ class cPig : public cPassiveMonster { typedef cPassiveMonster super; - + public: cPig(void); @@ -19,7 +19,7 @@ public: // cEntity overrides virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override; - + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; virtual void OnRightClicked(cPlayer & a_Player) override; virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; diff --git a/src/Mobs/Rabbit.h b/src/Mobs/Rabbit.h index 79a9afe15..aafd979d1 100644 --- a/src/Mobs/Rabbit.h +++ b/src/Mobs/Rabbit.h @@ -26,7 +26,7 @@ class cRabbit : public cPassiveMonster { typedef cPassiveMonster super; - + public: cRabbit(); cRabbit(eRabbitType Type, int MoreCarrotTicks = 0); diff --git a/src/Mobs/Sheep.h b/src/Mobs/Sheep.h index 97f481bec..02aa888f1 100644 --- a/src/Mobs/Sheep.h +++ b/src/Mobs/Sheep.h @@ -11,7 +11,7 @@ class cSheep : public cPassiveMonster { typedef cPassiveMonster super; - + public: /** The number is the color of the sheep. diff --git a/src/Mobs/Silverfish.h b/src/Mobs/Silverfish.h index 2df333dbc..be325a7aa 100644 --- a/src/Mobs/Silverfish.h +++ b/src/Mobs/Silverfish.h @@ -11,7 +11,7 @@ class cSilverfish : public cAggressiveMonster { typedef cAggressiveMonster super; - + public: cSilverfish(void) : super("Silverfish", mtSilverfish, "mob.silverfish.hit", "mob.silverfish.kill", 0.3, 0.7) diff --git a/src/Mobs/Slime.cpp b/src/Mobs/Slime.cpp index d7ea50dda..316f68523 100644 --- a/src/Mobs/Slime.cpp +++ b/src/Mobs/Slime.cpp @@ -53,7 +53,7 @@ bool cSlime::Attack(std::chrono::milliseconds a_Dt) // Only slimes larger than size 1 attack a player. return super::Attack(a_Dt); } - + return false; } diff --git a/src/Mobs/Slime.h b/src/Mobs/Slime.h index c03a82bf4..c78461a02 100644 --- a/src/Mobs/Slime.h +++ b/src/Mobs/Slime.h @@ -11,7 +11,7 @@ class cSlime : public cAggressiveMonster { typedef cAggressiveMonster super; - + public: /** Creates a slime of the specified size; size can be 1, 2 or 4, with 1 is the smallest and 4 is the tallest. */ cSlime(int a_Size); @@ -24,11 +24,11 @@ public: virtual void KilledBy(TakeDamageInfo & a_TDI) override; int GetSize(void) const { return m_Size; } - + /** Returns the text describing the slime's size, as used by the client's resource subsystem for sounds. Returns either "big" or "small". */ static AString GetSizeName(int a_Size); - + protected: /** Size of the slime, with 1 being the smallest. diff --git a/src/Mobs/Squid.h b/src/Mobs/Squid.h index 7e944a17e..590c50495 100644 --- a/src/Mobs/Squid.h +++ b/src/Mobs/Squid.h @@ -11,14 +11,14 @@ class cSquid : public cPassiveMonster { typedef cPassiveMonster super; - + public: cSquid(); virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; CLASS_PROTODEF(cSquid) - + virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; // Squids do not drown (or float) diff --git a/src/Mobs/Villager.h b/src/Mobs/Villager.h index dc356b4a6..6f3e7b4e8 100644 --- a/src/Mobs/Villager.h +++ b/src/Mobs/Villager.h @@ -11,7 +11,7 @@ class cVillager : public cPassiveMonster { typedef cPassiveMonster super; - + public: enum eVillagerType diff --git a/src/Mobs/Witch.h b/src/Mobs/Witch.h index 8230e1f98..706fcd9b3 100644 --- a/src/Mobs/Witch.h +++ b/src/Mobs/Witch.h @@ -11,7 +11,7 @@ class cWitch : public cAggressiveMonster { typedef cAggressiveMonster super; - + public: cWitch(); diff --git a/src/Mobs/Wither.h b/src/Mobs/Wither.h index 9e333c7fa..b430588c9 100644 --- a/src/Mobs/Wither.h +++ b/src/Mobs/Wither.h @@ -11,7 +11,7 @@ class cWither : public cAggressiveMonster { typedef cAggressiveMonster super; - + public: cWither(void); @@ -23,14 +23,14 @@ public: /** Returns whether the wither is invulnerable to arrows. */ bool IsArmored(void) const; - + // cEntity overrides virtual bool Initialize(cWorld & a_World) override; virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override; virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; virtual void KilledBy(TakeDamageInfo & a_TDI) override; - + virtual bool IsUndead(void) override { return true; } private: diff --git a/src/Mobs/ZombiePigman.cpp b/src/Mobs/ZombiePigman.cpp index 96d587287..73ad81b36 100644 --- a/src/Mobs/ZombiePigman.cpp +++ b/src/Mobs/ZombiePigman.cpp @@ -25,7 +25,7 @@ void cZombiePigman::GetDrops(cItems & a_Drops, cEntity * a_Killer) } AddRandomDropItem(a_Drops, 0, 1 + LootingLevel, E_ITEM_ROTTEN_FLESH); AddRandomDropItem(a_Drops, 0, 1 + LootingLevel, E_ITEM_GOLD_NUGGET); - + cItems RareDrops; RareDrops.Add(cItem(E_ITEM_GOLD)); AddRandomRareDropItem(a_Drops, RareDrops, LootingLevel); diff --git a/src/Mobs/ZombiePigman.h b/src/Mobs/ZombiePigman.h index d8b886ca4..c8f6753a4 100644 --- a/src/Mobs/ZombiePigman.h +++ b/src/Mobs/ZombiePigman.h @@ -10,7 +10,7 @@ class cZombiePigman : public cPassiveAggressiveMonster { typedef cPassiveAggressiveMonster super; - + public: cZombiePigman(void); @@ -18,7 +18,7 @@ public: virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; virtual void KilledBy(TakeDamageInfo & a_TDI) override; - + virtual bool IsUndead(void) override { return true; } } ; diff --git a/src/MonsterConfig.cpp b/src/MonsterConfig.cpp index 278e67b93..28132607e 100644 --- a/src/MonsterConfig.cpp +++ b/src/MonsterConfig.cpp @@ -57,13 +57,13 @@ cMonsterConfig::~cMonsterConfig() void cMonsterConfig::Initialize() { cIniFile MonstersIniFile; - + if (!MonstersIniFile.ReadFile("monsters.ini")) { LOGWARNING("%s: Cannot read monsters.ini file, monster attributes not available", __FUNCTION__); return; } - + for (int i = static_cast(MonstersIniFile.GetNumKeys()); i >= 0; i--) { sAttributesStruct Attributes; diff --git a/src/MonsterConfig.h b/src/MonsterConfig.h index 50979c44a..55a01549b 100644 --- a/src/MonsterConfig.h +++ b/src/MonsterConfig.h @@ -17,9 +17,9 @@ class cMonsterConfig public: cMonsterConfig(void); ~cMonsterConfig(); - + void AssignAttributes(cMonster * a_Monster, const AString & a_Name); - + private: struct sAttributesStruct; struct sMonsterConfigState; diff --git a/src/Noise/InterpolNoise.h b/src/Noise/InterpolNoise.h index afc7cff49..447796739 100644 --- a/src/Noise/InterpolNoise.h +++ b/src/Noise/InterpolNoise.h @@ -42,7 +42,7 @@ public: m_FracY(a_FracY) { } - + /** Generates part of the output noise array using the current m_WorkRnds[] values */ void Generate( @@ -63,7 +63,7 @@ public: } // for x } // for y } - + /** Initializes m_WorkRnds[] with the specified values of the noise at the specified integral coords. */ void InitWorkRnds(int a_FloorX, int a_FloorY) @@ -75,7 +75,7 @@ public: (*m_WorkRnds)[1][0] = m_Noise.IntNoise2D(m_CurFloorX + 1, m_CurFloorY); (*m_WorkRnds)[1][1] = m_Noise.IntNoise2D(m_CurFloorX + 1, m_CurFloorY + 1); } - + /** Updates m_WorkRnds[] for the new integral coords */ void Move(int a_NewFloorX, int a_NewFloorY) @@ -85,7 +85,7 @@ public: int OldFloorY = m_CurFloorY; Workspace * OldWorkRnds = m_WorkRnds; m_WorkRnds = (m_WorkRnds == &m_Workspace1) ? &m_Workspace2 : &m_Workspace1; - + // Reuse as much of the old workspace as possible: // TODO: Try out if simply calculating all 4 elements each time is faster than this monster loop int DiffX = OldFloorX - a_NewFloorX; @@ -114,10 +114,10 @@ public: protected: typedef NOISE_DATATYPE Workspace[2][2]; - + /** The noise used for generating the values at integral coords. */ const cNoise & m_Noise; - + /** The current random values; points to either m_Workspace1 or m_Workspace2 (doublebuffering) */ Workspace * m_WorkRnds; @@ -129,7 +129,7 @@ protected: /** Coords of the currently calculated m_WorkRnds[]. */ int m_CurFloorX, m_CurFloorY; - + /** The output array to generate into. */ NOISE_DATATYPE * m_Array; @@ -346,7 +346,7 @@ public: ASSERT(a_SizeY < MAX_SIZE); ASSERT(a_StartX < a_EndX); ASSERT(a_StartY < a_EndY); - + // Calculate the integral and fractional parts of each coord: int FloorX[MAX_SIZE]; int FloorY[MAX_SIZE]; @@ -357,11 +357,11 @@ public: int NumSameX, NumSameY; CalcFloorFrac(a_SizeX, a_StartX, a_EndX, FloorX, FracX, SameX, NumSameX); CalcFloorFrac(a_SizeY, a_StartY, a_EndY, FloorY, FracY, SameY, NumSameY); - + cInterpolCell2D Cell(m_Noise, a_Array, a_SizeX, a_SizeY, FracX, FracY); - + Cell.InitWorkRnds(FloorX[0], FloorY[0]); - + // Calculate query values using Cell: int FromY = 0; for (int y = 0; y < NumSameY; y++) @@ -422,9 +422,9 @@ public: a_SizeX, a_SizeY, a_SizeZ, FracX, FracY, FracZ ); - + Cell.InitWorkRnds(FloorX[0], FloorY[0], FloorZ[0]); - + // Calculate query values using Cell: int FromZ = 0; for (int z = 0; z < NumSameZ; z++) diff --git a/src/Noise/Noise.cpp b/src/Noise/Noise.cpp index aa9f0412f..cc63a34a9 100644 --- a/src/Noise/Noise.cpp +++ b/src/Noise/Noise.cpp @@ -116,7 +116,7 @@ void Debug3DNoise(const NOISE_DATATYPE * a_Noise, size_t a_SizeX, size_t a_SizeY { const int BUF_SIZE = 512; ASSERT(a_SizeX <= BUF_SIZE); // Just stretch it, if needed - + // Save in XY cuts: cFile f1; if (f1.Open(Printf("%s_XY (" SIZE_T_FMT ").grab", a_FileNameBase.c_str(), a_SizeX), cFile::fmWrite)) @@ -169,7 +169,7 @@ void Debug2DNoise(const NOISE_DATATYPE * a_Noise, size_t a_SizeX, size_t a_SizeY { const int BUF_SIZE = 512; ASSERT(a_SizeX <= BUF_SIZE); // Just stretch it, if needed - + cFile f1; if (f1.Open(Printf("%s (" SIZE_T_FMT ").grab", a_FileNameBase.c_str(), a_SizeX), cFile::fmWrite)) { @@ -203,30 +203,30 @@ public: const NOISE_DATATYPE * a_FracX, ///< Pointer to the array that stores the X fractional values const NOISE_DATATYPE * a_FracY ///< Pointer to the attay that stores the Y fractional values ); - + /** Uses current m_WorkRnds[] to generate part of the array */ void Generate( int a_FromX, int a_ToX, int a_FromY, int a_ToY ); - + /** Initializes m_WorkRnds[] with the specified Floor values */ void InitWorkRnds(int a_FloorX, int a_FloorY); - + /** Updates m_WorkRnds[] for the new Floor values. */ void Move(int a_NewFloorX, int a_NewFloorY); protected: typedef NOISE_DATATYPE Workspace[4][4]; - + const cNoise & m_Noise; - + Workspace * m_WorkRnds; ///< The current random values; points to either m_Workspace1 or m_Workspace2 (doublebuffering) Workspace m_Workspace1; ///< Buffer 1 for workspace doublebuffering, used in Move() Workspace m_Workspace2; ///< Buffer 2 for workspace doublebuffering, used in Move() int m_CurFloorX; int m_CurFloorY; - + NOISE_DATATYPE * m_Array; int m_SizeX, m_SizeY; const NOISE_DATATYPE * m_FracX; @@ -311,7 +311,7 @@ void cCubicCell2D::Move(int a_NewFloorX, int a_NewFloorY) int OldFloorY = m_CurFloorY; Workspace * OldWorkRnds = m_WorkRnds; m_WorkRnds = (m_WorkRnds == &m_Workspace1) ? &m_Workspace2 : &m_Workspace1; - + // Reuse as much of the old workspace as possible: int DiffX = OldFloorX - a_NewFloorX; int DiffY = OldFloorY - a_NewFloorY; @@ -355,32 +355,32 @@ public: const NOISE_DATATYPE * a_FracY, ///< Pointer to the attay that stores the Y fractional values const NOISE_DATATYPE * a_FracZ ///< Pointer to the array that stores the Z fractional values ); - + /** Uses current m_WorkRnds[] to generate part of the array */ void Generate( int a_FromX, int a_ToX, int a_FromY, int a_ToY, int a_FromZ, int a_ToZ ); - + /** Initializes m_WorkRnds[] with the specified Floor values */ void InitWorkRnds(int a_FloorX, int a_FloorY, int a_FloorZ); - + /** Updates m_WorkRnds[] for the new Floor values. */ void Move(int a_NewFloorX, int a_NewFloorY, int a_NewFloorZ); protected: typedef NOISE_DATATYPE Workspace[4][4][4]; - + const cNoise & m_Noise; - + Workspace * m_WorkRnds; ///< The current random values; points to either m_Workspace1 or m_Workspace2 (doublebuffering) Workspace m_Workspace1; ///< Buffer 1 for workspace doublebuffering, used in Move() Workspace m_Workspace2; ///< Buffer 2 for workspace doublebuffering, used in Move() int m_CurFloorX; int m_CurFloorY; int m_CurFloorZ; - + NOISE_DATATYPE * m_Array; int m_SizeX, m_SizeY, m_SizeZ; const NOISE_DATATYPE * m_FracX; @@ -490,7 +490,7 @@ void cCubicCell3D::Move(int a_NewFloorX, int a_NewFloorY, int a_NewFloorZ) int OldFloorZ = m_CurFloorZ; Workspace * OldWorkRnds = m_WorkRnds; m_WorkRnds = (m_WorkRnds == &m_Workspace1) ? &m_Workspace2 : &m_Workspace1; - + // Reuse as much of the old workspace as possible: int DiffX = OldFloorX - a_NewFloorX; int DiffY = OldFloorY - a_NewFloorY; @@ -594,7 +594,7 @@ NOISE_DATATYPE cNoise::CubicNoise2D(NOISE_DATATYPE a_X, NOISE_DATATYPE a_Y) cons { const int BaseX = FAST_FLOOR(a_X); const int BaseY = FAST_FLOOR(a_Y); - + const NOISE_DATATYPE points[4][4] = { { IntNoise2D(BaseX - 1, BaseY - 1), IntNoise2D(BaseX, BaseY - 1), IntNoise2D(BaseX + 1, BaseY - 1), IntNoise2D(BaseX + 2, BaseY - 1), }, @@ -623,7 +623,7 @@ NOISE_DATATYPE cNoise::CubicNoise3D(NOISE_DATATYPE a_X, NOISE_DATATYPE a_Y, NOIS const int BaseX = FAST_FLOOR(a_X); const int BaseY = FAST_FLOOR(a_Y); const int BaseZ = FAST_FLOOR(a_Z); - + const NOISE_DATATYPE points1[4][4] = { { IntNoise3D(BaseX - 1, BaseY - 1, BaseZ - 1), IntNoise3D(BaseX, BaseY - 1, BaseZ - 1), IntNoise3D(BaseX + 1, BaseY - 1, BaseZ - 1), IntNoise3D(BaseX + 2, BaseY - 1, BaseZ - 1), }, @@ -716,7 +716,7 @@ void cCubicNoise::Generate2D( ASSERT(a_SizeY < MAX_SIZE); ASSERT(a_StartX < a_EndX); ASSERT(a_StartY < a_EndY); - + // Calculate the integral and fractional parts of each coord: int FloorX[MAX_SIZE]; int FloorY[MAX_SIZE]; @@ -727,11 +727,11 @@ void cCubicNoise::Generate2D( int NumSameX, NumSameY; CalcFloorFrac(a_SizeX, a_StartX, a_EndX, FloorX, FracX, SameX, NumSameX); CalcFloorFrac(a_SizeY, a_StartY, a_EndY, FloorY, FracY, SameY, NumSameY); - + cCubicCell2D Cell(m_Noise, a_Array, a_SizeX, a_SizeY, FracX, FracY); - + Cell.InitWorkRnds(FloorX[0], FloorY[0]); - + // Calculate query values using Cell: int FromY = 0; for (int y = 0; y < NumSameY; y++) @@ -769,7 +769,7 @@ void cCubicNoise::Generate3D( ASSERT(a_StartX < a_EndX); ASSERT(a_StartY < a_EndY); ASSERT(a_StartZ < a_EndZ); - + // Calculate the integral and fractional parts of each coord: int FloorX[MAX_SIZE]; int FloorY[MAX_SIZE]; @@ -784,15 +784,15 @@ void cCubicNoise::Generate3D( CalcFloorFrac(a_SizeX, a_StartX, a_EndX, FloorX, FracX, SameX, NumSameX); CalcFloorFrac(a_SizeY, a_StartY, a_EndY, FloorY, FracY, SameY, NumSameY); CalcFloorFrac(a_SizeZ, a_StartZ, a_EndZ, FloorZ, FracZ, SameZ, NumSameZ); - + cCubicCell3D Cell( m_Noise, a_Array, a_SizeX, a_SizeY, a_SizeZ, FracX, FracY, FracZ ); - + Cell.InitWorkRnds(FloorX[0], FloorY[0], FloorZ[0]); - + // Calculate query values using Cell: int FromZ = 0; for (int z = 0; z < NumSameZ; z++) @@ -841,7 +841,7 @@ void cCubicNoise::CalcFloorFrac( a_Frac[i] = val - a_Floor[i]; val += dif; } - + // Mark up the same floor values into a_Same / a_NumSame: int CurFloor = a_Floor[0]; int LastSame = 0; diff --git a/src/Noise/OctavedNoise.h b/src/Noise/OctavedNoise.h index efb9a0167..6dd79365f 100644 --- a/src/Noise/OctavedNoise.h +++ b/src/Noise/OctavedNoise.h @@ -167,7 +167,7 @@ protected: { public: N m_Noise; - + /** Coord multiplier. */ NOISE_DATATYPE m_Frequency; diff --git a/src/OSSupport/CriticalSection.cpp b/src/OSSupport/CriticalSection.cpp index 5248356c5..2e533676d 100644 --- a/src/OSSupport/CriticalSection.cpp +++ b/src/OSSupport/CriticalSection.cpp @@ -23,7 +23,7 @@ cCriticalSection::cCriticalSection() void cCriticalSection::Lock() { m_Mutex.lock(); - + #ifdef _DEBUG m_IsLocked += 1; m_OwningThreadID = std::this_thread::get_id(); @@ -40,7 +40,7 @@ void cCriticalSection::Unlock() ASSERT(m_IsLocked > 0); m_IsLocked -= 1; #endif // _DEBUG - + m_Mutex.unlock(); } diff --git a/src/OSSupport/CriticalSection.h b/src/OSSupport/CriticalSection.h index 236a7d203..6ea18051a 100644 --- a/src/OSSupport/CriticalSection.h +++ b/src/OSSupport/CriticalSection.h @@ -12,7 +12,7 @@ class cCriticalSection public: void Lock(void); void Unlock(void); - + // IsLocked / IsLockedByCurrentThread are only used in ASSERT statements, but because of the changes with ASSERT they must always be defined // The fake versions (in Release) will not effect the program in any way #ifdef _DEBUG @@ -23,14 +23,14 @@ public: bool IsLocked(void) { return false; } bool IsLockedByCurrentThread(void) { return false; } #endif // _DEBUG - + private: #ifdef _DEBUG int m_IsLocked; // Number of times this CS is locked std::thread::id m_OwningThreadID; #endif // _DEBUG - + std::recursive_mutex m_Mutex; } ALIGN_8; @@ -46,12 +46,12 @@ class cCSLock // In Windows, it is an error to call cCriticalSection::Unlock() multiple times if the lock is not held, // therefore we need to check this value whether we are locked or not. bool m_IsLocked; - + public: cCSLock(cCriticalSection * a_CS); cCSLock(cCriticalSection & a_CS); ~cCSLock(); - + // Temporarily unlock or re-lock: void Lock(void); void Unlock(void); @@ -71,7 +71,7 @@ class cCSUnlock public: cCSUnlock(cCSLock & a_Lock); ~cCSUnlock(); - + private: DISALLOW_COPY_AND_ASSIGN(cCSUnlock); } ; diff --git a/src/OSSupport/Errors.cpp b/src/OSSupport/Errors.cpp index ce2e2acb0..a05650111 100644 --- a/src/OSSupport/Errors.cpp +++ b/src/OSSupport/Errors.cpp @@ -17,37 +17,37 @@ AString GetOSErrorString( int a_ErrNo) Out.erase(Out.length() - 2); } return Out; - + #else // _WIN32 - + // According to http://linux.die.net/man/3/strerror_r there are two versions of strerror_r(): - + #if defined(__GLIBC__) && defined( _GNU_SOURCE) && !defined(ANDROID_NDK) // GNU version of strerror_r() - + char * res = strerror_r( errno, buffer, ARRAYCOUNT(buffer)); if (res != nullptr) { Printf(Out, "%d: %s", a_ErrNo, res); return Out; } - + #else // XSI version of strerror_r(): - + int res = strerror_r( errno, buffer, ARRAYCOUNT(buffer)); if (res == 0) { Printf(Out, "%d: %s", a_ErrNo, buffer); return Out; } - + #endif // strerror_r() version - + else { Printf(Out, "Error %d while getting error string for error #%d!", errno, a_ErrNo); return Out; } - + #endif // else _WIN32 } diff --git a/src/OSSupport/Event.h b/src/OSSupport/Event.h index 067a2207c..94f062123 100644 --- a/src/OSSupport/Event.h +++ b/src/OSSupport/Event.h @@ -37,7 +37,7 @@ public: /** Waits for the event until either it is signalled, or the (relative) timeout is passed. Returns true if the event was signalled, false if the timeout was hit or there was an error. */ bool Wait(unsigned a_TimeoutMSec); - + private: /** Used for checking for spurious wakeups. */ diff --git a/src/OSSupport/File.cpp b/src/OSSupport/File.cpp index d99892aae..b4e4c3f6f 100644 --- a/src/OSSupport/File.cpp +++ b/src/OSSupport/File.cpp @@ -50,12 +50,12 @@ cFile::~cFile() bool cFile::Open(const AString & iFileName, eMode iMode) { ASSERT(!IsOpen()); // You should close the file before opening another one - + if (IsOpen()) { Close(); } - + const char * Mode = nullptr; switch (iMode) { @@ -125,13 +125,13 @@ bool cFile::IsOpen(void) const bool cFile::IsEOF(void) const { ASSERT(IsOpen()); - + if (!IsOpen()) { // Unopened files behave as at EOF return true; } - + return (feof(m_File) != 0); } @@ -142,12 +142,12 @@ bool cFile::IsEOF(void) const int cFile::Read (void * a_Buffer, size_t a_NumBytes) { ASSERT(IsOpen()); - + if (!IsOpen()) { return -1; } - + return static_cast(fread(a_Buffer, 1, a_NumBytes, m_File)); // fread() returns the portion of Count parameter actually read, so we need to send a_a_NumBytes as Count } @@ -158,7 +158,7 @@ int cFile::Read (void * a_Buffer, size_t a_NumBytes) AString cFile::Read(size_t a_NumBytes) { ASSERT(IsOpen()); - + if (!IsOpen()) { return AString(); @@ -179,7 +179,7 @@ AString cFile::Read(size_t a_NumBytes) int cFile::Write(const void * a_Buffer, size_t a_NumBytes) { ASSERT(IsOpen()); - + if (!IsOpen()) { return -1; @@ -196,12 +196,12 @@ int cFile::Write(const void * a_Buffer, size_t a_NumBytes) long cFile::Seek (int iPosition) { ASSERT(IsOpen()); - + if (!IsOpen()) { return -1; } - + if (fseek(m_File, iPosition, SEEK_SET) != 0) { return -1; @@ -217,12 +217,12 @@ long cFile::Seek (int iPosition) long cFile::Tell (void) const { ASSERT(IsOpen()); - + if (!IsOpen()) { return -1; } - + return ftell(m_File); } @@ -233,12 +233,12 @@ long cFile::Tell (void) const long cFile::GetSize(void) const { ASSERT(IsOpen()); - + if (!IsOpen()) { return -1; } - + long CurPos = Tell(); if (CurPos < 0) { @@ -263,12 +263,12 @@ long cFile::GetSize(void) const int cFile::ReadRestOfFile(AString & a_Contents) { ASSERT(IsOpen()); - + if (!IsOpen()) { return -1; } - + long TotalSize = GetSize(); if (TotalSize < 0) { @@ -282,7 +282,7 @@ int cFile::ReadRestOfFile(AString & a_Contents) } auto DataSize = static_cast(TotalSize - Position); - + // HACK: This depends on the internal knowledge that AString's data() function returns the internal buffer directly a_Contents.assign(DataSize, '\0'); return Read(reinterpret_cast(const_cast(a_Contents.data())), DataSize); @@ -502,7 +502,7 @@ bool cFile::CreateFolderRecursive(const AString & a_FolderPath) AStringVector cFile::GetFolderContents(const AString & a_Folder) { AStringVector AllFiles; - + #ifdef _WIN32 // If the folder name doesn't contain the terminating slash / backslash, add it: @@ -515,7 +515,7 @@ AStringVector cFile::GetFolderContents(const AString & a_Folder) { FileFilter.push_back('\\'); } - + // Find all files / folders: FileFilter.append("*.*"); HANDLE hFind; @@ -528,7 +528,7 @@ AStringVector cFile::GetFolderContents(const AString & a_Folder) } while (FindNextFileA(hFind, &FindFileData)); FindClose(hFind); } - + #else // _WIN32 DIR * dp; @@ -550,7 +550,7 @@ AStringVector cFile::GetFolderContents(const AString & a_Folder) } closedir(dp); } - + #endif // else _WIN32 return AllFiles; diff --git a/src/OSSupport/File.h b/src/OSSupport/File.h index aab86811d..28485d9f8 100644 --- a/src/OSSupport/File.h +++ b/src/OSSupport/File.h @@ -39,13 +39,13 @@ class cFile public: // tolua_end - + #ifdef _WIN32 static const char PathSeparator = '\\'; #else static const char PathSeparator = '/'; #endif - + /** The mode in which to open the file */ enum eMode { @@ -54,45 +54,45 @@ public: fmReadWrite, // Read / write. If the file already exists, it will be left intact; writing will overwrite the data from the beginning fmAppend // Write-only. If the file already exists cursor will be moved to the end of the file } ; - + /** Simple constructor - creates an unopened file object, use Open() to open / create a real file */ cFile(void); - + /** Constructs and opens / creates the file specified, use IsOpen() to check for success */ cFile(const AString & iFileName, eMode iMode); - + /** Auto-closes the file, if open */ ~cFile(); - + bool Open(const AString & iFileName, eMode iMode); void Close(void); bool IsOpen(void) const; bool IsEOF(void) const; - + /** Reads up to a_NumBytes bytes into a_Buffer, returns the number of bytes actually read, or -1 on failure; asserts if not open */ int Read(void * a_Buffer, size_t a_NumBytes); - + /** Reads up to a_NumBytes bytes, returns the bytes actually read, or empty string on failure; asserts if not open */ AString Read(size_t a_NumBytes); /** Writes up to a_NumBytes bytes from a_Buffer, returns the number of bytes actually written, or -1 on failure; asserts if not open */ int Write(const void * a_Buffer, size_t a_NumBytes); - + /** Seeks to iPosition bytes from file start, returns old position or -1 for failure; asserts if not open */ long Seek (int iPosition); - + /** Returns the current position (bytes from file start) or -1 for failure; asserts if not open */ long Tell (void) const; - + /** Returns the size of file, in bytes, or -1 for failure; asserts if not open */ long GetSize(void) const; - + /** Reads the file from current position till EOF into an AString; returns the number of bytes read or -1 for error */ int ReadRestOfFile(AString & a_Contents); - + /** Returns true if the file specified exists */ static bool Exists(const AString & a_FileName); // Exported in ManualBindings.cpp - + /** Deletes a file or a folder, returns true if successful. Prefer to use DeleteFile or DeleteFolder, since those don't have the penalty of checking whether a_Path is a folder. */ static bool Delete(const AString & a_Path); // Exported in ManualBindings.cpp @@ -100,7 +100,7 @@ public: /** Deletes a file, returns true if successful. Returns false if a_FileName points to a folder. */ static bool DeleteFile(const AString & a_FileName); // Exported in ManualBindings.cpp - + /** Deletes a folder, returns true if successful. Returns false if a_FolderName points to a file. */ static bool DeleteFolder(const AString & a_FolderName); // Exported in ManualBindings.cpp @@ -109,23 +109,23 @@ public: The specified folder itself stays intact. Returns true on success, false on failure. */ static bool DeleteFolderContents(const AString & a_FolderName); // Exported in ManualBindings.cpp - + /** Renames a file or folder, returns true if successful. May fail if dest already exists (libc-dependant)! */ static bool Rename(const AString & a_OrigPath, const AString & a_NewPath); // Exported in ManualBindings.cpp - + /** Copies a file, returns true if successful. Overwrites the dest file if it already exists. */ static bool Copy(const AString & a_SrcFileName, const AString & a_DstFileName); // Exported in ManualBindings.cpp - + /** Returns true if the specified path is a folder */ static bool IsFolder(const AString & a_Path); // Exported in ManualBindings.cpp - + /** Returns true if the specified path is a regular file */ static bool IsFile(const AString & a_Path); // Exported in ManualBindings.cpp - + /** Returns the size of the file, or a negative number on error */ static long GetSize(const AString & a_FileName); // Exported in ManualBindings.cpp - + /** Creates a new folder with the specified name. Returns true if successful. Path may be relative or absolute */ static bool CreateFolder(const AString & a_FolderPath); // Exported in ManualBindings.cpp @@ -133,7 +133,7 @@ public: Returns true if the folder exists at the end of the operation (either created, or already existed). Supports only paths that use the path separator used by the current platform (MSVC CRT supports slashes for file paths, too, but this function doesn't) */ static bool CreateFolderRecursive(const AString & a_FolderPath); // Exported in ManualBindings.cpp - + /** Returns the entire contents of the specified file as a string. Returns empty string on error. */ static AString ReadWholeFile(const AString & a_FileName); // Exported in ManualBindings.cpp @@ -157,15 +157,15 @@ public: static AString GetExecutableExt(void); // tolua_end - + /** Returns the list of all items in the specified folder (files, folders, nix pipes, whatever's there). */ static AStringVector GetFolderContents(const AString & a_Folder); // Exported in ManualBindings.cpp int Printf(const char * a_Fmt, ...) FORMATSTRING(2, 3); - + /** Flushes all the bufferef output into the file (only when writing) */ void Flush(void); - + private: FILE * m_File; } ; // tolua_export diff --git a/src/OSSupport/GZipFile.cpp b/src/OSSupport/GZipFile.cpp index 2ddc260e5..e83d42583 100644 --- a/src/OSSupport/GZipFile.cpp +++ b/src/OSSupport/GZipFile.cpp @@ -64,13 +64,13 @@ int cGZipFile::ReadRestOfFile(AString & a_Contents) ASSERT(!"No file has been opened"); return -1; } - + if (m_Mode != fmRead) { ASSERT(!"Bad file mode, cannot read"); return -1; } - + // Since the gzip format doesn't really support getting the uncompressed length, we need to read incrementally. Yuck! int NumBytesRead = 0; int TotalBytes = 0; diff --git a/src/OSSupport/GZipFile.h b/src/OSSupport/GZipFile.h index d1728fd8e..00a2fd717 100644 --- a/src/OSSupport/GZipFile.h +++ b/src/OSSupport/GZipFile.h @@ -23,24 +23,24 @@ public: fmRead, // Read-only. If the file doesn't exist, object will not be valid fmWrite, // Write-only. If the file already exists, it will be overwritten } ; - + cGZipFile(void); ~cGZipFile(); - + /** Opens the file. Returns true if successful. Fails if a file has already been opened through this object. */ bool Open(const AString & a_FileName, eMode a_Mode); - + /** Closes the file, flushing all buffers. This object may be then reused for a different file and / or mode */ void Close(void); - + /** Reads the rest of the file and decompresses it into a_Contents. Returns the number of decompressed bytes, <0 for error */ int ReadRestOfFile(AString & a_Contents); - + /** Writes a_Contents into file, compressing it along the way. Returns true if successful. Multiple writes are supported. */ bool Write(const AString & a_Contents) { return Write(a_Contents.data(), static_cast(a_Contents.size())); } - + bool Write(const char * a_Data, int a_Size); - + protected: gzFile m_File; eMode m_Mode; diff --git a/src/OSSupport/IsThread.h b/src/OSSupport/IsThread.h index 0c28f5623..85f437267 100644 --- a/src/OSSupport/IsThread.h +++ b/src/OSSupport/IsThread.h @@ -48,7 +48,7 @@ public: /** Returns true if the thread calling this function is the thread contained within this object. */ bool IsCurrentThread(void) const { return std::this_thread::get_id() == m_Thread.get_id(); } - + private: /** The name of the thread, used to aid debugging in IDEs which support named threads */ diff --git a/src/OSSupport/Queue.h b/src/OSSupport/Queue.h index 00d21c49b..d5a4bd443 100644 --- a/src/OSSupport/Queue.h +++ b/src/OSSupport/Queue.h @@ -26,7 +26,7 @@ public: /** Called when an Item is deleted from the queue without being returned */ static void Delete(T) {} - + /** Called when an Item is inserted with EnqueueItemIfNotPresent and there is another equal value already inserted */ static void Combine(T & a_existing, const T & a_new) { @@ -44,10 +44,10 @@ class cQueue { // The actual storage type for the queue typedef typename std::list QueueType; - + // Make iterator an alias for the QueueType's iterator typedef typename QueueType::iterator iterator; - + public: cQueue() {} ~cQueue() {} @@ -188,13 +188,13 @@ public: private: /** The contents of the queue */ QueueType m_Contents; - + /** Mutex that protects access to the queue contents */ cCriticalSection m_CS; - + /** Event that is signalled when an item is added */ cEvent m_evtAdded; - + /** Event that is signalled when an item is removed (both dequeued or erased) */ cEvent m_evtRemoved; }; diff --git a/src/OSSupport/TCPLinkImpl.cpp b/src/OSSupport/TCPLinkImpl.cpp index ae6ba04f1..b15b6282f 100644 --- a/src/OSSupport/TCPLinkImpl.cpp +++ b/src/OSSupport/TCPLinkImpl.cpp @@ -274,7 +274,7 @@ void cTCPLinkImpl::EventCallback(bufferevent * a_BufferEvent, short a_What, void Self->m_Self.reset(); return; } - + // Unknown event, report it: LOGWARNING("cTCPLinkImpl: Unhandled LibEvent event %d (0x%x)", a_What, a_What); ASSERT(!"cTCPLinkImpl: Unhandled LibEvent event"); diff --git a/src/OverridesSettingsRepository.cpp b/src/OverridesSettingsRepository.cpp index e63f2c44c..9e85abce6 100644 --- a/src/OverridesSettingsRepository.cpp +++ b/src/OverridesSettingsRepository.cpp @@ -54,14 +54,14 @@ bool cOverridesSettingsRepository::AddKeyComment(const AString & a_keyname, cons return m_Main->AddKeyComment(a_keyname, a_comment); } - + AString cOverridesSettingsRepository::GetKeyComment(const AString & a_keyname, const int a_commentID) const { - + if (m_Overrides->KeyExists(a_keyname)) { return m_Overrides->GetKeyComment(a_keyname, a_commentID); diff --git a/src/OverridesSettingsRepository.h b/src/OverridesSettingsRepository.h index 04a53997f..62c1ec83d 100644 --- a/src/OverridesSettingsRepository.h +++ b/src/OverridesSettingsRepository.h @@ -20,7 +20,7 @@ public: virtual int AddKeyName(const AString & keyname) override; virtual bool AddKeyComment(const AString & keyname, const AString & comment) override; - + virtual AString GetKeyComment(const AString & keyname, const int commentID) const override; virtual bool DeleteKeyComment(const AString & keyname, const int commentID) override; diff --git a/src/PolarSSL++/AesCfb128Decryptor.cpp b/src/PolarSSL++/AesCfb128Decryptor.cpp index af0d5106e..0aba1c42c 100644 --- a/src/PolarSSL++/AesCfb128Decryptor.cpp +++ b/src/PolarSSL++/AesCfb128Decryptor.cpp @@ -33,7 +33,7 @@ cAesCfb128Decryptor::~cAesCfb128Decryptor() void cAesCfb128Decryptor::Init(const Byte a_Key[16], const Byte a_IV[16]) { ASSERT(!IsValid()); // Cannot Init twice - + memcpy(m_IV, a_IV, 16); aes_setkey_enc(&m_Aes, a_Key, 128); m_IsValid = true; @@ -46,7 +46,7 @@ void cAesCfb128Decryptor::Init(const Byte a_Key[16], const Byte a_IV[16]) void cAesCfb128Decryptor::ProcessData(Byte * a_DecryptedOut, const Byte * a_EncryptedIn, size_t a_Length) { ASSERT(IsValid()); // Must Init() first - + // PolarSSL doesn't support AES-CFB8, need to implement it manually: for (size_t i = 0; i < a_Length; i++) { diff --git a/src/PolarSSL++/AesCfb128Decryptor.h b/src/PolarSSL++/AesCfb128Decryptor.h index 84c790b83..56b96d3b3 100644 --- a/src/PolarSSL++/AesCfb128Decryptor.h +++ b/src/PolarSSL++/AesCfb128Decryptor.h @@ -19,28 +19,28 @@ class cAesCfb128Decryptor { public: - + cAesCfb128Decryptor(void); ~cAesCfb128Decryptor(); - + /** Initializes the decryptor with the specified Key / IV */ void Init(const Byte a_Key[16], const Byte a_IV[16]); - + /** Decrypts a_Length bytes of the encrypted data; produces a_Length output bytes */ void ProcessData(Byte * a_DecryptedOut, const Byte * a_EncryptedIn, size_t a_Length); - + /** Returns true if the object has been initialized with the Key / IV */ bool IsValid(void) const { return m_IsValid; } - + protected: aes_context m_Aes; - + /** The InitialVector, used by the CFB mode decryption */ Byte m_IV[16]; - + /** Current offset in the m_IV, used by the CFB mode decryption */ size_t m_IVOffset; - + /** Indicates whether the object has been initialized with the Key / IV */ bool m_IsValid; } ; diff --git a/src/PolarSSL++/AesCfb128Encryptor.cpp b/src/PolarSSL++/AesCfb128Encryptor.cpp index a641ad48e..ac0262e69 100644 --- a/src/PolarSSL++/AesCfb128Encryptor.cpp +++ b/src/PolarSSL++/AesCfb128Encryptor.cpp @@ -34,7 +34,7 @@ void cAesCfb128Encryptor::Init(const Byte a_Key[16], const Byte a_IV[16]) { ASSERT(!IsValid()); // Cannot Init twice ASSERT(m_IVOffset == 0); - + memcpy(m_IV, a_IV, 16); aes_setkey_enc(&m_Aes, a_Key, 128); m_IsValid = true; @@ -47,7 +47,7 @@ void cAesCfb128Encryptor::Init(const Byte a_Key[16], const Byte a_IV[16]) void cAesCfb128Encryptor::ProcessData(Byte * a_EncryptedOut, const Byte * a_PlainIn, size_t a_Length) { ASSERT(IsValid()); // Must Init() first - + // PolarSSL doesn't do AES-CFB8, so we need to implement it ourselves: for (size_t i = 0; i < a_Length; i++) { diff --git a/src/PolarSSL++/AesCfb128Encryptor.h b/src/PolarSSL++/AesCfb128Encryptor.h index 9dbb5d2c3..71280a098 100644 --- a/src/PolarSSL++/AesCfb128Encryptor.h +++ b/src/PolarSSL++/AesCfb128Encryptor.h @@ -21,25 +21,25 @@ class cAesCfb128Encryptor public: cAesCfb128Encryptor(void); ~cAesCfb128Encryptor(); - + /** Initializes the decryptor with the specified Key / IV */ void Init(const Byte a_Key[16], const Byte a_IV[16]); - + /** Encrypts a_Length bytes of the plain data; produces a_Length output bytes */ void ProcessData(Byte * a_EncryptedOut, const Byte * a_PlainIn, size_t a_Length); - + /** Returns true if the object has been initialized with the Key / IV */ bool IsValid(void) const { return m_IsValid; } - + protected: aes_context m_Aes; - + /** The InitialVector, used by the CFB mode encryption */ Byte m_IV[16]; - + /** Current offset in the m_IV, used by the CFB mode encryption */ size_t m_IVOffset; - + /** Indicates whether the object has been initialized with the Key / IV */ bool m_IsValid; } ; diff --git a/src/PolarSSL++/BlockingSslClientSocket.cpp b/src/PolarSSL++/BlockingSslClientSocket.cpp index 61aee211d..7d7fc4ccf 100644 --- a/src/PolarSSL++/BlockingSslClientSocket.cpp +++ b/src/PolarSSL++/BlockingSslClientSocket.cpp @@ -106,7 +106,7 @@ bool cBlockingSslClientSocket::Connect(const AString & a_ServerName, UInt16 a_Po m_LastErrorText = "Already connected"; return false; } - + // Connect the underlying socket: m_ServerName = a_ServerName; if (!cNetwork::Connect(a_ServerName, a_Port, @@ -123,7 +123,7 @@ bool cBlockingSslClientSocket::Connect(const AString & a_ServerName, UInt16 a_Po { return false; } - + // Initialize the SSL: int ret = m_Ssl.Initialize(true); if (ret != 0) @@ -131,20 +131,20 @@ bool cBlockingSslClientSocket::Connect(const AString & a_ServerName, UInt16 a_Po Printf(m_LastErrorText, "SSL initialization failed: -0x%x", -ret); return false; } - + // If we have been assigned a trusted CA root cert store, push it into the SSL context: if (m_CACerts.get() != nullptr) { m_Ssl.SetCACerts(m_CACerts, m_ExpectedPeerName); } - + ret = m_Ssl.Handshake(); if (ret != 0) { Printf(m_LastErrorText, "SSL handshake failed: -0x%x", -ret); return false; } - + return true; } @@ -163,7 +163,7 @@ bool cBlockingSslClientSocket::SetTrustedRootCertsFromString(const AString & a_C a_ExpectedPeerName.c_str() ); } - + // Parse the cert: m_CACerts.reset(new cX509Cert); int ret = m_CACerts->Parse(a_CACerts.data(), a_CACerts.size()); @@ -173,7 +173,7 @@ bool cBlockingSslClientSocket::SetTrustedRootCertsFromString(const AString & a_C return false; } m_ExpectedPeerName = a_ExpectedPeerName; - + return true; } @@ -188,7 +188,7 @@ bool cBlockingSslClientSocket::Send(const void * a_Data, size_t a_NumBytes) m_LastErrorText = "Socket is closed"; return false; } - + // Keep sending the data until all of it is sent: const char * Data = reinterpret_cast(a_Data); size_t NumBytes = a_NumBytes; @@ -241,7 +241,7 @@ void cBlockingSslClientSocket::Disconnect(void) { return; } - + m_Ssl.NotifyClose(); m_IsConnected = false; diff --git a/src/PolarSSL++/BlockingSslClientSocket.h b/src/PolarSSL++/BlockingSslClientSocket.h index 3c61f7f89..bc7cbe039 100644 --- a/src/PolarSSL++/BlockingSslClientSocket.h +++ b/src/PolarSSL++/BlockingSslClientSocket.h @@ -27,60 +27,60 @@ public: { Disconnect(); } - + /** Connects to the specified server and performs SSL handshake. Returns true if successful, false on failure. Sets internal error text on failure. */ bool Connect(const AString & a_ServerName, UInt16 a_Port); - + /** Sends the specified data over the connection. Returns true if successful, false on failure. Sets the internal error text on failure. */ bool Send(const void * a_Data, size_t a_NumBytes); - + /** Receives data from the connection. Blocks until there is any data available, then returns as much as possible. Returns the number of bytes actually received, negative number on failure. Sets the internal error text on failure. */ int Receive(void * a_Data, size_t a_MaxBytes); - + /** Disconnects the connection gracefully, if possible. Note that this also frees the internal SSL context, so all the certificates etc. are lost. */ void Disconnect(void); - + /** Sets the root certificates that are to be trusted. Forces the connection to use strict cert verification. Needs to be used before calling Connect(). a_ExpectedPeerName is the name that we expect to receive in the SSL peer's cert; verification will fail if the presented name is different (possible MITM). Returns true on success, false on failure. Sets internal error text on failure. */ bool SetTrustedRootCertsFromString(const AString & a_CACerts, const AString & a_ExpectedPeerName); - + /** Returns the text of the last error that has occurred in this instance. */ const AString & GetLastErrorText(void) const { return m_LastErrorText; } - + protected: friend class cBlockingSslClientSocketConnectCallbacks; friend class cBlockingSslClientSocketLinkCallbacks; /** The SSL context used for the socket */ cCallbackSslContext m_Ssl; - + /** The underlying socket to the SSL server */ cTCPLinkPtr m_Socket; /** The object used to signal state changes in the socket (the cause of the blocking). */ cEvent m_Event; - + /** The trusted CA root cert store, if we are to verify the cert strictly. Set by SetTrustedRootCertsFromString(). */ cX509CertPtr m_CACerts; - + /** The expected SSL peer's name, if we are to verify the cert strictly. Set by SetTrustedRootCertsFromString(). */ AString m_ExpectedPeerName; /** The hostname to which the socket is connecting (stored for error reporting). */ AString m_ServerName; - + /** Text of the last error that has occurred. */ AString m_LastErrorText; - + /** Set to true if the connection established successfully. */ std::atomic m_IsConnected; @@ -90,8 +90,8 @@ protected: /** Buffer for the data incoming on the network socket. Protected by m_CSIncomingData. */ AString m_IncomingData; - - + + /** Called when the connection is established successfully. */ void OnConnected(void); diff --git a/src/PolarSSL++/BufferedSslContext.h b/src/PolarSSL++/BufferedSslContext.h index 1b7e1af46..ab058a52e 100644 --- a/src/PolarSSL++/BufferedSslContext.h +++ b/src/PolarSSL++/BufferedSslContext.h @@ -19,28 +19,28 @@ class cBufferedSslContext : public cSslContext { typedef cSslContext super; - + public: /** Creates a new context with the buffers of specified size for the encrypted / decrypted data. */ cBufferedSslContext(size_t a_BufferSize = 64000); - + /** Stores the specified data in the "incoming" buffer, to be process by the SSL decryptor. This is the data received from the SSL peer. Returns the number of bytes actually stored. If 0 is returned, owner should check the error state. */ size_t WriteIncoming(const void * a_Data, size_t a_NumBytes); - + /** Retrieves data from the "outgoing" buffer, after being processed by the SSL encryptor. This is the data to be sent to the SSL peer. Returns the number of bytes actually retrieved. */ size_t ReadOutgoing(void * a_Data, size_t a_DataMaxSize); - + protected: /** Buffer for the data that has been encrypted into the SSL stream and should be sent out. */ cByteBuffer m_OutgoingData; - + /** Buffer for the data that has come in and needs to be decrypted from the SSL stream. */ cByteBuffer m_IncomingData; - + // cSslContext overrides: virtual int ReceiveEncrypted(unsigned char * a_Buffer, size_t a_NumBytes) override; diff --git a/src/PolarSSL++/CallbackSslContext.h b/src/PolarSSL++/CallbackSslContext.h index 3e6edc5f4..1fc131182 100644 --- a/src/PolarSSL++/CallbackSslContext.h +++ b/src/PolarSSL++/CallbackSslContext.h @@ -25,7 +25,7 @@ public: public: // Force a virtual destructor in descendants: virtual ~cDataCallbacks() {} - + /** Called when PolarSSL wants to read encrypted data from the SSL peer. The returned value is the number of bytes received, or a PolarSSL error on failure. The implementation can return POLARSSL_ERR_NET_WANT_READ or POLARSSL_ERR_NET_WANT_WRITE to indicate @@ -33,7 +33,7 @@ public: SSL operation that invoked this call will terminate with the same return value, so that the owner is notified of this condition and can potentially restart the operation later on. */ virtual int ReceiveEncrypted(unsigned char * a_Buffer, size_t a_NumBytes) = 0; - + /** Called when PolarSSL wants to write encrypted data to the SSL peer. The returned value is the number of bytes sent, or a PolarSSL error on failure. The implementation can return POLARSSL_ERR_NET_WANT_READ or POLARSSL_ERR_NET_WANT_WRITE to indicate @@ -42,14 +42,14 @@ public: notified of this condition and can potentially restart the operation later on. */ virtual int SendEncrypted(const unsigned char * a_Buffer, size_t a_NumBytes) = 0; } ; - - + + /** Creates a new SSL context with no callbacks assigned */ cCallbackSslContext(void); - + /** Creates a new SSL context with the specified callbacks */ cCallbackSslContext(cDataCallbacks & a_Callbacks); - + protected: /** The callbacks to use to send and receive SSL peer data */ cDataCallbacks * m_Callbacks; diff --git a/src/PolarSSL++/CryptoKey.cpp b/src/PolarSSL++/CryptoKey.cpp index cc4eefdfe..b01fee5f9 100644 --- a/src/PolarSSL++/CryptoKey.cpp +++ b/src/PolarSSL++/CryptoKey.cpp @@ -66,7 +66,7 @@ cCryptoKey::~cCryptoKey() int cCryptoKey::Decrypt(const Byte * a_EncryptedData, size_t a_EncryptedLength, Byte * a_DecryptedData, size_t a_DecryptedMaxLength) { ASSERT(IsValid()); - + size_t DecryptedLen = a_DecryptedMaxLength; int res = pk_decrypt(&m_Pk, a_EncryptedData, a_EncryptedLength, @@ -87,7 +87,7 @@ int cCryptoKey::Decrypt(const Byte * a_EncryptedData, size_t a_EncryptedLength, int cCryptoKey::Encrypt(const Byte * a_PlainData, size_t a_PlainLength, Byte * a_EncryptedData, size_t a_EncryptedMaxLength) { ASSERT(IsValid()); - + size_t EncryptedLength = a_EncryptedMaxLength; int res = pk_encrypt(&m_Pk, a_PlainData, a_PlainLength, a_EncryptedData, &EncryptedLength, a_EncryptedMaxLength, @@ -108,7 +108,7 @@ int cCryptoKey::Encrypt(const Byte * a_PlainData, size_t a_PlainLength, Byte * a int cCryptoKey::ParsePublic(const void * a_Data, size_t a_NumBytes) { ASSERT(!IsValid()); // Cannot parse a second key - + return pk_parse_public_key(&m_Pk, reinterpret_cast(a_Data), a_NumBytes); } @@ -120,7 +120,7 @@ int cCryptoKey::ParsePublic(const void * a_Data, size_t a_NumBytes) int cCryptoKey::ParsePrivate(const void * a_Data, size_t a_NumBytes, const AString & a_Password) { ASSERT(!IsValid()); // Cannot parse a second key - + if (a_Password.empty()) { return pk_parse_key(&m_Pk, reinterpret_cast(a_Data), a_NumBytes, nullptr, 0); diff --git a/src/PolarSSL++/CryptoKey.h b/src/PolarSSL++/CryptoKey.h index 9c298e501..fc8034d16 100644 --- a/src/PolarSSL++/CryptoKey.h +++ b/src/PolarSSL++/CryptoKey.h @@ -19,30 +19,30 @@ class cCryptoKey { friend class cSslContext; - + public: /** Constructs an empty key instance. Before use, it needs to be filled by ParsePublic() or ParsePrivate() */ cCryptoKey(void); - + /** Constructs the public key out of the DER- or PEM-encoded pubkey data */ cCryptoKey(const AString & a_PublicKeyData); - + /** Constructs the private key out of the DER- or PEM-encoded privkey data, with the specified password. If a_Password is empty, no password is assumed. */ cCryptoKey(const AString & a_PrivateKeyData, const AString & a_Password); - + ~cCryptoKey(); - + /** Decrypts the data using the stored public key Both a_EncryptedData and a_DecryptedData must be at least bytes large. Returns the number of bytes decrypted, or negative number for error. */ int Decrypt(const Byte * a_EncryptedData, size_t a_EncryptedLength, Byte * a_DecryptedData, size_t a_DecryptedMaxLength); - + /** Encrypts the data using the stored public key Both a_EncryptedData and a_DecryptedData must be at least bytes large. Returns the number of bytes decrypted, or negative number for error. */ int Encrypt(const Byte * a_PlainData, size_t a_PlainLength, Byte * a_EncryptedData, size_t a_EncryptedMaxLength); - + /** Parses the specified data into a public key representation. The key can be DER- or PEM-encoded. Returns 0 on success, PolarSSL error code on failure. */ @@ -53,18 +53,18 @@ public: The key can be DER- or PEM-encoded. Returns 0 on success, PolarSSL error code on failure. */ int ParsePrivate(const void * a_Data, size_t a_NumBytes, const AString & a_Password); - + /** Returns true if the contained key is valid. */ bool IsValid(void) const; protected: /** The PolarSSL representation of the key data */ pk_context m_Pk; - + /** The random generator used in encryption and decryption */ cCtrDrbgContext m_CtrDrbg; - - + + /** Returns the internal context ptr. Only use in PolarSSL API calls. */ pk_context * GetInternal(void) { return &m_Pk; } } ; diff --git a/src/PolarSSL++/CtrDrbgContext.cpp b/src/PolarSSL++/CtrDrbgContext.cpp index 25c2987b1..daacc70cc 100644 --- a/src/PolarSSL++/CtrDrbgContext.cpp +++ b/src/PolarSSL++/CtrDrbgContext.cpp @@ -38,7 +38,7 @@ int cCtrDrbgContext::Initialize(const void * a_Custom, size_t a_CustomSize) // Already initialized return 0; } - + int res = ctr_drbg_init(&m_CtrDrbg, entropy_func, &(m_EntropyContext->m_Entropy), reinterpret_cast(a_Custom), a_CustomSize); m_IsValid = (res == 0); return res; diff --git a/src/PolarSSL++/CtrDrbgContext.h b/src/PolarSSL++/CtrDrbgContext.h index 230db8753..16b4a44b0 100644 --- a/src/PolarSSL++/CtrDrbgContext.h +++ b/src/PolarSSL++/CtrDrbgContext.h @@ -27,29 +27,29 @@ class cCtrDrbgContext friend class cSslContext; friend class cRsaPrivateKey; friend class cCryptoKey; - + public: /** Constructs the context with a new entropy context. */ cCtrDrbgContext(void); - + /** Constructs the context with the specified entropy context. */ cCtrDrbgContext(const SharedPtr & a_EntropyContext); - + /** Initializes the context. a_Custom is optional additional data to use for entropy, nullptr is accepted. Returns 0 if successful, PolarSSL error code on failure. */ int Initialize(const void * a_Custom, size_t a_CustomSize); - + /** Returns true if the object is valid (has been initialized properly) */ bool IsValid(void) const { return m_IsValid; } - + protected: /** The entropy source used for generating the random */ SharedPtr m_EntropyContext; /** The random generator context */ ctr_drbg_context m_CtrDrbg; - + /** Set to true if the object is valid (has been initialized properly) */ bool m_IsValid; diff --git a/src/PolarSSL++/EntropyContext.h b/src/PolarSSL++/EntropyContext.h index bc7fff066..69671d32f 100644 --- a/src/PolarSSL++/EntropyContext.h +++ b/src/PolarSSL++/EntropyContext.h @@ -21,7 +21,7 @@ class cEntropyContext public: cEntropyContext(void); ~cEntropyContext(); - + protected: entropy_context m_Entropy; } ; diff --git a/src/PolarSSL++/RsaPrivateKey.cpp b/src/PolarSSL++/RsaPrivateKey.cpp index ed94923c2..17cede05f 100644 --- a/src/PolarSSL++/RsaPrivateKey.cpp +++ b/src/PolarSSL++/RsaPrivateKey.cpp @@ -78,7 +78,7 @@ AString cRsaPrivateKey::GetPubKeyDER(void) } m_IsValid = true; } - + ~cPubKey() { if (m_IsValid) @@ -86,14 +86,14 @@ AString cRsaPrivateKey::GetPubKeyDER(void) pk_free(&m_Key); } } - + operator pk_context * (void) { return &m_Key; } - + protected: bool m_IsValid; pk_context m_Key; } PkCtx(&m_Rsa); - + unsigned char buf[3000]; int res = pk_write_pubkey_der(PkCtx, buf, sizeof(buf)); if (res < 0) diff --git a/src/PolarSSL++/RsaPrivateKey.h b/src/PolarSSL++/RsaPrivateKey.h index 4d03f27df..32422da8d 100644 --- a/src/PolarSSL++/RsaPrivateKey.h +++ b/src/PolarSSL++/RsaPrivateKey.h @@ -20,41 +20,41 @@ class cRsaPrivateKey { friend class cSslContext; - + public: /** Creates a new empty object, the key is not assigned */ cRsaPrivateKey(void); - + /** Deep-copies the key from a_Other */ cRsaPrivateKey(const cRsaPrivateKey & a_Other); - + ~cRsaPrivateKey(); - + /** Generates a new key within this object, with the specified size in bits. Returns true on success, false on failure. */ bool Generate(unsigned a_KeySizeBits = 1024); - + /** Returns the public key part encoded in ASN1 DER encoding */ AString GetPubKeyDER(void); - + /** Decrypts the data using RSAES-PKCS#1 algorithm. Both a_EncryptedData and a_DecryptedData must be at least bytes large. Returns the number of bytes decrypted, or negative number for error. */ int Decrypt(const Byte * a_EncryptedData, size_t a_EncryptedLength, Byte * a_DecryptedData, size_t a_DecryptedMaxLength); - + /** Encrypts the data using RSAES-PKCS#1 algorithm. Both a_EncryptedData and a_DecryptedData must be at least bytes large. Returns the number of bytes decrypted, or negative number for error. */ int Encrypt(const Byte * a_PlainData, size_t a_PlainLength, Byte * a_EncryptedData, size_t a_EncryptedMaxLength); - + protected: /** The PolarSSL key context */ rsa_context m_Rsa; /** The random generator used for generating the key and encryption / decryption */ cCtrDrbgContext m_CtrDrbg; - - + + /** Returns the internal context ptr. Only use in PolarSSL API calls. */ rsa_context * GetInternal(void) { return &m_Rsa; } } ; diff --git a/src/PolarSSL++/Sha1Checksum.cpp b/src/PolarSSL++/Sha1Checksum.cpp index e69ef236f..5a56c18b0 100644 --- a/src/PolarSSL++/Sha1Checksum.cpp +++ b/src/PolarSSL++/Sha1Checksum.cpp @@ -66,7 +66,7 @@ cSha1Checksum::cSha1Checksum(void) : void cSha1Checksum::Update(const Byte * a_Data, size_t a_Length) { ASSERT(m_DoesAcceptInput); // Not Finalize()-d yet, or Restart()-ed - + sha1_update(&m_Sha1, a_Data, a_Length); } @@ -77,7 +77,7 @@ void cSha1Checksum::Update(const Byte * a_Data, size_t a_Length) void cSha1Checksum::Finalize(cSha1Checksum::Checksum & a_Output) { ASSERT(m_DoesAcceptInput); // Not Finalize()-d yet, or Restart()-ed - + sha1_finish(&m_Sha1, a_Output); m_DoesAcceptInput = false; } @@ -90,7 +90,7 @@ void cSha1Checksum::DigestToJava(const Checksum & a_Digest, AString & a_Out) { Checksum Digest; memcpy(Digest, a_Digest, sizeof(Digest)); - + bool IsNegative = (Digest[0] >= 0x80); if (IsNegative) { diff --git a/src/PolarSSL++/Sha1Checksum.h b/src/PolarSSL++/Sha1Checksum.h index 68fdbcf1b..23eb6f420 100644 --- a/src/PolarSSL++/Sha1Checksum.h +++ b/src/PolarSSL++/Sha1Checksum.h @@ -20,30 +20,30 @@ class cSha1Checksum { public: typedef Byte Checksum[20]; // The type used for storing the checksum - + cSha1Checksum(void); - + /** Adds the specified data to the checksum */ void Update(const Byte * a_Data, size_t a_Length); - + /** Calculates and returns the final checksum */ void Finalize(Checksum & a_Output); - + /** Returns true if the object is accepts more input data, false if Finalize()-d (need to Restart()) */ bool DoesAcceptInput(void) const { return m_DoesAcceptInput; } - + /** Converts a raw 160-bit SHA1 digest into a Java Hex representation According to http://wiki.vg/wiki/index.php?title=Protocol_Encryption&oldid=2802 */ static void DigestToJava(const Checksum & a_Digest, AString & a_JavaOut); - + /** Clears the current context and start a new checksum calculation */ void Restart(void); - + protected: /** True if the object is accepts more input data, false if Finalize()-d (need to Restart()) */ bool m_DoesAcceptInput; - + sha1_context m_Sha1; } ; diff --git a/src/PolarSSL++/SslContext.cpp b/src/PolarSSL++/SslContext.cpp index 4ff0c3077..74b45ea33 100644 --- a/src/PolarSSL++/SslContext.cpp +++ b/src/PolarSSL++/SslContext.cpp @@ -44,7 +44,7 @@ int cSslContext::Initialize(bool a_IsClient, const SharedPtr & LOGWARNING("SSL: Double initialization is not supported."); return POLARSSL_ERR_SSL_BAD_INPUT_DATA; // There is no return value well-suited for this, reuse this one. } - + // Set the CtrDrbg context, create a new one if needed: m_CtrDrbg = a_CtrDrbg; if (m_CtrDrbg.get() == nullptr) @@ -52,7 +52,7 @@ int cSslContext::Initialize(bool a_IsClient, const SharedPtr & m_CtrDrbg.reset(new cCtrDrbgContext); m_CtrDrbg->Initialize("Cuberite", 8); } - + // Initialize PolarSSL's structures: memset(&m_Ssl, 0, sizeof(m_Ssl)); int res = ssl_init(&m_Ssl); @@ -64,7 +64,7 @@ int cSslContext::Initialize(bool a_IsClient, const SharedPtr & ssl_set_authmode(&m_Ssl, SSL_VERIFY_NONE); // We cannot verify because we don't have a CA chain, required by PolarSSL, implemented yet (TODO) ssl_set_rng(&m_Ssl, ctr_drbg_random, &m_CtrDrbg->m_CtrDrbg); ssl_set_bio(&m_Ssl, ReceiveEncrypted, this, SendEncrypted, this); - + #ifdef _DEBUG /* // These functions allow us to debug SSL and certificate problems, but produce way too much output, @@ -74,7 +74,7 @@ int cSslContext::Initialize(bool a_IsClient, const SharedPtr & ssl_set_verify(&m_Ssl, &SSLVerifyCert, this); //*/ - + /* // Set ciphersuite to the easiest one to decode, so that the connection can be wireshark-decoded: static const int CipherSuites[] = @@ -87,7 +87,7 @@ int cSslContext::Initialize(bool a_IsClient, const SharedPtr & ssl_set_ciphersuites(&m_Ssl, CipherSuites); //*/ #endif - + m_IsValid = true; return 0; } @@ -99,18 +99,18 @@ int cSslContext::Initialize(bool a_IsClient, const SharedPtr & void cSslContext::SetOwnCert(const cX509CertPtr & a_OwnCert, const cRsaPrivateKeyPtr & a_OwnCertPrivKey) { ASSERT(m_IsValid); // Call Initialize() first - + // Check that both the cert and the key is valid: if ((a_OwnCert.get() == nullptr) || (a_OwnCertPrivKey.get() == nullptr)) { LOGWARNING("SSL: Own certificate is not valid, skipping the set."); return; } - + // Make sure we have the cert stored for later, PolarSSL only uses the cert later on m_OwnCert = a_OwnCert; m_OwnCertPrivKey = a_OwnCertPrivKey; - + // Set into the context: ssl_set_own_cert_rsa(&m_Ssl, m_OwnCert->GetInternal(), m_OwnCertPrivKey->GetInternal()); } @@ -122,18 +122,18 @@ void cSslContext::SetOwnCert(const cX509CertPtr & a_OwnCert, const cRsaPrivateKe void cSslContext::SetOwnCert(const cX509CertPtr & a_OwnCert, const cCryptoKeyPtr & a_OwnCertPrivKey) { ASSERT(m_IsValid); // Call Initialize() first - + // Check that both the cert and the key is valid: if ((a_OwnCert.get() == nullptr) || (a_OwnCertPrivKey.get() == nullptr)) { LOGWARNING("SSL: Own certificate is not valid, skipping the set."); return; } - + // Make sure we have the cert stored for later, PolarSSL only uses the cert later on m_OwnCert = a_OwnCert; m_OwnCertPrivKey2 = a_OwnCertPrivKey; - + // Set into the context: ssl_set_own_cert(&m_Ssl, m_OwnCert->GetInternal(), m_OwnCertPrivKey2->GetInternal()); } @@ -145,12 +145,12 @@ void cSslContext::SetOwnCert(const cX509CertPtr & a_OwnCert, const cCryptoKeyPtr void cSslContext::SetCACerts(const cX509CertPtr & a_CACert, const AString & a_ExpectedPeerName) { ASSERT(m_IsValid); // Call Initialize() first - + // Store the data in our internal buffers, to avoid losing the pointers later on // PolarSSL will need these after this call returns, and the caller may move / delete the data before that: m_ExpectedPeerName = a_ExpectedPeerName; m_CACerts = a_CACert; - + // Set the trusted CA root cert store: ssl_set_authmode(&m_Ssl, SSL_VERIFY_REQUIRED); ssl_set_ca_chain(&m_Ssl, m_CACerts->GetInternal(), nullptr, m_ExpectedPeerName.empty() ? nullptr : m_ExpectedPeerName.c_str()); @@ -171,7 +171,7 @@ int cSslContext::WritePlain(const void * a_Data, size_t a_NumBytes) return res; } } - + return ssl_write(&m_Ssl, reinterpret_cast(a_Data), a_NumBytes); } @@ -190,7 +190,7 @@ int cSslContext::ReadPlain(void * a_Data, size_t a_MaxBytes) return res; } } - + return ssl_read(&m_Ssl, reinterpret_cast(a_Data), a_MaxBytes); } @@ -202,7 +202,7 @@ int cSslContext::Handshake(void) { ASSERT(m_IsValid); // Need to call Initialize() first ASSERT(!m_HasHandshaken); // Must not call twice - + int res = ssl_handshake(&m_Ssl); if (res == 0) { @@ -232,7 +232,7 @@ int cSslContext::NotifyClose(void) // Don't want the trace messages return; } - + // Remove the terminating LF: size_t len = strlen(a_Text) - 1; while ((len > 0) && (a_Text[len] <= 32)) @@ -240,7 +240,7 @@ int cSslContext::NotifyClose(void) len--; } AString Text(a_Text, len + 1); - + LOGD("SSL (%d): %s", a_Level, Text.c_str()); } diff --git a/src/PolarSSL++/SslContext.h b/src/PolarSSL++/SslContext.h index 408fc7c56..27f9dd674 100644 --- a/src/PolarSSL++/SslContext.h +++ b/src/PolarSSL++/SslContext.h @@ -39,30 +39,30 @@ class cSslContext abstract public: /** Creates a new uninitialized context */ cSslContext(void); - + virtual ~cSslContext(); - + /** Initializes the context for use as a server or client. Returns 0 on success, PolarSSL error on failure. */ int Initialize(bool a_IsClient, const SharedPtr & a_CtrDrbg = SharedPtr()); - + /** Returns true if the object has been initialized properly. */ bool IsValid(void) const { return m_IsValid; } - + /** Sets the certificate to use as our own. Must be used when representing a server, optional when client. Must be called after Initialize(). */ void SetOwnCert(const cX509CertPtr & a_OwnCert, const cRsaPrivateKeyPtr & a_OwnCertPrivKey); - + /** Sets the certificate to use as our own. Must be used when representing a server, optional when client. Must be called after Initialize(). */ void SetOwnCert(const cX509CertPtr & a_OwnCert, const cCryptoKeyPtr & a_OwnCertPrivKey); - + /** Sets a cert chain as the trusted cert store for this context. Must be called after Initialize(). Calling this will switch the context into strict cert verification mode. a_ExpectedPeerName is the CommonName that we expect the SSL peer to have in its cert, if it is different, the verification will fail. An empty string will disable the CN check. */ void SetCACerts(const cX509CertPtr & a_CACert, const AString & a_ExpectedPeerName); - + /** Writes data to be encrypted and sent to the SSL peer. Will perform SSL handshake, if needed. Returns the number of bytes actually written, or PolarSSL error code. If the return value is POLARSSL_ERR_NET_WANT_READ or POLARSSL_ERR_NET_WANT_WRITE, the owner should send any @@ -70,7 +70,7 @@ public: this function again with the same parameters. Note that this may repeat a few times before the data is actually written, mainly due to initial handshake. */ int WritePlain(const void * a_Data, size_t a_NumBytes); - + /** Reads data decrypted from the SSL stream. Will perform SSL handshake, if needed. Returns the number of bytes actually read, or PolarSSL error code. If the return value is POLARSSL_ERR_NET_WANT_READ or POLARSSL_ERR_NET_WANT_WRITE, the owner should send any @@ -78,75 +78,75 @@ public: this function again with the same parameters. Note that this may repeat a few times before the data is actually read, mainly due to initial handshake. */ int ReadPlain(void * a_Data, size_t a_MaxBytes); - + /** Performs the SSL handshake. Returns zero on success, PoladSSL error code on failure. If the return value is POLARSSL_ERR_NET_WANT_READ or POLARSSL_ERR_NET_WANT_WRITE, the owner should send any cached outgoing data to the SSL peer and write any incoming data received from the SSL peer and then call this function again. Note that this may repeat a few times before the handshake is completed. */ int Handshake(void); - + /** Returns true if the SSL handshake has been completed. */ bool HasHandshaken(void) const { return m_HasHandshaken; } - + /** Notifies the SSL peer that the connection is being closed. Returns 0 on success, PolarSSL error code on failure. */ int NotifyClose(void); - + protected: /** True if the object has been initialized properly. */ bool m_IsValid; - + /** The random generator to use */ SharedPtr m_CtrDrbg; - + /** The SSL context that PolarSSL uses. */ ssl_context m_Ssl; - + /** The certificate that we present to the peer. */ cX509CertPtr m_OwnCert; - + /** Private key for m_OwnCert, if initialized from a cRsaPrivateKey. */ cRsaPrivateKeyPtr m_OwnCertPrivKey; - + /** Private key for m_OwnCert, if initialized from a cCryptoKey. */ cCryptoKeyPtr m_OwnCertPrivKey2; - + /** True if the SSL handshake has been completed. */ bool m_HasHandshaken; - + /** A copy of the trusted CA root cert store that is passed to us in SetCACerts(), so that the pointer stays valid even after the call, when PolarSSL finally uses it. */ cX509CertPtr m_CACerts; - + /** Buffer for the expected peer name. We need to buffer it because the caller may free the string they give us before PolarSSL consumes the raw pointer it gets to the CN. */ AString m_ExpectedPeerName; - - + + /** The callback used by PolarSSL when it wants to read encrypted data. */ static int ReceiveEncrypted(void * a_This, unsigned char * a_Buffer, size_t a_NumBytes) { return (reinterpret_cast(a_This))->ReceiveEncrypted(a_Buffer, a_NumBytes); } - + /** The callback used by PolarSSL when it wants to write encrypted data. */ static int SendEncrypted(void * a_This, const unsigned char * a_Buffer, size_t a_NumBytes) { return (reinterpret_cast(a_This))->SendEncrypted(a_Buffer, a_NumBytes); } - + #ifdef _DEBUG /** The callback used by PolarSSL to output debug messages */ static void SSLDebugMessage(void * a_UserParam, int a_Level, const char * a_Text); - + /** The callback used by PolarSSL to log information on the cert chain */ static int SSLVerifyCert(void * a_This, x509_crt * a_Crt, int a_Depth, int * a_Flags); #endif // _DEBUG /** Called when PolarSSL wants to read encrypted data. */ virtual int ReceiveEncrypted(unsigned char * a_Buffer, size_t a_NumBytes) = 0; - + /** Called when PolarSSL wants to write encrypted data. */ virtual int SendEncrypted(const unsigned char * a_Buffer, size_t a_NumBytes) = 0; } ; diff --git a/src/PolarSSL++/X509Cert.h b/src/PolarSSL++/X509Cert.h index 991617d24..8c3468f03 100644 --- a/src/PolarSSL++/X509Cert.h +++ b/src/PolarSSL++/X509Cert.h @@ -18,15 +18,15 @@ class cX509Cert { friend class cSslContext; - + public: cX509Cert(void); ~cX509Cert(void); - + /** Parses the certificate chain data into the context. Returns 0 on succes, or PolarSSL error code on failure. */ int Parse(const void * a_CertContents, size_t a_Size); - + protected: x509_crt m_Cert; diff --git a/src/ProbabDistrib.cpp b/src/ProbabDistrib.cpp index ec3a4d85f..f63aa0605 100644 --- a/src/ProbabDistrib.cpp +++ b/src/ProbabDistrib.cpp @@ -43,7 +43,7 @@ void cProbabDistrib::SetPoints(const cProbabDistrib::cPoints & a_Points) { continue; } - + // Add the current trapezoid to the sum: ProbSum += (LastProb + itr->m_Probability) * (itr->m_Value - LastValue) / 2; LastProb = itr->m_Probability; @@ -89,7 +89,7 @@ bool cProbabDistrib::SetDefString(const AString & a_DefString) } Pts.push_back(cPoint(Value, Prob)); } // for itr - Points[] - + SetPoints(Pts); return true; } @@ -112,7 +112,7 @@ int cProbabDistrib::MapValue(int a_OrigValue) const { ASSERT(a_OrigValue >= 0); ASSERT(a_OrigValue < m_Sum); - + // Binary search through m_Cumulative for placement: size_t Lo = 0; size_t Hi = m_Cumulative.size() - 1; @@ -130,7 +130,7 @@ int cProbabDistrib::MapValue(int a_OrigValue) const } } ASSERT(Hi - Lo == 1); - + // Linearly interpolate between Lo and Hi: int ProbDif = m_Cumulative[Hi].m_Probability - m_Cumulative[Lo].m_Probability; ProbDif = (ProbDif != 0) ? ProbDif : 1; diff --git a/src/ProbabDistrib.h b/src/ProbabDistrib.h index 29442bce8..aeac5a30a 100644 --- a/src/ProbabDistrib.h +++ b/src/ProbabDistrib.h @@ -35,33 +35,33 @@ public: public: int m_Value; int m_Probability; - + cPoint(int a_Value, int a_Probability) : m_Value(a_Value), m_Probability(a_Probability) { } } ; - + typedef std::vector cPoints; - - + + cProbabDistrib(int a_MaxValue); - + /** Sets the distribution curve using an array of [value, probability] points, linearly interpolated. a_Points must not be empty. */ void SetPoints(const cPoints & a_Points); - + /** Sets the distribution curve using a definition string; returns true on successful parse */ bool SetDefString(const AString & a_DefString); - + /** Gets a random value from a_Rand, shapes it into the distribution curve and returns the value. */ int Random(MTRand & a_Rand) const; - + /** Maps value in range [0, m_Sum] into the range [0, m_MaxValue] using the stored probability */ int MapValue(int a_OrigValue) const; - + int GetSum(void) const { return m_Sum; } - + protected: int m_MaxValue; diff --git a/src/Protocol/Authenticator.cpp b/src/Protocol/Authenticator.cpp index 304486935..12e963143 100644 --- a/src/Protocol/Authenticator.cpp +++ b/src/Protocol/Authenticator.cpp @@ -194,7 +194,7 @@ bool cAuthenticator::AuthWithYggdrasil(AString & a_UserName, const AString & a_S a_UserName = root.get("name", "Unknown").asString(); a_UUID = cMojangAPI::MakeUUIDShort(root.get("id", "").asString()); a_Properties = root["properties"]; - + // Store the player's profile in the MojangAPI caches: cRoot::Get()->GetMojangAPI().AddPlayerProfile(a_UserName, a_UUID, a_Properties); diff --git a/src/Protocol/Authenticator.h b/src/Protocol/Authenticator.h index 845277569..a8c551fc7 100644 --- a/src/Protocol/Authenticator.h +++ b/src/Protocol/Authenticator.h @@ -50,7 +50,7 @@ public: /** Stops the authenticator thread. The thread may be started and stopped repeatedly */ void Stop(void); - + private: class cUser @@ -76,13 +76,13 @@ private: /** The server that is to be contacted for auth / UUID conversions */ AString m_Server; - + /** The URL to use for auth, without server part. %USERNAME% will be replaced with actual user name. %SERVERID% will be replaced with server's ID. For example "/session/minecraft/hasJoined?username=%USERNAME%&serverId=%SERVERID%". */ AString m_Address; - + AString m_PropertiesAddress; bool m_ShouldAuthenticate; diff --git a/src/Protocol/ChunkDataSerializer.cpp b/src/Protocol/ChunkDataSerializer.cpp index 8c5569cc7..848a6f597 100644 --- a/src/Protocol/ChunkDataSerializer.cpp +++ b/src/Protocol/ChunkDataSerializer.cpp @@ -39,14 +39,14 @@ const AString & cChunkDataSerializer::Serialize(int a_Version, int a_ChunkX, int { return itr->second; } - + AString data; switch (a_Version) { case RELEASE_1_3_2: Serialize39(data); break; case RELEASE_1_8_0: Serialize47(data, a_ChunkX, a_ChunkZ); break; // TODO: Other protocol versions may serialize the data differently; implement here - + default: { LOGERROR("cChunkDataSerializer::Serialize(): Unknown version: %d", a_Version); @@ -74,7 +74,7 @@ void cChunkDataSerializer::Serialize39(AString & a_Data) const int SkyLightOffset = BlockLightOffset + sizeof(m_BlockLight); const int BiomeOffset = SkyLightOffset + sizeof(m_BlockSkyLight); const int DataSize = BiomeOffset + BiomeDataSize; - + // Temporary buffer for the composed data: char AllData [DataSize]; @@ -91,29 +91,29 @@ void cChunkDataSerializer::Serialize39(AString & a_Data) char CompressedBlockData[CompressedMaxSize]; uLongf CompressedSize = compressBound(DataSize); - + // Run-time check that our compile-time guess about CompressedMaxSize was enough: ASSERT(CompressedSize <= CompressedMaxSize); - + compress2(reinterpret_cast(CompressedBlockData), &CompressedSize, reinterpret_cast(AllData), sizeof(AllData), Z_DEFAULT_COMPRESSION); // Now put all those data into a_Data: - + // "Ground-up continuous", or rather, "biome data present" flag: a_Data.push_back('\x01'); - + // Two bitmaps; we're aways sending the full chunk with no additional data, so the bitmaps are 0xffff and 0, respectively // Also, no endian flipping is needed because of the const values unsigned short BitMap1 = 0xffff; unsigned short BitMap2 = 0; a_Data.append(reinterpret_cast(&BitMap1), sizeof(short)); a_Data.append(reinterpret_cast(&BitMap2), sizeof(short)); - + UInt32 CompressedSizeBE = htonl(static_cast(CompressedSize)); a_Data.append(reinterpret_cast(&CompressedSizeBE), sizeof(CompressedSizeBE)); - + // Unlike 29, 39 doesn't have the "unused" int - + a_Data.append(CompressedBlockData, CompressedSize); } diff --git a/src/Protocol/ChunkDataSerializer.h b/src/Protocol/ChunkDataSerializer.h index 6acc1544b..823a93f15 100644 --- a/src/Protocol/ChunkDataSerializer.h +++ b/src/Protocol/ChunkDataSerializer.h @@ -17,21 +17,21 @@ protected: const cChunkDef::BlockNibbles & m_BlockLight; const cChunkDef::BlockNibbles & m_BlockSkyLight; const unsigned char * m_BiomeData; - + typedef std::map Serializations; - + Serializations m_Serializations; - + void Serialize39(AString & a_Data); // Release 1.3.1 to 1.7.10 void Serialize47(AString & a_Data, int a_ChunkX, int a_ChunkZ); // Release 1.8 - + public: enum { RELEASE_1_3_2 = 39, RELEASE_1_8_0 = 47, } ; - + cChunkDataSerializer( const cChunkDef::BlockTypes & a_BlockTypes, const cChunkDef::BlockNibbles & a_BlockMetas, diff --git a/src/Protocol/MojangAPI.h b/src/Protocol/MojangAPI.h index bea950740..65eb1b102 100644 --- a/src/Protocol/MojangAPI.h +++ b/src/Protocol/MojangAPI.h @@ -32,24 +32,24 @@ class cMojangAPI { public: // tolua_end - + cMojangAPI(void); ~cMojangAPI(); - + /** Initializes the API; reads the settings from the specified ini file. Loads cached results from disk. */ void Start(cSettingsRepositoryInterface & a_Settings, bool a_ShouldAuth); - + /** Connects to the specified server using SSL, sends the given request and receives the response. Checks Mojang certificates using the hard-coded Starfield root CA certificate. Returns true if all was successful, false on failure. */ static bool SecureRequest(const AString & a_ServerName, const AString & a_Request, AString & a_Response); - + /** Normalizes the given UUID to its short form (32 bytes, no dashes, lowercase). Logs a warning and returns empty string if not a UUID. Note: only checks the string's length, not the actual content. */ static AString MakeUUIDShort(const AString & a_UUID); - + /** Normalizes the given UUID to its dashed form (36 bytes, 4 dashes, lowercase). Logs a warning and returns empty string if not a UUID. Note: only checks the string's length, not the actual content. */ @@ -62,7 +62,7 @@ public: operation, do not use this in world-tick thread! If you have multiple names to resolve, use the GetUUIDsFromPlayerNames() function, it uses a single request for multiple names. */ AString GetUUIDFromPlayerName(const AString & a_PlayerName, bool a_UseOnlyCached = false); - + /** Converts a UUID into a playername. The returned playername will be empty on error. Both short and dashed UUID formats are accepted. @@ -71,7 +71,7 @@ public: If a_UseOnlyCached is false and the name is not found in the cache, it is looked up online, which is a blocking operation, do not use this in world-tick thread! */ AString GetPlayerNameFromUUID(const AString & a_UUID, bool a_UseOnlyCached = false); - + /** Converts the player names into UUIDs. a_PlayerName[idx] will be converted to UUID and returned as idx-th value The UUID will be empty on error. @@ -79,12 +79,12 @@ public: If a_UseOnlyCached is false, the names not found in the cache are looked up online, which is a blocking operation, do not use this in world-tick thread! */ AStringVector GetUUIDsFromPlayerNames(const AStringVector & a_PlayerName, bool a_UseOnlyCached = false); - + /** Called by the Authenticator to add a PlayerName -> UUID mapping that it has received from authenticating a user. This adds the cache item and "refreshes" it if existing, adjusting its datetime stamp to now. */ void AddPlayerNameToUUIDMapping(const AString & a_PlayerName, const AString & a_UUID); - + /** Called by the Authenticator to add a profile that it has received from authenticating a user. Adds the profile to the respective mapping caches and updtes their datetime stamp to now. */ void AddPlayerProfile(const AString & a_PlayerName, const AString & a_UUID, const Json::Value & a_Properties); @@ -105,7 +105,7 @@ protected: AString m_Textures; // The Textures field of the profile properties AString m_TexturesSignature; // The signature of the Textures field of the profile properties Int64 m_DateTime; // UNIXtime of the profile lookup - + /** Default constructor for the container's sake. */ sProfile(void) : m_PlayerName(), @@ -115,7 +115,7 @@ protected: m_DateTime(time(nullptr)) { } - + /** Constructor for the storage creation. */ sProfile( const AString & a_PlayerName, @@ -131,7 +131,7 @@ protected: m_DateTime(a_DateTime) { } - + /** Constructor that parses the values from the Json profile. */ sProfile( const AString & a_PlayerName, @@ -142,37 +142,37 @@ protected: }; typedef std::map cProfileMap; - + /** The server to connect to when converting player names to UUIDs. For example "api.mojang.com". */ AString m_NameToUUIDServer; - + /** The URL to use for converting player names to UUIDs, without server part. For example "/profiles/page/1". */ AString m_NameToUUIDAddress; - + /** The server to connect to when converting UUID to profile. For example "sessionserver.mojang.com". */ AString m_UUIDToProfileServer; - + /** The URL to use for converting UUID to profile, without the server part. Will replace %UUID% with the actual UUID. For example "session/minecraft/profile/%UUID%?unsigned=false". */ AString m_UUIDToProfileAddress; - + /** Cache for the Name-to-UUID lookups. The map key is lowercased PlayerName. Protected by m_CSNameToUUID. */ cProfileMap m_NameToUUID; - + /** Protects m_NameToUUID against simultaneous multi-threaded access. */ cCriticalSection m_CSNameToUUID; - + /** Cache for the Name-to-UUID lookups. The map key is lowercased short UUID. Protected by m_CSUUIDToName. */ cProfileMap m_UUIDToName; - + /** Protects m_UUIDToName against simultaneous multi-threaded access. */ cCriticalSection m_CSUUIDToName; - + /** Cache for the UUID-to-profile lookups. The map key is lowercased short UUID. Protected by m_CSUUIDToProfile. */ cProfileMap m_UUIDToProfile; - + /** Protects m_UUIDToProfile against simultaneous multi-threaded access. */ cCriticalSection m_CSUUIDToProfile; @@ -184,14 +184,14 @@ protected: /** The thread that periodically updates the stale data in the DB from the Mojang servers. */ SharedPtr m_UpdateThread; - - + + /** Loads the caches from a disk storage. */ void LoadCachesFromDisk(void); - + /** Saves the caches to a disk storage. */ void SaveCachesToDisk(void); - + /** Makes sure all specified names are in the m_PlayerNameToUUID cache. Downloads any missing ones from Mojang API servers. Names that are not valid are not added into the cache. ASSUMEs that a_PlayerNames contains lowercased player names. */ @@ -202,7 +202,7 @@ protected: ASSUMEs that a_PlayerNames contans lowercased player names. For performance reasons takes a non-const reference and modifies the list given to it, until empty. */ void QueryNamesToUUIDs(AStringVector & a_PlayerNames); - + /** Makes sure the specified UUID is in the m_UUIDToProfile cache. If missing, downloads it from Mojang API servers. UUIDs that are not valid will not be added into the cache. ASSUMEs that a_UUID is a lowercased short UUID. */ diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index af0485a78..62faf0b28 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -59,10 +59,10 @@ public: } virtual ~cProtocol() {} - + /** Called when client sends some data */ virtual void DataReceived(const char * a_Data, size_t a_Size) = 0; - + // Sending stuff to clients (alphabetically sorted): virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) = 0; virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) = 0; @@ -160,10 +160,10 @@ protected: /** Buffer for composing the outgoing packets, through cPacketizer */ cByteBuffer m_OutPacketBuffer; - + /** Buffer for composing packet length (so that each cPacketizer instance doesn't allocate a new cPacketBuffer) */ cByteBuffer m_OutPacketLenBuffer; - + /** A generic data-sending routine, all outgoing packet data needs to be routed through this so that descendants may override it. */ virtual void SendData(const char * a_Data, size_t a_Size) = 0; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 1c8c81bbd..69b87e4d1 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -121,7 +121,7 @@ cProtocol172::cProtocol172(cClientHandle * a_Client, const AString & a_ServerAdd m_Client->SetUUID(cMojangAPI::MakeUUIDShort(Params[2])); m_Client->SetProperties(Params[3]); } - + // Create the comm log file, if so requested: if (g_ShouldLogCommIn || g_ShouldLogCommOut) { @@ -163,7 +163,7 @@ void cProtocol172::DataReceived(const char * a_Data, size_t a_Size) void cProtocol172::SendAttachEntity(const cEntity & a_Entity, const cEntity * a_Vehicle) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x1b); // Attach Entity packet Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); Pkt.WriteBEUInt32((a_Vehicle != nullptr) ? a_Vehicle->GetUniqueID() : 0); @@ -177,7 +177,7 @@ void cProtocol172::SendAttachEntity(const cEntity & a_Entity, const cEntity * a_ void cProtocol172::SendBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x24); // Block Action packet Pkt.WriteBEInt32(a_BlockX); Pkt.WriteBEInt16(static_cast(a_BlockY)); @@ -194,7 +194,7 @@ void cProtocol172::SendBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, cha void cProtocol172::SendBlockBreakAnim(UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x25); // Block Break Animation packet Pkt.WriteVarInt32(a_EntityID); Pkt.WriteBEInt32(a_BlockX); @@ -211,7 +211,7 @@ void cProtocol172::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLO { ASSERT(m_State == 3); // In game mode? ASSERT((a_BlockY >= 0) && (a_BlockY < 256)); - + cPacketizer Pkt(*this, 0x23); // Block Change packet Pkt.WriteBEInt32(a_BlockX); Pkt.WriteBEUInt8(static_cast(a_BlockY)); @@ -227,7 +227,7 @@ void cProtocol172::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLO void cProtocol172::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x22); // Multi Block Change packet Pkt.WriteBEInt32(a_ChunkX); Pkt.WriteBEInt32(a_ChunkZ); @@ -283,11 +283,11 @@ void cProtocol172::SendChat(const cCompositeChat & a_Message, eChatType a_Type, void cProtocol172::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) { ASSERT(m_State == 3); // In game mode? - + // Serialize first, before creating the Packetizer (the packetizer locks a CS) // This contains the flags and bitmasks, too const AString & ChunkData = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_3_2, a_ChunkX, a_ChunkZ); - + cPacketizer Pkt(*this, 0x21); // Chunk Data packet Pkt.WriteBEInt32(a_ChunkX); Pkt.WriteBEInt32(a_ChunkZ); @@ -301,7 +301,7 @@ void cProtocol172::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerialize void cProtocol172::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x0d); // Collect Item packet Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); Pkt.WriteBEUInt32(a_Player.GetUniqueID()); @@ -314,7 +314,7 @@ void cProtocol172::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a void cProtocol172::SendDestroyEntity(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x13); // Destroy Entities packet Pkt.WriteBEUInt8(1); Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); @@ -352,7 +352,7 @@ void cProtocol172::SendDisconnect(const AString & a_Reason) void cProtocol172::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x36); // Sign Editor Open packet Pkt.WriteBEInt32(a_BlockX); Pkt.WriteBEInt32(a_BlockY); @@ -368,7 +368,7 @@ void cProtocol172::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, in ASSERT(m_State == 3); // In game mode? ASSERT((a_EffectID >= 0) && (a_EffectID < 256)); ASSERT((a_Amplifier >= 0) && (a_Amplifier < 256)); - + cPacketizer Pkt(*this, 0x1D); // Entity Effect packet Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); Pkt.WriteBEUInt8(static_cast(a_EffectID)); @@ -383,7 +383,7 @@ void cProtocol172::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, in void cProtocol172::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x04); // Entity Equipment packet Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); Pkt.WriteBEInt16(a_SlotNum); @@ -397,7 +397,7 @@ void cProtocol172::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum void cProtocol172::SendEntityHeadLook(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x19); // Entity Head Look packet Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); Pkt.WriteByteAngle(a_Entity.GetHeadYaw()); @@ -410,7 +410,7 @@ void cProtocol172::SendEntityHeadLook(const cEntity & a_Entity) void cProtocol172::SendEntityLook(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x16); // Entity Look packet Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); Pkt.WriteByteAngle(a_Entity.GetYaw()); @@ -424,7 +424,7 @@ void cProtocol172::SendEntityLook(const cEntity & a_Entity) void cProtocol172::SendEntityMetadata(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x1c); // Entity Metadata packet Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); WriteEntityMetadata(Pkt, a_Entity); @@ -438,7 +438,7 @@ void cProtocol172::SendEntityMetadata(const cEntity & a_Entity) void cProtocol172::SendEntityProperties(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x20); // Entity Properties packet Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); WriteEntityProperties(Pkt, a_Entity); @@ -451,7 +451,7 @@ void cProtocol172::SendEntityProperties(const cEntity & a_Entity) void cProtocol172::SendEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x15); // Entity Relative Move packet Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); Pkt.WriteBEInt8(a_RelX); @@ -466,7 +466,7 @@ void cProtocol172::SendEntityRelMove(const cEntity & a_Entity, char a_RelX, char void cProtocol172::SendEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x17); // Entity Look And Relative Move packet Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); Pkt.WriteBEInt8(a_RelX); @@ -483,7 +483,7 @@ void cProtocol172::SendEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, void cProtocol172::SendEntityStatus(const cEntity & a_Entity, char a_Status) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x1a); // Entity Status packet Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); Pkt.WriteBEInt8(a_Status); @@ -496,7 +496,7 @@ void cProtocol172::SendEntityStatus(const cEntity & a_Entity, char a_Status) void cProtocol172::SendEntityVelocity(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x12); // Entity Velocity packet Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); // 400 = 8000 / 20 ... Conversion from our speed in m / s to 8000 m / tick @@ -512,7 +512,7 @@ void cProtocol172::SendEntityVelocity(const cEntity & a_Entity) void cProtocol172::SendExplosion(double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x27); // Explosion packet Pkt.WriteBEFloat(static_cast(a_BlockX)); Pkt.WriteBEFloat(static_cast(a_BlockY)); @@ -537,7 +537,7 @@ void cProtocol172::SendExplosion(double a_BlockX, double a_BlockY, double a_Bloc void cProtocol172::SendGameMode(eGameMode a_GameMode) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x2b); // Change Game State packet Pkt.WriteBEUInt8(3); // Reason: Change game mode Pkt.WriteBEFloat(static_cast(a_GameMode)); // The protocol really represents the value with a float! @@ -550,7 +550,7 @@ void cProtocol172::SendGameMode(eGameMode a_GameMode) void cProtocol172::SendHealth(void) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x06); // Update Health packet cPlayer * Player = m_Client->GetPlayer(); Pkt.WriteBEFloat(static_cast(Player->GetHealth())); @@ -574,7 +574,7 @@ void cProtocol172::SendHideTitle(void) void cProtocol172::SendInventorySlot(char a_WindowID, short a_SlotNum, const cItem & a_Item) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x2f); // Set Slot packet Pkt.WriteBEInt8(a_WindowID); Pkt.WriteBEInt16(a_SlotNum); @@ -593,7 +593,7 @@ void cProtocol172::SendKeepAlive(UInt32 a_PingID) LOGWARNING("Trying to send a KeepAlive packet to a player who's not yet fully logged in (%d). The protocol class prevented the packet.", m_State); return; } - + cPacketizer Pkt(*this, 0x00); // Keep Alive packet Pkt.WriteBEUInt32(a_PingID); } @@ -616,7 +616,7 @@ void cProtocol172::SendLogin(const cPlayer & a_Player, const cWorld & a_World) Pkt.WriteString("default"); // Level type - wtf? } m_LastSentDimension = a_World.GetDimension(); - + // Send the spawn position: { cPacketizer Pkt(*this, 0x05); // Spawn Position packet @@ -624,7 +624,7 @@ void cProtocol172::SendLogin(const cPlayer & a_Player, const cWorld & a_World) Pkt.WriteBEInt32(static_cast(a_World.GetSpawnY())); Pkt.WriteBEInt32(static_cast(a_World.GetSpawnZ())); } - + // Send player abilities: SendPlayerAbilities(); } @@ -635,7 +635,7 @@ void cProtocol172::SendLogin(const cPlayer & a_Player, const cWorld & a_World) void cProtocol172::SendLoginSuccess(void) { ASSERT(m_State == 2); // State: login? - + { cPacketizer Pkt(*this, 0x02); // Login success packet Pkt.WriteString(cMojangAPI::MakeUUIDDashed(m_Client->GetUUID())); @@ -652,7 +652,7 @@ void cProtocol172::SendLoginSuccess(void) void cProtocol172::SendPaintingSpawn(const cPainting & a_Painting) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x10); // Spawn Painting packet Pkt.WriteVarInt32(a_Painting.GetUniqueID()); Pkt.WriteString(a_Painting.GetName().c_str()); @@ -724,7 +724,7 @@ void cProtocol172::SendMapData(const cMap & a_Map, int a_DataStartX, int a_DataS void cProtocol172::SendPickupSpawn(const cPickup & a_Pickup) { ASSERT(m_State == 3); // In game mode? - + { cPacketizer Pkt(*this, 0x0e); // Spawn Object packet Pkt.WriteVarInt32(a_Pickup.GetUniqueID()); @@ -752,7 +752,7 @@ void cProtocol172::SendPickupSpawn(const cPickup & a_Pickup) void cProtocol172::SendPlayerAbilities(void) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x39); // Player Abilities packet Byte Flags = 0; cPlayer * Player = m_Client->GetPlayer(); @@ -781,7 +781,7 @@ void cProtocol172::SendPlayerAbilities(void) void cProtocol172::SendEntityAnimation(const cEntity & a_Entity, char a_Animation) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x0b); // Animation packet Pkt.WriteVarInt32(a_Entity.GetUniqueID()); Pkt.WriteBEInt8(a_Animation); @@ -794,7 +794,7 @@ void cProtocol172::SendEntityAnimation(const cEntity & a_Entity, char a_Animatio void cProtocol172::SendParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x2A); Pkt.WriteString(a_ParticleName); Pkt.WriteBEFloat(a_SrcX); @@ -883,7 +883,7 @@ void cProtocol172::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, con void cProtocol172::SendPlayerMaxSpeed(void) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x20); // Entity Properties cPlayer * Player = m_Client->GetPlayer(); Pkt.WriteBEUInt32(Player->GetUniqueID()); @@ -912,15 +912,15 @@ void cProtocol172::SendPlayerMaxSpeed(void) void cProtocol172::SendPlayerMoveLook(void) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x08); // Player Position And Look packet cPlayer * Player = m_Client->GetPlayer(); Pkt.WriteBEDouble(Player->GetPosX()); - + // Protocol docs say this is PosY, but #323 says this is eye-pos // Moreover, the "+ 0.001" is there because otherwise the player falls through the block they were standing on. Pkt.WriteBEDouble(Player->GetStance() + 0.001); - + Pkt.WriteBEDouble(Player->GetPosZ()); Pkt.WriteBEFloat(static_cast(Player->GetYaw())); Pkt.WriteBEFloat(static_cast(Player->GetPitch())); @@ -944,7 +944,7 @@ void cProtocol172::SendPlayerPosition(void) void cProtocol172::SendPlayerSpawn(const cPlayer & a_Player) { ASSERT(m_State == 3); // In game mode? - + // Called to spawn another player for the client cPacketizer Pkt(*this, 0x0c); // Spawn Player packet Pkt.WriteVarInt32(a_Player.GetUniqueID()); @@ -977,7 +977,7 @@ void cProtocol172::SendPluginMessage(const AString & a_Channel, const AString & { ASSERT(m_State == 3); // In game mode? ASSERT(a_Message.size() <= std::numeric_limits::max()); - + cPacketizer Pkt(*this, 0x3f); Pkt.WriteString(a_Channel); Pkt.WriteBEUInt16(static_cast(a_Message.size())); @@ -992,7 +992,7 @@ void cProtocol172::SendRemoveEntityEffect(const cEntity & a_Entity, int a_Effect { ASSERT(m_State == 3); // In game mode? ASSERT((a_EffectID >= 0) && (a_EffectID < 256)); - + cPacketizer Pkt(*this, 0x1e); Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); Pkt.WriteBEUInt8(static_cast(a_EffectID)); @@ -1035,7 +1035,7 @@ void cProtocol172::SendRespawn(eDimension a_Dimension, bool a_ShouldIgnoreDimens void cProtocol172::SendExperience (void) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x1f); // Experience Packet cPlayer * Player = m_Client->GetPlayer(); Pkt.WriteBEFloat(Player->GetXpPercentage()); @@ -1051,7 +1051,7 @@ void cProtocol172::SendExperienceOrb(const cExpOrb & a_ExpOrb) { ASSERT(m_State == 3); // In game mode? ASSERT((a_ExpOrb.GetReward() >= 0) && (a_ExpOrb.GetReward() < SHRT_MAX)); - + cPacketizer Pkt(*this, 0x11); Pkt.WriteVarInt32(a_ExpOrb.GetUniqueID()); Pkt.WriteFPInt(a_ExpOrb.GetPosX()); @@ -1067,7 +1067,7 @@ void cProtocol172::SendExperienceOrb(const cExpOrb & a_ExpOrb) void cProtocol172::SendScoreboardObjective(const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x3b); Pkt.WriteString(a_Name); Pkt.WriteString(a_DisplayName); @@ -1081,7 +1081,7 @@ void cProtocol172::SendScoreboardObjective(const AString & a_Name, const AString void cProtocol172::SendScoreUpdate(const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x3c); Pkt.WriteString(a_Player); Pkt.WriteBEUInt8(a_Mode); @@ -1100,7 +1100,7 @@ void cProtocol172::SendScoreUpdate(const AString & a_Objective, const AString & void cProtocol172::SendDisplayObjective(const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x3d); Pkt.WriteBEUInt8(static_cast(a_Display)); Pkt.WriteString(a_Objective); @@ -1167,7 +1167,7 @@ void cProtocol172::SendSoundParticleEffect(const EffectID a_EffectID, int a_SrcX { ASSERT(m_State == 3); // In game mode? ASSERT((a_SrcY >= 0) && (a_SrcY < 256)); - + cPacketizer Pkt(*this, 0x28); // Effect packet Pkt.WriteBEInt32(static_cast(a_EffectID)); Pkt.WriteBEInt32(a_SrcX); @@ -1184,7 +1184,7 @@ void cProtocol172::SendSoundParticleEffect(const EffectID a_EffectID, int a_SrcX void cProtocol172::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x0e); // Spawn Object packet Pkt.WriteVarInt32(a_FallingBlock.GetUniqueID()); Pkt.WriteBEUInt8(70); // Falling block @@ -1206,7 +1206,7 @@ void cProtocol172::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock) void cProtocol172::SendSpawnMob(const cMonster & a_Mob) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x0f); // Spawn Mob packet Pkt.WriteVarInt32(a_Mob.GetUniqueID()); Pkt.WriteBEUInt8(static_cast(a_Mob.GetMobType())); @@ -1230,7 +1230,7 @@ void cProtocol172::SendSpawnMob(const cMonster & a_Mob) void cProtocol172::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0xe); // Spawn Object packet Pkt.WriteVarInt32(a_Entity.GetUniqueID()); Pkt.WriteBEInt8(a_ObjectType); @@ -1255,7 +1255,7 @@ void cProtocol172::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, void cProtocol172::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0xe); // Spawn Object packet Pkt.WriteVarInt32(a_Vehicle.GetUniqueID()); Pkt.WriteBEInt8(a_VehicleType); @@ -1280,7 +1280,7 @@ void cProtocol172::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleTyp void cProtocol172::SendStatistics(const cStatManager & a_Manager) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x37); Pkt.WriteVarInt32(statCount); // TODO 2014-05-11 xdot: Optimization: Send "dirty" statistics only @@ -1302,7 +1302,7 @@ void cProtocol172::SendStatistics(const cStatManager & a_Manager) void cProtocol172::SendTabCompletionResults(const AStringVector & a_Results) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x3a); // Tab-Complete packet Pkt.WriteVarInt32(static_cast(a_Results.size())); @@ -1319,7 +1319,7 @@ void cProtocol172::SendTabCompletionResults(const AStringVector & a_Results) void cProtocol172::SendTeleportEntity(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x18); Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); Pkt.WriteFPInt(a_Entity.GetPosX()); @@ -1336,7 +1336,7 @@ void cProtocol172::SendTeleportEntity(const cEntity & a_Entity) void cProtocol172::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x2c); // Spawn Global Entity packet Pkt.WriteVarInt32(0); // EntityID = 0, always Pkt.WriteBEUInt8(1); // Type = Thunderbolt @@ -1366,7 +1366,7 @@ void cProtocol172::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_Do // When writing a "-" before the number the client ignores it but it will stop the client-side time expiration. a_TimeOfDay = std::min(-a_TimeOfDay, -1LL); } - + cPacketizer Pkt(*this, 0x03); Pkt.WriteBEInt64(a_WorldAge); Pkt.WriteBEInt64(a_TimeOfDay); @@ -1379,7 +1379,7 @@ void cProtocol172::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_Do void cProtocol172::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x21); // Chunk Data packet Pkt.WriteBEInt32(a_ChunkX); Pkt.WriteBEInt32(a_ChunkZ); @@ -1395,7 +1395,7 @@ void cProtocol172::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) void cProtocol172::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x35); // Update tile entity packet Pkt.WriteBEInt32(a_BlockEntity.GetPosX()); Pkt.WriteBEInt16(static_cast(a_BlockEntity.GetPosY())); @@ -1424,7 +1424,7 @@ void cProtocol172::SendUpdateSign(int a_BlockX, int a_BlockY, int a_BlockZ, cons { ASSERT(m_State == 3); // In game mode? ASSERT((a_BlockY >= 0) && (a_BlockY < cChunkDef::Height)); - + cPacketizer Pkt(*this, 0x33); Pkt.WriteBEInt32(a_BlockX); Pkt.WriteBEInt16(static_cast(a_BlockY)); @@ -1444,7 +1444,7 @@ void cProtocol172::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_Bloc { ASSERT(m_State == 3); // In game mode? ASSERT((a_BlockY >= 0) && (a_BlockY < cChunkDef::Height)); - + cPacketizer Pkt(*this, 0x0a); Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); Pkt.WriteBEInt32(a_BlockX); @@ -1459,7 +1459,7 @@ void cProtocol172::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_Bloc void cProtocol172::SendWeather(eWeather a_Weather) { ASSERT(m_State == 3); // In game mode? - + { cPacketizer Pkt(*this, 0x2b); // Change Game State packet Pkt.WriteBEUInt8((a_Weather == wSunny) ? 1 : 2); // End rain / begin rain @@ -1476,7 +1476,7 @@ void cProtocol172::SendWeather(eWeather a_Weather) void cProtocol172::SendWholeInventory(const cWindow & a_Window) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x30); // Window Items packet Pkt.WriteBEInt8(a_Window.GetWindowID()); Pkt.WriteBEInt16(static_cast(a_Window.GetNumSlots())); @@ -1495,7 +1495,7 @@ void cProtocol172::SendWholeInventory(const cWindow & a_Window) void cProtocol172::SendWindowClose(const cWindow & a_Window) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x2e); Pkt.WriteBEInt8(a_Window.GetWindowID()); } @@ -1507,13 +1507,13 @@ void cProtocol172::SendWindowClose(const cWindow & a_Window) void cProtocol172::SendWindowOpen(const cWindow & a_Window) { ASSERT(m_State == 3); // In game mode? - + if (a_Window.GetWindowType() < 0) { // Do not send this packet for player inventory windows return; } - + cPacketizer Pkt(*this, 0x2d); Pkt.WriteBEInt8(a_Window.GetWindowID()); Pkt.WriteBEInt8(static_cast(a_Window.GetWindowType())); @@ -1533,7 +1533,7 @@ void cProtocol172::SendWindowOpen(const cWindow & a_Window) void cProtocol172::SendWindowProperty(const cWindow & a_Window, short a_Property, short a_Value) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x31); // Window Property packet Pkt.WriteBEInt8(a_Window.GetWindowID()); Pkt.WriteBEInt16(a_Property); @@ -1607,7 +1607,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size) // Write one NUL extra, so that we can detect over-reads bb.Write("\0", 1); - + // Log the packet info into the comm log file: if (g_ShouldLogCommIn) { @@ -1628,7 +1628,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size) { // Unknown packet, already been reported, but without the length. Log the length here: LOGWARNING("Unhandled packet: type 0x%x, state %d, length %u", PacketType, m_State, PacketLen); - + #ifdef _DEBUG // Dump the packet contents into the log: bb.ResetRead(); @@ -1639,13 +1639,13 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size) CreateHexDump(Out, Packet.data(), Packet.size(), 24); LOGD("Packet contents:\n%s", Out.c_str()); #endif // _DEBUG - + // Put a message in the comm log: if (g_ShouldLogCommIn) { m_CommLogFile.Printf("^^^^^^ Unhandled packet ^^^^^^\n\n\n"); } - + return; } @@ -1705,7 +1705,7 @@ bool cProtocol172::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) } break; } - + case 2: { // Login @@ -1716,7 +1716,7 @@ bool cProtocol172::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) } break; } - + case 3: { // Game @@ -1753,9 +1753,9 @@ bool cProtocol172::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) { // Received a packet in an unknown state, report: LOGWARNING("Received a packet in an unknown protocol state %d. Ignoring further packets.", m_State); - + // Cannot kick the client - we don't know this state and thus the packet number for the kick packet - + // Switch to a state when all further packets are silently ignored: m_State = 255; return false; @@ -1767,7 +1767,7 @@ bool cProtocol172::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) return false; } } // switch (m_State) - + // Unknown packet type, report to the ClientHandle: m_Client->PacketUnknown(a_PacketType); return false; @@ -1887,7 +1887,7 @@ void cProtocol172::HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffe m_Client->Kick("Hacked client"); return; } - + // Decrypt the symmetric encryption key using privkey: Byte DecryptedKey[MAX_ENC_LEN]; res = rsaDecryptor.Decrypt( @@ -1900,7 +1900,7 @@ void cProtocol172::HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffe m_Client->Kick("Hacked client"); return; } - + StartEncryption(DecryptedKey); m_Client->HandleLogin(4, m_Client->GetUsername()); } @@ -1917,13 +1917,13 @@ void cProtocol172::HandlePacketLoginStart(cByteBuffer & a_ByteBuffer) m_Client->Kick("Bad username"); return; } - + if (!m_Client->HandleHandshake(Username)) { // The client is not welcome here, they have been sent a Kick packet already return; } - + cServer * Server = cRoot::Get()->GetServer(); // If auth is required, then send the encryption request: if (Server->ShouldAuthenticate()) @@ -1938,7 +1938,7 @@ void cProtocol172::HandlePacketLoginStart(cByteBuffer & a_ByteBuffer) m_Client->SetUsername(Username); return; } - + m_Client->HandleLogin(4, Username); } @@ -2008,7 +2008,7 @@ void cProtocol172::HandlePacketClientSettings(cByteBuffer & a_ByteBuffer) HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, ChatColors); HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Difficulty); HANDLE_READ(a_ByteBuffer, ReadBool, bool, ShowCape); - + m_Client->SetLocale(Locale); m_Client->SetViewDistance(ViewDistance); // TODO: Do anything with the other values. @@ -2182,14 +2182,14 @@ void cProtocol172::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) ); return; } - + // If the plugin channel is recognized vanilla, handle it directly: if (Channel.substr(0, 3) == "MC|") { HandleVanillaPluginMessage(a_ByteBuffer, Channel, Length); return; } - + // Read the plugin message and relay to clienthandle: AString Data; if (!a_ByteBuffer.ReadString(Data, Length)) @@ -2364,7 +2364,7 @@ void cProtocol172::HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const } // TODO: Entity-based commandblock update - + default: { m_Client->SendChat(Printf("Failure setting command block command; unhandled mode %d", Mode), mtFailure); @@ -2392,7 +2392,7 @@ void cProtocol172::HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const { m_Client->SetClientBrand(Brand); } - + // Send back our brand: SendPluginMessage("MC|Brand", "Cuberite"); return; @@ -2420,7 +2420,7 @@ void cProtocol172::HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const return; } LOG("Unhandled vanilla plugin channel: \"%s\".", a_Channel.c_str()); - + // Read the payload and send it through to the clienthandle: AString Message; VERIFY(a_ByteBuffer.ReadString(Message, a_PayloadLength)); @@ -2466,12 +2466,12 @@ void cProtocol172::SendPacket(cPacketizer & a_Packet) m_OutPacketLenBuffer.ReadAll(DataToSend); SendData(DataToSend.data(), DataToSend.size()); m_OutPacketLenBuffer.CommitRead(); - + // Send the packet data: m_OutPacketBuffer.ReadAll(DataToSend); SendData(DataToSend.data(), DataToSend.size()); m_OutPacketBuffer.CommitRead(); - + // Log the comm into logfile: if (g_ShouldLogCommOut) { @@ -2498,7 +2498,7 @@ bool cProtocol172::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item) return true; } a_Item.m_ItemType = ItemType; - + HANDLE_PACKET_READ(a_ByteBuffer, ReadBEInt8, Int8, ItemCount); HANDLE_PACKET_READ(a_ByteBuffer, ReadBEInt16, Int16, ItemDamage); a_Item.m_ItemCount = ItemCount; @@ -2515,7 +2515,7 @@ bool cProtocol172::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item) { return false; } - + ParseItemMetadata(a_Item, Metadata); return true; } @@ -2535,7 +2535,7 @@ void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata) LOGWARNING("Cannot unGZIP item metadata (" SIZE_T_FMT " bytes):\n%s", a_Metadata.size(), HexDump.c_str()); return; } - + // Parse into NBT: cParsedNBT NBT(Uncompressed.data(), Uncompressed.size()); if (!NBT.IsValid()) @@ -2545,7 +2545,7 @@ void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata) LOGWARNING("Cannot parse NBT item metadata: (" SIZE_T_FMT " bytes)\n%s", Uncompressed.size(), HexDump.c_str()); return; } - + // Load enchantments and custom display names from the NBT data: for (int tag = NBT.GetFirstChild(NBT.GetRoot()); tag >= 0; tag = NBT.GetNextSibling(tag)) { @@ -2614,7 +2614,7 @@ void cProtocol172::StartEncryption(const Byte * a_Key) m_Encryptor.Init(a_Key, a_Key); m_Decryptor.Init(a_Key, a_Key); m_IsEncrypted = true; - + // Prepare the m_AuthServerID: cSha1Checksum Checksum; cServer * Server = cRoot::Get()->GetServer(); @@ -2660,17 +2660,17 @@ void cProtocol172::WriteItem(cPacketizer & a_Pkt, const cItem & a_Item) // Fix, to make sure no invalid values are sent. ItemType = -1; } - + if (a_Item.IsEmpty()) { a_Pkt.WriteBEInt16(-1); return; } - + a_Pkt.WriteBEInt16(ItemType); a_Pkt.WriteBEInt8(a_Item.m_ItemCount); a_Pkt.WriteBEInt16(a_Item.m_ItemDamage); - + if (a_Item.m_Enchantments.IsEmpty() && a_Item.IsBothNameAndLoreEmpty() && (a_Item.m_ItemType != E_ITEM_FIREWORK_ROCKET) && (a_Item.m_ItemType != E_ITEM_FIREWORK_STAR) && !a_Item.m_ItemColor.IsValid()) { a_Pkt.WriteBEInt16(-1); @@ -2857,7 +2857,7 @@ void cProtocol172::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_En } a_Pkt.WriteBEUInt8(0); // Byte(0) + index 0 a_Pkt.WriteBEUInt8(Flags); - + switch (a_Entity.GetEntityType()) { case cEntity::etPlayer: break; // TODO? @@ -2884,7 +2884,7 @@ void cProtocol172::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_En a_Pkt.WriteBEInt32(1); // Shaking direction, doesn't seem to affect anything a_Pkt.WriteBEUInt8(0x73); a_Pkt.WriteBEFloat(static_cast(Minecart.LastDamage() + 10)); // Damage taken / shake effect multiplyer - + if (Minecart.GetPayload() == cMinecart::mpNone) { auto & RideableMinecart = reinterpret_cast(Minecart); @@ -2981,7 +2981,7 @@ void cProtocol172::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) a_Pkt.WriteBEUInt8(reinterpret_cast(a_Mob).IsHanging() ? 1 : 0); break; } // case mtBat - + case mtCreeper: { a_Pkt.WriteBEUInt8(0x10); @@ -2990,7 +2990,7 @@ void cProtocol172::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) a_Pkt.WriteBEUInt8(reinterpret_cast(a_Mob).IsCharged() ? 1 : 0); break; } // case mtCreeper - + case mtEnderman: { auto & Enderman = reinterpret_cast(a_Mob); @@ -3002,14 +3002,14 @@ void cProtocol172::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) a_Pkt.WriteBEUInt8(Enderman.IsScreaming() ? 1 : 0); break; } // case mtEnderman - + case mtGhast: { a_Pkt.WriteBEUInt8(0x10); a_Pkt.WriteBEUInt8(reinterpret_cast(a_Mob).IsCharging()); break; } // case mtGhast - + case mtHorse: { auto & Horse = reinterpret_cast(a_Mob); @@ -3062,14 +3062,14 @@ void cProtocol172::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) a_Pkt.WriteBEUInt8(static_cast(reinterpret_cast(a_Mob).GetSize())); break; } // case mtMagmaCube - + case mtPig: { a_Pkt.WriteBEUInt8(0x10); a_Pkt.WriteBEUInt8(reinterpret_cast(a_Mob).IsSaddled() ? 1 : 0); break; } // case mtPig - + case mtSheep: { a_Pkt.WriteBEUInt8(0x10); @@ -3082,28 +3082,28 @@ void cProtocol172::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) a_Pkt.WriteBEUInt8(SheepMetadata); break; } // case mtSheep - + case mtSkeleton: { a_Pkt.WriteBEUInt8(0x0d); a_Pkt.WriteBEUInt8(reinterpret_cast(a_Mob).IsWither() ? 1 : 0); break; } // case mtSkeleton - + case mtSlime: { a_Pkt.WriteBEUInt8(0x10); a_Pkt.WriteBEUInt8(static_cast(reinterpret_cast(a_Mob).GetSize())); break; } // case mtSlime - + case mtVillager: { a_Pkt.WriteBEUInt8(0x50); a_Pkt.WriteBEInt32(reinterpret_cast(a_Mob).GetVilType()); break; } // case mtVillager - + case mtWitch: { a_Pkt.WriteBEUInt8(0x15); @@ -3119,7 +3119,7 @@ void cProtocol172::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) a_Pkt.WriteBEFloat(static_cast(a_Mob.GetHealth())); break; } // case mtWither - + case mtWolf: { auto & Wolf = reinterpret_cast(a_Mob); @@ -3147,7 +3147,7 @@ void cProtocol172::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) a_Pkt.WriteBEUInt8(static_cast(Wolf.GetCollarColor())); break; } // case mtWolf - + case mtZombie: { auto & Zombie = reinterpret_cast(a_Mob); @@ -3184,7 +3184,7 @@ void cProtocol172::WriteEntityProperties(cPacketizer & a_Pkt, const cEntity & a_ // auto & Mob = reinterpret_cast(a_Entity); // TODO: Send properties and modifiers based on the mob type - + a_Pkt.WriteBEInt32(0); // NumProperties } diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index 747ffe186..24d8f8898 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -52,11 +52,11 @@ class cProtocol172 : public cProtocol { typedef cProtocol super; - + public: cProtocol172(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State); - + /** Called when client sends some data: */ virtual void DataReceived(const char * a_Data, size_t a_Size) override; @@ -147,30 +147,30 @@ public: protected: AString m_ServerAddress; - + UInt16 m_ServerPort; - + AString m_AuthServerID; - + /** State of the protocol. 1 = status, 2 = login, 3 = game */ UInt32 m_State; /** Buffer for the received data */ cByteBuffer m_ReceivedData; - + bool m_IsEncrypted; - + cAesCfb128Decryptor m_Decryptor; cAesCfb128Encryptor m_Encryptor; /** The logfile where the comm is logged, when g_ShouldLogComm is true */ cFile m_CommLogFile; - + /** The dimension that was last sent to a player in a Respawn or Login packet. Used to avoid Respawning into the same dimension, which confuses the client. */ eDimension m_LastSentDimension; - - + + /** Adds the received (unencrypted) data to m_ReceivedData, parses complete packets */ void AddReceivedData(const char * a_Data, size_t a_Size); @@ -186,7 +186,7 @@ protected: // Packet handlers while in the Login state (m_State == 2): void HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer); void HandlePacketLoginStart(cByteBuffer & a_ByteBuffer); - + // Packet handlers while in the Game state (m_State == 3): void HandlePacketAnimation (cByteBuffer & a_ByteBuffer); void HandlePacketBlockDig (cByteBuffer & a_ByteBuffer); @@ -211,11 +211,11 @@ protected: void HandlePacketEnchantItem (cByteBuffer & a_ByteBuffer); void HandlePacketWindowClick (cByteBuffer & a_ByteBuffer); void HandlePacketWindowClose (cByteBuffer & a_ByteBuffer); - + /** Parses Vanilla plugin messages into specific ClientHandle calls. The message payload is still in the bytebuffer, to be read by this function. */ void HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const AString & a_Channel, UInt16 a_PayloadLength); - + /** Sends the data to the client, encrypting them if needed. */ virtual void SendData(const char * a_Data, size_t a_Size) override; @@ -223,13 +223,13 @@ protected: virtual void SendPacket(cPacketizer & a_Packet) override; void SendCompass(const cWorld & a_World); - + /** Reads an item out of the received data, sets a_Item to the values read. Returns false if not enough received data */ virtual bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item); - + /** Parses item metadata as read by ReadItem(), into the item enchantments. */ void ParseItemMetadata(cItem & a_Item, const AString & a_Metadata); - + void StartEncryption(const Byte * a_Key); /** Converts the BlockFace received by the protocol into eBlockFace constants. @@ -261,10 +261,10 @@ class cProtocol176 : public cProtocol172 { typedef cProtocol172 super; - + public: cProtocol176(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State); - + // cProtocol172 overrides: virtual void SendPlayerSpawn(const cPlayer & a_Player) override; virtual void HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) override; diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index c80907ed8..eab6c4721 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -174,7 +174,7 @@ void cProtocol180::DataReceived(const char * a_Data, size_t a_Size) void cProtocol180::SendAttachEntity(const cEntity & a_Entity, const cEntity * a_Vehicle) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x1b); // Attach Entity packet Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); Pkt.WriteBEUInt32((a_Vehicle != nullptr) ? a_Vehicle->GetUniqueID() : 0); @@ -188,7 +188,7 @@ void cProtocol180::SendAttachEntity(const cEntity & a_Entity, const cEntity * a_ void cProtocol180::SendBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x24); // Block Action packet Pkt.WritePosition64(a_BlockX, a_BlockY, a_BlockZ); Pkt.WriteBEInt8(a_Byte1); @@ -203,7 +203,7 @@ void cProtocol180::SendBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, cha void cProtocol180::SendBlockBreakAnim(UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x25); // Block Break Animation packet Pkt.WriteVarInt32(a_EntityID); Pkt.WritePosition64(a_BlockX, a_BlockY, a_BlockZ); @@ -250,7 +250,7 @@ void cProtocol180::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockV void cProtocol180::SendChat(const AString & a_Message, eChatType a_Type) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x02); // Chat Message packet Pkt.WriteString(Printf("{\"text\":\"%s\"}", EscapeString(a_Message).c_str())); Pkt.WriteBEInt8(a_Type); @@ -294,7 +294,7 @@ void cProtocol180::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerialize void cProtocol180::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x0d); // Collect Item packet Pkt.WriteVarInt32(a_Entity.GetUniqueID()); Pkt.WriteVarInt32(a_Player.GetUniqueID()); @@ -307,7 +307,7 @@ void cProtocol180::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a void cProtocol180::SendDestroyEntity(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x13); // Destroy Entities packet Pkt.WriteVarInt32(1); Pkt.WriteVarInt32(a_Entity.GetUniqueID()); @@ -345,7 +345,7 @@ void cProtocol180::SendDisconnect(const AString & a_Reason) void cProtocol180::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x36); // Sign Editor Open packet Pkt.WritePosition64(a_BlockX, a_BlockY, a_BlockZ); } @@ -357,7 +357,7 @@ void cProtocol180::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ) void cProtocol180::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x1D); // Entity Effect packet Pkt.WriteVarInt32(a_Entity.GetUniqueID()); Pkt.WriteBEUInt8(static_cast(a_EffectID)); @@ -373,7 +373,7 @@ void cProtocol180::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, in void cProtocol180::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x04); // Entity Equipment packet Pkt.WriteVarInt32(a_Entity.GetUniqueID()); Pkt.WriteBEInt16(a_SlotNum); @@ -387,7 +387,7 @@ void cProtocol180::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum void cProtocol180::SendEntityHeadLook(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x19); // Entity Head Look packet Pkt.WriteVarInt32(a_Entity.GetUniqueID()); Pkt.WriteByteAngle(a_Entity.GetHeadYaw()); @@ -400,7 +400,7 @@ void cProtocol180::SendEntityHeadLook(const cEntity & a_Entity) void cProtocol180::SendEntityLook(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x16); // Entity Look packet Pkt.WriteVarInt32(a_Entity.GetUniqueID()); Pkt.WriteByteAngle(a_Entity.GetYaw()); @@ -415,7 +415,7 @@ void cProtocol180::SendEntityLook(const cEntity & a_Entity) void cProtocol180::SendEntityMetadata(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x1c); // Entity Metadata packet Pkt.WriteVarInt32(a_Entity.GetUniqueID()); WriteEntityMetadata(Pkt, a_Entity); @@ -429,7 +429,7 @@ void cProtocol180::SendEntityMetadata(const cEntity & a_Entity) void cProtocol180::SendEntityProperties(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x20); // Entity Properties packet Pkt.WriteVarInt32(a_Entity.GetUniqueID()); WriteEntityProperties(Pkt, a_Entity); @@ -442,7 +442,7 @@ void cProtocol180::SendEntityProperties(const cEntity & a_Entity) void cProtocol180::SendEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x15); // Entity Relative Move packet Pkt.WriteVarInt32(a_Entity.GetUniqueID()); Pkt.WriteBEInt8(a_RelX); @@ -458,7 +458,7 @@ void cProtocol180::SendEntityRelMove(const cEntity & a_Entity, char a_RelX, char void cProtocol180::SendEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x17); // Entity Look And Relative Move packet Pkt.WriteVarInt32(a_Entity.GetUniqueID()); Pkt.WriteBEInt8(a_RelX); @@ -476,7 +476,7 @@ void cProtocol180::SendEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, void cProtocol180::SendEntityStatus(const cEntity & a_Entity, char a_Status) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x1a); // Entity Status packet Pkt.WriteBEUInt32(a_Entity.GetUniqueID()); Pkt.WriteBEInt8(a_Status); @@ -489,7 +489,7 @@ void cProtocol180::SendEntityStatus(const cEntity & a_Entity, char a_Status) void cProtocol180::SendEntityVelocity(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x12); // Entity Velocity packet Pkt.WriteVarInt32(a_Entity.GetUniqueID()); // 400 = 8000 / 20 ... Conversion from our speed in m / s to 8000 m / tick @@ -505,7 +505,7 @@ void cProtocol180::SendEntityVelocity(const cEntity & a_Entity) void cProtocol180::SendExplosion(double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x27); // Explosion packet Pkt.WriteBEFloat(static_cast(a_BlockX)); Pkt.WriteBEFloat(static_cast(a_BlockY)); @@ -530,7 +530,7 @@ void cProtocol180::SendExplosion(double a_BlockX, double a_BlockY, double a_Bloc void cProtocol180::SendGameMode(eGameMode a_GameMode) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x2b); // Change Game State packet Pkt.WriteBEUInt8(3); // Reason: Change game mode Pkt.WriteBEFloat(static_cast(a_GameMode)); // The protocol really represents the value with a float! @@ -570,7 +570,7 @@ void cProtocol180::SendHideTitle(void) void cProtocol180::SendInventorySlot(char a_WindowID, short a_SlotNum, const cItem & a_Item) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x2f); // Set Slot packet Pkt.WriteBEInt8(a_WindowID); Pkt.WriteBEInt16(a_SlotNum); @@ -589,7 +589,7 @@ void cProtocol180::SendKeepAlive(UInt32 a_PingID) LOGWARNING("Trying to send a KeepAlive packet to a player who's not yet fully logged in (%d). The protocol class prevented the packet.", m_State); return; } - + cPacketizer Pkt(*this, 0x00); // Keep Alive packet Pkt.WriteVarInt32(a_PingID); } @@ -613,7 +613,7 @@ void cProtocol180::SendLogin(const cPlayer & a_Player, const cWorld & a_World) Pkt.WriteBool(false); // Reduced Debug Info - wtf? } m_LastSentDimension = a_World.GetDimension(); - + // Send the spawn position: { cPacketizer Pkt(*this, 0x05); // Spawn Position packet @@ -625,7 +625,7 @@ void cProtocol180::SendLogin(const cPlayer & a_Player, const cWorld & a_World) cPacketizer Pkt(*this, 0x41); Pkt.WriteBEInt8(1); } - + // Send player abilities: SendPlayerAbilities(); } @@ -677,7 +677,7 @@ void cProtocol180::SendPaintingSpawn(const cPainting & a_Painting) void cProtocol180::SendMapData(const cMap & a_Map, int a_DataStartX, int a_DataStartY) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x34); Pkt.WriteVarInt32(a_Map.GetID()); Pkt.WriteBEUInt8(static_cast(a_Map.GetScale())); @@ -708,7 +708,7 @@ void cProtocol180::SendMapData(const cMap & a_Map, int a_DataStartX, int a_DataS void cProtocol180::SendPickupSpawn(const cPickup & a_Pickup) { ASSERT(m_State == 3); // In game mode? - + { cPacketizer Pkt(*this, 0x0e); // Spawn Object packet Pkt.WriteVarInt32(a_Pickup.GetUniqueID()); @@ -737,7 +737,7 @@ void cProtocol180::SendPickupSpawn(const cPickup & a_Pickup) void cProtocol180::SendPlayerAbilities(void) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x39); // Player Abilities packet Byte Flags = 0; cPlayer * Player = m_Client->GetPlayer(); @@ -766,7 +766,7 @@ void cProtocol180::SendPlayerAbilities(void) void cProtocol180::SendEntityAnimation(const cEntity & a_Entity, char a_Animation) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x0b); // Animation packet Pkt.WriteVarInt32(a_Entity.GetUniqueID()); Pkt.WriteBEInt8(a_Animation); @@ -954,7 +954,7 @@ void cProtocol180::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, con void cProtocol180::SendPlayerMaxSpeed(void) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x20); // Entity Properties cPlayer * Player = m_Client->GetPlayer(); Pkt.WriteVarInt32(Player->GetUniqueID()); @@ -983,7 +983,7 @@ void cProtocol180::SendPlayerMaxSpeed(void) void cProtocol180::SendPlayerMoveLook(void) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x08); // Player Position And Look packet cPlayer * Player = m_Client->GetPlayer(); Pkt.WriteBEDouble(Player->GetPosX()); @@ -1035,7 +1035,7 @@ void cProtocol180::SendPlayerSpawn(const cPlayer & a_Player) void cProtocol180::SendPluginMessage(const AString & a_Channel, const AString & a_Message) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x3f); Pkt.WriteString(a_Channel); Pkt.WriteBuf(a_Message.data(), a_Message.size()); @@ -1048,7 +1048,7 @@ void cProtocol180::SendPluginMessage(const AString & a_Channel, const AString & void cProtocol180::SendRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x1e); Pkt.WriteVarInt32(a_Entity.GetUniqueID()); Pkt.WriteBEUInt8(static_cast(a_EffectID)); @@ -1094,7 +1094,7 @@ void cProtocol180::SendRespawn(eDimension a_Dimension, bool a_ShouldIgnoreDimens void cProtocol180::SendExperience(void) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x1f); // Experience Packet cPlayer * Player = m_Client->GetPlayer(); Pkt.WriteBEFloat(Player->GetXpPercentage()); @@ -1109,7 +1109,7 @@ void cProtocol180::SendExperience(void) void cProtocol180::SendExperienceOrb(const cExpOrb & a_ExpOrb) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x11); Pkt.WriteVarInt32(a_ExpOrb.GetUniqueID()); Pkt.WriteFPInt(a_ExpOrb.GetPosX()); @@ -1125,7 +1125,7 @@ void cProtocol180::SendExperienceOrb(const cExpOrb & a_ExpOrb) void cProtocol180::SendScoreboardObjective(const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x3b); Pkt.WriteString(a_Name); Pkt.WriteBEUInt8(a_Mode); @@ -1143,7 +1143,7 @@ void cProtocol180::SendScoreboardObjective(const AString & a_Name, const AString void cProtocol180::SendScoreUpdate(const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x3c); Pkt.WriteString(a_Player); Pkt.WriteBEUInt8(a_Mode); @@ -1162,7 +1162,7 @@ void cProtocol180::SendScoreUpdate(const AString & a_Objective, const AString & void cProtocol180::SendDisplayObjective(const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x3d); Pkt.WriteBEUInt8(static_cast(a_Display)); Pkt.WriteString(a_Objective); @@ -1238,7 +1238,7 @@ void cProtocol180::SendSoundEffect(const AString & a_SoundName, double a_X, doub void cProtocol180::SendSoundParticleEffect(const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x28); // Effect packet Pkt.WriteBEInt32(static_cast(a_EffectID)); Pkt.WritePosition64(a_SrcX, a_SrcY, a_SrcZ); @@ -1253,7 +1253,7 @@ void cProtocol180::SendSoundParticleEffect(const EffectID a_EffectID, int a_SrcX void cProtocol180::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x0e); // Spawn Object packet Pkt.WriteVarInt32(a_FallingBlock.GetUniqueID()); Pkt.WriteBEUInt8(70); // Falling block @@ -1275,7 +1275,7 @@ void cProtocol180::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock) void cProtocol180::SendSpawnMob(const cMonster & a_Mob) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x0f); // Spawn Mob packet Pkt.WriteVarInt32(a_Mob.GetUniqueID()); Pkt.WriteBEUInt8(static_cast(a_Mob.GetMobType())); @@ -1331,7 +1331,7 @@ void cProtocol180::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, void cProtocol180::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0xe); // Spawn Object packet Pkt.WriteVarInt32(a_Vehicle.GetUniqueID()); Pkt.WriteBEUInt8(static_cast(a_VehicleType)); @@ -1356,7 +1356,7 @@ void cProtocol180::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleTyp void cProtocol180::SendStatistics(const cStatManager & a_Manager) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x37); Pkt.WriteVarInt32(statCount); // TODO 2014-05-11 xdot: Optimization: Send "dirty" statistics only @@ -1378,7 +1378,7 @@ void cProtocol180::SendStatistics(const cStatManager & a_Manager) void cProtocol180::SendTabCompletionResults(const AStringVector & a_Results) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x3a); // Tab-Complete packet Pkt.WriteVarInt32(static_cast(a_Results.size())); @@ -1395,7 +1395,7 @@ void cProtocol180::SendTabCompletionResults(const AStringVector & a_Results) void cProtocol180::SendTeleportEntity(const cEntity & a_Entity) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x18); Pkt.WriteVarInt32(a_Entity.GetUniqueID()); Pkt.WriteFPInt(a_Entity.GetPosX()); @@ -1413,7 +1413,7 @@ void cProtocol180::SendTeleportEntity(const cEntity & a_Entity) void cProtocol180::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x2c); // Spawn Global Entity packet Pkt.WriteVarInt32(0); // EntityID = 0, always Pkt.WriteBEUInt8(1); // Type = Thunderbolt @@ -1450,7 +1450,7 @@ void cProtocol180::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_Do // When writing a "-" before the number the client ignores it but it will stop the client-side time expiration. a_TimeOfDay = std::min(-a_TimeOfDay, -1LL); } - + cPacketizer Pkt(*this, 0x03); Pkt.WriteBEInt64(a_WorldAge); Pkt.WriteBEInt64(a_TimeOfDay); @@ -1463,7 +1463,7 @@ void cProtocol180::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_Do void cProtocol180::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x21); // Chunk Data packet Pkt.WriteBEInt32(a_ChunkX); Pkt.WriteBEInt32(a_ChunkZ); @@ -1478,7 +1478,7 @@ void cProtocol180::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) void cProtocol180::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x35); // Update tile entity packet Pkt.WritePosition64(a_BlockEntity.GetPosX(), a_BlockEntity.GetPosY(), a_BlockEntity.GetPosZ()); @@ -1525,7 +1525,7 @@ void cProtocol180::SendUpdateSign(int a_BlockX, int a_BlockY, int a_BlockZ, cons void cProtocol180::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x0a); Pkt.WriteVarInt32(a_Entity.GetUniqueID()); Pkt.WritePosition64(a_BlockX, a_BlockY, a_BlockZ); @@ -1538,7 +1538,7 @@ void cProtocol180::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_Bloc void cProtocol180::SendWeather(eWeather a_Weather) { ASSERT(m_State == 3); // In game mode? - + { cPacketizer Pkt(*this, 0x2b); // Change Game State packet Pkt.WriteBEUInt8((a_Weather == wSunny) ? 1 : 2); // End rain / begin rain @@ -1555,7 +1555,7 @@ void cProtocol180::SendWeather(eWeather a_Weather) void cProtocol180::SendWholeInventory(const cWindow & a_Window) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x30); // Window Items packet Pkt.WriteBEInt8(a_Window.GetWindowID()); Pkt.WriteBEInt16(static_cast(a_Window.GetNumSlots())); @@ -1574,7 +1574,7 @@ void cProtocol180::SendWholeInventory(const cWindow & a_Window) void cProtocol180::SendWindowClose(const cWindow & a_Window) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x2e); Pkt.WriteBEInt8(a_Window.GetWindowID()); } @@ -1627,7 +1627,7 @@ void cProtocol180::SendWindowOpen(const cWindow & a_Window) void cProtocol180::SendWindowProperty(const cWindow & a_Window, short a_Property, short a_Value) { ASSERT(m_State == 3); // In game mode? - + cPacketizer Pkt(*this, 0x31); // Window Property packet Pkt.WriteBEInt8(a_Window.GetWindowID()); Pkt.WriteBEInt16(a_Property); @@ -1832,7 +1832,7 @@ void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size) m_ReceivedData.ResetRead(); break; } - + // Check packet for compression: UInt32 UncompressedSize = 0; AString UncompressedData; @@ -1868,7 +1868,7 @@ void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size) } } } - + // Move the packet payload to a separate cByteBuffer, bb: cByteBuffer bb(PacketLen + 1); if (UncompressedSize == 0) @@ -1892,7 +1892,7 @@ void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size) // Write one NUL extra, so that we can detect over-reads bb.Write("\0", 1); - + // Log the packet info into the comm log file: if (g_ShouldLogCommIn && m_CommLogFile.IsOpen()) { @@ -1913,7 +1913,7 @@ void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size) { // Unknown packet, already been reported, but without the length. Log the length here: LOGWARNING("Unhandled packet: type 0x%x, state %d, length %u", PacketType, m_State, PacketLen); - + #ifdef _DEBUG // Dump the packet contents into the log: bb.ResetRead(); @@ -1924,13 +1924,13 @@ void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size) CreateHexDump(Out, Packet.data(), Packet.size(), 24); LOGD("Packet contents:\n%s", Out.c_str()); #endif // _DEBUG - + // Put a message in the comm log: if (g_ShouldLogCommIn && m_CommLogFile.IsOpen()) { m_CommLogFile.Printf("^^^^^^ Unhandled packet ^^^^^^\n\n\n"); } - + return; } @@ -1991,7 +1991,7 @@ bool cProtocol180::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) } break; } - + case 2: { // Login @@ -2002,7 +2002,7 @@ bool cProtocol180::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) } break; } - + case 3: { // Game @@ -2039,9 +2039,9 @@ bool cProtocol180::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) { // Received a packet in an unknown state, report: LOGWARNING("Received a packet in an unknown protocol state %d. Ignoring further packets.", m_State); - + // Cannot kick the client - we don't know this state and thus the packet number for the kick packet - + // Switch to a state when all further packets are silently ignored: m_State = 255; return false; @@ -2053,7 +2053,7 @@ bool cProtocol180::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) return false; } } // switch (m_State) - + // Unknown packet type, report to the ClientHandle: m_Client->PacketUnknown(a_PacketType); return false; @@ -2164,7 +2164,7 @@ void cProtocol180::HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffe m_Client->Kick("Hacked client"); return; } - + // Decrypt the symmetric encryption key using privkey: Byte DecryptedKey[MAX_ENC_LEN]; res = rsaDecryptor.Decrypt(reinterpret_cast(EncKey.data()), EncKey.size(), DecryptedKey, sizeof(DecryptedKey)); @@ -2174,7 +2174,7 @@ void cProtocol180::HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffe m_Client->Kick("Hacked client"); return; } - + StartEncryption(DecryptedKey); m_Client->HandleLogin(4, m_Client->GetUsername()); } @@ -2191,13 +2191,13 @@ void cProtocol180::HandlePacketLoginStart(cByteBuffer & a_ByteBuffer) m_Client->Kick("Bad username"); return; } - + if (!m_Client->HandleHandshake(Username)) { // The client is not welcome here, they have been sent a Kick packet already return; } - + cServer * Server = cRoot::Get()->GetServer(); // If auth is required, then send the encryption request: if (Server->ShouldAuthenticate()) @@ -2212,7 +2212,7 @@ void cProtocol180::HandlePacketLoginStart(cByteBuffer & a_ByteBuffer) m_Client->SetUsername(Username); return; } - + m_Client->HandleLogin(4, Username); } @@ -2287,7 +2287,7 @@ void cProtocol180::HandlePacketClientSettings(cByteBuffer & a_ByteBuffer) HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, ChatFlags); HANDLE_READ(a_ByteBuffer, ReadBool, bool, ChatColors); HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, SkinFlags); - + m_Client->SetLocale(Locale); m_Client->SetViewDistance(ViewDistance); // TODO: Handle other values @@ -2451,7 +2451,7 @@ void cProtocol180::HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer) void cProtocol180::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) { HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel); - + // If the plugin channel is recognized vanilla, handle it directly: if (Channel.substr(0, 3) == "MC|") { @@ -2723,7 +2723,7 @@ void cProtocol180::HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const return; } LOG("Unhandled vanilla plugin channel: \"%s\".", a_Channel.c_str()); - + // Read the payload and send it through to the clienthandle: AString Message; VERIFY(a_ByteBuffer.ReadString(Message, a_ByteBuffer.GetReadableSpace() - 1)); @@ -2768,7 +2768,7 @@ bool cProtocol180::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a return true; } a_Item.m_ItemType = ItemType; - + HANDLE_PACKET_READ(a_ByteBuffer, ReadBEInt8, Int8, ItemCount); HANDLE_PACKET_READ(a_ByteBuffer, ReadBEInt16, Int16, ItemDamage); a_Item.m_ItemCount = ItemCount; @@ -2804,7 +2804,7 @@ void cProtocol180::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata) LOGWARNING("Cannot parse NBT item metadata: (" SIZE_T_FMT " bytes)\n%s", a_Metadata.size(), HexDump.c_str()); return; } - + // Load enchantments and custom display names from the NBT data: for (int tag = NBT.GetFirstChild(NBT.GetRoot()); tag >= 0; tag = NBT.GetNextSibling(tag)) { @@ -2873,7 +2873,7 @@ void cProtocol180::StartEncryption(const Byte * a_Key) m_Encryptor.Init(a_Key, a_Key); m_Decryptor.Init(a_Key, a_Key); m_IsEncrypted = true; - + // Prepare the m_AuthServerID: cSha1Checksum Checksum; cServer * Server = cRoot::Get()->GetServer(); @@ -2982,17 +2982,17 @@ void cProtocol180::WriteItem(cPacketizer & a_Pkt, const cItem & a_Item) // Fix, to make sure no invalid values are sent. ItemType = -1; } - + if (a_Item.IsEmpty()) { a_Pkt.WriteBEInt16(-1); return; } - + a_Pkt.WriteBEInt16(ItemType); a_Pkt.WriteBEInt8(a_Item.m_ItemCount); a_Pkt.WriteBEInt16(a_Item.m_ItemDamage); - + if (a_Item.m_Enchantments.IsEmpty() && a_Item.IsBothNameAndLoreEmpty() && (a_Item.m_ItemType != E_ITEM_FIREWORK_ROCKET) && (a_Item.m_ItemType != E_ITEM_FIREWORK_STAR) && !a_Item.m_ItemColor.IsValid()) { a_Pkt.WriteBEInt8(0); @@ -3218,7 +3218,7 @@ void cProtocol180::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_En a_Pkt.WriteBEInt32(1); // Shaking direction, doesn't seem to affect anything a_Pkt.WriteBEUInt8(0x73); a_Pkt.WriteBEFloat(static_cast(Minecart.LastDamage() + 10)); // Damage taken / shake effect multiplyer - + if (Minecart.GetPayload() == cMinecart::mpNone) { auto & RideableMinecart = reinterpret_cast(Minecart); @@ -3441,7 +3441,7 @@ void cProtocol180::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) auto & Sheep = reinterpret_cast(a_Mob); a_Pkt.WriteBEUInt8(0x0c); a_Pkt.WriteBEInt8(Sheep.IsBaby() ? -1 : (Sheep.IsInLoveCooldown() ? 1 : 0)); - + a_Pkt.WriteBEUInt8(0x10); Byte SheepMetadata = 0; SheepMetadata = static_cast(Sheep.GetFurColor()); @@ -3575,7 +3575,7 @@ void cProtocol180::WriteEntityProperties(cPacketizer & a_Pkt, const cEntity & a_ // const cMonster & Mob = (const cMonster &)a_Entity; // TODO: Send properties and modifiers based on the mob type - + a_Pkt.WriteBEInt32(0); // NumProperties } diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index 8b5b7ffa2..8a446a1b9 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -51,11 +51,11 @@ class cProtocol180 : public cProtocol { typedef cProtocol super; - + public: cProtocol180(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State); - + /** Called when client sends some data: */ virtual void DataReceived(const char * a_Data, size_t a_Size) override; @@ -157,30 +157,30 @@ public: protected: AString m_ServerAddress; - + UInt16 m_ServerPort; - + AString m_AuthServerID; - + /** State of the protocol. 1 = status, 2 = login, 3 = game */ UInt32 m_State; /** Buffer for the received data */ cByteBuffer m_ReceivedData; - + bool m_IsEncrypted; - + cAesCfb128Decryptor m_Decryptor; cAesCfb128Encryptor m_Encryptor; /** The logfile where the comm is logged, when g_ShouldLogComm is true */ cFile m_CommLogFile; - + /** The dimension that was last sent to a player in a Respawn or Login packet. Used to avoid Respawning into the same dimension, which confuses the client. */ eDimension m_LastSentDimension; - - + + /** Adds the received (unencrypted) data to m_ReceivedData, parses complete packets */ void AddReceivedData(const char * a_Data, size_t a_Size); @@ -196,7 +196,7 @@ protected: // Packet handlers while in the Login state (m_State == 2): void HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer); void HandlePacketLoginStart(cByteBuffer & a_ByteBuffer); - + // Packet handlers while in the Game state (m_State == 3): void HandlePacketAnimation (cByteBuffer & a_ByteBuffer); void HandlePacketBlockDig (cByteBuffer & a_ByteBuffer); @@ -221,12 +221,12 @@ protected: void HandlePacketEnchantItem (cByteBuffer & a_ByteBuffer); void HandlePacketWindowClick (cByteBuffer & a_ByteBuffer); void HandlePacketWindowClose (cByteBuffer & a_ByteBuffer); - + /** Parses Vanilla plugin messages into specific ClientHandle calls. The message payload is still in the bytebuffer, the handler reads it specifically for each handled channel */ void HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const AString & a_Channel); - - + + /** Sends the data to the client, encrypting them if needed. */ virtual void SendData(const char * a_Data, size_t a_Size) override; @@ -234,15 +234,15 @@ protected: virtual void SendPacket(cPacketizer & a_Packet) override; void SendCompass(const cWorld & a_World); - + /** Reads an item out of the received data, sets a_Item to the values read. Returns false if not enough received data. a_KeepRemainingBytes tells the function to keep that many bytes at the end of the buffer. */ virtual bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_KeepRemainingBytes = 0); - + /** Parses item metadata as read by ReadItem(), into the item enchantments. */ void ParseItemMetadata(cItem & a_Item, const AString & a_Metadata); - + void StartEncryption(const Byte * a_Key); /** Converts the BlockFace received by the protocol into eBlockFace constants. diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index c88bd8639..fff55b6e9 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -66,7 +66,7 @@ void cProtocolRecognizer::DataReceived(const char * a_Data, size_t a_Size) m_Client->Kick("Unsupported protocol version"); return; } - + if (!TryRecognizeProtocol()) { return; diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index c548ad5ba..89dfaec38 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -29,7 +29,7 @@ class cProtocolRecognizer : public cProtocol { typedef cProtocol super; - + public: enum { @@ -40,13 +40,13 @@ public: cProtocolRecognizer(cClientHandle * a_Client); virtual ~cProtocolRecognizer(); - + /** Translates protocol version number into protocol version text: 49 -> "1.4.4" */ static AString GetVersionTextFromInt(int a_ProtocolVersion); - + /** Called when client sends some data: */ virtual void DataReceived(const char * a_Data, size_t a_Size) override; - + /** Sending stuff to clients (alphabetically sorted): */ virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) override; virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override; @@ -128,7 +128,7 @@ public: virtual void SendWindowClose (const cWindow & a_Window) override; virtual void SendWindowOpen (const cWindow & a_Window) override; virtual void SendWindowProperty (const cWindow & a_Window, short a_Property, short a_Value) override; - + virtual AString GetAuthServerID(void) override; virtual void SendData(const char * a_Data, size_t a_Size) override; @@ -139,11 +139,11 @@ protected: /** Buffer for the incoming data until we recognize the protocol */ cByteBuffer m_Buffer; - + /** Tries to recognize protocol based on m_Buffer contents; returns true if recognized */ bool TryRecognizeProtocol(void); - + /** Tries to recognize a protocol in the lengthed family (1.7+), based on m_Buffer; returns true if recognized. The packet length and type have already been read, type is 0 The number of bytes remaining in the packet is passed as a_PacketLengthRemaining. */ diff --git a/src/RCONServer.cpp b/src/RCONServer.cpp index 9ca8492a9..2c65658cb 100644 --- a/src/RCONServer.cpp +++ b/src/RCONServer.cpp @@ -29,7 +29,7 @@ enum // Client -> Server: RCON_PACKET_COMMAND = 2, RCON_PACKET_LOGIN = 3, - + // Server -> Client: RCON_PACKET_RESPONSE = 2, } ; @@ -87,19 +87,19 @@ public: m_RequestID(a_RequestID) { } - + // cCommandOutputCallback overrides: virtual void Out(const AString & a_Text) override { m_Buffer.append(a_Text); } - + virtual void Finished(void) override { m_Connection.SendResponse(m_RequestID, RCON_PACKET_RESPONSE, static_cast(m_Buffer.size()), m_Buffer.c_str()); delete this; } - + protected: cRCONServer::cConnection & m_Connection; UInt32 m_RequestID; @@ -148,7 +148,7 @@ void cRCONServer::Initialize(cSettingsRepositoryInterface & a_Settings) LOGWARNING("RCON is requested, but the password is not set. RCON is now disabled."); return; } - + // Read the listening ports for RCON from config: AStringVector Ports = ReadUpgradeIniPorts(a_Settings, "RCON", "Ports", "PortsIPv4", "PortsIPv6", "25575"); @@ -207,7 +207,7 @@ void cRCONServer::cConnection::OnReceivedData(const char * a_Data, size_t a_Size // Append data to the buffer: m_Buffer.append(a_Data, a_Size); - + // Process the packets in the buffer: while (m_Buffer.size() >= 14) { @@ -227,7 +227,7 @@ void cRCONServer::cConnection::OnReceivedData(const char * a_Data, size_t a_Size // Incomplete packet yet, wait for more data to come return; } - + UInt32 RequestID = UIntFromBuffer(m_Buffer.data() + 4); UInt32 PacketType = UIntFromBuffer(m_Buffer.data() + 8); if (!ProcessPacket(RequestID, PacketType, Length - 10, m_Buffer.data() + 12)) @@ -276,14 +276,14 @@ bool cRCONServer::cConnection::ProcessPacket(UInt32 a_RequestID, UInt32 a_Packet return false; } m_IsAuthenticated = true; - + LOGD("RCON: Client at %s has successfully authenticated", m_IPAddress.c_str()); - + // Send OK response: SendResponse(a_RequestID, RCON_PACKET_RESPONSE, 0, nullptr); return true; } - + case RCON_PACKET_COMMAND: { if (!m_IsAuthenticated) @@ -292,17 +292,17 @@ bool cRCONServer::cConnection::ProcessPacket(UInt32 a_RequestID, UInt32 a_Packet SendResponse(a_RequestID, RCON_PACKET_RESPONSE, sizeof(AuthNeeded), AuthNeeded); return false; } - + AString cmd(a_Payload, a_PayloadLength); LOGD("RCON command from %s: \"%s\"", m_IPAddress.c_str(), cmd.c_str()); cRoot::Get()->ExecuteConsoleCommand(cmd, *(new cRCONCommandOutput(*this, a_RequestID))); - + // Send an empty response: SendResponse(a_RequestID, RCON_PACKET_RESPONSE, 0, nullptr); return true; } } - + // Unknown packet type, drop the connection: LOGWARNING("RCON: Client at %s has sent an unknown packet type %d, dropping connection.", m_IPAddress.c_str(), a_PacketType @@ -340,7 +340,7 @@ void cRCONServer::cConnection::SendResponse(UInt32 a_RequestID, UInt32 a_PacketT { ASSERT((a_PayloadLength == 0) || (a_Payload != nullptr)); // Either zero data to send, or a valid payload ptr ASSERT(m_Link != nullptr); - + char Buffer[12]; UInt32 Length = a_PayloadLength + 10; UIntToBuffer(Length, Buffer); diff --git a/src/RCONServer.h b/src/RCONServer.h index ecd936eeb..2aba6ebf2 100644 --- a/src/RCONServer.h +++ b/src/RCONServer.h @@ -28,64 +28,64 @@ class cRCONServer public: cRCONServer(cServer & a_Server); virtual ~cRCONServer(); - + void Initialize(cSettingsRepositoryInterface & a_Settings); - + protected: friend class cRCONCommandOutput; friend class cRCONListenCallbacks; - + class cConnection : public cTCPLink::cCallbacks { public: cConnection(cRCONServer & a_RCONServer, const AString & a_IPAddress); - + protected: friend class cRCONCommandOutput; - + /** Set to true if the client has successfully authenticated */ bool m_IsAuthenticated; - + /** Buffer for the incoming data */ AString m_Buffer; - + /** Server that owns this connection and processes requests */ cRCONServer & m_RCONServer; - + /** The TCP link to the client */ cTCPLinkPtr m_Link; - + /** Address of the client */ AString m_IPAddress; - + // cTCPLink::cCallbacks overrides: virtual void OnLinkCreated(cTCPLinkPtr a_Link) override; virtual void OnReceivedData(const char * a_Data, size_t a_Length) override; virtual void OnRemoteClosed(void) override; virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg) override; - + /** Processes the given packet and sends the response; returns true if successful, false if the connection is to be dropped */ bool ProcessPacket(UInt32 a_RequestID, UInt32 a_PacketType, UInt32 a_PayloadLength, const char * a_Payload); - + /** Reads 4 bytes from a_Buffer and returns the LE UInt32 they represent */ UInt32 UIntFromBuffer(const char * a_Buffer); - + /** Puts 4 bytes representing the int into the buffer */ void UIntToBuffer(UInt32 a_Value, char * a_Buffer); - + /** Sends a RCON packet back to the client */ void SendResponse(UInt32 a_RequestID, UInt32 a_PacketType, UInt32 a_PayloadLength, const char * a_Payload); } ; - - + + /** The server object that will process the commands received */ cServer & m_Server; - + /** The sockets for accepting RCON connections (one socket per port). */ cServerHandlePtrs m_ListenServers; - + /** Password for authentication */ AString m_Password; } ; diff --git a/src/RankManager.cpp b/src/RankManager.cpp index 922d9768e..0c6ef508e 100644 --- a/src/RankManager.cpp +++ b/src/RankManager.cpp @@ -25,14 +25,14 @@ public: m_MojangAPI(a_MojangAPI) { } - - - + + + /** Performs the complete migration from INI files to DB. */ bool Migrate(void) { cRankManager::cMassChangeLock Lock(m_RankManager); - + LOGD("Reading groups..."); if (!ReadGroups()) { @@ -52,16 +52,16 @@ public: CleanUserGroups(); LOGD("Resolving user UUIDs..."); ResolveUserUUIDs(); - + LOGD("Setting ranks..."); SetRanks(); LOGD("Creating defaults..."); CreateDefaults(); - + return true; } - + protected: /** Container for a group read from an INI file. */ @@ -71,9 +71,9 @@ protected: AString m_Color; AStringVector m_Inherits; AStringVector m_Permissions; - + sGroup(void) {} - + sGroup(const AString & a_Name, const AString & a_Color, const AStringVector & a_Inherits, const AStringVector & a_Permissions): m_Name(a_Name), m_Color(a_Color), @@ -83,23 +83,23 @@ protected: } }; typedef std::map sGroupMap; - - + + /** Container for a single user read from an INI file. */ struct sUser { AString m_Name; AStringVector m_Groups; - + /** Assigned by ResolveUserUUIDs(), contains the online (Mojang) UUID of the player. */ AString m_UUID; /** Assigned by ResolveUserUUIDs(), contains the offline (generated) UUID of the player. */ AString m_OfflineUUID; - - + + sUser(void) {} - + sUser(const AString & a_Name, const AStringVector & a_Groups): m_Name(a_Name), m_Groups(a_Groups) @@ -107,22 +107,22 @@ protected: } }; typedef std::map sUserMap; - + typedef std::map cStringMap; - - + + /** The parent Rank manager where we will create the groups, ranks and players */ cRankManager & m_RankManager; - + /** The player name to UUID resolver */ cMojangAPI & m_MojangAPI; - + /** List of all groups read from the ini file */ sGroupMap m_Groups; - + /** List of all players read from the ini file. */ sUserMap m_Users; - + /** Maps lists of groups to rank names. Each group list is either a simple "" if there's only one group, or ", , ...", where the secondary groups are @@ -132,8 +132,8 @@ protected: where N is a unique number. */ cStringMap m_GroupsToRanks; - - + + /** Reads the groups from the "groups.ini" file into m_Groups */ bool ReadGroups(void) { @@ -143,7 +143,7 @@ protected: { return false; } - + // Read all the groups into a map: int NumGroups = Groups.GetNumKeys(); for (int i = 0; i < NumGroups; i++) @@ -164,9 +164,9 @@ protected: } // for i - Groups' keys return true; } - - + + /** Removes non-existent groups from all the groups' inheritance */ void CleanGroupInheritance(void) { @@ -194,8 +194,8 @@ protected: } // for itrG - m_Groups[] } - - + + /** Reads the users from the "users.ini" file into m_Users */ bool ReadUsers(void) { @@ -205,7 +205,7 @@ protected: { return false; } - + // Read all the users into a map: int NumUsers = Users.GetNumKeys(); for (int i = 0; i < NumUsers; i++) @@ -224,9 +224,9 @@ protected: } // for i - Users' keys return true; } - - - + + + /** Removes non-existent groups from each user's definition. */ void CleanUserGroups(void) { @@ -253,9 +253,9 @@ protected: } // for itrG - Groups[] } // for itrU - m_Users[] } - - - + + + /** Creates groups based on m_Groups. Ignores group inheritance. */ void CreateGroups(void) @@ -267,8 +267,8 @@ protected: m_RankManager.AddPermissionsToGroup(itr->second.m_Permissions, itr->second.m_Name); } // for itr - m_Groups[] } - - + + /** Resolves the UUID of each user in m_Users. If a user doesn't resolve, they are removed and logged in the console. */ void ResolveUserUUIDs(void) @@ -280,7 +280,7 @@ protected: PlayerNames.push_back(itr->second.m_Name); } m_MojangAPI.GetUUIDsFromPlayerNames(PlayerNames); - + // Assign the UUIDs back to players, remove those not resolved: for (sUserMap::iterator itr = m_Users.begin(); itr != m_Users.end(); ++itr) { @@ -293,9 +293,9 @@ protected: itr->second.m_OfflineUUID = cClientHandle::GenerateOfflineUUID(itr->second.m_Name); } } - - - + + + /** Adds the specified groups to the specified ranks. Recurses on the groups' inheritance. */ void AddGroupsToRank(const AStringVector & a_Groups, const AString & a_RankName) { @@ -303,21 +303,21 @@ protected: { // Normalize the group name: sGroup & Group = m_Groups[StrToLower(*itr)]; - + // Avoid loops, check if the group is already added: if (m_RankManager.IsGroupInRank(Group.m_Name, a_RankName)) { continue; } - + // Add the group, and all the groups it inherits from recursively: m_RankManager.AddGroupToRank(Group.m_Name, a_RankName); AddGroupsToRank(Group.m_Inherits, a_RankName); } // for itr - a_Groups[] } - - - + + + /** Creates a rank for each player, based on the master groups they are assigned. */ void SetRanks(void) { @@ -330,7 +330,7 @@ protected: LOGWARNING("RankMigrator: Player %s has no groups assigned to them, skipping the player.", itr->second.m_Name.c_str()); continue; } - + // Compose the rank name out of group names: AString RankName; for (AStringVector::const_iterator itrG = Groups.begin(), endG = Groups.end(); itrG != endG; ++itrG) @@ -342,14 +342,14 @@ protected: } RankName.append(GroupName); } // for itrG - Groups[] - + // Create the rank, with al its groups: if (!m_RankManager.RankExists(RankName)) { m_RankManager.AddRank(RankName, "", "", m_Groups[StrToLower(Groups[0])].m_Color); AddGroupsToRank(Groups, RankName); } - + // Set the rank to the user, using both the online and offline UUIDs: m_RankManager.SetPlayerRank(itr->second.m_UUID, itr->second.m_Name, RankName); m_RankManager.SetPlayerRank(itr->second.m_OfflineUUID, itr->second.m_Name, RankName); @@ -407,7 +407,7 @@ cRankManager::~cRankManager() void cRankManager::Initialize(cMojangAPI & a_MojangAPI) { ASSERT(!m_IsInitialized); // Calling Initialize for the second time? - + // Create the DB tables, if they don't exist: m_DB.exec("CREATE TABLE IF NOT EXISTS Rank (RankID INTEGER PRIMARY KEY, Name, MsgPrefix, MsgSuffix, MsgNameColorCode)"); m_DB.exec("CREATE TABLE IF NOT EXISTS PlayerRank (PlayerUUID, PlayerName, RankID INTEGER)"); @@ -416,9 +416,9 @@ void cRankManager::Initialize(cMojangAPI & a_MojangAPI) m_DB.exec("CREATE TABLE IF NOT EXISTS PermissionItem (PermGroupID INTEGER, Permission)"); m_DB.exec("CREATE TABLE IF NOT EXISTS RestrictionItem (PermGroupID INTEGER, Permission)"); m_DB.exec("CREATE TABLE IF NOT EXISTS DefaultRank (RankID INTEGER)"); - + m_IsInitialized = true; - + a_MojangAPI.SetRankManager(this); // Check if tables empty, migrate from ini files then @@ -439,7 +439,7 @@ void cRankManager::Initialize(cMojangAPI & a_MojangAPI) CreateDefaults(); LOGINFO("Default ranks created."); } - + // Load the default rank: try { @@ -473,7 +473,7 @@ AString cRankManager::GetPlayerRankName(const AString & a_PlayerUUID) { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + try { SQLite::Statement stmt(m_DB, "SELECT Rank.Name FROM Rank LEFT JOIN PlayerRank ON Rank.RankID = PlayerRank.RankID WHERE PlayerRank.PlayerUUID = ?"); @@ -528,7 +528,7 @@ AStringVector cRankManager::GetPlayerGroups(const AString & a_PlayerUUID) { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + AStringVector res; try { @@ -540,7 +540,7 @@ AStringVector cRankManager::GetPlayerGroups(const AString & a_PlayerUUID) "WHERE PlayerRank.PlayerUUID = ?" ); stmt.bind(1, a_PlayerUUID); - + // Execute and get results: while (stmt.executeStep()) { @@ -590,7 +590,7 @@ AStringVector cRankManager::GetRankGroups(const AString & a_RankName) { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + AStringVector res; try { @@ -621,7 +621,7 @@ AStringVector cRankManager::GetGroupPermissions(const AString & a_GroupName) { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + AStringVector res; try { @@ -651,7 +651,7 @@ AStringVector cRankManager::GetGroupRestrictions(const AString & a_GroupName) { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + AStringVector res; try { @@ -681,7 +681,7 @@ AStringVector cRankManager::GetRankPermissions(const AString & a_RankName) { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + AStringVector res; try { @@ -712,7 +712,7 @@ AStringVector cRankManager::GetRankRestrictions(const AString & a_RankName) { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + AStringVector res; try { @@ -769,7 +769,7 @@ AStringVector cRankManager::GetAllRanks(void) { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + AStringVector res; try { @@ -794,7 +794,7 @@ AStringVector cRankManager::GetAllGroups(void) { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + AStringVector res; try { @@ -819,7 +819,7 @@ AStringVector cRankManager::GetAllPermissions(void) { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + AStringVector res; try { @@ -844,7 +844,7 @@ AStringVector cRankManager::GetAllRestrictions(void) { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + AStringVector res; try { @@ -912,7 +912,7 @@ void cRankManager::AddRank( { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + try { // Check if such a rank name is already used: @@ -928,7 +928,7 @@ void cRankManager::AddRank( } } } - + // Insert a new rank: SQLite::Statement stmt(m_DB, "INSERT INTO Rank (Name, MsgPrefix, MsgSuffix, MsgNameColorCode) VALUES (?, ?, ?, ?)"); stmt.bind(1, a_RankName); @@ -955,7 +955,7 @@ void cRankManager::AddGroup(const AString & a_GroupName) { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + try { // Check if such a group name is already used: @@ -971,7 +971,7 @@ void cRankManager::AddGroup(const AString & a_GroupName) } } } - + // Insert a new group: SQLite::Statement stmt(m_DB, "INSERT INTO PermGroup (Name) VALUES (?)"); stmt.bind(1, a_GroupName); @@ -995,7 +995,7 @@ void cRankManager::AddGroups(const AStringVector & a_GroupNames) { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + try { for (AStringVector::const_iterator itr = a_GroupNames.begin(), end = a_GroupNames.end(); itr != end; ++itr) @@ -1013,7 +1013,7 @@ void cRankManager::AddGroups(const AStringVector & a_GroupNames) } } } - + // Insert a new group: SQLite::Statement stmt(m_DB, "INSERT INTO PermGroup (Name) VALUES (?)"); stmt.bind(1, *itr); @@ -1038,7 +1038,7 @@ bool cRankManager::AddGroupToRank(const AString & a_GroupName, const AString & a { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + try { // Get the group's ID: @@ -1053,7 +1053,7 @@ bool cRankManager::AddGroupToRank(const AString & a_GroupName, const AString & a } GroupID = stmt.getColumn(0); } - + // Get the rank's ID: int RankID; { @@ -1066,7 +1066,7 @@ bool cRankManager::AddGroupToRank(const AString & a_GroupName, const AString & a } RankID = stmt.getColumn(0); } - + // Check if the group is already there: { SQLite::Statement stmt(m_DB, "SELECT COUNT(*) FROM RankPermGroup WHERE RankID = ? AND PermGroupID = ?"); @@ -1085,7 +1085,7 @@ bool cRankManager::AddGroupToRank(const AString & a_GroupName, const AString & a return true; } } - + // Add the group: { SQLite::Statement stmt(m_DB, "INSERT INTO RankPermGroup (RankID, PermGroupID) VALUES (?, ?)"); @@ -1097,7 +1097,7 @@ bool cRankManager::AddGroupToRank(const AString & a_GroupName, const AString & a return false; } } - + // Adding succeeded: return true; } @@ -1116,7 +1116,7 @@ bool cRankManager::AddPermissionToGroup(const AString & a_Permission, const AStr { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + try { // Get the group's ID: @@ -1131,7 +1131,7 @@ bool cRankManager::AddPermissionToGroup(const AString & a_Permission, const AStr } GroupID = stmt.getColumn(0).getInt(); } - + // Check if the permission is already present: { SQLite::Statement stmt(m_DB, "SELECT COUNT(*) FROM PermissionItem WHERE PermGroupID = ? AND Permission = ?"); @@ -1150,7 +1150,7 @@ bool cRankManager::AddPermissionToGroup(const AString & a_Permission, const AStr return true; } } - + // Add the permission: { SQLite::Statement stmt(m_DB, "INSERT INTO PermissionItem (Permission, PermGroupID) VALUES (?, ?)"); @@ -1162,7 +1162,7 @@ bool cRankManager::AddPermissionToGroup(const AString & a_Permission, const AStr return false; } } - + // Adding succeeded: return true; } @@ -1183,7 +1183,7 @@ bool cRankManager::AddRestrictionToGroup(const AString & a_Restriction, const AS { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + try { // Get the group's ID: @@ -1198,7 +1198,7 @@ bool cRankManager::AddRestrictionToGroup(const AString & a_Restriction, const AS } GroupID = stmt.getColumn(0).getInt(); } - + // Check if the restriction is already present: { SQLite::Statement stmt(m_DB, "SELECT COUNT(*) FROM RestrictionItem WHERE PermGroupID = ? AND Permission = ?"); @@ -1217,7 +1217,7 @@ bool cRankManager::AddRestrictionToGroup(const AString & a_Restriction, const AS return true; } } - + // Add the restriction: { SQLite::Statement stmt(m_DB, "INSERT INTO RestrictionItem (Permission, PermGroupID) VALUES (?, ?)"); @@ -1229,7 +1229,7 @@ bool cRankManager::AddRestrictionToGroup(const AString & a_Restriction, const AS return false; } } - + // Adding succeeded: return true; } @@ -1250,7 +1250,7 @@ bool cRankManager::AddPermissionsToGroup(const AStringVector & a_Permissions, co { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + try { // Get the group's ID: @@ -1265,7 +1265,7 @@ bool cRankManager::AddPermissionsToGroup(const AStringVector & a_Permissions, co } GroupID = stmt.getColumn(0).getInt(); } - + for (AStringVector::const_iterator itr = a_Permissions.begin(), end = a_Permissions.end(); itr != end; ++itr) { // Check if the permission is already present: @@ -1286,7 +1286,7 @@ bool cRankManager::AddPermissionsToGroup(const AStringVector & a_Permissions, co continue; } } - + // Add the permission: { SQLite::Statement stmt(m_DB, "INSERT INTO PermissionItem (Permission, PermGroupID) VALUES (?, ?)"); @@ -1299,7 +1299,7 @@ bool cRankManager::AddPermissionsToGroup(const AStringVector & a_Permissions, co } } } // for itr - a_Permissions[] - + // Adding succeeded: return true; } @@ -1320,7 +1320,7 @@ bool cRankManager::AddRestrictionsToGroup(const AStringVector & a_Restrictions, { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + try { // Get the group's ID: @@ -1335,7 +1335,7 @@ bool cRankManager::AddRestrictionsToGroup(const AStringVector & a_Restrictions, } GroupID = stmt.getColumn(0).getInt(); } - + for (auto itr = a_Restrictions.cbegin(), end = a_Restrictions.cend(); itr != end; ++itr) { // Check if the restriction is already present: @@ -1356,7 +1356,7 @@ bool cRankManager::AddRestrictionsToGroup(const AStringVector & a_Restrictions, continue; } } - + // Add the permission: { SQLite::Statement stmt(m_DB, "INSERT INTO RestrictionItem (Permission, PermGroupID) VALUES (?, ?)"); @@ -1369,7 +1369,7 @@ bool cRankManager::AddRestrictionsToGroup(const AStringVector & a_Restrictions, } } } // for itr - a_Restrictions[] - + // Adding succeeded: return true; } @@ -1397,7 +1397,7 @@ void cRankManager::RemoveRank(const AString & a_RankName, const AString & a_Repl LOGWARNING("%s: Cannot remove rank %s, it is the default rank and the replacement rank doesn't exist.", __FUNCTION__, a_RankName.c_str()); return; } - + AStringVector res; try { @@ -1413,7 +1413,7 @@ void cRankManager::RemoveRank(const AString & a_RankName, const AString & a_Repl } RemoveRankID = stmt.getColumn(0).getInt(); } - + // Get the RankID for the replacement rank: int ReplacementRankID = -1; { @@ -1424,14 +1424,14 @@ void cRankManager::RemoveRank(const AString & a_RankName, const AString & a_Repl ReplacementRankID = stmt.getColumn(0).getInt(); } } - + // Remove the rank's bindings to groups: { SQLite::Statement stmt(m_DB, "DELETE FROM RankPermGroup WHERE RankID = ?"); stmt.bind(1, RemoveRankID); stmt.exec(); } - + // Adjust players: if (ReplacementRankID == -1) { @@ -1448,7 +1448,7 @@ void cRankManager::RemoveRank(const AString & a_RankName, const AString & a_Repl stmt.bind(2, RemoveRankID); stmt.exec(); } - + // Remove the rank from the DB: { SQLite::Statement stmt(m_DB, "DELETE FROM Rank WHERE RankID = ?"); @@ -1476,7 +1476,7 @@ void cRankManager::RemoveGroup(const AString & a_GroupName) { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + try { // Get the ID of the group: @@ -1491,21 +1491,21 @@ void cRankManager::RemoveGroup(const AString & a_GroupName) } GroupID = stmt.getColumn(0).getInt(); } - + // Remove all permissions from the group: { SQLite::Statement stmt(m_DB, "DELETE FROM PermissionItem WHERE PermGroupID = ?"); stmt.bind(1, GroupID); stmt.exec(); } - + // Remove the group from all ranks that contain it: { SQLite::Statement stmt(m_DB, "DELETE FROM RankPermGroup WHERE PermGroupID = ?"); stmt.bind(1, GroupID); stmt.exec(); } - + // Remove the group itself: { SQLite::Statement stmt(m_DB, "DELETE FROM PermGroup WHERE PermGroupID = ?"); @@ -1527,7 +1527,7 @@ void cRankManager::RemoveGroupFromRank(const AString & a_GroupName, const AStrin { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + try { // Get the IDs of the group and the rank: @@ -1549,14 +1549,14 @@ void cRankManager::RemoveGroupFromRank(const AString & a_GroupName, const AStrin GroupID = stmt.getColumn(0).getInt(); RankID = stmt.getColumn(1).getInt(); } - + // Remove the group from all ranks that contain it: { SQLite::Statement stmt(m_DB, "DELETE FROM RankPermGroup WHERE PermGroupID = ?"); stmt.bind(1, GroupID); stmt.exec(); } - + // Remove the group-to-rank binding: { SQLite::Statement stmt(m_DB, "DELETE FROM RankPermGroup WHERE PermGroupID = ? AND RankID = ?"); @@ -1579,7 +1579,7 @@ void cRankManager::RemovePermissionFromGroup(const AString & a_Permission, const { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + try { // Get the ID of the group: @@ -1594,7 +1594,7 @@ void cRankManager::RemovePermissionFromGroup(const AString & a_Permission, const } GroupID = stmt.getColumn(0).getInt(); } - + // Remove the permission from the group: { SQLite::Statement stmt(m_DB, "DELETE FROM PermissionItem WHERE PermGroupID = ? AND Permission = ?"); @@ -1619,7 +1619,7 @@ void cRankManager::RemoveRestrictionFromGroup(const AString & a_Restriction, con { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + try { // Get the ID of the group: @@ -1634,7 +1634,7 @@ void cRankManager::RemoveRestrictionFromGroup(const AString & a_Restriction, con } GroupID = stmt.getColumn(0).getInt(); } - + // Remove the permission from the group: { SQLite::Statement stmt(m_DB, "DELETE FROM RestrictionItem WHERE PermGroupID = ? AND Permission = ?"); @@ -1659,7 +1659,7 @@ bool cRankManager::RenameRank(const AString & a_OldName, const AString & a_NewNa { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + try { // Check that NewName doesn't exist: @@ -1672,7 +1672,7 @@ bool cRankManager::RenameRank(const AString & a_OldName, const AString & a_NewNa return false; } } - + // Rename: { SQLite::Statement stmt(m_DB, "UPDATE Rank SET Name = ? WHERE Name = ?"); @@ -1684,7 +1684,7 @@ bool cRankManager::RenameRank(const AString & a_OldName, const AString & a_NewNa return false; } } - + // Update the default rank, if it was the one being renamed: if (a_OldName == m_DefaultRank) { @@ -1709,7 +1709,7 @@ bool cRankManager::RenameGroup(const AString & a_OldName, const AString & a_NewN { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + try { // Check that NewName doesn't exist: @@ -1722,7 +1722,7 @@ bool cRankManager::RenameGroup(const AString & a_OldName, const AString & a_NewN return false; } } - + // Rename: bool res; { @@ -1731,7 +1731,7 @@ bool cRankManager::RenameGroup(const AString & a_OldName, const AString & a_NewN stmt.bind(2, a_OldName); res = (stmt.exec() > 0); } - + return res; } catch (const SQLite::Exception & ex) @@ -1750,7 +1750,7 @@ void cRankManager::SetPlayerRank(const AString & a_PlayerUUID, const AString & a { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + try { // Get the rank ID: @@ -1765,7 +1765,7 @@ void cRankManager::SetPlayerRank(const AString & a_PlayerUUID, const AString & a } RankID = stmt.getColumn(0).getInt(); } - + // Update the player's rank, if already in DB: { SQLite::Statement stmt(m_DB, "UPDATE PlayerRank SET RankID = ?, PlayerName = ? WHERE PlayerUUID = ?"); @@ -1778,7 +1778,7 @@ void cRankManager::SetPlayerRank(const AString & a_PlayerUUID, const AString & a return; } } - + // The player is not yet in the DB, add them: SQLite::Statement stmt(m_DB, "INSERT INTO PlayerRank (RankID, PlayerUUID, PlayerName) VALUES (?, ?, ?)"); stmt.bind(1, RankID); @@ -1789,7 +1789,7 @@ void cRankManager::SetPlayerRank(const AString & a_PlayerUUID, const AString & a // Successfully added the player return; } - + LOGWARNING("%s: Failed to set player UUID %s to rank %s.", __FUNCTION__, a_PlayerUUID.c_str(), a_RankName.c_str() ); @@ -1838,7 +1838,7 @@ void cRankManager::SetRankVisuals( { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + try { SQLite::Statement stmt(m_DB, "UPDATE Rank SET MsgPrefix = ?, MsgSuffix = ?, MsgNameColorCode = ? WHERE Name = ?"); @@ -1870,7 +1870,7 @@ bool cRankManager::GetRankVisuals( { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + try { SQLite::Statement stmt(m_DB, "SELECT MsgPrefix, MsgSuffix, MsgNameColorCode FROM Rank WHERE Name = ?"); @@ -1900,7 +1900,7 @@ bool cRankManager::RankExists(const AString & a_RankName) { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + try { SQLite::Statement stmt(m_DB, "SELECT * FROM Rank WHERE Name = ?"); @@ -1926,7 +1926,7 @@ bool cRankManager::GroupExists(const AString & a_GroupName) { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + try { SQLite::Statement stmt(m_DB, "SELECT * FROM PermGroup WHERE Name = ?"); @@ -1952,7 +1952,7 @@ bool cRankManager::IsPlayerRankSet(const AString & a_PlayerUUID) { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + try { SQLite::Statement stmt(m_DB, "SELECT * FROM PlayerRank WHERE PlayerUUID = ?"); @@ -1978,7 +1978,7 @@ bool cRankManager::IsGroupInRank(const AString & a_GroupName, const AString & a_ { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + try { SQLite::Statement stmt(m_DB, @@ -2010,7 +2010,7 @@ bool cRankManager::IsPermissionInGroup(const AString & a_Permission, const AStri { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + try { SQLite::Statement stmt(m_DB, @@ -2041,7 +2041,7 @@ bool cRankManager::IsRestrictionInGroup(const AString & a_Restriction, const ASt { ASSERT(m_IsInitialized); cCSLock Lock(m_CS); - + try { SQLite::Statement stmt(m_DB, diff --git a/src/RankManager.h b/src/RankManager.h index b3431b7d1..73d94a5a7 100644 --- a/src/RankManager.h +++ b/src/RankManager.h @@ -35,81 +35,81 @@ public: m_Transaction(a_RankManager.m_DB) { } - + ~cMassChangeLock() { m_Transaction.commit(); } - + protected: cCSLock m_Lock; SQLite::Transaction m_Transaction; }; - - + + /** Creates the rank manager. Needs to be initialized before other use. */ cRankManager(void); ~cRankManager(); - + /** Initializes the rank manager. Performs migration and default-setting if no data is found in the DB. The a_MojangAPI param is used when migrating from old ini files, to look up player UUIDs. */ void Initialize(cMojangAPI & a_MojangAPI); - + /** Returns the name of the rank that the specified player has assigned to them. If the player has no rank assigned, returns an empty string (NOT the default rank). */ AString GetPlayerRankName(const AString & a_PlayerUUID); - + /** Returns the last name that the specified player has. An empty string is returned if the player isn't in the database. */ AString GetPlayerName(const AString & a_PlayerUUID); - + /** Returns the names of Groups that the specified player has assigned to them. */ AStringVector GetPlayerGroups(const AString & a_PlayerUUID); - + /** Returns the permissions that the specified player has assigned to them. If the player has no rank assigned to them, returns the default rank's permissions. */ AStringVector GetPlayerPermissions(const AString & a_PlayerUUID); - + /** Returns the restrictions that the specified player has assigned to them. If the player has no rank assigned to them, returns the default rank's restrictions. */ AStringVector GetPlayerRestrictions(const AString & a_PlayerUUID); - + /** Returns the names of groups that the specified rank has assigned to it. Returns an empty vector if the rank doesn't exist. */ AStringVector GetRankGroups(const AString & a_RankName); - + /** Returns the permissions that the specified group has assigned to it. Returns an empty vector if the group doesn't exist. */ AStringVector GetGroupPermissions(const AString & a_GroupName); - + /** Returns the restrictions that the specified group has assigned to it. Returns an empty vector if the group doesn't exist. */ AStringVector GetGroupRestrictions(const AString & a_GroupName); - + /** Returns all permissions that the specified rank has assigned to it, through all its groups. Returns an empty vector if the rank doesn't exist. Any non-existent groups are ignored. */ AStringVector GetRankPermissions(const AString & a_RankName); - + /** Returns all restrictions that the specified rank has assigned to it, through all its groups. Returns an empty vector if the rank doesn't exist. Any non-existent groups are ignored. */ AStringVector GetRankRestrictions(const AString & a_RankName); - + /** Returns the short uuids of all defined players. The returned players are ordered by their name (NOT their UUIDs). */ AStringVector GetAllPlayerUUIDs(void); - + /** Returns the names of all defined ranks. */ AStringVector GetAllRanks(void); - + /** Returns the names of all permission groups. */ AStringVector GetAllGroups(void); - + /** Returns all the distinct permissions that are stored in the DB. */ AStringVector GetAllPermissions(void); - + /** Returns all the distinct restrictions that are stored in the DB. */ AStringVector GetAllRestrictions(void); - + /** Returns all the distinct permissions and restrictions that are stored in the DB. */ AStringVector GetAllPermissionsRestrictions(void); @@ -121,7 +121,7 @@ public: AString & a_MsgSuffix, AString & a_MsgNameColorCode ); - + /** Adds a new rank. No action if the rank already exists. */ void AddRank( const AString & a_RankName, @@ -129,38 +129,38 @@ public: const AString & a_MsgSuffix, const AString & a_MsgNameColorCode ); - + /** Adds a new permission group. No action if such a group already exists. */ void AddGroup(const AString & a_GroupName); - + /** Bulk-adds groups. Group names that already exist are silently skipped. */ void AddGroups(const AStringVector & a_GroupNames); - + /** Adds the specified permission group to the specified rank. Fails if the rank or group names are not found. Returns true if successful, false on error. */ bool AddGroupToRank(const AString & a_GroupName, const AString & a_RankName); - + /** Adds the specified permission to the specified permission group. Fails if the permission group name is not found. Returns true if successful, false on error. */ bool AddPermissionToGroup(const AString & a_Permission, const AString & a_GroupName); - + /** Adds the specified restriction to the specified group. Fails if the group name is not found. Returns true if successful, false on error. */ bool AddRestrictionToGroup(const AString & a_Restriction, const AString & a_GroupName); - + /** Adds the specified permissions to the specified permission group. Fails if the permission group name is not found. Returns true if successful, false on error. */ bool AddPermissionsToGroup(const AStringVector & a_Permissions, const AString & a_GroupName); - + /** Adds the specified restrictions to the specified group. Fails if the group name is not found. Returns true if successful, false on error. */ bool AddRestrictionsToGroup(const AStringVector & a_Restrictions, const AString & a_GroupName); - + /** Removes the specified rank. All players assigned to that rank will be re-assigned to a_ReplacementRankName. If a_ReplacementRankName is empty or not a valid rank, the player will be removed from the DB, @@ -168,32 +168,32 @@ public: If the rank being removed is the default rank, the default will be changed to the replacement rank; the operation fails silently if there's no replacement. */ void RemoveRank(const AString & a_RankName, const AString & a_ReplacementRankName); - + /** Removes the specified group completely. The group will first be removed from all ranks using it, and then removed itself. */ void RemoveGroup(const AString & a_GroupName); - + /** Removes the specified group from the specified rank. The group will stay defined, even if no rank is using it. */ void RemoveGroupFromRank(const AString & a_GroupName, const AString & a_RankName); - + /** Removes the specified permission from the specified group. */ void RemovePermissionFromGroup(const AString & a_Permission, const AString & a_GroupName); - + /** Removes the specified restriction from the specified group. */ void RemoveRestrictionFromGroup(const AString & a_Restriction, const AString & a_GroupName); - + /** Renames the specified rank. No action if the rank name is not found. Fails if the new name is already used. Updates the cached m_DefaultRank if the default rank is being renamed. Returns true on success, false on failure. */ bool RenameRank(const AString & a_OldName, const AString & a_NewName); - + /** Renames the specified group. No action if the rank name is not found. Fails if the new name is already used. Returns true on success, false on failure. */ bool RenameGroup(const AString & a_OldName, const AString & a_NewName); - + /** Sets the specified player's rank. If the player already had rank assigned to them, it is overwritten with the new rank and name. Note that this doesn't change the cPlayer if the player is already connected, you need to update all the @@ -206,7 +206,7 @@ public: all the instances manually. No action if the player has no rank assigned to them already. */ void RemovePlayerRank(const AString & a_PlayerUUID); - + /** Sets the message visuals of an existing rank. No action if the rank name is not found. */ void SetRankVisuals( const AString & a_RankName, @@ -214,7 +214,7 @@ public: const AString & a_MsgSuffix, const AString & a_MsgNameColorCode ); - + /** Returns the message visuals of an existing rank. Returns true if successful, false on error (rank doesn't exist). */ bool GetRankVisuals( @@ -223,25 +223,25 @@ public: AString & a_MsgSuffix, AString & a_MsgNameColorCode ); - + /** Returns true iff the specified rank exists in the DB. */ bool RankExists(const AString & a_RankName); - + /** Returns true iff the specified group exists in the DB. */ bool GroupExists(const AString & a_GroupName); - + /** Returns true iff the specified player has a rank assigned to them in the DB. */ bool IsPlayerRankSet(const AString & a_PlayerUUID); - + /** Returns true iff the specified rank contains the specified group. */ bool IsGroupInRank(const AString & a_GroupName, const AString & a_RankName); - + /** Returns true iff the specified group contains the specified permission. */ bool IsPermissionInGroup(const AString & a_Permission, const AString & a_GroupName); - + /** Returns true iff the specified group contains the specified restriction. */ bool IsRestrictionInGroup(const AString & a_Restriction, const AString & a_GroupName); - + /** Called by cMojangAPI whenever the playername-uuid pairing is discovered. Updates the DB. */ void NotifyNameUUID(const AString & a_PlayerName, const AString & a_UUID); @@ -255,7 +255,7 @@ public: /** Removes all player ranks from the database. Note that this doesn't change the cPlayer instances for the already connected players, you need to update all the instances manually. */ void ClearPlayerRanks(void); - + /** Updates the playername that is saved with this uuid. Returns false if a error occurred */ bool UpdatePlayerName(const AString & a_PlayerUUID, const AString & a_NewPlayerName); @@ -263,24 +263,24 @@ protected: /** The database storage for all the data. Protected by m_CS. */ SQLite::Database m_DB; - + /** The name of the default rank. Kept as a cache so that queries for it don't need to go through the DB. */ AString m_DefaultRank; /** The mutex protecting m_DB and m_DefaultRank against multi-threaded access. */ cCriticalSection m_CS; - + /** Set to true once the manager is initialized. */ bool m_IsInitialized; /** The MojangAPI instance that is used for translating playernames to UUIDs. Set in Initialize(), may be nullptr. */ cMojangAPI * m_MojangAPI; - - + + /** Returns true if all the DB tables are empty, indicating a fresh new install. */ bool AreDBTablesEmpty(void); - + /** Returns true iff the specified DB table is empty. If there's an error while querying, returns false. */ bool IsDBTableEmpty(const AString & a_TableName); diff --git a/src/Scoreboard.cpp b/src/Scoreboard.cpp index 9f251ab94..5e416c0d1 100644 --- a/src/Scoreboard.cpp +++ b/src/Scoreboard.cpp @@ -30,13 +30,13 @@ AString cObjective::TypeToString(eType a_Type) case otStatBlockMine: return "stat.mineBlock"; case otStatEntityKill: return "stat.killEntity"; case otStatEntityKilledBy: return "stat.entityKilledBy"; - + // clang optimisises this line away then warns that it has done so. #if !defined(__clang__) default: return ""; #endif } - + } diff --git a/src/Server.h b/src/Server.h index 9131697c2..b6c8bfe1f 100644 --- a/src/Server.h +++ b/src/Server.h @@ -61,22 +61,22 @@ public: bool InitServer(cSettingsRepositoryInterface & a_Settings, bool a_ShouldAuth); // tolua_begin - + const AString & GetDescription(void) const {return m_Description; } // Player counts: int GetMaxPlayers(void) const { return m_MaxPlayers; } int GetNumPlayers(void) const; void SetMaxPlayers(int a_MaxPlayers) { m_MaxPlayers = a_MaxPlayers; } - + /** Check if the player is queued to be transferred to a World. Returns true is Player is found in queue. */ bool IsPlayerInQueue(AString a_Username); - + /** Can login more than once with same username. Returns false if it is not allowed, true otherwise. */ bool DoesAllowMultiLogin(void) { return m_bAllowMultiLogin; } - + // Hardcore mode or not: bool IsHardcore(void) const { return m_bIsHardcore; } @@ -85,85 +85,85 @@ public: bool Start(void); bool Command(cClientHandle & a_Client, AString & a_Cmd); - + /** Executes the console command, sends output through the specified callback */ void ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallback & a_Output); - + /** Lists all available console commands and their helpstrings */ void PrintHelp(const AStringVector & a_Split, cCommandOutputCallback & a_Output); /** Binds the built-in console commands with the plugin manager */ static void BindBuiltInConsoleCommands(void); - + void Shutdown(void); void KickUser(int a_ClientID, const AString & a_Reason); - + /** Authenticates the specified user, called by cAuthenticator */ void AuthenticateUser(int a_ClientID, const AString & a_Name, const AString & a_UUID, const Json::Value & a_Properties); const AString & GetServerID(void) const { return m_ServerID; } // tolua_export - + /** Called by cClientHandle's destructor; stop m_SocketThreads from calling back into a_Client */ void ClientDestroying(const cClientHandle * a_Client); - + /** Don't tick a_Client anymore, it will be ticked from its cPlayer instead */ void ClientMovedToWorld(const cClientHandle * a_Client); - + /** Notifies the server that a player was created; the server uses this to adjust the number of players */ void PlayerCreated(const cPlayer * a_Player); - + /** Notifies the server that a player is being destroyed; the server uses this to adjust the number of players */ void PlayerDestroying(const cPlayer * a_Player); /** Returns base64 encoded favicon data (obtained from favicon.png) */ const AString & GetFaviconData(void) const { return m_FaviconData; } - + cRsaPrivateKey & GetPrivateKey(void) { return m_PrivateKey; } const AString & GetPublicKeyDER(void) const { return m_PublicKeyDER; } - + /** Returns true if authentication has been turned on in server settings. */ bool ShouldAuthenticate(void) const { return m_ShouldAuthenticate; } // tolua_export - + /** Returns true if offline UUIDs should be used to load data for players whose normal UUIDs cannot be found. Loaded from the settings.ini [PlayerData].LoadOfflinePlayerData setting. */ bool ShouldLoadOfflinePlayerData(void) const { return m_ShouldLoadOfflinePlayerData; } - + /** Returns true if old-style playernames should be used to load data for players whose regular datafiles cannot be found. This allows a seamless transition from name-based to UUID-based player storage. Loaded from the settings.ini [PlayerData].LoadNamedPlayerData setting. */ bool ShouldLoadNamedPlayerData(void) const { return m_ShouldLoadNamedPlayerData; } - + /** Returns true if BungeeCord logins (that specify the player's UUID) are allowed. Read from settings, admins should set this to true only when they chain to BungeeCord, it makes the server vulnerable to identity theft through direct connections. */ bool ShouldAllowBungeeCord(void) const { return m_ShouldAllowBungeeCord; } - + private: friend class cRoot; // so cRoot can create and destroy cServer friend class cServerListenCallbacks; // Accessing OnConnectionAccepted() - + /** The server tick thread takes care of the players who aren't yet spawned in a world */ class cTickThread : public cIsThread { typedef cIsThread super; - + public: cTickThread(cServer & a_Server); - + protected: cServer & m_Server; - + // cIsThread overrides: virtual void Execute(void) override; } ; - - + + /** The network sockets listening for client connections. */ cServerHandlePtrs m_ServerHandles; - + /** Protects m_Clients and m_ClientsToRemove against multithreaded access. */ cCriticalSection m_CSClients; @@ -172,7 +172,7 @@ private: /** Clients that have just been moved into a world and are to be removed from m_Clients in the next Tick(). */ cClientHandles m_ClientsToRemove; - + /** Protects m_PlayerCount against multithreaded access. */ mutable cCriticalSection m_CSPlayerCount; @@ -184,49 +184,49 @@ private: /** Adjustment to m_PlayerCount to be applied in the Tick thread. */ int m_PlayerCountDiff; - + int m_ClientViewDistance; // The default view distance for clients; settable in Settings.ini bool m_bIsConnected; // true - connected false - not connected std::atomic m_bRestarting; - + /** The private key used for the assymetric encryption start in the protocols */ cRsaPrivateKey m_PrivateKey; - + /** Public key for m_PrivateKey, ASN1-DER-encoded */ AString m_PublicKeyDER; - + cRCONServer m_RCONServer; - + AString m_Description; AString m_FaviconData; int m_MaxPlayers; bool m_bIsHardcore; - + /** True - allow same username to login more than once False - only once */ bool m_bAllowMultiLogin; - + cTickThread m_TickThread; cEvent m_RestartEvent; - + /** The server ID used for client authentication */ AString m_ServerID; - + /** If true, players will be online-authenticated agains Mojang servers. This setting is the same as the "online-mode" setting in Vanilla. */ bool m_ShouldAuthenticate; - + /** True if offline UUIDs should be used to load data for players whose normal UUIDs cannot be found. This allows transitions from an offline (no-auth) server to an online one. Loaded from the settings.ini [PlayerData].LoadOfflinePlayerData setting. */ bool m_ShouldLoadOfflinePlayerData; - + /** True if old-style playernames should be used to load data for players whose regular datafiles cannot be found. This allows a seamless transition from name-based to UUID-based player storage. Loaded from the settings.ini [PlayerData].LoadNamedPlayerData setting. */ bool m_ShouldLoadNamedPlayerData; - + /** True if BungeeCord handshake packets (with player UUID) should be accepted. */ bool m_ShouldAllowBungeeCord; @@ -243,9 +243,9 @@ private: /** Creates a new cClientHandle instance and adds it to the list of clients. Returns the cClientHandle reinterpreted as cTCPLink callbacks. */ cTCPLink::cCallbacksPtr OnConnectionAccepted(const AString & a_RemoteIPAddress); - + bool Tick(float a_Dt); - + /** Ticks the clients in m_Clients, manages the list in respect to removing clients */ void TickClients(float a_Dt); }; // tolua_export diff --git a/src/SetChunkData.cpp b/src/SetChunkData.cpp index c0ae31fd3..d85f78459 100644 --- a/src/SetChunkData.cpp +++ b/src/SetChunkData.cpp @@ -48,7 +48,7 @@ cSetChunkData::cSetChunkData( // Copy block types and metas: memcpy(m_BlockTypes, a_BlockTypes, sizeof(cChunkDef::BlockTypes)); memcpy(m_BlockMetas, a_BlockMetas, sizeof(cChunkDef::BlockNibbles)); - + // Copy lights, if both given: if ((a_BlockLight != nullptr) && (a_SkyLight != nullptr)) { @@ -60,7 +60,7 @@ cSetChunkData::cSetChunkData( { m_IsLightValid = false; } - + // Copy the heightmap, if available: if (a_HeightMap != nullptr) { @@ -71,7 +71,7 @@ cSetChunkData::cSetChunkData( { m_IsHeightMapValid = false; } - + // Copy biomes, if available: if (a_Biomes != nullptr) { @@ -82,7 +82,7 @@ cSetChunkData::cSetChunkData( { m_AreBiomesValid = false; } - + // Move entities and blockentities: m_Entities = std::move(a_Entities); m_BlockEntities = std::move(a_BlockEntities); diff --git a/src/SetChunkData.h b/src/SetChunkData.h index bf5283569..2f3c3d6a3 100644 --- a/src/SetChunkData.h +++ b/src/SetChunkData.h @@ -47,50 +47,50 @@ public: cBlockEntityList && a_BlockEntities, bool a_ShouldMarkDirty ); - + int GetChunkX(void) const { return m_ChunkX; } int GetChunkZ(void) const { return m_ChunkZ; } - + /** Returns the internal storage of the block types, read-only. */ const cChunkDef::BlockTypes & GetBlockTypes(void) const { return m_BlockTypes; } - + /** Returns the internal storage of the block types, read-only. */ const cChunkDef::BlockNibbles & GetBlockMetas(void) const { return m_BlockMetas; } - + /** Returns the internal storage of the block light, read-only. */ const cChunkDef::BlockNibbles & GetBlockLight(void) const { return m_BlockLight; } - + /** Returns the internal storage of the block types, read-only. */ const cChunkDef::BlockNibbles & GetSkyLight(void) const { return m_SkyLight; } - + /** Returns the internal storage for heightmap, read-only. */ const cChunkDef::HeightMap & GetHeightMap(void) const { return m_HeightMap; } - + /** Returns the internal storage for biomes, read-write. */ cChunkDef::BiomeMap & GetBiomes(void) { return m_Biomes; } - + /** Returns the internal storage for entities, read-write. */ cEntityList & GetEntities(void) { return m_Entities; } - + /** Returns the internal storage for block entities, read-write. */ cBlockEntityList & GetBlockEntities(void) { return m_BlockEntities; } - + /** Returns whether both light arrays stored in this object are valid. */ bool IsLightValid(void) const { return m_IsLightValid; } - + /** Returns whether the heightmap stored in this object is valid. */ bool IsHeightMapValid(void) const { return m_IsHeightMapValid; } /** Returns whether the biomes stored in this object are valid. */ bool AreBiomesValid(void) const { return m_AreBiomesValid; } - + /** Returns whether the chunk should be marked as dirty after its data is set. Used by the generator to save chunks after generating. */ bool ShouldMarkDirty(void) const { return m_ShouldMarkDirty; } - + /** Marks the biomes stored in this object as valid. */ void MarkBiomesValid(void) { m_AreBiomesValid = true; } - + /** Calculates the heightmap based on the contained blocktypes and marks it valid. */ void CalculateHeightMap(void); @@ -100,7 +100,7 @@ public: protected: int m_ChunkX; int m_ChunkZ; - + cChunkDef::BlockTypes m_BlockTypes; cChunkDef::BlockNibbles m_BlockMetas; cChunkDef::BlockNibbles m_BlockLight; @@ -109,7 +109,7 @@ protected: cChunkDef::BiomeMap m_Biomes; cEntityList m_Entities; cBlockEntityList m_BlockEntities; - + bool m_IsLightValid; bool m_IsHeightMapValid; bool m_AreBiomesValid; diff --git a/src/SettingsRepositoryInterface.h b/src/SettingsRepositoryInterface.h index a40163dd9..d10f94119 100644 --- a/src/SettingsRepositoryInterface.h +++ b/src/SettingsRepositoryInterface.h @@ -23,7 +23,7 @@ public: /** Add a key comment, will always fail if the repository does not support comments */ virtual bool AddKeyComment(const AString & keyname, const AString & comment) = 0; - + /** Return a key comment, returns "" for repositories that do not return comments */ virtual AString GetKeyComment(const AString & keyname, const int commentID) const = 0; diff --git a/src/Simulator/DelayedFluidSimulator.cpp b/src/Simulator/DelayedFluidSimulator.cpp index e0da3ff61..d21e8dc6d 100644 --- a/src/Simulator/DelayedFluidSimulator.cpp +++ b/src/Simulator/DelayedFluidSimulator.cpp @@ -21,7 +21,7 @@ bool cDelayedFluidSimulatorChunkData::cSlot::Add(int a_RelX, int a_RelY, int a_R { ASSERT(a_RelZ >= 0); ASSERT(a_RelZ < static_cast(ARRAYCOUNT(m_Blocks))); - + cCoordWithIntVector & Blocks = m_Blocks[a_RelZ]; int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ); for (cCoordWithIntVector::const_iterator itr = Blocks.begin(), end = Blocks.end(); itr != end; ++itr) @@ -85,12 +85,12 @@ void cDelayedFluidSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, // Not inside the world (may happen when rclk with a full bucket - the client sends Y = -1) return; } - + if ((a_Chunk == nullptr) || !a_Chunk->IsValid()) { return; } - + int RelX = a_BlockX - a_Chunk->GetPosX() * cChunkDef::Width; int RelZ = a_BlockZ - a_Chunk->GetPosZ() * cChunkDef::Width; BLOCKTYPE BlockType = a_Chunk->GetBlock(RelX, a_BlockY, RelZ); @@ -102,7 +102,7 @@ void cDelayedFluidSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, auto ChunkDataRaw = (m_FluidBlock == E_BLOCK_WATER) ? a_Chunk->GetWaterSimulatorData() : a_Chunk->GetLavaSimulatorData(); cDelayedFluidSimulatorChunkData * ChunkData = static_cast(ChunkDataRaw); cDelayedFluidSimulatorChunkData::cSlot & Slot = ChunkData->m_Slots[m_AddSlotNum]; - + // Add, if not already present: if (!Slot.Add(RelX, a_BlockY, RelZ)) { @@ -135,7 +135,7 @@ void cDelayedFluidSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a auto ChunkDataRaw = (m_FluidBlock == E_BLOCK_WATER) ? a_Chunk->GetWaterSimulatorData() : a_Chunk->GetLavaSimulatorData(); cDelayedFluidSimulatorChunkData * ChunkData = static_cast(ChunkDataRaw); cDelayedFluidSimulatorChunkData::cSlot & Slot = ChunkData->m_Slots[m_SimSlotNum]; - + // Simulate all the blocks in the scheduled slot: for (size_t i = 0; i < ARRAYCOUNT(Slot.m_Blocks); i++) { diff --git a/src/Simulator/DelayedFluidSimulator.h b/src/Simulator/DelayedFluidSimulator.h index 05f70e2fd..62efb717e 100644 --- a/src/Simulator/DelayedFluidSimulator.h +++ b/src/Simulator/DelayedFluidSimulator.h @@ -24,19 +24,19 @@ public: public: /** Returns true if the specified block is stored */ bool HasBlock(int a_RelX, int a_RelY, int a_RelZ); - + /** Adds the specified block unless already present; returns true if added, false if the block was already present */ bool Add(int a_RelX, int a_RelY, int a_RelZ); - + /** Array of block containers, each item stores blocks for one Z coord Int param is the block index (for faster duplicate comparison in Add()) */ cCoordWithIntVector m_Blocks[16]; } ; - + cDelayedFluidSimulatorChunkData(int a_TickDelay); virtual ~cDelayedFluidSimulatorChunkData(); - + /** Slots, one for each delay tick, each containing the blocks to simulate */ cSlot * m_Slots; } ; @@ -52,25 +52,25 @@ class cDelayedFluidSimulator : public: cDelayedFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid, int a_TickDelay); - + // cSimulator overrides: virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override; virtual void Simulate(float a_Dt) override; virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override; virtual cFluidSimulatorData * CreateChunkData(void) override { return new cDelayedFluidSimulatorChunkData(m_TickDelay); } - + protected: int m_TickDelay; // Count of the m_Slots array in each ChunkData int m_AddSlotNum; // Index into m_Slots[] where to add new blocks in each ChunkData int m_SimSlotNum; // Index into m_Slots[] where to simulate blocks in each ChunkData - + int m_TotalBlocks; // Statistics only: the total number of blocks currently queued /* Slots: | 0 | 1 | ... | m_AddSlotNum | m_SimSlotNum | ... | m_TickDelay - 1 | | adding blocks here ^ | ^ simulating here */ - + /** Called from SimulateChunk() to simulate each block in one slot of blocks. Descendants override this method to provide custom simulation. */ virtual void SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ) = 0; } ; diff --git a/src/Simulator/FireSimulator.cpp b/src/Simulator/FireSimulator.cpp index b1d36d526..5fc19ae15 100644 --- a/src/Simulator/FireSimulator.cpp +++ b/src/Simulator/FireSimulator.cpp @@ -120,7 +120,7 @@ void cFireSimulator::SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, ++itr; continue; } - + // Burn out the fire one step by increasing the meta: /* FLOG("FS: Fire at {%d, %d, %d} is stepping", @@ -224,7 +224,7 @@ void cFireSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * { return; } - + int RelX = a_BlockX - a_Chunk->GetPosX() * cChunkDef::Width; int RelZ = a_BlockZ - a_Chunk->GetPosZ() * cChunkDef::Width; BLOCKTYPE BlockType = a_Chunk->GetBlock(RelX, a_BlockY, RelZ); @@ -232,7 +232,7 @@ void cFireSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * { return; } - + // Check for duplicates: cFireSimulatorChunkData & ChunkData = a_Chunk->GetFireSimulatorData(); for (cCoordWithIntList::iterator itr = ChunkData.begin(), end = ChunkData.end(); itr != end; ++itr) @@ -269,7 +269,7 @@ int cFireSimulator::GetBurnStepTime(cChunk * a_Chunk, int a_RelX, int a_RelY, in } IsBlockBelowSolid = cBlockInfo::IsSolid(BlockBelow); } - + for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++) { BLOCKTYPE BlockType; @@ -307,7 +307,7 @@ void cFireSimulator::TrySpreadFire(cChunk * a_Chunk, int a_RelX, int a_RelY, int return; } */ - + for (int x = a_RelX - 1; x <= a_RelX + 1; x++) { for (int z = a_RelZ - 1; z <= a_RelZ + 1; z++) @@ -316,12 +316,12 @@ void cFireSimulator::TrySpreadFire(cChunk * a_Chunk, int a_RelX, int a_RelY, int { // No need to check the coords for equality with the parent block, // it cannot catch fire anyway (because it's not an air block) - + if (m_World.GetTickRandomNumber(MAX_CHANCE_FLAMMABILITY) > m_Flammability) { continue; } - + // Start the fire in the neighbor {x, y, z} /* FLOG("FS: Trying to start fire at {%d, %d, %d}.", @@ -332,12 +332,12 @@ void cFireSimulator::TrySpreadFire(cChunk * a_Chunk, int a_RelX, int a_RelY, int { int a_PosX = x + a_Chunk->GetPosX() * cChunkDef::Width; int a_PosZ = z + a_Chunk->GetPosZ() * cChunkDef::Width; - + if (cRoot::Get()->GetPluginManager()->CallHookBlockSpread(m_World, a_PosX, y, a_PosZ, ssFireSpread)) { return; } - + FLOG("FS: Starting new fire at {%d, %d, %d}.", a_PosX, y, a_PosZ); a_Chunk->UnboundedRelSetBlock(x, y, z, E_BLOCK_FIRE, 0); } @@ -406,13 +406,13 @@ bool cFireSimulator::CanStartFireInBlock(cChunk * a_NearChunk, int a_RelX, int a // The chunk is not accessible return false; } - + if (BlockType != E_BLOCK_AIR) { // Only an air block can be replaced by a fire block return false; } - + for (size_t i = 0; i < ARRAYCOUNT(gNeighborCoords); i++) { if (!a_NearChunk->UnboundedRelGetBlock(a_RelX + gNeighborCoords[i].x, a_RelY + gNeighborCoords[i].y, a_RelZ + gNeighborCoords[i].z, BlockType, BlockMeta)) diff --git a/src/Simulator/FireSimulator.h b/src/Simulator/FireSimulator.h index a59c66de5..bda02cbf7 100644 --- a/src/Simulator/FireSimulator.h +++ b/src/Simulator/FireSimulator.h @@ -39,22 +39,22 @@ protected: /** Chance [0..100000] of an adjacent fuel to catch fire on each tick */ int m_Flammability; - + /** Chance [0..100000] of a fuel burning out being replaced by a new fire block instead of an air block */ int m_ReplaceFuelChance; - - + + virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override; - + /** Returns the time [msec] after which the specified fire block is stepped again; based on surrounding fuels */ int GetBurnStepTime(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ); - + /** Tries to spread fire to a neighborhood of the specified block */ void TrySpreadFire(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ); - + /** Removes all burnable blocks neighboring the specified block */ void RemoveFuelNeighbors(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ); - + /** Returns true if a fire can be started in the specified block, that is, it is an air block and has fuel next to it. Note that a_NearChunk may be a chunk neighbor to the block specified! diff --git a/src/Simulator/FloodyFluidSimulator.cpp b/src/Simulator/FloodyFluidSimulator.cpp index 518357f0b..afa54b2ad 100644 --- a/src/Simulator/FloodyFluidSimulator.cpp +++ b/src/Simulator/FloodyFluidSimulator.cpp @@ -54,7 +54,7 @@ void cFloodyFluidSimulator::SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_Re a_Chunk->GetBlock(a_RelX, a_RelY, a_RelZ), a_Chunk->GetMeta(a_RelX, a_RelY, a_RelZ) ); - + BLOCKTYPE MyBlock; NIBBLETYPE MyMeta; a_Chunk->GetBlockTypeMeta(a_RelX, a_RelY, a_RelZ, MyBlock, MyMeta); @@ -108,7 +108,7 @@ void cFloodyFluidSimulator::SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_Re { SpreadXZ(a_Chunk, a_RelX, a_RelY, a_RelZ, NewMeta); } - + // If source creation is on, check for it here: if ( (m_NumNeighborsForSource > 0) && // Source creation is on @@ -189,7 +189,7 @@ bool cFloodyFluidSimulator::CheckTributaries(cChunk * a_Chunk, int a_RelX, int a } } // for i - Coords[] } // if not fed from above - + // Block is not fed, decrease by m_Falloff levels: if (a_MyMeta >= 8) { @@ -231,11 +231,11 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i const int BlockX = a_NearChunk->GetPosX() * cChunkDef::Width + a_RelX; const int BlockZ = a_NearChunk->GetPosZ() * cChunkDef::Width + a_RelZ; - + BLOCKTYPE BlockType; NIBBLETYPE BlockMeta; a_NearChunk->GetBlockTypeMeta(a_RelX, a_RelY, a_RelZ, BlockType, BlockMeta); - + if (IsAllowedBlock(BlockType)) { if ((BlockMeta == a_NewMeta) || IsHigherMeta(BlockMeta, a_NewMeta)) @@ -295,13 +295,13 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i { ASSERT(!"Unknown fluid!"); } - + if (!IsPassableForFluid(BlockType)) { // Can't spread there return; } - + // Wash away the block there, if possible: if (CanWashAway(BlockType)) { @@ -337,7 +337,7 @@ void cFloodyFluidSimulator::SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, i bool cFloodyFluidSimulator::CheckNeighborsForSource(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ) { FLOG(" Checking neighbors for source creation"); - + static const Vector3i NeighborCoords[] = { Vector3i(-1, 0, 0), @@ -345,7 +345,7 @@ bool cFloodyFluidSimulator::CheckNeighborsForSource(cChunk * a_Chunk, int a_RelX Vector3i( 0, 0, -1), Vector3i( 0, 0, 1), } ; - + int NumNeeded = m_NumNeighborsForSource; for (size_t i = 0; i < ARRAYCOUNT(NeighborCoords); i++) { diff --git a/src/Simulator/FloodyFluidSimulator.h b/src/Simulator/FloodyFluidSimulator.h index 44ac05ab3..7d6d81655 100644 --- a/src/Simulator/FloodyFluidSimulator.h +++ b/src/Simulator/FloodyFluidSimulator.h @@ -27,23 +27,23 @@ class cFloodyFluidSimulator : public cDelayedFluidSimulator { typedef cDelayedFluidSimulator super; - + public: cFloodyFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid, NIBBLETYPE a_Falloff, int a_TickDelay, int a_NumNeighborsForSource); - + protected: NIBBLETYPE m_Falloff; int m_NumNeighborsForSource; - + // cDelayedFluidSimulator overrides: virtual void SimulateBlock(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override; - + /** Checks tributaries, if not fed, decreases the block's level and returns true. */ bool CheckTributaries(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_MyMeta); /** Spreads into the specified block, if the blocktype there allows. a_Area is for checking. */ void SpreadToNeighbor(cChunk * a_NearChunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta); - + /** Checks if there are enough neighbors to create a source at the coords specified; turns into source and returns true if so. */ bool CheckNeighborsForSource(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ); diff --git a/src/Simulator/FluidSimulator.cpp b/src/Simulator/FluidSimulator.cpp index d2ca22775..10e4fee21 100644 --- a/src/Simulator/FluidSimulator.cpp +++ b/src/Simulator/FluidSimulator.cpp @@ -97,7 +97,7 @@ bool cFluidSimulator::IsHigherMeta(NIBBLETYPE a_Meta1, NIBBLETYPE a_Meta2) // Falling fluid is higher than anything, including self return true; } - + if (a_Meta2 == 0) { // Second block is a source and first block isn't @@ -108,7 +108,7 @@ bool cFluidSimulator::IsHigherMeta(NIBBLETYPE a_Meta1, NIBBLETYPE a_Meta2) // Second block is falling and the first one is neither a source nor falling return false; } - + // All special cases have been handled, now it's just a raw comparison: return (a_Meta1 < a_Meta2); } @@ -177,7 +177,7 @@ Direction cFluidSimulator::GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a LowestPoint = 9; // This always dominates X = Pos->x; Z = Pos->z; - + } delete Pos; Pos = nullptr; diff --git a/src/Simulator/FluidSimulator.h b/src/Simulator/FluidSimulator.h index 87a1361f1..4d5590e54 100644 --- a/src/Simulator/FluidSimulator.h +++ b/src/Simulator/FluidSimulator.h @@ -39,31 +39,31 @@ class cFluidSimulator : public cSimulator { typedef cSimulator super; - + public: cFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid); // cSimulator overrides: virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) override; - + /** Gets the flowing direction. If a_Over is true also the block over the current block affects the direction (standard) */ virtual Direction GetFlowingDirection(int a_X, int a_Y, int a_Z, bool a_Over = true); - + /** Creates a ChunkData object for the simulator to use. The simulator returns the correct object type. */ virtual cFluidSimulatorData * CreateChunkData(void) { return nullptr; } - + bool IsFluidBlock (BLOCKTYPE a_BlockType) const { return (a_BlockType == m_FluidBlock); } bool IsStationaryFluidBlock(BLOCKTYPE a_BlockType) const { return (a_BlockType == m_StationaryFluidBlock); } bool IsAnyFluidBlock (BLOCKTYPE a_BlockType) const { return ((a_BlockType == m_FluidBlock) || (a_BlockType == m_StationaryFluidBlock)); } - + static bool CanWashAway(BLOCKTYPE a_BlockType); - + bool IsSolidBlock (BLOCKTYPE a_BlockType); bool IsPassableForFluid(BLOCKTYPE a_BlockType); - + /** Returns true if a_Meta1 is a higher fluid than a_Meta2. Takes source blocks into account. */ bool IsHigherMeta(NIBBLETYPE a_Meta1, NIBBLETYPE a_Meta2); - + protected: BLOCKTYPE m_FluidBlock; // The fluid block type that needs simulating BLOCKTYPE m_StationaryFluidBlock; // The fluid block type that indicates no simulation is needed diff --git a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h index a43a6e49b..673d50e49 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h +++ b/src/Simulator/IncrementalRedstoneSimulator/IncrementalRedstoneSimulator.h @@ -17,7 +17,7 @@ public: super(a_World) { } - + virtual void Simulate(float a_dt) override; virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override {} @@ -161,7 +161,7 @@ public: static std::unique_ptr CreateComponent(cWorld & a_World, BLOCKTYPE a_BlockType, cIncrementalRedstoneSimulatorChunkData * a_Data); private: - + // oh yea its crazy time cIncrementalRedstoneSimulatorChunkData m_Data; } ; diff --git a/src/Simulator/IncrementalRedstoneSimulator/TripwireHookHandler.h b/src/Simulator/IncrementalRedstoneSimulator/TripwireHookHandler.h index d472d2dfb..382a1c311 100644 --- a/src/Simulator/IncrementalRedstoneSimulator/TripwireHookHandler.h +++ b/src/Simulator/IncrementalRedstoneSimulator/TripwireHookHandler.h @@ -122,7 +122,7 @@ public: m_World.SetBlockMeta(a_Position, Meta); return GetAdjustedRelatives(a_Position, GetRelativeAdjacents()); } - + return {}; } diff --git a/src/Simulator/NoopFluidSimulator.h b/src/Simulator/NoopFluidSimulator.h index 9fe2f9040..a237e960b 100644 --- a/src/Simulator/NoopFluidSimulator.h +++ b/src/Simulator/NoopFluidSimulator.h @@ -19,7 +19,7 @@ class cNoopFluidSimulator : public cFluidSimulator { typedef cFluidSimulator super; - + public: cNoopFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid) : super(a_World, a_Fluid, a_StationaryFluid) diff --git a/src/Simulator/NoopRedstoneSimulator.h b/src/Simulator/NoopRedstoneSimulator.h index 34c8627d2..a5d9e9448 100644 --- a/src/Simulator/NoopRedstoneSimulator.h +++ b/src/Simulator/NoopRedstoneSimulator.h @@ -34,7 +34,7 @@ public: UNUSED(a_BlockZ); UNUSED(a_Chunk); } - + virtual cRedstoneSimulatorChunkData * CreateChunkData() override { return nullptr; diff --git a/src/Simulator/SandSimulator.cpp b/src/Simulator/SandSimulator.cpp index 2ced0cb83..d3773ee41 100644 --- a/src/Simulator/SandSimulator.cpp +++ b/src/Simulator/SandSimulator.cpp @@ -251,7 +251,7 @@ void cSandSimulator::FinishFalling( ) { ASSERT(a_BlockY < cChunkDef::Height); - + BLOCKTYPE CurrentBlockType = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); if ((a_FallingBlockType == E_BLOCK_ANVIL) || IsReplacedOnRematerialization(CurrentBlockType)) { @@ -263,7 +263,7 @@ void cSandSimulator::FinishFalling( } return; } - + // Create a pickup instead: cItems Pickups; Pickups.Add(static_cast(a_FallingBlockType), 1, a_FallingBlockMeta); @@ -286,7 +286,7 @@ void cSandSimulator::DoInstantFall(cChunk * a_Chunk, int a_RelX, int a_RelY, int NIBBLETYPE FallingBlockMeta; a_Chunk->GetBlockTypeMeta(a_RelX, a_RelY, a_RelZ, FallingBlockType, FallingBlockMeta); a_Chunk->SetBlock(a_RelX, a_RelY, a_RelZ, E_BLOCK_AIR, 0); - + // Search for a place to put it: for (int y = a_RelY - 1; y >= 0; y--) { @@ -307,14 +307,14 @@ void cSandSimulator::DoInstantFall(cChunk * a_Chunk, int a_RelX, int a_RelY, int // Can fall further down continue; } - + // Finish the fall at the found bottom: int BlockX = a_RelX + a_Chunk->GetPosX() * cChunkDef::Width; int BlockZ = a_RelZ + a_Chunk->GetPosZ() * cChunkDef::Width; FinishFalling(&m_World, BlockX, BlockY, BlockZ, FallingBlockType, FallingBlockMeta); return; } - + // The block just "fell off the world" without leaving a trace } diff --git a/src/Simulator/SandSimulator.h b/src/Simulator/SandSimulator.h index 68ba718bd..cda26775e 100644 --- a/src/Simulator/SandSimulator.h +++ b/src/Simulator/SandSimulator.h @@ -32,19 +32,19 @@ public: virtual void Simulate(float a_Dt) override { UNUSED(a_Dt);} // not used virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) override; virtual bool IsAllowedBlock(BLOCKTYPE a_BlockType) override; - + /** Returns true if a falling-able block can start falling through the specified block type */ static bool CanStartFallingThrough(BLOCKTYPE a_BlockType); - + /** Returns true if an already-falling block can pass through the specified block type (e. g. torch) */ static bool CanContinueFallThrough(BLOCKTYPE a_BlockType); - + /** Returns true if the falling block rematerializing will replace the specified block type (e. g. tall grass) */ static bool IsReplacedOnRematerialization(BLOCKTYPE a_BlockType); - + /** Returns true if the specified block breaks falling blocks while they fall through it (e. g. halfslabs) */ static bool DoesBreakFallingThrough(BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); - + /** Called when a block finishes falling at the specified coords, either by insta-fall, or through cFallingBlock entity. It either rematerializes the block (a_FallingBlockType) at the specified coords, or creates a pickup, @@ -56,11 +56,11 @@ public: protected: bool m_IsInstantFall; // If set to true, blocks don't fall using cFallingBlock entity, but instantly instead - + int m_TotalBlocks; // Total number of blocks currently in the queue for simulating - + virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) override; - + /** Performs the instant fall of the block - removes it from top, Finishes it at the bottom */ void DoInstantFall(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ); }; diff --git a/src/Simulator/Simulator.h b/src/Simulator/Simulator.h index 421960083..b0e3b16f4 100644 --- a/src/Simulator/Simulator.h +++ b/src/Simulator/Simulator.h @@ -22,7 +22,7 @@ public: /** Called in each tick, a_Dt is the time passed since the last tick, in msec */ virtual void Simulate(float a_Dt) = 0; - + /** Called in each tick for each chunk, a_Dt is the time passed since the last tick, in msec; direct access to chunk data available */ virtual void SimulateChunk(std::chrono::milliseconds a_Dt, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk) { @@ -31,7 +31,7 @@ public: UNUSED(a_ChunkZ); UNUSED(a_Chunk); } - + /** Called when a block changes */ virtual void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk); @@ -39,7 +39,7 @@ public: protected: friend class cChunk; // Calls AddBlock() in its WakeUpSimulators() function, to speed things up - + /** Called to simulate a new block */ virtual void AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk) = 0; diff --git a/src/Simulator/SimulatorManager.h b/src/Simulator/SimulatorManager.h index b96f6ca84..e6ad68bf3 100644 --- a/src/Simulator/SimulatorManager.h +++ b/src/Simulator/SimulatorManager.h @@ -32,16 +32,16 @@ public: ~cSimulatorManager(); void Simulate(float a_Dt); - + void SimulateChunk(std::chrono::milliseconds a_DT, int a_ChunkX, int a_ChunkZ, cChunk * a_Chunk); - + void WakeUp(int a_BlockX, int a_BlockY, int a_BlockZ, cChunk * a_Chunk); void RegisterSimulator(cSimulator * a_Simulator, int a_Rate); // Takes ownership of the simulator object! protected: typedef std::vector > cSimulators; - + cWorld & m_World; cSimulators m_Simulators; long long m_Ticks; diff --git a/src/Simulator/VanillaFluidSimulator.h b/src/Simulator/VanillaFluidSimulator.h index 89a56ca14..3f8c45128 100644 --- a/src/Simulator/VanillaFluidSimulator.h +++ b/src/Simulator/VanillaFluidSimulator.h @@ -24,10 +24,10 @@ class cVanillaFluidSimulator : public cFloodyFluidSimulator { typedef cFloodyFluidSimulator super; - + public: cVanillaFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid, NIBBLETYPE a_Falloff, int a_TickDelay, int a_NumNeighborsForSource); - + protected: // cFloodyFluidSimulator overrides: virtual void SpreadXZ(cChunk * a_Chunk, int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_NewMeta) override; diff --git a/src/Simulator/VaporizeFluidSimulator.h b/src/Simulator/VaporizeFluidSimulator.h index c8eb7802b..8076972a8 100644 --- a/src/Simulator/VaporizeFluidSimulator.h +++ b/src/Simulator/VaporizeFluidSimulator.h @@ -20,7 +20,7 @@ class cVaporizeFluidSimulator : public cFluidSimulator { typedef cFluidSimulator super; - + public: cVaporizeFluidSimulator(cWorld & a_World, BLOCKTYPE a_Fluid, BLOCKTYPE a_StationaryFluid); diff --git a/src/SpawnPrepare.cpp b/src/SpawnPrepare.cpp index ba9fc1117..3ea383ee9 100644 --- a/src/SpawnPrepare.cpp +++ b/src/SpawnPrepare.cpp @@ -19,7 +19,7 @@ public: protected: cSpawnPrepare & m_SpawnPrepare; - + virtual void Call(int a_ChunkX, int a_ChunkZ, bool a_IsSuccess) override { m_SpawnPrepare.PreparedChunkCallback(a_ChunkX, a_ChunkZ); diff --git a/src/SpawnPrepare.h b/src/SpawnPrepare.h index 3f4a3b377..1c7a42b2f 100644 --- a/src/SpawnPrepare.h +++ b/src/SpawnPrepare.h @@ -4,7 +4,7 @@ #include class cWorld; - + /** Generates and lights the spawn area of the world. Runs as a separate thread. */ diff --git a/src/StringCompression.cpp b/src/StringCompression.cpp index a7f2db2a9..8be6d0026 100644 --- a/src/StringCompression.cpp +++ b/src/StringCompression.cpp @@ -13,7 +13,7 @@ int CompressString(const char * a_Data, size_t a_Length, AString & a_Compressed, int a_Factor) { uLongf CompressedSize = compressBound(static_cast(a_Length)); - + // HACK: We're assuming that AString returns its internal buffer in its data() call and we're overwriting that buffer! // It saves us one allocation and one memcpy of the entire compressed data // It may not work on some STL implementations! (Confirmed working on MSVC 2008 & 2010) @@ -64,14 +64,14 @@ int CompressStringGZIP(const char * a_Data, size_t a_Length, AString & a_Compres strm.avail_in = static_cast(a_Length); strm.next_out = reinterpret_cast(Buffer); strm.avail_out = sizeof(Buffer); - + int res = deflateInit2(&strm, 9, Z_DEFLATED, 31, 9, Z_DEFAULT_STRATEGY); if (res != Z_OK) { LOG("%s: compression initialization failed: %d (\"%s\").", __FUNCTION__, res, strm.msg); return res; } - + for (;;) { res = deflate(&strm, Z_FINISH); @@ -91,7 +91,7 @@ int CompressStringGZIP(const char * a_Data, size_t a_Length, AString & a_Compres } break; } - + case Z_STREAM_END: { // Finished compressing. Consume the rest of the buffer and return @@ -99,7 +99,7 @@ int CompressStringGZIP(const char * a_Data, size_t a_Length, AString & a_Compres deflateEnd(&strm); return Z_OK; } - + default: { // An error has occurred, log it and return the error value @@ -128,14 +128,14 @@ extern int UncompressStringGZIP(const char * a_Data, size_t a_Length, AString & strm.avail_in = static_cast(a_Length); strm.next_out = reinterpret_cast(Buffer); strm.avail_out = sizeof(Buffer); - + int res = inflateInit2(&strm, 31); // Force GZIP decoding if (res != Z_OK) { LOG("%s: uncompression initialization failed: %d (\"%s\").", __FUNCTION__, res, strm.msg); return res; } - + for (;;) { res = inflate(&strm, Z_NO_FLUSH); @@ -155,7 +155,7 @@ extern int UncompressStringGZIP(const char * a_Data, size_t a_Length, AString & } break; } - + case Z_STREAM_END: { // Finished uncompressing. Consume the rest of the buffer and return @@ -163,7 +163,7 @@ extern int UncompressStringGZIP(const char * a_Data, size_t a_Length, AString & inflateEnd(&strm); return Z_OK; } - + default: { // An error has occurred, log it and return the error value @@ -190,14 +190,14 @@ extern int InflateString(const char * a_Data, size_t a_Length, AString & a_Uncom strm.avail_in = static_cast(a_Length); strm.next_out = reinterpret_cast(Buffer); strm.avail_out = sizeof(Buffer); - + int res = inflateInit(&strm); // Force GZIP decoding if (res != Z_OK) { LOG("%s: inflation initialization failed: %d (\"%s\").", __FUNCTION__, res, strm.msg); return res; } - + for (;;) { res = inflate(&strm, Z_NO_FLUSH); @@ -217,7 +217,7 @@ extern int InflateString(const char * a_Data, size_t a_Length, AString & a_Uncom } break; } - + case Z_STREAM_END: { // Finished uncompressing. Consume the rest of the buffer and return @@ -225,7 +225,7 @@ extern int InflateString(const char * a_Data, size_t a_Length, AString & a_Uncom inflateEnd(&strm); return Z_OK; } - + default: { // An error has occurred, log it and return the error value diff --git a/src/Tracer.cpp b/src/Tracer.cpp index 17f1bdfbc..913f25e01 100644 --- a/src/Tracer.cpp +++ b/src/Tracer.cpp @@ -166,11 +166,11 @@ bool cTracer::Trace(const Vector3f & a_Start, const Vector3f & a_Direction, int LOGD("%s: Start Y is outside the world (%.2f), not tracing.", __FUNCTION__, a_Start.y); return false; } - + SetValues(a_Start, a_Direction); Vector3f End = a_Start + (dir * static_cast(a_Distance)); - + if (End.y < 0) { float dist = -a_Start.y / dir.y; // No division by 0 possible @@ -181,7 +181,7 @@ bool cTracer::Trace(const Vector3f & a_Start, const Vector3f & a_Direction, int end1.x = static_cast(floorf(End.x)); end1.y = static_cast(floorf(End.y)); end1.z = static_cast(floorf(End.z)); - + // check if first is occupied if (pos.Equals(end1)) { @@ -250,7 +250,7 @@ bool cTracer::Trace(const Vector3f & a_Start, const Vector3f & a_Direction, int { return false; } - + if ((pos.y < 0) || (pos.y >= cChunkDef::Height)) { return false; @@ -328,7 +328,7 @@ int cTracer::intersect3D_SegmentPlane(const Vector3f & a_Origin, const Vector3f } return 0; // no intersection } - + // they are not parallel // compute intersect param float sI = N / D; diff --git a/src/Tracer.h b/src/Tracer.h index d8422a7c6..8d1f494f7 100644 --- a/src/Tracer.h +++ b/src/Tracer.h @@ -57,7 +57,7 @@ private: Returns 1 if an intersection occured at a single point Returns 2 if the line segment lies in the plane being checked */ int intersect3D_SegmentPlane(const Vector3f & a_Origin, const Vector3f & a_End, const Vector3f & a_PlanePos, const Vector3f & a_PlaneNormal); - + /** Determines which face on the block a collision occured, if it does occur Returns 0 if the block is air, water or no collision occured Return 1 through 6 for the following block faces, repectively: -x, -z, x, z, y, -y */ diff --git a/src/UI/BeaconWindow.h b/src/UI/BeaconWindow.h index fa28b41ba..2b35e9d4a 100644 --- a/src/UI/BeaconWindow.h +++ b/src/UI/BeaconWindow.h @@ -25,7 +25,7 @@ public: cBeaconWindow(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconEntity * a_Beacon); cBeaconEntity * GetBeaconEntity(void) const { return m_Beacon; } - + virtual void DistributeStack(cItem & a_ItemStack, int a_Slot, cPlayer & a_Player, cSlotArea * a_ClickedArea, bool a_ShouldApply) override; // cWindow Overrides: diff --git a/src/UI/ChestWindow.h b/src/UI/ChestWindow.h index a3b20cdd9..bf8ef4f2f 100644 --- a/src/UI/ChestWindow.h +++ b/src/UI/ChestWindow.h @@ -32,7 +32,7 @@ public: virtual void OpenedByPlayer(cPlayer & a_Player) override; virtual void DistributeStack(cItem & a_ItemStack, int a_Slot, cPlayer & a_Player, cSlotArea * a_ClickedArea, bool a_ShouldApply) override; - + protected: cWorld * m_World; int m_BlockX, m_BlockY, m_BlockZ; // Position of the chest, for the window-close packet diff --git a/src/UI/InventoryWindow.h b/src/UI/InventoryWindow.h index 10952d37f..c02dcfbbb 100644 --- a/src/UI/InventoryWindow.h +++ b/src/UI/InventoryWindow.h @@ -24,7 +24,7 @@ public: cInventoryWindow(cPlayer & a_Player); virtual void DistributeStack(cItem & a_ItemStack, int a_Slot, cPlayer & a_Player, cSlotArea * a_ClickedArea, bool a_ShouldApply) override; - + protected: cPlayer & m_Player; }; diff --git a/src/UI/SlotArea.cpp b/src/UI/SlotArea.cpp index dc89ff8d4..2cef9b06d 100644 --- a/src/UI/SlotArea.cpp +++ b/src/UI/SlotArea.cpp @@ -48,7 +48,7 @@ void cSlotArea::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickA ItemToFullString(*GetSlot(a_SlotNum, a_Player)).c_str() ); */ - + ASSERT((a_SlotNum >= 0) && (a_SlotNum < GetNumSlots())); bool bAsync = false; @@ -57,7 +57,7 @@ void cSlotArea::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickA LOGWARNING("GetSlot(%d) returned nullptr! Ignoring click", a_SlotNum); return; } - + switch (a_ClickAction) { case caShiftLeftClick: @@ -100,7 +100,7 @@ void cSlotArea::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickA break; } } - + cItem Slot(*GetSlot(a_SlotNum, a_Player)); if (!Slot.IsSameType(a_ClickedItem)) { @@ -154,7 +154,7 @@ void cSlotArea::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickA } break; } - + case caLeftClick: { // Left-clicked @@ -193,7 +193,7 @@ void cSlotArea::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickA return; } } // switch (a_ClickAction - + SetSlot(a_SlotNum, a_Player, Slot); if (bAsync) { @@ -216,7 +216,7 @@ void cSlotArea::ShiftClicked(cPlayer & a_Player, int a_SlotNum, const cItem & a_ Slot.Empty(); } SetSlot(a_SlotNum, a_Player, Slot); - + // Some clients try to guess our actions and not always right (armor slots in 1.2.5), so we fix them: m_ParentWindow.BroadcastWholeWindow(); } @@ -240,14 +240,14 @@ void cSlotArea::DblClicked(cPlayer & a_Player, int a_SlotNum) LOGD("%s DblClicked with an empty hand over empty slot, ignoring", a_Player.GetName().c_str()); return; } - + // Add as many items from the surrounding area into hand as possible: // First skip full stacks, then if there's still space, process full stacks as well: if (!m_ParentWindow.CollectItemsToHand(Dragging, *this, a_Player, false)) { m_ParentWindow.CollectItemsToHand(Dragging, *this, a_Player, true); } - + m_ParentWindow.BroadcastWholeWindow(); // We need to broadcast, in case the window was a chest opened by multiple players } @@ -560,7 +560,7 @@ void cSlotAreaCrafting::OnPlayerRemoved(cPlayer & a_Player) { // Toss all items on the crafting grid: TossItems(a_Player, 1, m_NumSlots); - + // Remove the current recipe from the player -> recipe map: for (cRecipeMap::iterator itr = m_Recipes.begin(), end = m_Recipes.end(); itr != end; ++itr) { @@ -640,7 +640,7 @@ void cSlotAreaCrafting::ClickedResult(cPlayer & a_Player) // Get the new recipe and update the result slot: UpdateRecipe(a_Player); - + // We're done. Send all changes to the client and bail out: m_ParentWindow.BroadcastWholeWindow(); } @@ -667,7 +667,7 @@ void cSlotAreaCrafting::ShiftClickedResult(cPlayer & a_Player) // Couldn't distribute all of it. Bail out return; } - + // Distribute the result, this time for real: ResultCopy = Result; m_ParentWindow.DistributeStack(ResultCopy, 0, a_Player, this, true); @@ -681,7 +681,7 @@ void cSlotAreaCrafting::ShiftClickedResult(cPlayer & a_Player) // Broadcast the window, we sometimes move items to different locations than Vanilla, causing needless desyncs: m_ParentWindow.BroadcastWholeWindow(); - + // If the recipe has changed, bail out: if (!Recipe.GetResult().IsEqual(Result)) { @@ -737,7 +737,7 @@ cCraftingRecipe & cSlotAreaCrafting::GetRecipeForPlayer(cPlayer & a_Player) return itr->second; } } // for itr - m_Recipes[] - + // Not found. Add a new one: cCraftingGrid Grid(GetPlayerSlots(a_Player) + 1, m_GridSize, m_GridSize); cCraftingRecipe Recipe(Grid); @@ -906,7 +906,7 @@ void cSlotAreaAnvil::ShiftClicked(cPlayer & a_Player, int a_SlotNum, const cItem OnTakeResult(a_Player); } SetSlot(a_SlotNum, a_Player, Slot); - + // Some clients try to guess our actions and not always right (armor slots in 1.2.5), so we fix them: m_ParentWindow.BroadcastWholeWindow(); } @@ -1055,7 +1055,7 @@ void cSlotAreaAnvil::UpdateResult(cPlayer & a_Player) cItem Input(*GetSlot(0, a_Player)); cItem SecondInput(*GetSlot(1, a_Player)); cItem Output(*GetSlot(2, a_Player)); - + if (Input.IsEmpty()) { Output.Empty(); @@ -1071,7 +1071,7 @@ void cSlotAreaAnvil::UpdateResult(cPlayer & a_Player) if (!SecondInput.IsEmpty()) { bool IsEnchantBook = (SecondInput.m_ItemType == E_ITEM_ENCHANTED_BOOK); - + RepairCost += SecondInput.m_RepairCost; if (Input.IsDamageable() && cItemHandler::GetItemHandler(Input)->CanRepairWithRawMaterial(SecondInput.m_ItemType)) { @@ -1307,7 +1307,7 @@ void cSlotAreaBeacon::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ { return; } - + Slot = DraggingItem.CopyOne(); DraggingItem.m_ItemCount -= 1; if (DraggingItem.m_ItemCount <= 0) @@ -1459,7 +1459,7 @@ void cSlotAreaEnchanting::Clicked(cPlayer & a_Player, int a_SlotNum, eClickActio break; } } - + cItem Slot(*GetSlot(a_SlotNum, a_Player)); if (!Slot.IsSameType(a_ClickedItem)) { @@ -2227,12 +2227,12 @@ void cSlotAreaInventoryBase::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAc DropClicked(a_Player, a_SlotNum, (a_ClickAction == caCtrlDropKey)); return; } - + // Creative inventory must treat a_ClickedItem as a DraggedItem instead, replacing the inventory slot with it SetSlot(a_SlotNum, a_Player, a_ClickedItem); return; } - + // Survival inventory and all other windows' inventory has the same handling as normal slot areas super::Clicked(a_Player, a_SlotNum, a_ClickAction, a_ClickedItem); return; @@ -2316,7 +2316,7 @@ void cSlotAreaArmor::Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_C DropClicked(a_Player, a_SlotNum, (a_ClickAction == caCtrlDropKey)); return; } - + SetSlot(a_SlotNum, a_Player, a_ClickedItem); return; } @@ -2473,18 +2473,18 @@ const cItem * cSlotAreaTemporary::GetSlot(int a_SlotNum, cPlayer & a_Player) con { LOGERROR("cSlotAreaTemporary: player \"%s\" not found for slot %d!", a_Player.GetName().c_str(), a_SlotNum); ASSERT(!"cSlotAreaTemporary: player not found!"); - + // Player not found, this should not happen, ever! Return nullptr, but things may break by this. return nullptr; } - + if (a_SlotNum >= static_cast(itr->second.size())) { LOGERROR("cSlotAreaTemporary: asking for more slots than actually stored!"); ASSERT(!"cSlotAreaTemporary: asking for more slots than actually stored!"); return nullptr; } - + return &(itr->second[static_cast(a_SlotNum)]); } @@ -2501,13 +2501,13 @@ void cSlotAreaTemporary::SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem LOGWARNING("cSlotAreaTemporary: player not found!"); return; } - + if (a_SlotNum >= static_cast(itr->second.size())) { LOGERROR("cSlotAreaTemporary: asking for more slots than actually stored!"); return; } - + itr->second[static_cast(a_SlotNum)] = a_Item; } @@ -2544,7 +2544,7 @@ void cSlotAreaTemporary::TossItems(cPlayer & a_Player, int a_Begin, int a_End) LOGWARNING("Player tossing items (%s) not found in the item map", a_Player.GetName().c_str()); return; } - + cItems Drops; for (int i = a_Begin; i < a_End; i++) { @@ -2555,7 +2555,7 @@ void cSlotAreaTemporary::TossItems(cPlayer & a_Player, int a_Begin, int a_End) } Item.Empty(); } // for i - itr->second[] - + double vX = 0, vY = 0, vZ = 0; EulerToVector(-a_Player.GetYaw(), a_Player.GetPitch(), vZ, vX, vY); vY = -vY * 2 + 1.f; diff --git a/src/UI/SlotArea.h b/src/UI/SlotArea.h index 0ff36ce50..b5809b872 100644 --- a/src/UI/SlotArea.h +++ b/src/UI/SlotArea.h @@ -33,18 +33,18 @@ class cSlotArea public: cSlotArea(int a_NumSlots, cWindow & a_ParentWindow); virtual ~cSlotArea() {} // force a virtual destructor in all subclasses - + int GetNumSlots(void) const { return m_NumSlots; } - + /** Called to retrieve an item in the specified slot for the specified player. Must return a valid cItem. */ virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) const = 0; - + /** Called to set an item in the specified slot for the specified player */ virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) = 0; - + /** Called when a player clicks in the window. Parameters taken from the click packet. */ virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem); - + /** Called from Clicked when the action is a shiftclick (left or right) */ virtual void ShiftClicked(cPlayer & a_Player, int a_SlotNum, const cItem & a_ClickedItem); @@ -62,17 +62,17 @@ public: /** Called when a new player opens the same parent window. The window already tracks the player. CS-locked. */ virtual void OnPlayerAdded(cPlayer & a_Player); - + /** Called when one of the players closes the parent window. The window already doesn't track the player. CS-locked. */ virtual void OnPlayerRemoved(cPlayer & a_Player); - + /** Called to store as much of a_ItemStack in the area as possible. a_ItemStack is modified to reflect the change. The default implementation searches each slot for available space and distributes the stack there. if a_ShouldApply is true, the changes are written into the slots; if a_ShouldApply is false, only a_ItemStack is modified to reflect the number of fits (for fit-testing purposes) If a_KeepEmptySlots is true, empty slots will be skipped and won't be filled */ virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots, bool a_BackFill); - + /** Called on DblClicking to collect all stackable items into hand. The items are accumulated in a_Dragging and removed from the slots immediately. If a_CollectFullStacks is false, slots with full stacks are skipped while collecting. @@ -93,16 +93,16 @@ class cSlotAreaInventoryBase : public cSlotArea { typedef cSlotArea super; - + public: cSlotAreaInventoryBase(int a_NumSlots, int a_SlotOffset, cWindow & a_ParentWindow); - + // Creative inventory's click handling is somewhat different from survival inventory's, handle that here: virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) override; virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) const override; virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override; - + protected: int m_SlotOffset; // Index that this area's slot 0 has in the underlying cInventory } ; @@ -116,7 +116,7 @@ class cSlotAreaInventory : public cSlotAreaInventoryBase { typedef cSlotAreaInventoryBase super; - + public: cSlotAreaInventory(cWindow & a_ParentWindow) : cSlotAreaInventoryBase(cInventory::invInventoryCount, cInventory::invInventoryOffset, a_ParentWindow) @@ -133,7 +133,7 @@ class cSlotAreaHotBar : public cSlotAreaInventoryBase { typedef cSlotAreaInventoryBase super; - + public: cSlotAreaHotBar(cWindow & a_ParentWindow) : cSlotAreaInventoryBase(cInventory::invHotbarCount, cInventory::invHotbarOffset, a_ParentWindow) @@ -174,18 +174,18 @@ class cSlotAreaItemGrid : public cItemGrid::cListener { typedef cSlotArea super; - + public: cSlotAreaItemGrid(cItemGrid & a_ItemGrid, cWindow & a_ParentWindow); - + virtual ~cSlotAreaItemGrid(); - + virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) const override; virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override; protected: cItemGrid & m_ItemGrid; - + // cItemGrid::cListener overrides: virtual void OnSlotChanged(cItemGrid * a_ItemGrid, int a_SlotNum) override; } ; @@ -201,24 +201,24 @@ class cSlotAreaTemporary : public cSlotArea { typedef cSlotArea super; - + public: cSlotAreaTemporary(int a_NumSlots, cWindow & a_ParentWindow); - + // cSlotArea overrides: virtual const cItem * GetSlot (int a_SlotNum, cPlayer & a_Player) const override; virtual void SetSlot (int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override; virtual void OnPlayerAdded (cPlayer & a_Player) override; virtual void OnPlayerRemoved(cPlayer & a_Player) override; - + /** Tosses the player's items in slots [a_Begin, a_End) (ie. incl. a_Begin, but excl. a_End) */ void TossItems(cPlayer & a_Player, int a_Begin, int a_End); - + protected: typedef std::map > cItemMap; // Maps EntityID -> items - + cItemMap m_Items; - + /** Returns the pointer to the slot array for the player specified. */ cItem * GetPlayerSlots(cPlayer & a_Player); } ; @@ -231,7 +231,7 @@ class cSlotAreaCrafting : public cSlotAreaTemporary { typedef cSlotAreaTemporary super; - + public: /** a_GridSize is allowed to be only 2 or 3 */ cSlotAreaCrafting(int a_GridSize, cWindow & a_ParentWindow); @@ -241,7 +241,7 @@ public: virtual void DblClicked (cPlayer & a_Player, int a_SlotNum) override; virtual void OnPlayerRemoved(cPlayer & a_Player) override; virtual void SetSlot (int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override; - + // Distributing items into this area is completely disabled virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots, bool a_BackFill) override; @@ -250,14 +250,14 @@ protected: /** Maps player's EntityID -> current recipe. Not a std::map because cCraftingGrid needs proper constructor params. */ typedef std::list > cRecipeMap; - + int m_GridSize; cRecipeMap m_Recipes; - + /** Handles a click in the result slot. Crafts using the current recipe, if possible. */ void ClickedResult(cPlayer & a_Player); - + /** Handles a shift-click in the result slot. Crafts using the current recipe until it changes or no more space for result. */ void ShiftClickedResult(cPlayer & a_Player); @@ -267,7 +267,7 @@ protected: /** Updates the current recipe and result slot based on the ingredients currently in the crafting grid of the specified player. */ void UpdateRecipe(cPlayer & a_Player); - + /** Retrieves the recipe for the specified player from the map, or creates one if not found. */ cCraftingRecipe & GetRecipeForPlayer(cPlayer & a_Player); @@ -321,13 +321,13 @@ class cSlotAreaBeacon : public cItemGrid::cListener { typedef cSlotArea super; - + public: cSlotAreaBeacon(cBeaconEntity * a_Beacon, cWindow & a_ParentWindow); virtual ~cSlotAreaBeacon(); static bool IsPlaceableItem(short a_ItemType); - + virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) override; virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots, bool a_BackFill) override; virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) const override; @@ -380,10 +380,10 @@ class cSlotAreaChest : { public: cSlotAreaChest(cChestEntity * a_Chest, cWindow & a_ParentWindow); - + virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) const override; virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override; - + protected: cChestEntity * m_Chest; } ; @@ -397,10 +397,10 @@ class cSlotAreaDoubleChest : { public: cSlotAreaDoubleChest(cChestEntity * a_TopChest, cChestEntity * a_BottomChest, cWindow & a_ParentWindow); - + virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) const override; virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override; - + protected: cChestEntity * m_TopChest; cChestEntity * m_BottomChest; @@ -432,17 +432,17 @@ class cSlotAreaFurnace : public cItemGrid::cListener { typedef cSlotArea super; - + public: cSlotAreaFurnace(cFurnaceEntity * a_Furnace, cWindow & a_ParentWindow); - + virtual ~cSlotAreaFurnace(); - + virtual void Clicked(cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) override; virtual void DistributeStack(cItem & a_ItemStack, cPlayer & a_Player, bool a_ShouldApply, bool a_KeepEmptySlots, bool a_BackFill) override; virtual const cItem * GetSlot(int a_SlotNum, cPlayer & a_Player) const override; virtual void SetSlot(int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override; - + protected: cFurnaceEntity * m_Furnace; diff --git a/src/UI/Window.cpp b/src/UI/Window.cpp index e23c3c698..5a2e55feb 100644 --- a/src/UI/Window.cpp +++ b/src/UI/Window.cpp @@ -253,7 +253,7 @@ void cWindow::Clicked( break; } } - + if (a_SlotNum < 0) { // TODO: Other click actions with irrelevant slot number (FS #371) @@ -270,7 +270,7 @@ void cWindow::Clicked( } LocalSlotNum -= itr->GetNumSlots(); } - + LOGWARNING("Slot number higher than available window slots: %d, max %d received from \"%s\"; ignoring.", a_SlotNum, GetNumSlots(), a_Player.GetName().c_str() ); @@ -288,7 +288,7 @@ void cWindow::OpenedByPlayer(cPlayer & a_Player) m_OpenedBy.remove(&a_Player); // Then add player m_OpenedBy.push_back(&a_Player); - + for (cSlotAreas::iterator itr = m_SlotAreas.begin(), end = m_SlotAreas.end(); itr != end; ++itr) { (*itr)->OnPlayerAdded(a_Player); @@ -326,7 +326,7 @@ bool cWindow::ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse) } // for itr - m_SlotAreas[] m_OpenedBy.remove(&a_Player); - + if ((m_WindowType != wtInventory) && m_OpenedBy.empty()) { Destroy(); @@ -336,7 +336,7 @@ bool cWindow::ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse) { delete this; } - + return true; } @@ -436,7 +436,7 @@ bool cWindow::CollectItemsToHand(cItem & a_Dragging, cSlotArea & a_Area, cPlayer return true; } } - + // a_Dragging still not full, ask slot areas before a_Area in the list: for (cSlotAreas::iterator itr = m_SlotAreas.begin(), end = m_SlotAreas.end(); itr != end; ++itr) { @@ -480,7 +480,7 @@ void cWindow::SendSlot(cPlayer & a_Player, cSlotArea * a_SlotArea, int a_Relativ ASSERT(!"cWindow::SendSlot(): unknown a_SlotArea"); return; } - + a_Player.GetClientHandle()->SendInventorySlot( m_WindowID, static_cast(a_RelativeSlotNum + SlotBase), *(a_SlotArea->GetSlot(a_RelativeSlotNum, a_Player)) ); @@ -512,7 +512,7 @@ cSlotArea * cWindow::GetSlotArea(int a_GlobalSlotNum, int & a_LocalSlotNum) ASSERT(!"Invalid SlotNum"); return nullptr; } - + // Iterate through all the SlotAreas, find the correct one int LocalSlotNum = a_GlobalSlotNum; for (cSlotAreas::iterator itr = m_SlotAreas.begin(), end = m_SlotAreas.end(); itr != end; ++itr) @@ -524,7 +524,7 @@ cSlotArea * cWindow::GetSlotArea(int a_GlobalSlotNum, int & a_LocalSlotNum) } LocalSlotNum -= (*itr)->GetNumSlots(); } // for itr - m_SlotAreas[] - + // We shouldn't be here - the check at the beginnning should prevent this. Log and assert LOGWARNING("%s: GetNumSlots() is out of sync: %d; LocalSlotNum = %d", __FUNCTION__, GetNumSlots(), LocalSlotNum); ASSERT(!"Invalid GetNumSlots"); @@ -543,7 +543,7 @@ const cSlotArea * cWindow::GetSlotArea(int a_GlobalSlotNum, int & a_LocalSlotNum ASSERT(!"Invalid SlotNum"); return nullptr; } - + // Iterate through all the SlotAreas, find the correct one int LocalSlotNum = a_GlobalSlotNum; for (cSlotAreas::const_iterator itr = m_SlotAreas.begin(), end = m_SlotAreas.end(); itr != end; ++itr) @@ -555,7 +555,7 @@ const cSlotArea * cWindow::GetSlotArea(int a_GlobalSlotNum, int & a_LocalSlotNum } LocalSlotNum -= (*itr)->GetNumSlots(); } // for itr - m_SlotAreas[] - + // We shouldn't be here - the check at the beginnning should prevent this. Log and assert LOGWARNING("%s: GetNumSlots() is out of sync: %d; LocalSlotNum = %d", __FUNCTION__, GetNumSlots(), LocalSlotNum); ASSERT(!"Invalid GetNumSlots"); @@ -590,20 +590,20 @@ void cWindow::OnLeftPaintEnd(cPlayer & a_Player) { // Process the entire action stored in the internal structures for inventory painting // distribute as many items as possible - + const cSlotNums & SlotNums = a_Player.GetInventoryPaintSlots(); cItem ToDistribute(a_Player.GetDraggingItem()); int ToEachSlot = static_cast(ToDistribute.m_ItemCount) / static_cast(SlotNums.size()); - + int NumDistributed = DistributeItemToSlots(a_Player, ToDistribute, ToEachSlot, SlotNums); - + // Remove the items distributed from the dragging item: a_Player.GetDraggingItem().m_ItemCount -= NumDistributed; if (a_Player.GetDraggingItem().m_ItemCount == 0) { a_Player.GetDraggingItem().Empty(); } - + SendWholeWindow(*a_Player.GetClientHandle()); // To fix #2345 (custom recipes don't work when inventory-painting), we send the result slot explicitly once again @@ -622,16 +622,16 @@ void cWindow::OnRightPaintEnd(cPlayer & a_Player) const cSlotNums & SlotNums = a_Player.GetInventoryPaintSlots(); cItem ToDistribute(a_Player.GetDraggingItem()); - + int NumDistributed = DistributeItemToSlots(a_Player, ToDistribute, 1, SlotNums); - + // Remove the items distributed from the dragging item: a_Player.GetDraggingItem().m_ItemCount -= NumDistributed; if (a_Player.GetDraggingItem().m_ItemCount == 0) { a_Player.GetDraggingItem().Empty(); } - + SendWholeWindow(*a_Player.GetClientHandle()); // To fix #2345 (custom recipes don't work when inventory-painting), we send the result slot explicitly once again @@ -651,7 +651,7 @@ int cWindow::DistributeItemToSlots(cPlayer & a_Player, const cItem & a_Item, int // This doesn't seem to happen with the 1.5.1 client, so we don't worry about it for now return 0; } - + // Distribute to individual slots, keep track of how many items were actually distributed (full stacks etc.) int NumDistributed = 0; for (cSlotNums::const_iterator itr = a_SlotNums.begin(), end = a_SlotNums.end(); itr != end; ++itr) @@ -663,7 +663,7 @@ int cWindow::DistributeItemToSlots(cPlayer & a_Player, const cItem & a_Item, int LOGWARNING("%s: Bad SlotArea for slot %d", __FUNCTION__, *itr); continue; } - + // Modify the item at the slot cItem AtSlot(*Area->GetSlot(LocalSlotNum, a_Player)); int MaxStack = AtSlot.GetMaxStackSize(); @@ -712,7 +712,7 @@ void cWindow::BroadcastSlot(cSlotArea * a_Area, int a_LocalSlotNum) ASSERT(!"Invalid slot area"); return; } - + // Broadcast the update packet: cCSLock Lock(m_CS); for (cPlayerList::iterator itr = m_OpenedBy.begin(); itr != m_OpenedBy.end(); ++itr) diff --git a/src/UI/Window.h b/src/UI/Window.h index 76d22a12c..8a70b5855 100644 --- a/src/UI/Window.h +++ b/src/UI/Window.h @@ -67,9 +67,9 @@ public: wtDropper = 10, wtAnimalChest = 11, }; - + // tolua_end - + static const int c_NumInventorySlots = 36; cWindow(WindowType a_WindowType, const AString & a_WindowTitle); @@ -81,32 +81,32 @@ public: cWindowOwner * GetOwner(void) { return m_Owner; } void SetOwner( cWindowOwner * a_Owner) { m_Owner = a_Owner; } - + /** Returns the total number of slots */ int GetNumSlots(void) const; - + /** Returns the number of slots, excluding the player's inventory (used for network protocols) */ int GetNumNonInventorySlots(void) const { return GetNumSlots() - c_NumInventorySlots; } - + // tolua_begin - + /** Returns the item at the specified slot for the specified player. Returns nullptr if invalid SlotNum requested */ const cItem * GetSlot(cPlayer & a_Player, int a_SlotNum) const; - + /** Sets the item to the specified slot for the specified player */ void SetSlot(cPlayer & a_Player, int a_SlotNum, const cItem & a_Item); - + /** Returns true if the specified slot is in the Player Main Inventory slotarea */ bool IsSlotInPlayerMainInventory(int a_SlotNum) const; - + /** Returns true if the specified slot is in the Player Hotbar slotarea */ bool IsSlotInPlayerHotbar(int a_SlotNum) const; - + /** Returns true if the specified slot is in the Player Main Inventory or Hotbar slotareas. Note that returns false for Armor. */ bool IsSlotInPlayerInventory(int a_SlotNum) const; - + // tolua_end - + /** Fills a_Slots with the slots read from m_SlotAreas[], for the specified player */ void GetSlots(cPlayer & a_Player, cItems & a_Slots) const; @@ -118,40 +118,40 @@ public: ); virtual void OpenedByPlayer(cPlayer & a_Player); - + /** Called when a player closes this window; notifies all slot areas. Returns true if close accepted */ virtual bool ClosedByPlayer(cPlayer & a_Player, bool a_CanRefuse); /** Sends the specified slot's contents to all clients of this window; the slot is specified as local in an area */ void BroadcastSlot(cSlotArea * a_Area, int a_LocalSlotNum); - + /** Sends the contents of the whole window to the specified client */ void SendWholeWindow(cClientHandle & a_Client); - + /** Sends the contents of the whole window to all clients of this window. */ void BroadcastWholeWindow(void); // tolua_begin - + const AString & GetWindowTitle() const { return m_WindowTitle; } void SetWindowTitle(const AString & a_WindowTitle) { m_WindowTitle = a_WindowTitle; } - + /** Sends the UpdateWindowProperty (0x69) packet to all clients of the window */ virtual void SetProperty(short a_Property, short a_Value); - + /** Sends the UpdateWindowPropert(0x69) packet to the specified player */ virtual void SetProperty(short a_Property, short a_Value, cPlayer & a_Player); // tolua_end void OwnerDestroyed(void); - + /** Calls the callback safely for each player that has this window open; returns true if all players have been enumerated */ bool ForEachPlayer(cItemCallback & a_Callback); /** Calls the callback safely for each client that has this window open; returns true if all clients have been enumerated */ bool ForEachClient(cItemCallback & a_Callback); - + /** Called on shift-clicking to distribute the stack into other areas; Modifies a_ItemStack as it is distributed! if a_ShouldApply is true, the changes are written into the slots; if a_ShouldApply is false, only a_ItemStack is modified to reflect the number of fits (for fit-testing purposes) */ @@ -162,58 +162,58 @@ public: if a_ShouldApply is false, only a_ItemStack is modified to reflect the number of fits (for fit-testing purposes) If a_BackFill is true, the areas will be filled from the back (right side). (Example: Empty Hotbar -> Item get in slot 8, not slot 0) */ void DistributeStackToAreas(cItem & a_ItemStack, cPlayer & a_Player, cSlotAreas & a_AreasInOrder, bool a_ShouldApply, bool a_BackFill); - + /** Called on DblClicking to collect all stackable items from all areas into hand, starting with the specified area. The items are accumulated in a_Dragging and removed from the SlotAreas immediately. If a_CollectFullStacks is false, slots with full stacks in the area are skipped while collecting. Returns true if full stack has been collected, false if there's space remaining to fill. */ bool CollectItemsToHand(cItem & a_Dragging, cSlotArea & a_Area, cPlayer & a_Player, bool a_CollectFullStacks); - + /** Used by cSlotAreas to send individual slots to clients, a_RelativeSlotNum is the slot number relative to a_SlotArea */ void SendSlot(cPlayer & a_Player, cSlotArea * a_SlotArea, int a_RelativeSlotNum); protected: cSlotAreas m_SlotAreas; - + char m_WindowID; int m_WindowType; AString m_WindowTitle; cCriticalSection m_CS; cPlayerList m_OpenedBy; - + bool m_IsDestroyed; - + cWindowOwner * m_Owner; - + static Byte m_WindowIDCounter; /** Sets the internal flag as "destroyed"; notifies the owner that the window is destroying */ virtual void Destroy(void); - + /** Returns the correct slot area for the specified window-global SlotNum Also returns the area-local SlotNum corresponding to the GlobalSlotNum If the global SlotNum is out of range, returns nullptr */ cSlotArea * GetSlotArea(int a_GlobalSlotNum, int & a_LocalSlotNum); - + /** Returns the correct slot area for the specified window-global SlotNum Also returns the area-local SlotNum corresponding to the GlobalSlotNum If the global SlotNum is out of range, returns nullptr. Const version. */ const cSlotArea * GetSlotArea(int a_GlobalSlotNum, int & a_LocalSlotNum) const; - + /** Prepares the internal structures for inventory painting from the specified player */ void OnPaintBegin(cPlayer & a_Player); - + /** Adds the slot to the internal structures for inventory painting by the specified player */ void OnPaintProgress(cPlayer & a_Player, int a_SlotNum); - + /** Processes the entire action stored in the internal structures for inventory painting; distributes as many items as possible */ void OnLeftPaintEnd(cPlayer & a_Player); /** Processes the entire action stored in the internal structures for inventory painting; distributes one item into each slot */ void OnRightPaintEnd(cPlayer & a_Player); - + /** Distributes a_NumToEachSlot items into the slots specified in a_SlotNums; returns the total number of items distributed */ int DistributeItemToSlots(cPlayer & a_Player, const cItem & a_Item, int a_NumToEachSlot, const cSlotNums & a_SlotNums); } ; // tolua_export diff --git a/src/Vector3.h b/src/Vector3.h index 900ad65e3..c4b72fd57 100644 --- a/src/Vector3.h +++ b/src/Vector3.h @@ -121,7 +121,7 @@ public: y = Clamp(y, a_Min, a_Max); z = Clamp(z, a_Min, a_Max); } - + inline Vector3 Cross(const Vector3 & a_Rhs) const { return Vector3( @@ -147,7 +147,7 @@ public: #pragma clang diagnostic pop #endif } - + inline bool EqualsEps(const Vector3 & a_Rhs, T a_Eps) const { return (Abs(x - a_Rhs.x) < a_Eps) && (Abs(y - a_Rhs.y) < a_Eps) && (Abs(z - a_Rhs.z) < a_Eps); @@ -236,7 +236,7 @@ public: } // tolua_begin - + inline Vector3 operator + (const Vector3& a_Rhs) const { return Vector3( @@ -362,7 +362,7 @@ public: /** Return value of LineCoeffToPlane() if the line is parallel to the plane. */ static const double NO_INTERSECTION; - + protected: /** Returns the absolute value of the given argument. diff --git a/src/VoronoiMap.cpp b/src/VoronoiMap.cpp index 5ad634fe4..4c0aab61a 100644 --- a/src/VoronoiMap.cpp +++ b/src/VoronoiMap.cpp @@ -87,9 +87,9 @@ int cVoronoiMap::GetValueAt( { int CellX = a_X / m_CellSize; int CellY = a_Y / m_CellSize; - + UpdateCell(CellX, CellY); - + // Get 5x5 neighboring cell seeds, compare distance to each. Return the value in the minumim-distance cell int NearestSeedX = 0, NearestSeedY = 0; int MinDist = m_CellSize * m_CellSize * 16; // There has to be a cell closer than this @@ -101,7 +101,7 @@ int cVoronoiMap::GetValueAt( { int SeedX = m_SeedX[x][y]; int SeedY = m_SeedZ[x][y]; - + int Dist = (SeedX - a_X) * (SeedX - a_X) + (SeedY - a_Y) * (SeedY - a_Y); if (Dist < MinDist) { @@ -187,7 +187,7 @@ void cVoronoiMap::UpdateCell(int a_CellX, int a_CellZ) { return; } - + // Update the cell cache for the new cell position: int NoiseBaseX = a_CellX - 2; int NoiseBaseZ = a_CellZ - 2; diff --git a/src/VoronoiMap.h b/src/VoronoiMap.h index 7700b1306..e2c853e12 100644 --- a/src/VoronoiMap.h +++ b/src/VoronoiMap.h @@ -19,7 +19,7 @@ class cVoronoiMap { public: cVoronoiMap(int a_Seed, int a_CellSize = 128, int a_JitterSize = 128); - + /** Sets both the cell size and jitter size used for generating the Voronoi seeds. */ void SetCellSize(int a_CellSize); @@ -30,14 +30,14 @@ public: This offset makes the voronoi cells align to a non-grid. Clamps the value to [-m_CellSize, +m_CellSize]. */ void SetOddRowOffset(int a_OddRowOffset); - + /** Returns the value in the cell into which the specified point lies. */ int GetValueAt(int a_X, int a_Y); - + /** Returns the value in the cell into which the specified point lies, and the distance to the nearest Voronoi seed. */ int GetValueAt(int a_X, int a_Y, int & a_MinDistance); - + /** Returns the value in the cell into which the specified point lies, and the distances to the 2 nearest Voronoi seeds. Uses a cache. */ int GetValueAt( @@ -58,7 +58,7 @@ protected: cNoise m_Noise1; cNoise m_Noise2; cNoise m_Noise3; - + /** Size of the Voronoi cells (avg X / Y distance between the seeds). Expected to be at least 2. */ int m_CellSize; @@ -70,10 +70,10 @@ protected: This allows us to have non-rectangular grids. Expected to be between -m_CellSize and +m_CellSize. */ int m_OddRowOffset; - + /** The X coordinate of the currently cached cell neighborhood */ int m_CurrentCellX; - + /** The Z coordinate of the currently cached cell neighborhood */ int m_CurrentCellZ; @@ -82,8 +82,8 @@ protected: /** The seeds of cells around m_CurrentCellX, m_CurrentCellZ, X-coords */ int m_SeedZ[5][5]; - - + + /** Updates the cached cell seeds to match the specified cell. Noop if cell pos already matches. Updates m_SeedX and m_SeedZ. */ void UpdateCell(int a_CellX, int a_CellZ); diff --git a/src/WebAdmin.cpp b/src/WebAdmin.cpp index 27294f19b..29e1bbccf 100644 --- a/src/WebAdmin.cpp +++ b/src/WebAdmin.cpp @@ -180,7 +180,7 @@ void cWebAdmin::Stop(void) { return; } - + LOGD("Stopping WebAdmin..."); m_HTTPServer.Stop(); m_IsRunning = false; @@ -575,12 +575,12 @@ AString cWebAdmin::GetURLEncodedString(const AString & a_Input) { // Translation table from nibble to hex: static const char Hex[] = "0123456789abcdef"; - + // Preallocate the output to match input: AString dst; size_t len = a_Input.length(); dst.reserve(len); - + // Loop over input and substitute whatever is needed: for (size_t i = 0; i < len; i++) { diff --git a/src/WebAdmin.h b/src/WebAdmin.h index 4dbcc57a6..a3ebac43c 100644 --- a/src/WebAdmin.h +++ b/src/WebAdmin.h @@ -122,7 +122,7 @@ public: /** Starts the HTTP server taking care of the admin. Returns true if successful */ bool Start(void); - + /** Stops the HTTP server, if it was started. */ void Stop(void); @@ -160,7 +160,7 @@ public: /** Escapes text passed into it, so it can be embedded into html. */ static AString GetHTMLEscapedString(const AString & a_Input); - + /** Escapes the string for use in an URL */ static AString GetURLEncodedString(const AString & a_Input); @@ -214,7 +214,7 @@ protected: /** Set to true if Init() succeeds and the webadmin isn't to be disabled */ bool m_IsInitialized; - + /** Set to true if Start() succeeds in starting the server, reset back to false in Stop(). */ bool m_IsRunning; diff --git a/src/World.h b/src/World.h index 95ac6b21b..c5df65049 100644 --- a/src/World.h +++ b/src/World.h @@ -91,7 +91,7 @@ class cWorld : public: // tolua_end - + /** A simple RAII locker for the chunkmap - locks the chunkmap in its constructor, unlocks it in the destructor */ class cLock : public cCSLock @@ -105,7 +105,7 @@ public: { return "cWorld"; } - + // tolua_begin int GetTicksUntilWeatherChange(void) const { return m_WeatherInterval; } @@ -122,7 +122,7 @@ public: virtual Int64 GetWorldAge (void) const override { return std::chrono::duration_cast(m_WorldAge).count(); } virtual int GetTimeOfDay(void) const override { return std::chrono::duration_cast(m_TimeOfDay).count(); } - + void SetTicksUntilWeatherChange(int a_WeatherInterval) { m_WeatherInterval = a_WeatherInterval; @@ -134,38 +134,38 @@ public: UpdateSkyDarkness(); BroadcastTimeUpdate(); } - + /** Returns the default weather interval for the specific weather type. Returns -1 for any unknown weather. */ int GetDefaultWeatherInterval(eWeather a_Weather); - + /** Returns the current game mode. Partly OBSOLETE, you should use IsGameModeXXX() functions wherever applicable */ eGameMode GetGameMode(void) const { return m_GameMode; } /** Returns true if the world is in Creative mode */ bool IsGameModeCreative(void) const { return (m_GameMode == gmCreative); } - + /** Returns true if the world is in Survival mode */ bool IsGameModeSurvival(void) const { return (m_GameMode == gmSurvival); } - + /** Returns true if the world is in Adventure mode */ bool IsGameModeAdventure(void) const { return (m_GameMode == gmAdventure); } - + /** Returns true if the world is in Spectator mode */ bool IsGameModeSpectator(void) const { return (m_GameMode == gmSpectator); } - + bool IsPVPEnabled(void) const { return m_bEnabledPVP; } bool IsDeepSnowEnabled(void) const { return m_IsDeepSnowEnabled; } - + bool ShouldLavaSpawnFire(void) const { return m_ShouldLavaSpawnFire; } - + bool VillagersShouldHarvestCrops(void) const { return m_VillagersShouldHarvestCrops; } virtual eDimension GetDimension(void) const override { return m_Dimension; } /** Returns the world height at the specified coords; waits for the chunk to get loaded / generated */ virtual int GetHeight(int a_BlockX, int a_BlockZ) override; - + // tolua_end /** Retrieves the world height at the specified coords; returns false if chunk not loaded / generated */ @@ -218,35 +218,35 @@ public: void BroadcastTimeUpdate (const cClientHandle * a_Exclude = nullptr); virtual void BroadcastUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) override; void BroadcastWeather (eWeather a_Weather, const cClientHandle * a_Exclude = nullptr); - + virtual cBroadcastInterface & GetBroadcastManager(void) override { return *this; } - + /** If there is a block entity at the specified coords, sends it to the client specified */ void SendBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cClientHandle & a_Client); - + void MarkRedstoneDirty(int a_ChunkX, int a_ChunkZ); void MarkChunkDirty (int a_ChunkX, int a_ChunkZ, bool a_MarkRedstoneDirty = false); void MarkChunkSaving(int a_ChunkX, int a_ChunkZ); void MarkChunkSaved (int a_ChunkX, int a_ChunkZ); - + /** Puts the chunk data into a queue to be set into the chunkmap in the tick thread. If the chunk data doesn't contain valid biomes, the biomes are calculated before adding the data into the queue. */ void QueueSetChunkData(const cSetChunkDataPtr & a_SetChunkData); - + void ChunkLighted( int a_ChunkX, int a_ChunkZ, const cChunkDef::BlockNibbles & a_BlockLight, const cChunkDef::BlockNibbles & a_SkyLight ); - + bool GetChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataCallback & a_Callback); - + /** Gets the chunk's blocks, only the block types */ bool GetChunkBlockTypes(int a_ChunkX, int a_ChunkZ, BLOCKTYPE * a_BlockTypes); - + /** Returns true iff the chunk is in the loader / generator queue. */ bool IsChunkQueued(int a_ChunkX, int a_ChunkZ) const; @@ -254,10 +254,10 @@ public: bool IsChunkValid(int a_ChunkX, int a_ChunkZ) const; bool HasChunkAnyClients(int a_ChunkX, int a_ChunkZ) const; - + /** Queues a task to unload unused chunks onto the tick thread. The prefferred way of unloading. */ void QueueUnloadUnusedChunks(void); // tolua_export - + void CollectPickupsByPlayer(cPlayer & a_Player); /** Adds the player to the world. @@ -280,10 +280,10 @@ public: /** Finds a player from a partial or complete player name and calls the callback - case-insensitive */ bool FindAndDoWithPlayer(const AString & a_PlayerNameHint, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << - + // TODO: This interface is dangerous - rewrite to DoWithClosestPlayer(pos, sight, action) cPlayer * FindClosestPlayer(const Vector3d & a_Pos, float a_SightLimit, bool a_CheckLineOfSight = true); - + /** Finds the player over his uuid and calls the callback */ bool DoWithPlayerByUUID(const AString & a_PlayerUUID, cPlayerListCallback & a_Callback); // >> EXPORTED IN MANUALBINDINGS << @@ -292,14 +292,14 @@ public: /** Adds the entity into its appropriate chunk; takes ownership of the entity ptr. The entity is added lazily - this function only puts it in a queue that is then processed by the Tick thread. */ void AddEntity(cEntity * a_Entity); - + /** Returns true if an entity with the specified UniqueID exists in the world. Note: Only loaded chunks are considered. */ bool HasEntity(UInt32 a_UniqueID); - + /** Calls the callback for each entity in the entire world; returns true if all entities processed, false if the callback aborted by returning true */ bool ForEachEntity(cEntityCallback & a_Callback); // Exported in ManualBindings.cpp - + /** Calls the callback for each entity in the specified chunk; returns true if all entities processed, false if the callback aborted by returning true */ bool ForEachEntityInChunk(int a_ChunkX, int a_ChunkZ, cEntityCallback & a_Callback); // Exported in ManualBindings.cpp @@ -314,27 +314,27 @@ public: /** Compares clients of two chunks, calls the callback accordingly */ void CompareChunkClients(int a_ChunkX1, int a_ChunkZ1, int a_ChunkX2, int a_ChunkZ2, cClientDiffCallback & a_Callback); - + /** Adds client to a chunk, if not already present; returns true if added, false if present */ bool AddChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client); - + /** Removes client from the chunk specified */ void RemoveChunkClient(int a_ChunkX, int a_ChunkZ, cClientHandle * a_Client); - + /** Removes the client from all chunks it is present in */ void RemoveClientFromChunks(cClientHandle * a_Client); - + /** Sends the chunk to the client specified, if the client doesn't have the chunk yet. If chunk not valid, the request is postponed (ChunkSender will send that chunk when it becomes valid + lighted). */ void SendChunkTo(int a_ChunkX, int a_ChunkZ, cChunkSender::eChunkPriority a_Priority, cClientHandle * a_Client); - + /** Sends the chunk to the client specified, even if the client already has the chunk. If the chunk's not valid, the request is postponed (ChunkSender will send that chunk when it becomes valid + lighted). */ void ForceSendChunkTo(int a_ChunkX, int a_ChunkZ, cChunkSender::eChunkPriority a_Priority, cClientHandle * a_Client); /** Removes client from ChunkSender's queue of chunks to be sent */ void RemoveClientFromChunkSender(cClientHandle * a_Client); - + /** Touches the chunk, causing it to be loaded or generated */ void TouchChunk(int a_ChunkX, int a_ChunkZ); @@ -343,10 +343,10 @@ public: The specified callback is called after the chunk has been prepared. If there's no preparation to do, only the callback is called. It is legal to call with no callback. */ void PrepareChunk(int a_ChunkX, int a_ChunkZ, std::unique_ptr a_CallAfter = {}); - + /** Marks the chunk as failed-to-load: */ void ChunkLoadFailed(int a_ChunkX, int a_ChunkZ); - + /** Sets the sign text, asking plugins for permission first. a_Player is the player who this change belongs to, may be nullptr. Returns true if sign text changed. */ bool SetSignLines(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player = nullptr); // Exported in ManualBindings.cpp @@ -361,28 +361,28 @@ public: /** Regenerate the given chunk: */ void RegenerateChunk(int a_ChunkX, int a_ChunkZ); // tolua_export - + /** Generates the given chunk */ void GenerateChunk(int a_ChunkX, int a_ChunkZ); // tolua_export - + /** Queues a chunk for lighting; a_Callback is called after the chunk is lighted */ void QueueLightChunk(int a_ChunkX, int a_ChunkZ, std::unique_ptr a_Callback = {}); - + bool IsChunkLighted(int a_ChunkX, int a_ChunkZ); - + /** Calls the callback for each chunk in the coords specified (all cords are inclusive). Returns true if all chunks have been processed successfully */ virtual bool ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback) override; /** Calls the callback for each loaded chunk. Returns true if all chunks have been processed successfully */ bool ForEachLoadedChunk(std::function a_Callback); - + // tolua_begin - + /** Sets the block at the specified coords to the specified value. Full processing, incl. updating neighbors, is performed. */ void SetBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, bool a_SendToClients = true); - + /** Sets the block at the specified coords to the specified value. The replacement doesn't trigger block updates. The replaced blocks aren't checked for block entities (block entity is leaked if it exists at this block) @@ -391,12 +391,12 @@ public: { m_ChunkMap->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); } - + BLOCKTYPE GetBlock (int a_BlockX, int a_BlockY, int a_BlockZ) { return m_ChunkMap->GetBlock(a_BlockX, a_BlockY, a_BlockZ); } - + NIBBLETYPE GetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ) { return m_ChunkMap->GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); @@ -404,15 +404,15 @@ public: void SetBlockMeta (int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_MetaData); NIBBLETYPE GetBlockSkyLight (int a_BlockX, int a_BlockY, int a_BlockZ); NIBBLETYPE GetBlockBlockLight(int a_BlockX, int a_BlockY, int a_BlockZ); - + // tolua_end - + bool GetBlockTypeMeta (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta); // TODO: Exported in ManualBindings.cpp bool GetBlockInfo (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_Meta, NIBBLETYPE & a_SkyLight, NIBBLETYPE & a_BlockLight); // TODO: Exported in ManualBindings.cpp // TODO: NIBBLETYPE GetBlockActualLight(int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_begin - + // Vector3i variants: void FastSetBlock(const Vector3i & a_Pos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { FastSetBlock( a_Pos.x, a_Pos.y, a_Pos.z, a_BlockType, a_BlockMeta); } BLOCKTYPE GetBlock (const Vector3i & a_Pos) { return GetBlock( a_Pos.x, a_Pos.y, a_Pos.z); } @@ -420,22 +420,22 @@ public: void SetBlockMeta(const Vector3i & a_Pos, NIBBLETYPE a_MetaData) { SetBlockMeta( a_Pos.x, a_Pos.y, a_Pos.z, a_MetaData); } NIBBLETYPE GetBlockBlockLight(const Vector3i & a_Pos) { return GetBlockBlockLight( a_Pos.x, a_Pos.y, a_Pos.z); } // tolua_end - + /** Writes the block area into the specified coords. Returns true if all chunks have been processed. Prefer cBlockArea::Write() instead, this is the internal implementation; cBlockArea does error checking, too. a_DataTypes is a bitmask of cBlockArea::baXXX constants ORed together. */ virtual bool WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes) override; - + // tolua_begin /** Spawns item pickups for each item in the list. May compress pickups if too many entities: */ virtual void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_FlyAwaySpeed = 1.0, bool IsPlayerCreated = false) override; - + /** Spawns item pickups for each item in the list. May compress pickups if too many entities. All pickups get the speed specified. */ virtual void SpawnItemPickups(const cItems & a_Pickups, double a_BlockX, double a_BlockY, double a_BlockZ, double a_SpeedX, double a_SpeedY, double a_SpeedZ, bool IsPlayerCreated = false) override; - + /** Spawns an falling block entity at the given position. Returns the UniqueID of the spawned falling block, or cEntity::INVALID_ID on failure. */ UInt32 SpawnFallingBlock(int a_X, int a_Y, int a_Z, BLOCKTYPE BlockType, NIBBLETYPE BlockMeta); @@ -462,10 +462,10 @@ public: /** Replaces world blocks with a_Blocks, if they are of type a_FilterBlockType */ void ReplaceBlocks(const sSetBlockVector & a_Blocks, BLOCKTYPE a_FilterBlockType); - + /** Retrieves block types of the specified blocks. If a chunk is not loaded, doesn't modify the block. Returns true if all blocks were read. */ bool GetBlocks(sSetBlockVector & a_Blocks, bool a_ContinueOnFailure); - + // tolua_begin bool DigBlock (int a_X, int a_Y, int a_Z); virtual void SendBlockTo(int a_X, int a_Y, int a_Z, cPlayer * a_Player) override; @@ -476,21 +476,21 @@ public: /** Wakes up the simulators for the specified block */ virtual void WakeUpSimulators(int a_BlockX, int a_BlockY, int a_BlockZ) override; - + /** Wakes up the simulators for the specified area of blocks */ void WakeUpSimulatorsInArea(int a_MinBlockX, int a_MaxBlockX, int a_MinBlockY, int a_MaxBlockY, int a_MinBlockZ, int a_MaxBlockZ); // tolua_end inline cSimulatorManager * GetSimulatorManager(void) { return m_SimulatorManager.get(); } - + inline cFluidSimulator * GetWaterSimulator(void) { return m_WaterSimulator; } inline cFluidSimulator * GetLavaSimulator (void) { return m_LavaSimulator; } inline cRedstoneSimulator * GetRedstoneSimulator(void) { return m_RedstoneSimulator; } - + /** Calls the callback for each block entity in the specified chunk; returns true if all block entities processed, false if the callback aborted by returning true */ bool ForEachBlockEntityInChunk(int a_ChunkX, int a_ChunkZ, cBlockEntityCallback & a_Callback); // Exported in ManualBindings.cpp - + /** Calls the callback for each brewingstand in the specified chunk; returns true if all brewingstands processed, false if the callback aborted by returning true */ bool ForEachBrewingstandInChunk(int a_ChunkX, int a_ChunkZ, cBrewingstandCallback & a_Callback); // Exported in ManualBindings.cpp @@ -508,7 +508,7 @@ public: /** Calls the callback for each furnace in the specified chunk; returns true if all furnaces processed, false if the callback aborted by returning true */ bool ForEachFurnaceInChunk(int a_ChunkX, int a_ChunkZ, cFurnaceCallback & a_Callback); // Exported in ManualBindings.cpp - + /** Does an explosion with the specified strength at the specified coordinates. Executes the HOOK_EXPLODING and HOOK_EXPLODED hooks as part of the processing. a_SourceData exact type depends on the a_Source, see the declaration of the esXXX constants in BlockID.h for details. @@ -553,10 +553,10 @@ public: /** Retrieves the test on the sign at the specified coords; returns false if there's no sign at those coords, true if found */ bool GetSignLines (int a_BlockX, int a_BlockY, int a_BlockZ, AString & a_Line1, AString & a_Line2, AString & a_Line3, AString & a_Line4); // Exported in ManualBindings.cpp - + /** a_Player is using block entity at [x, y, z], handle that: */ void UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) {m_ChunkMap->UseBlockEntity(a_Player, a_BlockX, a_BlockY, a_BlockZ); } // tolua_export - + /** Calls the callback for the chunk specified, with ChunkMapCS locked; returns false if the chunk doesn't exist, otherwise returns the same value as the callback */ bool DoWithChunk(int a_ChunkX, int a_ChunkZ, cChunkCallback & a_Callback); bool DoWithChunk(int a_ChunkX, int a_ChunkZ, std::function a_Callback); @@ -566,21 +566,21 @@ public: bool DoWithChunkAt(Vector3i a_BlockPos, std::function a_Callback); void GrowTreeImage(const sSetBlockVector & a_Blocks); - + // tolua_begin /** Grows a tree at the specified coords, either from a sapling there, or based on the biome */ void GrowTree (int a_BlockX, int a_BlockY, int a_BlockZ); - + /** Grows a tree at the specified coords, based on the sapling meta provided */ void GrowTreeFromSapling(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBLETYPE a_SaplingMeta); - + /** Grows a tree at the specified coords, based on the biome in the place */ void GrowTreeByBiome (int a_BlockX, int a_BlockY, int a_BlockZ); - + /** Grows the plant at the specified block to its ripe stage (bonemeal used); returns false if the block is not growable. If a_IsBonemeal is true, block is not grown if not allowed in world.ini */ bool GrowRipePlant(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_IsByBonemeal = false); - + /** Grows a cactus present at the block specified by the amount of blocks specified, up to the max height specified in the config */ void GrowCactus(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow); @@ -589,18 +589,18 @@ public: /** Grows a sugarcane present at the block specified by the amount of blocks specified, up to the max height specified in the config */ void GrowSugarcane(int a_BlockX, int a_BlockY, int a_BlockZ, int a_NumBlocksToGrow); - + /** Returns the biome at the specified coords. Reads the biome from the chunk, if loaded, otherwise uses the world generator to provide the biome value */ EMCSBiome GetBiomeAt(int a_BlockX, int a_BlockZ); - + /** Sets the biome at the specified coords. Returns true if successful, false if not (chunk not loaded). Doesn't resend the chunk to clients, use ForceSendChunkTo() for that. */ bool SetBiomeAt(int a_BlockX, int a_BlockZ, EMCSBiome a_Biome); - + /** Sets the biome at the area. Returns true if successful, false if any subarea failed (chunk not loaded). (Re)sends the chunks to their relevant clients if successful. */ bool SetAreaBiome(int a_MinX, int a_MaxX, int a_MinZ, int a_MaxZ, EMCSBiome a_Biome); - + /** Sets the biome at the area. Returns true if successful, false if any subarea failed (chunk not loaded). (Re)sends the chunks to their relevant clients if successful. The cuboid needn't be sorted. */ @@ -608,7 +608,7 @@ public: /** Returns the name of the world */ const AString & GetName(void) const { return m_WorldName; } - + /** Returns the name of the world.ini file used by this world */ const AString & GetIniFileName(void) const {return m_IniFileName; } @@ -645,7 +645,7 @@ public: AString GetLinkedOverworldName(void) const { return m_LinkedOverworldName; } void SetLinkedOverworldName(const AString & a_Name) { m_LinkedOverworldName = a_Name; } - + /** Returns or sets the minumim or maximum netherportal width */ virtual int GetMinNetherPortalWidth(void) const override { return m_MinNetherPortalWidth; } virtual int GetMaxNetherPortalWidth(void) const override { return m_MaxNetherPortalWidth; } @@ -659,16 +659,16 @@ public: virtual void SetMaxNetherPortalHeight(int a_NewMaxHeight) override { m_MaxNetherPortalHeight = a_NewMaxHeight; } // tolua_end - + /** Saves all chunks immediately. Dangerous interface, may deadlock, use QueueSaveAllChunks() instead */ void SaveAllChunks(void); - + /** Queues a task to save all chunks onto the tick thread. The prefferred way of saving chunks from external sources */ void QueueSaveAllChunks(void); // tolua_export - + /** Queues a task onto the tick thread. The task object will be deleted once the task is finished */ void QueueTask(std::function a_Task); // Exported in ManualBindings.cpp - + /** Queues a lambda task onto the tick thread, with the specified delay. */ void ScheduleTask(int a_DelayTicks, std::function a_Task); @@ -687,13 +687,13 @@ public: cLightingThread & GetLightingThread(void) { return m_Lighting; } void InitializeSpawn(void); - + /** Starts threads that belong to this world */ void Start(void); - + /** Stops threads that belong to this world (part of deinit) */ void Stop(void); - + /** Processes the blocks queued for ticking with a delay (m_BlockTickQueue[]) */ void TickQueuedBlocks(void); @@ -711,34 +711,34 @@ public: // tolua_begin /** Casts a thunderbolt at the specified coords */ void CastThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ); - + /** Sets the specified weather; resets weather interval; asks and notifies plugins of the change */ void SetWeather(eWeather a_NewWeather); - + /** Forces a weather change in the next game tick */ void ChangeWeather(void); - + /** Returns the current weather. Instead of comparing values directly to the weather constants, use IsWeatherXXX() functions, if possible */ eWeather GetWeather(void) const { return m_Weather; } - + /** Returns true if the current weather is sun */ bool IsWeatherSunny(void) const { return (m_Weather == wSunny); } - + /** Returns true if it is sunny at the specified location. This takes into account biomes. */ bool IsWeatherSunnyAt(int a_BlockX, int a_BlockZ) { return (IsWeatherSunny() || IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ))); } - + /** Returns true if the current weather is rain */ bool IsWeatherRain(void) const { return (m_Weather == wRain); } - + /** Returns true if it is raining at the specified location. This takes into account biomes. */ bool IsWeatherRainAt(int a_BlockX, int a_BlockZ) { return (IsWeatherRain() && !IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ))); } - + /** Returns true if the current weather is stormy */ bool IsWeatherStorm(void) const { return (m_Weather == wStorm); } @@ -747,10 +747,10 @@ public: { return (IsWeatherStorm() && !IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ))); } - + /** Returns true if the current weather has any precipitation - rain, storm or snow */ bool IsWeatherWet(void) const { return !IsWeatherSunny(); } - + /** Returns true if it is raining, stormy or snowing at the specified location. This takes into account biomes. */ virtual bool IsWeatherWetAt(int a_BlockX, int a_BlockZ) override { @@ -765,33 +765,33 @@ public: cChunkGenerator & GetGenerator(void) { return m_Generator; } cWorldStorage & GetStorage (void) { return m_Storage; } cChunkMap * GetChunkMap (void) { return m_ChunkMap.get(); } - + /** Sets the blockticking to start at the specified block. Only one blocktick per chunk may be set, second call overwrites the first call */ void SetNextBlockTick(int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export - + int GetMaxSugarcaneHeight(void) const { return m_MaxSugarcaneHeight; } // tolua_export int GetMaxCactusHeight (void) const { return m_MaxCactusHeight; } // tolua_export bool IsBlockDirectlyWatered(int a_BlockX, int a_BlockY, int a_BlockZ); // tolua_export - + /** Spawns a mob of the specified type. Returns the mob's UniqueID if recognized and spawned, cEntity::INVALID_ID otherwise */ virtual UInt32 SpawnMob(double a_PosX, double a_PosY, double a_PosZ, eMonsterType a_MonsterType, bool a_Baby = false) override; // tolua_export UInt32 SpawnMobFinalize(cMonster * a_Monster); - + /** Creates a projectile of the specified type. Returns the projectile's UniqueID if successful, cEntity::INVALID_ID otherwise Item parameter is currently used for Fireworks to correctly set entity metadata based on item metadata. */ UInt32 CreateProjectile(double a_PosX, double a_PosY, double a_PosZ, cProjectileEntity::eKind a_Kind, cEntity * a_Creator, const cItem * a_Item, const Vector3d * a_Speed = nullptr); // tolua_export - + /** Returns a random number from the m_TickRand in range [0 .. a_Range]. To be used only in the tick thread! */ int GetTickRandomNumber(int a_Range) { return static_cast(m_TickRand.randInt(a_Range)); } - + /** Appends all usernames starting with a_Text (case-insensitive) into Results */ void TabCompleteUserName(const AString & a_Text, AStringVector & a_Results); /** Get the current darkness level based on the time */ NIBBLETYPE GetSkyDarkness() { return m_SkyDarkness; } - + /** Increments (a_AlwaysTicked == true) or decrements (false) the m_AlwaysTicked counter for the specified chunk. If the m_AlwaysTicked counter is greater than zero, the chunk is ticked in the tick-thread regardless of whether it has any clients or not. @@ -800,43 +800,43 @@ public: void SetChunkAlwaysTicked(int a_ChunkX, int a_ChunkZ, bool a_AlwaysTicked = true); // tolua_export cBroadcaster GetBroadcaster(); - + private: friend class cRoot; - + class cTickThread : public cIsThread { typedef cIsThread super; public: cTickThread(cWorld & a_World); - + protected: cWorld & m_World; - + // cIsThread overrides: virtual void Execute(void) override; } ; - - + + /** Implementation of the callbacks that the ChunkGenerator uses to store new chunks and interface to plugins */ class cChunkGeneratorCallbacks : public cChunkGenerator::cChunkSink, public cChunkGenerator::cPluginInterface { cWorld * m_World; - + // cChunkSink overrides: virtual void OnChunkGenerated (cChunkDesc & a_ChunkDesc) override; virtual bool IsChunkValid (int a_ChunkX, int a_ChunkZ) override; virtual bool HasChunkAnyClients(int a_ChunkX, int a_ChunkZ) override; virtual bool IsChunkQueued (int a_ChunkX, int a_ChunkZ) override; - + // cPluginInterface overrides: virtual void CallHookChunkGenerating(cChunkDesc & a_ChunkDesc) override; virtual void CallHookChunkGenerated (cChunkDesc & a_ChunkDesc) override; - + public: cChunkGeneratorCallbacks(cWorld & a_World); } ; @@ -849,15 +849,15 @@ private: AString m_LinkedOverworldName; AString m_IniFileName; - + /** Name of the storage schema used to load and save chunks */ AString m_StorageSchema; - + int m_StorageCompressionFactor; - + /** The dimension of the world, used by the client to provide correct lighting scheme */ eDimension m_Dimension; - + /** This random generator is to be used only in the Tick() method, and thus only in the World-Tick-thread (MTRand is not exactly thread-safe) */ MTRand m_TickRand; @@ -891,7 +891,7 @@ private: bool m_IsDeepSnowEnabled; bool m_ShouldLavaSpawnFire; bool m_VillagersShouldHarvestCrops; - + std::vector m_BlockTickQueue; std::vector m_BlockTickQueueCopy; // Second is for safely removing the objects from the queue @@ -901,12 +901,12 @@ private: cFluidSimulator * m_LavaSimulator; std::unique_ptr m_FireSimulator; cRedstoneSimulator * m_RedstoneSimulator; - + cCriticalSection m_CSPlayers; cPlayerList m_Players; cWorldStorage m_Storage; - + unsigned int m_MaxPlayers; std::unique_ptr m_ChunkMap; @@ -919,7 +919,7 @@ private: int m_MaxSunnyTicks, m_MinSunnyTicks; int m_MaxRainTicks, m_MinRainTicks; int m_MaxThunderStormTicks, m_MinThunderStormTicks; - + int m_MaxCactusHeight; int m_MaxSugarcaneHeight; bool m_IsCactusBonemealable; @@ -936,7 +936,7 @@ private: /** Whether command blocks are enabled or not */ bool m_bCommandBlocksEnabled; - + /** Whether prefixes such as [INFO] are prepended to SendMessageXXX() / BroadcastChatXXX() functions */ bool m_bUseChatPrefixes; @@ -955,35 +955,35 @@ private: /** Name of the End world - where End portals should teleport. Only used when this world is an Overworld. */ AString m_LinkedEndWorldName; - + cChunkGenerator m_Generator; cScoreboard m_Scoreboard; cMapManager m_MapManager; - + /** The callbacks that the ChunkGenerator uses to store new chunks and interface to plugins */ cChunkGeneratorCallbacks m_GeneratorCallbacks; - + cChunkSender m_ChunkSender; cLightingThread m_Lighting; cTickThread m_TickThread; - + /** Guards the m_Tasks */ cCriticalSection m_CSTasks; - + /** Tasks that have been queued onto the tick thread, possibly to be executed at target tick in the future; guarded by m_CSTasks */ std::vector>> m_Tasks; - + /** Guards m_Clients */ cCriticalSection m_CSClients; - + /** List of clients in this world, these will be ticked by this world */ cClientHandlePtrs m_Clients; - + /** Clients that are scheduled for removal (ticked in another world), waiting for TickClients() to remove them */ cClientHandles m_ClientsToRemove; - + /** Clients that are scheduled for adding, waiting for TickClients to add them */ cClientHandlePtrs m_ClientsToAdd; @@ -998,10 +998,10 @@ private: /** List of players that are scheduled for adding, waiting for the Tick thread to add them. */ cPlayerList m_PlayersToAdd; - + /** CS protecting m_SetChunkDataQueue. */ cCriticalSection m_CSSetChunkDataQueue; - + /** Queue for the chunk data to be set into m_ChunkMap by the tick thread. Protected by m_CSSetChunkDataQueue */ cSetChunkDataPtrs m_SetChunkDataQueue; @@ -1013,13 +1013,13 @@ private: /** Handles the weather in each tick */ void TickWeather(float a_Dt); - + /** Handles the mob spawning / moving / destroying each tick */ void TickMobs(std::chrono::milliseconds a_Dt); - + /** Executes all tasks queued onto the tick thread */ void TickQueuedTasks(void); - + /** Ticks all clients that are in this world */ void TickClients(float a_Dt); diff --git a/src/WorldStorage/EnchantmentSerializer.cpp b/src/WorldStorage/EnchantmentSerializer.cpp index b28e16b1d..9f477f316 100644 --- a/src/WorldStorage/EnchantmentSerializer.cpp +++ b/src/WorldStorage/EnchantmentSerializer.cpp @@ -9,7 +9,7 @@ void EnchantmentSerializer::WriteToNBTCompound(const cEnchantments & a_Enchantme { // Write the enchantments into the specified NBT writer // begin with the LIST tag of the specified name ("ench" or "StoredEnchantments") - + a_Writer.BeginList(a_ListTagName, TAG_Compound); for (cEnchantments::cMap::const_iterator itr = a_Enchantments.m_Enchantments.begin(), end = a_Enchantments.m_Enchantments.end(); itr != end; ++itr) { @@ -38,7 +38,7 @@ void EnchantmentSerializer::ParseFromNBT(cEnchantments & a_Enchantments, const c ASSERT(!"Bad EnchListTag type"); return; } - + // Verify that the list is of Compounds: if (a_NBT.GetChildrenType(a_EnchListTagIdx) != TAG_Compound) { @@ -48,15 +48,15 @@ void EnchantmentSerializer::ParseFromNBT(cEnchantments & a_Enchantments, const c ASSERT(!"Bad EnchListTag children type"); return; } - + a_Enchantments.Clear(); - + // Iterate over all the compound children, parse an enchantment from each: for (int tag = a_NBT.GetFirstChild(a_EnchListTagIdx); tag >= 0; tag = a_NBT.GetNextSibling(tag)) { // tag is the compound inside the "ench" list tag ASSERT(a_NBT.GetType(tag) == TAG_Compound); - + // Search for the id and lvl tags' values: int id = -1, lvl = -1; for (int ch = a_NBT.GetFirstChild(tag); ch >= 0; ch = a_NBT.GetNextSibling(ch)) @@ -74,13 +74,13 @@ void EnchantmentSerializer::ParseFromNBT(cEnchantments & a_Enchantments, const c lvl = a_NBT.GetShort(ch); } } // for ch - children of the compound tag - + if ((id == -1) || (lvl <= 0)) { // Failed to parse either the id or the lvl, skip this compound continue; } - + // Store the enchantment: a_Enchantments.m_Enchantments[id] = static_cast(lvl); } // for tag - children of the ench list tag diff --git a/src/WorldStorage/EnchantmentSerializer.h b/src/WorldStorage/EnchantmentSerializer.h index 5c12e01bc..4dc75cb86 100644 --- a/src/WorldStorage/EnchantmentSerializer.h +++ b/src/WorldStorage/EnchantmentSerializer.h @@ -14,10 +14,10 @@ namespace EnchantmentSerializer /** Writes the enchantments into the specified NBT writer; begins with the LIST tag of the specified name ("ench" or "StoredEnchantments") */ void WriteToNBTCompound(const cEnchantments & a_Enchantments, cFastNBTWriter & a_Writer, const AString & a_ListTagName); - + /** Reads the enchantments from the specified NBT list tag (ench or StoredEnchantments) */ void ParseFromNBT(cEnchantments & a_Enchantments, const cParsedNBT & a_NBT, int a_EnchListTagIdx); - + }; diff --git a/src/WorldStorage/FastNBT.cpp b/src/WorldStorage/FastNBT.cpp index 1a81a6469..608269aad 100644 --- a/src/WorldStorage/FastNBT.cpp +++ b/src/WorldStorage/FastNBT.cpp @@ -69,16 +69,16 @@ bool cParsedNBT::Parse(void) // The top-level tag must be a Compound return false; } - + m_Tags.reserve(NBT_RESERVE_SIZE); - + m_Tags.push_back(cFastNBTTag(TAG_Compound, -1)); - + m_Pos = 1; - + RETURN_FALSE_IF_FALSE(ReadString(m_Tags.back().m_NameStart, m_Tags.back().m_NameLength)); RETURN_FALSE_IF_FALSE(ReadCompound()); - + return true; } @@ -145,7 +145,7 @@ bool cParsedNBT::ReadCompound(void) bool cParsedNBT::ReadList(eTagType a_ChildrenType) { // Reads the latest tag as a list of items of type a_ChildrenType - + // Read the count: NEEDBYTES(4); int Count = GetBEInt(m_Data + m_Pos); @@ -190,7 +190,7 @@ bool cParsedNBT::ReadList(eTagType a_ChildrenType) m_Pos += LEN; \ return true; \ } - + bool cParsedNBT::ReadTag(void) { cFastNBTTag & Tag = m_Tags.back(); @@ -202,12 +202,12 @@ bool cParsedNBT::ReadTag(void) CASE_SIMPLE_TAG(Long, 8) CASE_SIMPLE_TAG(Float, 4) CASE_SIMPLE_TAG(Double, 8) - + case TAG_String: { return ReadString(Tag.m_DataStart, Tag.m_DataLength); } - + case TAG_ByteArray: { NEEDBYTES(4); @@ -224,7 +224,7 @@ bool cParsedNBT::ReadTag(void) m_Pos += static_cast(len); return true; } - + case TAG_List: { NEEDBYTES(1); @@ -233,13 +233,13 @@ bool cParsedNBT::ReadTag(void) RETURN_FALSE_IF_FALSE(ReadList(ItemType)); return true; } - + case TAG_Compound: { RETURN_FALSE_IF_FALSE(ReadCompound()); return true; } - + case TAG_IntArray: { NEEDBYTES(4); @@ -257,7 +257,7 @@ bool cParsedNBT::ReadTag(void) m_Pos += static_cast(len); return true; } - + #if !defined(__clang__) default: #endif @@ -284,7 +284,7 @@ int cParsedNBT::FindChildByName(int a_Tag, const char * a_Name, size_t a_NameLen { return -1; } - + if (a_NameLength == 0) { a_NameLength = strlen(a_Name); @@ -328,7 +328,7 @@ int cParsedNBT::FindTagByPath(int a_Tag, const AString & a_Path) const } Begin = i + 1; } // for i - a_Path[] - + if (Begin < Length) { Tag = FindChildByName(Tag, a_Path.c_str() + Begin, Length - Begin); @@ -363,9 +363,9 @@ void cFastNBTWriter::BeginCompound(const AString & a_Name) ASSERT(!"Stack overflow"); return; } - + TagCommon(a_Name, TAG_Compound); - + ++m_CurrentStack; m_Stack[m_CurrentStack].m_Type = TAG_Compound; } @@ -378,7 +378,7 @@ void cFastNBTWriter::EndCompound(void) { ASSERT(m_CurrentStack > 0); ASSERT(IsStackTopCompound()); - + m_Result.push_back(TAG_End); --m_CurrentStack; } @@ -394,12 +394,12 @@ void cFastNBTWriter::BeginList(const AString & a_Name, eTagType a_ChildrenType) ASSERT(!"Stack overflow"); return; } - + TagCommon(a_Name, TAG_List); - + m_Result.push_back(static_cast(a_ChildrenType)); m_Result.append(4, static_cast(0)); - + ++m_CurrentStack; m_Stack[m_CurrentStack].m_Type = TAG_List; m_Stack[m_CurrentStack].m_Pos = static_cast(m_Result.size()) - 4; @@ -415,7 +415,7 @@ void cFastNBTWriter::EndList(void) { ASSERT(m_CurrentStack > 0); ASSERT(m_Stack[m_CurrentStack].m_Type == TAG_List); - + // Update the list count: SetBEInt(const_cast(m_Result.c_str() + m_Stack[m_CurrentStack].m_Pos), m_Stack[m_CurrentStack].m_Count); diff --git a/src/WorldStorage/FastNBT.h b/src/WorldStorage/FastNBT.h index a23dc7af2..60c9ac293 100644 --- a/src/WorldStorage/FastNBT.h +++ b/src/WorldStorage/FastNBT.h @@ -56,16 +56,16 @@ Structure (all with the tree structure it describes) supports moving in memory ( struct cFastNBTTag { public: - + eTagType m_Type; - + // The following members are indices into the data stream. m_DataLength == 0 if no data available // They must not be pointers, because the datastream may be copied into another AString object in the meantime. size_t m_NameStart; size_t m_NameLength; size_t m_DataStart; size_t m_DataLength; - + // The following members are indices into the array returned; -1 if not valid // They must not be pointers, because pointers would not survive std::vector reallocation int m_Parent; @@ -73,7 +73,7 @@ public: int m_NextSibling; int m_FirstChild; int m_LastChild; - + cFastNBTTag(eTagType a_Type, int a_Parent) : m_Type(a_Type), m_NameStart(0), @@ -119,24 +119,24 @@ class cParsedNBT { public: cParsedNBT(const char * a_Data, size_t a_Length); - + bool IsValid(void) const {return m_IsValid; } - + /** Returns the root tag of the hierarchy. */ int GetRoot(void) const {return 0; } /** Returns the first child of the specified tag, or -1 if none / not applicable. */ int GetFirstChild (int a_Tag) const { return m_Tags[static_cast(a_Tag)].m_FirstChild; } - + /** Returns the last child of the specified tag, or -1 if none / not applicable. */ int GetLastChild (int a_Tag) const { return m_Tags[static_cast(a_Tag)].m_LastChild; } - + /** Returns the next sibling of the specified tag, or -1 if none. */ int GetNextSibling(int a_Tag) const { return m_Tags[static_cast(a_Tag)].m_NextSibling; } - + /** Returns the previous sibling of the specified tag, or -1 if none. */ int GetPrevSibling(int a_Tag) const { return m_Tags[static_cast(a_Tag)].m_PrevSibling; } - + /** Returns the length of the tag's data, in bytes. Not valid for Compound or List tags! */ size_t GetDataLength (int a_Tag) const @@ -154,35 +154,35 @@ public: ASSERT(m_Tags[static_cast(a_Tag)].m_Type != TAG_Compound); return m_Data + m_Tags[static_cast(a_Tag)].m_DataStart; } - + /** Returns the direct child tag of the specified name, or -1 if no such tag. */ int FindChildByName(int a_Tag, const AString & a_Name) const { return FindChildByName(a_Tag, a_Name.c_str(), a_Name.length()); } - + /** Returns the direct child tag of the specified name, or -1 if no such tag. */ int FindChildByName(int a_Tag, const char * a_Name, size_t a_NameLength = 0) const; /** Returns the child tag of the specified path (Name1 / Name2 / Name3...), or -1 if no such tag. */ int FindTagByPath(int a_Tag, const AString & a_Path) const; - + eTagType GetType(int a_Tag) const { return m_Tags[static_cast(a_Tag)].m_Type; } - + /** Returns the children type for a List tag; undefined on other tags. If list empty, returns TAG_End. */ eTagType GetChildrenType(int a_Tag) const { ASSERT(m_Tags[static_cast(a_Tag)].m_Type == TAG_List); return (m_Tags[static_cast(a_Tag)].m_FirstChild < 0) ? TAG_End : m_Tags[static_cast(m_Tags[static_cast(a_Tag)].m_FirstChild)].m_Type; } - + /** Returns the value stored in a Byte tag. Not valid for any other tag type. */ inline unsigned char GetByte(int a_Tag) const { ASSERT(m_Tags[static_cast(a_Tag)].m_Type == TAG_Byte); return static_cast(m_Data[static_cast(m_Tags[static_cast(a_Tag)].m_DataStart)]); } - + /** Returns the value stored in a Short tag. Not valid for any other tag type. */ inline Int16 GetShort(int a_Tag) const { @@ -208,20 +208,20 @@ public: inline float GetFloat(int a_Tag) const { ASSERT(m_Tags[static_cast(a_Tag)].m_Type == TAG_Float); - + // Cause a compile-time error if sizeof(float) != 4 // If your platform produces a compiler error here, you'll need to add code that manually decodes 32-bit floats char Check1[5 - sizeof(float)]; // Fails if sizeof(float) > 4 char Check2[sizeof(float) - 3]; // Fails if sizeof(float) < 4 UNUSED_VAR(Check1); UNUSED_VAR(Check2); - + Int32 i = GetBEInt(m_Data + m_Tags[static_cast(a_Tag)].m_DataStart); float f; memcpy(&f, &i, sizeof(f)); return f; } - + /** Returns the value stored in a Double tag. Not valid for any other tag type. */ inline double GetDouble(int a_Tag) const { @@ -235,7 +235,7 @@ public: ASSERT(m_Tags[static_cast(a_Tag)].m_Type == TAG_Double); return NetworkToHostDouble8(m_Data + m_Tags[static_cast(a_Tag)].m_DataStart); } - + /** Returns the value stored in a String tag. Not valid for any other tag type. */ inline AString GetString(int a_Tag) const { @@ -244,7 +244,7 @@ public: res.assign(m_Data + m_Tags[static_cast(a_Tag)].m_DataStart, static_cast(m_Tags[static_cast(a_Tag)].m_DataLength)); return res; } - + /** Returns the tag's name. For tags that are not named, returns an empty string. */ inline AString GetName(int a_Tag) const { @@ -252,7 +252,7 @@ public: res.assign(m_Data + m_Tags[static_cast(a_Tag)].m_NameStart, static_cast(m_Tags[static_cast(a_Tag)].m_NameLength)); return res; } - + protected: const char * m_Data; size_t m_Length; @@ -277,13 +277,13 @@ class cFastNBTWriter { public: cFastNBTWriter(const AString & a_RootTagName = ""); - + void BeginCompound(const AString & a_Name); void EndCompound(void); - + void BeginList(const AString & a_Name, eTagType a_ChildrenType); void EndList(void); - + void AddByte (const AString & a_Name, unsigned char a_Value); void AddShort (const AString & a_Name, Int16 a_Value); void AddInt (const AString & a_Name, Int32 a_Value); @@ -298,11 +298,11 @@ public: { AddByteArray(a_Name, a_Value.data(), a_Value.size()); } - + const AString & GetResult(void) const {return m_Result; } - + void Finish(void); - + protected: struct sParent @@ -312,24 +312,24 @@ protected: int m_Count; // for TAG_List, the element count eTagType m_ItemType; // for TAG_List, the element type } ; - + static const int MAX_STACK = 50; // Highly doubtful that an NBT would be constructed this many levels deep - + // These two fields emulate a stack. A raw array is used due to speed issues - no reallocations are allowed. sParent m_Stack[MAX_STACK]; int m_CurrentStack; - + AString m_Result; - + bool IsStackTopCompound(void) const { return (m_Stack[m_CurrentStack].m_Type == TAG_Compound); } - + void WriteString(const char * a_Data, UInt16 a_Length); - + inline void TagCommon(const AString & a_Name, eTagType a_Type) { // If we're directly inside a list, check that the list is of the correct type: ASSERT((m_Stack[m_CurrentStack].m_Type != TAG_List) || (m_Stack[m_CurrentStack].m_ItemType == a_Type)); - + if (IsStackTopCompound()) { // Compound: add the type and name: diff --git a/src/WorldStorage/MapSerializer.cpp b/src/WorldStorage/MapSerializer.cpp index 8acfa4696..3899ad505 100644 --- a/src/WorldStorage/MapSerializer.cpp +++ b/src/WorldStorage/MapSerializer.cpp @@ -68,7 +68,7 @@ bool cMapSerializer::Save(void) SaveMapToNBT(Writer); Writer.Finish(); - + #ifdef _DEBUG cParsedNBT TestParse(Writer.GetResult().data(), Writer.GetResult().size()); ASSERT(TestParse.IsValid()); @@ -140,7 +140,7 @@ bool cMapSerializer::LoadMapFromNBT(const cParsedNBT & a_NBT) if ((CurrLine >= 0) && (a_NBT.GetType(CurrLine) == TAG_Byte)) { eDimension Dimension = static_cast(a_NBT.GetByte(CurrLine)); - + if (Dimension != m_Map->m_World->GetDimension()) { // TODO 2014-03-20 xdot: We should store nether maps in nether worlds, e.t.c. @@ -259,7 +259,7 @@ bool cIDCountSerializer::Save(void) } Writer.Finish(); - + #ifdef _DEBUG cParsedNBT TestParse(Writer.GetResult().data(), Writer.GetResult().size()); ASSERT(TestParse.IsValid()); diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 3a0823491..86ad10af2 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -65,7 +65,7 @@ void cNBTChunkSerializer::Finish(void) { m_Writer.EndList(); } - + // If light not valid, reset it to all zeroes: if (!m_IsLightValid) { @@ -100,7 +100,7 @@ void cNBTChunkSerializer::AddItem(const cItem & a_Item, int a_Slot, const AStrin { m_Writer.AddByte ("Slot", static_cast(a_Slot)); } - + // Write the tag compound (for enchantment, firework, custom name and repair cost): if ( (!a_Item.m_Enchantments.IsEmpty()) || @@ -142,7 +142,7 @@ void cNBTChunkSerializer::AddItem(const cItem & a_Item, int a_Slot, const AStrin } m_Writer.EndCompound(); } - + m_Writer.EndCompound(); } @@ -457,7 +457,7 @@ void cNBTChunkSerializer::AddFallingBlockEntity(cFallingBlock * a_FallingBlock) void cNBTChunkSerializer::AddMinecartEntity(cMinecart * a_Minecart) { m_Writer.BeginCompound(""); - + switch (a_Minecart->GetPayload()) { case cMinecart::mpChest: @@ -490,7 +490,7 @@ void cNBTChunkSerializer::AddMinecartEntity(cMinecart * a_Minecart) break; } } // switch (Payload) - + m_Writer.EndCompound(); } @@ -717,7 +717,7 @@ void cNBTChunkSerializer::AddProjectileEntity(cProjectileEntity * a_Projectile) m_Writer.BeginCompound(""); AddBasicEntity(a_Projectile, a_Projectile->GetMCAClassName()); m_Writer.AddByte("inGround", a_Projectile->IsInGround() ? 1 : 0); - + switch (a_Projectile->GetProjectileKind()) { case cProjectileEntity::pkArrow: @@ -734,7 +734,7 @@ void cNBTChunkSerializer::AddProjectileEntity(cProjectileEntity * a_Projectile) case cProjectileEntity::pkSplashPotion: { cSplashPotionEntity * Potion = reinterpret_cast(a_Projectile); - + m_Writer.AddInt("EffectType", static_cast(Potion->GetEntityEffectType())); m_Writer.AddInt("EffectDuration", static_cast(Potion->GetEntityEffect().GetDuration())); m_Writer.AddShort("EffectIntensity", Potion->GetEntityEffect().GetIntensity()); @@ -920,7 +920,7 @@ void cNBTChunkSerializer::Entity(cEntity * a_Entity) } m_IsTagOpen = true; m_HasHadEntity = true; - + switch (a_Entity->GetEntityType()) { case cEntity::etBoat: AddBoatEntity (reinterpret_cast (a_Entity)); break; diff --git a/src/WorldStorage/NBTChunkSerializer.h b/src/WorldStorage/NBTChunkSerializer.h index 9cdfb1a76..08433c3ec 100644 --- a/src/WorldStorage/NBTChunkSerializer.h +++ b/src/WorldStorage/NBTChunkSerializer.h @@ -70,19 +70,19 @@ public: /** Close NBT tags that we've opened */ void Finish(void); - + bool IsLightValid(void) const {return m_IsLightValid; } protected: - + /* From cChunkDataSeparateCollector we inherit: - m_BlockTypes[] - m_BlockMetas[] - m_BlockLight[] - m_BlockSkyLight[] */ - + cFastNBTWriter & m_Writer; - + bool m_IsTagOpen; // True if a tag has been opened in the callbacks and not yet closed. bool m_HasHadEntity; // True if any Entity has already been received and processed bool m_HasHadBlockEntity; // True if any BlockEntity has already been received and processed @@ -91,10 +91,10 @@ protected: /** Writes an item into the writer, if slot >= 0, adds the Slot tag. The compound is named as requested. */ void AddItem(const cItem & a_Item, int a_Slot, const AString & a_CompoundName = ""); - + /** Writes an item grid into the writer; begins the stored slot numbers with a_BeginSlotNum. Note that it doesn't begin nor end the list tag */ void AddItemGrid(const cItemGrid & a_Grid, int a_BeginSlotNum = 0); - + // Block entities: void AddBasicTileEntity (cBlockEntity * a_Entity, const char * a_EntityTypeID); void AddBeaconEntity (cBeaconEntity * a_Entity); @@ -111,7 +111,7 @@ protected: void AddMobHeadEntity (cMobHeadEntity * a_MobHead); void AddCommandBlockEntity(cCommandBlockEntity * a_CmdBlock); void AddFlowerPotEntity (cFlowerPotEntity * a_FlowerPot); - + // Entities: void AddBasicEntity (cEntity * a_Entity, const AString & a_ClassName); void AddBoatEntity (cBoat * a_Boat); @@ -126,9 +126,9 @@ protected: void AddExpOrbEntity (cExpOrb * a_ExpOrb); void AddItemFrameEntity (cItemFrame * a_ItemFrame); void AddPaintingEntity (cPainting * a_Painting); - + void AddMinecartChestContents(cMinecartWithChest * a_Minecart); - + // cChunkDataSeparateCollector overrides: virtual void LightIsValid(bool a_IsLightValid) override; virtual void HeightMap(const cChunkDef::HeightMap * a_HeightMap) override; diff --git a/src/WorldStorage/SchematicFileSerializer.cpp b/src/WorldStorage/SchematicFileSerializer.cpp index 6267668c5..1b2047574 100644 --- a/src/WorldStorage/SchematicFileSerializer.cpp +++ b/src/WorldStorage/SchematicFileSerializer.cpp @@ -70,7 +70,7 @@ bool cSchematicFileSerializer::LoadFromSchematicFile(cBlockArea & a_BlockArea, c return false; } File.Close(); - + // Parse the NBT: cParsedNBT NBT(Contents.data(), Contents.size()); if (!NBT.IsValid()) @@ -78,7 +78,7 @@ bool cSchematicFileSerializer::LoadFromSchematicFile(cBlockArea & a_BlockArea, c LOG("Cannot parse the NBT in the schematic file \"%s\".", a_FileName.c_str()); return false; } - + return LoadFromSchematicNBT(a_BlockArea, NBT); } @@ -104,7 +104,7 @@ bool cSchematicFileSerializer::LoadFromSchematicString(cBlockArea & a_BlockArea, LOG("%s: Cannot parse the NBT in the schematic data.", __FUNCTION__); return false; } - + return LoadFromSchematicNBT(a_BlockArea, NBT); } @@ -121,7 +121,7 @@ bool cSchematicFileSerializer::SaveToSchematicFile(const cBlockArea & a_BlockAre LOG("%s: Cannot serialize the area into an NBT representation for file \"%s\".", __FUNCTION__, a_FileName.c_str()); return false; } - + // Save to file cGZipFile File; if (!File.Open(a_FileName, cGZipFile::fmWrite)) @@ -151,7 +151,7 @@ bool cSchematicFileSerializer::SaveToSchematicString(const cBlockArea & a_BlockA LOG("%s: Cannot serialize the area into an NBT representation.", __FUNCTION__); return false; } - + // Gzip the data: int res = CompressStringGZIP(NBT.data(), NBT.size(), a_Out); if (res != Z_OK) @@ -196,7 +196,7 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP ); return false; } - + int SizeX = a_NBT.GetShort(TSizeX); int SizeY = a_NBT.GetShort(TSizeY); int SizeZ = a_NBT.GetShort(TSizeZ); @@ -205,7 +205,7 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP LOG("Dimensions are invalid in the schematic file: %d, %d, %d", SizeX, SizeY, SizeZ); return false; } - + int TBlockTypes = a_NBT.FindChildByName(a_NBT.GetRoot(), "Blocks"); int TBlockMetas = a_NBT.FindChildByName(a_NBT.GetRoot(), "Data"); if ((TBlockTypes < 0) || (a_NBT.GetType(TBlockTypes) != TAG_ByteArray)) @@ -214,14 +214,14 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP return false; } bool AreMetasPresent = (TBlockMetas > 0) && (a_NBT.GetType(TBlockMetas) == TAG_ByteArray); - + a_BlockArea.Clear(); a_BlockArea.SetSize(SizeX, SizeY, SizeZ, AreMetasPresent ? (cBlockArea::baTypes | cBlockArea::baMetas) : cBlockArea::baTypes); - + int TOffsetX = a_NBT.FindChildByName(a_NBT.GetRoot(), "WEOffsetX"); int TOffsetY = a_NBT.FindChildByName(a_NBT.GetRoot(), "WEOffsetY"); int TOffsetZ = a_NBT.FindChildByName(a_NBT.GetRoot(), "WEOffsetZ"); - + if ( (TOffsetX < 0) || (TOffsetY < 0) || (TOffsetZ < 0) || (a_NBT.GetType(TOffsetX) != TAG_Int) || @@ -247,7 +247,7 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP NumTypeBytes = a_NBT.GetDataLength(TBlockTypes); } memcpy(a_BlockArea.m_BlockTypes, a_NBT.GetData(TBlockTypes), NumTypeBytes); - + if (AreMetasPresent) { size_t NumMetaBytes = a_BlockArea.GetBlockCount(); @@ -260,7 +260,7 @@ bool cSchematicFileSerializer::LoadFromSchematicNBT(cBlockArea & a_BlockArea, cP } memcpy(a_BlockArea.m_BlockMetas, a_NBT.GetData(TBlockMetas), NumMetaBytes); } - + return true; } @@ -293,7 +293,7 @@ AString cSchematicFileSerializer::SaveToSchematicNBT(const cBlockArea & a_BlockA AString Dummy(a_BlockArea.GetBlockCount(), 0); Writer.AddByteArray("Data", Dummy.data(), Dummy.size()); } - + Writer.AddInt("WEOffsetX", a_BlockArea.m_WEOffset.x); Writer.AddInt("WEOffsetY", a_BlockArea.m_WEOffset.y); Writer.AddInt("WEOffsetZ", a_BlockArea.m_WEOffset.z); @@ -304,7 +304,7 @@ AString cSchematicFileSerializer::SaveToSchematicNBT(const cBlockArea & a_BlockA Writer.BeginList("TileEntities", TAG_Compound); Writer.EndList(); Writer.Finish(); - + return Writer.GetResult(); } diff --git a/src/WorldStorage/SchematicFileSerializer.h b/src/WorldStorage/SchematicFileSerializer.h index 05b6c74f4..6aaa0662f 100644 --- a/src/WorldStorage/SchematicFileSerializer.h +++ b/src/WorldStorage/SchematicFileSerializer.h @@ -25,20 +25,20 @@ class cParsedNBT; class cSchematicFileSerializer { public: - + /** Loads an area from a .schematic file. Returns true if successful. */ static bool LoadFromSchematicFile(cBlockArea & a_BlockArea, const AString & a_FileName); - + /** Loads an area from a string containing the .schematic file data. Returns true if successful. */ static bool LoadFromSchematicString(cBlockArea & a_BlockArea, const AString & a_SchematicData); - + /** Saves the area into a .schematic file. Returns true if successful. */ static bool SaveToSchematicFile(const cBlockArea & a_BlockArea, const AString & a_FileName); - + /** Saves the area into a string containing the .schematic file data. Returns true if successful, false on failure. The data is stored into a_Out. */ static bool SaveToSchematicString(const cBlockArea & a_BlockArea, AString & a_Out); - + private: /** Loads the area from a schematic file uncompressed and parsed into a NBT tree. Returns true if successful. */ diff --git a/src/WorldStorage/ScoreboardSerializer.cpp b/src/WorldStorage/ScoreboardSerializer.cpp index 01e56dbe1..27ce36455 100644 --- a/src/WorldStorage/ScoreboardSerializer.cpp +++ b/src/WorldStorage/ScoreboardSerializer.cpp @@ -67,7 +67,7 @@ bool cScoreboardSerializer::Save(void) SaveScoreboardToNBT(Writer); Writer.Finish(); - + #ifdef _DEBUG cParsedNBT TestParse(Writer.GetResult().data(), Writer.GetResult().size()); ASSERT(TestParse.IsValid()); @@ -102,7 +102,7 @@ void cScoreboardSerializer::SaveScoreboardToNBT(cFastNBTWriter & a_Writer) a_Writer.BeginCompound("data"); a_Writer.BeginList("Objectives", TAG_Compound); - + for (cScoreboard::cObjectiveMap::const_iterator it = m_ScoreBoard->m_Objectives.begin(); it != m_ScoreBoard->m_Objectives.end(); ++it) { const cObjective & Objective = it->second; @@ -133,7 +133,7 @@ void cScoreboardSerializer::SaveScoreboardToNBT(cFastNBTWriter & a_Writer) a_Writer.AddString("Name", it2->first); a_Writer.AddString("Objective", it->first); - + a_Writer.EndCompound(); } } @@ -141,7 +141,7 @@ void cScoreboardSerializer::SaveScoreboardToNBT(cFastNBTWriter & a_Writer) a_Writer.EndList(); // PlayerScores a_Writer.BeginList("Teams", TAG_Compound); - + for (cScoreboard::cTeamMap::const_iterator it = m_ScoreBoard->m_Teams.begin(); it != m_ScoreBoard->m_Teams.end(); ++it) { const cTeam & Team = it->second; diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 385a3a3ca..4fc855589 100755 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -110,7 +110,7 @@ cWSSAnvil::cWSSAnvil(cWorld * a_World, int a_CompressionFactor) : Writer.AddString("LevelName", a_World->GetName()); Writer.EndCompound(); Writer.Finish(); - + gzFile gz = gzopen((FILE_IO_PREFIX + fnam).c_str(), "wb"); if (gz != nullptr) { @@ -145,7 +145,7 @@ bool cWSSAnvil::LoadChunk(const cChunkCoords & a_Chunk) // The reason for failure is already printed in GetChunkData() return false; } - + return LoadChunkFromData(a_Chunk, ChunkData); } @@ -166,7 +166,7 @@ bool cWSSAnvil::SaveChunk(const cChunkCoords & a_Chunk) LOGWARNING("Cannot store chunk [%d, %d] data", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); return false; } - + // Everything successful return true; } @@ -266,7 +266,7 @@ cWSSAnvil::cMCAFile * cWSSAnvil::LoadMCAFile(const cChunkCoords & a_Chunk) ASSERT(a_Chunk.m_ChunkZ - RegionZ * 32 >= 0); ASSERT(a_Chunk.m_ChunkX - RegionX * 32 < 32); ASSERT(a_Chunk.m_ChunkZ - RegionZ * 32 < 32); - + // Is it already cached? for (cMCAFiles::iterator itr = m_Files.begin(); itr != m_Files.end(); ++itr) { @@ -282,7 +282,7 @@ cWSSAnvil::cMCAFile * cWSSAnvil::LoadMCAFile(const cChunkCoords & a_Chunk) return f; } } - + // Load it anew: AString FileName; Printf(FileName, "%s%cregion", m_World->GetName().c_str(), cFile::PathSeparator); @@ -294,7 +294,7 @@ cWSSAnvil::cMCAFile * cWSSAnvil::LoadMCAFile(const cChunkCoords & a_Chunk) return nullptr; } m_Files.push_front(f); - + // If there are too many MCA files cached, delete the last one used: if (m_Files.size() > MAX_MCA_FILES) { @@ -319,7 +319,7 @@ bool cWSSAnvil::LoadChunkFromData(const cChunkCoords & a_Chunk, const AString & ChunkLoadFailed(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, "InflateString() failed", a_Data); return false; } - + // Parse the NBT data: cParsedNBT NBT(Uncompressed.data(), Uncompressed.size()); if (!NBT.IsValid()) @@ -346,7 +346,7 @@ bool cWSSAnvil::SaveChunkToData(const cChunkCoords & a_Chunk, AString & a_Data) return false; } Writer.Finish(); - + CompressString(Writer.GetResult().data(), Writer.GetResult().size(), a_Data, m_CompressionFactor); return true; } @@ -362,12 +362,12 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT cChunkDef::BlockNibbles MetaData; cChunkDef::BlockNibbles BlockLight; cChunkDef::BlockNibbles SkyLight; - + memset(BlockTypes, E_BLOCK_AIR, sizeof(BlockTypes)); memset(MetaData, 0, sizeof(MetaData)); memset(SkyLight, 0xff, sizeof(SkyLight)); // By default, data not present in the NBT means air, which means full skylight memset(BlockLight, 0x00, sizeof(BlockLight)); - + // Load the blockdata, blocklight and skylight: int Level = a_NBT.FindChildByName(0, "Level"); if (Level < 0) @@ -405,7 +405,7 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT CopyNBTData(a_NBT, Child, "SkyLight", reinterpret_cast(&(SkyLight[y * 2048])), 2048); CopyNBTData(a_NBT, Child, "BlockLight", reinterpret_cast(&(BlockLight[y * 2048])), 2048); } // for itr - LevelSections[] - + // Load the biomes from NBT, if present and valid. First try MCS-style, then Vanilla-style: cChunkDef::BiomeMap BiomeMap; cChunkDef::BiomeMap * Biomes = LoadBiomeMapFromNBT(&BiomeMap, a_NBT, a_NBT.FindChildByName(Level, "MCSBiomes")); @@ -414,15 +414,15 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT // MCS-style biomes not available, load vanilla-style: Biomes = LoadVanillaBiomeMapFromNBT(&BiomeMap, a_NBT, a_NBT.FindChildByName(Level, "Biomes")); } - + // Load the entities from NBT: cEntityList Entities; cBlockEntityList BlockEntities; LoadEntitiesFromNBT (Entities, a_NBT, a_NBT.FindChildByName(Level, "Entities")); LoadBlockEntitiesFromNBT(BlockEntities, a_NBT, a_NBT.FindChildByName(Level, "TileEntities"), BlockTypes, MetaData); - + bool IsLightValid = (a_NBT.FindChildByName(Level, "MCSIsLightValid") > 0); - + /* // Uncomment this block for really cool stuff :) // DEBUG magic: Invert the underground, so that we can see the MC generator in action :) @@ -458,7 +458,7 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT } } // for y //*/ - + cSetChunkDataPtr SetChunkData(new cSetChunkData( a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, BlockTypes, MetaData, @@ -501,7 +501,7 @@ bool cWSSAnvil::SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_ return false; } Serializer.Finish(); // Close NBT tags - + // Save biomes, both MCS (IntArray) and MC-vanilla (ByteArray): if (Serializer.m_BiomesAreValid) { @@ -535,7 +535,7 @@ bool cWSSAnvil::SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_ a_Writer.EndCompound(); } a_Writer.EndList(); // "Sections" - + // Store the information that the lighting is valid. // For compatibility reason, the default is "invalid" (missing) - this means older data is re-lighted upon loading. if (Serializer.IsLightValid()) @@ -545,10 +545,10 @@ bool cWSSAnvil::SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_ // Save the world age to the chunk data. Required by vanilla and mcedit. a_Writer.AddLong("LastUpdate", m_World->GetWorldAge()); - + // Store the flag that the chunk has all the ores, trees, dungeons etc. MCS chunks are always complete. a_Writer.AddByte("TerrainPopulated", 1); - + a_Writer.EndCompound(); // "Level" return true; } @@ -619,7 +619,7 @@ void cWSSAnvil::LoadEntitiesFromNBT(cEntityList & a_Entities, const cParsedNBT & { return; } - + for (int Child = a_NBT.GetFirstChild(a_TagIdx); Child != -1; Child = a_NBT.GetNextSibling(Child)) { if (a_NBT.GetType(Child) != TAG_Compound) @@ -645,7 +645,7 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con { return; } - + for (int Child = a_NBT.GetFirstChild(a_TagIdx); Child != -1; Child = a_NBT.GetNextSibling(Child)) { if (a_NBT.GetType(Child) != TAG_Compound) @@ -761,19 +761,19 @@ bool cWSSAnvil::LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_ a_Item.Empty(); return true; } - + int Damage = a_NBT.FindChildByName(a_TagIdx, "Damage"); if ((Damage > 0) && (a_NBT.GetType(Damage) == TAG_Short)) { a_Item.m_ItemDamage = a_NBT.GetShort(Damage); } - + int Count = a_NBT.FindChildByName(a_TagIdx, "Count"); if ((Count > 0) && (a_NBT.GetType(Count) == TAG_Byte)) { a_Item.m_ItemCount = static_cast(a_NBT.GetByte(Count)); } - + // Find the "tag" tag, used for enchantments and other extra data int TagTag = a_NBT.FindChildByName(a_TagIdx, "tag"); if (TagTag <= 0) @@ -819,7 +819,7 @@ bool cWSSAnvil::LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_ { cFireworkItem::ParseFromNBT(a_Item.m_FireworkItem, a_NBT, FireworksTag, static_cast(a_Item.m_ItemType)); } - + return true; } @@ -1134,7 +1134,7 @@ cBlockEntity * cWSSAnvil::LoadFurnaceFromNBT(const cParsedNBT & a_NBT, int a_Tag { return nullptr; // Make it an empty furnace - the chunk loader will provide an empty cFurnaceEntity for this } - + std::unique_ptr Furnace = cpp14::make_unique(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, m_World); Furnace->SetLoading(true); @@ -1152,7 +1152,7 @@ cBlockEntity * cWSSAnvil::LoadFurnaceFromNBT(const cParsedNBT & a_NBT, int a_Tag Furnace->SetSlot(a_NBT.GetByte(Slot), Item); } } // for itr - ItemDefs[] - + // Load burn time: int BurnTime = a_NBT.FindChildByName(a_TagIdx, "BurnTime"); if (BurnTime >= 0) @@ -1161,7 +1161,7 @@ cBlockEntity * cWSSAnvil::LoadFurnaceFromNBT(const cParsedNBT & a_NBT, int a_Tag // Anvil doesn't store the time that the fuel can burn. We simply "reset" the current value to be the 100% Furnace->SetBurnTimes(bt, 0); } - + // Load cook time: int CookTime = a_NBT.FindChildByName(a_TagIdx, "CookTime"); if (CookTime >= 0) @@ -1741,9 +1741,9 @@ void cWSSAnvil::LoadMinecartFFromNBT(cEntityList & a_Entities, const cParsedNBT { return; } - + // TODO: Load the Push and Fuel tags - + a_Entities.push_back(Minecart.release()); } @@ -1758,7 +1758,7 @@ void cWSSAnvil::LoadMinecartTFromNBT(cEntityList & a_Entities, const cParsedNBT { return; } - + // TODO: Everything to do with TNT carts a_Entities.push_back(Minecart.release()); @@ -1775,7 +1775,7 @@ void cWSSAnvil::LoadMinecartHFromNBT(cEntityList & a_Entities, const cParsedNBT { return; } - + // TODO: Everything to do with hopper carts a_Entities.push_back(Minecart.release()); @@ -1798,13 +1798,13 @@ void cWSSAnvil::LoadPickupFromNBT(cEntityList & a_Entities, const cParsedNBT & a { return; } - + std::unique_ptr Pickup = cpp14::make_unique(0, 0, 0, Item, false); // Pickup delay doesn't matter, just say false if (!LoadEntityBaseFromNBT(*Pickup.get(), a_NBT, a_TagIdx)) { return; } - + // Load age: int Age = a_NBT.FindChildByName(a_TagIdx, "Age"); if (Age > 0) @@ -1826,14 +1826,14 @@ void cWSSAnvil::LoadTNTFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB { return; } - + // Load Fuse Ticks: int FuseTicks = a_NBT.FindChildByName(a_TagIdx, "Fuse"); if (FuseTicks > 0) { TNT->SetFuseTicks(static_cast(a_NBT.GetByte(FuseTicks))); } - + a_Entities.push_back(TNT.release()); } @@ -1911,7 +1911,7 @@ void cWSSAnvil::LoadItemFrameFromNBT(cEntityList & a_Entities, const cParsedNBT { return; } - + std::unique_ptr ItemFrame = cpp14::make_unique(BLOCK_FACE_NONE, 0.0, 0.0, 0.0); if (!LoadEntityBaseFromNBT(*ItemFrame.get(), a_NBT, a_TagIdx)) { @@ -1920,14 +1920,14 @@ void cWSSAnvil::LoadItemFrameFromNBT(cEntityList & a_Entities, const cParsedNBT ItemFrame->SetItem(Item); LoadHangingFromNBT(*ItemFrame.get(), a_NBT, a_TagIdx); - + // Load Rotation: int Rotation = a_NBT.FindChildByName(a_TagIdx, "ItemRotation"); if (Rotation > 0) { ItemFrame->SetItemRotation(static_cast(a_NBT.GetByte(Rotation))); } - + a_Entities.push_back(ItemFrame.release()); } @@ -1965,7 +1965,7 @@ void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ { return; } - + // Load pickup state: int PickupIdx = a_NBT.FindChildByName(a_TagIdx, "pickup"); if ((PickupIdx > 0) && (a_NBT.GetType(PickupIdx) == TAG_Byte)) @@ -1981,14 +1981,14 @@ void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ Arrow->SetPickupState((a_NBT.GetByte(PlayerIdx) == 0) ? cArrowEntity::psNoPickup : cArrowEntity::psInSurvivalOrCreative); } } - + // Load damage: int DamageIdx = a_NBT.FindChildByName(a_TagIdx, "damage"); if ((DamageIdx > 0) && (a_NBT.GetType(DamageIdx) == TAG_Double)) { Arrow->SetDamageCoeff(a_NBT.GetDouble(DamageIdx)); } - + // Load block hit: int InBlockXIdx = a_NBT.FindChildByName(a_TagIdx, "xTile"); int InBlockYIdx = a_NBT.FindChildByName(a_TagIdx, "yTile"); @@ -2020,7 +2020,7 @@ void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ } } } - + // Store the new arrow in the entities list: a_Entities.push_back(Arrow.release()); } @@ -2035,15 +2035,15 @@ void cWSSAnvil::LoadSplashPotionFromNBT(cEntityList & a_Entities, const cParsedN { return; } - + int EffectDuration = a_NBT.FindChildByName(a_TagIdx, "EffectDuration"); int EffectIntensity = a_NBT.FindChildByName(a_TagIdx, "EffectIntensity"); int EffectDistanceModifier = a_NBT.FindChildByName(a_TagIdx, "EffectDistanceModifier"); - + SplashPotion->SetEntityEffectType(static_cast(a_NBT.FindChildByName(a_TagIdx, "EffectType"))); SplashPotion->SetEntityEffect(cEntityEffect(EffectDuration, static_cast(EffectIntensity), EffectDistanceModifier)); SplashPotion->SetPotionColor(a_NBT.FindChildByName(a_TagIdx, "PotionName")); - + // Store the new splash potion in the entities list: a_Entities.push_back(SplashPotion.release()); } @@ -2059,7 +2059,7 @@ void cWSSAnvil::LoadSnowballFromNBT(cEntityList & a_Entities, const cParsedNBT & { return; } - + // Store the new snowball in the entities list: a_Entities.push_back(Snowball.release()); } @@ -2075,7 +2075,7 @@ void cWSSAnvil::LoadEggFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB { return; } - + // Store the new egg in the entities list: a_Entities.push_back(Egg.release()); } @@ -2091,7 +2091,7 @@ void cWSSAnvil::LoadFireballFromNBT(cEntityList & a_Entities, const cParsedNBT & { return; } - + // Store the new fireball in the entities list: a_Entities.push_back(Fireball.release()); } @@ -2107,7 +2107,7 @@ void cWSSAnvil::LoadFireChargeFromNBT(cEntityList & a_Entities, const cParsedNBT { return; } - + // Store the new FireCharge in the entities list: a_Entities.push_back(FireCharge.release()); } @@ -2123,7 +2123,7 @@ void cWSSAnvil::LoadThrownEnderpearlFromNBT(cEntityList & a_Entities, const cPar { return; } - + // Store the new enderpearl in the entities list: a_Entities.push_back(Enderpearl.release()); } @@ -2139,7 +2139,7 @@ void cWSSAnvil::LoadBatFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2159,7 +2159,7 @@ void cWSSAnvil::LoadBlazeFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2179,7 +2179,7 @@ void cWSSAnvil::LoadCaveSpiderFromNBT(cEntityList & a_Entities, const cParsedNBT { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2199,7 +2199,7 @@ void cWSSAnvil::LoadChickenFromNBT(cEntityList & a_Entities, const cParsedNBT & { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2219,7 +2219,7 @@ void cWSSAnvil::LoadCowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2239,7 +2239,7 @@ void cWSSAnvil::LoadCreeperFromNBT(cEntityList & a_Entities, const cParsedNBT & { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2259,7 +2259,7 @@ void cWSSAnvil::LoadEnderDragonFromNBT(cEntityList & a_Entities, const cParsedNB { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2319,7 +2319,7 @@ void cWSSAnvil::LoadGiantFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2339,7 +2339,7 @@ void cWSSAnvil::LoadGuardianFromNBT(cEntityList & a_Entities, const cParsedNBT & { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2372,12 +2372,12 @@ void cWSSAnvil::LoadHorseFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; } - + int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age"); if (AgeableIdx > 0) { @@ -2390,7 +2390,7 @@ void cWSSAnvil::LoadHorseFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ } Monster->SetAge(Age); } - + a_Entities.push_back(Monster.release()); } @@ -2405,7 +2405,7 @@ void cWSSAnvil::LoadIronGolemFromNBT(cEntityList & a_Entities, const cParsedNBT { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2434,7 +2434,7 @@ void cWSSAnvil::LoadMagmaCubeFromNBT(cEntityList & a_Entities, const cParsedNBT { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2454,7 +2454,7 @@ void cWSSAnvil::LoadMooshroomFromNBT(cEntityList & a_Entities, const cParsedNBT { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2474,7 +2474,7 @@ void cWSSAnvil::LoadOcelotFromNBT(cEntityList & a_Entities, const cParsedNBT & a { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2492,7 +2492,7 @@ void cWSSAnvil::LoadOcelotFromNBT(cEntityList & a_Entities, const cParsedNBT & a } Monster->SetAge(Age); } - + a_Entities.push_back(Monster.release()); } @@ -2507,12 +2507,12 @@ void cWSSAnvil::LoadPigFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; } - + int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age"); if (AgeableIdx > 0) { @@ -2525,7 +2525,7 @@ void cWSSAnvil::LoadPigFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB } Monster->SetAge(Age); } - + a_Entities.push_back(Monster.release()); } @@ -2551,12 +2551,12 @@ void cWSSAnvil::LoadRabbitFromNBT(cEntityList & a_Entities, const cParsedNBT & a { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; } - + int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age"); if (AgeableIdx > 0) { @@ -2569,7 +2569,7 @@ void cWSSAnvil::LoadRabbitFromNBT(cEntityList & a_Entities, const cParsedNBT & a } Monster->SetAge(Age); } - + a_Entities.push_back(Monster.release()); } @@ -2591,7 +2591,7 @@ void cWSSAnvil::LoadSheepFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2602,7 +2602,7 @@ void cWSSAnvil::LoadSheepFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ { Monster->SetSheared(a_NBT.GetByte(ShearedIdx) != 0); } - + int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age"); if (AgeableIdx > 0) { @@ -2615,7 +2615,7 @@ void cWSSAnvil::LoadSheepFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ } Monster->SetAge(Age); } - + a_Entities.push_back(Monster.release()); } @@ -2630,7 +2630,7 @@ void cWSSAnvil::LoadSilverfishFromNBT(cEntityList & a_Entities, const cParsedNBT { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2658,7 +2658,7 @@ void cWSSAnvil::LoadSkeletonFromNBT(cEntityList & a_Entities, const cParsedNBT & { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2687,7 +2687,7 @@ void cWSSAnvil::LoadSlimeFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2707,7 +2707,7 @@ void cWSSAnvil::LoadSnowGolemFromNBT(cEntityList & a_Entities, const cParsedNBT { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2727,7 +2727,7 @@ void cWSSAnvil::LoadSpiderFromNBT(cEntityList & a_Entities, const cParsedNBT & a { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2747,7 +2747,7 @@ void cWSSAnvil::LoadSquidFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2775,12 +2775,12 @@ void cWSSAnvil::LoadVillagerFromNBT(cEntityList & a_Entities, const cParsedNBT & { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; } - + int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age"); if (AgeableIdx > 0) { @@ -2793,8 +2793,8 @@ void cWSSAnvil::LoadVillagerFromNBT(cEntityList & a_Entities, const cParsedNBT & } Monster->SetAge(Age); } - - + + a_Entities.push_back(Monster.release()); } @@ -2809,7 +2809,7 @@ void cWSSAnvil::LoadWitchFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2829,7 +2829,7 @@ void cWSSAnvil::LoadWitherFromNBT(cEntityList & a_Entities, const cParsedNBT & a { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2859,7 +2859,7 @@ void cWSSAnvil::LoadWolfFromNBT(cEntityList & a_Entities, const cParsedNBT & a_N { return; } - + LoadWolfOwner(*Monster.get(), a_NBT, a_TagIdx); int SittingIdx = a_NBT.FindChildByName(a_TagIdx, "Sitting"); @@ -2894,7 +2894,7 @@ void cWSSAnvil::LoadWolfFromNBT(cEntityList & a_Entities, const cParsedNBT & a_N } } } - + int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age"); if (AgeableIdx > 0) { @@ -2907,7 +2907,7 @@ void cWSSAnvil::LoadWolfFromNBT(cEntityList & a_Entities, const cParsedNBT & a_N } Monster->SetAge(Age); } - + a_Entities.push_back(Monster.release()); } @@ -2930,12 +2930,12 @@ void cWSSAnvil::LoadZombieFromNBT(cEntityList & a_Entities, const cParsedNBT & a { return; } - + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; } - + int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age"); if (AgeableIdx > 0) { @@ -2948,7 +2948,7 @@ void cWSSAnvil::LoadZombieFromNBT(cEntityList & a_Entities, const cParsedNBT & a } Monster->SetAge(Age); } - + a_Entities.push_back(Monster.release()); } @@ -2968,7 +2968,7 @@ void cWSSAnvil::LoadPigZombieFromNBT(cEntityList & a_Entities, const cParsedNBT { return; } - + int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age"); if (AgeableIdx > 0) { @@ -2981,7 +2981,7 @@ void cWSSAnvil::LoadPigZombieFromNBT(cEntityList & a_Entities, const cParsedNBT } Monster->SetAge(Age); } - + a_Entities.push_back(Monster.release()); } @@ -3008,7 +3008,7 @@ void cWSSAnvil::LoadWolfOwner(cWolf & a_Wolf, const cParsedNBT & a_NBT, int a_Ta // There is no owner, bail out: return; } - + // Convert name to UUID, if needed: if (OwnerUUID.empty()) { @@ -3026,7 +3026,7 @@ void cWSSAnvil::LoadWolfOwner(cWolf & a_Wolf, const cParsedNBT & a_NBT, int a_Ta // Normalize the UUID: OwnerUUID = cMojangAPI::MakeUUIDShort(OwnerUUID); } - + // Convert UUID to name, if needed: if (OwnerName.empty()) { @@ -3038,7 +3038,7 @@ void cWSSAnvil::LoadWolfOwner(cWolf & a_Wolf, const cParsedNBT & a_NBT, int a_Ta return; } } - + a_Wolf.SetOwner(OwnerName, OwnerUUID); a_Wolf.SetIsTame(true); } @@ -3055,7 +3055,7 @@ bool cWSSAnvil::LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_N return false; } a_Entity.SetPosition(Pos[0], Pos[1], Pos[2]); - + double Speed[3]; if (!LoadDoublesListFromNBT(Speed, 3, a_NBT, a_NBT.FindChildByName(a_TagIdx, "Motion"))) { @@ -3065,7 +3065,7 @@ bool cWSSAnvil::LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_N Speed[2] = 0; } a_Entity.SetSpeed(Speed[0], Speed[1], Speed[2]); - + double Rotation[3]; if (!LoadDoublesListFromNBT(Rotation, 2, a_NBT, a_NBT.FindChildByName(a_TagIdx, "Rotation"))) { @@ -3079,7 +3079,7 @@ bool cWSSAnvil::LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_N // Load health: int Health = a_NBT.FindChildByName(a_TagIdx, "Health"); a_Entity.SetHealth(Health > 0 ? a_NBT.GetShort(Health) : a_Entity.GetMaxHealth()); - + return true; } @@ -3133,7 +3133,7 @@ bool cWSSAnvil::LoadProjectileBaseFromNBT(cProjectileEntity & a_Entity, const cP { return false; } - + bool IsInGround = false; int InGroundIdx = a_NBT.FindChildByName(a_TagIdx, "inGround"); if (InGroundIdx > 0) @@ -3141,7 +3141,7 @@ bool cWSSAnvil::LoadProjectileBaseFromNBT(cProjectileEntity & a_Entity, const cP IsInGround = (a_NBT.GetByte(InGroundIdx) != 0); } a_Entity.SetIsInGround(IsInGround); - + return true; } @@ -3230,13 +3230,13 @@ cWSSAnvil::cMCAFile::cMCAFile(cWSSAnvil & a_ParentSchema, const AString & a_File bool cWSSAnvil::cMCAFile::OpenFile(bool a_IsForReading) { bool writeOutNeeded = false; - + if (m_File.IsOpen()) { // Already open return true; } - + if (a_IsForReading) { if (!cFile::Exists(m_FileName)) @@ -3245,13 +3245,13 @@ bool cWSSAnvil::cMCAFile::OpenFile(bool a_IsForReading) return false; } } - + if (!m_File.Open(m_FileName, cFile::fmReadWrite)) { // The file failed to open return false; } - + // Load the header: if (m_File.Read(m_Header, sizeof(m_Header)) != sizeof(m_Header)) { @@ -3269,7 +3269,7 @@ bool cWSSAnvil::cMCAFile::OpenFile(bool a_IsForReading) memset(m_TimeStamps, 0, sizeof(m_TimeStamps)); writeOutNeeded = true; } - + if (writeOutNeeded) { m_File.Seek(0); @@ -3296,7 +3296,7 @@ bool cWSSAnvil::cMCAFile::GetChunkData(const cChunkCoords & a_Chunk, AString & a { return false; } - + int LocalX = a_Chunk.m_ChunkX % 32; if (LocalX < 0) { @@ -3313,9 +3313,9 @@ bool cWSSAnvil::cMCAFile::GetChunkData(const cChunkCoords & a_Chunk, AString & a { return false; } - + m_File.Seek(static_cast(ChunkOffset * 4096)); - + UInt32 ChunkSize = 0; if (m_File.Read(&ChunkSize, 4) != 4) { @@ -3337,7 +3337,7 @@ bool cWSSAnvil::cMCAFile::GetChunkData(const cChunkCoords & a_Chunk, AString & a return false; } ChunkSize--; - + a_Data = m_File.Read(ChunkSize); if (a_Data.size() != ChunkSize) { @@ -3376,7 +3376,7 @@ bool cWSSAnvil::cMCAFile::SetChunkData(const cChunkCoords & a_Chunk, const AStri { LocalZ = 32 + LocalZ; } - + unsigned ChunkSector = FindFreeLocation(LocalX, LocalZ, a_Data); // Store the chunk data: @@ -3398,7 +3398,7 @@ bool cWSSAnvil::cMCAFile::SetChunkData(const cChunkCoords & a_Chunk, const AStri LOGWARNING("Cannot save chunk [%d, %d], writing(3) data to file \"%s\" failed", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, GetFileName().c_str()); return false; } - + // Add padding to 4K boundary: size_t BytesWritten = a_Data.size() + MCA_CHUNK_HEADER_LENGTH; if (BytesWritten % 4096 != 0) @@ -3406,7 +3406,7 @@ bool cWSSAnvil::cMCAFile::SetChunkData(const cChunkCoords & a_Chunk, const AStri static const char Padding[4095] = {0}; m_File.Write(Padding, 4096 - (BytesWritten % 4096)); } - + // Store the header: ChunkSize = (static_cast(a_Data.size()) + MCA_CHUNK_HEADER_LENGTH + 4095) / 4096; // Round data size up to nearest 4KB sector, make it a sector number if (ChunkSize > 255) @@ -3416,7 +3416,7 @@ bool cWSSAnvil::cMCAFile::SetChunkData(const cChunkCoords & a_Chunk, const AStri ); return false; } - + // Store the header info in the table m_Header[LocalX + 32 * LocalZ] = htonl((ChunkSector << 8) | ChunkSize); @@ -3438,7 +3438,7 @@ bool cWSSAnvil::cMCAFile::SetChunkData(const cChunkCoords & a_Chunk, const AStri LOGWARNING("Cannot save chunk [%d, %d], writing timestamps to file \"%s\" failed", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, GetFileName().c_str()); return false; } - + return true; } @@ -3455,7 +3455,7 @@ unsigned cWSSAnvil::cMCAFile::FindFreeLocation(int a_LocalX, int a_LocalZ, const { return ChunkLocation >> 8; } - + // Doesn't fit, append to the end of file (we're wasting a lot of space, TODO: fix this later) unsigned MaxLocation = 2 << 8; // Minimum sector is #2 - after the headers for (size_t i = 0; i < ARRAYCOUNT(m_Header); i++) diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h index 03fa22457..0bd12af57 100755 --- a/src/WorldStorage/WSSAnvil.h +++ b/src/WorldStorage/WSSAnvil.h @@ -31,10 +31,10 @@ enum { /** Maximum number of chunks in an MCA file - also the count of the header items */ MCA_MAX_CHUNKS = 32 * 32, - + /** The MCA header is 8 KiB */ MCA_HEADER_SIZE = MCA_MAX_CHUNKS * 8, - + /** There are 5 bytes of header in front of each chunk */ MCA_CHUNK_HEADER_LENGTH = 5, } ; @@ -47,55 +47,55 @@ class cWSSAnvil : public cWSSchema { typedef cWSSchema super; - + public: cWSSAnvil(cWorld * a_World, int a_CompressionFactor); virtual ~cWSSAnvil(); - + protected: class cMCAFile { public: - + cMCAFile(cWSSAnvil & a_ParentSchema, const AString & a_FileName, int a_RegionX, int a_RegionZ); - + bool GetChunkData (const cChunkCoords & a_Chunk, AString & a_Data); bool SetChunkData (const cChunkCoords & a_Chunk, const AString & a_Data); bool EraseChunkData(const cChunkCoords & a_Chunk); - + int GetRegionX (void) const {return m_RegionX; } int GetRegionZ (void) const {return m_RegionZ; } const AString & GetFileName(void) const {return m_FileName; } - + protected: cWSSAnvil & m_ParentSchema; - + int m_RegionX; int m_RegionZ; cFile m_File; AString m_FileName; - + // The header, copied from the file so we don't have to seek to it all the time // First 1024 entries are chunk locations - the 3 + 1 byte sector-offset and sector-count unsigned m_Header[MCA_MAX_CHUNKS]; - + // Chunk timestamps, following the chunk headers unsigned m_TimeStamps[MCA_MAX_CHUNKS]; - + /** Finds a free location large enough to hold a_Data. Gets a hint of the chunk coords, places the data there if it fits. Returns the sector number. */ unsigned FindFreeLocation(int a_LocalX, int a_LocalZ, const AString & a_Data); - + /** Opens a MCA file either for a Read operation (fails if doesn't exist) or for a Write operation (creates new if not found) */ bool OpenFile(bool a_IsForReading); } ; typedef std::list cMCAFiles; - + cCriticalSection m_CS; cMCAFiles m_Files; // a MRU cache of MCA files - + int m_CompressionFactor; @@ -110,41 +110,41 @@ protected: /** Loads the chunk from the data (no locking needed) */ bool LoadChunkFromData(const cChunkCoords & a_Chunk, const AString & a_Data); - + /** Saves the chunk into datastream (no locking needed) */ bool SaveChunkToData(const cChunkCoords & a_Chunk, AString & a_Data); - + /** Loads the chunk from NBT data (no locking needed). a_RawChunkData is the raw (compressed) chunk data, used for offloading when chunk loading fails. */ bool LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT & a_NBT, const AString & a_RawChunkData); - + /** Saves the chunk into NBT data using a_Writer; returns true on success */ bool SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_Writer); - + /** Loads the chunk's biome map from vanilla-format; returns a_BiomeMap if biomes present and valid, nullptr otherwise */ cChunkDef::BiomeMap * LoadVanillaBiomeMapFromNBT(cChunkDef::BiomeMap * a_BiomeMap, const cParsedNBT & a_NBT, int a_TagIdx); - + /** Loads the chunk's biome map from MCS format; returns a_BiomeMap if biomes present and valid, nullptr otherwise */ cChunkDef::BiomeMap * LoadBiomeMapFromNBT(cChunkDef::BiomeMap * a_BiomeMap, const cParsedNBT & a_NBT, int a_TagIdx); - + /** Loads the chunk's entities from NBT data (a_Tag is the Level\\Entities list tag; may be -1) */ void LoadEntitiesFromNBT(cEntityList & a_Entitites, const cParsedNBT & a_NBT, int a_Tag); - + /** Loads the chunk's BlockEntities from NBT data (a_Tag is the Level\\TileEntities list tag; may be -1) */ void LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntitites, const cParsedNBT & a_NBT, int a_Tag, BLOCKTYPE * a_BlockTypes, NIBBLETYPE * a_BlockMetas); - + /** Loads the data for a block entity from the specified NBT tag. Returns the loaded block entity, or nullptr upon failure. */ cBlockEntity * LoadBlockEntityFromNBT(const cParsedNBT & a_NBT, int a_Tag, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); /** Loads a cItem contents from the specified NBT tag; returns true if successful. Doesn't load the Slot tag */ bool LoadItemFromNBT(cItem & a_Item, const cParsedNBT & a_NBT, int a_TagIdx); - + /** Loads contentents of an Items[] list tag into a cItemGrid ItemGrid begins at the specified slot offset Slots outside the ItemGrid range are ignored */ void LoadItemGridFromNBT(cItemGrid & a_ItemGrid, const cParsedNBT & a_NBT, int a_ItemsTagIdx, int s_SlotOffset = 0); - + /** Returns true iff the "id" child tag inside the specified tag equals the specified expected type. */ bool CheckBlockEntityType(const cParsedNBT & a_NBT, int a_TagIdx, const char * a_ExpectedType); @@ -162,9 +162,9 @@ protected: cBlockEntity * LoadMobHeadFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); cBlockEntity * LoadNoteBlockFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ); cBlockEntity * LoadSignFromNBT (const cParsedNBT & a_NBT, int a_TagIdx, int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_SignBlockType); - + void LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_EntityTagIdx, const char * a_IDTag, size_t a_IDTagLength); - + void LoadBoatFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadEnderCrystalFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadFallingBlockFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); @@ -220,19 +220,19 @@ protected: void LoadWolfFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadZombieFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadPigZombieFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); - + /** Loads the wolf's owner information from the NBT into the specified wolf entity. */ void LoadWolfOwner(cWolf & a_Wolf, const cParsedNBT & a_NBT, int a_TagIdx); - + /** Loads entity common data from the NBT compound; returns true if successful */ bool LoadEntityBaseFromNBT(cEntity & a_Entity, const cParsedNBT & a_NBT, int a_TagIdx); - + /** Loads monster common data from the NBT compound; returns true if successful */ bool LoadMonsterBaseFromNBT(cMonster & a_Monster, const cParsedNBT & a_NBT, int a_TagIdx); - + /** Loads projectile common data from the NBT compound; returns true if successful */ bool LoadProjectileBaseFromNBT(cProjectileEntity & a_Entity, const cParsedNBT & a_NBT, int a_TagIx); - + /** Loads an array of doubles of the specified length from the specified NBT list tag a_TagIdx; returns true if successful */ bool LoadDoublesListFromNBT(double * a_Doubles, int a_NumDoubles, const cParsedNBT & a_NBT, int a_TagIdx); @@ -241,13 +241,13 @@ protected: /** Helper function for extracting the X, Y, and Z int subtags of a NBT compound; returns true if successful */ bool GetBlockEntityNBTPos(const cParsedNBT & a_NBT, int a_TagIdx, int & a_X, int & a_Y, int & a_Z); - + /** Gets the correct MCA file either from cache or from disk, manages the m_MCAFiles cache; assumes m_CS is locked */ cMCAFile * LoadMCAFile(const cChunkCoords & a_Chunk); - + /** Copies a_Length bytes of data from the specified NBT Tag's Child into the a_Destination buffer */ void CopyNBTData(const cParsedNBT & a_NBT, int a_Tag, const AString & a_ChildName, char * a_Destination, size_t a_Length); - + // cWSSchema overrides: virtual bool LoadChunk(const cChunkCoords & a_Chunk) override; virtual bool SaveChunk(const cChunkCoords & a_Chunk) override; diff --git a/src/WorldStorage/WorldStorage.cpp b/src/WorldStorage/WorldStorage.cpp index 3a2385848..55555d731 100644 --- a/src/WorldStorage/WorldStorage.cpp +++ b/src/WorldStorage/WorldStorage.cpp @@ -22,7 +22,7 @@ class cWSSForgetful : { public: cWSSForgetful(cWorld * a_World) : cWSSchema(a_World) {} - + protected: // cWSSchema overrides: virtual bool LoadChunk(const cChunkCoords & a_Chunk) override {return false; } @@ -65,7 +65,7 @@ bool cWorldStorage::Start(cWorld * a_World, const AString & a_StorageSchemaName, m_World = a_World; m_StorageSchemaName = a_StorageSchemaName; InitSchemas(a_StorageCompressionFactor); - + return super::Start(); } @@ -85,14 +85,14 @@ void cWorldStorage::Stop(void) void cWorldStorage::WaitForFinish(void) { LOGD("Waiting for the world storage to finish saving"); - + { m_LoadQueue.Clear(); } - + // Wait for the saving to finish: WaitForSaveQueueEmpty(); - + // Wait for the thread to finish: m_ShouldTerminate = true; m_Event.Set(); // Wake up the thread if waiting @@ -170,7 +170,7 @@ void cWorldStorage::InitSchemas(int a_StorageCompressionFactor) m_Schemas.push_back(new cWSSAnvil (m_World, a_StorageCompressionFactor)); m_Schemas.push_back(new cWSSForgetful(m_World)); // Add new schemas here - + if (NoCaseCompare(m_StorageSchemaName, "default") == 0) { m_SaveSchema = m_Schemas.front(); @@ -184,7 +184,7 @@ void cWorldStorage::InitSchemas(int a_StorageCompressionFactor) return; } } // for itr - m_Schemas[] - + // Unknown schema selected, let the admin know: LOGWARNING("Unknown storage schema name \"%s\". Using default (\"%s\"). Available schemas:", m_StorageSchemaName.c_str(), m_SaveSchema->GetName().c_str() @@ -213,7 +213,7 @@ void cWorldStorage::Execute(void) { return; } - + Success = LoadOneChunk(); Success |= SaveOneChunk(); } while (Success); @@ -258,7 +258,7 @@ bool cWorldStorage::SaveOneChunk(void) { return false; } - + // Save the chunk, if it's valid: bool Status = false; if (m_World->IsChunkValid(ToSave.m_ChunkX, ToSave.m_ChunkZ)) @@ -286,7 +286,7 @@ bool cWorldStorage::SaveOneChunk(void) bool cWorldStorage::LoadChunk(int a_ChunkX, int a_ChunkZ) { ASSERT(m_World->IsChunkQueued(a_ChunkX, a_ChunkZ)); - + cChunkCoords Coords(a_ChunkX, a_ChunkZ); // First try the schema that is used for saving @@ -294,7 +294,7 @@ bool cWorldStorage::LoadChunk(int a_ChunkX, int a_ChunkZ) { return true; } - + // If it didn't have the chunk, try all the other schemas: for (cWSSchemaList::iterator itr = m_Schemas.begin(); itr != m_Schemas.end(); ++itr) { @@ -303,10 +303,10 @@ bool cWorldStorage::LoadChunk(int a_ChunkX, int a_ChunkZ) return true; } } - + // Notify the chunk owner that the chunk failed to load (sets cChunk::m_HasLoadFailed to true): m_World->ChunkLoadFailed(a_ChunkX, a_ChunkZ); - + return false; } diff --git a/src/WorldStorage/WorldStorage.h b/src/WorldStorage/WorldStorage.h index ab8a7f44b..e171aad43 100644 --- a/src/WorldStorage/WorldStorage.h +++ b/src/WorldStorage/WorldStorage.h @@ -37,11 +37,11 @@ class cWSSchema abstract public: cWSSchema(cWorld * a_World) : m_World(a_World) {} virtual ~cWSSchema() {} // Force the descendants' destructors to be virtual - + virtual bool LoadChunk(const cChunkCoords & a_Chunk) = 0; virtual bool SaveChunk(const cChunkCoords & a_Chunk) = 0; virtual const AString GetName(void) const = 0; - + protected: cWorld * m_World; @@ -58,7 +58,7 @@ class cWorldStorage : public cIsThread { typedef cIsThread super; - + public: cWorldStorage(void); @@ -71,16 +71,16 @@ public: /** Queues a chunk to be saved, asynchronously. The callback, if specified, will be called with the result of the save operation. */ void QueueSaveChunk(int a_ChunkX, int a_ChunkZ, cChunkCoordCallback * a_Callback = nullptr); - + bool Start(cWorld * a_World, const AString & a_StorageSchemaName, int a_StorageCompressionFactor); // Hide the cIsThread's Start() method, we need to provide args void Stop(void); // Hide the cIsThread's Stop() method, we need to signal the event void WaitForFinish(void); void WaitForLoadQueueEmpty(void); void WaitForSaveQueueEmpty(void); - + size_t GetLoadQueueLength(void); size_t GetSaveQueueLength(void); - + protected: cWorld * m_World; @@ -88,27 +88,27 @@ protected: cChunkCoordsQueue m_LoadQueue; cChunkCoordsQueue m_SaveQueue; - + /** All the storage schemas (all used for loading) */ cWSSchemaList m_Schemas; - + /** The one storage schema used for saving */ cWSSchema * m_SaveSchema; /** Set when there's any addition to the queues */ cEvent m_Event; - + /** Loads the chunk specified; returns true on success, false on failure */ bool LoadChunk(int a_ChunkX, int a_ChunkZ); void InitSchemas(int a_StorageCompressionFactor); - + virtual void Execute(void) override; - + /** Loads one chunk from the queue (if any queued); returns true if there are more chunks in the load queue */ bool LoadOneChunk(void); - + /** Saves one chunk from the queue (if any queued); returns true if there are more chunks in the save queue */ bool SaveOneChunk(void); } ; diff --git a/src/XMLParser.h b/src/XMLParser.h index bfd3c8c1c..723ea92ed 100644 --- a/src/XMLParser.h +++ b/src/XMLParser.h @@ -22,29 +22,29 @@ class CXMLParser public: CXMLParser(void); virtual ~CXMLParser(); - + // The actual parsing, may be called several times; the last time needs iIsFinal == true (-> flush) int Parse(const char * iData, size_t iLength, bool iIsFinal = false); private: // LibExpat stuff: XML_Parser mParser; - + static void StartElementHandler(void * iContext, const XML_Char * iElement, const XML_Char ** iAttributes) { ((CXMLParser *)iContext)->OnStartElement(iElement, iAttributes); } - + static void EndElementHandler (void * iContext, const XML_Char * iElement) { ((CXMLParser *)iContext)->OnEndElement(iElement); } - + static void CharacterDataHandler (void * iContext, const XML_Char * iData, int iLength) { ((CXMLParser *)iContext)->OnCharacters(iData, iLength); } - + protected: virtual void OnStartElement(const XML_Char * iElement, const XML_Char ** iAttributes) = 0; virtual void OnEndElement (const XML_Char * iElement) = 0; @@ -79,7 +79,7 @@ class CExpatImpl // @access Constructors and destructors public: - + // @cmember General constructor CExpatImpl () @@ -245,7 +245,7 @@ protected: } // @cmember Enable / Disable default handler - + void EnableDefaultHandler (bool fEnable = true, bool fExpand = true) { assert (m_p != nullptr); @@ -258,33 +258,33 @@ protected: XML_SetDefaultHandler (m_p, fEnable ? DefaultHandler : nullptr); } } - + // @cmember Enable / Disable external entity ref handler - + void EnableExternalEntityRefHandler (bool fEnable = true) { assert (m_p != nullptr); XML_SetExternalEntityRefHandler (m_p, fEnable ? ExternalEntityRefHandler : nullptr); } - + // @cmember Enable / Disable unknown encoding handler - + void EnableUnknownEncodingHandler (bool fEnable = true) { assert (m_p != nullptr); XML_SetUnknownEncodingHandler (m_p, fEnable ? UnknownEncodingHandler : nullptr); } - + // @cmember Enable / Disable start namespace handler - + void EnableStartNamespaceDeclHandler (bool fEnable = true) { assert (m_p != nullptr); XML_SetStartNamespaceDeclHandler (m_p, fEnable ? StartNamespaceDeclHandler : nullptr); } - + // @cmember Enable / Disable end namespace handler - + void EnableEndNamespaceDeclHandler (bool fEnable = true) { assert (m_p != nullptr); @@ -298,7 +298,7 @@ protected: EnableStartNamespaceDeclHandler (fEnable); EnableEndNamespaceDeclHandler (fEnable); } - + // @cmember Enable / Disable the XML declaration handler void EnableXmlDeclHandler (bool fEnable = true) @@ -479,43 +479,43 @@ public: } // @cmember Default handler - + void OnDefault (const XML_Char *pszData, int nLength) { return; } - + // @cmember External entity ref handler - + bool OnExternalEntityRef (const XML_Char *pszContext, const XML_Char *pszBase, const XML_Char *pszSystemID, const XML_Char *pszPublicID) { return false; } - + // @cmember Unknown encoding handler - + bool OnUnknownEncoding (const XML_Char *pszName, XML_Encoding *pInfo) { return false; } - + // @cmember Start namespace declaration handler - + void OnStartNamespaceDecl (const XML_Char *pszPrefix, const XML_Char *pszURI) { return; } - + // @cmember End namespace declaration handler - + void OnEndNamespaceDecl (const XML_Char *pszPrefix) { return; } - + // @cmember XML declaration handler void OnXmlDecl (const XML_Char *pszVersion, const XML_Char *pszEncoding, @@ -614,16 +614,16 @@ protected: } // @cmember Default wrapper - + static void __cdecl DefaultHandler (void *pUserData, const XML_Char *pszData, int nLength) { _T *pThis = static_cast <_T *> ((CExpatImpl <_T> *) pUserData); pThis ->OnDefault (pszData, nLength); } - + // @cmember External entity ref wrapper - + static int __cdecl ExternalEntityRefHandler (void *pUserData, const XML_Char *pszContext, const XML_Char *pszBase, const XML_Char *pszSystemID, const XML_Char *pszPublicID) @@ -632,31 +632,31 @@ protected: return pThis ->OnExternalEntityRef (pszContext, pszBase, pszSystemID, pszPublicID) ? 1 : 0; } - + // @cmember Unknown encoding wrapper - + static int __cdecl UnknownEncodingHandler (void * pUserData, const XML_Char * pszName, XML_Encoding * pInfo) { _T *pThis = static_cast <_T *> ((CExpatImpl <_T> *) pUserData); return pThis ->OnUnknownEncoding (pszName, pInfo) ? 1 : 0; } - + // @cmember Start namespace decl wrapper - + static void __cdecl StartNamespaceDeclHandler (void * pUserData, const XML_Char * pszPrefix, const XML_Char * pszURI) { _T *pThis = static_cast <_T *> ((CExpatImpl <_T> *) pUserData); pThis ->OnStartNamespaceDecl (pszPrefix, pszURI); } - + // @cmember End namespace decl wrapper - + static void __cdecl EndNamespaceDeclHandler (void * pUserData, const XML_Char * pszPrefix) { _T *pThis = static_cast <_T *> ((CExpatImpl <_T> *) pUserData); pThis ->OnEndNamespaceDecl (pszPrefix); } - + // @cmember XML declaration wrapper static void __cdecl XmlDeclHandler (void *pUserData, const XML_Char *pszVersion, const XML_Char *pszEncoding, int nStandalone) @@ -684,12 +684,12 @@ protected: _T *pThis = static_cast <_T *> ((CExpatImpl <_T> *) pUserData); pThis ->OnEndDoctypeDecl (); } - - + + protected: XML_Parser m_p; - + /** Returns the value of the specified attribute, if found; nullptr otherwise */ static const XML_Char * FindAttr(const XML_Char ** iAttrs, const XML_Char * iAttrToFind) { diff --git a/src/main.cpp b/src/main.cpp index 1b77e2480..76af90cde 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -341,9 +341,9 @@ static void WINAPI serviceMain(DWORD argc, TCHAR *argv[]) serviceSetState(0, SERVICE_STOPPED, GetLastError()); return; } - + serviceSetState(SERVICE_ACCEPT_STOP, SERVICE_RUNNING, 0); - + DWORD ThreadID; g_ServiceThread = CreateThread(nullptr, 0, serviceWorkerThread, nullptr, 0, &ThreadID); if (g_ServiceThread == nullptr) @@ -353,9 +353,9 @@ static void WINAPI serviceMain(DWORD argc, TCHAR *argv[]) return; } WaitForSingleObject(g_ServiceThread, INFINITE); // Wait here for a stop signal. - + CloseHandle(g_ServiceThread); - + serviceSetState(0, SERVICE_STOPPED, 0); } #endif // Windows service support. @@ -466,11 +466,11 @@ int main(int argc, char ** argv) #if defined(_DEBUG) && defined(_MSC_VER) _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); - + // _X: The simple built-in CRT leak finder - simply break when allocating the Nth block ({N} is listed in the leak output) // Only useful when the leak is in the same sequence all the time // _CrtSetBreakAlloc(85950); - + #endif // _DEBUG && _MSC_VER #ifndef _DEBUG @@ -487,7 +487,7 @@ int main(int argc, char ** argv) #ifdef __unix__ std::signal(SIGPIPE, SIG_IGN); #endif - + #ifdef _WIN32 if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE)) { -- cgit v1.2.3