map sanitization (invalid references in map)

This commit is contained in:
Ondrej Novak 2025-02-15 14:31:52 +01:00
parent 14d1a4666d
commit 00e7005c02
4 changed files with 64 additions and 19 deletions

View file

@ -380,7 +380,7 @@ static const int console_height = 165;
static const int console_padding = 3; static const int console_padding = 3;
static int console_blink = 0; static int console_blink = 0;
static char console_visible = 0; static char console_visible = 0;
#define CONSOLE_FONT H_FTINY #define CONSOLE_FONT H_FLITT5
void draw_console_window() { void draw_console_window() {
if (!console_visible) return; if (!console_visible) return;
@ -584,15 +584,17 @@ static int process_actions(const char *command) {
} }
if (istrcmp(command, "ascent") == 0) { if (istrcmp(command, "ascent") == 0) {
int lev = postavy[0].exp; int lev = postavy[0].level;
for (int i = 0; i < POCET_POSTAV; ++i) { for (int i = 0; i < POCET_POSTAV; ++i) {
THUMAN *p = postavy+i; THUMAN *p = postavy+i;
if (p->used) lev = MAX(lev,p->level); if (p->used) lev = MAX(lev,p->level);
} }
for (int i = 0; i < POCET_POSTAV; ++i) { for (int i = 0; i < POCET_POSTAV; ++i) {
THUMAN *p = postavy+i; THUMAN *p = postavy+i;
p->exp = level_map[lev-1]; if (p->used) {
check_player_new_level(p); p->exp = level_map[lev-1];
check_player_new_level(p);
}
} }
return 1; return 1;
} }

View file

@ -748,7 +748,7 @@ void a_touch(int sector,int dir);
int do_action(int action_numb,int sector,int direct,int flags,int nosend); int do_action(int action_numb,int sector,int direct,int flags,int nosend);
void delay_action(int action_numb,int sector,int direct,int flags,int nosend,int delay); void delay_action(int action_numb,int sector,int direct,int flags,int nosend,int delay);
int32_t load_section(FILE *f,void **section, int *sct_type,int32_t *sect_size); int32_t load_section(FILE *f,void **section, int *sct_type,int32_t *sect_size);
void prepare_graphics(int *ofs,char *names,int32_t size,ABLOCK_DECODEPROC decomp,int class); int prepare_graphics(int *ofs,char *names,int32_t size,ABLOCK_DECODEPROC decomp,int class);
void show_automap(char full); void show_automap(char full);
void draw_medium_map(void); void draw_medium_map(void);
void anim_sipky(int h,int mode); void anim_sipky(int h,int mode);

View file

@ -68,6 +68,7 @@ TMAP_EDIT_INFO *map_coord;
TSTR_LIST level_texts; TSTR_LIST level_texts;
int mapsize; int mapsize;
int num_ofsets[10]; //tabulka ofsetu pro cisla sten k levelu int num_ofsets[10]; //tabulka ofsetu pro cisla sten k levelu
int num_ofsets_count[10]; //count of items in each table
char sekceid[]="<BLOCK>"; char sekceid[]="<BLOCK>";
char datapath; char datapath;
D_ACTION *d_action={NULL}; D_ACTION *d_action={NULL};
@ -115,9 +116,10 @@ int32_t load_section(FILE *f,void **section, int *sct_type,int32_t *sect_size)
} }
void prepare_graphics(int *ofs,char *names,int32_t size,ABLOCK_DECODEPROC decomp,int class) int prepare_graphics(int *ofs,char *names,int32_t size,ABLOCK_DECODEPROC decomp,int class)
{ {
char *p,*end; char *p,*end;
int count = 0;
end=names+size; end=names+size;
p=names; p=names;
@ -127,7 +129,9 @@ void prepare_graphics(int *ofs,char *names,int32_t size,ABLOCK_DECODEPROC decom
p=strchr(p,'\0'); p=strchr(p,'\0');
p++; p++;
(*ofs)++; (*ofs)++;
++count;
} }
return count;
} }
@ -187,6 +191,43 @@ const char *find_map_from_hash_impl(char *c, uint32_t h, int sz) {
return c; return c;
} }
void sanitize_map() {
for(int i = 1; i < mapsize; ++i) {
for (int j = 0; j < 4;++j) {
int nx = map_sectors[i].step_next[j];
if (nx > mapsize) {
map_sectors[i].step_next[j] = i;
}
}
TSECTOR *sctr = map_sectors+i;
if (sctr->floor > num_ofsets_count[FLOOR_NUM]) {
sctr->floor = 0;
} if (sctr->ceil > num_ofsets_count[CEIL_NUM]) {
sctr->ceil = 0;
}
}
for (int i = 1, cnt = mapsize * 4; i < cnt; ++i) {
TSTENA *s = map_sides+i;
int max_side = MIN(num_ofsets_count[MAIN_NUM],MIN(num_ofsets_count[LEFT_NUM],num_ofsets_count[RIGHT_NUM]));
int max_obl = MIN(num_ofsets_count[OBL_NUM],num_ofsets_count[OBL2_NUM]);
if (s->prim > max_side) {
s->prim = 0;
}
if (s->sec > max_side) {
s->sec = 0;
}
if ((s->oblouk & 0x0F)> max_obl) {
s->oblouk &= ~0x0F;
}
if (s->prim + (s->prim_anim & 0xF) > max_side) {
s->prim_anim = max_side - (s->prim_anim & 0xF);
}
if (s->sec + (s->sec_anim & 0xF) > max_side) {
s->sec_anim = max_side - (s->sec_anim & 0xF);
}
}
}
int load_map(const char *filename) int load_map(const char *filename)
{ {
@ -238,42 +279,43 @@ int load_map(const char *filename)
free(temp); free(temp);
break; break;
case A_STRMAIN: case A_STRMAIN:
num_ofsets[0]=ofsts-1; num_ofsets[MAIN_NUM]=ofsts-1;
prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA); num_ofsets_count[MAIN_NUM]=prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA);
free(temp); free(temp);
break; break;
case A_STRLEFT: case A_STRLEFT:
num_ofsets[1]=ofsts-1; num_ofsets[LEFT_NUM]=ofsts-1;
prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA); num_ofsets_count[LEFT_NUM]=prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA);
free(temp); free(temp);
break; break;
case A_STRRIGHT: case A_STRRIGHT:
num_ofsets[2]=ofsts-1; num_ofsets[RIGHT_NUM]=ofsts-1;
prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA); num_ofsets_count[RIGHT_NUM] = prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA);
free(temp); free(temp);
break; break;
case A_STRCEIL: case A_STRCEIL:
num_ofsets[3]=ofsts-1; num_ofsets[CEIL_NUM]=ofsts-1;
prepare_graphics(&ofsts,temp,size,pcx_15bit_autofade,SR_GRAFIKA); num_ofsets_count[CEIL_NUM]=prepare_graphics(&ofsts,temp,size,pcx_15bit_autofade,SR_GRAFIKA);
free(temp); free(temp);
break; break;
case A_STRFLOOR: case A_STRFLOOR:
num_ofsets[4]=ofsts-1; num_ofsets[FLOOR_NUM]=ofsts-1;
prepare_graphics(&ofsts,temp,size,pcx_15bit_autofade,SR_GRAFIKA); num_ofsets_count[FLOOR_NUM]=prepare_graphics(&ofsts,temp,size,pcx_15bit_autofade,SR_GRAFIKA);
free(temp); free(temp);
break; break;
case A_STRARC: case A_STRARC:
num_ofsets[OBL_NUM]=ofsts-1; num_ofsets[OBL_NUM]=ofsts-1;
prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA); num_ofsets_count[OBL_NUM]=prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA);
free(temp); free(temp);
break; break;
case A_STRARC2: case A_STRARC2:
num_ofsets[OBL2_NUM]=ofsts-1; num_ofsets[OBL2_NUM]=ofsts-1;
prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA); num_ofsets_count[OBL2_NUM]=prepare_graphics(&ofsts,temp,size,pcx_fade_decomp,SR_GRAFIKA);
free(temp); free(temp);
break; break;
case A_MAPGLOB: case A_MAPGLOB:
num_ofsets[BACK_NUM]=ofsts; num_ofsets[BACK_NUM]=ofsts;
num_ofsets_count[BACK_NUM]=1;
memset(&mglob,0,sizeof(mglob)); memset(&mglob,0,sizeof(mglob));
memcpy(&mglob,temp,MIN((int)size,(int)sizeof(mglob))); memcpy(&mglob,temp,MIN((int)size,(int)sizeof(mglob)));
free(temp); free(temp);
@ -364,6 +406,7 @@ int load_map(const char *filename)
current_map_hash = fnv1a_hash(filename); current_map_hash = fnv1a_hash(filename);
const char * hash_str = map_hash_to_string(current_map_hash); const char * hash_str = map_hash_to_string(current_map_hash);
temp_storage_store(hash_str, filename, strlen(filename)); temp_storage_store(hash_str, filename, strlen(filename));
sanitize_map();
return failed; return failed;
} }

View file

@ -365,7 +365,7 @@ static void build_dungeon_sound_map_in_dir(int sector, int side, int position, i
if (d<32) { if (d<32) {
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
int nx = map_sectors[cursect].step_next[i]; int nx = map_sectors[cursect].step_next[i];
if (nx && (map_sides[cursect * 4 +i].flags & SD_TRANSPARENT)) { if (nx && nx < mapsize && (map_sides[cursect * 4 +i].flags & SD_TRANSPARENT)) {
if (current_sound_sector_map[nx].parts[position].visit_counter != counter) { if (current_sound_sector_map[nx].parts[position].visit_counter != counter) {
TSOUND_MAP_QUEUE *t = queue+(qend % countof(queue)); TSOUND_MAP_QUEUE *t = queue+(qend % countof(queue));
++qend; ++qend;