mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-06-27 23:01:55 +00:00
Add dumping of t6 weapons
This commit is contained in:
155
src/ObjCommon/Game/T6/InfoStringT6.cpp
Normal file
155
src/ObjCommon/Game/T6/InfoStringT6.cpp
Normal file
@ -0,0 +1,155 @@
|
||||
#include "InfoStringT6.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
using namespace T6;
|
||||
|
||||
void InfoStringToStructConverter::FillStructure()
|
||||
{
|
||||
}
|
||||
|
||||
InfoStringToStructConverter::InfoStringToStructConverter(const InfoString& infoString, void* structure,
|
||||
const cspField_t* fields, const size_t fieldCount)
|
||||
: InfoStringToStructConverterBase(infoString, structure),
|
||||
m_fields(fields),
|
||||
m_field_count(fieldCount)
|
||||
{
|
||||
}
|
||||
|
||||
void InfoStringFromStructConverter::FillFromBaseField(const cspField_t& field)
|
||||
{
|
||||
switch (static_cast<csParseFieldType_t>(field.iFieldType))
|
||||
{
|
||||
case CSPFT_STRING:
|
||||
FillFromString(std::string(field.szName), field.iOffset);
|
||||
break;
|
||||
|
||||
case CSPFT_STRING_MAX_STRING_CHARS:
|
||||
FillFromStringBuffer(std::string(field.szName), field.iOffset, 1024);
|
||||
break;
|
||||
|
||||
case CSPFT_STRING_MAX_QPATH:
|
||||
FillFromStringBuffer(std::string(field.szName), field.iOffset, 64);
|
||||
break;
|
||||
|
||||
case CSPFT_STRING_MAX_OSPATH:
|
||||
FillFromStringBuffer(std::string(field.szName), field.iOffset, 256);
|
||||
break;
|
||||
|
||||
case CSPFT_INT:
|
||||
FillFromInt(std::string(field.szName), field.iOffset);
|
||||
break;
|
||||
|
||||
case CSPFT_UINT:
|
||||
FillFromUint(std::string(field.szName), field.iOffset);
|
||||
break;
|
||||
|
||||
case CSPFT_BOOL:
|
||||
FillFromBool(std::string(field.szName), field.iOffset);
|
||||
break;
|
||||
|
||||
case CSPFT_QBOOLEAN:
|
||||
FillFromQBoolean(std::string(field.szName), field.iOffset);
|
||||
break;
|
||||
|
||||
case CSPFT_FLOAT:
|
||||
FillFromFloat(std::string(field.szName), field.iOffset);
|
||||
break;
|
||||
|
||||
case CSPFT_MILLISECONDS:
|
||||
FillFromMilliseconds(std::string(field.szName), field.iOffset);
|
||||
break;
|
||||
|
||||
case CSPFT_FX:
|
||||
{
|
||||
const auto* fx = *reinterpret_cast<FxEffectDef**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
||||
|
||||
if (fx)
|
||||
m_info_string.SetValueForKey(std::string(field.szName), std::string(fx->name));
|
||||
else
|
||||
m_info_string.SetValueForKey(std::string(field.szName), "");
|
||||
break;
|
||||
}
|
||||
|
||||
case CSPFT_XMODEL:
|
||||
{
|
||||
const auto* model = *reinterpret_cast<XModel**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
||||
|
||||
if (model)
|
||||
m_info_string.SetValueForKey(std::string(field.szName), std::string(model->name));
|
||||
else
|
||||
m_info_string.SetValueForKey(std::string(field.szName), "");
|
||||
break;
|
||||
}
|
||||
|
||||
case CSPFT_MATERIAL:
|
||||
case CSPFT_MATERIAL_STREAM:
|
||||
{
|
||||
const auto* material = *reinterpret_cast<Material**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
||||
|
||||
if (material)
|
||||
m_info_string.SetValueForKey(std::string(field.szName), std::string(material->info.name));
|
||||
else
|
||||
m_info_string.SetValueForKey(std::string(field.szName), "");
|
||||
break;
|
||||
}
|
||||
|
||||
case CSPFT_PHYS_PRESET:
|
||||
{
|
||||
const auto* physPreset = *reinterpret_cast<PhysPreset**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
||||
|
||||
if (physPreset)
|
||||
m_info_string.SetValueForKey(std::string(field.szName), std::string(physPreset->name));
|
||||
else
|
||||
m_info_string.SetValueForKey(std::string(field.szName), "");
|
||||
break;
|
||||
}
|
||||
|
||||
case CSPFT_SCRIPT_STRING:
|
||||
FillFromScriptString(std::string(field.szName), field.iOffset);
|
||||
break;
|
||||
|
||||
case CSPFT_TRACER:
|
||||
{
|
||||
const auto* tracer = *reinterpret_cast<TracerDef**>(reinterpret_cast<uintptr_t>(m_structure) + field.iOffset);
|
||||
|
||||
if (tracer)
|
||||
m_info_string.SetValueForKey(std::string(field.szName), std::string(tracer->name));
|
||||
else
|
||||
m_info_string.SetValueForKey(std::string(field.szName), "");
|
||||
break;
|
||||
}
|
||||
|
||||
case CSPFT_SOUND_ALIAS_ID:
|
||||
assert(false);
|
||||
FillFromUint(std::string(field.szName), field.iOffset);
|
||||
break;
|
||||
|
||||
case CSPFT_NUM_BASE_FIELD_TYPES:
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void InfoStringFromStructConverter::FillInfoString()
|
||||
{
|
||||
for (auto fieldIndex = 0u; fieldIndex < m_field_count; fieldIndex++)
|
||||
{
|
||||
const auto& field = m_fields[fieldIndex];
|
||||
assert(field.iFieldType >= 0);
|
||||
|
||||
if (field.iFieldType < CSPFT_NUM_BASE_FIELD_TYPES)
|
||||
FillFromBaseField(field);
|
||||
else
|
||||
FillFromExtensionField(field);
|
||||
}
|
||||
}
|
||||
|
||||
InfoStringFromStructConverter::InfoStringFromStructConverter(const void* structure, const cspField_t* fields,
|
||||
const size_t fieldCount)
|
||||
: InfoStringFromStructConverterBase(structure),
|
||||
m_fields(fields),
|
||||
m_field_count(fieldCount)
|
||||
{
|
||||
}
|
32
src/ObjCommon/Game/T6/InfoStringT6.h
Normal file
32
src/ObjCommon/Game/T6/InfoStringT6.h
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
#include "Utils/InfoString.h"
|
||||
#include "Game/T6/T6.h"
|
||||
|
||||
namespace T6
|
||||
{
|
||||
class InfoStringToStructConverter : public InfoStringToStructConverterBase
|
||||
{
|
||||
const cspField_t* m_fields;
|
||||
size_t m_field_count;
|
||||
|
||||
protected:
|
||||
void FillStructure() override;
|
||||
|
||||
public:
|
||||
InfoStringToStructConverter(const InfoString& infoString, void* structure, const cspField_t* fields, size_t fieldCount);
|
||||
};
|
||||
|
||||
class InfoStringFromStructConverter : public InfoStringFromStructConverterBase
|
||||
{
|
||||
protected:
|
||||
const cspField_t* m_fields;
|
||||
size_t m_field_count;
|
||||
|
||||
virtual void FillFromExtensionField(const cspField_t& field) = 0;
|
||||
void FillFromBaseField(const cspField_t& field);
|
||||
void FillInfoString() override;
|
||||
|
||||
public:
|
||||
InfoStringFromStructConverter(const void* structure, const cspField_t* fields, size_t fieldCount);
|
||||
};
|
||||
}
|
208
src/ObjCommon/Utils/InfoString.cpp
Normal file
208
src/ObjCommon/Utils/InfoString.cpp
Normal file
@ -0,0 +1,208 @@
|
||||
#include "InfoString.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
|
||||
const std::string InfoString::EMPTY_VALUE;
|
||||
|
||||
bool InfoString::HasKey(const std::string& key) const
|
||||
{
|
||||
return m_values.find(key) != m_values.end();
|
||||
}
|
||||
|
||||
const std::string& InfoString::GetValueForKey(const std::string& key) const
|
||||
{
|
||||
const auto& value = m_values.find(key);
|
||||
|
||||
if (value == m_values.end())
|
||||
return EMPTY_VALUE;
|
||||
|
||||
return value->second;
|
||||
}
|
||||
|
||||
const std::string& InfoString::GetValueForKey(const std::string& key, bool* foundValue) const
|
||||
{
|
||||
const auto& value = m_values.find(key);
|
||||
|
||||
if (value == m_values.end())
|
||||
{
|
||||
if (foundValue)
|
||||
*foundValue = false;
|
||||
return EMPTY_VALUE;
|
||||
}
|
||||
|
||||
if (foundValue)
|
||||
*foundValue = true;
|
||||
return value->second;
|
||||
}
|
||||
|
||||
void InfoString::SetValueForKey(const std::string& key, std::string value)
|
||||
{
|
||||
if (!HasKey(key))
|
||||
m_keys_by_insertion.push_back(key);
|
||||
|
||||
m_values[key] = std::move(value);
|
||||
}
|
||||
|
||||
void InfoString::RemoveKey(const std::string& key)
|
||||
{
|
||||
const auto& value = m_values.find(key);
|
||||
|
||||
if (value != m_values.end())
|
||||
m_values.erase(value);
|
||||
}
|
||||
|
||||
std::string InfoString::ToString() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
bool first = true;
|
||||
|
||||
for (const auto& key : m_keys_by_insertion)
|
||||
{
|
||||
const auto value = m_values.find(key);
|
||||
if (!first)
|
||||
ss << '\\';
|
||||
else
|
||||
first = false;
|
||||
|
||||
ss << key << '\\' << value->second;
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string InfoString::ToString(const std::string& prefix) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << prefix;
|
||||
|
||||
for (const auto& key : m_keys_by_insertion)
|
||||
{
|
||||
const auto value = m_values.find(key);
|
||||
ss << '\\' << key << '\\' << value->second;
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void InfoString::FromString()
|
||||
{
|
||||
}
|
||||
|
||||
void InfoString::FromString(const std::string& prefix)
|
||||
{
|
||||
}
|
||||
|
||||
InfoStringToStructConverterBase::InfoStringToStructConverterBase(const InfoString& infoString, void* structure)
|
||||
: m_info_string(infoString),
|
||||
m_structure(structure)
|
||||
{
|
||||
}
|
||||
|
||||
InfoStringToStructConverterBase::~InfoStringToStructConverterBase()
|
||||
= default;
|
||||
|
||||
void InfoStringToStructConverterBase::Convert()
|
||||
{
|
||||
FillStructure();
|
||||
}
|
||||
|
||||
InfoStringFromStructConverterBase::InfoStringFromStructConverterBase(const void* structure)
|
||||
: m_structure(structure),
|
||||
m_get_scr_string([](scr_string_t)
|
||||
{
|
||||
assert(false);
|
||||
return "";
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
InfoStringFromStructConverterBase::InfoStringFromStructConverterBase(const void* structure,
|
||||
std::function<std::string(scr_string_t)>
|
||||
scriptStringValueCallback)
|
||||
: m_structure(structure),
|
||||
m_get_scr_string(std::move(scriptStringValueCallback))
|
||||
{
|
||||
}
|
||||
|
||||
InfoStringFromStructConverterBase::~InfoStringFromStructConverterBase()
|
||||
= default;
|
||||
|
||||
InfoString InfoStringFromStructConverterBase::Convert()
|
||||
{
|
||||
FillInfoString();
|
||||
return std::move(m_info_string);
|
||||
}
|
||||
|
||||
void InfoStringFromStructConverterBase::FillFromString(const std::string& key, size_t offset)
|
||||
{
|
||||
const auto* str = *reinterpret_cast<const char**>(reinterpret_cast<uintptr_t>(m_structure) + offset);
|
||||
|
||||
if (str)
|
||||
m_info_string.SetValueForKey(key, std::string(str));
|
||||
else
|
||||
m_info_string.SetValueForKey(key, "");
|
||||
}
|
||||
|
||||
void InfoStringFromStructConverterBase::FillFromStringBuffer(const std::string& key, const size_t offset,
|
||||
const size_t bufferSize)
|
||||
{
|
||||
const auto* str = reinterpret_cast<const char*>(reinterpret_cast<uintptr_t>(m_structure) + offset);
|
||||
const auto strLen = strnlen_s(str, bufferSize);
|
||||
m_info_string.SetValueForKey(key, std::string(str, strLen));
|
||||
}
|
||||
|
||||
void InfoStringFromStructConverterBase::FillFromInt(const std::string& key, const size_t offset)
|
||||
{
|
||||
const auto* num = reinterpret_cast<int*>(reinterpret_cast<uintptr_t>(m_structure) + offset);
|
||||
m_info_string.SetValueForKey(key, std::to_string(*num));
|
||||
}
|
||||
|
||||
void InfoStringFromStructConverterBase::FillFromUint(const std::string& key, const size_t offset)
|
||||
{
|
||||
const auto* num = reinterpret_cast<unsigned int*>(reinterpret_cast<uintptr_t>(m_structure) + offset);
|
||||
m_info_string.SetValueForKey(key, std::to_string(*num));
|
||||
}
|
||||
|
||||
void InfoStringFromStructConverterBase::FillFromBool(const std::string& key, const size_t offset)
|
||||
{
|
||||
const auto* bBool = reinterpret_cast<bool*>(reinterpret_cast<uintptr_t>(m_structure) + offset);
|
||||
m_info_string.SetValueForKey(key, *bBool ? "1" : "0");
|
||||
}
|
||||
|
||||
void InfoStringFromStructConverterBase::FillFromQBoolean(const std::string& key, const size_t offset)
|
||||
{
|
||||
const auto* iBool = reinterpret_cast<int*>(reinterpret_cast<uintptr_t>(m_structure) + offset);
|
||||
m_info_string.SetValueForKey(key, *iBool != 0 ? "1" : "0");
|
||||
}
|
||||
|
||||
void InfoStringFromStructConverterBase::FillFromFloat(const std::string& key, const size_t offset)
|
||||
{
|
||||
const auto* num = reinterpret_cast<float*>(reinterpret_cast<uintptr_t>(m_structure) + offset);
|
||||
m_info_string.SetValueForKey(key, std::to_string(*num));
|
||||
}
|
||||
|
||||
void InfoStringFromStructConverterBase::FillFromMilliseconds(const std::string& key, const size_t offset)
|
||||
{
|
||||
const auto* millis = reinterpret_cast<unsigned int*>(reinterpret_cast<uintptr_t>(m_structure) + offset);
|
||||
m_info_string.SetValueForKey(key, std::to_string(static_cast<float>(*millis) / 1000.0f));
|
||||
}
|
||||
|
||||
void InfoStringFromStructConverterBase::FillFromScriptString(const std::string& key, const size_t offset)
|
||||
{
|
||||
const auto* scrStr = reinterpret_cast<scr_string_t*>(reinterpret_cast<uintptr_t>(m_structure) + offset);
|
||||
m_info_string.SetValueForKey(key, m_get_scr_string(*scrStr));
|
||||
}
|
||||
|
||||
void InfoStringFromStructConverterBase::FillFromEnumInt(const std::string& key, const size_t offset,
|
||||
const char** enumValues, const size_t enumSize)
|
||||
{
|
||||
const auto num = *reinterpret_cast<int*>(reinterpret_cast<uintptr_t>(m_structure) + offset);
|
||||
|
||||
assert(num >= 0 && num < static_cast<int>(enumSize));
|
||||
|
||||
if (num >= 0 && num < static_cast<int>(enumSize))
|
||||
m_info_string.SetValueForKey(key, std::string(enumValues[num]));
|
||||
else
|
||||
m_info_string.SetValueForKey(key, "");
|
||||
}
|
78
src/ObjCommon/Utils/InfoString.h
Normal file
78
src/ObjCommon/Utils/InfoString.h
Normal file
@ -0,0 +1,78 @@
|
||||
#pragma once
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Zone/ZoneTypes.h"
|
||||
|
||||
class InfoString
|
||||
{
|
||||
static const std::string EMPTY_VALUE;
|
||||
std::unordered_map<std::string, std::string> m_values;
|
||||
std::vector<std::string> m_keys_by_insertion;
|
||||
|
||||
public:
|
||||
bool HasKey(const std::string& key) const;
|
||||
const std::string& GetValueForKey(const std::string& key) const;
|
||||
const std::string& GetValueForKey(const std::string& key, bool* foundValue) const;
|
||||
void SetValueForKey(const std::string& key, std::string value);
|
||||
void RemoveKey(const std::string& key);
|
||||
|
||||
std::string ToString() const;
|
||||
std::string ToString(const std::string& prefix) const;
|
||||
|
||||
void FromString();
|
||||
void FromString(const std::string& prefix);
|
||||
};
|
||||
|
||||
class InfoStringToStructConverterBase
|
||||
{
|
||||
protected:
|
||||
const InfoString& m_info_string;
|
||||
void* m_structure;
|
||||
|
||||
virtual void FillStructure() = 0;
|
||||
|
||||
public:
|
||||
InfoStringToStructConverterBase(const InfoString& infoString, void* structure);
|
||||
virtual ~InfoStringToStructConverterBase();
|
||||
InfoStringToStructConverterBase(const InfoStringToStructConverterBase& other) = delete;
|
||||
InfoStringToStructConverterBase(InfoStringToStructConverterBase&& other) noexcept = delete;
|
||||
InfoStringToStructConverterBase& operator=(const InfoStringToStructConverterBase& other) = delete;
|
||||
InfoStringToStructConverterBase& operator=(InfoStringToStructConverterBase&& other) noexcept = delete;
|
||||
|
||||
void Convert();
|
||||
};
|
||||
|
||||
class InfoStringFromStructConverterBase
|
||||
{
|
||||
protected:
|
||||
InfoString m_info_string;
|
||||
const void* m_structure;
|
||||
const std::function<std::string(scr_string_t)> m_get_scr_string;
|
||||
|
||||
void FillFromString(const std::string& key, size_t offset);
|
||||
void FillFromStringBuffer(const std::string& key, size_t offset, size_t bufferSize);
|
||||
void FillFromInt(const std::string& key, size_t offset);
|
||||
void FillFromUint(const std::string&, size_t offset);
|
||||
void FillFromBool(const std::string&, size_t offset);
|
||||
void FillFromQBoolean(const std::string& key, size_t offset);
|
||||
void FillFromFloat(const std::string& key, size_t offset);
|
||||
void FillFromMilliseconds(const std::string& key, size_t offset);
|
||||
void FillFromScriptString(const std::string& key, size_t offset);
|
||||
void FillFromEnumInt(const std::string& key, size_t offset, const char** enumValues, size_t enumSize);
|
||||
|
||||
virtual void FillInfoString() = 0;
|
||||
|
||||
public:
|
||||
explicit InfoStringFromStructConverterBase(const void* structure);
|
||||
InfoStringFromStructConverterBase(const void* structure, std::function<std::string(scr_string_t)> scriptStringValueCallback);
|
||||
virtual ~InfoStringFromStructConverterBase();
|
||||
InfoStringFromStructConverterBase(const InfoStringFromStructConverterBase& other) = delete;
|
||||
InfoStringFromStructConverterBase(InfoStringFromStructConverterBase&& other) noexcept = delete;
|
||||
InfoStringFromStructConverterBase& operator=(const InfoStringFromStructConverterBase& other) = delete;
|
||||
InfoStringFromStructConverterBase& operator=(InfoStringFromStructConverterBase&& other) noexcept = delete;
|
||||
|
||||
InfoString Convert();
|
||||
};
|
Reference in New Issue
Block a user