From ded1f674755335a9cbb5c08e321b4a4c092a0e8d Mon Sep 17 00:00:00 2001 From: DracoRPG Date: Fri, 6 Apr 2007 17:22:40 +0000 Subject: I'm still here! Rewrote fame ranking lists- changed MAP_NAME_LENGTH to 12, now there's MAP_NAME_LENGTH_EXT at 16 for uses where there is / may be the .gat extension, code adjusted accordingly - moved map_normalize_name to mapindex_normalize_name so that everything handling map names uses the same extension-removing function - greatly enhanced the map cache generator, complete documentation on the tool and the map cache format can be found in doc/ - the map cache format changed a bit as a consequence, but of course a new valid one is included (contains latest Nameless Island maps) - fixed a duplicate entry in map index git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@10167 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 11 + conf-tmpl/maps_athena.conf | 12 +- db/Changelog.txt | 2 + db/grf_files.txt | 15 - db/map_cache.dat | Bin 1576951 -> 1586340 bytes db/map_index.txt | 726 +++++++++++++++++++++++++++++++++++++++++++ db/map_list.txt | 713 ------------------------------------------ doc/map_cache.txt | 71 ++++- src/char/char.c | 10 +- src/char_sql/char.c | 21 +- src/common/mapindex.c | 52 ++-- src/common/mapindex.h | 1 + src/common/mmo.h | 5 +- src/map/atcommand.c | 20 +- src/map/charcommand.c | 4 +- src/map/chrif.c | 2 +- src/map/clif.c | 61 ++-- src/map/guild.c | 5 +- src/map/map.c | 70 ++--- src/map/map.h | 3 +- src/map/npc.c | 14 +- src/map/script.c | 18 +- src/map/skill.c | 14 +- src/tool/grfio.c | 1 - src/tool/mapcache.c | 214 +++++++++---- tools/mapcache/grf_files.txt | 15 + 26 files changed, 1131 insertions(+), 949 deletions(-) delete mode 100644 db/grf_files.txt create mode 100644 db/map_index.txt delete mode 100644 db/map_list.txt create mode 100644 tools/mapcache/grf_files.txt diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 062f25428..c3e6c3969 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -5,6 +5,17 @@ IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. 2007/04/07 + * Final touches to the whole map crap [DracoRPG] + - changed MAP_NAME_LENGTH to 12, now there's MAP_NAME_LENGTH_EXT at 16 for + uses where there is / may be the .gat extension, code adjusted accordingly + - moved map_normalize_name to mapindex_normalize_name so that everything + handling map names uses the same extension-removing function + - greatly enhanced the map cache generator, complete documentation on the + tool and the map cache format can be found in doc/ + - the map cache format changed a bit as a consequence, but of course a new + valid one is included (contains latest Nameless Island maps) + - and I'm sorry for the number of times I've moved around and renamed files, + now the final structure should have been reached * Capped clif_heal's heal field (the argument received is int, but the packet field is short, meaning that if the heal is high enough, the client would receive a negative heal amount). [Skotlex] diff --git a/conf-tmpl/maps_athena.conf b/conf-tmpl/maps_athena.conf index f7b969aa1..520be4347 100644 --- a/conf-tmpl/maps_athena.conf +++ b/conf-tmpl/maps_athena.conf @@ -744,7 +744,6 @@ map: ice_dun04 // --- Veins & Thor Dungeon --- // -- 2006-12-19sdata_k.gpf -- - map: que_thor map: thor_camp map: thor_v01 @@ -760,6 +759,17 @@ map: ve_fild05 map: ve_fild06 map: ve_fild07 +// --- Unknown Island & Abbey Dungeon --- +// -- 2007-04-02sdata_k.gpf +map: nameless_i +map: nameless_n +map: nameless_in +map: abbey01 +map: abbey02 +map: abbey03 +map: poring_w01 +map: poring_w02 + //------------------------- Clone Maps --------------------------- //------------------------- Extra Maps --------------------------- diff --git a/db/Changelog.txt b/db/Changelog.txt index cfed7180f..89c357ecc 100644 --- a/db/Changelog.txt +++ b/db/Changelog.txt @@ -21,6 +21,8 @@ ======================== 04/07 + * Updated map index and map cache with Nameless Island maps [DracoRPG] + - also removed the duplicate g_room2 entry from map index, read the note * Corrected Aliza card's item_db line. [Skotlex] 04/05 * Fixed some items that should heal percentual hp/sp [Playtester] diff --git a/db/grf_files.txt b/db/grf_files.txt deleted file mode 100644 index ef2421925..000000000 --- a/db/grf_files.txt +++ /dev/null @@ -1,15 +0,0 @@ -//----------------------------------------- -// GRF List -//----------------------------------------- - -grf: C:\Program Files\Gravity\RO\data.grf -grf: C:\Program Files\Gravity\RO\sdata.grf - -// You may add more in this format -// grf: - -//------ Others --------------------------- - -//Path to directory that contains the data dir -//NOTE: Path must include trailing backslash, only one data_dir entry is supported. -//data_dir: C:\Program Files\Gravity\RO\ diff --git a/db/map_cache.dat b/db/map_cache.dat index 34b8942ee..320e83c66 100644 Binary files a/db/map_cache.dat and b/db/map_cache.dat differ diff --git a/db/map_index.txt b/db/map_index.txt new file mode 100644 index 000000000..b23fe7ba8 --- /dev/null +++ b/db/map_index.txt @@ -0,0 +1,726 @@ +//====================================================================================== +// Map Index +//====================================================================================== +//Contains the list of maps with their respective IDs for inter-server use. +//IDs must never change, therefore any new maps need to be added at the end, +//and old ones must not be removed, but may be replaced. +//Format: +//mapnameindex <- specifies index for this map +//mapname <- map will use index of previous map +1 +//Note that map index 0 is special and reserved for "error" status. + +// NOTE TO DEVELOPERS +// Due to a removed duplicate, index 591 is free, if you have to add a single map, +// please add it there instead of the end. Then remove the 592 on next line (rachel) +// and remove all those comments. ~DracoRPG + +alb_ship 1 +alb2trea +alberta +alberta_in +alde_dun01 +alde_dun02 +alde_dun03 +alde_dun04 +aldeba_in +aldebaran +anthell01 +anthell02 +arena_room +c_tower1 +c_tower2 +c_tower3 +c_tower4 +force_1-1 +force_1-2 +force_1-3 +force_2-1 +force_2-2 +force_2-3 +force_3-1 +force_3-2 +force_3-3 +gef_dun00 +gef_dun01 +gef_dun02 +gef_dun03 +gef_fild00 +gef_fild01 +gef_fild02 +gef_fild03 +gef_fild04 +gef_fild05 +gef_fild06 +gef_fild07 +gef_fild08 +gef_fild09 +gef_fild10 +gef_fild11 +gef_fild12 +gef_fild13 +gef_fild14 +gef_tower +geffen +geffen_in +gl_cas01 +gl_cas02 +gl_church +gl_chyard +gl_dun01 +gl_dun02 +gl_in01 +gl_knt01 +gl_knt02 +gl_prison +gl_prison1 +gl_sew01 +gl_sew02 +gl_sew03 +gl_sew04 +gl_step +glast_01 +hunter_1-1 +hunter_2-1 +hunter_3-1 +in_hunter +in_moc_16 +in_orcs01 +in_sphinx1 +in_sphinx2 +in_sphinx3 +in_sphinx4 +in_sphinx5 +iz_dun00 +iz_dun01 +iz_dun02 +iz_dun03 +iz_dun04 +job_sword1 +izlu2dun +izlude +izlude_in +job_thief1 +knight_1-1 +knight_2-1 +knight_3-1 +mjo_dun01 +mjo_dun02 +mjo_dun03 +mjolnir_01 +mjolnir_02 +mjolnir_03 +mjolnir_04 +mjolnir_05 +mjolnir_06 +mjolnir_07 +mjolnir_08 +mjolnir_09 +mjolnir_10 +mjolnir_11 +mjolnir_12 +moc_castle +moc_fild01 +moc_fild02 +moc_fild03 +moc_fild04 +moc_fild05 +moc_fild06 +moc_fild07 +moc_fild08 +moc_fild09 +moc_fild10 +moc_fild11 +moc_fild12 +moc_fild13 +moc_fild14 +moc_fild15 +moc_fild16 +moc_fild17 +moc_fild18 +moc_fild19 +moc_pryd01 +moc_pryd02 +moc_pryd03 +moc_pryd04 +moc_pryd05 +moc_pryd06 +moc_prydb1 +moc_ruins +monk_in +morocc +morocc_in +new_1-1 +new_1-2 +new_1-3 +new_1-4 +new_2-1 +new_2-2 +new_2-3 +new_2-4 +new_3-1 +new_3-2 +new_3-3 +new_3-4 +new_4-1 +new_4-2 +new_4-3 +new_4-4 +new_5-1 +new_5-2 +new_5-3 +new_5-4 +orcsdun01 +orcsdun02 +ordeal_1-1 +ordeal_1-2 +ordeal_1-3 +ordeal_1-4 +ordeal_2-1 +ordeal_2-2 +ordeal_2-3 +ordeal_2-4 +ordeal_3-1 +ordeal_3-2 +ordeal_3-3 +ordeal_3-4 +pay_arche +pay_dun00 +pay_dun01 +pay_dun02 +pay_dun03 +pay_dun04 +pay_fild01 +pay_fild02 +pay_fild03 +pay_fild04 +pay_fild05 +pay_fild06 +pay_fild07 +pay_fild08 +pay_fild09 +pay_fild10 +pay_fild11 +payon +payon_in01 +payon_in02 +priest_1-1 +priest_2-1 +priest_3-1 +prontera +prt_are_in +prt_are01 +pvp_room +prt_castle +prt_church +prt_fild00 +prt_fild01 +prt_fild02 +prt_fild03 +prt_fild04 +prt_fild05 +prt_fild06 +prt_fild07 +prt_fild08 +prt_fild09 +prt_fild10 +prt_fild11 +prt_in +prt_maze01 +prt_maze02 +prt_maze03 +prt_monk +prt_sewb1 +prt_sewb2 +prt_sewb3 +prt_sewb4 +pvp_2vs2 +pvp_c_room +pvp_n_1-1 +pvp_n_1-2 +pvp_n_1-3 +pvp_n_1-4 +pvp_n_1-5 +pvp_n_2-1 +pvp_n_2-2 +pvp_n_2-3 +pvp_n_2-4 +pvp_n_2-5 +pvp_n_3-1 +pvp_n_3-2 +pvp_n_3-3 +pvp_n_3-4 +pvp_n_3-5 +pvp_n_4-1 +pvp_n_4-2 +pvp_n_4-3 +pvp_n_4-4 +pvp_n_4-5 +pvp_n_5-1 +pvp_n_5-2 +pvp_n_5-3 +pvp_n_5-4 +pvp_n_5-5 +pvp_n_6-1 +pvp_n_6-2 +pvp_n_6-3 +pvp_n_6-4 +pvp_n_6-5 +pvp_n_7-1 +pvp_n_7-2 +pvp_n_7-3 +pvp_n_7-4 +pvp_n_7-5 +pvp_n_8-1 +pvp_n_8-2 +pvp_n_8-3 +pvp_n_8-4 +pvp_n_8-5 +pvp_n_room +pvp_y_1-1 +pvp_y_1-2 +pvp_y_1-3 +pvp_y_1-4 +pvp_y_1-5 +pvp_y_2-1 +pvp_y_2-2 +pvp_y_2-3 +pvp_y_2-4 +pvp_y_2-5 +pvp_y_3-1 +pvp_y_3-2 +pvp_y_3-3 +pvp_y_3-4 +pvp_y_3-5 +pvp_y_4-1 +pvp_y_4-2 +pvp_y_4-3 +pvp_y_4-4 +pvp_y_4-5 +pvp_y_5-1 +pvp_y_5-2 +pvp_y_5-3 +pvp_y_5-4 +pvp_y_5-5 +pvp_y_6-1 +pvp_y_6-2 +pvp_y_6-3 +pvp_y_6-4 +pvp_y_6-5 +pvp_y_7-1 +pvp_y_7-2 +pvp_y_7-3 +pvp_y_7-4 +pvp_y_7-5 +pvp_y_8-1 +pvp_y_8-2 +pvp_y_8-3 +pvp_y_8-4 +pvp_y_8-5 +pvp_y_room +sword_1-1 +sword_2-1 +sword_3-1 +treasure01 +treasure02 +wizard_1-1 +wizard_2-1 +wizard_3-1 +xmas +xmas_dun01 +xmas_dun02 +xmas_fild01 +xmas_in +beach_dun +beach_dun2 +beach_dun3 +cmd_fild01 +cmd_fild02 +cmd_fild03 +cmd_fild04 +cmd_fild05 +cmd_fild06 +cmd_fild07 +cmd_fild08 +cmd_fild09 +cmd_in01 +cmd_in02 +comodo +quiz_00 +quiz_01 +g_room1-1 +g_room1-2 +g_room1-3 +g_room2 +tur_dun01 +tur_dun02 +tur_dun03 +tur_dun04 +tur_dun05 +tur_dun06 +alde_gld +aldeg_cas01 +aldeg_cas02 +aldeg_cas03 +aldeg_cas04 +aldeg_cas05 +gefg_cas01 +gefg_cas02 +gefg_cas03 +gefg_cas04 +gefg_cas05 +gld_dun01 +gld_dun02 +gld_dun03 +gld_dun04 +guild_room +guild_vs1 +guild_vs2 +guild_vs3 +guild_vs4 +guild_vs5 +guild_vs1-1 +guild_vs1-2 +guild_vs1-3 +guild_vs1-4 +guild_vs2-1 +guild_vs2-2 +job_hunte +job_knt +job_prist +job_wiz +pay_gld +payg_cas01 +payg_cas02 +payg_cas03 +payg_cas04 +payg_cas05 +prt_gld +prtg_cas01 +prtg_cas02 +prtg_cas03 +prtg_cas04 +prtg_cas05 +alde_alche +in_rogue +job_cru +job_duncer +job_monk +job_sage +mag_dun01 +mag_dun02 +monk_test +quiz_test +yuno +yuno_fild01 +yuno_fild02 +yuno_fild03 +yuno_fild04 +yuno_in01 +yuno_in02 +yuno_in03 +yuno_in04 +yuno_in05 +ama_dun01 +ama_dun02 +ama_dun03 +ama_fild01 +ama_in01 +ama_in02 +ama_test +amatsu +gon_dun01 +gon_dun02 +gon_dun03 +gon_fild01 +gon_in +gon_test +gonryun +sec_in01 +sec_in02 +sec_pri +umbala +um_dun01 +um_dun02 +um_fild01 +um_fild02 +um_fild03 +um_fild04 +um_in +niflheim +nif_fild01 +nif_fild02 +nif_in +yggdrasil01 +valkyrie +himinn +lou_in01 +lou_in02 +lou_dun03 +lou_dun02 +lou_dun01 +lou_fild01 +louyang +siege_test +n_castle +nguild_gef +nguild_prt +nguild_pay +nguild_alde +jawaii +jawaii_in +gefenia01 +gefenia02 +gefenia03 +gefenia04 +new_zone01 +new_zone02 +new_zone03 +new_zone04 +payon_in03 +ayothaya +ayo_in01 +ayo_in02 +ayo_fild01 +ayo_fild02 +ayo_dun01 +ayo_dun02 +que_god01 +que_god02 +yuno_fild05 +yuno_fild07 +yuno_fild08 +yuno_fild09 +yuno_fild11 +yuno_fild12 +alde_tt02 +turbo_n_1 +turbo_n_4 +turbo_n_8 +turbo_n_16 +turbo_e_4 +turbo_e_8 +turbo_e_16 +turbo_room +airplane +airport +einbech +einbroch +ein_dun01 +ein_dun02 +ein_fild06 +ein_fild07 +ein_fild08 +ein_fild09 +ein_fild10 +ein_in01 +que_sign01 +que_sign02 +ein_fild03 +ein_fild04 +lhz_fild02 +lhz_fild03 +yuno_pre +lhz_fild01 +lighthalzen +lhz_in01 +lhz_in02 +lhz_in03 +lhz_que01 +lhz_dun01 +lhz_dun02 +lhz_dun03 +lhz_cube +juperos_01 +juperos_02 +jupe_area1 +jupe_area2 +jupe_core +jupe_ele +jupe_ele_r +jupe_gate +y_airport +lhz_airport +airplane_01 +jupe_cave +quiz_02 +hu_fild07 +hu_fild05 +hu_fild04 +hu_fild01 +yuno_fild06 +job_soul +job_star +que_job01 +que_job02 +que_job03 +abyss_01 +abyss_02 +abyss_03 +thana_step +thana_boss +tha_scene01 +tha_t01 +tha_t02 +tha_t03 +tha_t04 +tha_t07 +tha_t05 +tha_t06 +tha_t08 +tha_t09 +tha_t10 +tha_t11 +tha_t12 +auction_01 +auction_02 +hugel +hu_in01 +que_bingo +que_hugel +p_track01 +p_track02 +odin_tem01 +odin_tem02 +odin_tem03 +hu_fild02 +hu_fild03 +hu_fild06 +ein_fild01 +ein_fild02 +ein_fild05 +yuno_fild10 +kh_kiehl02 +kh_kiehl01 +kh_dun02 +kh_dun01 +kh_mansion +kh_rossi +kh_school +kh_vila +force_map1 +force_map2 +force_map3 +job_hunter +job_knight +job_priest +job_wizard +// INDEX 591 IS FREE, PLEASE USE IT +rachel 592 +ra_in01 +ra_fild01 +ra_fild02 +ra_fild03 +ra_fild04 +ra_fild05 +ra_fild06 +ra_fild07 +ra_fild08 +ra_fild09 +ra_fild10 +ra_fild11 +ra_fild12 +ra_fild13 +ra_san01 +ra_san02 +ra_san03 +ra_san04 +ra_san05 +ra_temin +ra_temple +ra_temsky +que_rachel +ice_dun01 +ice_dun02 +ice_dun03 +ice_dun04 +que_thor +thor_camp +thor_v01 +thor_v02 +thor_v03 +veins +ve_in +ve_fild01 +ve_fild02 +ve_fild03 +ve_fild04 +ve_fild05 +ve_fild06 +ve_fild07 +poring_c01 +poring_c02 +que_ng +nameless_i +nameless_n +nameless_in +abbey01 +abbey02 +abbey03 +poring_w01 +poring_w02 + + +// Only add maps under this line if they are not standard maps! + + +//====================================================================================== +// - Other/Extra maps - +//====================================================================================== +//rwc01 1000 +//rwc02 +//rwc03 +//prontera_x +//alberta_x +//aldebaran_x +//geffen_x +//izlude_x +//prt_church_x +//prontera_s +//pay_arche_s +//xmas_old +//ordeal_a00 +//ordeal_a02 +//fay_vilg00 +//fay_vilg01 +//gef_vilg00 +//gef_vilg01 +//moc_dugn01 +//moc_dugn02 +//moc_fild01 +//moc_fild02 +//moc_fild03 +//moc_fild04 +//moc_intr00 +//moc_intr01 +//moc_intr02 +//moc_intr04 +//moc_vilg00 +//moc_vilg01 +//moc_vilg02 +//probemap +//probemap02 +//prt_cstl01 +//prt_dugn00 +//prt_dugn01 +//prt_fild00 +//prt_fild01 +//prt_fild03 +//prt_fild04 +//prt_fild05 +//prt_intr01 +//prt_intr01_a +//prt_intr02 +//prt_vilg00 +//prt_vilg01 +//prt_vilg02 +//tank_test +//tank_test2 +//test + +//====================================================================================== +//Place your custom maps with a starting ID here. +//====================================================================================== +//Example: +// +//mymap 1250 +//mymap-2 diff --git a/db/map_list.txt b/db/map_list.txt deleted file mode 100644 index 94585d873..000000000 --- a/db/map_list.txt +++ /dev/null @@ -1,713 +0,0 @@ -//====================================================================================== -// Map Index -//====================================================================================== -//Contains the list of maps with their respective IDs for inter-server use. -//IDs must never change, therefore any new maps need to be added at the end, -//and old ones must not be removed, but may be replaced. -//Format: -//mapnameindex <- specifies index for this map -//mapname <- map will use index of previous map +1 -//Note that map index 0 is special and reserved for "error" status. - -alb_ship 1 -alb2trea -alberta -alberta_in -alde_dun01 -alde_dun02 -alde_dun03 -alde_dun04 -aldeba_in -aldebaran -anthell01 -anthell02 -arena_room -c_tower1 -c_tower2 -c_tower3 -c_tower4 -force_1-1 -force_1-2 -force_1-3 -force_2-1 -force_2-2 -force_2-3 -force_3-1 -force_3-2 -force_3-3 -gef_dun00 -gef_dun01 -gef_dun02 -gef_dun03 -gef_fild00 -gef_fild01 -gef_fild02 -gef_fild03 -gef_fild04 -gef_fild05 -gef_fild06 -gef_fild07 -gef_fild08 -gef_fild09 -gef_fild10 -gef_fild11 -gef_fild12 -gef_fild13 -gef_fild14 -gef_tower -geffen -geffen_in -gl_cas01 -gl_cas02 -gl_church -gl_chyard -gl_dun01 -gl_dun02 -gl_in01 -gl_knt01 -gl_knt02 -gl_prison -gl_prison1 -gl_sew01 -gl_sew02 -gl_sew03 -gl_sew04 -gl_step -glast_01 -hunter_1-1 -hunter_2-1 -hunter_3-1 -in_hunter -in_moc_16 -in_orcs01 -in_sphinx1 -in_sphinx2 -in_sphinx3 -in_sphinx4 -in_sphinx5 -iz_dun00 -iz_dun01 -iz_dun02 -iz_dun03 -iz_dun04 -job_sword1 -izlu2dun -izlude -izlude_in -job_thief1 -knight_1-1 -knight_2-1 -knight_3-1 -mjo_dun01 -mjo_dun02 -mjo_dun03 -mjolnir_01 -mjolnir_02 -mjolnir_03 -mjolnir_04 -mjolnir_05 -mjolnir_06 -mjolnir_07 -mjolnir_08 -mjolnir_09 -mjolnir_10 -mjolnir_11 -mjolnir_12 -moc_castle -moc_fild01 -moc_fild02 -moc_fild03 -moc_fild04 -moc_fild05 -moc_fild06 -moc_fild07 -moc_fild08 -moc_fild09 -moc_fild10 -moc_fild11 -moc_fild12 -moc_fild13 -moc_fild14 -moc_fild15 -moc_fild16 -moc_fild17 -moc_fild18 -moc_fild19 -moc_pryd01 -moc_pryd02 -moc_pryd03 -moc_pryd04 -moc_pryd05 -moc_pryd06 -moc_prydb1 -moc_ruins -monk_in -morocc -morocc_in -new_1-1 -new_1-2 -new_1-3 -new_1-4 -new_2-1 -new_2-2 -new_2-3 -new_2-4 -new_3-1 -new_3-2 -new_3-3 -new_3-4 -new_4-1 -new_4-2 -new_4-3 -new_4-4 -new_5-1 -new_5-2 -new_5-3 -new_5-4 -orcsdun01 -orcsdun02 -ordeal_1-1 -ordeal_1-2 -ordeal_1-3 -ordeal_1-4 -ordeal_2-1 -ordeal_2-2 -ordeal_2-3 -ordeal_2-4 -ordeal_3-1 -ordeal_3-2 -ordeal_3-3 -ordeal_3-4 -pay_arche -pay_dun00 -pay_dun01 -pay_dun02 -pay_dun03 -pay_dun04 -pay_fild01 -pay_fild02 -pay_fild03 -pay_fild04 -pay_fild05 -pay_fild06 -pay_fild07 -pay_fild08 -pay_fild09 -pay_fild10 -pay_fild11 -payon -payon_in01 -payon_in02 -priest_1-1 -priest_2-1 -priest_3-1 -prontera -prt_are_in -prt_are01 -pvp_room -prt_castle -prt_church -prt_fild00 -prt_fild01 -prt_fild02 -prt_fild03 -prt_fild04 -prt_fild05 -prt_fild06 -prt_fild07 -prt_fild08 -prt_fild09 -prt_fild10 -prt_fild11 -prt_in -prt_maze01 -prt_maze02 -prt_maze03 -prt_monk -prt_sewb1 -prt_sewb2 -prt_sewb3 -prt_sewb4 -pvp_2vs2 -pvp_c_room -pvp_n_1-1 -pvp_n_1-2 -pvp_n_1-3 -pvp_n_1-4 -pvp_n_1-5 -pvp_n_2-1 -pvp_n_2-2 -pvp_n_2-3 -pvp_n_2-4 -pvp_n_2-5 -pvp_n_3-1 -pvp_n_3-2 -pvp_n_3-3 -pvp_n_3-4 -pvp_n_3-5 -pvp_n_4-1 -pvp_n_4-2 -pvp_n_4-3 -pvp_n_4-4 -pvp_n_4-5 -pvp_n_5-1 -pvp_n_5-2 -pvp_n_5-3 -pvp_n_5-4 -pvp_n_5-5 -pvp_n_6-1 -pvp_n_6-2 -pvp_n_6-3 -pvp_n_6-4 -pvp_n_6-5 -pvp_n_7-1 -pvp_n_7-2 -pvp_n_7-3 -pvp_n_7-4 -pvp_n_7-5 -pvp_n_8-1 -pvp_n_8-2 -pvp_n_8-3 -pvp_n_8-4 -pvp_n_8-5 -pvp_n_room -pvp_y_1-1 -pvp_y_1-2 -pvp_y_1-3 -pvp_y_1-4 -pvp_y_1-5 -pvp_y_2-1 -pvp_y_2-2 -pvp_y_2-3 -pvp_y_2-4 -pvp_y_2-5 -pvp_y_3-1 -pvp_y_3-2 -pvp_y_3-3 -pvp_y_3-4 -pvp_y_3-5 -pvp_y_4-1 -pvp_y_4-2 -pvp_y_4-3 -pvp_y_4-4 -pvp_y_4-5 -pvp_y_5-1 -pvp_y_5-2 -pvp_y_5-3 -pvp_y_5-4 -pvp_y_5-5 -pvp_y_6-1 -pvp_y_6-2 -pvp_y_6-3 -pvp_y_6-4 -pvp_y_6-5 -pvp_y_7-1 -pvp_y_7-2 -pvp_y_7-3 -pvp_y_7-4 -pvp_y_7-5 -pvp_y_8-1 -pvp_y_8-2 -pvp_y_8-3 -pvp_y_8-4 -pvp_y_8-5 -pvp_y_room -sword_1-1 -sword_2-1 -sword_3-1 -treasure01 -treasure02 -wizard_1-1 -wizard_2-1 -wizard_3-1 -xmas -xmas_dun01 -xmas_dun02 -xmas_fild01 -xmas_in -beach_dun -beach_dun2 -beach_dun3 -cmd_fild01 -cmd_fild02 -cmd_fild03 -cmd_fild04 -cmd_fild05 -cmd_fild06 -cmd_fild07 -cmd_fild08 -cmd_fild09 -cmd_in01 -cmd_in02 -comodo -quiz_00 -quiz_01 -g_room1-1 -g_room1-2 -g_room1-3 -g_room2 -tur_dun01 -tur_dun02 -tur_dun03 -tur_dun04 -tur_dun05 -tur_dun06 -alde_gld -aldeg_cas01 -aldeg_cas02 -aldeg_cas03 -aldeg_cas04 -aldeg_cas05 -gefg_cas01 -gefg_cas02 -gefg_cas03 -gefg_cas04 -gefg_cas05 -gld_dun01 -gld_dun02 -gld_dun03 -gld_dun04 -guild_room -guild_vs1 -guild_vs2 -guild_vs3 -guild_vs4 -guild_vs5 -guild_vs1-1 -guild_vs1-2 -guild_vs1-3 -guild_vs1-4 -guild_vs2-1 -guild_vs2-2 -job_hunte -job_knt -job_prist -job_wiz -pay_gld -payg_cas01 -payg_cas02 -payg_cas03 -payg_cas04 -payg_cas05 -prt_gld -prtg_cas01 -prtg_cas02 -prtg_cas03 -prtg_cas04 -prtg_cas05 -alde_alche -in_rogue -job_cru -job_duncer -job_monk -job_sage -mag_dun01 -mag_dun02 -monk_test -quiz_test -yuno -yuno_fild01 -yuno_fild02 -yuno_fild03 -yuno_fild04 -yuno_in01 -yuno_in02 -yuno_in03 -yuno_in04 -yuno_in05 -ama_dun01 -ama_dun02 -ama_dun03 -ama_fild01 -ama_in01 -ama_in02 -ama_test -amatsu -gon_dun01 -gon_dun02 -gon_dun03 -gon_fild01 -gon_in -gon_test -gonryun -sec_in01 -sec_in02 -sec_pri -umbala -um_dun01 -um_dun02 -um_fild01 -um_fild02 -um_fild03 -um_fild04 -um_in -niflheim -nif_fild01 -nif_fild02 -nif_in -yggdrasil01 -valkyrie -himinn -lou_in01 -lou_in02 -lou_dun03 -lou_dun02 -lou_dun01 -lou_fild01 -louyang -siege_test -n_castle -nguild_gef -nguild_prt -nguild_pay -nguild_alde -jawaii -jawaii_in -gefenia01 -gefenia02 -gefenia03 -gefenia04 -new_zone01 -new_zone02 -new_zone03 -new_zone04 -payon_in03 -ayothaya -ayo_in01 -ayo_in02 -ayo_fild01 -ayo_fild02 -ayo_dun01 -ayo_dun02 -que_god01 -que_god02 -yuno_fild05 -yuno_fild07 -yuno_fild08 -yuno_fild09 -yuno_fild11 -yuno_fild12 -alde_tt02 -turbo_n_1 -turbo_n_4 -turbo_n_8 -turbo_n_16 -turbo_e_4 -turbo_e_8 -turbo_e_16 -turbo_room -airplane -airport -einbech -einbroch -ein_dun01 -ein_dun02 -ein_fild06 -ein_fild07 -ein_fild08 -ein_fild09 -ein_fild10 -ein_in01 -que_sign01 -que_sign02 -ein_fild03 -ein_fild04 -lhz_fild02 -lhz_fild03 -yuno_pre -lhz_fild01 -lighthalzen -lhz_in01 -lhz_in02 -lhz_in03 -lhz_que01 -lhz_dun01 -lhz_dun02 -lhz_dun03 -lhz_cube -juperos_01 -juperos_02 -jupe_area1 -jupe_area2 -jupe_core -jupe_ele -jupe_ele_r -jupe_gate -y_airport -lhz_airport -airplane_01 -jupe_cave -quiz_02 -hu_fild07 -hu_fild05 -hu_fild04 -hu_fild01 -yuno_fild06 -job_soul -job_star -que_job01 -que_job02 -que_job03 -abyss_01 -abyss_02 -abyss_03 -thana_step -thana_boss -tha_scene01 -tha_t01 -tha_t02 -tha_t03 -tha_t04 -tha_t07 -tha_t05 -tha_t06 -tha_t08 -tha_t09 -tha_t10 -tha_t11 -tha_t12 -auction_01 -auction_02 -hugel -hu_in01 -que_bingo -que_hugel -p_track01 -p_track02 -odin_tem01 -odin_tem02 -odin_tem03 -hu_fild02 -hu_fild03 -hu_fild06 -ein_fild01 -ein_fild02 -ein_fild05 -yuno_fild10 -kh_kiehl02 -kh_kiehl01 -kh_dun02 -kh_dun01 -kh_mansion -kh_rossi -kh_school -kh_vila -force_map1 -force_map2 -force_map3 -job_hunter -job_knight -job_priest -job_wizard -g_room2 -rachel -ra_in01 -ra_fild01 -ra_fild02 -ra_fild03 -ra_fild04 -ra_fild05 -ra_fild06 -ra_fild07 -ra_fild08 -ra_fild09 -ra_fild10 -ra_fild11 -ra_fild12 -ra_fild13 -ra_san01 -ra_san02 -ra_san03 -ra_san04 -ra_san05 -ra_temin -ra_temple -ra_temsky -que_rachel -ice_dun01 -ice_dun02 -ice_dun03 -ice_dun04 -que_thor -thor_camp -thor_v01 -thor_v02 -thor_v03 -veins -ve_in -ve_fild01 -ve_fild02 -ve_fild03 -ve_fild04 -ve_fild05 -ve_fild06 -ve_fild07 -poring_c01 -poring_c02 -que_ng - - -// Only add maps under this line if they are not standard maps! - - -//====================================================================================== -// - Other/Extra maps - -//====================================================================================== -//rwc01 1000 -//rwc02 -//rwc03 -//prontera_x -//alberta_x -//aldebaran_x -//geffen_x -//izlude_x -//prt_church_x -//prontera_s -//pay_arche_s -//xmas_old -//ordeal_a00 -//ordeal_a02 -//fay_vilg00 -//fay_vilg01 -//gef_vilg00 -//gef_vilg01 -//moc_dugn01 -//moc_dugn02 -//moc_fild01 -//moc_fild02 -//moc_fild03 -//moc_fild04 -//moc_intr00 -//moc_intr01 -//moc_intr02 -//moc_intr04 -//moc_vilg00 -//moc_vilg01 -//moc_vilg02 -//probemap -//probemap02 -//prt_cstl01 -//prt_dugn00 -//prt_dugn01 -//prt_fild00 -//prt_fild01 -//prt_fild03 -//prt_fild04 -//prt_fild05 -//prt_intr01 -//prt_intr01_a -//prt_intr02 -//prt_vilg00 -//prt_vilg01 -//prt_vilg02 -//tank_test -//tank_test2 -//test - -//====================================================================================== -//Place your custom maps with a starting ID here. -//====================================================================================== -//Example: -// -//mymap 1250 -//mymap-2 diff --git a/doc/map_cache.txt b/doc/map_cache.txt index 4ab77e99b..82849cdf4 100644 --- a/doc/map_cache.txt +++ b/doc/map_cache.txt @@ -1,18 +1,67 @@ -"How to use the mapcache builder" -DracoRPG +//===== Athena Doc ======================================== +//= Map Cache Builder and Format Documentation +//===== By ================================================ +//= DracoRPG +//===== Version =========================================== +//= 1.0 +//========================================================= +//= 0.1 - Short howto for the initial builder version +//= 1.0 - Complete manual covering the improved version +//===== Description ======================================= +//= A complete manual for eAthena's map cache generator +//= as well as a reference on the map cache format used +//========================================================= +Preface: +------------------------------------------------------------------------------- -This is only useful if you have custom maps, as eAthena is provided with an updated mapcache containing every map -from kRO Sakray's data. +Since SVN revision ~10000, the map-server does not know how to read RO client files anymore. It reads maps from a +"map cache" file that contains all and only the useful data about the maps. A map cache containing every official +kRO Sakray map currently supported by eAthena is provided as a default. +If you have custom maps or want to minimize the size of your map cache because your server does not load all of them +(multi-map-server or light test server), you can use the map cache builder to generate a new one fitting your needs. -1. First add the path to the directory / GRF containing your maps to db/grf_files.txt -/!\ Please note you must also have the official maps as the whole mapcache will be rebuilt from scratch +Map cache builder manual: +------------------------------------------------------------------------------- -2. Then add those custom maps at the end of db/map_list.txt, carefully chosing their index +The source code for the map cache builder is located in src/tool/. It can be built using "make tools" if you use the Makefile +or using the "mapcache" project under Visual Studio. Named "mapcache", the executable will be in your eAthena main folder. +The map cache builder needs 3 file paths : one is a list of GRFs and/or data directory containing the maps, the second +is the list of maps to add to the map cache, and the last one is the path of the map cache to generate. Default values for +those paths are "tools/mapcache/grf_files.txt", "db/map_index.txt" and "db/map_cache.dat". +The list of GRF and/or data directory must follow the format and indication of the default file: as many "grf:" entries as +you wish and optionally one only "data_dir:" entry with trailing backslash included. // comments are supported as usual. +In fact, any file with one map name per line can be used as a map list, that's why the map index list is used as a default: +we are sure it contains every map supported by the server. Anything after the map name is ignored, // comments are supported +and if the first word on the line is "map:" then the second word is used as the map name instead: that allows using +maps_athena.conf as your map list, which is handy if you want to generate a minimal map cache for each of your multiple +map-servers. +The map cache file path can point to an already existing file, as the builder adds a map only if it's not already cached. +This way, you can add custom maps to the base map cache without even needing kRO Sakray maps. If you wish to rebuild the +entire map cache, though, you can either provide a path to a non-existing file, or force the rebuild mode. -3. Now just run the mapcache builder and it'll build a new one at db/map_cache.dat +Here are the command-line arguments you can provide to the map cache builder to customize its behavior: + -grf path/to/grf/list + Allows to specify the file containing the list of GRFs and/or data directory + -list path/to/map/list + Allows to specify the file containing the list of maps to add to the map cache + -cache path/to/map/cache + Allows to specify the path to the generated map cache + - rebuild + Allows to force the rebuild mode (map cache will be overwritten even if it already exists) -NOTE: -You can override those default paths by providing your own ones as command-line arguments to the mapcache builder: -$> mapcache [grf_files_path [map_list_path [map_cache_path]]] \ No newline at end of file +Map cache format reference: +------------------------------------------------------------------------------- + +The file is written as little-endian, even on big-endian systems, for cross-compatibility reasons. Appropriate conversions +are done when generating it, so don't worry about it. +The first 6 bytes are a main header: + file size + number of maps +Then maps are stored one right after another: +<12-characters-long string> map name + X size + Y size + compressed cell data length + compressed cell data diff --git a/src/char/char.c b/src/char/char.c index 371303c87..46379bf30 100644 --- a/src/char/char.c +++ b/src/char/char.c @@ -1605,10 +1605,6 @@ void create_online_files(void) { if (online_display_option & 24) { // 8 or 16 // prepare map name memcpy(temp, mapindex_id2name(char_dat[j].status.last_point.map), MAP_NAME_LENGTH); - temp[MAP_NAME_LENGTH] = '\0'; - if (strstr(temp, ".gat") != NULL) { - temp[strstr(temp, ".gat") - temp] = 0; // suppress the '.gat' - } // write map name if (online_display_option & 16) { // map-name AND coordinates fprintf(fp2, " %s (%d, %d)\n", temp, char_dat[j].status.last_point.x, char_dat[j].status.last_point.y); @@ -3532,13 +3528,13 @@ int parse_char(int fd) { //Send player to map uint32 subnet_map_ip; - char map_name[MAP_NAME_LENGTH]; - snprintf(map_name, MAP_NAME_LENGTH, "%s.gat", mapindex_id2name(cd->last_point.map)); + char map_name[MAP_NAME_LENGTH_EXT]; + snprintf(map_name, MAP_NAME_LENGTH_EXT, "%s.gat", mapindex_id2name(cd->last_point.map)); WFIFOHEAD(fd,28); WFIFOW(fd,0) = 0x71; WFIFOL(fd,2) = cd->char_id; - memcpy(WFIFOP(fd,6), map_name, MAP_NAME_LENGTH); + memcpy(WFIFOP(fd,6), map_name, MAP_NAME_LENGTH_EXT); // Advanced subnet check [LuzZza] subnet_map_ip = lan_subnetcheck(ipl); diff --git a/src/char_sql/char.c b/src/char_sql/char.c index b0de20e75..a0c780cb9 100644 --- a/src/char_sql/char.c +++ b/src/char_sql/char.c @@ -3340,13 +3340,12 @@ int parse_char(int fd) { //Send player to map. uint32 subnet_map_ip; - char map_name[MAP_NAME_LENGTH]; - snprintf(map_name, MAP_NAME_LENGTH, "%s.gat", mapindex_id2name(char_dat.last_point.map)); - + char map_name[MAP_NAME_LENGTH_EXT]; + snprintf(map_name, MAP_NAME_LENGTH_EXT, "%s.gat", mapindex_id2name(char_dat.last_point.map)); WFIFOHEAD(fd,28); WFIFOW(fd,0) = 0x71; WFIFOL(fd,2) = char_dat.char_id; - memcpy(WFIFOP(fd,6), map_name, MAP_NAME_LENGTH); + memcpy(WFIFOP(fd,6), map_name, MAP_NAME_LENGTH_EXT); // Advanced subnet check [LuzZza] subnet_map_ip = lan_subnetcheck(ipl); @@ -4024,17 +4023,15 @@ int char_config_read(const char *cfgName) { } else if (strcmpi(w1, "save_log") == 0) { save_log = config_switch(w2); } else if (strcmpi(w1, "start_point") == 0) { - char map[MAP_NAME_LENGTH]; + char map[MAP_NAME_LENGTH_EXT]; int x, y; if (sscanf(w2, "%16[^,],%d,%d", map, &x, &y) < 3) continue; - if (strstr(map, ".gat") != NULL) { // Verify at least if '.gat' is in the map name - start_point.map = mapindex_name2id(map); - if (!start_point.map) - ShowError("Specified start_point %s not found in map-index cache.\n", map); - start_point.x = x; - start_point.y = y; - } + start_point.map = mapindex_name2id(map); + if (!start_point.map) + ShowError("Specified start_point %s not found in map-index cache.\n", map); + start_point.x = x; + start_point.y = y; } else if (strcmpi(w1, "start_zeny") == 0) { start_zeny = atoi(w2); if (start_zeny < 0) diff --git a/src/common/mapindex.c b/src/common/mapindex.c index bfd67140a..cc847e538 100644 --- a/src/common/mapindex.c +++ b/src/common/mapindex.c @@ -15,42 +15,53 @@ //Leave an extra char of space to hold the terminator, in case for the strncpy(mapindex_id2name()) calls. struct indexes { char name[MAP_NAME_LENGTH+1]; //Stores map name - int length; //Stores string length WITHOUT the extension for quick lookup. + char exists; //Set to 1 if index exists } indexes[MAX_MAPINDEX]; static unsigned short max_index = 0; -char mapindex_cfgfile[80] = "db/map_list.txt"; +char mapindex_cfgfile[80] = "db/map_index.txt"; + +// Removes the extension from a map name +char *mapindex_normalize_name(char *mapname) +{ + char *ptr, *ptr2; + ptr = strchr(mapname, '.'); + if (ptr) { //Check and remove extension. + while (ptr[1] && (ptr2 = strchr(ptr+1, '.'))) + ptr = ptr2; //Skip to the last dot. + if(stricmp(ptr,".gat") == 0 || + stricmp(ptr,".afm") == 0 || + stricmp(ptr,".af2") == 0) + *ptr = '\0'; //Remove extension. + } + return mapname; +} /// Adds a map to the specified index /// Returns 1 if successful, 0 oherwise int mapindex_addmap(int index, const char *name) { char map_name[1024]; - char *ext; - int length; if (index < 0 || index >= MAX_MAPINDEX) { ShowError("(mapindex_add) Map index (%d) for \"%s\" out of range (max is %d)\n", index, name, MAX_MAPINDEX); return 0; } + snprintf(map_name, 1024, "%s", name); - map_name[1023] = 0; - length = strlen(map_name); - if (length > MAP_NAME_LENGTH) { + mapindex_normalize_name(map_name); + + if (strlen(map_name) > MAP_NAME_LENGTH-1) { ShowError("(mapindex_add) Map name %s is too long. Maps are limited to %d characters.\n", map_name, MAP_NAME_LENGTH); return 0; } - if ((ext = strstr(map_name, ".")) != NULL) { // Remove extension - length = ext-map_name; - *ext = '\0'; - } - if (indexes[index].length) + if (indexes[index].exists) ShowWarning("(mapindex_add) Overriding index %d: map \"%s\" -> \"%s\"\n", index, indexes[index].name, map_name); strncpy(indexes[index].name, map_name, MAP_NAME_LENGTH); - indexes[index].length = length; + indexes[index].exists = 1; if (max_index <= index) max_index = index+1; return 1; @@ -59,17 +70,18 @@ int mapindex_addmap(int index, const char *name) unsigned short mapindex_name2id(const char* name) { //TODO: Perhaps use a db to speed this up? [Skotlex] int i; - int length = strlen(name); - char *ext = strstr(name, "."); - if (ext) - length = ext-name; //Base map-name length without the extension. + char map_name[1024]; + + snprintf(map_name, 1024, "%s", name); + mapindex_normalize_name(map_name); + for (i = 1; i < max_index; i++) { - if (strncmp(indexes[i].name,name,length)==0) + if (strcmp(indexes[i].name,map_name)==0) return i; } #ifdef MAPINDEX_AUTOADD - if( mapindex_addmap(i,name) ) + if( mapindex_addmap(i,map_name) ) { ShowDebug("mapindex_name2id: Auto-added map \"%s\" to position %d\n", indexes[i], i); return i; @@ -83,7 +95,7 @@ unsigned short mapindex_name2id(const char* name) { } const char* mapindex_id2name(unsigned short id) { - if (id > MAX_MAPINDEX || !indexes[id].length) { + if (id > MAX_MAPINDEX || !indexes[id].exists) { ShowDebug("mapindex_id2name: Requested name for non-existant map index [%d] in cache.\n", id); return indexes[0].name; //Theorically this should never happen, hence we return this string to prevent null pointer crashes. } diff --git a/src/common/mapindex.h b/src/common/mapindex.h index dfcb150e2..0ec192258 100644 --- a/src/common/mapindex.h +++ b/src/common/mapindex.h @@ -37,6 +37,7 @@ extern char mapindex_cfgfile[80]; #define MAP_VEINS "veins" #define MAP_JAIL "sec_pri" #define MAP_NOVICE "new_zone01" +char *mapindex_normalize_name(char *mapname); int mapindex_addmap(int index, const char *name); unsigned short mapindex_name2id(const char*); const char* mapindex_id2name(unsigned short); diff --git a/src/common/mmo.h b/src/common/mmo.h index f07876115..8d5071cc2 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -77,8 +77,9 @@ #define NAME_LENGTH 24 //For item names, which tend to have much longer names. #define ITEM_NAME_LENGTH 50 -//For Map Names, which the client considers to be 16 in length -#define MAP_NAME_LENGTH 16 +//For Map Names, which the client considers to be 16 in length including the .gat extension +#define MAP_NAME_LENGTH 12 +#define MAP_NAME_LENGTH_EXT 16 #define MAX_FRIENDS 40 #define MAX_MEMOPOINTS 10 diff --git a/src/map/atcommand.c b/src/map/atcommand.c index f77d04044..2ce3009eb 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -1310,7 +1310,7 @@ int atcommand_send(const int fd, struct map_session_data* sd, const char* comman */ int atcommand_rura( const int fd, struct map_session_data* sd, const char* command, const char* message) { - char map_name[MAP_NAME_LENGTH]; + char map_name[MAP_NAME_LENGTH_EXT]; unsigned short mapindex; int x = 0, y = 0; int m = -1; @@ -1698,7 +1698,7 @@ int atcommand_whomap3(const int fd, struct map_session_data* sd, const char* com int i, count, users; int pl_GM_level, GM_level; int map_id; - char map_name[MAP_NAME_LENGTH]; + char map_name[MAP_NAME_LENGTH_EXT]; memset(atcmd_output, '\0', sizeof(atcmd_output)); memset(map_name, '\0', sizeof(map_name)); @@ -1752,7 +1752,7 @@ int atcommand_whomap2(const int fd, struct map_session_data* sd, const char* com int i, count, users; int pl_GM_level, GM_level; int map_id = 0; - char map_name[MAP_NAME_LENGTH]; + char map_name[MAP_NAME_LENGTH_EXT]; nullpo_retr(-1, sd); @@ -1810,7 +1810,7 @@ int atcommand_whomap(const int fd, struct map_session_data* sd, const char* comm int i, count, users; int pl_GM_level, GM_level; int map_id = 0; - char map_name[MAP_NAME_LENGTH]; + char map_name[MAP_NAME_LENGTH_EXT]; struct guild *g; struct party_data *p; @@ -3190,10 +3190,10 @@ int atcommand_go(const int fd, struct map_session_data* sd, const char* command, { int i; int town; - char map_name[MAP_NAME_LENGTH]; + char map_name[MAP_NAME_LENGTH_EXT]; int m; - const struct { char map[MAP_NAME_LENGTH]; int x, y; } data[] = { + const struct { char map[MAP_NAME_LENGTH_EXT]; int x, y; } data[] = { { MAP_PRONTERA, 156, 191 }, // 0=Prontera { MAP_MORROC, 156, 93 }, // 1=Morroc { MAP_GEFFEN, 119, 59 }, // 2=Geffen @@ -3250,7 +3250,7 @@ int atcommand_go(const int fd, struct map_session_data* sd, const char* command, return -1; } else { // get possible name of the city - map_name[MAP_NAME_LENGTH-1] = '\0'; + map_name[MAP_NAME_LENGTH_EXT-1] = '\0'; for (i = 0; map_name[i]; i++) map_name[i] = TOLOWER(map_name[i]); // try to see if it's a name, and not a number (try a lot of possibilities, write errors and abbreviations too) @@ -3636,7 +3636,7 @@ static int atkillmonster_sub(struct block_list *bl, va_list ap) void atcommand_killmonster_sub(const int fd, struct map_session_data* sd, const char* message, const int drop) { int map_id; - char map_name[MAP_NAME_LENGTH]; + char map_name[MAP_NAME_LENGTH_EXT]; if (!sd) return; @@ -5432,8 +5432,8 @@ int atcommand_mapinfo(const int fd, struct map_session_data* sd, const char* com } if (atcmd_player_name[0] == '\0') { - memcpy(atcmd_player_name, mapindex_id2name(sd->mapindex), MAP_NAME_LENGTH); - atcmd_player_name[MAP_NAME_LENGTH] = '\0'; + memcpy(atcmd_player_name, mapindex_id2name(sd->mapindex), MAP_NAME_LENGTH_EXT); + atcmd_player_name[MAP_NAME_LENGTH_EXT] = '\0'; m_id = map_mapindex2mapid(sd->mapindex); } else { m_id = map_mapname2mapid(atcmd_player_name); diff --git a/src/map/charcommand.c b/src/map/charcommand.c index e826d42b8..415f216d5 100644 --- a/src/map/charcommand.c +++ b/src/map/charcommand.c @@ -617,7 +617,7 @@ int charcommand_save( const int fd, struct map_session_data* sd, const char* command, const char* message) { - char map_name[MAP_NAME_LENGTH]; + char map_name[MAP_NAME_LENGTH_EXT]; char character[NAME_LENGTH]; struct map_session_data* pl_sd; int x = 0, y = 0; @@ -1130,7 +1130,7 @@ int charcommand_warp( const int fd, struct map_session_data* sd, const char* command, const char* message) { - char map_name[MAP_NAME_LENGTH]; + char map_name[MAP_NAME_LENGTH_EXT]; char character[NAME_LENGTH]; int x = 0, y = 0; struct map_session_data *pl_sd; diff --git a/src/map/chrif.c b/src/map/chrif.c index 3fef01c5c..2af51c20d 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -328,7 +328,7 @@ int chrif_changemapserver(struct map_session_data *sd, short map, int x, int y, int chrif_changemapserverack(int fd) { struct map_session_data *sd; - char mapname[MAP_NAME_LENGTH+1]; + char mapname[MAP_NAME_LENGTH_EXT]; RFIFOHEAD(fd); sd = map_id2sd(RFIFOL(fd,2)); diff --git a/src/map/clif.c b/src/map/clif.c index 615b5fee3..36ae1d658 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -1208,12 +1208,16 @@ static void clif_spiritball_single(int fd, struct map_session_data *sd) *------------------------------------------ */ static int clif_set0192(int fd, int m, int x, int y, int type) { + char map_name[MAP_NAME_LENGTH_EXT]; + + sprintf(map_name, "%s.gat", map[m].name); + WFIFOHEAD(fd, packet_len(0x192)); WFIFOW(fd,0) = 0x192; WFIFOW(fd,2) = x; WFIFOW(fd,4) = y; WFIFOW(fd,6) = type; - memcpy(WFIFOP(fd,8),map[m].name,MAP_NAME_LENGTH); + memcpy(WFIFOP(fd,8),map_name,MAP_NAME_LENGTH_EXT); WFIFOSET(fd,packet_len(0x192)); return 0; @@ -1600,17 +1604,17 @@ void clif_setwaitclose(int fd) { */ int clif_changemap(struct map_session_data *sd, short map, int x, int y) { int fd; - char map_name[MAP_NAME_LENGTH]; - + char map_name[MAP_NAME_LENGTH_EXT]; + nullpo_retr(0, sd); fd = sd->fd; - snprintf(map_name, MAP_NAME_LENGTH, "%s.gat", mapindex_id2name(map)); + sprintf(map_name, "%s.gat", mapindex_id2name(map)); WFIFOHEAD(fd, packet_len(0x91)); WFIFOW(fd,0) = 0x91; - memcpy(WFIFOP(fd,2), map_name, MAP_NAME_LENGTH); + memcpy(WFIFOP(fd,2), map_name, MAP_NAME_LENGTH_EXT); WFIFOW(fd,18) = x; WFIFOW(fd,20) = y; WFIFOSET(fd, packet_len(0x91)); @@ -1631,7 +1635,7 @@ int clif_changemapserver(struct map_session_data* sd, const char* mapname, int x WFIFOHEAD(fd, packet_len(0x92)); WFIFOW(fd,0) = 0x92; //Better not trust the null-terminator is there. [Skotlex] - memcpy(WFIFOP(fd,2), mapname, MAP_NAME_LENGTH); + memcpy(WFIFOP(fd,2), mapname, MAP_NAME_LENGTH_EXT); WFIFOB(fd,17) = 0; //Null terminator for mapname WFIFOW(fd,18) = x; WFIFOW(fd,20) = y; @@ -4661,10 +4665,10 @@ int clif_skill_warppoint(struct map_session_data *sd,int skill_num,int skill_lv, WFIFOHEAD(fd,packet_len(0x11c)); WFIFOW(fd,0)=0x11c; WFIFOW(fd,2)=skill_num; - strncpy((char*)WFIFOP(fd, 4),map1,MAP_NAME_LENGTH); - strncpy((char*)WFIFOP(fd,20),map2,MAP_NAME_LENGTH); - strncpy((char*)WFIFOP(fd,36),map3,MAP_NAME_LENGTH); - strncpy((char*)WFIFOP(fd,52),map4,MAP_NAME_LENGTH); + strncpy((char*)WFIFOP(fd, 4),map1,MAP_NAME_LENGTH_EXT); + strncpy((char*)WFIFOP(fd,20),map2,MAP_NAME_LENGTH_EXT); + strncpy((char*)WFIFOP(fd,36),map3,MAP_NAME_LENGTH_EXT); + strncpy((char*)WFIFOP(fd,52),map4,MAP_NAME_LENGTH_EXT); WFIFOSET(fd,packet_len(0x11c)); sd->menuskill_id = skill_num; if (skill_num == AL_WARP) @@ -5660,7 +5664,7 @@ int clif_party_created(struct map_session_data *sd,int flag) int clif_party_member_info(struct party_data *p, struct map_session_data *sd) { unsigned char buf[96]; - char map_name[MAP_NAME_LENGTH]; + char map_name[MAP_NAME_LENGTH_EXT]; if (!sd) { //Pick any party member (this call is used when changing item share rules) int i; @@ -5669,7 +5673,7 @@ int clif_party_member_info(struct party_data *p, struct map_session_data *sd) sd = p->data[i].sd; } - snprintf(map_name, MAP_NAME_LENGTH, "%s.gat", mapindex_id2name(sd->mapindex)); + snprintf(map_name, MAP_NAME_LENGTH_EXT, "%s.gat", mapindex_id2name(sd->mapindex)); WBUFW(buf,0)=0x1e9; WBUFL(buf,2)= sd->status.account_id; @@ -5679,7 +5683,7 @@ int clif_party_member_info(struct party_data *p, struct map_session_data *sd) WBUFB(buf,14)=0; //Unconfirmed byte, could be online/offline. memcpy(WBUFP(buf,15), p->party.name, NAME_LENGTH); memcpy(WBUFP(buf,39), sd->status.name, NAME_LENGTH); - memcpy(WBUFP(buf,63), map_name, MAP_NAME_LENGTH); + memcpy(WBUFP(buf,63), map_name, MAP_NAME_LENGTH_EXT); WBUFB(buf,79) = (p->party.item&1)?1:0; WBUFB(buf,80) = (p->party.item&2)?1:0; clif_send(buf,packet_len(0x1e9),&sd->bl,PARTY); @@ -5693,7 +5697,7 @@ int clif_party_member_info(struct party_data *p, struct map_session_data *sd) *------------------------------------------*/ int clif_party_info(struct party_data* p, struct map_session_data *sd) { - unsigned char buf[2+2+NAME_LENGTH+(4+NAME_LENGTH+MAP_NAME_LENGTH+1+1)*MAX_PARTY]; + unsigned char buf[2+2+NAME_LENGTH+(4+NAME_LENGTH+MAP_NAME_LENGTH_EXT+1+1)*MAX_PARTY]; struct map_session_data* party_sd = NULL; int i, c; @@ -5704,17 +5708,17 @@ int clif_party_info(struct party_data* p, struct map_session_data *sd) for(i = 0, c = 0; i < MAX_PARTY; i++) { struct party_member* m = &p->party.member[i]; - char map_name[MAP_NAME_LENGTH]; + char map_name[MAP_NAME_LENGTH_EXT]; if(!m->account_id) continue; if(party_sd == NULL) party_sd = p->data[i].sd; - snprintf(map_name, MAP_NAME_LENGTH, "%s.gat", mapindex_id2name(m->map)); + snprintf(map_name, MAP_NAME_LENGTH_EXT, "%s.gat", mapindex_id2name(m->map)); WBUFL(buf,28+c*46) = m->account_id; memcpy(WBUFP(buf,28+c*46+4), m->name, NAME_LENGTH); - memcpy(WBUFP(buf,28+c*46+28), map_name, MAP_NAME_LENGTH); + memcpy(WBUFP(buf,28+c*46+28), map_name, MAP_NAME_LENGTH_EXT); WBUFB(buf,28+c*46+44) = (m->leader) ? 0 : 1; WBUFB(buf,28+c*46+45) = (m->online) ? 0 : 1; c++; @@ -5993,12 +5997,12 @@ int clif_hpmeter(struct map_session_data *sd) int clif_party_move(struct party *p,struct map_session_data *sd,int online) { unsigned char buf[128]; - char map_name[MAP_NAME_LENGTH]; + char map_name[MAP_NAME_LENGTH_EXT]; nullpo_retr(0, sd); nullpo_retr(0, p); - snprintf(map_name, MAP_NAME_LENGTH, "%s.gat", map[sd->bl.m].name); + snprintf(map_name, MAP_NAME_LENGTH_EXT, "%s.gat", map[sd->bl.m].name); WBUFW(buf, 0)=0x104; WBUFL(buf, 2)=sd->status.account_id; @@ -6008,7 +6012,7 @@ int clif_party_move(struct party *p,struct map_session_data *sd,int online) WBUFB(buf,14)=!online; memcpy(WBUFP(buf,15),p->name, NAME_LENGTH); memcpy(WBUFP(buf,39),sd->status.name, NAME_LENGTH); - memcpy(WBUFP(buf,63),map_name, MAP_NAME_LENGTH); + memcpy(WBUFP(buf,63),map_name, MAP_NAME_LENGTH_EXT); clif_send(buf,packet_len(0x104),&sd->bl,PARTY); return 0; } @@ -6415,6 +6419,9 @@ int clif_changemapcell(int m,int x,int y,int cell_type,int type) { struct block_list bl; unsigned char buf[32]; + char map_name[MAP_NAME_LENGTH_EXT]; + + snprintf(map_name, MAP_NAME_LENGTH_EXT, "%s.gat", map[m].name); bl.type = BL_NUL; bl.m = m; @@ -6424,7 +6431,7 @@ int clif_changemapcell(int m,int x,int y,int cell_type,int type) WBUFW(buf,2) = x; WBUFW(buf,4) = y; WBUFW(buf,6) = cell_type; - memcpy(WBUFP(buf,8),map[m].name,MAP_NAME_LENGTH); + memcpy(WBUFP(buf,8),map_name,MAP_NAME_LENGTH_EXT); if(!type) clif_send(buf,packet_len(0x192),&bl,AREA); else @@ -7850,13 +7857,13 @@ void clif_gospel_info(struct map_session_data *sd, int type) void clif_feel_info(struct map_session_data *sd, unsigned char feel_level, unsigned char type) { int fd=sd->fd; - char map_name[MAP_NAME_LENGTH]; + char map_name[MAP_NAME_LENGTH_EXT]; - snprintf(map_name, MAP_NAME_LENGTH, "%s.gat", mapindex_id2name(sd->feel_map[feel_level].index)); + snprintf(map_name, MAP_NAME_LENGTH_EXT, "%s.gat", mapindex_id2name(sd->feel_map[feel_level].index)); WFIFOHEAD(fd,packet_len(0x20e)); WFIFOW(fd,0)=0x20e; - memcpy(WFIFOP(fd,2),map_name, MAP_NAME_LENGTH); + memcpy(WFIFOP(fd,2),map_name, MAP_NAME_LENGTH_EXT); WFIFOL(fd,26)=sd->bl.id; WFIFOB(fd,30)=feel_level; WFIFOB(fd,31)=type?1:0; @@ -8636,8 +8643,8 @@ int clif_message(struct block_list *bl, const char* msg) */ void clif_parse_MapMove(int fd, struct map_session_data *sd) { // /m /mapmove (as @rura GM command) - char output[MAP_NAME_LENGTH+15]; // Max length of a short: ' -6XXXX' -> 7 digits - char message[MAP_NAME_LENGTH+15+5]; // "/mm "+output + char output[MAP_NAME_LENGTH_EXT+15]; // Max length of a short: ' -6XXXX' -> 7 digits + char message[MAP_NAME_LENGTH_EXT+15+5]; // "/mm "+output char *map_name; RFIFOHEAD(fd); @@ -8647,7 +8654,7 @@ void clif_parse_MapMove(int fd, struct map_session_data *sd) { return; map_name = RFIFOP(fd,2); - map_name[MAP_NAME_LENGTH-1]='\0'; + map_name[MAP_NAME_LENGTH_EXT-1]='\0'; sprintf(output, "%s %d %d", map_name, RFIFOW(fd,18), RFIFOW(fd,20)); atcommand_rura(fd, sd, "@rura", output); if(log_config.gm && get_atcommand_level(AtCommand_MapMove) >= log_config.gm) diff --git a/src/map/guild.c b/src/map/guild.c index 64af2e12a..8399022e3 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -9,6 +9,7 @@ #include "../common/timer.h" #include "../common/nullpo.h" #include "../common/malloc.h" +#include "../common/mapindex.h" #include "../common/showmsg.h" #include "../common/ers.h" @@ -183,7 +184,7 @@ static int guild_read_castledb(void) gc=(struct guild_castle *)aCalloc(1,sizeof(struct guild_castle)); gc->castle_id=atoi(str[0]); - memcpy(gc->map_name,map_normalize_name(str[1]),MAP_NAME_LENGTH-1); + memcpy(gc->map_name,mapindex_normalize_name(str[1]),MAP_NAME_LENGTH-1); memcpy(gc->castle_name,str[2],NAME_LENGTH-1); memcpy(gc->castle_event,str[3],NAME_LENGTH-1); @@ -254,7 +255,7 @@ struct guild_castle *guild_mapname2gc(char *mapname) int i; struct guild_castle *gc=NULL; - map_normalize_name(mapname); + mapindex_normalize_name(mapname); for(i=0;iname, info.name) == 0) { // Map found m->xs = info.xs; m->ys = info.ys; m->gat = (unsigned char *)aMalloc(m->xs*m->ys); // Allocate room for map cells data buf = aMalloc(info.len); // Allocate a temp buffer to read the zipped map - fread(buf, info.len, 1, map_cache_fp); + fread(buf, info.len, 1, fp); size = m->xs*m->ys; decode_zip(m->gat, &size, buf, info.len); // Unzip the map from the buffer aFree(buf); return 1; } else // Map not found, jump to the beginning of the next map info header - fseek(map_cache_fp, info.len, SEEK_CUR); + fseek(fp, info.len, SEEK_CUR); } return 0; @@ -2482,7 +2469,7 @@ int map_addmap(char *mapname) { return 1; } - memcpy(map[map_num].name, map_normalize_name(mapname), MAP_NAME_LENGTH-1); + memcpy(map[map_num].name, mapindex_normalize_name(mapname), MAP_NAME_LENGTH-1); map_num++; return 0; } @@ -2520,8 +2507,9 @@ int map_readallmaps (void) { int i; int maps_removed = 0; + FILE *fp; - if(!(map_cache_fp = fopen(map_cache_file, "rb"))) + if(!(fp = fopen(map_cache_file, "rb"))) { ShowFatalError("Unable to open map cache file "CL_WHITE"%s"CL_RESET"\n", map_cache_file); exit(1); //No use launching server if maps can't be read. @@ -2559,7 +2547,7 @@ int map_readallmaps (void) fflush(stdout); } - if(!map_readmap(&map[i])) { + if(!map_readfromcache(&map[i], fp)) { map_delmapid(i); maps_removed++; i--; @@ -2609,6 +2597,8 @@ int map_readallmaps (void) map[i].block_mob_count = (int*)aCallocA(size, 1); } + fclose(fp); + // finished map loading printf("\r"); ShowInfo("Successfully loaded '"CL_WHITE"%d"CL_RESET"' maps.%30s\n",map_num,""); diff --git a/src/map/map.h b/src/map/map.h index 96b2b79b8..468f7a7d6 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -1030,7 +1030,7 @@ enum { ATK_LUCKY=1,ATK_FLEE,ATK_DEF}; // struct map_data { char name[MAP_NAME_LENGTH]; unsigned short index; //Index is the map index used by the mapindex* functions. - unsigned char *gat; // NULLなら下のmap_data_other_serverとして扱う + unsigned char *gat; // If this is NULL the map is not on this map-server unsigned char *cell; //Contains temporary cell data that is set/unset on tiles. #ifdef CELL_NOSTACK unsigned char *cell_bl; //Holds amount of bls in any given cell. @@ -1350,7 +1350,6 @@ void map_foreachpc(int (*func)(DBKey,void*,va_list),...); int map_foreachiddb(int (*)(DBKey,void*,va_list),...); void map_addnickdb(struct map_session_data *); struct map_session_data * map_nick2sd(const char*); -char *map_normalize_name(char *mapname); // その他 int map_check_dir(int s_dir,int t_dir); diff --git a/src/map/npc.c b/src/map/npc.c index f4be64e16..9d12fa2d6 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -1659,7 +1659,7 @@ int npc_parse_warp (char *w1,char *w2,char *w3,char *w4) { int x, y, xs, ys, to_x, to_y, m; int i; - char mapname[MAP_NAME_LENGTH], to_mapname[MAP_NAME_LENGTH]; + char mapname[MAP_NAME_LENGTH_EXT], to_mapname[MAP_NAME_LENGTH_EXT]; struct npc_data *nd; // 引数の個数チェック @@ -1723,7 +1723,7 @@ static int npc_parse_shop (char *w1, char *w2, char *w3, char *w4) #define MAX_SHOPITEM 100 char *p; int x, y, dir, m, pos = 0; - char mapname[MAP_NAME_LENGTH]; + char mapname[MAP_NAME_LENGTH_EXT]; struct npc_data *nd; if (strcmp(w1, "-") == 0) { @@ -1953,7 +1953,7 @@ static int npc_skip_script (char *w1,char *w2,char *w3,char *w4,char *first_line static int npc_parse_script(char *w1,char *w2,char *w3,char *w4,char *first_line,FILE *fp,int *lines,const char* file) { int x, y, dir = 0, m, xs = 0, ys = 0, class_ = 0; // [Valaris] thanks to fov - char mapname[MAP_NAME_LENGTH]; + char mapname[MAP_NAME_LENGTH_EXT]; unsigned char *srcbuf = NULL; struct script_code *script; int srcsize = 65536; @@ -2380,7 +2380,7 @@ int npc_parse_mob2 (struct spawn_data *mob, int index) int npc_parse_mob (char *w1, char *w2, char *w3, char *w4) { int level, num, class_, mode, x,y,xs,ys; - char mapname[MAP_NAME_LENGTH]; + char mapname[MAP_NAME_LENGTH_EXT]; char mobname[NAME_LENGTH]; struct spawn_data mob, *data; @@ -2515,7 +2515,7 @@ int npc_parse_mob (char *w1, char *w2, char *w3, char *w4) static int npc_parse_mapflag (char *w1, char *w2, char *w3, char *w4) { int m; - char mapname[MAP_NAME_LENGTH]; + char mapname[MAP_NAME_LENGTH_EXT]; int state = 1; // 引数の個数チェック @@ -2530,7 +2530,7 @@ static int npc_parse_mapflag (char *w1, char *w2, char *w3, char *w4) //マップフラグ if (strcmpi(w3, "nosave") == 0) { - char savemap[MAP_NAME_LENGTH]; + char savemap[MAP_NAME_LENGTH_EXT]; int savex, savey; if (state == 0) ; //Map flag disabled. @@ -2764,7 +2764,7 @@ static int npc_parse_mapflag (char *w1, char *w2, char *w3, char *w4) static int npc_parse_mapcell (char *w1, char *w2, char *w3, char *w4) { int m, cell, x, y, x0, y0, x1, y1; - char type[24], mapname[MAP_NAME_LENGTH]; + char type[24], mapname[MAP_NAME_LENGTH_EXT]; if (sscanf(w1, "%15[^,]", mapname) != 1) return 1; diff --git a/src/map/script.c b/src/map/script.c index b0f582b58..602020cf2 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -9119,10 +9119,10 @@ BUILDIN_FUNC(flagemblem) BUILDIN_FUNC(getcastlename) { - char mapname[MAP_NAME_LENGTH]; + char mapname[MAP_NAME_LENGTH_EXT]; struct guild_castle *gc; - strncpy(mapname, script_getstr(st,2), MAP_NAME_LENGTH); + strncpy(mapname, script_getstr(st,2), MAP_NAME_LENGTH_EXT); gc = guild_mapname2gc(mapname); if(gc) @@ -9134,13 +9134,13 @@ BUILDIN_FUNC(getcastlename) BUILDIN_FUNC(getcastledata) { - char mapname[MAP_NAME_LENGTH]; + char mapname[MAP_NAME_LENGTH_EXT]; int index=script_getnum(st,3); const char *event=NULL; struct guild_castle *gc; int i; - strncpy(mapname, script_getstr(st,2), MAP_NAME_LENGTH); + strncpy(mapname, script_getstr(st,2), MAP_NAME_LENGTH_EXT); gc = guild_mapname2gc(mapname); if(script_hasdata(st,4) && index==0 && gc) { @@ -9202,12 +9202,12 @@ BUILDIN_FUNC(getcastledata) BUILDIN_FUNC(setcastledata) { - char mapname[MAP_NAME_LENGTH]; + char mapname[MAP_NAME_LENGTH_EXT]; int index=script_getnum(st,3); int value=script_getnum(st,4); struct guild_castle *gc; - strncpy(mapname, script_getstr(st,2), MAP_NAME_LENGTH); + strncpy(mapname, script_getstr(st,2), MAP_NAME_LENGTH_EXT); gc = guild_mapname2gc(mapname); if(gc) { @@ -11084,9 +11084,9 @@ BUILDIN_FUNC(getsavepoint) y=sd->status.save_point.y; switch(type){ case 0: - mapname=(char *) aMallocA((MAP_NAME_LENGTH+1)*sizeof(char)); + mapname=(char *) aMallocA((MAP_NAME_LENGTH)*sizeof(char)); memcpy(mapname, mapindex_id2name(sd->status.save_point.map), MAP_NAME_LENGTH); - mapname[MAP_NAME_LENGTH]='\0'; + mapname[MAP_NAME_LENGTH-1]='\0'; script_pushstr(st,mapname); break; case 1: @@ -11133,7 +11133,7 @@ BUILDIN_FUNC(getmapxy) char prefix; int x,y,type; - char mapname[MAP_NAME_LENGTH+1]; + char mapname[MAP_NAME_LENGTH]; memset(mapname, 0, sizeof(mapname)); if( !data_isreference(script_getdata(st,2)) ){ diff --git a/src/map/skill.c b/src/map/skill.c index 1aaecb778..b44219db1 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -4445,8 +4445,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in } else { if (sd->skillitem != AL_TELEPORT) { - char save_map[MAP_NAME_LENGTH]; - snprintf(save_map, MAP_NAME_LENGTH, "%s.gat", mapindex_id2name(sd->status.save_point.map)); + char save_map[MAP_NAME_LENGTH_EXT]; + snprintf(save_map, MAP_NAME_LENGTH_EXT, "%s.gat", mapindex_id2name(sd->status.save_point.map)); clif_skill_warppoint(sd,skillid,skilllv,"Random",save_map,"",""); } else //Autocasted Teleport level 2?? @@ -6086,14 +6086,14 @@ int skill_castend_pos2 (struct block_list *src, int x, int y, int skillid, int s case AL_WARP: if(sd) { - char memo[4][MAP_NAME_LENGTH] = {"", "", "", ""}; - snprintf(memo[0], MAP_NAME_LENGTH, "%s.gat", mapindex_id2name(sd->status.save_point.map)); + char memo[4][MAP_NAME_LENGTH_EXT] = {"", "", "", ""}; + snprintf(memo[0], MAP_NAME_LENGTH_EXT, "%s.gat", mapindex_id2name(sd->status.save_point.map)); if (skilllv>1 && sd->status.memo_point[0].map) - snprintf(memo[1], MAP_NAME_LENGTH, "%s.gat", mapindex_id2name(sd->status.memo_point[0].map)); + snprintf(memo[1], MAP_NAME_LENGTH_EXT, "%s.gat", mapindex_id2name(sd->status.memo_point[0].map)); if (skilllv>2 && sd->status.memo_point[1].map) - snprintf(memo[2], MAP_NAME_LENGTH, "%s.gat", mapindex_id2name(sd->status.memo_point[1].map)); + snprintf(memo[2], MAP_NAME_LENGTH_EXT, "%s.gat", mapindex_id2name(sd->status.memo_point[1].map)); if (skilllv>3 && sd->status.memo_point[2].map) - snprintf(memo[3], MAP_NAME_LENGTH, "%s.gat", mapindex_id2name(sd->status.memo_point[2].map)); + snprintf(memo[3], MAP_NAME_LENGTH_EXT, "%s.gat", mapindex_id2name(sd->status.memo_point[2].map)); clif_skill_warppoint(sd,skillid,skilllv, memo[0],memo[1],memo[2],memo[3]); diff --git a/src/tool/grfio.c b/src/tool/grfio.c index 3b19ca2f8..72034d92f 100644 --- a/src/tool/grfio.c +++ b/src/tool/grfio.c @@ -578,7 +578,6 @@ void* grfio_reads(char *fname, int *size) if (entry != NULL && entry->gentry < 0) { entry->gentry = -entry->gentry; // local file checked } else { - printf("%s not found (grfio_reads - local file %s)\n", fname, lfname); return NULL; } } diff --git a/src/tool/mapcache.c b/src/tool/mapcache.c index d088a9d52..c576a6b6c 100644 --- a/src/tool/mapcache.c +++ b/src/tool/mapcache.c @@ -4,6 +4,7 @@ #include #include #include +#include #ifndef _WIN32 #include @@ -11,12 +12,18 @@ #include "grfio.h" -char grf_list_file[256] = "db/grf_files.txt"; -char map_list_file[256] = "db/map_list.txt"; +#define MAP_NAME_LENGTH 12 +#define MAP_NAME_LENGTH_EXT 16 +#define NO_WATER 1000000 + +char grf_list_file[256] = "tools/mapcache/grf_files.txt"; +char map_list_file[256] = "db/map_index.txt"; char map_cache_file[256] = "db/map_cache.dat"; +int rebuild = 0; -#define MAP_NAME_LENGTH 16 -#define NO_WATER 1000000 +FILE *map_cache_fp; + +unsigned long file_size; // Used internally, this structure contains the physical map cells struct map_data { @@ -26,31 +33,25 @@ struct map_data { }; // This is the main header found at the very beginning of the file -unsigned short map_count; +struct main_header { + unsigned long file_size; + unsigned short map_count; +} header; // This is the header appended before every compressed map cells info -struct map_cache_info { +struct map_info { char name[MAP_NAME_LENGTH]; - unsigned short index; short xs; short ys; long len; }; -FILE *map_cache_fp; - -int filesize; -/// Converts an unsigned short (16 bits) from current machine order to little-endian -unsigned short MakeUShortLE(unsigned short val) -{ - unsigned char buf[2]; - buf[0] = (unsigned char)( (val & 0x00FF) ); - buf[1] = (unsigned char)( (val & 0xFF00) >> 0x08 ); - return *((unsigned short*)buf); -} +/************************************* +* Big-endian compatibility functions * +*************************************/ -/// Converts a short (16 bits) from current machine order to little-endian +// Converts a short (16 bits) from current machine order to little-endian short MakeShortLE(short val) { unsigned char buf[2]; @@ -59,7 +60,7 @@ short MakeShortLE(short val) return *((short*)buf); } -/// Converts a long (32 bits) from current machine order to little-endian +// Converts a long (32 bits) from current machine order to little-endian long MakeLongLE(long val) { unsigned char buf[4]; @@ -70,7 +71,23 @@ long MakeLongLE(long val) return *((long*)buf); } -/// Reads an unsigned long (32 bits) in little-endian from the buffer +// Reads an unsigned short (16 bits) in little-endian from the buffer +unsigned short GetUShort(const unsigned char *buf) +{ + return ( ((unsigned short)(buf[0])) ) + |( ((unsigned short)(buf[1])) << 0x08 ); +} + +// Reads a long (32 bits) in little-endian from the buffer +long GetLong(const unsigned char *buf) +{ + return ( ((long)(buf[0])) ) + |( ((long)(buf[1])) << 0x08 ) + |( ((long)(buf[2])) << 0x10 ) + |( ((long)(buf[3])) << 0x18 ); +} + +// Reads an unsigned long (32 bits) in little-endian from the buffer unsigned long GetULong(const unsigned char *buf) { return ( ((unsigned long)(buf[0])) ) @@ -87,7 +104,7 @@ float GetFloat(const unsigned char *buf) } -// Read map from GRF's GAT and RSW files +// Reads a map from GRF's GAT and RSW files int read_map(char *name, struct map_data *m) { char filename[256]; @@ -143,31 +160,31 @@ int read_map(char *name, struct map_data *m) return 1; } -void cache_map(char *name, unsigned short index, struct map_data *m) +// Adds a map to the cache +void cache_map(char *name, struct map_data *m) { - struct map_cache_info info; - unsigned long len; - char *write_buf; + struct map_info info; + long len; + unsigned char *write_buf; // Create an output buffer twice as big as the uncompressed map... this way we're sure it fits len = m->xs*m->ys*2; - write_buf = (char *)malloc(len); + write_buf = (unsigned char *)malloc(len); // Compress the cells and get the compressed length - encode_zip((unsigned char *)write_buf, &len, m->cells, m->xs*m->ys); + encode_zip(write_buf, &len, m->cells, m->xs*m->ys); // Fill the map header strncpy(info.name, name, MAP_NAME_LENGTH); - info.index = MakeUShortLE(index); info.xs = MakeShortLE(m->xs); info.ys = MakeShortLE(m->ys); - info.len = MakeLongLE((long)len); + info.len = MakeLongLE(len); // Append map header then compressed cells at the end of the file - fseek(map_cache_fp, filesize, SEEK_SET); - fwrite(&info, sizeof(struct map_cache_info), 1, map_cache_fp); + fseek(map_cache_fp, header.file_size, SEEK_SET); + fwrite(&info, sizeof(struct map_info), 1, map_cache_fp); fwrite(write_buf, 1, len, map_cache_fp); - map_count++; - filesize += sizeof(struct map_cache_info) + len; + header.file_size += sizeof(struct map_info) + len; + header.map_count++; free(write_buf); free(m->cells); @@ -175,41 +192,111 @@ void cache_map(char *name, unsigned short index, struct map_data *m) return; } +// Checks whether a map is already is the cache +int find_map(char *name) +{ + int i; + struct map_info info; + + fseek(map_cache_fp, sizeof(struct main_header), SEEK_SET); + + for(i = 0; i < header.map_count; i++) { + fread(&info, sizeof(info), 1, map_cache_fp); + if(strcmp(name, info.name) == 0) // Map found + return 1; + else // Map not found, jump to the beginning of the next map info header + fseek(map_cache_fp, GetLong((unsigned char *)&(info.len)), SEEK_CUR); + } + + return 0; +} + +// Cuts the extension from a map name +char *remove_extension(char *mapname) +{ + char *ptr, *ptr2; + ptr = strchr(mapname, '.'); + if (ptr) { //Check and remove extension. + while (ptr[1] && (ptr2 = strchr(ptr+1, '.'))) + ptr = ptr2; //Skip to the last dot. + if(stricmp(ptr,".gat") == 0 || + stricmp(ptr,".afm") == 0 || + stricmp(ptr,".af2") == 0) + *ptr = '\0'; //Remove extension. + } + return mapname; +} + +// Processes command-line arguments +void process_args(int argc, char *argv[]) +{ + int i; + + for(i = 0; i < argc; i++) { + if(strcmp(argv[i], "-grf") == 0) { + if(++i < argc) + strcpy(grf_list_file, argv[i]); + } else if(strcmp(argv[i], "-list") == 0) { + if(++i < argc) + strcpy(map_list_file, argv[i]); + } else if(strcmp(argv[i], "-cache") == 0) { + if(++i < argc) + strcpy(map_cache_file, argv[i]); + } else if(strcmp(argv[i], "-rebuild") == 0) + rebuild = 1; + } + +} + int main(int argc, char *argv[]) { FILE *list; char line[1024]; struct map_data map; - char name[MAP_NAME_LENGTH]; - unsigned short index = 1; + char name[MAP_NAME_LENGTH_EXT]; - if(argc > 1) - strcpy(grf_list_file, argv[1]); - if(argc > 2) - strcpy(map_list_file, argv[2]); - if(argc > 3) - strcpy(map_cache_file, argv[3]); + // Process the command-line arguments + process_args(argc, argv); printf("Initializing grfio with %s\n", grf_list_file); grfio_init(grf_list_file); + // Attempt to open the map cache file and force rebuild if not found printf("Opening map cache: %s\n", map_cache_file); - map_cache_fp = fopen(map_cache_file, "wb"); - if( map_cache_fp == NULL ) { + if(!rebuild) { + map_cache_fp = fopen(map_cache_file, "rb"); + if(map_cache_fp == NULL) { + printf("Existing map cache not found, forcing rebuild mode\n"); + rebuild = 1; + } else + fclose(map_cache_fp); + } + if(rebuild) + map_cache_fp = fopen(map_cache_file, "w+b"); + else + map_cache_fp = fopen(map_cache_file, "r+b"); + if(map_cache_fp == NULL) { printf("Failure when opening map cache file %s\n", map_cache_file); exit(1); } + // Open the map list printf("Opening map list: %s\n", map_list_file); list = fopen(map_list_file, "r"); - if( list == NULL ) { + if(list == NULL) { printf("Failure when opening maps list file %s\n", map_list_file); - exit(1); + exit(2); } // Initialize the main header - map_count = 0; - filesize = sizeof(map_count); + if(rebuild) { + header.file_size = sizeof(struct main_header); + header.map_count = 0; + } else { + fread(&header, sizeof(struct main_header), 1, map_cache_fp); + header.file_size = GetULong((unsigned char *)&(header.file_size)); + header.map_count = GetUShort((unsigned char *)&(header.map_count)); + } // Read and process the map list while(fgets(line, 1020, list)){ @@ -217,30 +304,37 @@ int main(int argc, char *argv[]) if(line[0] == '/' && line[1] == '/') continue; - if(sscanf(line, "%16s %hu", name, &index) > 0) { // No defines in strings, 16 is hardcoded here - printf("Index %d : %s\n", index, name); - if(read_map(name, &map)) - cache_map(name, index, &map); - else - printf("Map file not found in GRF\n"); - // If the 2nd argument is omitted at next line, we'll keep last used index + 1 - index++; - } + if(sscanf(line, "%15s", name) < 1) + continue; + + if(strcmp("map:", name) == 0 && sscanf(line, "%*s %15s", name) < 1) + continue; + + remove_extension(name); + printf("%s", name); + if(find_map(name)) + printf(" already in cache!\n"); + else if(read_map(name, &map)) { + cache_map(name, &map); + printf(" successfully cached\n"); + } else + printf(" not found in GRF!\n"); + } printf("Closing map list: %s\n", map_list_file); fclose(list); - printf("Closing map cache: %s\n", map_cache_file); // Write the main header and close the map cache + printf("Closing map cache: %s\n", map_cache_file); fseek(map_cache_fp, 0, SEEK_SET); - fwrite(&map_count, sizeof(map_count), 1, map_cache_fp); + fwrite(&header, sizeof(struct main_header), 1, map_cache_fp); fclose(map_cache_fp); printf("Finalizing grfio\n"); grfio_final(); - printf("%d maps cached\n", map_count); + printf("%d maps now in cache\n", header.map_count); return 0; } diff --git a/tools/mapcache/grf_files.txt b/tools/mapcache/grf_files.txt new file mode 100644 index 000000000..21a3145bc --- /dev/null +++ b/tools/mapcache/grf_files.txt @@ -0,0 +1,15 @@ +//----------------------------------------- +// GRF List +// Add as many entries as you wish +//----------------------------------------- + +//grf: C:\Program Files\Gravity\RO\data.grf +grf: C:\Program Files\Gravity\RO\sdata.grf + +//----------------------------------------- +// Data Directory +// Path must include trailing backslash +// Only one entry supported! +//----------------------------------------- + +//data_dir: C:\Program Files\Gravity\RO\ -- cgit v1.2.3-70-g09d2