// ギルドデータ一括受信(初期化時) int guild_castlealldataload(int len,struct guild_castle *gc) { int i; int n = (len-4) / sizeof(struct guild_castle); int ev; nullpo_ret(gc); //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 if( ev < 0 ) { //No castles owned, invoke OnAgitInit as it is. npc_event_doall("OnAgitInit"); npc_event_doall("OnAgitInit2"); } else // load received castles into memory, one by one for( i = 0; i < n; i++, 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); continue; } // update mapserver castle data with new info memcpy(&c->guild_id, &gc->guild_id, sizeof(struct guild_castle) - ((uintptr)&c->guild_id - (uintptr)c)); if( c->guild_id ) { if( i != ev ) guild_request_info(c->guild_id); else { // last owned one guild_npc_request_info(c->guild_id, "::OnAgitInit"); guild_npc_request_info(c->guild_id, "::OnAgitInit2"); } } } return 0; }
/** * Pet menu options. * @param sd : player requesting * @param menunum : menu option chosen * @return 0:success, 1:failure */ int pet_menu(struct map_session_data *sd,int menunum) { struct item_data *egg_id; nullpo_ret(sd); if (sd->pd == NULL) return 1; //You lost the pet already. if(!sd->status.pet_id || sd->pd->pet.intimate <= 0 || sd->pd->pet.incubate) return 1; egg_id = itemdb_exists(sd->pd->petDB->EggID); if (egg_id) { if ((egg_id->flag.trade_restriction&0x01) && !pc_inventoryblank(sd)) { clif_displaymessage(sd->fd, msg_txt(sd, 451)); // You can't return your pet because your inventory is full. return 1; } } switch(menunum) { case 0: clif_send_petstatus(sd); break; case 1: pet_food(sd, sd->pd); break; case 2: pet_performance(sd, sd->pd); break; case 3: pet_return_egg(sd, sd->pd); break; case 4: pet_unequipitem(sd, sd->pd); break; } return 0; }
/*========================================== * player chatroom creation *------------------------------------------*/ int chat_createpcchat(struct map_session_data* sd, const char* title, const char* pass, int limit, bool pub) { struct chat_data* cd; nullpo_ret(sd); if( sd->chatID ) return 0; //Prevent people abusing the chat system by creating multiple chats, as pointed out by End of Exam. [Skotlex] if( sd->state.vending || sd->state.buyingstore ) {// not chat, when you already have a store open return 0; } if( map[sd->bl.m].flag.nochat ) { clif_displaymessage(sd->fd, msg_txt(281)); return 0; //Can't create chatrooms on this map. } if( map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKNOBOARDS) ) { clif_displaymessage (sd->fd, "Can't create chat rooms in this Area."); return 0; } pc_stop_walking(sd,1); cd = chat_createchat(&sd->bl, title, pass, limit, pub, 0, "", 0, 1, MAX_LEVEL); if( cd ) { cd->users = 1; cd->usersd[0] = sd; pc_setchatid(sd,cd->bl.id); clif_createchat(sd,0); clif_dispchat(cd,0); } else clif_createchat(sd,1); return 0; }
/** * @see DBApply */ int bg_send_xy_timer_sub(DBKey key, DBData *data, va_list ap) { struct battleground_data *bg = db_data2ptr(data); struct map_session_data *sd; int i; nullpo_ret(bg); for( i = 0; i < MAX_BG_MEMBERS; i++ ) { if( (sd = bg->members[i].sd) == NULL ) continue; if( sd->bl.x != bg->members[i].x || sd->bl.y != bg->members[i].y ) { // xy update bg->members[i].x = sd->bl.x; bg->members[i].y = sd->bl.y; clif_bg_xy(sd); } } return 0; }
int mail_removeitem(struct map_session_data *sd, short flag) { nullpo_ret(sd); if( sd->mail.amount ) { if (flag) { // Item send log_pick_pc(sd, LOG_TYPE_MAIL, sd->mail.nameid, -sd->mail.amount, &sd->status.inventory[sd->mail.index]); pc_delitem(sd, sd->mail.index, sd->mail.amount, 1, 0); } else clif_additem(sd, sd->mail.index, sd->mail.amount, 0); } sd->mail.nameid = 0; sd->mail.index = 0; sd->mail.amount = 0; return 1; }
/*========================================== * Move an item from cart to storage. * @index : cart inventory index * return * 0 : fail * 1 : success *------------------------------------------*/ int storage_storageaddfromcart(struct map_session_data* sd, int index, int amount) { nullpo_ret(sd); if( sd->status.storage.storage_amount > MAX_STORAGE ) return 0; // storage full / storage closed if( index < 0 || index >= MAX_CART ) return 0; if( sd->status.cart[index].nameid <= 0 ) return 0; //No item there. if( amount < 1 || amount > sd->status.cart[index].amount ) return 0; if( storage_additem(sd,&sd->status.cart[index],amount) == 0 ) pc_cart_delitem(sd,index,amount,0,LOG_TYPE_STORAGE); return 1; }
/// delete an existing account entry + its regs static bool account_db_sql_remove(AccountDB* self, const int account_id) { AccountDB_SQL* db = (AccountDB_SQL*)self; struct Sql *sql_handle; bool result = false; nullpo_ret(db); sql_handle = db->accounts; if( SQL_SUCCESS != SQL->QueryStr(sql_handle, "START TRANSACTION") || SQL_SUCCESS != SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = %d", db->account_db, account_id) || SQL_SUCCESS != SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = %d", db->global_acc_reg_num_db, account_id) || SQL_SUCCESS != SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `account_id` = %d", db->global_acc_reg_str_db, account_id) ) Sql_ShowDebug(sql_handle); else result = true; result &= ( SQL_SUCCESS == SQL->QueryStr(sql_handle, (result == true) ? "COMMIT" : "ROLLBACK") ); return result; }
/*=============================================================== * Change elemental mode. *-------------------------------------------------------------*/ int elemental_change_mode(struct elemental_data *ed, int mode) { nullpo_ret(ed); // Remove target elemental_unlocktarget(ed); // Removes the effects of the previous mode. if(ed->elemental.mode != mode ) elemental_clean_effect(ed); ed->battle_status.mode = ed->elemental.mode = mode; // Normalize elemental mode to elemental skill mode. if( mode == EL_MODE_AGGRESSIVE ) mode = EL_SKILLMODE_AGGRESSIVE; // Aggressive spirit mode -> Aggressive spirit skill. else if( mode == EL_MODE_ASSIST ) mode = EL_SKILLMODE_ASSIST; // Assist spirit mode -> Assist spirit skill. else mode = EL_SKILLMODE_PASIVE; // Passive spirit mode -> Passive spirit skill. // Use a skill inmediately after every change mode. if( mode != EL_SKILLMODE_AGGRESSIVE ) elemental_change_mode_ack(ed,mode); return 1; }
/*========================================== * Add an item to the storage from the inventory. * @index : inventory idx * return * 0 : fail * 1 : success *------------------------------------------*/ int storage_storageadd(struct map_session_data* sd, int index, int amount) { nullpo_ret(sd); if( sd->status.storage.storage_amount > MAX_STORAGE ) return 0; // storage full if( index < 0 || index >= MAX_INVENTORY ) return 0; if( sd->status.inventory[index].nameid <= 0 ) return 0; // No item on that spot if( amount < 1 || amount > sd->status.inventory[index].amount ) return 0; if( storage_additem(sd,&sd->status.inventory[index],amount) == 0 ) pc_delitem(sd,index,amount,0,4,LOG_TYPE_STORAGE); return 1; }
// Create a party whether or not int mapif_party_created(int fd, int account_id, int char_id, struct party *p) { nullpo_ret(p); WFIFOHEAD(fd, 39); WFIFOW(fd,0)=0x3820; WFIFOL(fd,2)=account_id; WFIFOL(fd,6)=char_id; if(p!=NULL){ WFIFOB(fd,10)=0; WFIFOL(fd,11)=p->party_id; memcpy(WFIFOP(fd,15),p->name,NAME_LENGTH); ShowInfo("int_party: Party created (%d - %s)\n",p->party_id,p->name); }else{ WFIFOB(fd,10)=1; WFIFOL(fd,11)=0; memset(WFIFOP(fd,15),0,NAME_LENGTH); } WFIFOSET(fd,39); return 0; }
bool mapif_homunculus_rename(const char *name) { int i; nullpo_ret(name); // Check Authorized letters/symbols in the name of the homun if( char_name_option == 1 ) {// only letters/symbols in char_name_letters are authorized for( i = 0; i < NAME_LENGTH && name[i]; i++ ) if( strchr(char_name_letters, name[i]) == NULL ) return false; } else if( char_name_option == 2 ) {// letters/symbols in char_name_letters are forbidden for( i = 0; i < NAME_LENGTH && name[i]; i++ ) if( strchr(char_name_letters, name[i]) != NULL ) return false; } return true; }
int merc_menu(struct map_session_data *sd,int menunum) { nullpo_ret(sd); if (sd->hd == NULL) return 1; switch(menunum) { case 0: break; case 1: merc_hom_food(sd, sd->hd); break; case 2: merc_hom_delete(sd->hd, -1); break; default: ShowError("merc_menu : unknown menu choice : %d\n", menunum) ; break; } return 0; }
// 所属キャラの確認 static int party_check_member(struct party *p) { nullpo_ret(p); for (int i = 0; i < fd_max; i++) { if (!session[i]) continue; map_session_data *sd = static_cast<map_session_data *>(session[i]->session_data.get()); if (sd && sd->state.auth) { if (sd->status.party_id == p->party_id) { int j, f = 1; for (j = 0; j < MAX_PARTY; j++) { // パーティにデータがあるか確認 if (p->member[j].account_id == sd->status.account_id) { if (p->member[j].name == sd->status.name) f = 0; // データがある else { // I can prove it was already zeroed // p->member[j].sd = NULL; // 同垢別キャラだった } } } if (f) { sd->status.party_id = 0; if (battle_config.error_log) PRINTF("party: check_member %d[%s] is not member\n", sd->status.account_id, sd->status.name); } } } } return 0; }
static int elemental_ai_sub_timer_activesearch (struct block_list *bl, va_list ap) { struct elemental_data *ed; struct block_list **target; int dist; nullpo_ret (bl); ed = va_arg (ap, struct elemental_data *); target = va_arg (ap, struct block_list **); //If can't seek yet, not an enemy, or you can't attack it, skip. if ( (*target) == bl || !status_check_skilluse (&ed->bl, bl, 0, 0)) return 0; if (battle_check_target (&ed->bl, bl, BCT_ENEMY) <= 0) return 0; switch (bl->type) { case BL_PC: if (!map_flag_vs (ed->bl.m)) return 0; default: dist = distance_bl (&ed->bl, bl); if ( ( (*target) == NULL || !check_distance_bl (&ed->bl, *target, dist)) && battle_check_range (&ed->bl, bl, ed->db->range2)) { //Pick closest target? (*target) = bl; ed->target_id = bl->id; ed->min_chase = dist + ed->db->range3; if (ed->min_chase > AREA_SIZE) ed->min_chase = AREA_SIZE; return 1; } break; } return 0; }
// 情報所得 int party_recv_info(const struct party *sp) { int i; nullpo_ret(sp); struct party *p = party_db.search(sp->party_id); if (p == NULL) { p = party_db.init(sp->party_id); // 最初のロードなのでユーザーのチェックを行う *p = *sp; party_check_member(p); } else *p = *sp; for (i = 0; i < MAX_PARTY; i++) { // sdの設定 dumb_ptr<map_session_data> sd = map_id2sd(p->member[i].account_id); p->member[i].sd = (sd != NULL && sd->status.party_id == p->party_id) ? sd.operator->() : NULL; } clif_party_info(p, -1); for (i = 0; i < MAX_PARTY; i++) { // 設定情報の送信 // dumb_ptr<map_session_data> sd = map_id2sd(p->member[i].account_id); dumb_ptr<map_session_data> sd = dumb_ptr<map_session_data>(p->member[i].sd); if (sd != NULL && sd->party_sended == 0) { clif_party_option(p, sd, 0x100); sd->party_sended = 1; } } return 0; }
/*=============================================================== * Action that elemental perform after changing mode. * Activates one of the skills of the new mode. *-------------------------------------------------------------*/ int elemental_change_mode_ack(struct elemental_data *ed, int mode) { struct block_list *bl = &ed->master->bl; short skillnum, skilllv; int i; nullpo_ret(ed); if( !bl ) return 0; // Select a skill. ARR_FIND(0, MAX_ELESKILLTREE, i, ed->db->skill[i].id && (ed->db->skill[i].mode&mode)); if( i == MAX_ELESKILLTREE ) return 0; skillnum = ed->db->skill[i].id; skilllv = ed->db->skill[i].lv; if( elemental_skillnotok(skillnum, ed) ) return 0; if( ed->ud.skilltimer != -1 ) return 0; else if( DIFF_TICK(gettick(), ed->ud.canact_tick) < 0 ) return 0; ed->target_id = bl->id; // Set new target ed->last_thinktime = gettick(); if( skill_get_inf(skillnum) & INF_GROUND_SKILL ) unit_skilluse_pos(&ed->bl, bl->x, bl->y, skillnum, skilllv); else unit_skilluse_id(&ed->bl,bl->id,skillnum,skilllv); ed->target_id = 0; // Reset target after casting the skill to avoid continious attack. return 1; }
// exp share and added zeny share [Valaris] int party_exp_share(struct party_data* p, struct block_list* src, unsigned int base_exp, unsigned int job_exp, int zeny) { struct map_session_data* sd[MAX_PARTY]; unsigned int i, c; nullpo_ret(p); // count the number of players eligible for exp sharing for (i = c = 0; i < MAX_PARTY; i++) { if( (sd[c] = p->data[i].sd) == NULL || sd[c]->bl.m != src->m || pc_isdead(sd[c]) || (battle_config.idle_no_share && pc_isidle(sd[c])) ) continue; c++; } if (c < 1) return 0; base_exp/=c; job_exp/=c; zeny/=c; if (battle_config.party_even_share_bonus && c > 1) { double bonus = 100 + battle_config.party_even_share_bonus*(c-1); if (base_exp) base_exp = (unsigned int) cap_value(base_exp * bonus/100, 0, UINT_MAX); if (job_exp) job_exp = (unsigned int) cap_value(job_exp * bonus/100, 0, UINT_MAX); if (zeny) zeny = (unsigned int) cap_value(zeny * bonus/100, INT_MIN, INT_MAX); } for (i = 0; i < c; i++) { pc_gainexp(sd[i], src, base_exp, job_exp, false); if (zeny) // zeny from mobs [Valaris] pc_getzeny(sd[i],zeny); } return 0; }
/** * Saves a pet to the SQL database. * * @remark * In case of newly created pet, the pet ID is not updated to reflect the * newly assigned ID. The caller must do so. * * @param p The pet data to save. * @return The ID of the saved pet. * @retval 0 in case of errors. */ int inter_pet_tosql(const struct s_pet *p) { //`pet` (`pet_id`, `class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incubate`) char esc_name[NAME_LENGTH*2+1];// escaped pet name int pet_id = 0, hungry = 0, intimate = 0; nullpo_ret(p); SQL->EscapeStringLen(inter->sql_handle, esc_name, p->name, strnlen(p->name, NAME_LENGTH)); hungry = cap_value(p->hungry, 0, 100); intimate = cap_value(p->intimate, 0, 1000); if (p->pet_id == 0) { // New pet. if (SQL_ERROR == SQL->Query(inter->sql_handle, "INSERT INTO `%s` " "(`class`,`name`,`account_id`,`char_id`,`level`,`egg_id`,`equip`,`intimate`,`hungry`,`rename_flag`,`incubate`) " "VALUES ('%d', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d')", pet_db, p->class_, esc_name, p->account_id, p->char_id, p->level, p->egg_id, p->equip, intimate, hungry, p->rename_flag, p->incubate)) { Sql_ShowDebug(inter->sql_handle); return 0; } pet_id = (int)SQL->LastInsertId(inter->sql_handle); } else { // Update pet. if (SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `class`='%d',`name`='%s',`account_id`='%d',`char_id`='%d',`level`='%d',`egg_id`='%d',`equip`='%d',`intimate`='%d',`hungry`='%d',`rename_flag`='%d',`incubate`='%d' WHERE `pet_id`='%d'", pet_db, p->class_, esc_name, p->account_id, p->char_id, p->level, p->egg_id, p->equip, intimate, hungry, p->rename_flag, p->incubate, p->pet_id)) { Sql_ShowDebug(inter->sql_handle); return 0; } pet_id = p->pet_id; } if (save_log) ShowInfo("Pet saved %d - %s.\n", pet_id, p->name); return pet_id; }
// ギルド敵対 int guild_opposition(struct map_session_data *sd,struct map_session_data *tsd) { struct guild *g; int i; nullpo_ret(sd); g=guild_search(sd->status.guild_id); if(g==NULL || tsd==NULL) return 0; // Prevent creation opposition with same guilds [LuzZza] if(sd->status.guild_id == tsd->status.guild_id) return 0; if( guild_get_alliance_count(g,1) >= battle_config.max_guild_alliance ) { clif_guild_oppositionack(sd,1); return 0; } for(i=0;i<MAX_GUILDALLIANCE;i++){ // すでに関係を持っているか確認 if(g->alliance[i].guild_id==tsd->status.guild_id){ if(g->alliance[i].opposition==1){ // すでに敵対 clif_guild_oppositionack(sd,2); return 0; } if(agit_flag || agit2_flag || agit3_flag) // Prevent the changing of alliances to oppositions during WoE.. return 0; //Change alliance to opposition. intif_guild_alliance( sd->status.guild_id,tsd->status.guild_id, sd->status.account_id,tsd->status.account_id,8 ); } } // inter鯖に敵対要請 intif_guild_alliance( sd->status.guild_id,tsd->status.guild_id, sd->status.account_id,tsd->status.account_id,1 ); return 0; }
int mail_removeitem(struct map_session_data *sd, short flag) { nullpo_ret(sd); if( sd->mail.amount ) { if (flag) { // Item send if(log_config.enable_logs&0x2000) log_pick_pc(sd, "E", sd->mail.nameid, -sd->mail.amount, &sd->status.inventory[sd->mail.index], sd->status.inventory[sd->mail.index].serial); pc_delitem(sd, sd->mail.index, sd->mail.amount, 1, 0); } else clif_additem(sd, sd->mail.index, sd->mail.amount, 0); } sd->mail.nameid = 0; sd->mail.index = 0; sd->mail.amount = 0; return 1; }
int ext_storage_get(struct map_session_data* sd, int index, int amount) { int flag; nullpo_ret(sd); if( index < 0 || index >= MAX_EXTRA_STORAGE ) return 0; if( sd->status.ext_storage.items[index].nameid <= 0 ) return 0; //Nothing there if( amount < 1 || amount > sd->status.ext_storage.items[index].amount ) return 0; if( (flag = pc_additem(sd,&sd->status.ext_storage.items[index],amount,LOG_TYPE_STORAGE)) == 0 ) ext_storage_delitem(sd,index,amount); else clif_additem(sd,0,0,flag); return 1; }
/*========================================== * player chatroom creation *------------------------------------------*/ bool chat_createpcchat(struct map_session_data* sd, const char* title, const char* pass, int limit, bool pub) { struct chat_data* cd; nullpo_ret(sd); if( sd->chatID ) return false; //Prevent people abusing the chat system by creating multiple chats, as pointed out by End of Exam. [Skotlex] if( sd->state.vending || sd->state.buyingstore ) { // not chat, when you already have a store open return false; } if( map->list[sd->bl.m].flag.nochat ) { clif->message(sd->fd, msg_sd(sd,281)); return false; //Can't create chatrooms on this map. } if( map->getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKNOCHAT) ) { clif->message (sd->fd, msg_sd(sd,865)); // "Can't create chat rooms in this area." return false; } pc_stop_walking(sd, STOPWALKING_FLAG_FIXPOS); cd = chat->create(&sd->bl, title, pass, limit, pub, 0, "", 0, 1, MAX_LEVEL); if( cd ) { cd->users = 1; cd->usersd[0] = sd; pc_setchatid(sd,cd->bl.id); pc_stop_attack(sd); clif->createchat(sd,0); // 0 = success clif->dispchat(cd,0); return true; } clif->createchat(sd,1); // 1 = Room limit exceeded return false; }
int party_recv_info(struct party *sp) { struct party_data *p; int i; bool party_new = false; nullpo_ret(sp); p = (struct party_data*)idb_ensure(party_db, sp->party_id, create_party); if (!p->party.party_id) //party just received. { party_new = true; party_check_member(sp); } memcpy(&p->party,sp,sizeof(struct party)); memset(&p->state, 0, sizeof(p->state)); memset(&p->data, 0, sizeof(p->data)); for(i=0;i<MAX_PARTY;i++){ if (!p->party.member[i].account_id) continue; p->data[i].sd = party_sd_check(p->party.party_id, p->party.member[i].account_id, p->party.member[i].char_id); } party_check_state(p); if (party_new) { //Send party data to all players. struct map_session_data *sd; for(i=0;i<MAX_PARTY;i++){ sd = p->data[i].sd; if(!sd) continue; clif_charnameupdate(sd); //Update other people's display. [Skotlex] clif_party_member_info(p,sd); clif_party_option(p,sd,0x100); clif_party_info(p,NULL); } } return 0; }
int mapif_create_pet(int fd, int account_id, int char_id, short pet_class, short pet_lv, short pet_egg_id, short pet_equip, short intimate, short hungry, char rename_flag, char incubate, char *pet_name) { nullpo_ret(pet_name); memset(inter_pet->pt, 0, sizeof(struct s_pet)); safestrncpy(inter_pet->pt->name, pet_name, NAME_LENGTH); if(incubate == 1) inter_pet->pt->account_id = inter_pet->pt->char_id = 0; else { inter_pet->pt->account_id = account_id; inter_pet->pt->char_id = char_id; } inter_pet->pt->class_ = pet_class; inter_pet->pt->level = pet_lv; inter_pet->pt->egg_id = pet_egg_id; inter_pet->pt->equip = pet_equip; inter_pet->pt->intimate = intimate; inter_pet->pt->hungry = hungry; inter_pet->pt->rename_flag = rename_flag; inter_pet->pt->incubate = incubate; if(inter_pet->pt->hungry < 0) inter_pet->pt->hungry = 0; else if(inter_pet->pt->hungry > 100) inter_pet->pt->hungry = 100; if(inter_pet->pt->intimate < 0) inter_pet->pt->intimate = 0; else if(inter_pet->pt->intimate > 1000) inter_pet->pt->intimate = 1000; inter_pet->pt->pet_id = -1; //Signal NEW pet. if (inter_pet->tosql(inter_pet->pt->pet_id,inter_pet->pt)) mapif->pet_created(fd, account_id, inter_pet->pt); else //Failed... mapif->pet_created(fd, account_id, NULL); return 0; }
/// retrieve data from db and store it in the provided data structure static bool account_db_sql_load_str(AccountDB* self, struct mmo_account* acc, const char* userid) { AccountDB_SQL* db = (AccountDB_SQL*)self; Sql* sql_handle; char esc_userid[2*NAME_LENGTH+1]; int account_id; char* data; nullpo_ret(db); sql_handle = db->accounts; SQL->EscapeString(sql_handle, esc_userid, userid); // get the list of account IDs for this user ID if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `account_id` FROM `%s` WHERE `userid`= %s '%s'", db->account_db, (db->case_sensitive ? "BINARY" : ""), esc_userid) ) { Sql_ShowDebug(sql_handle); return false; } if( SQL->NumRows(sql_handle) > 1 ) {// serious problem - duplicate account ShowError("account_db_sql_load_str: Varias contas relacionadas ao usuario '%s'!\n", userid); SQL->FreeResult(sql_handle); return false; } if( SQL_SUCCESS != SQL->NextRow(sql_handle) ) {// no such entry SQL->FreeResult(sql_handle); return false; } SQL->GetData(sql_handle, 0, &data, NULL); account_id = atoi(data); return account_db_sql_load_num(self, acc, account_id); }
int log_atcommand(struct map_session_data* sd, const char* message) { if(!log_config.enable_logs) return 0; nullpo_ret(sd); #ifndef TXT_ONLY if( log_config.sql_logs ) { SqlStmt* stmt; stmt = SqlStmt_Malloc(logmysql_handle); if( SQL_SUCCESS != SqlStmt_Prepare(stmt, "INSERT DELAYED INTO `%s` (`atcommand_date`, `account_id`, `char_id`, `char_name`, `map`, `command`) VALUES (NOW(), '%d', '%d', ?, '%s', ?)", log_config.log_gm_db, sd->status.account_id, sd->status.char_id, mapindex_id2name(sd->mapindex) ) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, sd->status.name, strnlen(sd->status.name, NAME_LENGTH)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (char*)message, safestrnlen(message, 255)) || SQL_SUCCESS != SqlStmt_Execute(stmt) ) { SqlStmt_ShowDebug(stmt); SqlStmt_Free(stmt); return 0; } SqlStmt_Free(stmt); } else #endif { FILE* logfp; if((logfp = fopen(log_config.log_gm, "a+")) == NULL) return 0; time(&curtime); strftime(timestring, 254, "%m/%d/%Y %H:%M:%S", localtime(&curtime)); fprintf(logfp, "%s - %s[%d]: %s\n", timestring, sd->status.name, sd->status.account_id, message); fclose(logfp); } return 1; }
/*========================================== * Change a chatroom's owner * Return * 0: User not found/Missing data * 1: Success *------------------------------------------*/ bool chat_changechatowner(struct map_session_data* sd, const char* nextownername) { struct chat_data* cd; struct map_session_data* tmpsd; int i; nullpo_ret(sd); cd = (struct chat_data*)map->id2bl(sd->chatID); if( cd == NULL || (struct block_list*) sd != cd->owner ) return false; ARR_FIND( 1, cd->users, i, strncmp(cd->usersd[i]->status.name, nextownername, NAME_LENGTH) == 0 ); if( i == cd->users ) return false; // name not found // erase temporarily clif->clearchat(cd,0); // set new owner cd->owner = (struct block_list*) cd->usersd[i]; clif->changechatowner(cd,cd->usersd[i]); // swap the old and new owners' positions tmpsd = cd->usersd[i]; cd->usersd[i] = cd->usersd[0]; cd->usersd[0] = tmpsd; // set the new chatroom position map->delblock( &cd->bl ); cd->bl.x = cd->owner->x; cd->bl.y = cd->owner->y; map->addblock( &cd->bl ); // and display again clif->dispchat(cd,0); return true; }
int pet_target_check(struct pet_data *pd, struct block_list *bl, int type) { int rate; nullpo_ret(pd); Assert((pd->master == NULL) || (pd->master->pd == pd)); if(bl == NULL || bl->type != BL_MOB || bl->prev == NULL || pd->pet.intimate < battle_config.pet_support_min_friendly || pd->pet.hungry < 1 || pd->pet.class_ == status_get_class(bl)) return 0; if(pd->bl.m != bl->m || !check_distance_bl(&pd->bl, bl, pd->db->range2)) return 0; if(!status_check_skilluse(&pd->bl, bl, 0, 0)) return 0; if(!type) { rate = pd->petDB->attack_rate; rate = rate * pd->rate_fix / 1000; if(pd->petDB->attack_rate > 0 && rate <= 0) rate = 1; } else { rate = pd->petDB->defence_attack_rate; rate = rate * pd->rate_fix / 1000; if(pd->petDB->defence_attack_rate > 0 && rate <= 0) rate = 1; } if(rnd()%10000 < rate && (pd->target_id == 0 || rnd()%10000 < pd->petDB->change_target_rate)) pd->target_id = bl->id; return 0; }
/** * Get from Storage to the Cart inventory * @param sd : player * @param index : storage index to take the item from * @param amount : number of item to take * @return 0:fail, 1:success */ int storage_storagegettocart(struct map_session_data* sd, int index, int amount) { short flag; nullpo_ret(sd); if( index < 0 || index >= sd->storage_size ) return 0; if( sd->status.storage.items[index].nameid <= 0 ) return 0; //Nothing there. if( amount < 1 || amount > sd->status.storage.items[index].amount ) return 0; if( (flag = pc_cart_additem(sd,&sd->status.storage.items[index],amount,LOG_TYPE_STORAGE)) == 0 ) storage_delitem(sd,index,amount); else { clif_dropitem(sd,index,0); clif_cart_additem_ack(sd,(flag==1)?ADDITEM_TO_CART_FAIL_WEIGHT:ADDITEM_TO_CART_FAIL_COUNT); } return 1; }
/*========================================== * Kick an user from a chatroom * Return: * 0: User cannot be kicked (is gm)/Missing data * 1: Success *------------------------------------------*/ bool chat_kickchat(struct map_session_data* sd, const char* kickusername) { struct chat_data* cd; int i; nullpo_ret(sd); cd = (struct chat_data *)map->id2bl(sd->chatID); if( cd==NULL || (struct block_list *)sd != cd->owner ) return false; ARR_FIND( 0, cd->users, i, strncmp(cd->usersd[i]->status.name, kickusername, NAME_LENGTH) == 0 ); if( i == cd->users ) // User not found return false; if (pc_has_permission(cd->usersd[i], PC_PERM_NO_CHAT_KICK)) return false; //gm kick protection [Valaris] idb_iput(cd->kick_list,cd->usersd[i]->status.char_id,1); chat->leave(cd->usersd[i], true); return true; }