1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-23 22:37:55 +02:00

Merge pull request #5940 from Laserlicht/case_insensitive

case insensitive cheat identifier
This commit is contained in:
Ivan Savenko
2025-07-31 17:05:26 +03:00
committed by GitHub
3 changed files with 34 additions and 20 deletions

View File

@@ -102,7 +102,7 @@ void CIdentifierStorage::requestIdentifier(const ObjectCallback & callback) cons
resolveIdentifier(callback); resolveIdentifier(callback);
} }
CIdentifierStorage::ObjectCallback CIdentifierStorage::ObjectCallback::fromNameWithType(const std::string & scope, const std::string & fullName, const std::function<void(si32)> & callback, bool optional) CIdentifierStorage::ObjectCallback CIdentifierStorage::ObjectCallback::fromNameWithType(const std::string & scope, const std::string & fullName, const std::function<void(si32)> & callback, bool optional, bool caseSensitive)
{ {
assert(!scope.empty()); assert(!scope.empty());
@@ -120,10 +120,11 @@ CIdentifierStorage::ObjectCallback CIdentifierStorage::ObjectCallback::fromNameW
result.callback = callback; result.callback = callback;
result.optional = optional; result.optional = optional;
result.dynamicType = true; result.dynamicType = true;
result.caseSensitive = caseSensitive;
return result; return result;
} }
CIdentifierStorage::ObjectCallback CIdentifierStorage::ObjectCallback::fromNameAndType(const std::string & scope, const std::string & type, const std::string & fullName, const std::function<void(si32)> & callback, bool optional, bool bypassDependenciesCheck) CIdentifierStorage::ObjectCallback CIdentifierStorage::ObjectCallback::fromNameAndType(const std::string & scope, const std::string & type, const std::string & fullName, const std::function<void(si32)> & callback, bool optional, bool bypassDependenciesCheck, bool caseSensitive)
{ {
assert(!scope.empty()); assert(!scope.empty());
@@ -150,27 +151,28 @@ CIdentifierStorage::ObjectCallback CIdentifierStorage::ObjectCallback::fromNameA
result.optional = optional; result.optional = optional;
result.bypassDependenciesCheck = bypassDependenciesCheck; result.bypassDependenciesCheck = bypassDependenciesCheck;
result.dynamicType = false; result.dynamicType = false;
result.caseSensitive = caseSensitive;
return result; return result;
} }
void CIdentifierStorage::requestIdentifier(const std::string & scope, const std::string & type, const std::string & name, const std::function<void(si32)> & callback) const void CIdentifierStorage::requestIdentifier(const std::string & scope, const std::string & type, const std::string & name, const std::function<void(si32)> & callback) const
{ {
requestIdentifier(ObjectCallback::fromNameAndType(scope, type, name, callback, false, false)); requestIdentifier(ObjectCallback::fromNameAndType(scope, type, name, callback, false, false, true));
} }
void CIdentifierStorage::requestIdentifier(const std::string & scope, const std::string & fullName, const std::function<void(si32)> & callback) const void CIdentifierStorage::requestIdentifier(const std::string & scope, const std::string & fullName, const std::function<void(si32)> & callback) const
{ {
requestIdentifier(ObjectCallback::fromNameWithType(scope, fullName, callback, false)); requestIdentifier(ObjectCallback::fromNameWithType(scope, fullName, callback, false, true));
} }
void CIdentifierStorage::requestIdentifier(const std::string & type, const JsonNode & name, const std::function<void(si32)> & callback) const void CIdentifierStorage::requestIdentifier(const std::string & type, const JsonNode & name, const std::function<void(si32)> & callback) const
{ {
requestIdentifier(ObjectCallback::fromNameAndType(name.getModScope(), type, name.String(), callback, false, false)); requestIdentifier(ObjectCallback::fromNameAndType(name.getModScope(), type, name.String(), callback, false, false, true));
} }
void CIdentifierStorage::requestIdentifier(const JsonNode & name, const std::function<void(si32)> & callback) const void CIdentifierStorage::requestIdentifier(const JsonNode & name, const std::function<void(si32)> & callback) const
{ {
requestIdentifier(ObjectCallback::fromNameWithType(name.getModScope(), name.String(), callback, false)); requestIdentifier(ObjectCallback::fromNameWithType(name.getModScope(), name.String(), callback, false, true));
} }
void CIdentifierStorage::requestIdentifierIfNotNull(const std::string & type, const JsonNode & name, const std::function<void(si32)> & callback) const void CIdentifierStorage::requestIdentifierIfNotNull(const std::string & type, const JsonNode & name, const std::function<void(si32)> & callback) const
@@ -181,29 +183,29 @@ void CIdentifierStorage::requestIdentifierIfNotNull(const std::string & type, co
void CIdentifierStorage::requestIdentifierIfFound(const std::string & type, const JsonNode & name, const std::function<void(si32)> & callback) const void CIdentifierStorage::requestIdentifierIfFound(const std::string & type, const JsonNode & name, const std::function<void(si32)> & callback) const
{ {
requestIdentifier(ObjectCallback::fromNameAndType(name.getModScope(), type, name.String(), callback, false, true)); requestIdentifier(ObjectCallback::fromNameAndType(name.getModScope(), type, name.String(), callback, false, true, true));
} }
void CIdentifierStorage::requestIdentifierIfFound(const std::string & scope, const std::string & type, const std::string & name, const std::function<void(si32)> & callback) const void CIdentifierStorage::requestIdentifierIfFound(const std::string & scope, const std::string & type, const std::string & name, const std::function<void(si32)> & callback) const
{ {
requestIdentifier(ObjectCallback::fromNameAndType(scope, type, name, callback, false, true)); requestIdentifier(ObjectCallback::fromNameAndType(scope, type, name, callback, false, true, true));
} }
void CIdentifierStorage::tryRequestIdentifier(const std::string & scope, const std::string & type, const std::string & name, const std::function<void(si32)> & callback) const void CIdentifierStorage::tryRequestIdentifier(const std::string & scope, const std::string & type, const std::string & name, const std::function<void(si32)> & callback) const
{ {
requestIdentifier(ObjectCallback::fromNameAndType(scope, type, name, callback, true, false)); requestIdentifier(ObjectCallback::fromNameAndType(scope, type, name, callback, true, false, true));
} }
void CIdentifierStorage::tryRequestIdentifier(const std::string & type, const JsonNode & name, const std::function<void(si32)> & callback) const void CIdentifierStorage::tryRequestIdentifier(const std::string & type, const JsonNode & name, const std::function<void(si32)> & callback) const
{ {
requestIdentifier(ObjectCallback::fromNameAndType(name.getModScope(), type, name.String(), callback, true, false)); requestIdentifier(ObjectCallback::fromNameAndType(name.getModScope(), type, name.String(), callback, true, false, true));
} }
std::optional<si32> CIdentifierStorage::getIdentifier(const std::string & scope, const std::string & type, const std::string & name, bool silent) const std::optional<si32> CIdentifierStorage::getIdentifier(const std::string & scope, const std::string & type, const std::string & name, bool silent) const
{ {
//assert(state != ELoadingState::LOADING); //assert(state != ELoadingState::LOADING);
auto options = ObjectCallback::fromNameAndType(scope, type, name, std::function<void(si32)>(), silent, false); auto options = ObjectCallback::fromNameAndType(scope, type, name, std::function<void(si32)>(), silent, false, true);
return getIdentifierImpl(options, silent); return getIdentifierImpl(options, silent);
} }
@@ -211,7 +213,7 @@ std::optional<si32> CIdentifierStorage::getIdentifier(const std::string & type,
{ {
assert(state != ELoadingState::LOADING); assert(state != ELoadingState::LOADING);
auto options = ObjectCallback::fromNameAndType(name.getModScope(), type, name.String(), std::function<void(si32)>(), silent, false); auto options = ObjectCallback::fromNameAndType(name.getModScope(), type, name.String(), std::function<void(si32)>(), silent, false, true);
return getIdentifierImpl(options, silent); return getIdentifierImpl(options, silent);
} }
@@ -220,7 +222,7 @@ std::optional<si32> CIdentifierStorage::getIdentifier(const JsonNode & name, boo
{ {
assert(state != ELoadingState::LOADING); assert(state != ELoadingState::LOADING);
auto options = ObjectCallback::fromNameWithType(name.getModScope(), name.String(), std::function<void(si32)>(), silent); auto options = ObjectCallback::fromNameWithType(name.getModScope(), name.String(), std::function<void(si32)>(), silent, true);
return getIdentifierImpl(options, silent); return getIdentifierImpl(options, silent);
} }
@@ -228,7 +230,13 @@ std::optional<si32> CIdentifierStorage::getIdentifier(const std::string & scope,
{ {
assert(state != ELoadingState::LOADING); assert(state != ELoadingState::LOADING);
auto options = ObjectCallback::fromNameWithType(scope, fullName, std::function<void(si32)>(), silent); auto options = ObjectCallback::fromNameWithType(scope, fullName, std::function<void(si32)>(), silent, true);
return getIdentifierImpl(options, silent);
}
std::optional<si32> CIdentifierStorage::getIdentifierCaseInsensitive(const std::string & scope, const std::string & type, const std::string & name, bool silent) const
{
auto options = ObjectCallback::fromNameAndType(scope, type, name, std::function<void(si32)>(), silent, false, false);
return getIdentifierImpl(options, silent); return getIdentifierImpl(options, silent);
} }
@@ -336,6 +344,7 @@ void CIdentifierStorage::registerObject(const std::string & scope, const std::st
{ {
logMod->trace("registered '%s' as %s:%s", fullID, scope, identifier); logMod->trace("registered '%s' as %s:%s", fullID, scope, identifier);
registeredObjects.insert(mapping); registeredObjects.insert(mapping);
registeredObjectsCaseLookup[boost::algorithm::to_lower_copy(mapping.first)] = mapping.first;
} }
else else
{ {
@@ -409,8 +418,10 @@ std::vector<CIdentifierStorage::ObjectData> CIdentifierStorage::getPossibleIdent
} }
std::string fullID = request.type + '.' + request.name; std::string fullID = request.type + '.' + request.name;
std::string fullIDCaseCorrected = request.caseSensitive ? fullID : registeredObjectsCaseLookup.at(boost::algorithm::to_lower_copy(fullID));
auto entries = registeredObjects.equal_range(fullIDCaseCorrected);
auto entries = registeredObjects.equal_range(fullID);
if (entries.first != entries.second) if (entries.first != entries.second)
{ {
std::vector<ObjectData> locatedIDs; std::vector<ObjectData> locatedIDs;

View File

@@ -34,12 +34,13 @@ class DLL_LINKAGE CIdentifierStorage
bool optional; bool optional;
bool bypassDependenciesCheck; bool bypassDependenciesCheck;
bool dynamicType; bool dynamicType;
bool caseSensitive;
/// Builds callback from identifier in form "targetMod:type.name" /// Builds callback from identifier in form "targetMod:type.name"
static ObjectCallback fromNameWithType(const std::string & scope, const std::string & fullName, const std::function<void(si32)> & callback, bool optional); static ObjectCallback fromNameWithType(const std::string & scope, const std::string & fullName, const std::function<void(si32)> & callback, bool optional, bool caseSensitive);
/// Builds callback from identifier in form "targetMod:name" /// Builds callback from identifier in form "targetMod:name"
static ObjectCallback fromNameAndType(const std::string & scope, const std::string & type, const std::string & fullName, const std::function<void(si32)> & callback, bool optional, bool bypassDependenciesCheck); static ObjectCallback fromNameAndType(const std::string & scope, const std::string & type, const std::string & fullName, const std::function<void(si32)> & callback, bool optional, bool bypassDependenciesCheck, bool caseSensitive);
private: private:
ObjectCallback() = default; ObjectCallback() = default;
@@ -57,6 +58,7 @@ class DLL_LINKAGE CIdentifierStorage
}; };
std::multimap<std::string, ObjectData> registeredObjects; std::multimap<std::string, ObjectData> registeredObjects;
std::map<std::string, std::string> registeredObjectsCaseLookup;
mutable std::vector<ObjectCallback> scheduledRequests; mutable std::vector<ObjectCallback> scheduledRequests;
/// All non-optional requests that have failed to resolve, for debug & error reporting /// All non-optional requests that have failed to resolve, for debug & error reporting
@@ -101,6 +103,7 @@ public:
std::optional<si32> getIdentifier(const std::string & type, const JsonNode & name, bool silent = false) const; std::optional<si32> getIdentifier(const std::string & type, const JsonNode & name, bool silent = false) const;
std::optional<si32> getIdentifier(const JsonNode & name, bool silent = false) const; std::optional<si32> getIdentifier(const JsonNode & name, bool silent = false) const;
std::optional<si32> getIdentifier(const std::string & scope, const std::string & fullName, bool silent = false) const; std::optional<si32> getIdentifier(const std::string & scope, const std::string & fullName, bool silent = false) const;
std::optional<si32> getIdentifierCaseInsensitive(const std::string & scope, const std::string & type, const std::string & name, bool silent) const;
/// registers new object /// registers new object
void registerObject(const std::string & scope, const std::string & type, const std::string & name, si32 identifier); void registerObject(const std::string & scope, const std::string & type, const std::string & name, si32 identifier);

View File

@@ -427,7 +427,7 @@ void PlayerMessageProcessor::cheatGiveArmy(PlayerColor player, const CGHeroInsta
{ {
} }
std::optional<int32_t> creatureId = LIBRARY->identifiers()->getIdentifier(ModScope::scopeGame(), "creature", creatureIdentifier, false); std::optional<int32_t> creatureId = LIBRARY->identifiers()->getIdentifierCaseInsensitive(ModScope::scopeGame(), "creature", creatureIdentifier, false);
if(creatureId.has_value()) if(creatureId.has_value())
{ {
@@ -468,7 +468,7 @@ void PlayerMessageProcessor::cheatGiveArtifacts(PlayerColor player, const CGHero
{ {
for (auto const & word : words) for (auto const & word : words)
{ {
auto artID = LIBRARY->identifiers()->getIdentifier(ModScope::scopeGame(), "artifact", word, false); auto artID = LIBRARY->identifiers()->getIdentifierCaseInsensitive(ModScope::scopeGame(), "artifact", word, false);
if(artID && LIBRARY->arth->objects[*artID]) if(artID && LIBRARY->arth->objects[*artID])
gameHandler->giveHeroNewArtifact(hero, ArtifactID(*artID), ArtifactPosition::FIRST_AVAILABLE); gameHandler->giveHeroNewArtifact(hero, ArtifactID(*artID), ArtifactPosition::FIRST_AVAILABLE);
} }
@@ -727,7 +727,7 @@ void PlayerMessageProcessor::cheatSkill(PlayerColor player, const CGHeroInstance
return; return;
} }
std::optional<int32_t> skillId = LIBRARY->identifiers()->getIdentifier(ModScope::scopeGame(), "skill", identifier, false); std::optional<int32_t> skillId = LIBRARY->identifiers()->getIdentifierCaseInsensitive(ModScope::scopeGame(), "skill", identifier, false);
if(!skillId.has_value()) if(!skillId.has_value())
return; return;