2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2025-06-30 08:11:49 +00:00

Restructure ZoneDefinitionWriting

This commit is contained in:
Jan
2021-03-08 17:28:24 +01:00
parent e6a91c0305
commit d96f813e73
18 changed files with 285 additions and 221 deletions

View File

@ -8,7 +8,7 @@ ContentPrinter::ContentPrinter(Zone* zone)
void ContentPrinter::PrintContent() const
{
const auto* pools = m_zone->m_pools.get();
printf("Zone '%s' (%s)\n", m_zone->m_name.c_str(), m_zone->m_game->GetName().c_str());
printf("Zone '%s' (%s)\n", m_zone->m_name.c_str(), m_zone->m_game->GetShortName().c_str());
puts("Content:");
for(const auto& asset : *pools)

View File

@ -1,29 +1,13 @@
#include "ZoneDefWriter.h"
const std::string AbstractZoneDefWriter::META_DATA_KEY_GAME = "game";
AbstractZoneDefWriter::AbstractZoneDefWriter(Zone* zone, std::ostream& stream)
: m_zone(zone),
m_stream(stream)
void AbstractZoneDefWriter::WriteZoneDef(std::ostream& stream, Zone* zone) const
{
}
ZoneDefinitionOutputStream out(stream);
void AbstractZoneDefWriter::EmptyLine() const
{
m_stream << "\n";
}
out.WriteComment(zone->m_game->GetFullName());
out.WriteMetaData(META_DATA_KEY_GAME, zone->m_game->GetShortName());
out.EmptyLine();
void AbstractZoneDefWriter::WriteComment(const std::string& comment) const
{
m_stream << "// " << comment << "\n";
}
void AbstractZoneDefWriter::WriteMetaData(const std::string& metaDataKey, const std::string& metaDataValue) const
{
m_stream << ">" << metaDataKey << "," << metaDataValue << "\n";
}
void AbstractZoneDefWriter::WriteEntry(const std::string& entryKey, const std::string& entryValue) const
{
m_stream << entryKey << "," << entryValue << "\n";
}
WriteMetaData(out, zone);
WriteContent(out, zone);
}

View File

@ -1,31 +1,30 @@
#pragma once
#include <ostream>
#include "Zone/Zone.h"
class AbstractZoneDefWriter
{
protected:
Zone* m_zone;
std::ostream& m_stream;
static const std::string META_DATA_KEY_GAME;
void EmptyLine() const;
void WriteComment(const std::string& comment) const;
void WriteMetaData(const std::string& metaDataKey, const std::string& metaDataValue) const;
void WriteEntry(const std::string& entryKey, const std::string& entryValue) const;
AbstractZoneDefWriter(Zone* zone, std::ostream& stream);
public:
virtual void WriteZoneDef() = 0;
};
#include "Zone/Definition/ZoneDefinitionStream.h"
class IZoneDefWriter
{
public:
IZoneDefWriter() = default;
virtual ~IZoneDefWriter() = default;
IZoneDefWriter(const IZoneDefWriter& other) = default;
IZoneDefWriter(IZoneDefWriter&& other) noexcept = default;
IZoneDefWriter& operator=(const IZoneDefWriter& other) = default;
IZoneDefWriter& operator=(IZoneDefWriter&& other) noexcept = default;
virtual bool CanHandleZone(Zone* zone) const = 0;
virtual void WriteZoneDef(Zone* zone, std::ostream& stream) const = 0;
virtual void WriteZoneDef(std::ostream& stream, Zone* zone) const = 0;
};
class AbstractZoneDefWriter : public IZoneDefWriter
{
protected:
static constexpr const char* META_DATA_KEY_GAME = "game";
virtual void WriteMetaData(ZoneDefinitionOutputStream& stream, Zone* zone) const = 0;
virtual void WriteContent(ZoneDefinitionOutputStream& stream, Zone* zone) const = 0;
public:
void WriteZoneDef(std::ostream& stream, Zone* zone) const override;
};

View File

