mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 07:37:20 +02:00
restore non-human-readable avatarEntityDataSettings format
This commit is contained in:
parent
dedc14434b
commit
43fc86fe54
2 changed files with 78 additions and 27 deletions
|
@ -50,6 +50,7 @@
|
||||||
#include <RecordingScriptingInterface.h>
|
#include <RecordingScriptingInterface.h>
|
||||||
#include <trackers/FaceTracker.h>
|
#include <trackers/FaceTracker.h>
|
||||||
#include <RenderableModelEntityItem.h>
|
#include <RenderableModelEntityItem.h>
|
||||||
|
#include <VariantMapToScriptValue.h>
|
||||||
|
|
||||||
#include "MyHead.h"
|
#include "MyHead.h"
|
||||||
#include "MySkeletonModel.h"
|
#include "MySkeletonModel.h"
|
||||||
|
@ -1263,11 +1264,11 @@ void MyAvatar::resizeAvatarEntitySettingHandles(uint32_t maxIndex) {
|
||||||
// Create Setting::Handles to mimic this.
|
// Create Setting::Handles to mimic this.
|
||||||
uint32_t settingsIndex = (uint32_t)_avatarEntityIDSettings.size() + 1;
|
uint32_t settingsIndex = (uint32_t)_avatarEntityIDSettings.size() + 1;
|
||||||
while (settingsIndex <= maxIndex) {
|
while (settingsIndex <= maxIndex) {
|
||||||
Setting::Handle<QString> idHandle(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "avatarEntityData"
|
Setting::Handle<QUuid> idHandle(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "avatarEntityData"
|
||||||
<< QString::number(settingsIndex) << "id", QUuid().toString());
|
<< QString::number(settingsIndex) << "id", QUuid());
|
||||||
_avatarEntityIDSettings.push_back(idHandle);
|
_avatarEntityIDSettings.push_back(idHandle);
|
||||||
Setting::Handle<QString> dataHandle(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "avatarEntityData"
|
Setting::Handle<QByteArray> dataHandle(QStringList() << AVATAR_SETTINGS_GROUP_NAME << "avatarEntityData"
|
||||||
<< QString::number(settingsIndex) << "properties", QString());
|
<< QString::number(settingsIndex) << "properties", QByteArray());
|
||||||
_avatarEntityDataSettings.push_back(dataHandle);
|
_avatarEntityDataSettings.push_back(dataHandle);
|
||||||
settingsIndex++;
|
settingsIndex++;
|
||||||
}
|
}
|
||||||
|
@ -1320,22 +1321,22 @@ void MyAvatar::saveAvatarEntityDataToSettings() {
|
||||||
for (const auto& id : _entitiesToRemoveFromSettings) {
|
for (const auto& id : _entitiesToRemoveFromSettings) {
|
||||||
// remove
|
// remove
|
||||||
entitiesToSave.erase(id);
|
entitiesToSave.erase(id);
|
||||||
std::map<QUuid, QString>::iterator itr = _avatarEntityStrings.find(id);
|
std::map<QUuid, QByteArray>::iterator itr = _poorlyFormattedAvatarEntityData.find(id);
|
||||||
if (itr != _avatarEntityStrings.end()) {
|
if (itr != _poorlyFormattedAvatarEntityData.end()) {
|
||||||
_avatarEntityStrings.erase(itr);
|
_poorlyFormattedAvatarEntityData.erase(itr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const auto& id : entitiesToSave) {
|
for (const auto& id : entitiesToSave) {
|
||||||
// remove old strings to be replaced by new saves
|
// remove old strings to be replaced by new saves
|
||||||
std::map<QUuid, QString>::iterator itr = _avatarEntityStrings.find(id);
|
std::map<QUuid, QByteArray>::iterator itr = _poorlyFormattedAvatarEntityData.find(id);
|
||||||
if (itr != _avatarEntityStrings.end()) {
|
if (itr != _poorlyFormattedAvatarEntityData.end()) {
|
||||||
_avatarEntityStrings.erase(itr);
|
_poorlyFormattedAvatarEntityData.erase(itr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_entitiesToRemoveFromSettings.clear();
|
_entitiesToRemoveFromSettings.clear();
|
||||||
});
|
});
|
||||||
|
|
||||||
uint32_t numEntities = (uint32_t)(entitiesToSave.size() + _avatarEntityStrings.size());
|
uint32_t numEntities = (uint32_t)(entitiesToSave.size() + _poorlyFormattedAvatarEntityData.size());
|
||||||
uint32_t prevNumEntities = _avatarEntityCountSetting.get(0);
|
uint32_t prevNumEntities = _avatarEntityCountSetting.get(0);
|
||||||
resizeAvatarEntitySettingHandles(std::max<uint32_t>(numEntities, prevNumEntities));
|
resizeAvatarEntitySettingHandles(std::max<uint32_t>(numEntities, prevNumEntities));
|
||||||
|
|
||||||
|
@ -1356,14 +1357,27 @@ void MyAvatar::saveAvatarEntityDataToSettings() {
|
||||||
QScriptEngine scriptEngine;
|
QScriptEngine scriptEngine;
|
||||||
QScriptValue toStringMethod = scriptEngine.evaluate("(function() { return JSON.stringify(this) })");
|
QScriptValue toStringMethod = scriptEngine.evaluate("(function() { return JSON.stringify(this) })");
|
||||||
for (const auto& entry : allProperties) {
|
for (const auto& entry : allProperties) {
|
||||||
QScriptValue scriptValue = EntityItemPropertiesToScriptValue(&scriptEngine, entry.second);
|
// begin recipe our unfortunate legacy avatarEntityData format
|
||||||
scriptValue.setProperty("toString", toStringMethod);
|
QScriptValue scriptValue = EntityItemNonDefaultPropertiesToScriptValue(&scriptEngine, entry.second);
|
||||||
_avatarEntityStrings[entry.first] = scriptValue.toString();
|
QVariant variantProperties = scriptValue.toVariant();
|
||||||
|
QJsonDocument jsonProperties = QJsonDocument::fromVariant(variantProperties);
|
||||||
|
// the ID of the parent/avatar changes from session to session. use a special UUID to indicate the avatar
|
||||||
|
QJsonObject jsonObject = jsonProperties.object();
|
||||||
|
if (jsonObject.contains("parentID")) {
|
||||||
|
if (QUuid(jsonObject["parentID"].toString()) == getID()) {
|
||||||
|
jsonObject["parentID"] = AVATAR_SELF_ID.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jsonProperties = QJsonDocument(jsonObject);
|
||||||
|
QByteArray binaryProperties = jsonProperties.toBinaryData();
|
||||||
|
// end recipe
|
||||||
|
|
||||||
|
_poorlyFormattedAvatarEntityData[entry.first] = binaryProperties;
|
||||||
}
|
}
|
||||||
// save all strings
|
// save all strings
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
for (const auto& entry : _avatarEntityStrings) {
|
for (const auto& entry : _poorlyFormattedAvatarEntityData) {
|
||||||
_avatarEntityIDSettings[i].set(entry.first.toString());
|
_avatarEntityIDSettings[i].set(entry.first);
|
||||||
_avatarEntityDataSettings[i].set(entry.second);
|
_avatarEntityDataSettings[i].set(entry.second);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
@ -1567,18 +1581,53 @@ void MyAvatar::loadAvatarEntityDataFromSettings() {
|
||||||
|
|
||||||
QScriptEngine scriptEngine;
|
QScriptEngine scriptEngine;
|
||||||
std::vector<EntityItemProperties> entitiesToLoad;
|
std::vector<EntityItemProperties> entitiesToLoad;
|
||||||
entitiesToLoad.resize(numEntities);
|
|
||||||
resizeAvatarEntitySettingHandles(numEntities);
|
resizeAvatarEntitySettingHandles(numEntities);
|
||||||
for (int i = 0; i < numEntities; i++) {
|
for (int i = 0; i < numEntities; i++) {
|
||||||
// DANGER: this JSONString --> EntityItemProperties operation is expensive
|
QUuid entityID = QUuid::createUuid(); // generate a new ID
|
||||||
EntityItemProperties& properties = entitiesToLoad[i];
|
QByteArray binaryData = _avatarEntityDataSettings[i].get();
|
||||||
properties.copyFromJSONString(scriptEngine, _avatarEntityDataSettings[i].get());
|
//updateAvatarEntity(entityID, binaryData);
|
||||||
// the ClientOnly property can get stripped out elsewhere so we need to always set it true here
|
|
||||||
|
|
||||||
|
_avatarEntityDataChanged = true;
|
||||||
|
if (_clientTraitsHandler) {
|
||||||
|
// we have a client traits handler, so we need to mark this instanced trait as changed
|
||||||
|
// so that changes will be sent next frame
|
||||||
|
_clientTraitsHandler->markInstancedTraitUpdated(AvatarTraits::AvatarEntity, entityID);
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonDocument jsonProperties = QJsonDocument::fromBinaryData(binaryData);
|
||||||
|
if (!jsonProperties.isObject()) {
|
||||||
|
qCDebug(interfaceapp) << "bad avatarEntityData json" << QString(binaryData.toHex());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant variantProperties = jsonProperties.toVariant();
|
||||||
|
QVariantMap asMap = variantProperties.toMap();
|
||||||
|
QScriptValue scriptProperties = variantMapToScriptValue(asMap, scriptEngine);
|
||||||
|
EntityItemProperties properties;
|
||||||
|
EntityItemPropertiesFromScriptValueHonorReadOnly(scriptProperties, properties);
|
||||||
properties.setEntityHostType(entity::HostType::AVATAR);
|
properties.setEntityHostType(entity::HostType::AVATAR);
|
||||||
properties.setOwningAvatarID(getID());
|
properties.setOwningAvatarID(getID());
|
||||||
|
|
||||||
|
// there's no entity-server to tell us we're the simulation owner, so always set the
|
||||||
|
// simulationOwner to the owningAvatarID and a high priority.
|
||||||
|
properties.setSimulationOwner(getID(), AVATAR_ENTITY_SIMULATION_PRIORITY);
|
||||||
|
|
||||||
|
if (properties.getParentID() == AVATAR_SELF_ID) {
|
||||||
|
properties.setParentID(getID());
|
||||||
|
}
|
||||||
|
|
||||||
|
// When grabbing avatar entities, they are parented to the joint moving them, then when un-grabbed
|
||||||
|
// they go back to the default parent (null uuid). When un-gripped, others saw the entity disappear.
|
||||||
|
// The thinking here is the local position was noticed as changing, but not the parentID (since it is now
|
||||||
|
// back to the default), and the entity flew off somewhere. Marking all changed definitely fixes this,
|
||||||
|
// and seems safe (per Seth).
|
||||||
|
properties.markAllChanged();
|
||||||
|
|
||||||
|
entitiesToLoad.push_back(properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
_avatarEntityStrings.clear();
|
_poorlyFormattedAvatarEntityData.clear();
|
||||||
auto entityTreeRenderer = qApp->getEntities();
|
auto entityTreeRenderer = qApp->getEntities();
|
||||||
EntityTreePointer entityTree = entityTreeRenderer ? entityTreeRenderer->getTree() : nullptr;
|
EntityTreePointer entityTree = entityTreeRenderer ? entityTreeRenderer->getTree() : nullptr;
|
||||||
if (entityTree) {
|
if (entityTree) {
|
||||||
|
@ -1597,7 +1646,10 @@ void MyAvatar::loadAvatarEntityDataFromSettings() {
|
||||||
// only remember an AvatarEntity that successfully loads and can be packed
|
// only remember an AvatarEntity that successfully loads and can be packed
|
||||||
QByteArray tempArray((const char*)packetData.getUncompressedData(), packetData.getUncompressedSize());
|
QByteArray tempArray((const char*)packetData.getUncompressedData(), packetData.getUncompressedSize());
|
||||||
storeAvatarEntityDataPayload(entityID, tempArray);
|
storeAvatarEntityDataPayload(entityID, tempArray);
|
||||||
_avatarEntityStrings[entityID] = _avatarEntityDataSettings[i].get();
|
|
||||||
|
// we store these binaryProperties for later: when saving back to settings
|
||||||
|
// unfortunately we must use this non-human-readable format because reasons
|
||||||
|
_poorlyFormattedAvatarEntityData[entityID] = _avatarEntityDataSettings[i].get();
|
||||||
}
|
}
|
||||||
packetData.reset();
|
packetData.reset();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1944,10 +1944,9 @@ private:
|
||||||
Setting::Handle<bool> _flyingHMDSetting;
|
Setting::Handle<bool> _flyingHMDSetting;
|
||||||
Setting::Handle<int> _avatarEntityCountSetting;
|
Setting::Handle<int> _avatarEntityCountSetting;
|
||||||
Setting::Handle<bool> _allowTeleportingSetting { "allowTeleporting", true };
|
Setting::Handle<bool> _allowTeleportingSetting { "allowTeleporting", true };
|
||||||
std::vector<Setting::Handle<QString>> _avatarEntityIDSettings;
|
std::vector<Setting::Handle<QUuid>> _avatarEntityIDSettings;
|
||||||
std::vector<Setting::Handle<QString>> _avatarEntityDataSettings;
|
std::vector<Setting::Handle<QByteArray>> _avatarEntityDataSettings;
|
||||||
std::map<QUuid, QString> _avatarEntityStrings;
|
std::map<QUuid, QByteArray> _poorlyFormattedAvatarEntityData;
|
||||||
std::map<QUuid, QString> _avatarEntityProperties;
|
|
||||||
std::set<QUuid> _entitiesToSaveToSettings;
|
std::set<QUuid> _entitiesToSaveToSettings;
|
||||||
std::set<QUuid> _entitiesToRemoveFromSettings;
|
std::set<QUuid> _entitiesToRemoveFromSettings;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue