- Guild Castle code cleanup:

- all changes to guild castle data are now handled first by map-server and only sent to char-server for saving
  - ensured that changes made to guild castle during char-server disconnection time will be resent on reconnect
  - actually removed definition of `MAX_GUILDCASTLE` (r15657)

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@15658 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
gepard1984 2012-03-05 00:08:28 +00:00
parent f810293de3
commit 47fc6d2fe2
9 changed files with 119 additions and 146 deletions

View File

@ -1136,17 +1136,6 @@ int mapif_guild_castle_dataload(int fd, int sz, int *castle_ids)
return 0; return 0;
} }
int mapif_guild_castle_datasave(int fd, int castle_id, int index, int value)
{
WFIFOHEAD(fd, 9);
WFIFOW(fd, 0) = 0x3841;
WFIFOW(fd, 2) = castle_id;
WFIFOB(fd, 4) = index;
WFIFOL(fd, 5) = value;
WFIFOSET(fd, 9);
return 0;
}
//------------------------------------------------------------------- //-------------------------------------------------------------------
// Packet received from map server // Packet received from map server
@ -1776,24 +1765,18 @@ int mapif_parse_GuildCastleDataSave(int fd, int castle_id, int index, int value)
if (gc == NULL) { if (gc == NULL) {
ShowError("mapif_parse_GuildCastleDataSave: castle id=%d not found\n", castle_id); ShowError("mapif_parse_GuildCastleDataSave: castle id=%d not found\n", castle_id);
mapif_guild_castle_datasave(fd, castle_id, index, value);
return 0; return 0;
} }
switch (index) { switch (index) {
case 1: case 1:
if (gc->guild_id != value) { if (log_inter && gc->guild_id != value) {
int gid = (value) ? value : gc->guild_id; int gid = (value) ? value : gc->guild_id;
struct guild *g = idb_get(guild_db_, gid); struct guild *g = idb_get(guild_db_, gid);
if (log_inter) inter_log("guild %s (id=%d) %s castle id=%d\n",
inter_log("guild %s (id=%d) %s castle id=%d\n", (g) ? g->name : "??", gid, (value) ? "occupy" : "abandon", castle_id);
(g) ? g->name : "??", gid, (value) ? "occupy" : "abandon", castle_id);
} }
gc->guild_id = value; gc->guild_id = value;
if (gc->guild_id == 0) {
// Delete guardians.
memset(gc->guardian, 0, sizeof(gc->guardian));
}
break; break;
case 2: gc->economy = value; break; case 2: gc->economy = value; break;
case 3: gc->defense = value; break; case 3: gc->defense = value; break;
@ -1812,7 +1795,6 @@ int mapif_parse_GuildCastleDataSave(int fd, int castle_id, int index, int value)
return 0; return 0;
} }
inter_guildcastle_tosql(gc); inter_guildcastle_tosql(gc);
mapif_guild_castle_datasave(fd, gc->castle_id, index, value);
return 0; return 0;
} }

View File

@ -106,7 +106,6 @@
#define MAX_GUILDEXPULSION 32 #define MAX_GUILDEXPULSION 32
#define MAX_GUILDALLIANCE 16 #define MAX_GUILDALLIANCE 16
#define MAX_GUILDSKILL 15 // increased max guild skills because of new skills [Sara-chan] #define MAX_GUILDSKILL 15 // increased max guild skills because of new skills [Sara-chan]
#define MAX_GUILDCASTLE 34 // Updated to include new entries for WoE:SE. [L0ne_W0lf]
#define MAX_GUILDLEVEL 50 #define MAX_GUILDLEVEL 50
#define MAX_GUARDIANS 8 //Local max per castle. [Skotlex] #define MAX_GUARDIANS 8 //Local max per castle. [Skotlex]
#define MAX_QUEST_DB 2000 //Max quests that the server will load #define MAX_QUEST_DB 2000 //Max quests that the server will load

View File

@ -510,6 +510,9 @@ void chrif_on_ready(void)
//Re-save any storages that were modified in the disconnection time. [Skotlex] //Re-save any storages that were modified in the disconnection time. [Skotlex]
do_reconnect_storage(); do_reconnect_storage();
//Re-save any guild castles that were modified in the disconnection time.
guild_castle_reconnect(-1, 0, 0);
} }

View File