@ -1,70 +1,45 @@
#include "ZoneDefWriterIW4.h"
#include "Game/IW4/GameIW4.h"
#include "Game/IW4/CommonIW4.h"
#include "Game/IW4/GameAssetPoolIW4.h"
#include <sstream>
#include <iomanip>
#include <cassert>
#include "Game/IW4/GameIW4.h"
#include "Game/IW4/GameAssetPoolIW4.h"
using namespace IW4;
namespace IW4
{
class ZoneDefWriterInternal final : public AbstractZoneDefWriter
{
void WriteContent() const
{
const auto* pools = dynamic_cast<GameAssetPoolIW4*>(m_zone->m_pools.get());
assert(pools);
if (!pools)
return;
// Localized strings are all collected in one string file. So only add this to the zone file.
if (!pools->m_localize->m_asset_lookup.empty())
{
WriteEntry(pools->GetAssetTypeName(ASSET_TYPE_LOCALIZE_ENTRY), m_zone->m_name);
}
for (const auto& asset : *pools)
{
switch (asset->m_type)
{
case ASSET_TYPE_LOCALIZE_ENTRY:
break;
default:
WriteEntry(pools->GetAssetTypeName(asset->m_type), asset->m_name);
break;
}
}
}
public:
ZoneDefWriterInternal(Zone* zone, std::ostream& stream)
: AbstractZoneDefWriter(zone, stream)
{
}
void WriteZoneDef() override
{
WriteComment("Call Of Duty: Modern Warfare 2");
WriteMetaData(META_DATA_KEY_GAME, "iw4");
EmptyLine();
WriteContent();
}
};
}
bool ZoneDefWriter::CanHandleZone(Zone* zone) const
{
return zone->m_game == &g_GameIW4;
}
void ZoneDefWriter::WriteZoneDef(Zone* zone, std::ostream& stream) const
void ZoneDefWriter::WriteMetaData(ZoneDefinitionOutputStream& stream, Zone* zone) const
{
ZoneDefWriterInternal writer(zone, stream);
writer.WriteZoneDef();
}
void ZoneDefWriter::WriteContent(ZoneDefinitionOutputStream& stream, Zone* zone) const
{
const auto* pools = dynamic_cast<GameAssetPoolIW4*>(zone->m_pools.get());
assert(pools);
if (!pools)
return;
// Localized strings are all collected in one string file. So only add this to the zone file.
if (!pools->m_localize->m_asset_lookup.empty())
{
stream.WriteEntry(pools->GetAssetTypeName(ASSET_TYPE_LOCALIZE_ENTRY), zone->m_name);
}
for (const auto& asset : *pools)
{
switch (asset->m_type)
{
case ASSET_TYPE_LOCALIZE_ENTRY:
break;
default:
stream.WriteEntry(pools->GetAssetTypeName(asset->m_type), asset->m_name);
break;
}
}
}

View File

@ -4,10 +4,13 @@
namespace IW4
{
class ZoneDefWriter final : public IZoneDefWriter
class ZoneDefWriter final : public AbstractZoneDefWriter
{
protected:
void WriteMetaData(::ZoneDefinitionOutputStream& stream, ::Zone* zone) const override;
void WriteContent(::ZoneDefinitionOutputStream& stream, ::Zone* zone) const override;
public:
bool CanHandleZone(Zone* zone) const override;
void WriteZoneDef(Zone* zone, std::ostream& stream) const override;
};
}

View File

