Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix various crashes #568

Merged
merged 10 commits into from
Jan 28, 2024
2 changes: 1 addition & 1 deletion data/configurables/character_traits.txt
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ army = { # Generals & Field Marshals
logistics = 2
}
pillager = {
trait = { commando }
traits = { commando }
attack = 1
logistics = 1
}
Expand Down
2 changes: 2 additions & 0 deletions data/configurables/unit_mappings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ combat_unit_type_light_tanks = {

pm_no_organization = {}
pm_general_training = {}
pm_training_streamlining = {}
pm_advanced_tactics_training = {}

## Pre-1.5 conversions

Expand Down
7 changes: 6 additions & 1 deletion src/hoi4_world/countries/hoi4_countries_converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,13 @@ std::map<std::string, Country> ConvertCountries(const vic3::World source_world,
ConvoyDistributor convoys = BuildConvoyDistributor("configurables/convoy_config.txt");
convoys.CalculateStateWeights(source_world);

for (const auto& [country_number, source_country]: source_world.GetCountries())
for (const auto& source_country: source_world.GetCountries() | std::views::values)
{
if (source_country.IsDead())
{
continue;
}

std::optional<Country> new_country = ConvertCountry(source_world,
source_country,
source_localizations,
Expand Down
4 changes: 4 additions & 0 deletions src/vic3_world/countries/vic3_country.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ struct CountryOptions
{
int number = 0;
std::string tag;
bool is_dead;
std::optional<std::string> dynamic_name;
std::optional<std::string> dynamic_adjective;
commonItems::Color color;
Expand Down Expand Up @@ -76,6 +77,7 @@ class Country
explicit Country(CountryOptions options):
number_(options.number),
tag_(std::move(options.tag)),
is_dead_(options.is_dead),
dynamic_name_(std::move(options.dynamic_name)),
dynamic_adjective_(std::move(options.dynamic_adjective)),
color_(options.color),
Expand All @@ -102,6 +104,7 @@ class Country

[[nodiscard]] int GetNumber() const { return number_; }
[[nodiscard]] const std::string& GetTag() const { return tag_; }
[[nodiscard]] bool IsDead() const { return is_dead_; }
[[nodiscard]] const std::optional<std::string>& GetDynamicName() const { return dynamic_name_; }
[[nodiscard]] const std::optional<std::string>& GetDynamicAdjective() const { return dynamic_adjective_; }
[[nodiscard]] const commonItems::Color& GetColor() const { return color_; }
Expand Down Expand Up @@ -152,6 +155,7 @@ class Country
private:
int number_ = 0;
std::string tag_;
bool is_dead_;
std::optional<std::string> dynamic_name_;
std::optional<std::string> dynamic_adjective_;
commonItems::Color color_;
Expand Down
18 changes: 10 additions & 8 deletions src/vic3_world/countries/vic3_country_importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,15 @@ vic3::CountryImporter::CountryImporter()
options_.color = commonItems::Color::Factory{}.getColor(input_stream);
});
country_parser_.registerKeyword("capital", [this](std::istream& input_stream) {
options_.capital_state = commonItems::getInt(input_stream);
const int64_t temp_number = commonItems::getLlong(input_stream);
if (temp_number == 4294967295)
{
options_.capital_state = -1;
}
else
{
options_.capital_state = static_cast<int>(temp_number);
}
});
country_parser_.registerKeyword("country_type", [this](std::istream& input_stream) {
options_.country_type = commonItems::getString(input_stream);
Expand Down Expand Up @@ -83,7 +91,7 @@ vic3::CountryImporter::CountryImporter()
});

country_parser_.registerKeyword("dead", [this](std::istream& input_stream) {
is_dead_ = commonItems::getString(input_stream) == "yes";
options_.is_dead = commonItems::getString(input_stream) == "yes";
});

/// ---- counters parser ----
Expand All @@ -107,13 +115,7 @@ std::optional<vic3::Country> vic3::CountryImporter::ImportCountry(const int numb
const std::map<std::string, commonItems::Color>& color_definitions)
{
options_ = {};
is_dead_ = false;

country_parser_.parseStream(input_stream);
if (is_dead_)
{
return std::nullopt;
}

if (options_.color == commonItems::Color())
{
Expand Down
2 changes: 0 additions & 2 deletions src/vic3_world/countries/vic3_country_importer.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ class CountryImporter
commonItems::parser counters_parser_;

CountryOptions options_;

bool is_dead_ = false; // Country marked as invalid data by game, but not yet cleaned up
};

} // namespace vic3
Expand Down
6 changes: 4 additions & 2 deletions src/vic3_world/countries/vic3_country_importer_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ TEST(Vic3WorldCountriesCountryImporter, DefaultsAreDefaulted)

EXPECT_TRUE(country.has_value());
EXPECT_TRUE(country.value_or(Country({})).GetTag().empty());
EXPECT_FALSE(country.value_or(Country({})).IsDead());
EXPECT_FALSE(country.value_or(Country({})).GetDynamicName());
EXPECT_FALSE(country.value_or(Country({})).GetDynamicAdjective());
EXPECT_EQ(country.value_or(Country({})).GetColor(), commonItems::Color(std::array{0, 0, 0}));
Expand Down Expand Up @@ -170,7 +171,7 @@ TEST(Vic3WorldCountriesCountryImporter, IgIdsCanBeAdded)
}


TEST(Vic3WorldCountriesCountryImporter, DeadCountriesAreSkipped)
TEST(Vic3WorldCountriesCountryImporter, DeadCountriesAreImported)
{
std::stringstream input;
input << "={\n";
Expand All @@ -180,7 +181,8 @@ TEST(Vic3WorldCountriesCountryImporter, DeadCountriesAreSkipped)
input << "}";
const auto country = CountryImporter{}.ImportCountry(0, input, {});

EXPECT_FALSE(country.has_value());
EXPECT_TRUE(country.has_value());
EXPECT_TRUE(country.value_or(Country({})).IsDead());
}

TEST(Vic3WorldCountriesCountryImporter, CountersSectionParsed)
Expand Down
4 changes: 3 additions & 1 deletion src/vic3_world/institutions/institutions_importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ void InstitutionsImporter::operator()(std::istream& input_stream)
this->current_institution_ = {};
};

DatabaseParser(elementParser).parseStream(input_stream);
DatabaseParser database_parser(elementParser);
database_parser.registerKeyword("dead", commonItems::ignoreItem);
database_parser.parseStream(input_stream);
}

} // namespace vic3
4 changes: 3 additions & 1 deletion src/vic3_world/laws/laws_importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ std::map<int, std::set<std::string>> vic3::ImportLaws(std::istream& input_stream
}
};