@ -1530,16 +1530,21 @@ int guild_broken_sub(DBKey key,void *data,va_list ap)
} }
//Invoked on Castles when a guild is broken. [Skotlex] //Invoked on Castles when a guild is broken. [Skotlex]
int castle_guild_broken_sub(DBKey key,void *data,va_list ap) int castle_guild_broken_sub(DBKey key, void *data, va_list ap)
{ {
struct guild_castle *gc=(struct guild_castle *)data; char name[EVENT_NAME_LENGTH];
int guild_id=va_arg(ap,int); struct guild_castle *gc = data;
int guild_id = va_arg(ap, int);
nullpo_ret(gc); nullpo_ret(gc);
if (gc->guild_id == guild_id) if (gc->guild_id == guild_id) {
{ //Save the new 'owner', this should invoke guardian clean up and other such things. // We call castle_event::OnGuildBreak of all castles of the guild
gc->guild_id = 0; // You can set all castle_events in the 'db/castle_db.txt'
safestrncpy(name, gc->castle_event, sizeof(name));
npc_event_do(strcat(name, "::OnGuildBreak"));
//Save the new 'owner', this should invoke guardian clean up and other such things.
guild_castledatasave(gc->castle_id, 1, 0); guild_castledatasave(gc->castle_id, 1, 0);
} }
return 0; return 0;
@ -1549,26 +1554,12 @@ int castle_guild_broken_sub(DBKey key,void *data,va_list ap)
int guild_broken(int guild_id,int flag) int guild_broken(int guild_id,int flag)
{ {
struct guild *g = guild_search(guild_id); struct guild *g = guild_search(guild_id);
struct guild_castle *gc = NULL;
DBIterator *iter = NULL;
struct map_session_data *sd = NULL; struct map_session_data *sd = NULL;
int i; int i;
char name[EVENT_NAME_LENGTH];
if(flag!=0 || g==NULL) if(flag!=0 || g==NULL)
return 0; return 0;
//we call castle_event::OnGuildBreak of all castles of the guild
//you can set all castle_events in the castle_db.txt
iter = db_iterator(castle_db);
for (gc = dbi_first(iter); dbi_exists(iter); gc = dbi_next(iter)) {
if (gc->guild_id == guild_id) {
safestrncpy(name, gc->castle_event, sizeof(name));
npc_event_do(strcat(name, "::OnGuildBreak"));
}
}
dbi_destroy(iter);
for(i=0;i<g->max_member;i++){ // ギルド解散を通知 for(i=0;i<g->max_member;i++){ // ギルド解散を通知
if((sd=g->member[i].sd)!=NULL){ if((sd=g->member[i].sd)!=NULL){
if(sd->state.storage_flag == 2) if(sd->state.storage_flag == 2)
@ -1716,60 +1707,99 @@ void guild_castle_map_init(void)
} }
} }
// ギルド城データ変更要求 /**
int guild_castledatasave(int castle_id,int index,int value) * Setter function for members of guild_castle struct.
* Handles all side-effects, like updating guardians.
* Sends updated info to char-server for saving.
* @param castle_id Castle ID
* @param index Type of data to change
* @param value New value
*/
int guild_castledatasave(int castle_id, int index, int value)
{ {
if( index == 1 ) struct guild_castle *gc = guild_castle_search(castle_id);
{ //The castle's owner has changed? Update Guardian ownership, too. [Skotlex]
struct guild_castle *gc = guild_castle_search(castle_id);
int m = -1;
if (gc) m = map_mapindex2mapid(gc->mapindex);
if (m != -1)
map_foreachinmap(mob_guardian_guildchange, m, BL_MOB); //FIXME: why not iterate over gc->guardian[i].id ?
}
else
if( index == 3 )
{ // defense invest change -> recalculate guardian hp
struct guild_castle* gc = guild_castle_search(castle_id);
if( gc )
{
int i;
struct mob_data* gd;
for( i = 0; i < MAX_GUARDIANS; i++ )
if( gc->guardian[i].visible && (gd = map_id2md(gc->guardian[i].id)) != NULL )
status_calc_mob(gd,0);
}
}
return intif_guild_castle_datasave(castle_id, index, value); // FIXME: it may fail if char-server is disconnected if (gc == NULL) {
} ShowWarning("guild_castledatasave: guild castle '%d' not found\n", castle_id);
// ギルド城データ変更通知
int guild_castledatasaveack(int castle_id,int index,int value)
{
struct guild_castle *gc=guild_castle_search(castle_id);
if(gc==NULL){
return 0; return 0;
} }
switch(index){
case 1: gc->guild_id = value; break; switch (index) {
case 2: gc->economy = value; break; case 1: // The castle's owner has changed? Update or remove Guardians too. [Skotlex]
case 3: gc->defense = value; break; {
case 4: gc->triggerE = value; break; int i;
case 5: gc->triggerD = value; break; struct mob_data *gd;
case 6: gc->nextTime = value; break; gc->guild_id = value;
case 7: gc->payTime = value; break; for (i = 0; i < MAX_GUARDIANS; i++)
case 8: gc->createTime = value; break; if (gc->guardian[i].visible && (gd = map_id2md(gc->guardian[i].id)) != NULL)
case 9: gc->visibleC = value; break; mob_guardian_guildchange(gd);
break;
}
case 2:
gc->economy = value; break;
case 3: // defense invest change -> recalculate guardian hp
{
int i;
struct mob_data *gd;
gc->defense = value;
for (i = 0; i < MAX_GUARDIANS; i++)
if (gc->guardian[i].visible && (gd = map_id2md(gc->guardian[i].id)) != NULL)
status_calc_mob(gd, 0);
break;
}
case 4:
gc->triggerE = value; break;
case 5:
gc->triggerD = value; break;
case 6:
gc->nextTime = value; break;
case 7:
gc->payTime = value; break;
case 8:
gc->createTime = value; break;
case 9:
gc->visibleC = value; break;
default: default:
if (index > 9 && index <= 9+MAX_GUARDIANS) { if (index > 9 && index <= 9+MAX_GUARDIANS) {
gc->guardian[index-10].visible = value; gc->guardian[index-10].visible = value;
break; break;
} }
ShowError("guild_castledatasaveack: not found index=%d\n", index); ShowWarning("guild_castledatasave: index = '%d' is out of allowed range\n", index);
return 0; return 0;
} }
return 1;
if (!intif_guild_castle_datasave(castle_id, index, value)) {
guild_castle_reconnect(castle_id, index, value);
}
return 0;
}
void guild_castle_reconnect_sub(void *key, void *data, va_list ap)
{
int castle_id = GetWord((int)key, 0);
int index = GetWord((int)key, 1);
intif_guild_castle_datasave(castle_id, index, *(int *)data);
aFree(data);
}
/**
* Saves pending guild castle data changes when char-server is
* disconnected.
* On reconnect pushes all changes to char-server for saving.
*/
void guild_castle_reconnect(int castle_id, int index, int value)
{
static struct linkdb_node *gc_save_pending = NULL;
if (castle_id < 0) { // char-server reconnected
linkdb_foreach(&gc_save_pending, guild_castle_reconnect_sub);
linkdb_final(&gc_save_pending);
} else {
int *data;
CREATE(data, int, 1);
*data = value;
linkdb_replace(&gc_save_pending, (void*)(MakeDWord(castle_id, index)), data);
}
} }
// ギルドデータ一括受信(初期化時) // ギルドデータ一括受信(初期化時)

View File

@ -91,10 +91,9 @@ int guild_gm_change(int guild_id, struct map_session_data *sd);
int guild_gm_changed(int guild_id, int account_id, int char_id); int guild_gm_changed(int guild_id, int account_id, int char_id);
void guild_castle_map_init(void); void guild_castle_map_init(void);
int guild_castledataload(int castle_id,int index);
int guild_castledatasave(int castle_id,int index,int value); int guild_castledatasave(int castle_id,int index,int value);
int guild_castledatasaveack(int castle_id,int index,int value);
int guild_castledataloadack(int len, struct guild_castle *gc); int guild_castledataloadack(int len, struct guild_castle *gc);
void guild_castle_reconnect(int castle_id, int index, int value);
int guild_agit_start(void); int guild_agit_start(void);
int guild_agit_end(void); int guild_agit_end(void);

View File

@ -36,7 +36,7 @@ static const int packet_len_table[]={
0, 0, 0, 0, 0, 0, 0, 0, -1,11, 0, 0, 0, 0, 0, 0, //0x3810 0, 0, 0, 0, 0, 0, 0, 0, -1,11, 0, 0, 0, 0, 0, 0, //0x3810
39,-1,15,15, 14,19, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3820 39,-1,15,15, 14,19, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3820
10,-1,15, 0, 79,19, 7,-1, 0,-1,-1,-1, 14,67,186,-1, //0x3830 10,-1,15, 0, 79,19, 7,-1, 0,-1,-1,-1, 14,67,186,-1, //0x3830
-1, 9, 0,14, 0, 0, 0, 0, -1,74,-1,11, 11,-1, 0, 0, //0x3840 -1, 0, 0,14, 0, 0, 0, 0, -1,74,-1,11, 11,-1, 0, 0, //0x3840
-1,-1, 7, 7, 7,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3850 Auctions [Zephyrus] -1,-1, 7, 7, 7,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3850 Auctions [Zephyrus]
-1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3860 Quests [Kevin] [Inkfish] -1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3860 Quests [Kevin] [Inkfish]
-1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3870 Mercenaries [Zephyrus] -1, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0x3870 Mercenaries [Zephyrus]
@ -749,7 +749,7 @@ int intif_guild_castle_datasave(int castle_id,int index, int value)
WFIFOB(inter_fd,4)=index; WFIFOB(inter_fd,4)=index;
WFIFOL(inter_fd,5)=value; WFIFOL(inter_fd,5)=value;
WFIFOSET(inter_fd,9); WFIFOSET(inter_fd,9);
return 0; return 1;
} }
//----------------------------------------------------------------- //-----------------------------------------------------------------
@ -1209,11 +1209,6 @@ int intif_parse_GuildCastleDataLoad(int fd)
{ {
return guild_castledataloadack(RFIFOW(fd,2), (struct guild_castle *)RFIFOP(fd,4)); return guild_castledataloadack(RFIFOW(fd,2), (struct guild_castle *)RFIFOP(fd,4));
} }
// ギルド城データ変更通知
int intif_parse_GuildCastleDataSave(int fd)
{
return guild_castledatasaveack(RFIFOW(fd,2),RFIFOB(fd,4),RFIFOL(fd,5));
}
int intif_parse_GuildMasterChanged(int fd) int intif_parse_GuildMasterChanged(int fd)
{ {
@ -2037,7 +2032,6 @@ int intif_parse(int fd)
case 0x383e: intif_parse_GuildNotice(fd); break; case 0x383e: intif_parse_GuildNotice(fd); break;
case 0x383f: intif_parse_GuildEmblem(fd); break; case 0x383f: intif_parse_GuildEmblem(fd); break;
case 0x3840: intif_parse_GuildCastleDataLoad(fd); break; case 0x3840: intif_parse_GuildCastleDataLoad(fd); break;
case 0x3841: intif_parse_GuildCastleDataSave(fd); break;
case 0x3843: intif_parse_GuildMasterChanged(fd); break; case 0x3843: intif_parse_GuildMasterChanged(fd); break;
//Quest system //Quest system

View File

@ -548,11 +548,8 @@ static int mob_spawn_guardian_sub(int tid, unsigned int tick, int id, intptr_t d
guild_castledatasave(md->guardian_data->castle->castle_id, 1, 0); guild_castledatasave(md->guardian_data->castle->castle_id, 1, 0);
} }
} else { } else {
if( md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS && md->guardian_data->castle->guardian[md->guardian_data->number].visible ) if (md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS && md->guardian_data->castle->guardian[md->guardian_data->number].visible)
{ //Safe removal of guardian.
md->guardian_data->castle->guardian[md->guardian_data->number].visible = 0;
guild_castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number,0); guild_castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number,0);
}
unit_free(&md->bl,CLR_OUTSIGHT); //Remove guardian. unit_free(&md->bl,CLR_OUTSIGHT); //Remove guardian.
} }
return 0; return 0;
@ -2512,13 +2509,10 @@ void mob_revive(struct mob_data *md, unsigned int hp)
clif_charnameack (0, &md->bl); clif_charnameack (0, &md->bl);
} }
int mob_guardian_guildchange(struct block_list *bl,va_list ap) int mob_guardian_guildchange(struct mob_data *md)
{ {
struct mob_data *md; struct guild *g;
struct guild* g; nullpo_ret(md);
nullpo_ret(bl);
nullpo_ret(md = (struct mob_data *)bl);
if (!md->guardian_data) if (!md->guardian_data)
return 0; return 0;
@ -2531,11 +2525,8 @@ int mob_guardian_guildchange(struct block_list *bl,va_list ap)
md->guardian_data->emblem_id = 0; md->guardian_data->emblem_id = 0;
md->guardian_data->guild_name[0] = '\0'; md->guardian_data->guild_name[0] = '\0';
} else { } else {
if( md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS && md->guardian_data->castle->guardian[md->guardian_data->number].visible ) if (md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS && md->guardian_data->castle->guardian[md->guardian_data->number].visible)
{ //Safe removal of guardian. guild_castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number, 0);
md->guardian_data->castle->guardian[md->guardian_data->number].visible = 0;
guild_castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number,0);
}
unit_free(&md->bl,CLR_OUTSIGHT); //Remove guardian. unit_free(&md->bl,CLR_OUTSIGHT); //Remove guardian.
} }
return 0; return 0;
@ -2545,11 +2536,8 @@ int mob_guardian_guildchange(struct block_list *bl,va_list ap)
if (g == NULL) if (g == NULL)
{ //Properly remove guardian info from Castle data. { //Properly remove guardian info from Castle data.
ShowError("mob_guardian_guildchange: New Guild (id %d) does not exists!\n", md->guardian_data->guild_id); ShowError("mob_guardian_guildchange: New Guild (id %d) does not exists!\n", md->guardian_data->guild_id);
if( md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS ) if (md->guardian_data->number >= 0 && md->guardian_data->number < MAX_GUARDIANS)
{ guild_castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number, 0);
md->guardian_data->castle->guardian[md->guardian_data->number].visible = 0;
guild_castledatasave(md->guardian_data->castle->castle_id, 10+md->guardian_data->number,0);
}
unit_free(&md->bl,CLR_OUTSIGHT); unit_free(&md->bl,CLR_OUTSIGHT);
return 0; return 0;
} }

