mirror of
				https://github.com/DarkflameUniverse/DarkflameServer.git
				synced 2025-10-31 04:32:06 +00:00 
			
		
		
		
	Normalize model positions when placing in the world
Have tested that placing a small and very large model both place and are located at the correct position.
This commit is contained in:
		| @@ -8,6 +8,7 @@ | ||||
|  | ||||
| #include "Database.h" | ||||
| #include "Game.h" | ||||
| #include "Sd0.h" | ||||
| #include "ZCompression.h" | ||||
| #include "Logger.h" | ||||
|  | ||||
| @@ -44,10 +45,10 @@ uint32_t BrickByBrickFix::TruncateBrokenBrickByBrickXml() { | ||||
| 				} | ||||
|  | ||||
| 				// Ignore the valgrind warning about uninitialized values.  These are discarded later when we know the actual uncompressed size. | ||||
| 				std::unique_ptr<uint8_t[]> uncompressedChunk(new uint8_t[ZCompression::MAX_SD0_CHUNK_SIZE]); | ||||
| 				std::unique_ptr<uint8_t[]> uncompressedChunk(new uint8_t[Sd0::MAX_UNCOMPRESSED_CHUNK_SIZE]); | ||||
| 				int32_t err{}; | ||||
| 				int32_t actualUncompressedSize = ZCompression::Decompress( | ||||
| 					compressedChunk.get(), chunkSize, uncompressedChunk.get(), ZCompression::MAX_SD0_CHUNK_SIZE, err); | ||||
| 					compressedChunk.get(), chunkSize, uncompressedChunk.get(), Sd0::MAX_UNCOMPRESSED_CHUNK_SIZE, err); | ||||
|  | ||||
| 				if (actualUncompressedSize != -1) { | ||||
| 					uint32_t previousSize = completeUncompressedModel.size(); | ||||
|   | ||||
| @@ -29,8 +29,8 @@ constexpr const char* GetFileNameFromAbsolutePath(const char* path) { | ||||
| // they will not be valid constexpr and will be evaluated at runtime instead of compile time! | ||||
| // The full string is still stored in the binary, however the offset of the filename in the absolute paths | ||||
| // is used in the instruction instead of the start of the absolute path. | ||||
| #define LOG(message, ...) do { auto str = FILENAME_AND_LINE; Game::logger->Log(str, message, ##__VA_ARGS__); } while(0) | ||||
| #define LOG_DEBUG(message, ...) do { auto str = FILENAME_AND_LINE; Game::logger->LogDebug(str, message, ##__VA_ARGS__); } while(0) | ||||
| #define LOG(message, ...) do { auto str_ = FILENAME_AND_LINE; Game::logger->Log(str_, message, ##__VA_ARGS__); } while(0) | ||||
| #define LOG_DEBUG(message, ...) do { auto str_ = FILENAME_AND_LINE; Game::logger->LogDebug(str_, message, ##__VA_ARGS__); } while(0) | ||||
|  | ||||
| // Writer class for writing data to files. | ||||
| class Writer { | ||||
|   | ||||
| @@ -8,11 +8,5 @@ namespace ZCompression { | ||||
| 	int32_t Compress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst); | ||||
|  | ||||
| 	int32_t Decompress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst, int32_t& nErr); | ||||
|  | ||||
| 	/** | ||||
| 	 * @brief Max size of an inflated sd0 zlib chunk | ||||
| 	 * | ||||
| 	 */ | ||||
| 	constexpr uint32_t MAX_SD0_CHUNK_SIZE = 1024 * 256; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| #include "Pack.h" | ||||
|  | ||||
| #include "BinaryIO.h" | ||||
| #include "Sd0.h" | ||||
| #include "ZCompression.h" | ||||
|  | ||||
| Pack::Pack(const std::filesystem::path& filePath) { | ||||
| @@ -106,7 +107,7 @@ bool Pack::ReadFileFromPack(const uint32_t crc, char** data, uint32_t* len) cons | ||||
| 		pos += size; // Move pointer position the amount of bytes read to the right | ||||
|  | ||||
| 		int32_t err; | ||||
| 		currentReadPos += ZCompression::Decompress(reinterpret_cast<uint8_t*>(chunk), size, reinterpret_cast<uint8_t*>(decompressedData + currentReadPos), ZCompression::MAX_SD0_CHUNK_SIZE, err); | ||||
| 		currentReadPos += ZCompression::Decompress(reinterpret_cast<uint8_t*>(chunk), size, reinterpret_cast<uint8_t*>(decompressedData + currentReadPos), Sd0::MAX_UNCOMPRESSED_CHUNK_SIZE, err); | ||||
|  | ||||
| 		free(chunk); | ||||
| 	} | ||||
|   | ||||
| @@ -22,7 +22,7 @@ public: | ||||
|  | ||||
| 	// Inserts a new UGC model into the database. | ||||
| 	virtual void InsertNewUgcModel( | ||||
| 		std::istringstream& sd0Data, | ||||
| 		std::stringstream& sd0Data, | ||||
| 		const uint32_t blueprintId, | ||||
| 		const uint32_t accountId, | ||||
| 		const uint32_t characterId) = 0; | ||||
|   | ||||
| @@ -81,7 +81,7 @@ public: | ||||
| 	void InsertCheatDetection(const IPlayerCheatDetections::Info& info) override; | ||||
| 	void InsertNewMail(const MailInfo& mail) override; | ||||
| 	void InsertNewUgcModel( | ||||
| 		std::istringstream& sd0Data, | ||||
| 		std::stringstream& sd0Data, | ||||
| 		const uint32_t blueprintId, | ||||
| 		const uint32_t accountId, | ||||
| 		const uint32_t characterId) override; | ||||
|   | ||||
| @@ -43,7 +43,7 @@ void MySQLDatabase::RemoveUnreferencedUgcModels() { | ||||
| } | ||||
|  | ||||
| void MySQLDatabase::InsertNewUgcModel( | ||||
| 	std::istringstream& sd0Data, // cant be const sad | ||||
| 	std:: stringstream& sd0Data, // cant be const sad | ||||
| 	const uint32_t blueprintId, | ||||
| 	const uint32_t accountId, | ||||
| 	const uint32_t characterId) { | ||||
|   | ||||
| @@ -79,7 +79,7 @@ public: | ||||
| 	void InsertCheatDetection(const IPlayerCheatDetections::Info& info) override; | ||||
| 	void InsertNewMail(const MailInfo& mail) override; | ||||
| 	void InsertNewUgcModel( | ||||
| 		std::istringstream& sd0Data, | ||||
| 		std::stringstream& sd0Data, | ||||
| 		const uint32_t blueprintId, | ||||
| 		const uint32_t accountId, | ||||
| 		const uint32_t characterId) override; | ||||
|   | ||||
| @@ -44,7 +44,7 @@ void SQLiteDatabase::RemoveUnreferencedUgcModels() { | ||||
| } | ||||
|  | ||||
| void SQLiteDatabase::InsertNewUgcModel( | ||||
| 	std::istringstream& sd0Data, // cant be const sad | ||||
| 	std::stringstream& sd0Data, // cant be const sad | ||||
| 	const uint32_t blueprintId, | ||||
| 	const uint32_t accountId, | ||||
| 	const uint32_t characterId) { | ||||
|   | ||||
| @@ -188,7 +188,7 @@ void TestSQLDatabase::InsertNewMail(const MailInfo& mail) { | ||||
|  | ||||
| } | ||||
|  | ||||
| void TestSQLDatabase::InsertNewUgcModel(std::istringstream& sd0Data, const uint32_t blueprintId, const uint32_t accountId, const uint32_t characterId) { | ||||
| void TestSQLDatabase::InsertNewUgcModel(std::stringstream& sd0Data, const uint32_t blueprintId, const uint32_t accountId, const uint32_t characterId) { | ||||
|  | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -58,7 +58,7 @@ class TestSQLDatabase : public GameDatabase { | ||||
| 	void InsertCheatDetection(const IPlayerCheatDetections::Info& info) override; | ||||
| 	void InsertNewMail(const MailInfo& mail) override; | ||||
| 	void InsertNewUgcModel( | ||||
| 		std::istringstream& sd0Data, | ||||
| 		std::stringstream& sd0Data, | ||||
| 		const uint32_t blueprintId, | ||||
| 		const uint32_t accountId, | ||||
| 		const uint32_t characterId) override; | ||||
|   | ||||
| @@ -99,7 +99,7 @@ Entity* EntityManager::CreateEntity(EntityInfo info, User* user, Entity* parentE | ||||
| 		} | ||||
|  | ||||
| 		// Exclude the zone control object from any flags | ||||
| 		if (!controller && info.lot != 14) { | ||||
| 		if (!controller) { | ||||
|  | ||||
| 			// The client flags means the client should render the entity | ||||
| 			GeneralUtils::SetBit(id, eObjectBits::CLIENT); | ||||
|   | ||||
| @@ -102,6 +102,8 @@ | ||||
| #include "CDComponentsRegistryTable.h" | ||||
| #include "CDObjectsTable.h" | ||||
| #include "eItemType.h" | ||||
| #include "Lxfml.h" | ||||
| #include "Sd0.h" | ||||
|  | ||||
| void GameMessages::SendFireEventClientSide(const LWOOBJID& objectID, const SystemAddress& sysAddr, std::u16string args, const LWOOBJID& object, int64_t param1, int param2, const LWOOBJID& sender) { | ||||
| 	CBITSTREAM; | ||||
| @@ -2613,16 +2615,26 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream& inStream, Entity* ent | ||||
| 		LWOOBJID propertyId = LWOOBJID_EMPTY; | ||||
| 		if (propertyInfo) propertyId = propertyInfo->id; | ||||
|  | ||||
| 		//Insert into ugc: | ||||
| 		// Save the binary data to the Sd0 buffer | ||||
| 		std::string str(sd0Data.get(), sd0Size); | ||||
| 		std::istringstream sd0DataStream(str); | ||||
| 		Database::Get()->InsertNewUgcModel(sd0DataStream, blueprintIDSmall, entity->GetCharacter()->GetParentUser()->GetAccountID(), entity->GetCharacter()->GetID()); | ||||
| 		Sd0 sd0(sd0DataStream); | ||||
|  | ||||
| 		// Uncompress the data and normalize the position | ||||
| 		const auto asStr = sd0.GetAsStringUncompressed(); | ||||
| 		const auto [newLxfml, newCenter] = Lxfml::NormalizePosition(asStr); | ||||
| 		auto [x, y, z] = newCenter; | ||||
|  | ||||
| 		// Recompress the data and save to the database | ||||
| 		sd0.FromData(reinterpret_cast<const uint8_t*>(newLxfml.data()), newLxfml.size()); | ||||
| 		auto sd0AsStream = sd0.GetAsStream(); | ||||
| 		Database::Get()->InsertNewUgcModel(sd0AsStream, blueprintIDSmall, entity->GetCharacter()->GetParentUser()->GetAccountID(), entity->GetCharacter()->GetID()); | ||||
|  | ||||
| 		//Insert into the db as a BBB model: | ||||
| 		IPropertyContents::Model model; | ||||
| 		model.id = newIDL; | ||||
| 		model.ugcId = blueprintIDSmall; | ||||
| 		model.position = NiPoint3Constant::ZERO; | ||||
| 		model.position = newCenter; | ||||
| 		model.rotation = NiQuaternion(0.0f, 0.0f, 0.0f, 0.0f); | ||||
| 		model.lot = 14; | ||||
| 		Database::Get()->InsertNewPropertyModel(propertyId, model, "Objects_14_name"); | ||||
| @@ -2648,6 +2660,9 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream& inStream, Entity* ent | ||||
| 		//} | ||||
|  | ||||
| 		//Tell the client their model is saved: (this causes us to actually pop out of our current state): | ||||
| 		const auto& newSd0 = sd0.GetAsVector(); | ||||
| 		uint32_t sd0Size{}; | ||||
| 		for (const auto& chunk : newSd0) sd0Size += chunk.size(); | ||||
| 		CBITSTREAM; | ||||
| 		BitStreamUtils::WriteHeader(bitStream, eConnectionType::CLIENT, MessageType::Client::BLUEPRINT_SAVE_RESPONSE); | ||||
| 		bitStream.Write(localId); | ||||
| @@ -2655,9 +2670,9 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream& inStream, Entity* ent | ||||
| 		bitStream.Write<uint32_t>(1); | ||||
| 		bitStream.Write(blueprintID); | ||||
|  | ||||
| 		bitStream.Write<uint32_t>(sd0Size); | ||||
| 		bitStream.Write(sd0Size); | ||||
|  | ||||
| 		bitStream.WriteAlignedBytes(reinterpret_cast<unsigned char*>(sd0Data.get()), sd0Size); | ||||
| 		for (const auto& chunk : newSd0) bitStream.WriteAlignedBytes(reinterpret_cast<const unsigned char*>(chunk.data()), chunk.size()); | ||||
|  | ||||
| 		SEND_PACKET; | ||||
|  | ||||
| @@ -2665,7 +2680,7 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream& inStream, Entity* ent | ||||
|  | ||||
| 		EntityInfo info; | ||||
| 		info.lot = 14; | ||||
| 		info.pos = {}; | ||||
| 		info.pos = newCenter; | ||||
| 		info.rot = {}; | ||||
| 		info.spawner = nullptr; | ||||
| 		info.spawnerID = entity->GetObjectID(); | ||||
|   | ||||
| @@ -1417,7 +1417,6 @@ void WorldShutdownProcess(uint32_t zoneId) { | ||||
| 	if (PropertyManagementComponent::Instance() != nullptr) { | ||||
| 		LOG("Saving ALL property data for zone %i clone %i!", zoneId, PropertyManagementComponent::Instance()->GetCloneId()); | ||||
| 		PropertyManagementComponent::Instance()->Save(); | ||||
| 		Database::Get()->RemoveUnreferencedUgcModels(); | ||||
| 		LOG("ALL property data saved for zone %i clone %i!", zoneId, PropertyManagementComponent::Instance()->GetCloneId()); | ||||
| 	} | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 David Markowitz
					David Markowitz