cl3.hpp (4730B)
1 #ifndef UUID_4CADE91E_2AF1_47AF_8425_9AA799509BFD 2 #define UUID_4CADE91E_2AF1_47AF_8425_9AA799509BFD 3 #pragma once 4 5 #include "../endian.hpp" 6 #include "../source.hpp" 7 #include "../sink.hpp" 8 9 #include <libshit/fixed_string.hpp> 10 #include <libshit/container/ordered_map.hpp> 11 #include <libshit/lua/auto_table.hpp> 12 13 #include <cstdint> 14 #include <vector> 15 #include <boost/filesystem/path.hpp> 16 17 namespace Neptools 18 { 19 namespace Stcm { class File; } 20 21 class Cl3 final : public Libshit::RefCounted, public Dumpable 22 { 23 LIBSHIT_DYNAMIC_OBJECT; 24 public: 25 struct Header 26 { 27 char magic[3]; 28 char endian; 29 std::uint32_t field_04; 30 std::uint32_t field_08; 31 std::uint32_t sections_count; 32 std::uint32_t sections_offset; 33 std::uint32_t field_14; 34 35 void Validate(FilePosition file_size) const; 36 }; 37 static_assert(sizeof(Header) == 0x18); 38 39 struct Section 40 { 41 Libshit::FixedString<0x20> name; 42 std::uint32_t count; 43 std::uint32_t data_size; 44 std::uint32_t data_offset; 45 std::uint32_t field_2c; 46 std::uint32_t field_30; 47 std::uint32_t field_34; 48 std::uint32_t field_38; 49 std::uint32_t field_3c; 50 std::uint32_t field_40; 51 std::uint32_t field_44; 52 std::uint32_t field_48; 53 std::uint32_t field_4c; 54 55 void Validate(FilePosition file_size) const; 56 }; 57 static_assert(sizeof(Section) == 0x50); 58 59 struct FileEntry 60 { 61 Libshit::FixedString<0x200> name; 62 std::uint32_t field_200; 63 std::uint32_t data_offset; 64 std::uint32_t data_size; 65 std::uint32_t link_start; 66 std::uint32_t link_count; 67 std::uint32_t field_214; 68 std::uint32_t field_218; 69 std::uint32_t field_21c; 70 std::uint32_t field_220; 71 std::uint32_t field_224; 72 std::uint32_t field_228; 73 std::uint32_t field_22c; 74 75 void Validate(uint32_t block_size) const; 76 }; 77 static_assert(sizeof(FileEntry) == 0x230); 78 79 struct LinkEntry 80 { 81 std::uint32_t field_00; 82 std::uint32_t linked_file_id; 83 std::uint32_t link_id; 84 std::uint32_t field_0c; 85 std::uint32_t field_10; 86 std::uint32_t field_14; 87 std::uint32_t field_18; 88 std::uint32_t field_1c; 89 90 void Validate(std::uint32_t i, std::uint32_t file_count) const; 91 }; 92 static_assert(sizeof(LinkEntry) == 0x20); 93 94 struct Entry 95 : public Libshit::OrderedMapItem, public Libshit::Lua::DynamicObject 96 { 97 LIBSHIT_DYNAMIC_OBJECT; 98 public: 99 std::string name; 100 uint32_t field_200 = 0; 101 102 using Links = std::vector<Libshit::WeakRefCountedPtr<Cl3::Entry>>; 103 // no setter - it doesn't work how you expect in lua 104 LIBSHIT_LUAGEN(get: "::Libshit::Lua::GetRefCountedOwnedMember") 105 Links links; 106 107 Libshit::SmartPtr<Dumpable> src; 108 109 Entry(std::string name, uint32_t field_200, 110 Libshit::SmartPtr<Dumpable> src) 111 : name{std::move(name)}, field_200{field_200}, src{std::move(src)} {} 112 explicit Entry(std::string name) : name{std::move(name)} {} 113 114 void Dispose() noexcept override; 115 }; 116 struct EntryKeyOfValue 117 { 118 using type = std::string; 119 const type& operator()(const Entry& e) { return e.name; } 120 }; 121 using Entries = Libshit::OrderedMap<Entry, EntryKeyOfValue>; 122 123 124 Cl3(Source src); 125 explicit Cl3(Endian endian = Endian::LITTLE) 126 : endian{endian}, field_14{0} {} 127 #if LIBSHIT_WITH_LUA 128 Cl3(Libshit::Lua::StateRef vm, Endian endian, uint32_t field_14, 129 Libshit::Lua::RawTable entries); 130 #endif 131 132 void Fixup() override; 133 FilePosition GetSize() const override; 134 135 Endian endian; 136 uint32_t field_14; 137 138 // no setter - it doesn't work how you expect in lua 139 LIBSHIT_LUAGEN(get: "::Libshit::Lua::GetRefCountedOwnedMember") 140 Entries entries; 141 uint32_t IndexOf(const Libshit::WeakSmartPtr<Entry>& ptr) const noexcept; 142 143 Entry& GetOrCreateFile(Libshit::StringView fname); 144 145 void ExtractTo(const boost::filesystem::path& dir) const; 146 void UpdateFromDir(const boost::filesystem::path& dir); 147 148 Stcm::File& GetStcm(); 149 150 Libshit::NotNullSharedPtr<TxtSerializable> GetDefaultTxtSerializable( 151 const Libshit::NotNullSharedPtr<Dumpable>& thiz) override; 152 153 void Dispose() noexcept override; 154 155 private: 156 FilePosition data_size; 157 unsigned link_count; 158 159 void Parse_(Source& src); 160 void Dump_(Sink& os) const override; 161 void Inspect_(std::ostream& os, unsigned indent) const override; 162 }; 163 164 void endian_reverse_inplace(Cl3::Header& hdr) noexcept; 165 void endian_reverse_inplace(Cl3::Section& sec) noexcept; 166 void endian_reverse_inplace(Cl3::FileEntry& entry) noexcept; 167 void endian_reverse_inplace(Cl3::LinkEntry& entry) noexcept; 168 } 169 #endif