forked from github/server
Merge branch 'develop' of github.com:eressea/server into develop
This commit is contained in:
commit
a2ded29c8a
9 changed files with 168 additions and 40 deletions
|
@ -13,9 +13,13 @@ include(MSVC)
|
||||||
set (HAVE_STRDUP 0)
|
set (HAVE_STRDUP 0)
|
||||||
set (HAVE_STRLCAT 0)
|
set (HAVE_STRLCAT 0)
|
||||||
set (HAVE_LIBBSD 0)
|
set (HAVE_LIBBSD 0)
|
||||||
|
set (HAVE_SIGNAL_H 0)
|
||||||
|
set (HAVE_EXECINFO_H 0)
|
||||||
else (MSVC)
|
else (MSVC)
|
||||||
|
|
||||||
INCLUDE (CheckIncludeFile)
|
INCLUDE (CheckIncludeFile)
|
||||||
|
CHECK_INCLUDE_FILE(signal.h HAVE_SIGNAL_H)
|
||||||
|
CHECK_INCLUDE_FILE(execinfo.h HAVE_EXECINFO_H)
|
||||||
CHECK_INCLUDE_FILE(bsd/string.h HAVE_LIBBSD)
|
CHECK_INCLUDE_FILE(bsd/string.h HAVE_LIBBSD)
|
||||||
|
|
||||||
INCLUDE (CheckFunctionExists)
|
INCLUDE (CheckFunctionExists)
|
||||||
|
|
|
@ -261,6 +261,10 @@ add_test(server test_eressea)
|
||||||
|
|
||||||
install(TARGETS eressea DESTINATION "bin")
|
install(TARGETS eressea DESTINATION "bin")
|
||||||
|
|
||||||
|
if (HAVE_EXECINFO_H AND HAVE_SIGNAL_H)
|
||||||
|
add_definitions(-DHAVE_BACKTRACE)
|
||||||
|
endif ()
|
||||||
|
|
||||||
if (HAVE_LIBBSD)
|
if (HAVE_LIBBSD)
|
||||||
add_definitions(-DHAVE_LIBBSD)
|
add_definitions(-DHAVE_LIBBSD)
|
||||||
endif (HAVE_LIBBSD)
|
endif (HAVE_LIBBSD)
|
||||||
|
|
|
@ -67,8 +67,6 @@ keyword_t getkeyword(const order * ord)
|
||||||
* keywords are expanded to their full length.
|
* keywords are expanded to their full length.
|
||||||
*/
|
*/
|
||||||
char* get_command(const order *ord, const struct locale *lang, char *sbuffer, size_t size) {
|
char* get_command(const order *ord, const struct locale *lang, char *sbuffer, size_t size) {
|
||||||
order_data *od = NULL;
|
|
||||||
const char * text;
|
|
||||||
keyword_t kwd = ORD_KEYWORD(ord);
|
keyword_t kwd = ORD_KEYWORD(ord);
|
||||||
sbstring sbs;
|
sbstring sbs;
|
||||||
|
|
||||||
|
@ -80,28 +78,35 @@ char* get_command(const order *ord, const struct locale *lang, char *sbuffer, si
|
||||||
sbs_strcat(&sbs, "@");
|
sbs_strcat(&sbs, "@");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ord->id < 0) {
|
|
||||||
skill_t sk = (skill_t)(100+ord->id);
|
|
||||||
assert(kwd == K_STUDY && sk != SK_MAGIC && sk < MAXSKILLS);
|
|
||||||
text = skillname(sk, lang);
|
|
||||||
} else {
|
|
||||||
od = odata_load(ord->id);
|
|
||||||
text = OD_STRING(od);
|
|
||||||
}
|
|
||||||
if (kwd != NOKEYWORD) {
|
if (kwd != NOKEYWORD) {
|
||||||
const char *str = (const char *)LOC(lang, keyword(kwd));
|
const char *str = (const char *)LOC(lang, keyword(kwd));
|
||||||
assert(str);
|
assert(str);
|
||||||
sbs_strcat(&sbs, str);
|
sbs_strcat(&sbs, str);
|
||||||
if (text) {
|
if (ord->id < 0) {
|
||||||
sbs_strcat(&sbs, " ");
|
skill_t sk = (skill_t)(100+ord->id);
|
||||||
|
assert(kwd == K_STUDY && sk != SK_MAGIC && sk < MAXSKILLS);
|
||||||
|
str = skillname(sk, lang);
|
||||||
|
if (str) {
|
||||||
|
if (strchr(str, ' ') == NULL) {
|
||||||
|
sbs_strcat(&sbs, " ");
|
||||||
|
sbs_strcat(&sbs, str);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sbs_strcat(&sbs, " '");
|
||||||
|
sbs_strcat(&sbs, str);
|
||||||
|
sbs_strcat(&sbs, "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
order_data *od = odata_load(ord->id);
|
||||||
|
str = OD_STRING(od);
|
||||||
|
if (str) {
|
||||||
|
sbs_strcat(&sbs, " ");
|
||||||
|
sbs_strcat(&sbs, str);
|
||||||
|
}
|
||||||
|
odata_release(od);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (text) {
|
|
||||||
sbs_strcat(&sbs, text);
|
|
||||||
}
|
|
||||||
if (od) {
|
|
||||||
odata_release(od);
|
|
||||||
}
|
|
||||||
return sbuffer;
|
return sbuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,30 +123,38 @@ int stream_order(struct stream *out, const struct order *ord, const struct local
|
||||||
swrite("@", 1, 1, out);
|
swrite("@", 1, 1, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ord->id < 0) {
|
|
||||||
skill_t sk = (skill_t)(100 + ord->id);
|
|
||||||
assert(kwd == K_STUDY && sk != SK_MAGIC && sk < MAXSKILLS);
|
|
||||||
text = skillname(sk, lang);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
od = odata_load(ord->id);
|
|
||||||
text = OD_STRING(od);
|
|
||||||
}
|
|
||||||
if (kwd != NOKEYWORD) {
|
if (kwd != NOKEYWORD) {
|
||||||
const char *str = (const char *)LOC(lang, keyword(kwd));
|
const char *str = (const char *)LOC(lang, keyword(kwd));
|
||||||
assert(str);
|
assert(str);
|
||||||
swrite(str, 1, strlen(str), out);
|
swrite(str, 1, strlen(str), out);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (text) {
|
if (ord->id < 0) {
|
||||||
char obuf[1024];
|
skill_t sk = (skill_t)(100 + ord->id);
|
||||||
swrite(" ", 1, 1, out);
|
|
||||||
if (escape) {
|
assert(kwd == K_STUDY && sk != SK_MAGIC && sk < MAXSKILLS);
|
||||||
text = str_escape(text, obuf, sizeof(obuf));
|
text = skillname(sk, lang);
|
||||||
|
if (strchr(text, ' ') != NULL) {
|
||||||
|
swrite(" '", 1, 2, out);
|
||||||
|
swrite(text, 1, strlen(text), out);
|
||||||
|
swrite("'", 1, 1, out);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
swrite(" ", 1, 1, out);
|
||||||
|
swrite(text, 1, strlen(text), out);
|
||||||
}
|
}
|
||||||
swrite(text, 1, strlen(text), out);
|
|
||||||
}
|
}
|
||||||
if (od) {
|
else {
|
||||||
|
od = odata_load(ord->id);
|
||||||
|
text = OD_STRING(od);
|
||||||
|
if (text) {
|
||||||
|
char obuf[1024];
|
||||||
|
swrite(" ", 1, 1, out);
|
||||||
|
if (escape) {
|
||||||
|
text = str_escape(text, obuf, sizeof(obuf));
|
||||||
|
}
|
||||||
|
swrite(text, 1, strlen(text), out);
|
||||||
|
}
|
||||||
odata_release(od);
|
odata_release(od);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,11 +527,27 @@ keyword_t init_order(const struct order *ord, const struct locale *lang)
|
||||||
parser_od = NULL;
|
parser_od = NULL;
|
||||||
}
|
}
|
||||||
if (ord->id < 0) {
|
if (ord->id < 0) {
|
||||||
|
const char *str;
|
||||||
skill_t sk = (skill_t)(100 + ord->id);
|
skill_t sk = (skill_t)(100 + ord->id);
|
||||||
|
|
||||||
assert(sk < MAXSKILLS);
|
assert(sk < MAXSKILLS);
|
||||||
assert(lang);
|
assert(lang);
|
||||||
assert(kwd == K_STUDY);
|
assert(kwd == K_STUDY);
|
||||||
init_tokens_str(skillname(sk, lang));
|
str = skillname(sk, lang);
|
||||||
|
if (strchr(str, ' ') == NULL) {
|
||||||
|
init_tokens_str(str);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
char token[32], *dup;
|
||||||
|
size_t len = strlen(str);
|
||||||
|
assert(len + 3 < sizeof(token));
|
||||||
|
token[0] = '\'';
|
||||||
|
memcpy(token + 1, str, len);
|
||||||
|
token[len + 1] = '\'';
|
||||||
|
token[len + 2] = '\0';
|
||||||
|
dup = str_strdup(token);
|
||||||
|
init_tokens_ex(dup, dup, free);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const char *str;
|
const char *str;
|
||||||
|
|
|
@ -3,10 +3,14 @@
|
||||||
#include "order.h"
|
#include "order.h"
|
||||||
|
|
||||||
#include <kernel/skills.h>
|
#include <kernel/skills.h>
|
||||||
|
#include <kernel/unit.h>
|
||||||
|
|
||||||
#include <util/parser.h>
|
#include <util/parser.h>
|
||||||
#include <util/language.h>
|
#include <util/language.h>
|
||||||
|
|
||||||
|
#include <stream.h>
|
||||||
|
#include <memstream.h>
|
||||||
|
|
||||||
#include <tests.h>
|
#include <tests.h>
|
||||||
#include <CuTest.h>
|
#include <CuTest.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -331,11 +335,73 @@ static void test_study_orders(CuTest *tc) {
|
||||||
test_teardown();
|
test_teardown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_study_order(CuTest *tc) {
|
||||||
|
char token[32];
|
||||||
|
stream out;
|
||||||
|
unit *u;
|
||||||
|
struct locale *lang;
|
||||||
|
|
||||||
|
test_setup();
|
||||||
|
lang = get_or_create_locale("de");
|
||||||
|
locale_setstring(lang, mkname("skill", skillnames[SK_ALCHEMY]), "Alchemie");
|
||||||
|
locale_setstring(lang, "keyword::study", "LERNE");
|
||||||
|
init_keywords(lang);
|
||||||
|
init_skills(lang);
|
||||||
|
u = test_create_unit(test_create_faction(NULL), test_create_plain(0, 0));
|
||||||
|
u->thisorder = create_order(K_STUDY, lang, "ALCH");
|
||||||
|
CuAssertIntEquals(tc, K_STUDY, init_order(u->thisorder, lang));
|
||||||
|
CuAssertStrEquals(tc, skillname(SK_ALCHEMY, lang), gettoken(token, sizeof(token)));
|
||||||
|
|
||||||
|
CuAssertStrEquals(tc, "LERNE Alchemie", get_command(u->thisorder, lang, token, sizeof(token)));
|
||||||
|
|
||||||
|
mstream_init(&out);
|
||||||
|
stream_order(&out, u->thisorder, lang, true);
|
||||||
|
swrite("\n", 1, 1, &out);
|
||||||
|
out.api->rewind(out.handle);
|
||||||
|
out.api->readln(out.handle, token, sizeof(token));
|
||||||
|
CuAssertStrEquals(tc, "LERNE Alchemie", token);
|
||||||
|
mstream_done(&out);
|
||||||
|
|
||||||
|
test_teardown();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_study_order_quoted(CuTest *tc) {
|
||||||
|
char token[32];
|
||||||
|
stream out;
|
||||||
|
unit *u;
|
||||||
|
struct locale *lang;
|
||||||
|
|
||||||
|
test_setup();
|
||||||
|
lang = get_or_create_locale("de");
|
||||||
|
locale_setstring(lang, mkname("skill", skillnames[SK_WEAPONLESS]), "Waffenloser Kampf");
|
||||||
|
locale_setstring(lang, "keyword::study", "LERNE");
|
||||||
|
init_keywords(lang);
|
||||||
|
init_skills(lang);
|
||||||
|
u = test_create_unit(test_create_faction(NULL), test_create_plain(0, 0));
|
||||||
|
u->thisorder = create_order(K_STUDY, lang, "Waffenloser~Kampf");
|
||||||
|
CuAssertIntEquals(tc, K_STUDY, init_order(u->thisorder, lang));
|
||||||
|
CuAssertStrEquals(tc, skillname(SK_WEAPONLESS, lang), gettoken(token, sizeof(token)));
|
||||||
|
|
||||||
|
CuAssertStrEquals(tc, "LERNE 'Waffenloser Kampf'", get_command(u->thisorder, lang, token, sizeof(token)));
|
||||||
|
|
||||||
|
mstream_init(&out);
|
||||||
|
stream_order(&out, u->thisorder, lang, true);
|
||||||
|
swrite("\n", 1, 1, &out);
|
||||||
|
out.api->rewind(out.handle);
|
||||||
|
out.api->readln(out.handle, token, sizeof(token));
|
||||||
|
CuAssertStrEquals(tc, "LERNE 'Waffenloser Kampf'", token);
|
||||||
|
mstream_done(&out);
|
||||||
|
|
||||||
|
test_teardown();
|
||||||
|
}
|
||||||
|
|
||||||
CuSuite *get_order_suite(void)
|
CuSuite *get_order_suite(void)
|
||||||
{
|
{
|
||||||
CuSuite *suite = CuSuiteNew();
|
CuSuite *suite = CuSuiteNew();
|
||||||
SUITE_ADD_TEST(suite, test_create_order);
|
SUITE_ADD_TEST(suite, test_create_order);
|
||||||
SUITE_ADD_TEST(suite, test_study_orders);
|
SUITE_ADD_TEST(suite, test_study_orders);
|
||||||
|
SUITE_ADD_TEST(suite, test_study_order);
|
||||||
|
SUITE_ADD_TEST(suite, test_study_order_quoted);
|
||||||
SUITE_ADD_TEST(suite, test_parse_order);
|
SUITE_ADD_TEST(suite, test_parse_order);
|
||||||
SUITE_ADD_TEST(suite, test_parse_make);
|
SUITE_ADD_TEST(suite, test_parse_make);
|
||||||
SUITE_ADD_TEST(suite, test_parse_make_temp);
|
SUITE_ADD_TEST(suite, test_parse_make_temp);
|
||||||
|
|
|
@ -1418,7 +1418,7 @@ int read_game(gamedata *data)
|
||||||
read_attribs(data, &global.attribs, NULL);
|
read_attribs(data, &global.attribs, NULL);
|
||||||
READ_INT(store, &turn);
|
READ_INT(store, &turn);
|
||||||
log_debug(" - reading turn %d", turn);
|
log_debug(" - reading turn %d", turn);
|
||||||
rng_init(turn);
|
rng_init(turn + config_get_int("game.seed", 0));
|
||||||
READ_INT(store, NULL); /* max_unique_id = ignore */
|
READ_INT(store, NULL); /* max_unique_id = ignore */
|
||||||
READ_INT(store, &nextborder);
|
READ_INT(store, &nextborder);
|
||||||
|
|
||||||
|
|
10
src/laws.c
10
src/laws.c
|
@ -141,7 +141,15 @@ bool IsImmune(const faction * f)
|
||||||
|
|
||||||
int NMRTimeout(void)
|
int NMRTimeout(void)
|
||||||
{
|
{
|
||||||
return config_get_int("nmr.timeout", 0);
|
int nmr_timeout = config_get_int("nmr.timeout", 0);
|
||||||
|
int ini_timeout = config_get_int("game.maxnmr", 0);
|
||||||
|
if (nmr_timeout > 0) {
|
||||||
|
if (ini_timeout > nmr_timeout) {
|
||||||
|
return nmr_timeout;
|
||||||
|
}
|
||||||
|
return (ini_timeout > 0) ? ini_timeout : nmr_timeout;
|
||||||
|
}
|
||||||
|
return ini_timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LongHunger(const struct unit *u)
|
bool LongHunger(const struct unit *u)
|
||||||
|
|
|
@ -1745,6 +1745,20 @@ static void test_cansee_sphere(CuTest *tc) {
|
||||||
test_teardown();
|
test_teardown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_nmr_timeout(CuTest *tc) {
|
||||||
|
test_setup();
|
||||||
|
CuAssertIntEquals(tc, 0, NMRTimeout());
|
||||||
|
config_set_int("nmr.timeout", 5);
|
||||||
|
CuAssertIntEquals(tc, 5, NMRTimeout());
|
||||||
|
config_set_int("game.maxnmr", 4);
|
||||||
|
CuAssertIntEquals(tc, 4, NMRTimeout());
|
||||||
|
config_set("nmr.timeout", NULL);
|
||||||
|
CuAssertIntEquals(tc, 4, NMRTimeout());
|
||||||
|
config_set("game.maxnmr", NULL);
|
||||||
|
CuAssertIntEquals(tc, 0, NMRTimeout());
|
||||||
|
test_teardown();
|
||||||
|
}
|
||||||
|
|
||||||
CuSuite *get_laws_suite(void)
|
CuSuite *get_laws_suite(void)
|
||||||
{
|
{
|
||||||
CuSuite *suite = CuSuiteNew();
|
CuSuite *suite = CuSuiteNew();
|
||||||
|
@ -1816,6 +1830,7 @@ CuSuite *get_laws_suite(void)
|
||||||
SUITE_ADD_TEST(suite, test_cansee);
|
SUITE_ADD_TEST(suite, test_cansee);
|
||||||
SUITE_ADD_TEST(suite, test_cansee_ring);
|
SUITE_ADD_TEST(suite, test_cansee_ring);
|
||||||
SUITE_ADD_TEST(suite, test_cansee_sphere);
|
SUITE_ADD_TEST(suite, test_cansee_sphere);
|
||||||
|
SUITE_ADD_TEST(suite, test_nmr_timeout);
|
||||||
|
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,8 +83,10 @@ static void load_inifile(void)
|
||||||
static const char * valid_keys[] = {
|
static const char * valid_keys[] = {
|
||||||
"game.id",
|
"game.id",
|
||||||
"game.deadlog",
|
"game.deadlog",
|
||||||
|
"game.maxnmr",
|
||||||
"game.name",
|
"game.name",
|
||||||
"game.start",
|
"game.start",
|
||||||
|
"game.seed",
|
||||||
"game.locale",
|
"game.locale",
|
||||||
"game.verbose",
|
"game.verbose",
|
||||||
"game.report",
|
"game.report",
|
||||||
|
@ -257,7 +259,7 @@ static int parse_args(int argc, char **argv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_SIGACTION) && defined(HAVE_EXECINFO)
|
#ifdef HAVE_BACKTRACE
|
||||||
#include <execinfo.h>
|
#include <execinfo.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
|
@ -278,7 +280,7 @@ static int setup_signal_handler(void)
|
||||||
{
|
{
|
||||||
struct sigaction act;
|
struct sigaction act;
|
||||||
|
|
||||||
act.sa_flags = SA_ONESHOT | SA_SIGINFO;
|
act.sa_flags = SA_RESETHAND | SA_SIGINFO;
|
||||||
act.sa_sigaction = report_segfault;
|
act.sa_sigaction = report_segfault;
|
||||||
sigfillset(&act.sa_mask);
|
sigfillset(&act.sa_mask);
|
||||||
return sigaction(SIGSEGV, &act, NULL);
|
return sigaction(SIGSEGV, &act, NULL);
|
||||||
|
|
2
storage
2
storage
|
@ -1 +1 @@
|
||||||
Subproject commit d807ef5ce64b3425b31fb440e0b93a4d233f517a
|
Subproject commit 5623ee6527e97af20c7d8efc03800b6fe1579744
|
Loading…
Reference in a new issue