/*========================================== * charid_dbへ追加(返信待ちがあれば返信) *------------------------------------------ */ void map_addchariddb(int charid,char *name) { struct charid2nick *p; int req=0; p=numdb_search(charid_db,charid); if(p==NULL){ // データベースにない p = malloc(sizeof(struct charid2nick)); if(p==NULL){ printf("out of memory : map_addchariddb\n"); exit(1); } p->req_id=0; }else numdb_erase(charid_db,charid); req=p->req_id; memcpy(p->nick,name,24); p->req_id=0; numdb_insert(charid_db,charid,p); if(req){ // 返信待ちがあれば返信 struct map_session_data *sd = map_id2sd(req); if(sd!=NULL) clif_solved_charname(sd,charid); } }
// パーティデータのロード int inter_party_init() { char line[8192]; struct party *p; FILE *fp; int c=0; party_db=numdb_init(); if( (fp=fopen(party_txt,"r"))==NULL ) return 1; while(fgets(line,sizeof(line),fp)){ int i,j=0; if( sscanf(line,"%d\t%%newid%%\n%n",&i,&j)==1 && j>0 && party_newid<=i){ party_newid=i; continue; } p=(struct party *)aCalloc(1,sizeof(struct party)); if(inter_party_fromstr(line,p)==0 && p->party_id>0){ if( p->party_id >= party_newid) party_newid=p->party_id+1; numdb_insert(party_db,p->party_id,p); party_check_empty(p); } else{ printf("int_party: broken data [%s] line %d\n",party_txt,c+1); free(p); } c++; } fclose(fp); // printf("int_party: %s read done (%d parties)\n",party_txt,c); return 0; }
/*========================================== * 傭兵作成 *------------------------------------------ */ bool mercdb_sql_new(struct mmo_mercstatus *p) { bool result; struct mmo_mercstatus *p2; nullpo_retr(false, p); result = sqldbs_query(&mysql_handle, "INSERT INTO `" MERC_TABLE "` (`class`,`account_id`,`char_id`,`hp`,`sp`,`kill_count`,`limit`) " "VALUES ('%d', '%d', '%d', '%d', '%d', '%d', '%u')", p->class_, p->account_id, p->char_id, p->hp, p->sp, p->kill_count, p->limit ); if(result == false) { p->merc_id = -1; return false; } p->merc_id = (int)sqldbs_insert_id(&mysql_handle); p2 = (struct mmo_mercstatus*)aMalloc(sizeof(struct mmo_mercstatus)); memcpy(p2, p, sizeof(struct mmo_mercstatus)); numdb_insert(merc_db, p->merc_id, p2); return true; }
// ========================================== // アカウント変数のジャーナルのロールフォワード用コールバック関数 // ------------------------------------------ int accregdb_journal_rollforward( int key, void* buf, int flag ) { struct accreg* reg = (struct accreg *)numdb_search( accreg_db, key ); // 念のためチェック if( flag == JOURNAL_FLAG_WRITE && key != ((struct accreg*)buf)->account_id ) { printf("inter: accreg_journal: key != account_id !\n"); return 0; } // データの置き換え if( reg ) { if( flag == JOURNAL_FLAG_DELETE ) { numdb_erase( accreg_db, key ); aFree( reg ); } else { memcpy( reg, buf, sizeof(struct accreg) ); } return 1; } // 追加 if( flag != JOURNAL_FLAG_DELETE ) { reg = (struct accreg*) aCalloc( 1, sizeof( struct accreg ) ); memcpy( reg, buf, sizeof(struct accreg) ); numdb_insert( accreg_db, key, reg ); return 1; } return 0; }
// 作成可否 int party_created(int account_id,int fail,int party_id,char *name) { struct map_session_data *sd; sd=map_id2sd(account_id); nullpo_retr(0, sd); if(fail==0){ struct party *p; sd->status.party_id=party_id; if((p=(struct party *) numdb_search(party_db,party_id))!=NULL){ ShowFatalError("party: id already exists!\n"); exit(1); } p=(struct party *)aCalloc(1,sizeof(struct party)); p->party_id=party_id; memcpy(p->name, name, NAME_LENGTH-1); numdb_insert(party_db,party_id,p); clif_party_created(sd,0); clif_charnameupdate(sd); //Update other people's display. [Skotlex] }else{ clif_party_created(sd,1); } return 0; }
/*========================================== * Loads all scdata from the given filename. *------------------------------------------ */ void status_load_scdata(const char* filename) { FILE *fp; int sd_count=0, sc_count=0; char line[8192]; struct scdata *sc; if ((fp = fopen(filename, "r")) == NULL) { ShowError("status_load_scdata: Nao se pode abrir o arquivo %s!\n", filename); return; } while(fgets(line, sizeof(line) - 1, fp)) { sc = (struct scdata*)aCalloc(1, sizeof(struct scdata)); if (inter_scdata_fromstr(line, sc)) { numdb_insert(scdata_db, sc->char_id, sc); sd_count++; sc_count+= sc->count; } else { ShowError("status_load_scdata: Arquivo de linha quebrada: %s\n", line); aFree(sc); } } fclose(fp); ShowStatus("Carregado %d salvo mudança de status %d personagem.\n", sc_count, sd_count); }
// パーティデータのロード int inter_party_init() { char line[8192]; struct party *p; FILE *fp; int c=0; party_db=numdb_init(); if( (fp=fopen(party_txt,"r"))==NULL ) return 1; while(fgets(line,sizeof(line),fp)){ p=malloc(sizeof(struct party)); if(p==NULL){ printf("int_party: out of memory!\n"); exit(0); } if(inter_party_fromstr(line,p)==0 && p->party_id>0){ if( p->party_id >= party_newid) party_newid=p->party_id+1; numdb_insert(party_db,p->party_id,p); party_check_empty(p); } else{ printf("int_party: broken data [%s] line %d\n",party_txt,c); } c++; } fclose(fp); // printf("int_party: %s read done (%d parties)\n",party_txt,c); return 0; }
// パーティ int mapif_parse_CreateParty(int fd,int account_id,char *name,char *nick,char *map,int lv) { struct party *p; if( (p=search_partyname(name))!=NULL){ printf("int_party: same name party exists [%s]\n",name); mapif_party_created(fd,account_id,NULL); return 0; } p=malloc(sizeof(struct party)); if(p==NULL){ printf("int_party: out of memory !\n"); mapif_party_created(fd,account_id,NULL); return 0; } memset(p,0,sizeof(struct party)); p->party_id=party_newid++; memcpy(p->name,name,24); p->exp=0; p->item=0; p->member[0].account_id=account_id; memcpy(p->member[0].name,nick,24); memcpy(p->member[0].map,map,16); p->member[0].leader=1; p->member[0].online=1; p->member[0].lv=lv; numdb_insert(party_db,p->party_id,p); mapif_party_created(fd,account_id,p); mapif_party_info(fd,p); return 0; }
struct storage *account2storage(intptr_t account_id) { struct storage *stor; stor=numdb_search(storage_db, account_id); if (stor == NULL) { CALLOC(stor, struct storage, 1); stor->account_id = account_id; numdb_insert(storage_db, (intptr_t)stor->account_id, stor); }
/*========================================== * キャラIDからクエストデータを取得 *------------------------------------------ */ const struct quest *questdb_sql_load(int char_id) { bool result = false; struct quest *q = (struct quest *)numdb_search(quest_db, char_id); if(q && q->char_id == char_id) { // 既にキャッシュが存在する return q; } if(q == NULL) { q = (struct quest *)aMalloc(sizeof(struct quest)); numdb_insert(quest_db, char_id, q); } memset(q, 0, sizeof(struct quest)); q->char_id = char_id; result = sqldbs_query(&mysql_handle, "SELECT `account_id`,`nameid`,`state`,`limit`,`mobid1`,`mobmax1`,`mobcnt1`,`mobid2`,`mobmax2`,`mobcnt2`,`mobid3`,`mobmax3`,`mobcnt3` " "FROM `" QUEST_TABLE "` WHERE `char_id`='%d'", char_id ); if(result == false) { q->char_id = -1; return NULL; } if(sqldbs_num_rows(&mysql_handle) > 0) { int i; char **sql_row; for(i = 0; (sql_row = sqldbs_fetch(&mysql_handle)) && i < MAX_QUESTLIST; i++) { if(q->account_id == 0) { q->account_id = atoi(sql_row[0]); } q->data[i].nameid = atoi(sql_row[1]); q->data[i].state = (char)atoi(sql_row[2]); q->data[i].limit = (unsigned int)atoi(sql_row[3]); q->data[i].mob[0].id = (short)atoi(sql_row[4]); q->data[i].mob[0].max = (short)atoi(sql_row[5]); q->data[i].mob[0].cnt = (short)atoi(sql_row[6]); q->data[i].mob[1].id = (short)atoi(sql_row[7]); q->data[i].mob[1].max = (short)atoi(sql_row[8]); q->data[i].mob[1].cnt = (short)atoi(sql_row[9]); q->data[i].mob[2].id = (short)atoi(sql_row[10]); q->data[i].mob[2].max = (short)atoi(sql_row[11]); q->data[i].mob[2].cnt = (short)atoi(sql_row[12]); } q->count = (i < MAX_QUESTLIST)? i: MAX_QUESTLIST; } else { // 見つからなくても正常 q = NULL; } sqldbs_free_result(&mysql_handle); return q; }
// アカウントから倉庫データインデックスを得る(新規倉庫追加可能) struct storage *account2storage (int account_id) { struct storage *s; s = (struct storage *) numdb_search (storage_db, account_id); if (s == NULL) { CREATE (s, struct storage, 1); memset (s, 0, sizeof (struct storage)); s->account_id = account_id; numdb_insert (storage_db, s->account_id, s); }
/*========================================== * アカウントIDから倉庫データをロード * (新規倉庫追加可能) *------------------------------------------ */ const struct storage* storagedb_txt_load(int account_id) { struct storage *s = (struct storage *)numdb_search(storage_db, account_id); if(s == NULL) { s = (struct storage *)aCalloc(1, sizeof(struct storage)); s->account_id = account_id; numdb_insert(storage_db, s->account_id, s); } return s; }
/*========================================== * カプラ倉庫データベース *------------------------------------------ */ static struct storage *account2storage(int account_id) { struct storage *stor; stor = (struct storage *)numdb_search(storage_db,account_id); if(stor == NULL) { stor = (struct storage *)aCalloc(1,sizeof(struct storage)); stor->account_id = account_id; numdb_insert(storage_db,stor->account_id,stor); } return stor; }
/*========================================== * 傭兵データファイルの読み込み *------------------------------------------ */ static bool mercdb_txt_read(void) { FILE *fp; bool ret = true; merc_db = numdb_init(); if((fp = fopen(merc_txt, "r")) == NULL) { printf("mercdb_txt_read: open [%s] failed !\n", merc_txt); ret = false; } else { int count = 0; char line[8192]; while(fgets(line, sizeof(line), fp)) { struct mmo_mercstatus *m = (struct mmo_mercstatus *)aCalloc(1, sizeof(struct mmo_mercstatus)); if(merc_fromstr(line, m) == 0 && m->merc_id > 0) { if(m->merc_id >= merc_newid) merc_newid = m->merc_id + 1; numdb_insert(merc_db, m->merc_id, m); } else { printf("int_merc: broken data [%s] line %d\n", merc_txt, count); aFree(m); } count++; } fclose(fp); } #ifdef TXT_JOURNAL if( merc_journal_enable ) { // ジャーナルデータのロールフォワード if( journal_load( &merc_journal, sizeof(struct mmo_mercstatus), merc_journal_file ) ) { int c = journal_rollforward( &merc_journal, merc_journal_rollforward ); printf("int_merc: journal: roll-forward (%d)\n", c ); // ロールフォワードしたので、txt データを保存する ( journal も新規作成される) mercdb_txt_sync(); } else { // ジャーナルを新規作成する journal_final( &merc_journal ); journal_create( &merc_journal, sizeof(struct mmo_mercstatus), merc_journal_cache, merc_journal_file ); } } #endif return ret; }
/*========================================== * アカウント変数の読み込み *------------------------------------------ */ static bool accregdb_txt_read(void) { FILE *fp; bool ret = true; accreg_db = numdb_init(); if((fp = fopen(accreg_txt, "r")) == NULL) { printf("accregdb_txt_read: open [%s] failed !\n", accreg_txt); ret = false; } else { int count = 0; char line[8192]; while(fgets(line, sizeof(line), fp)) { struct accreg *reg = (struct accreg *)aCalloc(1, sizeof(struct accreg)); if(accregdb_fromstr(line, reg) == 0 && reg->account_id > 0) { numdb_insert(accreg_db, reg->account_id, reg); } else { printf("inter: accreg: broken data [%s] line %d\n", accreg_txt, count); aFree(reg); } count++; } fclose(fp); } #ifdef TXT_JOURNAL if( accreg_journal_enable ) { // ジャーナルデータのロールフォワード if( journal_load( &accreg_journal, sizeof(struct accreg), accreg_journal_file ) ) { int c = journal_rollforward( &accreg_journal, accregdb_journal_rollforward ); printf("inter: accreg_journal: roll-forward (%d)\n", c ); // ロールフォワードしたので、txt データを保存する ( journal も新規作成される) accregdb_txt_sync(); } else { // ジャーナルを新規作成する journal_final( &accreg_journal ); journal_create( &accreg_journal, sizeof(struct accreg), accreg_journal_cache, accreg_journal_file ); } } #endif return ret; }
/*========================================== * Loads status change data of the player given. [Skotlex] *------------------------------------------ */ struct scdata* status_search_scdata(int aid, int cid) { struct scdata *data; data = numdb_search(scdata_db, cid); if (data == NULL) { data = aCalloc(1, sizeof(struct scdata)); data->account_id = aid; data->char_id = cid; numdb_insert(scdata_db, cid, data); } return data; }
/*========================================== * Search in item database *------------------------------------------ */ struct item_data* itemdb_search(intptr_t nameid) { struct item_data *id; id=numdb_search(item_db,nameid); if(id) return id; CALLOC(id, struct item_data, 1); numdb_insert(item_db,nameid,id); id->nameid=nameid; id->value_buy=10; id->value_sell=id->value_buy/2; id->weight=10; id->sex=2; id->elv=0; id->class_base[0]=0xff; id->class_base[1]=0xff; id->class_base[2]=0xff; id->class_upper=5; id->flag.available=0; id->flag.value_notdc=0; id->flag.value_notoc=0; id->flag.no_equip=0; id->view_id=0; if (nameid > 500 && nameid < 600) id->type = 0; //heal item else if (nameid > 600 && nameid < 700) id->type = 2; //use item else if ((nameid > 700 && nameid < 1100) || (nameid > 7000 && nameid < 8000)) id->type = 3; //correction else if (nameid >= 1750 && nameid < 1771) id->type = 10; //arrow else if (nameid > 1100 && nameid < 2000) id->type = 4; //weapon else if ((nameid > 2100 && nameid < 3000) || (nameid > 5000 && nameid < 6000)) id->type = 5; //armor else if (nameid > 4000 && nameid < 5000) id->type = 6; //card else if (nameid > 9000 && nameid < 10000) id->type = 7; //egg else if (nameid > 10000) id->type = 8; //petequip return id; }
/*========================================== * 傭兵作成 *------------------------------------------ */ bool mercdb_txt_new(struct mmo_mercstatus *p2) { struct mmo_mercstatus *p1; nullpo_retr(false, p2); p1 = (struct mmo_mercstatus *)aMalloc(sizeof(struct mmo_mercstatus)); p2->merc_id = merc_newid++; memcpy(p1, p2, sizeof(struct mmo_mercstatus)); numdb_insert(merc_db, p2->merc_id, p1); return true; }
/*========================================== * アカウントIDから倉庫データをロード *------------------------------------------ */ const struct storage* storagedb_sql_load(int account_id) { struct storage *s = (struct storage *)numdb_search(storage_db, account_id); if(s == NULL) { s = (struct storage *)aCalloc(1, sizeof(struct storage)); s->account_id = account_id; numdb_insert(storage_db, s->account_id, s); s->storage_amount = chardb_sql_loaditem(s->store_item, MAX_STORAGE, account_id, TABLE_NUM_STORAGE); } return s; }
/*========================================== * ギルドIDからギルド倉庫データを取得 *------------------------------------------ */ const struct guild_storage *gstoragedb_txt_load(int guild_id) { struct guild_storage *gs = NULL; if(guilddb_load_num(guild_id) != NULL) { gs = (struct guild_storage *)numdb_search(gstorage_db, guild_id); if(gs == NULL) { gs = (struct guild_storage *)aCalloc(1, sizeof(struct guild_storage)); gs->guild_id = guild_id; gs->last_fd = -1; numdb_insert(gstorage_db, gs->guild_id, gs); } } return gs; }
/*========================================== * ギルド倉庫データベース *------------------------------------------ */ static struct guild_storage *guild2storage(int guild_id) { struct guild_storage *gs = NULL; if(guild_search(guild_id) != NULL) { gs = (struct guild_storage *)numdb_search(guild_storage_db,guild_id); if(gs == NULL) { gs = (struct guild_storage *)aCalloc(1,sizeof(struct guild_storage)); gs->guild_id = guild_id; numdb_insert(guild_storage_db,gs->guild_id,gs); } } return gs; }
/*========================================== * ギルドIDからギルド倉庫をロード *------------------------------------------ */ const struct guild_storage *gstoragedb_sql_load(int guild_id) { struct guild_storage *s = (struct guild_storage *)numdb_search(gstorage_db, guild_id); if(s == NULL) { s = (struct guild_storage *)aCalloc(1, sizeof(struct guild_storage)); s->guild_id = guild_id; s->last_fd = -1; numdb_insert(gstorage_db, s->guild_id,s); s->storage_amount = chardb_sql_loaditem(s->store_item, MAX_GUILD_STORAGE, guild_id, TABLE_NUM_GUILD_STORAGE); } return s; }
/*========================================== * charid_dbへ追加(返信要求のみ) *------------------------------------------ */ int map_reqchariddb(struct map_session_data * sd,int charid) { struct charid2nick *p; p=numdb_search(charid_db,charid); if(p!=NULL) // データベースにすでにある return 0; p = malloc(sizeof(struct charid2nick)); if(p==NULL){ printf("out of memory : map_reqchariddb\n"); exit(1); } memset(p->nick,0,24); p->req_id=sd->bl.id; numdb_insert(charid_db,charid,p); return 0; }
// アカウントから倉庫データインデックスを得る(新規倉庫追加可能) struct storage *account2storage(int account_id) { struct storage *s; s= (struct storage *) numdb_search(storage_db,account_id); if(s == NULL) { s = (struct storage *) aCalloc(sizeof(struct storage), 1); if(s==NULL){ ShowFatalError("int_storage: out of memory!\n"); exit(0); } memset(s,0,sizeof(struct storage)); s->account_id=account_id; numdb_insert(storage_db,s->account_id,s); } return s; }
// 情報所得 int party_recv_info(struct party *sp) { struct party *p; int i; nullpo_retr(0, sp); if((p=(struct party *) numdb_search(party_db,sp->party_id))==NULL){ p=(struct party *)aCalloc(1,sizeof(struct party)); numdb_insert(party_db,sp->party_id,p); // 最初のロードなのでユーザーのチェックを行う party_check_member(sp); } memcpy(p,sp,sizeof(struct party)); for(i=0;i<MAX_PARTY;i++){ // sdの設定 struct map_session_data *sd = map_id2sd(p->member[i].account_id); if(sd!=NULL && sd->status.party_id==p->party_id && !sd->state.waitingdisconnect) p->member[i].sd=sd; else p->member[i].sd=NULL; } clif_party_info(p,-1); // Refresh hp/xy state [LuzZza] for(i=0;i<MAX_PARTY;i++) { struct map_session_data *sd = p->member[i].sd; if(sd!=NULL) { clif_party_hp(sd); clif_party_xy(sd); } } for(i=0;i<MAX_PARTY;i++){ // 設定情報の送信 struct map_session_data *sd = p->member[i].sd; if(sd!=NULL && sd->state.party_sent==0){ clif_party_option(p,sd,0x100); sd->state.party_sent=1; } } return 0; }
struct guild_storage *guild2storage(int guild_id) { struct guild_storage *gs = NULL; if(inter_guild_search(guild_id) != NULL) { gs= (struct guild_storage *) numdb_search(guild_storage_db,guild_id); if(gs == NULL) { gs = (struct guild_storage *) aCalloc(sizeof(struct guild_storage), 1); if(gs==NULL){ ShowFatalError("int_storage: out of memory!\n"); exit(0); } // memset(gs,0,sizeof(struct guild_storage)); aCalloc does this! [Skotlex] gs->guild_id=guild_id; numdb_insert(guild_storage_db,gs->guild_id,gs); } } return gs; }
//-------------------- // Creation of a party //-------------------- void mapif_parse_CreateParty(int fd, int account_id, char *party_name, char *nick, char *map, int lv, unsigned char item, unsigned char item2) { struct party *p; // check of structure of party_name is done in map-server /* moved to map-server------------ // check control chars and del for(i = 0; i < 24 && party_name[i]; i++) { if (!(party_name[i] & 0xe0) || party_name[i] == 0x7f) { printf("int_party: illegal party name [%s]\n", party_name); mapif_party_created(fd, account_id, NULL); return; } }--------------------*/ if ((p = search_partyname(party_name)) != NULL) { printf("int_party: same name party exists [%s]\n", party_name); mapif_party_created(fd, account_id, NULL); return; } CALLOC(p, struct party, 1); p->party_id = party_newid++; strncpy(p->name, party_name, 24); //p->exp = 0; // <item1>�A�C�e�����W���@�B0�Ōl�ʁA1�Ńp�[�e�B���L // <item2>�A�C�e�����z���@�B0�Ōl�ʁA1�Ńp�[�e�B�ɋϓ����z p->item = item; // item 1 p->itemc = item2; // item 2 p->member[0].account_id = account_id; strncpy(p->member[0].name, nick, 24); strncpy(p->member[0].map, map, 16); // 17 - NULL p->member[0].leader = 1; p->member[0].online = 1; p->member[0].lv = lv; numdb_insert(party_db, (CPU_INT)p->party_id, p); mapif_party_created(fd, account_id, p); mapif_party_info(fd, p); return; }
/*========================================== * セーブ *------------------------------------------ */ bool mercdb_txt_save(struct mmo_mercstatus *p2) { struct mmo_mercstatus *p1; nullpo_retr(false, p2); p1 = (struct mmo_mercstatus *)numdb_search(merc_db, p2->merc_id); if(p1 == NULL) { p1 = (struct mmo_mercstatus *)aMalloc(sizeof(struct mmo_mercstatus)); numdb_insert(merc_db, p2->merc_id, p1); } memcpy(p1, p2, sizeof(struct mmo_mercstatus)); #ifdef TXT_JOURNAL if( merc_journal_enable ) journal_write( &merc_journal, p1->merc_id, p1 ); #endif return true; }
/*========================================== * DBの検索 *------------------------------------------ */ struct item_data* itemdb_search(int nameid) { struct item_data *id; id=(struct item_data *) numdb_search(item_db,nameid); if(id) return id; id=(struct item_data *)aCalloc(1,sizeof(struct item_data)); numdb_insert(item_db,nameid,id); id->nameid=nameid; id->value_buy=10; id->value_sell=id->value_buy/2; id->weight=10; id->sex=2; id->class_base[0]=0xff; id->class_base[1]=0xff; id->class_base[2]=0xff; id->class_upper=5; if(nameid>500 && nameid<600) id->type=0; //heal item else if(nameid>600 && nameid<700) id->type=2; //use item else if((nameid>700 && nameid<1100) || (nameid>7000 && nameid<8000)) id->type=3; //correction else if(nameid>=1750 && nameid<1771) id->type=10; //arrow else if(nameid>1100 && nameid<2000) id->type=4; //weapon else if((nameid>2100 && nameid<3000) || (nameid>5000 && nameid<6000)) id->type=5; //armor else if(nameid>4000 && nameid<5000) id->type=6; //card else if(nameid>9000 && nameid<10000) id->type=7; //egg else if(nameid>10000) id->type=8; //petequip return id; }
/*========================================== * 倉庫データのセーブ *------------------------------------------ */ bool storagedb_txt_save(struct storage *s2) { struct storage *s1; nullpo_retr(false, s2); s1 = (struct storage *)numdb_search(storage_db, s2->account_id); if(s1 == NULL) { s1 = (struct storage *)aCalloc(1, sizeof(struct storage)); s1->account_id = s2->account_id; numdb_insert(storage_db, s2->account_id, s1); } memcpy(s1, s2, sizeof(struct storage)); #ifdef TXT_JOURNAL if( storage_journal_enable ) journal_write( &storage_journal, s1->account_id, s1 ); #endif return true; }