@ -11,104 +11,25 @@ using namespace T6;
namespace T6
{
class ZoneDefWriterInternal final : public AbstractZoneDefWriter
class KeyValuePairKnownKey
{
class KnownKey
{
public:
std::string m_key;
int m_hash;
explicit KnownKey(std::string key)
{
m_key = std::move(key);
m_hash = CommonT6::Com_HashKey(m_key.c_str(), 64);
}
};
inline static const KnownKey KNOWN_KEYS[]
{
KnownKey("ipak_read"),
KnownKey("ipak_write"),
KnownKey("initial_xmodels"),
KnownKey("initial_materials"),
};
void WriteKeyValuePair(KeyValuePair* kvp) const
{
for (const auto& knownKey : KNOWN_KEYS)
{
if (knownKey.m_hash == kvp->keyHash)
{
WriteMetaData("level." + knownKey.m_key, kvp->value);
return;
}
}
std::ostringstream str;
str << "level.@" << std::setfill('0') << std::setw(sizeof(int) * 2) << std::hex << kvp->keyHash;
WriteMetaData(str.str(), kvp->value);
}
void WriteContent() const
{
const auto* pools = dynamic_cast<GameAssetPoolT6*>(m_zone->m_pools.get());
assert(pools);
if (!pools)
return;
// Localized strings are all collected in one string file. So only add this to the zone file.
if (!pools->m_localize->m_asset_lookup.empty())
{
WriteEntry(pools->GetAssetTypeName(ASSET_TYPE_LOCALIZE_ENTRY), m_zone->m_name);
}
for (const auto& asset : *pools)
{
switch (asset->m_type)
{
case ASSET_TYPE_LOCALIZE_ENTRY:
case ASSET_TYPE_KEYVALUEPAIRS: // KeyValuePairs should be included as zone file metadata and not as content
break;
default:
WriteEntry(pools->GetAssetTypeName(asset->m_type), asset->m_name);
break;
}
}
}
public:
ZoneDefWriterInternal(Zone* zone, std::ostream& stream)
: AbstractZoneDefWriter(zone, stream)
std::string m_key;
int m_hash;
explicit KeyValuePairKnownKey(std::string key)
{
m_key = std::move(key);
m_hash = CommonT6::Com_HashKey(m_key.c_str(), 64);
}
};
void WriteZoneDef() override
{
WriteComment("Call Of Duty: Black Ops II");
WriteMetaData(META_DATA_KEY_GAME, "t6");
EmptyLine();
auto* assetPoolT6 = dynamic_cast<GameAssetPoolT6*>(m_zone->m_pools.get());
if (assetPoolT6 && !assetPoolT6->m_key_value_pairs->m_asset_lookup.empty())
{
for (auto kvpAsset : *assetPoolT6->m_key_value_pairs)
{
KeyValuePairs* keyValuePairs = kvpAsset->Asset();
for (int varIndex = 0; varIndex < keyValuePairs->numVariables; varIndex++)
{
WriteKeyValuePair(&keyValuePairs->keyValuePairs[varIndex]);
}
}
EmptyLine();
}
WriteContent();
}
const KeyValuePairKnownKey KEY_VALUE_PAIR_KNOWN_KEYS[]
{
KeyValuePairKnownKey("ipak_read"),
KeyValuePairKnownKey("ipak_write"),
KeyValuePairKnownKey("initial_xmodels"),
KeyValuePairKnownKey("initial_materials"),
};
}
@ -117,8 +38,66 @@ bool ZoneDefWriter::CanHandleZone(Zone* zone) const
return zone->m_game == &g_GameT6;
}
void ZoneDefWriter::WriteZoneDef(Zone* zone, std::ostream& stream) const
void ZoneDefWriter::WriteKeyValuePair(ZoneDefinitionOutputStream& stream, KeyValuePair* kvp)
{
ZoneDefWriterInternal writer(zone, stream);
writer.WriteZoneDef();
for (const auto& knownKey : KEY_VALUE_PAIR_KNOWN_KEYS)
{
if (knownKey.m_hash == kvp->keyHash)
{
stream.WriteMetaData("level." + knownKey.m_key, kvp->value);
return;
}
}
std::ostringstream str;
str << "level.@" << std::setfill('0') << std::setw(sizeof(int) * 2) << std::hex << kvp->keyHash;
stream.WriteMetaData(str.str(), kvp->value);
}
void ZoneDefWriter::WriteMetaData(ZoneDefinitionOutputStream& stream, Zone* zone) const
{
auto* assetPoolT6 = dynamic_cast<GameAssetPoolT6*>(zone->m_pools.get());
if (assetPoolT6 && !assetPoolT6->m_key_value_pairs->m_asset_lookup.empty())
{
for (const auto* kvpAsset : *assetPoolT6->m_key_value_pairs)
{
const auto* keyValuePairs = kvpAsset->Asset();
for (auto varIndex = 0; varIndex < keyValuePairs->numVariables; varIndex++)
{
WriteKeyValuePair(stream, &keyValuePairs->keyValuePairs[varIndex]);
}
}
stream.EmptyLine();
}
}
void ZoneDefWriter::WriteContent(ZoneDefinitionOutputStream& stream, Zone* zone) const
{
const auto* pools = dynamic_cast<GameAssetPoolT6*>(zone->m_pools.get());
assert(pools);
if (!pools)
return;
// Localized strings are all collected in one string file. So only add this to the zone file.
if (!pools->m_localize->m_asset_lookup.empty())
{
stream.WriteEntry(pools->GetAssetTypeName(ASSET_TYPE_LOCALIZE_ENTRY), zone->m_name);
}
for (const auto& asset : *pools)
{
switch (asset->m_type)
{
case ASSET_TYPE_LOCALIZE_ENTRY:
case ASSET_TYPE_KEYVALUEPAIRS: // KeyValuePairs should be included as zone file metadata and not as content
break;
default:
stream.WriteEntry(pools->GetAssetTypeName(asset->m_type), asset->m_name);
break;
}
}
}

View File

@ -1,13 +1,19 @@
#pragma once
#include "ContentLister/ZoneDefWriter.h"
#include "Game/T6/T6.h"
namespace T6
{
class ZoneDefWriter final : public IZoneDefWriter
class ZoneDefWriter final : public AbstractZoneDefWriter
{
static void WriteKeyValuePair(ZoneDefinitionOutputStream& stream, KeyValuePair* kvp);
protected:
void WriteMetaData(ZoneDefinitionOutputStream& stream, Zone* zone) const override;
void WriteContent(ZoneDefinitionOutputStream& stream, Zone* zone) const override;
public:
bool CanHandleZone(Zone* zone) const override;
void WriteZoneDef(Zone* zone, std::ostream& stream) const override;
};
}
}

View File

@ -168,7 +168,7 @@ class Unlinker::Impl
{
if (zoneDefWriter->CanHandleZone(zone))
{
zoneDefWriter->WriteZoneDef(zone, zoneDefinitionFile);
zoneDefWriter->WriteZoneDef(zoneDefinitionFile, zone);
result = true;
break;
}
@ -234,7 +234,7 @@ class Unlinker::Impl
return false;
auto gdt = std::make_unique<GdtOutputStream>(gdtStream);
gdt->BeginStream();
gdt->WriteVersion(GdtVersion(zone->m_game->GetName(), 1));
gdt->WriteVersion(GdtVersion(zone->m_game->GetShortName(), 1));
context.m_gdt = std::move(gdt);
}