From 2fc819cdae4de34b948398e0d0cfb170ee83fb56 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 10 Oct 2019 13:29:25 +0400 Subject: [PATCH] Encode ID's in all places to UTF-8 (bug #3977) --- CHANGELOG.md | 1 + apps/esmtool/record.cpp | 8 ++++---- apps/essimporter/convertscpt.cpp | 2 +- apps/essimporter/importinventory.cpp | 2 +- .../opencs/model/tools/referenceablecheck.cpp | 2 +- apps/opencs/model/tools/regioncheck.cpp | 2 +- apps/opencs/model/world/actoradapter.cpp | 2 +- .../model/world/nestedcoladapterimp.cpp | 2 +- apps/opencs/model/world/refidadapterimp.hpp | 2 +- apps/openmw/mwsound/soundmanagerimp.cpp | 2 +- apps/openmw/mwworld/containerstore.cpp | 6 +++--- components/esm/loadcont.cpp | 9 +++++++-- components/esm/loadcont.hpp | 2 +- components/esm/loadregn.cpp | 9 +++++++-- components/esm/loadregn.hpp | 2 +- components/esm/loadscpt.cpp | 19 ++++++++----------- components/esm/loadscpt.hpp | 2 +- 17 files changed, 41 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bafad417b..2c5ce7d6af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ Bug #3778: [Mod] Improved Thrown Weapon Projectiles - weapons have wrong transformation during throw animation Bug #3812: Wrong multiline tooltips width when word-wrapping is enabled Bug #3894: Hostile spell effects not detected/present on first frame of OnPCHitMe + Bug #3977: Non-ASCII characters in object ID's are not supported Bug #4077: Enchanted items are not recharged if they are not in the player's inventory Bug #4202: Open .omwaddon files without needing toopen openmw-cs first Bug #4240: Ash storm origin coordinates and hand shielding animation behavior are incorrect diff --git a/apps/esmtool/record.cpp b/apps/esmtool/record.cpp index c4b14a3413..e8f4444894 100644 --- a/apps/esmtool/record.cpp +++ b/apps/esmtool/record.cpp @@ -607,7 +607,7 @@ void Record::print() std::cout << " Weight: " << mData.mWeight << std::endl; for (const ESM::ContItem &item : mData.mInventory.mList) std::cout << " Inventory: Count: " << Misc::StringUtils::format("%4d", item.mCount) - << " Item: " << item.mItem.toString() << std::endl; + << " Item: " << item.mItem << std::endl; std::cout << " Deleted: " << mIsDeleted << std::endl; } @@ -653,7 +653,7 @@ void Record::print() for (const ESM::ContItem &item : mData.mInventory.mList) std::cout << " Inventory: Count: " << Misc::StringUtils::format("%4d", item.mCount) - << " Item: " << item.mItem.toString() << std::endl; + << " Item: " << item.mItem << std::endl; for (const std::string &spell : mData.mSpells.mList) std::cout << " Spell: " << spell << std::endl; @@ -1073,7 +1073,7 @@ void Record::print() for (const ESM::ContItem &item : mData.mInventory.mList) std::cout << " Inventory: Count: " << Misc::StringUtils::format("%4d", item.mCount) - << " Item: " << item.mItem.toString() << std::endl; + << " Item: " << item.mItem << std::endl; for (const std::string &spell : mData.mSpells.mList) std::cout << " Spell: " << spell << std::endl; @@ -1192,7 +1192,7 @@ void Record::print() if (!mData.mSleepList.empty()) std::cout << " Sleep List: " << mData.mSleepList << std::endl; for (const ESM::Region::SoundRef &soundref : mData.mSoundList) - std::cout << " Sound: " << (int)soundref.mChance << " = " << soundref.mSound.toString() << std::endl; + std::cout << " Sound: " << (int)soundref.mChance << " = " << soundref.mSound << std::endl; } template<> diff --git a/apps/essimporter/convertscpt.cpp b/apps/essimporter/convertscpt.cpp index ca81ebbbf2..484a2782a3 100644 --- a/apps/essimporter/convertscpt.cpp +++ b/apps/essimporter/convertscpt.cpp @@ -9,7 +9,7 @@ namespace ESSImport void convertSCPT(const SCPT &scpt, ESM::GlobalScript &out) { - out.mId = Misc::StringUtils::lowerCase(scpt.mSCHD.mName.toString()); + out.mId = Misc::StringUtils::lowerCase(scpt.mSCHD.mName); out.mRunning = scpt.mRunning; convertSCRI(scpt.mSCRI, out.mLocals); } diff --git a/apps/essimporter/importinventory.cpp b/apps/essimporter/importinventory.cpp index 8c7d07f637..177213a13a 100644 --- a/apps/essimporter/importinventory.cpp +++ b/apps/essimporter/importinventory.cpp @@ -17,7 +17,7 @@ namespace ESSImport esm.getHT(contItem); InventoryItem item; - item.mId = contItem.mItem.toString(); + item.mId = contItem.mItem; item.mCount = contItem.mCount; item.mRelativeEquipmentSlot = -1; item.mLockLevel = 0; diff --git a/apps/opencs/model/tools/referenceablecheck.cpp b/apps/opencs/model/tools/referenceablecheck.cpp index 73c28f5647..981e8c1957 100644 --- a/apps/opencs/model/tools/referenceablecheck.cpp +++ b/apps/opencs/model/tools/referenceablecheck.cpp @@ -910,7 +910,7 @@ void CSMTools::ReferenceableCheckStage::inventoryListCheck( { for (size_t i = 0; i < itemList.size(); ++i) { - std::string itemName = itemList[i].mItem.toString(); + std::string itemName = itemList[i].mItem; CSMWorld::RefIdData::LocalIndex localIndex = mReferencables.searchId(itemName); if (localIndex.first == -1) diff --git a/apps/opencs/model/tools/regioncheck.cpp b/apps/opencs/model/tools/regioncheck.cpp index 1e6f647867..27a73be93d 100644 --- a/apps/opencs/model/tools/regioncheck.cpp +++ b/apps/opencs/model/tools/regioncheck.cpp @@ -45,7 +45,7 @@ void CSMTools::RegionCheckStage::perform (int stage, CSMDoc::Messages& messages) for (const ESM::Region::SoundRef& sound : region.mSoundList) { if (sound.mChance > 100) - messages.add(id, "Chance of '" + sound.mSound.toString() + "' sound to play is over 100 percent", "", CSMDoc::Message::Severity_Warning); + messages.add(id, "Chance of '" + sound.mSound + "' sound to play is over 100 percent", "", CSMDoc::Message::Severity_Warning); } /// \todo check data members that can't be edited in the table view diff --git a/apps/opencs/model/world/actoradapter.cpp b/apps/opencs/model/world/actoradapter.cpp index 0e9b0745c7..5ed80a1e4e 100644 --- a/apps/opencs/model/world/actoradapter.cpp +++ b/apps/opencs/model/world/actoradapter.cpp @@ -538,7 +538,7 @@ namespace CSMWorld for (auto& item : npc.mInventory.mList) { if (item.mCount <= 0) continue; - std::string itemId = item.mItem.toString(); + std::string itemId = item.mItem; addNpcItem(itemId, data); } } diff --git a/apps/opencs/model/world/nestedcoladapterimp.cpp b/apps/opencs/model/world/nestedcoladapterimp.cpp index 5ae0dabaf9..76338efe51 100644 --- a/apps/opencs/model/world/nestedcoladapterimp.cpp +++ b/apps/opencs/model/world/nestedcoladapterimp.cpp @@ -396,7 +396,7 @@ namespace CSMWorld ESM::Region::SoundRef soundRef = soundList[subRowIndex]; switch (subColIndex) { - case 0: return QString(soundRef.mSound.toString().c_str()); + case 0: return QString(soundRef.mSound.c_str()); case 1: return soundRef.mChance; default: throw std::runtime_error("Region sounds subcolumn index out of range"); } diff --git a/apps/opencs/model/world/refidadapterimp.hpp b/apps/opencs/model/world/refidadapterimp.hpp index 16b7739f70..6cb6fcd9cb 100644 --- a/apps/opencs/model/world/refidadapterimp.hpp +++ b/apps/opencs/model/world/refidadapterimp.hpp @@ -1257,7 +1257,7 @@ namespace CSMWorld switch (subColIndex) { - case 0: return QString::fromUtf8(content.mItem.toString().c_str()); + case 0: return QString::fromUtf8(content.mItem.c_str()); case 1: return content.mCount; default: throw std::runtime_error("Trying to access non-existing column in the nested table!"); diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index cef791c85d..e01df7aa97 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -924,7 +924,7 @@ namespace MWSound { if(r - pos < sndref.mChance) { - playSound(sndref.mSound.toString(), 1.0f, 1.0f); + playSound(sndref.mSound, 1.0f, 1.0f); break; } pos += sndref.mChance; diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index 21ad9dfe11..8c5861e73f 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -495,7 +495,7 @@ void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const std:: for (std::vector::const_iterator iter (items.mList.begin()); iter!=items.mList.end(); ++iter) { - std::string id = Misc::StringUtils::lowerCase(iter->mItem.toString()); + std::string id = Misc::StringUtils::lowerCase(iter->mItem); addInitialItem(id, owner, iter->mCount); } @@ -626,10 +626,10 @@ void MWWorld::ContainerStore::restock (const ESM::InventoryList& items, const MW if (it->mCount >= 0) continue; - std::string itemOrList = Misc::StringUtils::lowerCase(it->mItem.toString()); + std::string itemOrList = Misc::StringUtils::lowerCase(it->mItem); //If it's levelled list, restock if there's need to do so. - if (MWBase::Environment::get().getWorld()->getStore().get().search(it->mItem.toString())) + if (MWBase::Environment::get().getWorld()->getStore().get().search(it->mItem)) { std::map::iterator listInMap = allowedForReplace.find(itemOrList); diff --git a/components/esm/loadcont.cpp b/components/esm/loadcont.cpp index 5ee785fb8d..107aea7cf6 100644 --- a/components/esm/loadcont.cpp +++ b/components/esm/loadcont.cpp @@ -9,8 +9,10 @@ namespace ESM void InventoryList::add(ESMReader &esm) { + esm.getSubHeader(); ContItem ci; - esm.getHT(ci, 36); + esm.getT(ci.mCount); + ci.mItem.assign(esm.getString(32)); mList.push_back(ci); } @@ -18,7 +20,10 @@ namespace ESM { for (std::vector::const_iterator it = mList.begin(); it != mList.end(); ++it) { - esm.writeHNT("NPCO", *it, 36); + esm.startSubRecord("NPCO"); + esm.writeT(it->mCount); + esm.writeFixedSizeString(it->mItem, 32); + esm.endRecord("NPCO"); } } diff --git a/components/esm/loadcont.hpp b/components/esm/loadcont.hpp index 4c847f4e2e..0cac580748 100644 --- a/components/esm/loadcont.hpp +++ b/components/esm/loadcont.hpp @@ -19,7 +19,7 @@ class ESMWriter; struct ContItem { int mCount; - NAME32 mItem; + std::string mItem; }; /// InventoryList, NPCO subrecord diff --git a/components/esm/loadregn.cpp b/components/esm/loadregn.cpp index e708bbb4e5..98edca48f0 100644 --- a/components/esm/loadregn.cpp +++ b/components/esm/loadregn.cpp @@ -62,8 +62,10 @@ namespace ESM break; case ESM::FourCC<'S','N','A','M'>::value: { + esm.getSubHeader(); SoundRef sr; - esm.getHT(sr, 33); + sr.mSound.assign(esm.getString(32)); + esm.getT(sr.mChance); mSoundList.push_back(sr); break; } @@ -103,7 +105,10 @@ namespace ESM esm.writeHNT("CNAM", mMapColor); for (std::vector::const_iterator it = mSoundList.begin(); it != mSoundList.end(); ++it) { - esm.writeHNT("SNAM", *it); + esm.startSubRecord("SNAM"); + esm.writeFixedSizeString(it->mSound, 32); + esm.writeT(it->mChance); + esm.endRecord("NPCO"); } } diff --git a/components/esm/loadregn.hpp b/components/esm/loadregn.hpp index a946e488e2..4adda5197b 100644 --- a/components/esm/loadregn.hpp +++ b/components/esm/loadregn.hpp @@ -37,7 +37,7 @@ struct Region // Reference to a sound that is played randomly in this region struct SoundRef { - NAME32 mSound; + std::string mSound; unsigned char mChance; }; // 33 bytes #pragma pack(pop) diff --git a/components/esm/loadscpt.cpp b/components/esm/loadscpt.cpp index b41dc496fa..10a91d2e2f 100644 --- a/components/esm/loadscpt.cpp +++ b/components/esm/loadscpt.cpp @@ -77,10 +77,10 @@ namespace ESM { case ESM::FourCC<'S','C','H','D'>::value: { - SCHD data; - esm.getHT(data, 52); - mData = data.mData; - mId = data.mName.toString(); + esm.getSubHeader(); + mId = esm.getString(32); + esm.getT(mData); + hasHeader = true; break; } @@ -131,13 +131,10 @@ namespace ESM for (std::vector::const_iterator it = mVarNames.begin(); it != mVarNames.end(); ++it) varNameString.append(*it); - SCHD data; - memset(&data, 0, sizeof(data)); - - data.mData = mData; - data.mName.assign(mId); - - esm.writeHNT("SCHD", data, 52); + esm.startSubRecord("SCHD"); + esm.writeFixedSizeString(mId, 32); + esm.writeT(mData, 20); + esm.endRecord("SCHD"); if (isDeleted) { diff --git a/components/esm/loadscpt.hpp b/components/esm/loadscpt.hpp index b8a06406dd..64cedb095b 100644 --- a/components/esm/loadscpt.hpp +++ b/components/esm/loadscpt.hpp @@ -31,7 +31,7 @@ public: }; struct SCHD { - NAME32 mName; + std::string mName; Script::SCHDstruct mData; }; // 52 bytes