diff --git a/res/core/messages.xml b/res/core/messages.xml index 766cd481c..d40efb9ac 100644 --- a/res/core/messages.xml +++ b/res/core/messages.xml @@ -5291,6 +5291,7 @@ + diff --git a/res/translations/messages.de.po b/res/translations/messages.de.po index a1d30c85c..776a1e207 100644 --- a/res/translations/messages.de.po +++ b/res/translations/messages.de.po @@ -2370,7 +2370,7 @@ msgid "sp_confusion_effect_0" msgstr "\"$unit($mage) stimmt einen seltsamen Gesang an. Ein plötzlicher Tumult entsteht, der sich jedoch schnell wieder legt.\"" msgid "pest" -msgstr "\"Hier wütete die Pest, und $int($dead) Bauern starben.\"" +msgstr "\"Hier wütete die Pest, und $int($dead) $resource($peasants,$dead) $if($eq($dead,1), \"starb\", \"starben\").\"" msgid "wormhole_exit" msgstr "\"$unit($unit) reist durch ein Wurmloch nach $region($region).\"" diff --git a/res/translations/messages.en.po b/res/translations/messages.en.po index 037b50d4d..9621b3d73 100644 --- a/res/translations/messages.en.po +++ b/res/translations/messages.en.po @@ -2370,7 +2370,7 @@ msgid "sp_confusion_effect_0" msgstr "\"$unit($mage) intones a mysterious chant. There is a sudden hubbub, but order is restored quickly.\"" msgid "pest" -msgstr "\"The region is visited by the plague and $int($dead) peasants died.\"" +msgstr "\"The region is visited by the plague and $int($dead) $resource($$peasants,$dead) died.\"" msgid "wormhole_exit" msgstr "\"$unit($unit) travels through a wormhole to $region($region).\"" diff --git a/res/translations/strings.de.po b/res/translations/strings.de.po index 68f126335..e6931c344 100644 --- a/res/translations/strings.de.po +++ b/res/translations/strings.de.po @@ -571,7 +571,7 @@ msgid "balloon" msgstr "Ballon" msgid "nr_schemes_template" -msgstr "Schemen der Regionen {0} sind erkennbar." +msgstr "Schemen von {0} sind erkennbar." msgid "list_two" msgstr "{0} und {1}" diff --git a/scripts/tests/e2/insects.lua b/scripts/tests/e2/insects.lua index 1898e215c..f5b8a3213 100644 --- a/scripts/tests/e2/insects.lua +++ b/scripts/tests/e2/insects.lua @@ -85,3 +85,30 @@ function test_recruit_in_desert() assert_equal('winter', get_season(get_turn())) assert_equal(2, u.number) end + +function test_ride_through_mountain() + local r1 = region.create(1, 0, "plain") + local r2 = region.create(2, 0, "mountain") + local r3 = region.create(3, 0, "plain") + local f = faction.create("insect") + local u = unit.create(f, r1, 1) + u.name="Hercules" + u:add_order('NACH O O') + u:add_item('horse', 1) + u:set_skill('riding', 1, true) + process_orders() + assert_equal(r3, u.region) +end + +function test_ride_from_mountain() + local r1 = region.create(1, 0, "mountain") + local r2 = region.create(2, 0, "plain") + local r3 = region.create(3, 0, "plain") + local f = faction.create("insect") + local u = unit.create(f, r1, 1) + u:add_order('NACH O O') + u:add_item('horse', 1) + u:set_skill('riding', 1, true) + process_orders() + assert_equal(r2, u.region) +end diff --git a/src/laws.c b/src/laws.c index 7f78ac04b..50d364660 100644 --- a/src/laws.c +++ b/src/laws.c @@ -2181,6 +2181,21 @@ int email_cmd(unit * u, struct order *ord) return 0; } +bool password_wellformed(const char *password) +{ + unsigned char *c = (unsigned char *)password; + int i; + if (!password || password[0]=='\0') { + return false; + } + for (i = 0; c[i] && i != PASSWORD_MAXSIZE; ++i) { + if (!isalnum(c[i])) { + return false; + } + } + return true; +} + int password_cmd(unit * u, struct order *ord) { char pwbuf[PASSWORD_MAXSIZE + 1]; @@ -2194,19 +2209,11 @@ int password_cmd(unit * u, struct order *ord) pwbuf[PASSWORD_MAXSIZE - 1] = '\0'; } - if (s && *s) { - unsigned char *c = (unsigned char *)pwbuf; - int i, r = 0; - - for (i = 0; c[i] && i != PASSWORD_MAXSIZE; ++i) { - if (!isalnum(c[i])) { - c[i] = 'X'; - ++r; - } - } - if (r != 0) { + if (!s || !password_wellformed(s)) { + if (s) { cmistake(u, ord, 283, MSG_EVENT); } + password_generate(pwbuf, PASSWORD_MAXSIZE); } faction_setpassword(u->faction, password_hash(pwbuf, PASSWORD_DEFAULT)); ADDMSG(&u->faction->msgs, msg_message("changepasswd", "value", pwbuf)); diff --git a/src/laws.h b/src/laws.h index 4924a5f6e..a49848ac9 100755 --- a/src/laws.h +++ b/src/laws.h @@ -48,6 +48,7 @@ extern "C" { void sinkships(struct region * r); void do_enter(struct region *r, bool is_final_attempt); bool long_order_allowed(const struct unit *u); + bool password_wellformed(const char *password); int password_cmd(struct unit *u, struct order *ord); int banner_cmd(struct unit *u, struct order *ord); diff --git a/src/laws.test.c b/src/laws.test.c index 5dff45a92..8b92629b2 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -49,37 +49,6 @@ static void test_new_building_can_be_renamed(CuTest * tc) test_teardown(); } -static void test_password_cmd(CuTest * tc) -{ - unit *u; - faction * f; - test_setup(); - u = test_create_unit(f = test_create_faction(NULL), test_create_plain(0, 0)); - - u->thisorder = create_order(K_PASSWORD, f->locale, "abcdefgh"); - password_cmd(u, u->thisorder); - CuAssertPtrNotNull(tc, faction_getpassword(f)); - CuAssertTrue(tc, checkpasswd(f, "abcdefgh")); - CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "changepasswd")); - free_order(u->thisorder); - - u->thisorder = create_order(K_PASSWORD, f->locale, "abc*de*"); - password_cmd(u, u->thisorder); - CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error283")); - CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "changepasswd")); - CuAssertTrue(tc, !checkpasswd(f, "abc*de*")); - CuAssertTrue(tc, checkpasswd(f, "abcXdeX")); - free_order(u->thisorder); - - u->thisorder = create_order(K_PASSWORD, f->locale, "1234567890123456789012345678901234567890"); - password_cmd(u, u->thisorder); - CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error321")); - CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "changepasswd")); - CuAssertTrue(tc, checkpasswd(f, "1234567890123456789012345678901")); - - test_teardown(); -} - static void test_rename_building(CuTest * tc) { region *r; @@ -1949,6 +1918,60 @@ static void test_long_order_on_ocean(CuTest *tc) { test_teardown(); } +static void test_password_cmd(CuTest *tc) { + unit *u; + message *msg; + faction * f; + + CuAssertTrue(tc, password_wellformed("PASSword")); + CuAssertTrue(tc, password_wellformed("1234567")); + CuAssertTrue(tc, !password_wellformed("$password")); + CuAssertTrue(tc, !password_wellformed("no space")); + + test_setup(); + mt_create_error(283); + mt_create_error(321); + mt_create_va(mt_new("changepasswd", NULL), "value:string", MT_NEW_END); + u = test_create_unit(f = test_create_faction(NULL), test_create_plain(0, 0)); + u->thisorder = create_order(K_PASSWORD, f->locale, "password1234", NULL); + password_cmd(u, u->thisorder); + CuAssertTrue(tc, checkpasswd(f, "password1234")); + CuAssertPtrNotNull(tc, msg = test_find_messagetype(f->msgs, "changepasswd")); + free_order(u->thisorder); + test_clear_messages(f); + + u->thisorder = create_order(K_PASSWORD, f->locale, "bad-password", NULL); + password_cmd(u, u->thisorder); + CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error283")); + CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "changepasswd")); + CuAssertTrue(tc, !checkpasswd(f, "password1234")); + free_order(u->thisorder); + test_clear_messages(f); + + u->thisorder = create_order(K_PASSWORD, f->locale, "''", NULL); + password_cmd(u, u->thisorder); + CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error283")); + CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "changepasswd")); + free_order(u->thisorder); + test_clear_messages(f); + + u->thisorder = create_order(K_PASSWORD, f->locale, NULL); + password_cmd(u, u->thisorder); + CuAssertTrue(tc, !checkpasswd(f, "password1234")); + CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error283")); + CuAssertPtrNotNull(tc, msg = test_find_messagetype(f->msgs, "changepasswd")); + free_order(u->thisorder); + test_clear_messages(f); + + u->thisorder = create_order(K_PASSWORD, f->locale, "1234567890123456789012345678901234567890"); + password_cmd(u, u->thisorder); + CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error321")); + CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "changepasswd")); + CuAssertTrue(tc, checkpasswd(f, "1234567890123456789012345678901")); + + test_teardown(); +} + static void test_peasant_migration(CuTest *tc) { region *r1, *r2; int rmax; diff --git a/src/randenc.c b/src/randenc.c index 368a839e9..356c9c695 100644 --- a/src/randenc.c +++ b/src/randenc.c @@ -587,7 +587,8 @@ void plagues(region * r) } if (dead > 0) { - ADDMSG(&r->msgs, msg_message("pest", "dead", dead)); + ADDMSG(&r->msgs, msg_message("pest", "peasants dead", + get_resourcetype(R_PEASANT), dead)); deathcounts(r, dead); rsetpeasants(r, peasants - dead); }