Merge pull request #197 from badgerman/bug-2070-negative-origin

Bug 2070: negative origin crashes the server
This commit is contained in:
Enno Rehling 2015-05-20 11:09:08 +02:00
commit 4607515e24
15 changed files with 98 additions and 49 deletions

View File

@ -58,7 +58,7 @@
<order name="tax" disable="yes"/> <order name="tax" disable="yes"/>
<order name="entertain" disable="yes"/> <order name="entertain" disable="yes"/>
<order name="sell" disable="yes"/> <order name="sell" disable="yes"/>
<order name="origin" disable="yes"/> <order name="origin" disable="no"/>
<skill name="armorer" enable="true"/> <skill name="armorer" enable="true"/>
<skill name="bow" enable="true"/> <skill name="bow" enable="true"/>

View File

@ -21,6 +21,7 @@ IF(CMAKE_COMPILER_IS_GNUCC)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion -Wno-sign-conversion") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion -Wno-sign-conversion")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic -Wsign-compare -Wall -Werror -Wno-unknown-pragmas -Wstrict-prototypes -Wpointer-arith -Wno-char-subscripts -Wno-long-long") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic -Wsign-compare -Wall -Werror -Wno-unknown-pragmas -Wstrict-prototypes -Wpointer-arith -Wno-char-subscripts -Wno-long-long")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=unused-but-set-variable")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -DHAVE__BOOL") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -DHAVE__BOOL")
elseif(MSVC) elseif(MSVC)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Wall /WX /MP") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Wall /WX /MP")

View File

@ -282,7 +282,7 @@ static int tolua_faction_normalize(lua_State * L)
plane *pl = rplane(r); plane *pl = rplane(r);
int nx = r->x, ny = r->y; int nx = r->x, ny = r->y;
pnormalize(&nx, &ny, pl); pnormalize(&nx, &ny, pl);
adjust_coordinates(f, &nx, &ny, pl, r); adjust_coordinates(f, &nx, &ny, pl);
tolua_pushnumber(L, (lua_Number)nx); tolua_pushnumber(L, (lua_Number)nx);
tolua_pushnumber(L, (lua_Number)ny); tolua_pushnumber(L, (lua_Number)ny);
return 2; return 2;
@ -297,7 +297,7 @@ static int tolua_faction_set_origin(lua_State * L)
plane *pl = rplane(r); plane *pl = rplane(r);
int id = pl ? pl->id : 0; int id = pl ? pl->id : 0;
set_origin(f, id, r->x - plane_center_x(pl), r->y - plane_center_y(pl)); faction_setorigin(f, id, r->x - plane_center_x(pl), r->y - plane_center_y(pl));
return 0; return 0;
} }

View File