DatabaseParser(law_parser_function).parseStream(input_stream);
DatabaseParser database_parser(law_parser_function);
database_parser.registerKeyword("dead", commonItems::ignoreItem);
database_parser.parseStream(input_stream);

LOG(LogLevel::Info) << fmt::format("\tImported {} active laws.", active_laws);
LOG(LogLevel::Info) << fmt::format("\tImported {} inactive laws.", inactive_laws);
Expand Down
23 changes: 11 additions & 12 deletions src/vic3_world/world/vic3_world_importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,22 +95,19 @@ std::vector<Mod> GetModsFromSave(const std::vector<std::string>& mod_names)

std::istringstream MeltSave(const rakaly::GameFile& save, const std::string& save_string)
{
std::string melted_save_string;
if (save.is_binary())
const auto melt = save.melt();
if (melt.has_unknown_tokens())
{
const auto melt = save.melt();
if (melt.has_unknown_tokens())
{
throw std::runtime_error("Unable to melt ironman save");
}

melt.writeData(melted_save_string);
throw std::runtime_error("Unable to melt ironman save");
}
else

std::string melted_save_string;
melt.writeData(melted_save_string);

if (melted_save_string.empty())
{
melted_save_string = save_string;
return std::istringstream{save_string};
}

return std::istringstream{melted_save_string};
}

Expand Down Expand Up @@ -258,6 +255,7 @@ void AssignMilitaryFormationsToCountries(const std::map<int, vic3::MilitaryForma
if (country == countries.end())
{
Log(LogLevel::Warning) << fmt::format("Could not find country {} to assign army formations.", country_number);
continue;
}
country->second.SetArmyFormations(army_formations);
}
Expand All @@ -267,6 +265,7 @@ void AssignMilitaryFormationsToCountries(const std::map<int, vic3::MilitaryForma
if (country == countries.end())
{
Log(LogLevel::Warning) << fmt::format("Could not find country {} to assign navy formations.", country_number);
continue;
}
country->second.SetNavyFormations(navy_formations);
}
Expand Down
Loading