//super shitcode
template<class T, T sentinel_element>
struct TerminatedSequence
{
const T* begin{};
std::size_t GetLength() const noexcept
{
std::size_t result = 0;
if (begin)
{
for (const T* i = begin; (*i != sentinel_element); ++i)
++result;
}
return result;
}
std::size_t GetLengthLimited(std::size_t limit) const noexcept
{
std::size_t result = 0;
if (begin)
{
const T* const end = begin + limit;
for (const T* i = begin; (i < end) && (*i != sentinel_element); ++i)
++result;
}
return result;
}
};
using SZ_String = TerminatedSequence<char, '\x00'>;
struct SchemaMetadataHelper
{
static DWORD _get_func_rva(const MemImage64& image, void* func)
{
if (image.IsTextPtr(func))
return image.GetRVA(func);
return 0;
}
struct named_filter
{
const char* name;
void* func;
};
enum class MetaDataType
{
CHARS8,
CSTRING_PTR,
NAMED_FILTER_PTR,
CSTRING_PTR_PTR,
CSTRINGPAIR_PTR,
I32,
FLOAT32,
FUNC,
LAST = FUNC,
NONE,
};
static constexpr auto _CHARS8 = std::to_array<std::string_view>({
"MDiskDataForResourceType",
"MResourceTypeForInfoType",
});
static constexpr auto _CSTRING_PTR = std::to_array<std::string_view>({
"MAlternateAttributeName",
"MAttributeName",
"MClassScriptBase",
"MClassScriptDescription",
"MDefaultString",
"MDmElementType",
"MEmitKV3TransferPostLoadFn",
"MEmitKV3TransferPostSaveFn",
"MEmitKV3TransferPreSaveFn",
"MKeyField",
"MKeyfieldname",
"MNetworkAlias",
"MNetworkChangeCallback",
"MNetworkEncoder",
"MNetworkExcludeByName",
"MNetworkExcludeByUserGroup",
"MNetworkGroup",
"MNetworkIncludeByName",
"MNetworkIncludeByUserGroup",
"MNetworkSerializer",
"MNetworkTypeAlias",
"MNetworkUserGroup",
"MPropertyAttributeChoiceEnumName",
"MPropertyAttributeChoiceName",
"MPropertyAttributeEditor",
"MPropertyAttributeRange",
"MPropertyFriendlyName",
"MPropertyGroupName",
"MResourceBlockType",
"MSrc1ImportAttributeName",
"MSrc1ImportDmElementType",
"MVectorIsSometimesCoordinate",
"MCellForDomain",
"MCustomFGDMetadata",
"MParticleReplacementOp",
"MPropertyCustomEditor",
"MPropertyCustomFGDType",
"MPropertyExtendedEditor",
"MVDataOutlinerIcon",
"MFieldVerificationName",
"MKV3TransferName",
"MPropertyDescription",
"MPropertyStartGroup",
"MPropertySuppressExpr",
"MVDataUniqueMonotonicInt",
"MScriptDescription",
"MPropertyIconName",
"MPropertyAttributeSuggestionName",
});
static constexpr auto _NAMED_FILTER_PTR = std::to_array<std::string_view>({
"MNetworkUserGroupSendProxyRecipientsFilter",
});
static constexpr auto _CSTRING_PTR_PTR = std::to_array<std::string_view>({
"MAliases",
});
static constexpr auto _CSTRINGPAIR_PTR = std::to_array<std::string_view>({
"MNetworkOverride",
"MNetworkVarNames",
"MNetworkReplayCompatField",
"MNetworkUserGroupProxy",
"MNetworkVarTypeOverride",
});
static constexpr auto _I32 = std::to_array<std::string_view>({
"MAlignment",
"MGenerateArrayKeynamesFirstIndex",
"MNetworkBitCount",
"MNetworkEncodeFlags",
"MNetworkPriority",
"MParticleOperatorType",
"MPropertySortPriority",
"MResourceVersion",
"MParticleMinVersion",
"MParticleMaxVersion",
"MVDataNodeType",
"MVDataOverlayType",
"MNetworkVarEmbeddedFieldOffsetDelta",
});
static constexpr auto _FLOAT32 = std::to_array<std::string_view>({
"MNetworkMaxValue",
"MNetworkMinValue",
});
static constexpr auto _FUNC = std::to_array<std::string_view>({
"MNetworkSendProxyRecipientsFilter",
"MPropertyChoiceProviderFn",
"MPropertyElementNameFn",
"MPreSerializationCallback",
"MUnserializationCallback",
});
static constexpr auto mappings = std::to_array({
std::span<const std::string_view, std::dynamic_extent>{ _CHARS8 },
std::span<const std::string_view, std::dynamic_extent>{ _CSTRING_PTR },
std::span<const std::string_view, std::dynamic_extent>{ _NAMED_FILTER_PTR },
std::span<const std::string_view, std::dynamic_extent>{ _CSTRING_PTR_PTR },
std::span<const std::string_view, std::dynamic_extent>{ _CSTRINGPAIR_PTR },
std::span<const std::string_view, std::dynamic_extent>{ _I32 },
std::span<const std::string_view, std::dynamic_extent>{ _FLOAT32 },
std::span<const std::string_view, std::dynamic_extent>{ _FUNC },
});
static MetaDataType classify(std::string_view name)
{
for (std::size_t i = 0; i <= std::to_underlying(MetaDataType::LAST); ++i)
{
const auto& list = mappings[i];
if (std::ranges::find(list, name) != list.end())
return static_cast<MetaDataType>(i);
}
return MetaDataType::NONE;
}
static std::string extract(const MemImage64& image, MetaDataType type, void* value, const void* address)
{
std::string result{};
if (value)
{
if (type == MetaDataType::CHARS8)
{
SZ_String str{ (const char*)value };
return { str.begin, str.GetLengthLimited(8) };
}
else if (type == MetaDataType::CSTRING_PTR)
{
const auto str = *(const char**)value;
if (str)
return { str };
}
else if (type == MetaDataType::NAMED_FILTER_PTR)
{
const auto filter = *(named_filter**)value;
if (filter)
{
if (filter->name)
{
result += std::format("name: {}", filter->name);
if (filter->func)
result += ' ';
}
if (filter->func)
result += std::format("func: {} + {}", image.name, (void*)_get_func_rva(image, filter->func));
}
}
else if (type == MetaDataType::CSTRING_PTR_PTR)
{
const auto str_ptr = *(const char***)value;
if (str_ptr)
{
const auto str = *str_ptr;
if (str)
return { str };
}
}
else if (type == MetaDataType::CSTRINGPAIR_PTR)
{
const auto str1 = *(const char**)value;
const auto str2 = *(const char**)((void**)value + 1);
if (str1)
{
result += str1;
if (str2)
result += ' ';
}
if (str2)
result += str2;
}
else if (type == MetaDataType::I32)
{
result += std::format("{}", *(std::int32_t*)value);
}
else if (type == MetaDataType::FLOAT32)
{
result += std::format("{}", *(float*)value);
}
else if (type == MetaDataType::FUNC)
{
void* actual_fn = *(void**)value;
if (!actual_fn)
result += "func: nullptr";
else
result += std::format("func: {} + {}", image.name, (void*)_get_func_rva(image, actual_fn));
}
else
result += std::format("<unidentified non-null meta: {} + {}>", image.name, (void*)image.GetRVA(address));
}
return result;
}
};