View File

@ -237,7 +237,7 @@ bool mob_ksprotected (struct block_list *src, struct block_list *target);
int mob_spawn_guardian(const char* mapname, short x, short y, const char* mobname, int class_, const char* event, int guardian, bool has_index); // Spawning Guardians [Valaris] int mob_spawn_guardian(const char* mapname, short x, short y, const char* mobname, int class_, const char* event, int guardian, bool has_index); // Spawning Guardians [Valaris]
int mob_spawn_bg(const char* mapname, short x, short y, const char* mobname, int class_, const char* event, unsigned int bg_id); int mob_spawn_bg(const char* mapname, short x, short y, const char* mobname, int class_, const char* event, unsigned int bg_id);
int mob_guardian_guildchange(struct block_list *bl,va_list ap); //Change Guardian's ownership. [Skotlex] int mob_guardian_guildchange(struct mob_data *md); //Change Guardian's ownership. [Skotlex]
int mob_randomwalk(struct mob_data *md,unsigned int tick); int mob_randomwalk(struct mob_data *md,unsigned int tick);
int mob_warpchase(struct mob_data *md, struct block_list *target); int mob_warpchase(struct mob_data *md, struct block_list *target);

View File

@ -10145,7 +10145,7 @@ BUILDIN_FUNC(getcastledata)
if (gc == NULL) { if (gc == NULL) {
script_pushint(st,0); script_pushint(st,0);
ShowWarning("builtin_setcastledata: guild castle for map '%s' not found\n", mapname); ShowWarning("buildin_setcastledata: guild castle for map '%s' not found\n", mapname);
return 1; return 1;
} }
@ -10182,43 +10182,21 @@ BUILDIN_FUNC(getcastledata)
BUILDIN_FUNC(setcastledata) BUILDIN_FUNC(setcastledata)
{ {
const char* mapname = mapindex_getmapname(script_getstr(st,2),NULL); const char *mapname = mapindex_getmapname(script_getstr(st,2),NULL);
int index = script_getnum(st,3); int index = script_getnum(st,3);
int value = script_getnum(st,4); int value = script_getnum(st,4);
struct guild_castle* gc = guild_mapname2gc(mapname); struct guild_castle *gc = guild_mapname2gc(mapname);
if (gc == NULL) { if (gc == NULL) {
ShowWarning("builtin_setcastledata: guild castle for map '%s' not found\n", mapname); ShowWarning("buildin_setcastledata: guild castle for map '%s' not found\n", mapname);
return 1; return 1;
} }
switch (index) { if (index <= 0 || index > 9+MAX_GUARDIANS) {
case 1: ShowWarning("buildin_setcastledata: index = '%d' is out of allowed range\n", index);
gc->guild_id = value; break; return 1;
case 2:
gc->economy = value; break;
case 3:
gc->defense = value; break;
case 4:
gc->triggerE = value; break;
case 5:
gc->triggerD = value; break;
case 6:
gc->nextTime = value; break;
case 7:
gc->payTime = value; break;
case 8:
gc->createTime = value; break;
case 9:
gc->visibleC = value; break;
default:
if (index > 9 && index <= 9+MAX_GUARDIANS) {
gc->guardian[index-10].visible = value;
break;
}
ShowWarning("buildin_setcastledata: index = '%d' is out of allowed range\n", index);
return 1;
} }
guild_castledatasave(gc->castle_id, index, value); guild_castledatasave(gc->castle_id, index, value);
return 0; return 0;
} }