@ -317,7 +317,7 @@ static int cr_region(variant var, char *buffer, const void *userdata)
plane *pl = rplane(r); plane *pl = rplane(r);
int nx = r->x, ny = r->y; int nx = r->x, ny = r->y;
pnormalize(&nx, &ny, pl); pnormalize(&nx, &ny, pl);
adjust_coordinates(report, &nx, &ny, pl, r); adjust_coordinates(report, &nx, &ny, pl);
sprintf(buffer, "%d %d %d", nx, ny, plane_id(pl)); sprintf(buffer, "%d %d %d", nx, ny, plane_id(pl));
return 0; return 0;
} }
@ -435,7 +435,7 @@ static int cr_regions(variant var, char *buffer, const void *userdata)
int nx = r->x, ny = r->y; int nx = r->x, ny = r->y;
pnormalize(&nx, &ny, pl); pnormalize(&nx, &ny, pl);
adjust_coordinates(f, &nx, &ny, pl, r); adjust_coordinates(f, &nx, &ny, pl);
wp += sprintf(wp, "\"%d %d %d", nx, ny, z); wp += sprintf(wp, "\"%d %d %d", nx, ny, z);
for (i = 1; i != rdata->nregions; ++i) { for (i = 1; i != rdata->nregions; ++i) {
r = rdata->regions[i]; r = rdata->regions[i];
@ -1257,7 +1257,7 @@ static void cr_output_region(FILE * F, report_context * ctx, seen_region * sr)
else { else {
nx = r->x, ny = r->y; nx = r->x, ny = r->y;
pnormalize(&nx, &ny, pl); pnormalize(&nx, &ny, pl);
adjust_coordinates(f, &nx, &ny, pl, r); adjust_coordinates(f, &nx, &ny, pl);
} }
if (pl) { if (pl) {
@ -1398,7 +1398,7 @@ static void cr_output_region(FILE * F, report_context * ctx, seen_region * sr)
plane *plx = rplane(r); plane *plx = rplane(r);
pnormalize(&nx, &ny, plx); pnormalize(&nx, &ny, plx);
adjust_coordinates(f, &nx, &ny, plx, r); adjust_coordinates(f, &nx, &ny, plx);
fprintf(F, "SCHEMEN %d %d\n", nx, ny); fprintf(F, "SCHEMEN %d %d\n", nx, ny);
fprintf(F, "\"%s\";Name\n", rname(r, f->locale)); fprintf(F, "\"%s\";Name\n", rname(r, f->locale));
rl2 = rl2->next; rl2 = rl2->next;
@ -1623,7 +1623,7 @@ report_computer(const char *filename, report_context * ctx, const char *charset)
int nx = r->x, ny = r->y; int nx = r->x, ny = r->y;
pnormalize(&nx, &ny, pl); pnormalize(&nx, &ny, pl);
adjust_coordinates(f, &nx, &ny, pl, r); adjust_coordinates(f, &nx, &ny, pl);
if (!plid) if (!plid)
fprintf(F, "BATTLE %d %d\n", nx, ny); fprintf(F, "BATTLE %d %d\n", nx, ny);
else { else {

View File

@ -257,7 +257,7 @@ unit *addplayer(region * r, faction * f)
char buffer[32]; char buffer[32];
assert(f->units == NULL); assert(f->units == NULL);
set_origin(f, 0, r->x, r->y); faction_setorigin(f, 0, r->x, r->y);
u = create_unit(r, f, 1, f->race, 0, NULL, NULL); u = create_unit(r, f, 1, f->race, 0, NULL, NULL);
equip_items(&u->faction->items, get_equipment("new_faction")); equip_items(&u->faction->items, get_equipment("new_faction"));
equip_unit(u, get_equipment("first_unit")); equip_unit(u, get_equipment("first_unit"));
@ -657,3 +657,38 @@ void remove_empty_factions(void)
fp = &(*fp)->next; fp = &(*fp)->next;
} }
} }
void faction_getorigin(const faction * f, int id, int *x, int *y)
{
ursprung *ur;
assert(f && x && y);
for (ur = f->ursprung; ur; ur = ur->next) {
if (ur->id == id) {
*x = ur->x;
*y = ur->y;
break;
}
}
}
void faction_setorigin(faction * f, int id, int x, int y)
{
ursprung *ur;
assert(f != NULL);
for (ur = f->ursprung; ur; ur = ur->next) {
if (ur->id == id) {
ur->x = ur->x + x;
ur->y = ur->y + y;
return;
}
}
ur = calloc(1, sizeof(ursprung));
ur->id = id;
ur->x = x;
ur->y = y;
addlist(&f->ursprung, ur);
}

View File

@ -154,6 +154,9 @@ extern "C" {
void faction_setpassword(struct faction *self, const char *password); void faction_setpassword(struct faction *self, const char *password);
bool valid_race(const struct faction *f, const struct race *rc); bool valid_race(const struct faction *f, const struct race *rc);
void faction_getorigin(const struct faction * f, int id, int *x, int *y);
void faction_setorigin(struct faction * f, int id, int x, int y);
struct spellbook * faction_get_spellbook(struct faction *f); struct spellbook * faction_get_spellbook(struct faction *f);
/* skills */ /* skills */

View File

@ -112,15 +112,45 @@ static void test_get_monsters(CuTest *tc) {
static void test_set_origin(CuTest *tc) { static void test_set_origin(CuTest *tc) {
faction *f; faction *f;
int x = 0, y = 0;
plane *pl;
test_cleanup(); test_cleanup();
test_create_world(); test_create_world();
pl = create_new_plane(0, "", 0, 19, 0, 19, 0);
f = test_create_faction(0); f = test_create_faction(0);
CuAssertPtrEquals(tc, 0, f->ursprung); CuAssertPtrEquals(tc, 0, f->ursprung);
set_origin(f, 0, 1, 1); faction_setorigin(f, 0, 1, 1);
CuAssertIntEquals(tc, 0, f->ursprung->id); CuAssertIntEquals(tc, 0, f->ursprung->id);
CuAssertIntEquals(tc, 1, f->ursprung->x); CuAssertIntEquals(tc, 1, f->ursprung->x);
CuAssertIntEquals(tc, 1, f->ursprung->y); CuAssertIntEquals(tc, 1, f->ursprung->y);
faction_getorigin(f, 0, &x, &y);
CuAssertIntEquals(tc, 1, x);
CuAssertIntEquals(tc, 1, y);
adjust_coordinates(f, &x, &y, pl);
CuAssertIntEquals(tc, -9, x);
CuAssertIntEquals(tc, -9, y);
adjust_coordinates(f, &x, &y, 0);
CuAssertIntEquals(tc, -10, x);
CuAssertIntEquals(tc, -10, y);
test_cleanup();
}
static void test_set_origin_bug(CuTest *tc) {
faction *f;
plane *pl;
int x = 17, y = 10;
test_cleanup();
test_create_world();
pl = create_new_plane(0, "", 0, 19, 0, 19, 0);
f = test_create_faction(0);
faction_setorigin(f, 0, -10, 3);
faction_setorigin(f, 0, -13, -4);
adjust_coordinates(f, &x, &y, pl);
CuAssertIntEquals(tc, 0, f->ursprung->id);
CuAssertIntEquals(tc, -9, x);
CuAssertIntEquals(tc, 2, y);
test_cleanup(); test_cleanup();
} }
@ -133,5 +163,6 @@ CuSuite *get_faction_suite(void)
SUITE_ADD_TEST(suite, test_remove_dead_factions); SUITE_ADD_TEST(suite, test_remove_dead_factions);
SUITE_ADD_TEST(suite, test_get_monsters); SUITE_ADD_TEST(suite, test_get_monsters);
SUITE_ADD_TEST(suite, test_set_origin); SUITE_ADD_TEST(suite, test_set_origin);
SUITE_ADD_TEST(suite, test_set_origin_bug);
return suite; return suite;
} }

View File

@ -136,7 +136,7 @@ ursprung_x(const faction * f, const plane * pl, const region * rdefault)
} }
if (!rdefault) if (!rdefault)
return 0; return 0;
set_origin((faction *)f, id, rdefault->x - plane_center_x(pl), faction_setorigin((faction *)f, id, rdefault->x - plane_center_x(pl),
rdefault->y - plane_center_y(pl)); rdefault->y - plane_center_y(pl));
return rdefault->x - plane_center_x(pl); return rdefault->x - plane_center_x(pl);
} }
@ -159,7 +159,7 @@ ursprung_y(const faction * f, const plane * pl, const region * rdefault)
} }
if (!rdefault) if (!rdefault)
return 0; return 0;
set_origin((faction *)f, id, rdefault->x - plane_center_x(pl), faction_setorigin((faction *)f, id, rdefault->x - plane_center_x(pl),
rdefault->y - plane_center_y(pl)); rdefault->y - plane_center_y(pl));
return rdefault->y - plane_center_y(pl); return rdefault->y - plane_center_y(pl);
} }
@ -181,14 +181,15 @@ int plane_center_y(const plane * pl)
} }
void void
adjust_coordinates(const faction * f, int *x, int *y, const plane * pl, adjust_coordinates(const faction * f, int *x, int *y, const plane * pl)
const region * r)
{ {
int nx = *x; int nx = *x;
int ny = *y; int ny = *y;
if (f) { if (f) {
nx -= ursprung_x(f, pl, r); int ux, uy;
ny -= ursprung_y(f, pl, r); faction_getorigin(f, pl?pl->id:0, &ux, &uy);
nx -= ux;
ny -= uy;
} }
if (pl) { if (pl) {
int plx = plane_center_x(pl); int plx = plane_center_x(pl);
@ -198,8 +199,8 @@ const region * r)
int width_2 = width / 2; int width_2 = width / 2;
int height_2 = height / 2; int height_2 = height / 2;
nx -= plx; nx = (nx - plx) % width;
ny -= ply; ny = (ny - ply) % height;
if (nx < 0) if (nx < 0)
nx = (width - (-nx) % width); nx = (width - (-nx) % width);
@ -221,26 +222,6 @@ const region * r)
*y = ny; *y = ny;
} }
void set_origin(faction * f, int id, int x, int y)
{
ursprung *ur;
assert(f != NULL);
for (ur = f->ursprung; ur; ur = ur->next) {
if (ur->id == id) {
ur->x = ur->x + x;
ur->y = ur->y + y;
return;
}
}
ur = calloc(1, sizeof(ursprung));
ur->id = id;
ur->x = x;
ur->y = y;
addlist(&f->ursprung, ur);
}
plane *create_new_plane(int id, const char *name, int minx, int maxx, int miny, plane *create_new_plane(int id, const char *name, int minx, int maxx, int miny,
int maxy, int flags) int maxy, int flags)
{ {

View File

@ -70,7 +70,6 @@ extern "C" {
struct plane *getplanebyid(int id); struct plane *getplanebyid(int id);
int plane_center_x(const struct plane *pl); int plane_center_x(const struct plane *pl);
int plane_center_y(const struct plane *pl); int plane_center_y(const struct plane *pl);
void set_origin(struct faction *f, int id, int x, int y);
struct plane *create_new_plane(int id, const char *name, int minx, int maxx, struct plane *create_new_plane(int id, const char *name, int minx, int maxx,
int miny, int maxy, int flags); int miny, int maxy, int flags);
struct plane *getplanebyname(const char *); struct plane *getplanebyname(const char *);
@ -82,8 +81,7 @@ extern "C" {
extern int read_plane_reference(plane ** pp, struct storage *store); extern int read_plane_reference(plane ** pp, struct storage *store);
extern int plane_width(const plane * pl); extern int plane_width(const plane * pl);
extern int plane_height(const plane * pl); extern int plane_height(const plane * pl);
void adjust_coordinates(const struct faction *f, int *x, int *y, void adjust_coordinates(const struct faction *f, int *x, int *y, const struct plane *pl);
const struct plane *pl, const struct region *r);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -121,7 +121,7 @@ const char *write_regionname(const region * r, const faction * f, char *buffer,
plane *pl = rplane(r); plane *pl = rplane(r);
int nx = r->x, ny = r->y; int nx = r->x, ny = r->y;
pnormalize(&nx, &ny, pl); pnormalize(&nx, &ny, pl);
adjust_coordinates(f, &nx, &ny, pl, r); adjust_coordinates(f, &nx, &ny, pl);
slprintf(buf, size, "%s (%d,%d)", rname(r, lang), nx, ny); slprintf(buf, size, "%s (%d,%d)", rname(r, lang), nx, ny);
} }
return buffer; return buffer;

View File

@ -1250,7 +1250,7 @@ faction *readfaction(struct gamedata * data)
READ_INT(data->store, &id); READ_INT(data->store, &id);
READ_INT(data->store, &ux); READ_INT(data->store, &ux);
READ_INT(data->store, &uy); READ_INT(data->store, &uy);
set_origin(f, id, ux, uy); faction_setorigin(f, id, ux, uy);
} }
f->newbies = 0; f->newbies = 0;

View File

@ -2542,7 +2542,7 @@ int origin_cmd(unit * u, struct order *ord)
px = (short)getint(); px = (short)getint();
py = (short)getint(); py = (short)getint();
set_origin(u->faction, getplaneid(u->region), px, py); faction_setorigin(u->faction, getplaneid(u->region), px, py);
return 0; return 0;
} }
@ -4382,7 +4382,7 @@ void init_processor(void)
p += 10; p += 10;
add_proc_order(p, K_QUIT, quit_cmd, 0, NULL); add_proc_order(p, K_QUIT, quit_cmd, 0, NULL);
// add_proc_order(p, K_URSPRUNG, origin_cmd, 0, NULL); add_proc_order(p, K_URSPRUNG, origin_cmd, 0, NULL);
add_proc_order(p, K_ALLY, ally_cmd, 0, NULL); add_proc_order(p, K_ALLY, ally_cmd, 0, NULL);
add_proc_order(p, K_PREFIX, prefix_cmd, 0, NULL); add_proc_order(p, K_PREFIX, prefix_cmd, 0, NULL);
add_proc_order(p, K_SETSTEALTH, setstealth_cmd, 0, NULL); add_proc_order(p, K_SETSTEALTH, setstealth_cmd, 0, NULL);

