scraps

Abandon all hope, ye who enter here.
git clone https://git.neptards.moe/neptards/scraps.git
Log | Files | Refs | Submodules | README | LICENSE

sql_importer_character.cpp (10402B)


      1 #include "scraps/format/rags_sql/sql_importer_private.hpp" // IWYU pragma: associated
      2 
      3 #include "scraps/format/rags_common/description.hpp"
      4 #include "scraps/format/rags_sql/test_helper/sql_helper.hpp"
      5 
      6 #include <libshit/char_utils.hpp>
      7 #include <libshit/doctest.hpp>
      8 #include <libshit/utils.hpp>
      9 
     10 #define LIBSHIT_LOG_NAME "import"
     11 #include <libshit/logger_helper.hpp>
     12 
     13 namespace Scraps::Format::RagsSql
     14 {
     15   using namespace std::string_literals;
     16   using namespace Libshit::NonowningStringLiterals;
     17   TEST_SUITE_BEGIN("Scraps::Format::RagsSql");
     18 
     19   void Importer::ImportPlayer(Proto::Character::Builder player)
     20   {
     21     SCRAPS_FORMAT_SQL_SIMPLE_SELECT(
     22       sql, "Player", SCRAPS_FORMAT_RAGS_PLAYER_MEMBERS
     23       SCRAPS_FORMAT_RAGS_PLAYER_TO_GAME_MEMBERS);
     24 
     25     sql.AssertHasRow();
     26     SCRAPS_FORMAT_RAGS_SQL_IMPORT(player, SCRAPS_FORMAT_RAGS_PLAYER_MEMBERS);
     27     SCRAPS_FORMAT_RAGS_SQL_IMPORT(game, SCRAPS_FORMAT_RAGS_PLAYER_TO_GAME_MEMBERS);
     28     sql.AssertNoRow();
     29     FinishPlayer(player);
     30 
     31     auto act_count = sql.GetCount("PlayerActions"_ns);
     32     auto acts = player.InitActions(act_count);
     33 
     34     IdMap act_ids;
     35     std::map<std::uint64_t, std::string> parent_ids;
     36 
     37     sql.Query("SELECT [Data] FROM [PlayerActions];"_ns, 1);
     38     for (std::uint32_t i = 0; i < act_count; ++i)
     39     {
     40       sql.AssertHasRow();
     41 
     42       auto doc = PrepareAction(sql.GetWString());
     43       ImportAction(acts[i], act_ids, parent_ids, *doc);
     44     }
     45     sql.AssertNoRow();
     46 
     47     for (std::uint32_t i = 0; i < act_count; ++i)
     48       if (auto it = parent_ids.find(acts[i].GetId()); it != parent_ids.end())
     49         acts[i].SetParentId(FindId(act_ids, it->second, "action", "None"));
     50 
     51     std::map<std::string, std::string, AsciiCaseLess> props_map;
     52     sql.Query("SELECT [Name], [Value] FROM [PlayerProperties];", 2);
     53     while (sql.HasRow())
     54     {
     55       auto name = sql.GetWString();
     56       auto val = sql.GetWString();
     57       auto [it, inserted] =
     58         props_map.try_emplace(Libshit::Move(name), Libshit::Move(val));
     59       if (!inserted)
     60         WARN << "Duplicate property " << Libshit::Quoted(name)
     61              << " in player, values " << Libshit::Quoted(it->second) << " vs "
     62              << Libshit::Quoted(val) << ", latter ignored" << std::endl;
     63     }
     64 
     65     auto props = player.InitProperties(SCRAPS_CAPNP_LIST_LEN(props_map.size()));
     66     std::uint32_t i = 0;
     67     for (auto&& [k,v] : props_map)
     68     {
     69       props[i].SetName(sp.InternCopy(k));
     70       props[i].SetValue(sp.InternString(Libshit::Move(v)));
     71       ++i;
     72     }
     73   }
     74 
     75   void Importer::ImportCharacters()
     76   {
     77     NameSet id_set;
     78     auto chars = game.InitCharacters(
     79       SCRAPS_CAPNP_LIST_LEN(character_ids.size() + 1));
     80     ImportPlayer(chars[0]);
     81 
     82     auto props = GetProperties("CharacterProperties", "Charname");
     83 
     84     SCRAPS_FORMAT_SQL_SIMPLE_SELECT(
     85       sql, "Characters", SCRAPS_FORMAT_RAGS_CHARACTER_MEMBERS);
     86     for (std::uint32_t i = 1, n = character_ids.size(); i < n; ++i)
     87     {
     88       sql.AssertHasRow();
     89       SCRAPS_FORMAT_RAGS_SQL_IMPORT(
     90         chars[i], SCRAPS_FORMAT_RAGS_CHARACTER_MEMBERS);
     91 
     92       chars[i].SetId(character_ids.at(sp.Get(chars[i].GetName())));
     93       ApplyProperties(props, chars[i], sp.Get(chars[i].GetName()));
     94     }
     95     sql.AssertNoRow();
     96 
     97     ImportActions(
     98       chars, "CharacterActions", "Charname", "character", character_ids);
     99     FinishProperties(props, "character");
    100   }
    101 
    102   TEST_CASE("ImportCharacters")
    103   {
    104     using C = Memory::Cell;
    105     TestHelper::TestSqls([](Sql& sql, Memory::DB& db)
    106     {
    107       db.tables["Player"] = {
    108         {
    109           { "Name", Memory::Type::NVARCHAR, 250 },
    110           { "Description", Memory::Type::NTEXT },
    111           { "StartingRoom", Memory::Type::NVARCHAR, 250 },
    112           { "PlayerGender", Memory::Type::INT },
    113           { "PromptForName", Memory::Type::BIT },
    114           { "PromptForGender", Memory::Type::BIT },
    115           { "PlayerPortrait", Memory::Type::NVARCHAR, 250 },
    116           { "EnforceWeight", Memory::Type::BIT },
    117           { "WeightLimit", Memory::Type::FLOAT },
    118         }, {
    119           { C::Ntext("John"), C::Ntext("Description..."),
    120             C::Ntext("00000000000000000000000000000123"), C::Int(1),
    121             C::Bit(true), C::Bit(true), C::Ntext("media0"), C::Bit(true),
    122             C::Float(3.14) },
    123         }
    124       };
    125       db.tables["PlayerActions"] = {
    126         {
    127           { "Data", Memory::Type::NTEXT },
    128         }, {
    129           // <x><Name>Test</Name></x>
    130           { C::Ntext("GAAAAB+LCABKkRhgAgOzqbCz8UvMTbULSS0usdEHM230K+wAg3dN9RgAAAA=") },
    131           { C::Ntext("<x><Name>Test2</Name></x>") },
    132         }
    133       };
    134       db.tables["PlayerProperties"] = {
    135         {
    136           { "Name", Memory::Type::NVARCHAR, 250 },
    137           { "Value", Memory::Type::NTEXT },
    138         }, {
    139           { C::Ntext("xyz"), C::Ntext("abc") },
    140           { C::Ntext("abc"), C::Ntext("val") },
    141           { C::Ntext("abc"), C::Ntext("ignored") },
    142         }
    143       };
    144 
    145       db.tables["Characters"] = {
    146         {
    147           { "Charname", Memory::Type::NVARCHAR, 250 },
    148           { "CharnameOverride", Memory::Type::NVARCHAR, 250 },
    149           { "CharGender", Memory::Type::INT },
    150           { "CurrentRoom", Memory::Type::NVARCHAR, 250 },
    151           { "Description", Memory::Type::NTEXT },
    152           { "AllowInventoryInteraction", Memory::Type::BIT },
    153           { "CharPortrait", Memory::Type::NVARCHAR, 250 },
    154         }, {
    155           { C::Ntext("player"), C::Ntext("override"), C::Int(0),
    156             C::Ntext("r00m"), C::Ntext("desc"),
    157             C::Bit(true), C::Ntext("") },
    158           { C::Ntext("char1"), C::Ntext(""), C::Int(2),
    159             C::Ntext(Uuid::VOID_ROOM_STR), C::Ntext("foofoofoo"), C::Bit(false),
    160             C::Ntext("media1") },
    161         }
    162       };
    163       db.tables["CharacterActions"] = {
    164         {
    165           { "Charname", Memory::Type::NVARCHAR, 250 },
    166           { "Data", Memory::Type::NTEXT },
    167         }, {
    168           { C::Ntext("player"),
    169             C::Ntext("GAAAAB+LCABKkRhgAgOzqbCz8UvMTbULSS0usdEHM230K+wAg3dN9RgAAAA=") },
    170         }
    171       };
    172       db.tables["CharacterProperties"] = {
    173         {
    174           { "Charname", Memory::Type::NVARCHAR, 250 },
    175           { "Name", Memory::Type::NVARCHAR, 250 },
    176           { "Value", Memory::Type::NTEXT },
    177         }, {
    178           { C::Ntext("char1"), C::Ntext("xyz"), C::Ntext("abc") },
    179           { C::Ntext("char1"), C::Ntext("abc"), C::Ntext("val") },
    180           { C::Ntext("char1"), C::Ntext("abc"), C::Ntext("ignored") },
    181         }
    182       };
    183 
    184       Importer imp{sql};
    185       imp.file_ids = {{"media0", imp.GetId()}, {"media1", imp.GetId()}}; // 2-3
    186       auto rid = imp.GetId(); // 4
    187       imp.room_uuids = {{{0,0x123}, rid}};
    188       imp.room_ids = {{"r00m", rid}};
    189       imp.GenIds(imp.character_ids, "Characters", "Charname"); // 5-6
    190 
    191       imp.ImportCharacters(); // player act: 7-8, chara act: 9
    192       CHECK(imp.game.GetPromptName());
    193       CHECK(imp.game.GetPromptGender());
    194 
    195       auto chars = imp.game.GetCharacters();
    196       REQUIRE(chars.size() == 3);
    197       CHECK(chars[0].GetId() == 1);
    198       CHECK(imp.sp.Get(chars[0].GetName()) == "player_conflict0");
    199       CHECK(imp.sp.Get(chars[0].GetNameOverride()) == "John");
    200       CHECK(imp.sp.Get(chars[0].GetDescription()) == "Description...");
    201       CHECK(chars[0].GetGender() == Proto::Gender::FEMALE);
    202       CHECK(chars[0].GetImageId() == 2);
    203       CHECK(chars[0].GetRoomId() == 4);
    204       CHECK(!chars[0].GetAllowInventoryInteraction());
    205       CHECK(chars[0].GetEnforceWeightLimit());
    206       CHECK(double(chars[0].GetWeightLimit()) == doctest::Approx(3.14));
    207 
    208       REQUIRE(chars[0].GetActions().size() == 2);
    209       CHECK(chars[0].GetActions()[0].GetId() == 7);
    210       CHECK(imp.sp.Get(chars[0].GetActions()[0].GetName()) == "Test");
    211       CHECK(chars[0].GetActions()[1].GetId() == 8);
    212       CHECK(imp.sp.Get(chars[0].GetActions()[1].GetName()) == "Test2");
    213 
    214       REQUIRE(chars[0].GetProperties().size() == 2);
    215       CHECK(imp.sp.Get(chars[0].GetProperties()[0].GetName()) == "abc");
    216       CHECK(imp.sp.Get(chars[0].GetProperties()[0].GetValue()) == "val");
    217       CHECK(imp.sp.Get(chars[0].GetProperties()[1].GetName()) == "xyz");
    218       CHECK(imp.sp.Get(chars[0].GetProperties()[1].GetValue()) == "abc");
    219 
    220 
    221       CHECK(chars[1].GetId() == 5);
    222       CHECK(imp.sp.Get(chars[1].GetName()) == "player");
    223       CHECK(imp.sp.Get(chars[1].GetNameOverride()) == "override");
    224       CHECK(imp.sp.Get(chars[1].GetDescription()) == "desc");
    225       CHECK(chars[1].GetGender() == Proto::Gender::MALE);
    226       CHECK(chars[1].GetImageId() == 0);
    227       CHECK(chars[1].GetRoomId() == 4);
    228       CHECK(chars[1].GetAllowInventoryInteraction());
    229       CHECK(!chars[1].GetEnforceWeightLimit());
    230       CHECK(chars[1].GetWeightLimit() == 0);
    231 
    232       REQUIRE(chars[1].GetActions().size() == 1);
    233       CHECK(chars[1].GetActions()[0].GetId() == 9);
    234       CHECK(imp.sp.Get(chars[1].GetActions()[0].GetName()) == "Test");
    235       REQUIRE(chars[1].GetProperties().size() == 0);
    236 
    237 
    238       CHECK(chars[2].GetId() == 6);
    239       CHECK(imp.sp.Get(chars[2].GetName()) == "char1");
    240       CHECK(imp.sp.Get(chars[2].GetNameOverride()) == "");
    241       CHECK(imp.sp.Get(chars[2].GetDescription()) == "foofoofoo");
    242       CHECK(chars[2].GetGender() == Proto::Gender::OTHER);
    243       CHECK(chars[2].GetImageId() == 3);
    244       CHECK(chars[2].GetRoomId() == 0);
    245       CHECK(!chars[2].GetAllowInventoryInteraction());
    246       CHECK(!chars[2].GetEnforceWeightLimit());
    247       CHECK(chars[2].GetWeightLimit() == 0);
    248 
    249       REQUIRE(chars[2].GetActions().size() == 0);
    250       REQUIRE(chars[2].GetProperties().size() == 2);
    251       CHECK(imp.sp.Get(chars[2].GetProperties()[0].GetName()) == "abc");
    252       CHECK(imp.sp.Get(chars[2].GetProperties()[0].GetValue()) == "val");
    253       CHECK(imp.sp.Get(chars[2].GetProperties()[1].GetName()) == "xyz");
    254       CHECK(imp.sp.Get(chars[2].GetProperties()[1].GetValue()) == "abc");
    255 
    256       // sort chara
    257       auto alpha = RagsCommon::SortOrder::ALPHA;
    258       imp.FinishGame(alpha, alpha, alpha);
    259 
    260       CHECK(chars[0].GetId() == 1);
    261       CHECK(imp.sp.Get(chars[0].GetName()) == "player_conflict0");
    262       CHECK(imp.sp.Get(chars[0].GetNameOverride()) == "John");
    263       CHECK(chars[1].GetId() == 5);
    264       CHECK(imp.sp.Get(chars[1].GetName()) == "char1");
    265       CHECK(imp.sp.Get(chars[1].GetNameOverride()) == "");
    266       CHECK(chars[2].GetId() == 6);
    267       CHECK(imp.sp.Get(chars[2].GetName()) == "player");
    268       CHECK(imp.sp.Get(chars[2].GetNameOverride()) == "override");
    269     });
    270   }
    271 
    272   TEST_SUITE_END();
    273 }