mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-10-11 18:08:05 +00:00
update last fixes
This commit is contained in:
@@ -2578,10 +2578,6 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream& inStream, Entity* ent
|
|||||||
|
|
||||||
//We need to get a new ID for our model first:
|
//We need to get a new ID for our model first:
|
||||||
if (!entity || !entity->GetCharacter() || !entity->GetCharacter()->GetParentUser()) return;
|
if (!entity || !entity->GetCharacter() || !entity->GetCharacter()->GetParentUser()) return;
|
||||||
const uint32_t maxRetries = 100;
|
|
||||||
uint32_t retries = 0;
|
|
||||||
bool blueprintIDExists = true;
|
|
||||||
bool modelExists = true;
|
|
||||||
|
|
||||||
//We need to get the propertyID: (stolen from Wincent's propertyManagementComp)
|
//We need to get the propertyID: (stolen from Wincent's propertyManagementComp)
|
||||||
const auto& worldId = Game::zoneManager->GetZone()->GetZoneID();
|
const auto& worldId = Game::zoneManager->GetZone()->GetZoneID();
|
||||||
@@ -2598,9 +2594,10 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream& inStream, Entity* ent
|
|||||||
std::istringstream sd0DataStream(str);
|
std::istringstream sd0DataStream(str);
|
||||||
Sd0 sd0(sd0DataStream);
|
Sd0 sd0(sd0DataStream);
|
||||||
|
|
||||||
// Uncompress the data and normalize the position
|
// Uncompress the data, split, and nornmalize the model
|
||||||
const auto asStr = sd0.GetAsStringUncompressed();
|
const auto asStr = sd0.GetAsStringUncompressed();
|
||||||
auto splitLxfmls = Lxfml::Split(asStr);
|
auto splitLxfmls = Lxfml::Split(asStr);
|
||||||
|
LOG_DEBUG("Split into %zu models", splitLxfmls.size());
|
||||||
|
|
||||||
CBITSTREAM;
|
CBITSTREAM;
|
||||||
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::BLUEPRINT_SAVE_RESPONSE);
|
BitStreamUtils::WriteHeader(bitStream, ServiceType::CLIENT, MessageType::Client::BLUEPRINT_SAVE_RESPONSE);
|
||||||
@@ -2609,38 +2606,77 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream& inStream, Entity* ent
|
|||||||
bitStream.Write<uint32_t>(splitLxfmls.size());
|
bitStream.Write<uint32_t>(splitLxfmls.size());
|
||||||
|
|
||||||
std::vector<LWOOBJID> blueprintIDs;
|
std::vector<LWOOBJID> blueprintIDs;
|
||||||
|
std::vector<LWOOBJID> modelIDs;
|
||||||
|
|
||||||
for (size_t i = 0; i < splitLxfmls.size(); ++i) {
|
for (size_t i = 0; i < splitLxfmls.size(); ++i) {
|
||||||
// Legacy logic to check for old random IDs (regenerating these is not really feasible)
|
// Legacy logic to check for old random IDs (regenerating these is not really feasible)
|
||||||
// Probably good to have this anyway in case someone messes with the last_object_id or it gets reset somehow
|
// Probably good to have this anyway in case someone messes with the last_object_id or it gets reset somehow
|
||||||
LWOOBJID newIDL = LWOOBJID_EMPTY;
|
const uint32_t maxRetries = 100;
|
||||||
|
uint32_t retries = 0;
|
||||||
|
bool blueprintIDExists = true;
|
||||||
|
bool modelExists = true;
|
||||||
|
|
||||||
|
LWOOBJID newID = LWOOBJID_EMPTY;
|
||||||
LWOOBJID blueprintID = LWOOBJID_EMPTY;
|
LWOOBJID blueprintID = LWOOBJID_EMPTY;
|
||||||
do {
|
do {
|
||||||
if (newIDL != LWOOBJID_EMPTY) LOG("Generating blueprintID for UGC model, collision with existing model ID: %llu", blueprintID);
|
if (newID != LWOOBJID_EMPTY) LOG("Generating blueprintID for UGC model, collision with existing model ID: %llu", blueprintID);
|
||||||
newIDL = ObjectIDManager::GetPersistentID();
|
newID = ObjectIDManager::GetPersistentID();
|
||||||
blueprintID = ObjectIDManager::GetPersistentID();
|
blueprintID = ObjectIDManager::GetPersistentID();
|
||||||
++retries;
|
++retries;
|
||||||
blueprintIDExists = Database::Get()->GetUgcModel(blueprintID).has_value();
|
blueprintIDExists = Database::Get()->GetUgcModel(blueprintID).has_value();
|
||||||
modelExists = Database::Get()->GetModel(newIDL).has_value();
|
modelExists = Database::Get()->GetModel(newID).has_value();
|
||||||
} while ((blueprintIDExists || modelExists) && retries < maxRetries);
|
} while ((blueprintIDExists || modelExists) && retries < maxRetries);
|
||||||
|
|
||||||
blueprintIDs.push_back(blueprintID);
|
blueprintIDs.push_back(blueprintID);
|
||||||
|
modelIDs.push_back(newID);
|
||||||
|
|
||||||
// Save each part to the database
|
// Save each model to the database
|
||||||
sd0.FromData(reinterpret_cast<const uint8_t*>(splitLxfmls[i].lxfml.data()), splitLxfmls[i].lxfml.size());
|
sd0.FromData(reinterpret_cast<const uint8_t*>(splitLxfmls[i].lxfml.data()), splitLxfmls[i].lxfml.size());
|
||||||
auto sd0AsStream = sd0.GetAsStream();
|
auto sd0AsStream = sd0.GetAsStream();
|
||||||
Database::Get()->InsertNewUgcModel(sd0AsStream, blueprintID, entity->GetCharacter()->GetParentUser()->GetAccountID(), entity->GetCharacter()->GetID());
|
Database::Get()->InsertNewUgcModel(sd0AsStream, blueprintID, entity->GetCharacter()->GetParentUser()->GetAccountID(), entity->GetCharacter()->GetID());
|
||||||
|
|
||||||
|
// Insert the new property model
|
||||||
|
IPropertyContents::Model model;
|
||||||
|
model.id = newID;
|
||||||
|
model.ugcId = blueprintID;
|
||||||
|
model.position = splitLxfmls[i].center;
|
||||||
|
model.rotation = NiQuaternion(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
model.lot = 14;
|
||||||
|
Database::Get()->InsertNewPropertyModel(propertyId, model, "Objects_14_name");
|
||||||
|
|
||||||
|
/*
|
||||||
|
Commented out until UGC server would be updated to use a sd0 file instead of lxfml stream.
|
||||||
|
(or you uncomment the lxfml decomp stuff above)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Send off to UGC for processing, if enabled:
|
||||||
|
// if (Game::config->GetValue("ugc_remote") == "1") {
|
||||||
|
// std::string ugcIP = Game::config->GetValue("ugc_ip");
|
||||||
|
// int ugcPort = std::stoi(Game::config->GetValue("ugc_port"));
|
||||||
|
|
||||||
|
// httplib::Client cli(ugcIP, ugcPort); //connect to UGC HTTP server using our config above ^
|
||||||
|
|
||||||
|
// //Send out a request:
|
||||||
|
// std::string request = "/3dservices/UGCC150/150" + std::to_string(blueprintID) + ".lxfml";
|
||||||
|
// cli.Put(request.c_str(), lxfml.c_str(), "text/lxfml");
|
||||||
|
|
||||||
|
// //When the "put" above returns, it means that the UGC HTTP server is done processing our model &
|
||||||
|
// //the nif, hkx and checksum files are ready to be downloaded from cache.
|
||||||
|
// }
|
||||||
|
|
||||||
// Write the ID and data to the response packet
|
// Write the ID and data to the response packet
|
||||||
bitStream.Write(blueprintID);
|
bitStream.Write(blueprintID);
|
||||||
uint32_t partSize = static_cast<uint32_t>(splitLxfmls[i].lxfml.size());
|
|
||||||
bitStream.Write(partSize);
|
const auto& newSd0 = sd0.GetAsVector();
|
||||||
bitStream.WriteAlignedBytes(reinterpret_cast<const unsigned char*>(splitLxfmls[i].lxfml.data()), partSize);
|
uint32_t newSd0Size{};
|
||||||
|
for (const auto& chunk : newSd0) newSd0Size += chunk.size();
|
||||||
|
bitStream.Write(newSd0Size);
|
||||||
|
for (const auto& chunk : newSd0) bitStream.WriteAlignedBytes(reinterpret_cast<const unsigned char*>(chunk.data()), chunk.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
SEND_PACKET;
|
SEND_PACKET;
|
||||||
|
|
||||||
// Create entities for each part
|
// Create entities for each model
|
||||||
for (size_t i = 0; i < splitLxfmls.size(); ++i) {
|
for (size_t i = 0; i < splitLxfmls.size(); ++i) {
|
||||||
EntityInfo info;
|
EntityInfo info;
|
||||||
info.lot = 14;
|
info.lot = 14;
|
||||||
@@ -2654,12 +2690,15 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream& inStream, Entity* ent
|
|||||||
info.settings.push_back(new LDFData<int>(u"componentWhitelist", 1));
|
info.settings.push_back(new LDFData<int>(u"componentWhitelist", 1));
|
||||||
info.settings.push_back(new LDFData<int>(u"modelType", 2));
|
info.settings.push_back(new LDFData<int>(u"modelType", 2));
|
||||||
info.settings.push_back(new LDFData<bool>(u"propertyObjectID", true));
|
info.settings.push_back(new LDFData<bool>(u"propertyObjectID", true));
|
||||||
info.settings.push_back(new LDFData<LWOOBJID>(u"userModelID", blueprintIDs[i]));
|
info.settings.push_back(new LDFData<LWOOBJID>(u"userModelID", modelIDs[i]));
|
||||||
|
|
||||||
Entity* newEntity = Game::entityManager->CreateEntity(info, nullptr);
|
Entity* newEntity = Game::entityManager->CreateEntity(info, nullptr);
|
||||||
if (newEntity) {
|
if (newEntity) {
|
||||||
Game::entityManager->ConstructEntity(newEntity);
|
Game::entityManager->ConstructEntity(newEntity);
|
||||||
PropertyManagementComponent::Instance()->AddModel(newEntity->GetObjectID(), blueprintIDs[i]);
|
|
||||||
|
//Make sure the propMgmt doesn't delete our model after the server dies
|
||||||
|
//Trying to do this after the entity is constructed. Shouldn't really change anything but
|
||||||
|
//there was an issue with builds not appearing since it was placed above ConstructEntity.
|
||||||
|
PropertyManagementComponent::Instance()->AddModel(newEntity->GetObjectID(), modelIDs[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user