View File

@ -780,7 +780,7 @@ CuSuite *get_laws_suite(void)
SUITE_ADD_TEST(suite, test_force_leave_buildings); SUITE_ADD_TEST(suite, test_force_leave_buildings);
SUITE_ADD_TEST(suite, test_force_leave_ships); SUITE_ADD_TEST(suite, test_force_leave_ships);
SUITE_ADD_TEST(suite, test_force_leave_ships_on_ocean); SUITE_ADD_TEST(suite, test_force_leave_ships_on_ocean);
DISABLE_TEST(suite, test_peasant_luck_effect); SUITE_ADD_TEST(suite, test_peasant_luck_effect);
SUITE_ADD_TEST(suite, test_luck_message); SUITE_ADD_TEST(suite, test_luck_message);
return suite; return suite;

View File

@ -1565,7 +1565,7 @@ report_template(const char *filename, report_context * ctx, const char *charset)
int nx = r->x, ny = r->y; int nx = r->x, ny = r->y;
pnormalize(&nx, &ny, pl); pnormalize(&nx, &ny, pl);
adjust_coordinates(f, &nx, &ny, pl, r); adjust_coordinates(f, &nx, &ny, pl);
newline(out); newline(out);
if (pl && pl->id != 0) { if (pl && pl->id != 0) {
sprintf(buf, "%s %d,%d,%d ; %s", LOC(f->locale, sprintf(buf, "%s %d,%d,%d ; %s", LOC(f->locale,

View File

@ -2001,7 +2001,7 @@ f_regionid(const region * r, const faction * f, char *buffer, size_t size)
int nx = r->x, ny = r->y; int nx = r->x, ny = r->y;
int named = (name && name[0]); int named = (name && name[0]);
pnormalize(&nx, &ny, pl); pnormalize(&nx, &ny, pl);
adjust_coordinates(f, &nx, &ny, pl, r); adjust_coordinates(f, &nx, &ny, pl);
len = strlcpy(buffer, rname(r, f ? f->locale : 0), size); len = strlcpy(buffer, rname(r, f ? f->locale : 0), size);
_snprintf(buffer + len, size - len, " (%d,%d%s%s)", nx, ny, named ? "," : "", (named) ? name : ""); _snprintf(buffer + len, size - len, " (%d,%d%s%s)", nx, ny, named ? "," : "", (named) ? name : "");
buffer[size - 1] = 0; buffer[size - 1] = 0;