diff options
author | gepard1984 <gepard1984@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2012-03-04 18:37:29 +0000 |
---|---|---|
committer | gepard1984 <gepard1984@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2012-03-04 18:37:29 +0000 |
commit | 262e60ab0b9cfc1f942a7b3ef11f7ed3abc7b208 (patch) | |
tree | 82cb02f8048521c7479ff012511a066612f6d439 /src | |
parent | ce4352cfef6f07bf3b4c0324f48f880c5c74f041 (diff) | |
download | hercules-262e60ab0b9cfc1f942a7b3ef11f7ed3abc7b208.tar.gz hercules-262e60ab0b9cfc1f942a7b3ef11f7ed3abc7b208.tar.bz2 hercules-262e60ab0b9cfc1f942a7b3ef11f7ed3abc7b208.tar.xz hercules-262e60ab0b9cfc1f942a7b3ef11f7ed3abc7b208.zip |
- Guild Castle code cleanup:
- removed `MAX_GUILDCASTLE` limit
- char-server now caches guild castles in `DBMap`
- improved guild castle SQL queries to support non-default values of `MAX_GUARDIANS`
- disallowed declaring guild castles on maps that are on other map-servers
- map-server now requests data for all guild castles from char-server on initial connect (bugreport:287)
- removed ''guildcastleinfo events'' as they were esentially duplicated ''OnAgitInit''
- optimized castle data load packets (bugreport:287)
- updated WoE scripts to reflect source changes (scripts no longer need or should request castle or guild data)
- updated related docs
- Added `db_size` macro.
- Replaced manual counting of castles occupied by a guild with `guild_checkcastles()` calls.
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@15657 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src')
-rw-r--r-- | src/char/int_guild.c | 326 | ||||
-rw-r--r-- | src/char/int_guild.h | 1 | ||||
-rw-r--r-- | src/char/inter.c | 4 | ||||
-rw-r--r-- | src/common/db.h | 1 | ||||
-rw-r--r-- | src/map/chrif.c | 1 | ||||
-rw-r--r-- | src/map/clif.c | 10 | ||||
-rw-r--r-- | src/map/guild.c | 140 | ||||
-rw-r--r-- | src/map/guild.h | 5 | ||||
-rw-r--r-- | src/map/intif.c | 33 | ||||
-rw-r--r-- | src/map/intif.h | 2 | ||||
-rw-r--r-- | src/map/script.c | 138 |
11 files changed, 266 insertions, 395 deletions
diff --git a/src/char/int_guild.c b/src/char/int_guild.c index 3b41e375f..912ee8ab1 100644 --- a/src/char/int_guild.c +++ b/src/char/int_guild.c @@ -32,8 +32,7 @@ static const char dataToHex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9 //Guild cache static DBMap* guild_db_; // int guild_id -> struct guild* - -struct guild_castle castles[MAX_GUILDCASTLE]; +static DBMap *castle_db; static unsigned int guild_exp[100]; @@ -525,92 +524,78 @@ struct guild * inter_guild_fromsql(int guild_id) return g; } +// `guild_castle` (`castle_id`, `guild_id`, `economy`, `defense`, `triggerE`, `triggerD`, `nextTime`, `payTime`, `createTime`, `visibleC`, `visibleG0`, `visibleG1`, `visibleG2`, `visibleG3`, `visibleG4`, `visibleG5`, `visibleG6`, `visibleG7`) int inter_guildcastle_tosql(struct guild_castle *gc) { - // `guild_castle` (`castle_id`, `guild_id`, `economy`, `defense`, `triggerE`, `triggerD`, `nextTime`, `payTime`, `createTime`, `visibleC`, `visibleG0`, `visibleG1`, `visibleG2`, `visibleG3`, `visibleG4`, `visibleG5`, `visibleG6`, `visibleG7`) - - if (gc==NULL) return 0; - #ifdef GUILD_DEBUG -ShowDebug("Save guild_castle (%d)\n", gc->castle_id); - #endif - -// sql_query("DELETE FROM `%s` WHERE `castle_id`='%d'",guild_castle_db, gc->castle_id); - if( SQL_ERROR == Sql_Query(sql_handle, "REPLACE INTO `%s` " - "(`castle_id`, `guild_id`, `economy`, `defense`, `triggerE`, `triggerD`, `nextTime`, `payTime`, `createTime`," - "`visibleC`, `visibleG0`, `visibleG1`, `visibleG2`, `visibleG3`, `visibleG4`, `visibleG5`, `visibleG6`, `visibleG7`)" - "VALUES ('%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d','%d')", - guild_castle_db, gc->castle_id, gc->guild_id, gc->economy, gc->defense, gc->triggerE, gc->triggerD, gc->nextTime, gc->payTime, gc->createTime, gc->visibleC, - gc->guardian[0].visible, gc->guardian[1].visible, gc->guardian[2].visible, gc->guardian[3].visible, gc->guardian[4].visible, gc->guardian[5].visible, gc->guardian[6].visible, gc->guardian[7].visible) ) + StringBuf buf; + int i; + + StringBuf_Init(&buf); + StringBuf_Printf(&buf, "REPLACE INTO `%s` SET `castle_id`='%d', `guild_id`='%d', `economy`='%d', `defense`='%d', " + "`triggerE`='%d', `triggerD`='%d', `nextTime`='%d', `payTime`='%d', `createTime`='%d', `visibleC`='%d'", + guild_castle_db, gc->castle_id, gc->guild_id, gc->economy, gc->defense, + gc->triggerE, gc->triggerD, gc->nextTime, gc->payTime, gc->createTime, gc->visibleC); + for (i = 0; i < MAX_GUARDIANS; ++i) + StringBuf_Printf(&buf, ", `visibleG%d`='%d'", i, gc->guardian[i].visible); + + if (SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf))) Sql_ShowDebug(sql_handle); + else if(save_log) + ShowInfo("Saved guild castle (%d)\n", gc->castle_id); - memcpy(&castles[gc->castle_id],gc,sizeof(struct guild_castle)); + StringBuf_Destroy(&buf); return 0; } -// Read guild_castle from sql -int inter_guildcastle_fromsql(int castle_id,struct guild_castle *gc) +// Read guild_castle from SQL +static struct guild_castle* inter_guildcastle_fromsql(int castle_id) { - static int castles_init=0; - char* data; - - if (gc==NULL) return 0; - if (castle_id==-1) return 0; - - if(!castles_init) - { - int i; - for(i=0;i<MAX_GUILDCASTLE;i++) - castles[i].castle_id=-1; - castles_init = 1; - } - - if(castles[castle_id].castle_id == castle_id) - { - memcpy(gc,&castles[castle_id],sizeof(struct guild_castle)); - return 1; - } - - memset(gc,0,sizeof(struct guild_castle)); - if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `castle_id`, `guild_id`, `economy`, `defense`, `triggerE`, `triggerD`, `nextTime`, `payTime`, `createTime`, " - "`visibleC`, `visibleG0`, `visibleG1`, `visibleG2`, `visibleG3`, `visibleG4`, `visibleG5`, `visibleG6`, `visibleG7`" - " FROM `%s` WHERE `castle_id`='%d'", guild_castle_db, castle_id) ) - { + char *data; + int i; + StringBuf buf; + struct guild_castle *gc = idb_get(castle_db, castle_id); + + if (gc != NULL) + return gc; + + StringBuf_Init(&buf); + StringBuf_AppendStr(&buf, "SELECT `castle_id`, `guild_id`, `economy`, `defense`, `triggerE`, " + "`triggerD`, `nextTime`, `payTime`, `createTime`, `visibleC`"); + for (i = 0; i < MAX_GUARDIANS; ++i) + StringBuf_Printf(&buf, ", `visibleG%d`", i); + StringBuf_Printf(&buf, " FROM `%s` WHERE `castle_id`='%d'", guild_castle_db, castle_id); + if (SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf))) { Sql_ShowDebug(sql_handle); - return 0; + StringBuf_Destroy(&buf); + return NULL; + } + StringBuf_Destroy(&buf); + + CREATE(gc, struct guild_castle, 1); + gc->castle_id = castle_id; + + if (SQL_SUCCESS == Sql_NextRow(sql_handle)) { + Sql_GetData(sql_handle, 1, &data, NULL); gc->guild_id = atoi(data); + Sql_GetData(sql_handle, 2, &data, NULL); gc->economy = atoi(data); + Sql_GetData(sql_handle, 3, &data, NULL); gc->defense = atoi(data); + Sql_GetData(sql_handle, 4, &data, NULL); gc->triggerE = atoi(data); + Sql_GetData(sql_handle, 5, &data, NULL); gc->triggerD = atoi(data); + Sql_GetData(sql_handle, 6, &data, NULL); gc->nextTime = atoi(data); + Sql_GetData(sql_handle, 7, &data, NULL); gc->payTime = atoi(data); + Sql_GetData(sql_handle, 8, &data, NULL); gc->createTime = atoi(data); + Sql_GetData(sql_handle, 9, &data, NULL); gc->visibleC = atoi(data); + for (i = 10; i < 10+MAX_GUARDIANS; i++) { + Sql_GetData(sql_handle, i, &data, NULL); gc->guardian[i-10].visible = atoi(data); + } } - // ARU: This needs to be set even if there are no SQL results - gc->castle_id=castle_id; - if( SQL_SUCCESS != Sql_NextRow(sql_handle) ) - { - Sql_FreeResult(sql_handle); - return 1; //Assume empty castle. - } - - Sql_GetData(sql_handle, 1, &data, NULL); gc->guild_id = atoi(data); - Sql_GetData(sql_handle, 2, &data, NULL); gc->economy = atoi(data); - Sql_GetData(sql_handle, 3, &data, NULL); gc->defense = atoi(data); - Sql_GetData(sql_handle, 4, &data, NULL); gc->triggerE = atoi(data); - Sql_GetData(sql_handle, 5, &data, NULL); gc->triggerD = atoi(data); - Sql_GetData(sql_handle, 6, &data, NULL); gc->nextTime = atoi(data); - Sql_GetData(sql_handle, 7, &data, NULL); gc->payTime = atoi(data); - Sql_GetData(sql_handle, 8, &data, NULL); gc->createTime = atoi(data); - Sql_GetData(sql_handle, 9, &data, NULL); gc->visibleC = atoi(data); - Sql_GetData(sql_handle, 10, &data, NULL); gc->guardian[0].visible = atoi(data); - Sql_GetData(sql_handle, 11, &data, NULL); gc->guardian[1].visible = atoi(data); - Sql_GetData(sql_handle, 12, &data, NULL); gc->guardian[2].visible = atoi(data); - Sql_GetData(sql_handle, 13, &data, NULL); gc->guardian[3].visible = atoi(data); - Sql_GetData(sql_handle, 14, &data, NULL); gc->guardian[4].visible = atoi(data); - Sql_GetData(sql_handle, 15, &data, NULL); gc->guardian[5].visible = atoi(data); - Sql_GetData(sql_handle, 16, &data, NULL); gc->guardian[6].visible = atoi(data); - Sql_GetData(sql_handle, 17, &data, NULL); gc->guardian[7].visible = atoi(data); - Sql_FreeResult(sql_handle); - memcpy(&castles[castle_id],gc,sizeof(struct guild_castle)); - if( save_log ) - ShowInfo("Loaded Castle %d (guild %d)\n", castle_id, gc->guild_id); + idb_put(castle_db, castle_id, gc); - return 1; + if (save_log) + ShowInfo("Loaded guild castle (%d - guild %d)\n", castle_id, gc->guild_id); + + return gc; } @@ -752,6 +737,7 @@ int inter_guild_sql_init(void) { //Initialize the guild cache guild_db_= idb_alloc(DB_OPT_RELEASE_DATA); + castle_db = idb_alloc(DB_OPT_RELEASE_DATA); //Read exp file inter_guild_ReadEXP(); @@ -774,6 +760,7 @@ static int guild_db_final(DBKey key, void *data, va_list ap) void inter_guild_sql_final(void) { guild_db_->destroy(guild_db_, guild_db_final); + db_destroy(castle_db); return; } @@ -1131,76 +1118,34 @@ int mapif_guild_master_changed(struct guild *g, int aid, int cid) return 0; } -int mapif_guild_castle_dataload(int castle_id,int index,int value) -{ - unsigned char buf[9]; - WBUFW(buf, 0)=0x3840; - WBUFW(buf, 2)=castle_id; - WBUFB(buf, 4)=index; - WBUFL(buf, 5)=value; - mapif_sendall(buf,9); - return 0; -} - -int mapif_guild_castle_datasave(int castle_id,int index,int value) +int mapif_guild_castle_dataload(int fd, int sz, int *castle_ids) { - unsigned char buf[9]; - WBUFW(buf, 0)=0x3841; - WBUFW(buf, 2)=castle_id; - WBUFB(buf, 4)=index; - WBUFL(buf, 5)=value; - mapif_sendall(buf,9); - return 0; -} - -int mapif_guild_castle_alldataload(int fd) -{ - struct guild_castle s_gc; - struct guild_castle* gc = &s_gc; + struct guild_castle *gc = NULL; + int num = (sz - 4) / sizeof(int); + int len = 4 + num * sizeof(*gc); int i; - int len; - char* data; - WFIFOHEAD(fd, 4 + MAX_GUILDCASTLE*sizeof(struct guild_castle)); - WFIFOW(fd, 0) = 0x3842; - if( SQL_ERROR == Sql_Query(sql_handle, - "SELECT `castle_id`, `guild_id`, `economy`, `defense`, `triggerE`, `triggerD`, `nextTime`, `payTime`, `createTime`," - " `visibleC`, `visibleG0`, `visibleG1`, `visibleG2`, `visibleG3`, `visibleG4`, `visibleG5`, `visibleG6`, `visibleG7`" - " FROM `%s` ORDER BY `castle_id`", guild_castle_db) ) - Sql_ShowDebug(sql_handle); - for( i = 0, len = 4; i < MAX_GUILDCASTLE && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i ) - { - memset(gc, 0, sizeof(struct guild_castle)); - - Sql_GetData(sql_handle, 0, &data, NULL); gc->castle_id = atoi(data); - Sql_GetData(sql_handle, 1, &data, NULL); gc->guild_id = atoi(data); - Sql_GetData(sql_handle, 2, &data, NULL); gc->economy = atoi(data); - Sql_GetData(sql_handle, 3, &data, NULL); gc->defense = atoi(data); - Sql_GetData(sql_handle, 4, &data, NULL); gc->triggerE = atoi(data); - Sql_GetData(sql_handle, 5, &data, NULL); gc->triggerD = atoi(data); - Sql_GetData(sql_handle, 6, &data, NULL); gc->nextTime = atoi(data); - Sql_GetData(sql_handle, 7, &data, NULL); gc->payTime = atoi(data); - Sql_GetData(sql_handle, 8, &data, NULL); gc->createTime = atoi(data); - Sql_GetData(sql_handle, 9, &data, NULL); gc->visibleC = atoi(data); - Sql_GetData(sql_handle, 10, &data, NULL); gc->guardian[0].visible = atoi(data); - Sql_GetData(sql_handle, 11, &data, NULL); gc->guardian[1].visible = atoi(data); - Sql_GetData(sql_handle, 12, &data, NULL); gc->guardian[2].visible = atoi(data); - Sql_GetData(sql_handle, 13, &data, NULL); gc->guardian[3].visible = atoi(data); - Sql_GetData(sql_handle, 14, &data, NULL); gc->guardian[4].visible = atoi(data); - Sql_GetData(sql_handle, 15, &data, NULL); gc->guardian[5].visible = atoi(data); - Sql_GetData(sql_handle, 16, &data, NULL); gc->guardian[6].visible = atoi(data); - Sql_GetData(sql_handle, 17, &data, NULL); gc->guardian[7].visible = atoi(data); - - memcpy(WFIFOP(fd, len), gc, sizeof(struct guild_castle)); - len += sizeof(struct guild_castle); - } - Sql_FreeResult(sql_handle); + WFIFOHEAD(fd, len); + WFIFOW(fd, 0) = 0x3840; WFIFOW(fd, 2) = len; + for (i = 0; i < num; i++) { + gc = inter_guildcastle_fromsql(*(castle_ids++)); + memcpy(WFIFOP(fd, 4 + i * sizeof(*gc)), gc, sizeof(*gc)); + } WFIFOSET(fd, len); - 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 @@ -1820,69 +1765,54 @@ int mapif_parse_GuildEmblem(int fd,int len,int guild_id,int dummy,const char *da return mapif_guild_emblem(g); } -int mapif_parse_GuildCastleDataLoad(int fd,int castle_id,int index) +int mapif_parse_GuildCastleDataLoad(int fd, int len, int *castle_ids) { - struct guild_castle gc; - if (!inter_guildcastle_fromsql(castle_id, &gc)) { - return mapif_guild_castle_dataload(castle_id,0,0); - } - switch(index){ - case 1: return mapif_guild_castle_dataload(gc.castle_id,index,gc.guild_id); break; - case 2: return mapif_guild_castle_dataload(gc.castle_id,index,gc.economy); break; - case 3: return mapif_guild_castle_dataload(gc.castle_id,index,gc.defense); break; - case 4: return mapif_guild_castle_dataload(gc.castle_id,index,gc.triggerE); break; - case 5: return mapif_guild_castle_dataload(gc.castle_id,index,gc.triggerD); break; - case 6: return mapif_guild_castle_dataload(gc.castle_id,index,gc.nextTime); break; - case 7: return mapif_guild_castle_dataload(gc.castle_id,index,gc.payTime); break; - case 8: return mapif_guild_castle_dataload(gc.castle_id,index,gc.createTime); break; - case 9: return mapif_guild_castle_dataload(gc.castle_id,index,gc.visibleC); break; - default: - if (index > 9 && index <= 9+MAX_GUARDIANS) - return mapif_guild_castle_dataload(gc.castle_id,index,gc.guardian[index-10].visible); - ShowError("mapif_parse_GuildCastleDataLoad ERROR!! (Not found index=%d)\n", index); - return 0; - } + return mapif_guild_castle_dataload(fd, len, castle_ids); } -int mapif_parse_GuildCastleDataSave(int fd,int castle_id,int index,int value) +int mapif_parse_GuildCastleDataSave(int fd, int castle_id, int index, int value) { - struct guild_castle gc; - if(!inter_guildcastle_fromsql(castle_id, &gc)) - return mapif_guild_castle_datasave(castle_id,index,value); - - switch(index){ - case 1: - if( gc.guild_id!=value ){ - int gid=(value)?value:gc.guild_id; - struct guild *g = (struct guild*)idb_get(guild_db_, gid); - if(log_inter) - inter_log("guild %s (id=%d) %s castle id=%d\n", - (g)?g->name:"??" ,gid, (value)?"occupy":"abandon", castle_id); - } - gc.guild_id = value; - if(gc.guild_id == 0) { - //Delete guardians. - memset(&gc.guardian, 0, sizeof(gc.guardian)); - } - break; - 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; - } - ShowError("mapif_parse_GuildCastleDataSave ERROR!! (Not found index=%d)\n", index); + struct guild_castle *gc = inter_guildcastle_fromsql(castle_id); + + if (gc == NULL) { + ShowError("mapif_parse_GuildCastleDataSave: castle id=%d not found\n", castle_id); + mapif_guild_castle_datasave(fd, castle_id, index, value); return 0; } - inter_guildcastle_tosql(&gc); - mapif_guild_castle_datasave(gc.castle_id,index,value); + + switch (index) { + case 1: + if (gc->guild_id != value) { + int gid = (value) ? value : gc->guild_id; + struct guild *g = idb_get(guild_db_, gid); + if (log_inter) + inter_log("guild %s (id=%d) %s castle id=%d\n", + (g) ? g->name : "??", gid, (value) ? "occupy" : "abandon", castle_id); + } + gc->guild_id = value; + if (gc->guild_id == 0) { + // Delete guardians. + memset(gc->guardian, 0, sizeof(gc->guardian)); + } + break; + 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; + } + ShowError("mapif_parse_GuildCastleDataSave: not found index=%d\n", index); + return 0; + } + inter_guildcastle_tosql(gc); + mapif_guild_castle_datasave(fd, gc->castle_id, index, value); return 0; } @@ -1947,7 +1877,7 @@ int inter_guild_parse_frommap(int fd) case 0x303D: mapif_parse_GuildAlliance(fd,RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10),RFIFOL(fd,14),RFIFOB(fd,18)); break; case 0x303E: mapif_parse_GuildNotice(fd,RFIFOL(fd,2),(const char*)RFIFOP(fd,6),(const char*)RFIFOP(fd,66)); break; case 0x303F: mapif_parse_GuildEmblem(fd,RFIFOW(fd,2)-12,RFIFOL(fd,4),RFIFOL(fd,8),(const char*)RFIFOP(fd,12)); break; - case 0x3040: mapif_parse_GuildCastleDataLoad(fd,RFIFOW(fd,2),RFIFOB(fd,4)); break; + case 0x3040: mapif_parse_GuildCastleDataLoad(fd,RFIFOW(fd,2),(int *)RFIFOP(fd,4)); break; case 0x3041: mapif_parse_GuildCastleDataSave(fd,RFIFOW(fd,2),RFIFOB(fd,4),RFIFOL(fd,5)); break; default: @@ -1957,12 +1887,6 @@ int inter_guild_parse_frommap(int fd) return 1; } -// processes a mapserver connection event -int inter_guild_mapif_init(int fd) -{ - return mapif_guild_castle_alldataload(fd); -} - // サーバーから脱退要求(キャラ削除用) int inter_guild_leave(int guild_id, int account_id, int char_id) { diff --git a/src/char/int_guild.h b/src/char/int_guild.h index 4577357f3..be1d16ab6 100644 --- a/src/char/int_guild.h +++ b/src/char/int_guild.h @@ -24,7 +24,6 @@ struct guild_castle; int inter_guild_parse_frommap(int fd); int inter_guild_sql_init(void); void inter_guild_sql_final(void); -int inter_guild_mapif_init(int fd); int inter_guild_leave(int guild_id,int account_id,int char_id); int mapif_parse_BreakGuild(int fd,int guild_id); int inter_guild_broken(int guild_id); diff --git a/src/char/inter.c b/src/char/inter.c index 75f6533fe..dbff1993f 100644 --- a/src/char/inter.c +++ b/src/char/inter.c @@ -47,7 +47,7 @@ int inter_recv_packet_length[] = { 6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, // 3010- -1,10,-1,14, 14,19, 6,-1, 14,14, 0, 0, 0, 0, 0, 0, // 3020- Party -1, 6,-1,-1, 55,19, 6,-1, 14,-1,-1,-1, 18,19,186,-1, // 3030- - 5, 9, 0, 0, 0, 0, 0, 0, 7, 6,10,10, 10,-1, 0, 0, // 3040- + -1, 9, 0, 0, 0, 0, 0, 0, 7, 6,10,10, 10,-1, 0, 0, // 3040- -1,-1,10,10, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3050- Auction System [Zephyrus] 6,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3060- Quest system [Kevin] [Inkfish] -1,10, 6,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3070- Mercenary packets [Zephyrus] @@ -315,8 +315,6 @@ void inter_final(void) int inter_mapif_init(int fd) { - inter_guild_mapif_init(fd); - return 0; } diff --git a/src/common/db.h b/src/common/db.h index d4728cbbf..e53ace0e6 100644 --- a/src/common/db.h +++ b/src/common/db.h @@ -595,6 +595,7 @@ struct DBMap { #define db_destroy(db) ( (db)->destroy((db),NULL) ) // Other macros #define db_clear(db) ( (db)->clear(db,NULL) ) +#define db_size(db) ( (db)->size(db) ) #define db_iterator(db) ( (db)->iterator(db) ) #define dbi_first(dbi) ( (dbi)->first(dbi,NULL) ) #define dbi_last(dbi) ( (dbi)->last(dbi,NULL) ) diff --git a/src/map/chrif.c b/src/map/chrif.c index 4c70aff90..a75c48ecb 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -458,6 +458,7 @@ int chrif_connectack(int fd) if( !char_init_done ) { char_init_done = true; ShowStatus("Event '"CL_WHITE"OnInterIfInitOnce"CL_RESET"' executed with '"CL_WHITE"%d"CL_RESET"' NPCs.\n", npc_event_doall("OnInterIfInitOnce")); + guild_castle_map_init(); } return 0; diff --git a/src/map/clif.c b/src/map/clif.c index 51d5b802d..c50dd9ee2 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -7054,7 +7054,7 @@ void clif_guild_masterormember(struct map_session_data *sd) /// 01b6 <guild id>.L <level>.L <member num>.L <member max>.L <exp>.L <max exp>.L <points>.L <honor>.L <virtue>.L <emblem id>.L <name>.24B <master name>.24B <manage land>.16B <zeny>.L (ZC_GUILD_INFO2) void clif_guild_basicinfo(struct map_session_data *sd) { - int fd,i,t; + int fd; struct guild *g; struct guild_castle *gc = NULL; @@ -7080,13 +7080,7 @@ void clif_guild_basicinfo(struct map_session_data *sd) memcpy(WFIFOP(fd,46),g->name, NAME_LENGTH); memcpy(WFIFOP(fd,70),g->master, NAME_LENGTH); - for(i = 0, t = 0; i < MAX_GUILDCASTLE; i++) - { - gc = guild_castle_search(i); - if(gc && g->guild_id == gc->guild_id) - t++; - } - safestrncpy((char*)WFIFOP(fd,94),msg_txt(300+t),16); // "'N' castles" + safestrncpy((char*)WFIFOP(fd,94),msg_txt(300+guild_checkcastles(g)),16); // "'N' castles" WFIFOL(fd,110) = 0; // zeny WFIFOSET(fd,packet_len(0x1b6)); diff --git a/src/map/guild.c b/src/map/guild.c index ef19e2f8a..75f63b2ae 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -33,7 +33,6 @@ static DBMap* guild_db; // int guild_id -> struct guild* static DBMap* castle_db; // int castle_id -> struct guild_castle* static DBMap* guild_expcache_db; // int char_id -> struct guild_expcache* static DBMap* guild_infoevent_db; // int guild_id -> struct eventlist* -static DBMap* guild_castleinfoevent_db; // int castle_id_index -> struct eventlist* struct eventlist { char name[EVENT_NAME_LENGTH]; @@ -160,10 +159,14 @@ int guild_check_skill_require(struct guild *g,int id) static bool guild_read_castledb(char* str[], int columns, int current) {// <castle id>,<map name>,<castle name>,<castle event>[,<reserved/unused switch flag>] struct guild_castle *gc; + int mapindex = mapindex_name2id(str[1]); + + if (map_mapindex2mapid(mapindex) < 0) // Map not found or on another map-server + return false; CREATE(gc, struct guild_castle, 1); gc->castle_id = atoi(str[0]); - gc->mapindex = mapindex_name2id(str[1]); + gc->mapindex = mapindex; safestrncpy(gc->castle_name, str[2], sizeof(gc->castle_name)); safestrncpy(gc->castle_event, str[3], sizeof(gc->castle_event)); @@ -1542,28 +1545,29 @@ int castle_guild_broken_sub(DBKey key,void *data,va_list ap) return 0; } -//Innvoked on /breakguild "Guild name" +//Invoked on /breakguild "Guild name" int guild_broken(int guild_id,int flag) { - struct guild *g=guild_search(guild_id); - struct guild_castle *gc=NULL; - struct map_session_data *sd; + struct guild *g = guild_search(guild_id); + struct guild_castle *gc = NULL; + DBIterator *iter = NULL; + struct map_session_data *sd = NULL; int i; char name[EVENT_NAME_LENGTH]; if(flag!=0 || g==NULL) return 0; - //we call castle_event::OnGuildBreak of all castlesof the guild + //we call castle_event::OnGuildBreak of all castles of the guild //you can set all castle_events in the castle_db.txt - for(i=0;i<MAX_GUILDCASTLE;i++){ - if( (gc=guild_castle_search(i)) != NULL ){ - if(gc->guild_id == guild_id){ - safestrncpy(name, gc->castle_event, 50); - npc_event_do(strcat(name,"::OnGuildBreak")); - } + 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++){ // ギルド解散を通知 if((sd=g->member[i].sd)!=NULL){ @@ -1686,71 +1690,32 @@ int guild_break(struct map_session_data *sd,char *name) return 0; } -// ギルド城データ要求 -int guild_castledataload(int castle_id,int index) +/** + * Creates a list of guild castle IDs to be requested + * from char-server. + */ +void guild_castle_map_init(void) { - return intif_guild_castle_dataload(castle_id,index); -} -// ギルド城情報所得時イベント追加 -int guild_addcastleinfoevent(int castle_id,int index,const char *name) -{ - struct eventlist *ev; - int code=castle_id|(index<<16); - - if( name==NULL || *name==0 ) - return 0; + DBIterator* iter = NULL; + int num = db_size(castle_db); - ev = (struct eventlist *)aMalloc(sizeof(struct eventlist)); - strncpy(ev->name,name,ARRAYLENGTH(ev->name)); - //The next event becomes whatever was currently stored. - ev->next = (struct eventlist *)idb_put(guild_castleinfoevent_db,code,ev); - return 0; -} + if (num > 0) { + struct guild_castle* gc = NULL; + int *castle_ids, *cursor; -// ギルド城データ要求返信 -int guild_castledataloadack(int castle_id,int index,int value) -{ - struct guild_castle *gc=guild_castle_search(castle_id); - int code=castle_id|(index<<16); - struct eventlist *ev,*ev2; - - if(gc==NULL){ - return 0; - } - switch(index){ - case 1: - gc->guild_id = value; - if (gc->guild_id && guild_search(gc->guild_id)==NULL) //Request guild data which will be required for spawned guardians. [Skotlex] - guild_request_info(gc->guild_id); - break; - 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; - } - ShowError("guild_castledataloadack ERROR!! (Not found castle_id=%d index=%d)\n", castle_id, index); - return 0; - } - - if( (ev = (struct eventlist *)idb_remove(guild_castleinfoevent_db,code))!=NULL ) - { - while(ev){ - npc_event_do(ev->name); - ev2=ev->next; - aFree(ev); - ev=ev2; + CREATE(castle_ids, int, num); + cursor = castle_ids; + iter = db_iterator(castle_db); + for (gc = dbi_first(iter); dbi_exists(iter); gc = dbi_next(iter)) { + *(cursor++) = gc->castle_id; } + dbi_destroy(iter); + if (intif_guild_castle_dataload(num, castle_ids)) + ShowStatus("Requested '"CL_WHITE"%d"CL_RESET"' guild castles from char-server...\n", num); + aFree(castle_ids); } - return 1; } + // ギルド城データ変更要求 int guild_castledatasave(int castle_id,int index,int value) { @@ -1776,7 +1741,7 @@ int guild_castledatasave(int castle_id,int index,int value) } } - return intif_guild_castle_datasave(castle_id,index,value); + return intif_guild_castle_datasave(castle_id, index, value); // FIXME: it may fail if char-server is disconnected } // ギルド城データ変更通知 @@ -1801,14 +1766,14 @@ int guild_castledatasaveack(int castle_id,int index,int value) gc->guardian[index-10].visible = value; break; } - ShowError("guild_castledatasaveack ERROR!! (Not found index=%d)\n", index); + ShowError("guild_castledatasaveack: not found index=%d\n", index); return 0; } return 1; } // ギルドデータ一括受信(初期化時) -int guild_castlealldataload(int len,struct guild_castle *gc) +int guild_castledataloadack(int len, struct guild_castle *gc) { int i; int n = (len-4) / sizeof(struct guild_castle); @@ -1816,7 +1781,7 @@ int guild_castlealldataload(int len,struct guild_castle *gc) nullpo_ret(gc); - //Last owned castle in the list invokes ::OnAgitinit + //Last owned castle in the list invokes ::OnAgitInit for( i = n-1; i >= 0 && !(gc[i].guild_id); --i ); ev = i; // offset of castle or -1 @@ -1829,12 +1794,12 @@ int guild_castlealldataload(int len,struct guild_castle *gc) { struct guild_castle *c = guild_castle_search(gc->castle_id); if (!c) { - ShowError("guild_castlealldataload Castle id=%d not found.\n", gc->castle_id); + ShowError("guild_castledataloadack: castle id=%d not found.\n", gc->castle_id); continue; } - // update mapserver castle data with new info - memcpy(&c->guild_id, &gc->guild_id, sizeof(struct guild_castle) - ((uintptr_t)&c->guild_id - (uintptr_t)c)); + // update map-server castle data with new info + memcpy(&c->guild_id, &gc->guild_id, sizeof(struct guild_castle) - offsetof(struct guild_castle, guild_id)); if( c->guild_id ) { @@ -1846,7 +1811,7 @@ int guild_castlealldataload(int len,struct guild_castle *gc) } } } - + ShowStatus("Received '"CL_WHITE"%d"CL_RESET"' guild castles from char-server.\n", n); return 0; } @@ -1881,15 +1846,16 @@ int guild_agit2_end(void) // How many castles does this guild have? int guild_checkcastles(struct guild *g) { - int i, nb_cas = 0; - struct guild_castle* gc; + int nb_cas = 0; + struct guild_castle* gc = NULL; + DBIterator *iter = db_iterator(castle_db); - for(i = 0; i < MAX_GUILDCASTLE; i++) { - gc = guild_castle_search(i); - if(gc && gc->guild_id == g->guild_id) + for (gc = dbi_first(iter); dbi_exists(iter); gc = dbi_next(iter)) { + if (gc->guild_id == g->guild_id) { nb_cas++; + } } - + dbi_destroy(iter); return nb_cas; } @@ -1938,7 +1904,6 @@ void do_init_guild(void) guild_expcache_db=idb_alloc(DB_OPT_BASE); guild_infoevent_db=idb_alloc(DB_OPT_BASE); expcache_ers = ers_new(sizeof(struct guild_expcache)); - guild_castleinfoevent_db=idb_alloc(DB_OPT_BASE); sv_readdb(db_path, "castle_db.txt", ',', 4, 5, -1, &guild_read_castledb); @@ -1957,6 +1922,5 @@ void do_final_guild(void) castle_db->destroy(castle_db,guild_castle_db_final); guild_expcache_db->destroy(guild_expcache_db,guild_expcache_db_final); guild_infoevent_db->destroy(guild_infoevent_db,eventlist_db_final); - guild_castleinfoevent_db->destroy(guild_castleinfoevent_db,eventlist_db_final); ers_destroy(expcache_ers); } diff --git a/src/map/guild.h b/src/map/guild.h index c6b380647..3af5be6c4 100644 --- a/src/map/guild.h +++ b/src/map/guild.h @@ -90,12 +90,11 @@ int guild_broken(int guild_id,int flag); 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_addcastleinfoevent(int castle_id,int index,const char *name); +void guild_castle_map_init(void); int guild_castledataload(int castle_id,int index); -int guild_castledataloadack(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_castlealldataload(int len,struct guild_castle *gc); +int guild_castledataloadack(int len, struct guild_castle *gc); int guild_agit_start(void); int guild_agit_end(void); diff --git a/src/map/intif.c b/src/map/intif.c index 54d039347..20d686c11 100644 --- a/src/map/intif.c +++ b/src/map/intif.c @@ -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 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 - 9, 9,-1,14, 0, 0, 0, 0, -1,74,-1,11, 11,-1, 0, 0, //0x3840 + -1, 9, 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, 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] @@ -720,17 +720,22 @@ int intif_guild_emblem(int guild_id,int len,const char *data) WFIFOSET(inter_fd,len+12); return 0; } -//現在のギルド城占領ギルドを調べる -int intif_guild_castle_dataload(int castle_id,int index) + +/** + * Requests guild castles data from char-server. + * @param num Number of castles, size of castle_ids array. + * @param castle_ids Pointer to array of castle IDs. + */ +int intif_guild_castle_dataload(int num, int *castle_ids) { if (CheckForCharServer()) return 0; - WFIFOHEAD(inter_fd,5); - WFIFOW(inter_fd,0)=0x3040; - WFIFOW(inter_fd,2)=castle_id; - WFIFOB(inter_fd,4)=index; - WFIFOSET(inter_fd,5); - return 0; + WFIFOHEAD(inter_fd, 4 + num * sizeof(int)); + WFIFOW(inter_fd, 0) = 0x3040; + WFIFOW(inter_fd, 2) = 4 + num * sizeof(int); + memcpy(WFIFOP(inter_fd, 4), castle_ids, num * sizeof(int)); + WFIFOSET(inter_fd, WFIFOW(inter_fd, 2)); + return 1; } //ギルド城占領ギルド変更要求 @@ -1072,7 +1077,6 @@ int intif_parse_GuildInfo(int fd) guild_recv_noinfo(RFIFOL(fd,4)); return 0; } - if( RFIFOW(fd,2)!=sizeof(struct guild)+4 ) ShowError("intif: guild info : data size error Gid: %d recv size: %d Expected size: %d\n",RFIFOL(fd,4),RFIFOW(fd,2),sizeof(struct guild)+4); guild_recv_info((struct guild *)RFIFOP(fd,4)); @@ -1203,7 +1207,7 @@ int intif_parse_GuildMessage(int fd) // ギルド城データ要求返信 int intif_parse_GuildCastleDataLoad(int fd) { - return guild_castledataloadack(RFIFOW(fd,2),RFIFOB(fd,4),RFIFOL(fd,5)); + return guild_castledataloadack(RFIFOW(fd,2), (struct guild_castle *)RFIFOP(fd,4)); } // ギルド城データ変更通知 int intif_parse_GuildCastleDataSave(int fd) @@ -1211,12 +1215,6 @@ int intif_parse_GuildCastleDataSave(int fd) return guild_castledatasaveack(RFIFOW(fd,2),RFIFOB(fd,4),RFIFOL(fd,5)); } -// ギルド城データ一括受信(初期化時) -int intif_parse_GuildCastleAllDataLoad(int fd) -{ - return guild_castlealldataload(RFIFOW(fd,2),(struct guild_castle *)RFIFOP(fd,4)); -} - int intif_parse_GuildMasterChanged(int fd) { return guild_gm_changed(RFIFOL(fd,2),RFIFOL(fd,6),RFIFOL(fd,10)); @@ -2040,7 +2038,6 @@ int intif_parse(int fd) case 0x383f: intif_parse_GuildEmblem(fd); break; case 0x3840: intif_parse_GuildCastleDataLoad(fd); break; case 0x3841: intif_parse_GuildCastleDataSave(fd); break; - case 0x3842: intif_parse_GuildCastleAllDataLoad(fd); break; case 0x3843: intif_parse_GuildMasterChanged(fd); break; //Quest system diff --git a/src/map/intif.h b/src/map/intif.h index b1315f40c..c7dc25db4 100644 --- a/src/map/intif.h +++ b/src/map/intif.h @@ -56,7 +56,7 @@ int intif_guild_skillup(int guild_id, int skill_num, int account_id, int max); int intif_guild_alliance(int guild_id1, int guild_id2, int account_id1, int account_id2, int flag); int intif_guild_notice(int guild_id, const char *mes1, const char *mes2); int intif_guild_emblem(int guild_id, int len, const char *data); -int intif_guild_castle_dataload(int castle_id, int index); +int intif_guild_castle_dataload(int num, int *castle_ids); int intif_guild_castle_datasave(int castle_id, int index, int value); int intif_create_pet(int account_id, int char_id, short pet_type, short pet_lv, short pet_egg_id, diff --git a/src/map/script.c b/src/map/script.c index 29387fe4e..67e9e722e 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -10139,52 +10139,44 @@ BUILDIN_FUNC(getcastlename) BUILDIN_FUNC(getcastledata) { - 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); + struct guild_castle *gc = guild_mapname2gc(mapname); - struct guild_castle* gc = guild_mapname2gc(mapname); + if (gc == NULL) { + script_pushint(st,0); + ShowWarning("builtin_setcastledata: guild castle for map '%s' not found\n", mapname); + return 1; + } - if(script_hasdata(st,4) && index==0 && gc) { - const char* event = script_getstr(st,4); - check_event(st, event); - guild_addcastleinfoevent(gc->castle_id, 9+MAX_GUARDIANS, event); - } - - if(gc){ - switch(index){ - case 0: { - int i; - for (i = 1; i <= 9+MAX_GUARDIANS; i++) // Initialize[AgitInit] - guild_castledataload(gc->castle_id,i); - } break; - case 1: - script_pushint(st,gc->guild_id); break; - case 2: - script_pushint(st,gc->economy); break; - case 3: - script_pushint(st,gc->defense); break; - case 4: - script_pushint(st,gc->triggerE); break; - case 5: - script_pushint(st,gc->triggerD); break; - case 6: - script_pushint(st,gc->nextTime); break; - case 7: - script_pushint(st,gc->payTime); break; - case 8: - script_pushint(st,gc->createTime); break; - case 9: - script_pushint(st,gc->visibleC); break; - default: - if (index > 9 && index <= 9+MAX_GUARDIANS) - script_pushint(st,gc->guardian[index-10].visible); - else - script_pushint(st,0); + switch (index) { + case 1: + script_pushint(st,gc->guild_id); break; + case 2: + script_pushint(st,gc->economy); break; + case 3: + script_pushint(st,gc->defense); break; + case 4: + script_pushint(st,gc->triggerE); break; + case 5: + script_pushint(st,gc->triggerD); break; + case 6: + script_pushint(st,gc->nextTime); break; + case 7: + script_pushint(st,gc->payTime); break; + case 8: + script_pushint(st,gc->createTime); break; + case 9: + script_pushint(st,gc->visibleC); break; + default: + if (index > 9 && index <= 9+MAX_GUARDIANS) { + script_pushint(st,gc->guardian[index-10].visible); break; - } - return 0; + } + script_pushint(st,0); + ShowWarning("buildin_setcastledata: index = '%d' is out of allowed range\n", index); + return 1; } - script_pushint(st,0); return 0; } @@ -10193,39 +10185,41 @@ BUILDIN_FUNC(setcastledata) const char* mapname = mapindex_getmapname(script_getstr(st,2),NULL); int index = script_getnum(st,3); int value = script_getnum(st,4); - struct guild_castle* gc = guild_mapname2gc(mapname); - if(gc) { - // Save Data byself First - switch(index){ - case 1: - gc->guild_id = value; break; - 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; - } - return 0; - } - guild_castledatasave(gc->castle_id,index,value); + if (gc == NULL) { + ShowWarning("builtin_setcastledata: guild castle for map '%s' not found\n", mapname); + return 1; + } + + switch (index) { + case 1: + gc->guild_id = value; break; + 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); return 0; } @@ -16065,7 +16059,7 @@ struct script_function buildin_func[] = { BUILDIN_DEF(agitcheck,""), // <Agitcheck> BUILDIN_DEF(flagemblem,"i"), // Flag Emblem BUILDIN_DEF(getcastlename,"s"), - BUILDIN_DEF(getcastledata,"si?"), + BUILDIN_DEF(getcastledata,"si"), BUILDIN_DEF(setcastledata,"sii"), BUILDIN_DEF(requestguildinfo,"i?"), BUILDIN_DEF(getequipcardcnt,"i"), |