Exemplo n.º 1
0
/**
 * Saves changed achievements for a character.
 * @param[in]   char_id     character identifier.
 * @param[out]  cp          pointer to loaded achievements.
 * @param[in]   p           pointer to map-sent character achievements.
 * @return number of achievements saved.
 */
static int inter_achievement_tosql(int char_id, struct char_achievements *cp, const struct char_achievements *p)
{
	StringBuf buf;
	int i = 0, rows = 0;

	nullpo_ret(cp);
	nullpo_ret(p);
	Assert_ret(char_id > 0);

	StrBuf->Init(&buf);
	StrBuf->Printf(&buf, "REPLACE INTO `%s` (`char_id`, `ach_id`, `completed_at`, `rewarded_at`", char_achievement_db);
	for (i = 0; i < MAX_ACHIEVEMENT_OBJECTIVES; i++)
		StrBuf->Printf(&buf, ", `obj_%d`", i);
	StrBuf->AppendStr(&buf, ") VALUES ");

	for (i = 0; i < VECTOR_LENGTH(*p); i++) {
		int j = 0;
		bool save = false;
		struct achievement *pa = &VECTOR_INDEX(*p, i), *cpa = NULL;

		ARR_FIND(0, VECTOR_LENGTH(*cp), j, ((cpa = &VECTOR_INDEX(*cp, j)) && cpa->id == pa->id));

		if (j == VECTOR_LENGTH(*cp))
			save = true;
		else if (memcmp(cpa, pa, sizeof(struct achievement)) != 0)
			save = true;

		if (save) {
			StrBuf->Printf(&buf, "%s('%d', '%d', '%"PRId64"', '%"PRId64"'", rows ?", ":"", char_id, pa->id, (int64)pa->completed_at, (int64)pa->rewarded_at);
			for (j = 0; j < MAX_ACHIEVEMENT_OBJECTIVES; j++)
				StrBuf->Printf(&buf, ", '%d'", pa->objective[j]);
			StrBuf->AppendStr(&buf, ")");
			rows++;
		}
	}

	if (rows > 0 && SQL_ERROR == SQL->QueryStr(inter->sql_handle, StrBuf->Value(&buf))) {
		Sql_ShowDebug(inter->sql_handle);
		StrBuf->Destroy(&buf); // Destroy the buffer.
		return 0;
	}
	// Destroy the buffer.
	StrBuf->Destroy(&buf);

	if (rows) {
		ShowInfo("achievements saved for char %d (total: %d, saved: %d)\n", char_id, VECTOR_LENGTH(*p), rows);

		/* Sync with inter-db acheivements. */
		VECTOR_CLEAR(*cp);
		VECTOR_ENSURE(*cp, VECTOR_LENGTH(*p), 1);
		VECTOR_PUSHARRAY(*cp, VECTOR_DATA(*p), VECTOR_LENGTH(*p));
	}

	return rows;
}
Exemplo n.º 2
0
/**
 * Retrieves all achievements of a character.
 * @param[in]  char_id  character identifier.
 * @param[out] cp       pointer to character achievements structure.
 * @return true on success, false on failure.
 */
static bool inter_achievement_fromsql(int char_id, struct char_achievements *cp)
{
	StringBuf buf;
	char *data;
	int i = 0, num_rows = 0;

	nullpo_ret(cp);

	Assert_ret(char_id > 0);

	// char_achievements (`char_id`, `ach_id`, `completed_at`, `rewarded_at`, `obj_0`, `obj_2`, ...`obj_9`)
	StrBuf->Init(&buf);
	StrBuf->AppendStr(&buf, "SELECT `ach_id`, `completed_at`, `rewarded_at`");
	for (i = 0; i < MAX_ACHIEVEMENT_OBJECTIVES; i++)
		StrBuf->Printf(&buf, ", `obj_%d`", i);
	StrBuf->Printf(&buf, " FROM `%s` WHERE `char_id` = '%d' ORDER BY `ach_id`", char_achievement_db, char_id);

	if (SQL_ERROR == SQL->QueryStr(inter->sql_handle, StrBuf->Value(&buf))) {
		Sql_ShowDebug(inter->sql_handle);
		StrBuf->Destroy(&buf);
		return false;
	}

	VECTOR_CLEAR(*cp);

	if ((num_rows = (int) SQL->NumRows(inter->sql_handle)) != 0) {
		int j = 0;

		VECTOR_ENSURE(*cp, num_rows, 1);

		for (i = 0; i < num_rows && SQL_SUCCESS == SQL->NextRow(inter->sql_handle); i++) {
			struct achievement t_ach = { 0 };
			SQL->GetData(inter->sql_handle, 0, &data, NULL); t_ach.id = atoi(data);
			SQL->GetData(inter->sql_handle, 1, &data, NULL); t_ach.completed_at = atoi(data);
			SQL->GetData(inter->sql_handle, 2, &data, NULL); t_ach.rewarded_at = atoi(data);
			/* Objectives */
			for (j = 0; j < MAX_ACHIEVEMENT_OBJECTIVES; j++) {
				SQL->GetData(inter->sql_handle, j + 3, &data, NULL);
				t_ach.objective[j] = atoi(data);
			}
			/* Add Entry */
			VECTOR_PUSH(*cp, t_ach);
		}
	}

	SQL->FreeResult(inter->sql_handle);

	StrBuf->Destroy(&buf);

	if (num_rows > 0)
		ShowInfo("achievements loaded for char %d (total: %d)\n", char_id, num_rows);

	return true;
}
Exemplo n.º 3
0
//Party map update notification
int mapif_party_membermoved(struct party *p, int idx)
{
	unsigned char buf[20];

	nullpo_ret(p);
	Assert_ret(idx >= 0 && idx < MAX_PARTY);
	WBUFW(buf,0) = 0x3825;
	WBUFL(buf,2) = p->party_id;
	WBUFL(buf,6) = p->member[idx].account_id;
	WBUFL(buf,10) = p->member[idx].char_id;
	WBUFW(buf,14) = p->member[idx].map;
	WBUFB(buf,16) = p->member[idx].online;
	WBUFW(buf,17) = p->member[idx].lv;
	mapif->sendall(buf, 19);
	return 0;
}
Exemplo n.º 4
0
/**
 * Map iterator subroutine to update quest objectives for a party after killing a monster.
 *
 * @see map_foreachinrange
 * @param ap Argument list, expecting:
 *           int Party ID
 *           int Mob ID
 */
int quest_update_objective_sub(struct block_list *bl, va_list ap)
{
	struct map_session_data *sd = NULL;
	int party_id = va_arg(ap, int);
	int mob_id = va_arg(ap, int);

	nullpo_ret(bl);
	Assert_ret(bl->type == BL_PC);
	sd = BL_UCAST(BL_PC, bl);

	if( !sd->avail_quests )
		return 0;
	if( sd->status.party_id != party_id )
		return 0;

	quest->update_objective(sd, mob_id);

	return 1;
}
Exemplo n.º 5
0
int pet_target_check(struct map_session_data *sd,struct block_list *bl,int type) {
	struct pet_data *pd;
	int rate;

	nullpo_ret(sd);
	pd = sd->pd;

	Assert_ret(pd->msd == 0 || pd->msd->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)
	{
		if(pd->target_id == 0 || rnd()%10000 < pd->petDB->change_target_rate)
			pd->target_id = bl->id;
	}

	return 0;
}
Exemplo n.º 6
0
// Save party to mysql
int inter_party_tosql(struct party *p, int flag, int index)
{
	// 'party' ('party_id','name','exp','item','leader_id','leader_char')
	char esc_name[NAME_LENGTH*2+1];// escaped party name
	int party_id;

	if( p == NULL || p->party_id == 0 )
		return 0;
	Assert_ret(index >= 0 && index < MAX_PARTY);
	party_id = p->party_id;

#ifdef NOISY
	ShowInfo("Save party request ("CL_BOLD"%d"CL_RESET" - %s).\n", party_id, p->name);
#endif
	SQL->EscapeStringLen(inter->sql_handle, esc_name, p->name, strnlen(p->name, NAME_LENGTH));

	if( flag & PS_BREAK )
	{// Break the party
		// we'll skip name-checking and just reset everyone with the same party id [celest]
		if( SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d'", char_db, party_id) )
			Sql_ShowDebug(inter->sql_handle);
		if( SQL_ERROR == SQL->Query(inter->sql_handle, "DELETE FROM `%s` WHERE `party_id`='%d'", party_db, party_id) )
			Sql_ShowDebug(inter->sql_handle);
		//Remove from memory
		idb_remove(inter_party->db, party_id);
		return 1;
	}

	if( flag & PS_CREATE )
	{// Create party
		if( SQL_ERROR == SQL->Query(inter->sql_handle, "INSERT INTO `%s` "
			"(`name`, `exp`, `item`, `leader_id`, `leader_char`) "
			"VALUES ('%s', '%d', '%d', '%d', '%d')",
			party_db, esc_name, p->exp, p->item, p->member[index].account_id, p->member[index].char_id) )
		{
			Sql_ShowDebug(inter->sql_handle);
			return 0;
		}
		party_id = p->party_id = (int)SQL->LastInsertId(inter->sql_handle);
	}

	if( flag & PS_BASIC )
	{// Update party info.
		if( SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `name`='%s', `exp`='%d', `item`='%d' WHERE `party_id`='%d'",
			party_db, esc_name, p->exp, p->item, party_id) )
			Sql_ShowDebug(inter->sql_handle);
	}

	if( flag & PS_LEADER )
	{// Update leader
		if( SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s`  SET `leader_id`='%d', `leader_char`='%d' WHERE `party_id`='%d'",
			party_db, p->member[index].account_id, p->member[index].char_id, party_id) )
			Sql_ShowDebug(inter->sql_handle);
	}

	if( flag & PS_ADDMEMBER )
	{// Add one party member.
		if( SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `party_id`='%d' WHERE `account_id`='%d' AND `char_id`='%d'",
			char_db, party_id, p->member[index].account_id, p->member[index].char_id) )
			Sql_ShowDebug(inter->sql_handle);
	}

	if( flag & PS_DELMEMBER )
	{// Remove one party member.
		if( SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d' AND `account_id`='%d' AND `char_id`='%d'",
			char_db, party_id, p->member[index].account_id, p->member[index].char_id) )
			Sql_ShowDebug(inter->sql_handle);
	}

	if( save_log )
		ShowInfo("Party Saved (%d - %s)\n", party_id, p->name);
	return 1;
}
Exemplo n.º 7
0
/**
 * Handler called whenever a global message is spoken in a NPC's area
 */
int npc_chat_sub(struct block_list* bl, va_list ap)
{
	struct npc_data *nd = NULL;
	struct npc_parse *npcParse = NULL;
	char *msg;
	int len, i;
	struct map_session_data* sd;
	struct npc_label_list* lst;
	struct pcrematch_set* pcreset;
	struct pcrematch_entry* e;

	nullpo_ret(bl);
	Assert_ret(bl->type == BL_NPC);
	nd = BL_UCAST(BL_NPC, bl);
	npcParse = nd->chatdb;

	// Not interested in anything you might have to say...
	if (npcParse == NULL || npcParse->active == NULL)
		return 0;

	msg = va_arg(ap,char*);
	len = va_arg(ap,int);
	sd = va_arg(ap,struct map_session_data *);

	// iterate across all active sets
	for (pcreset = npcParse->active; pcreset != NULL; pcreset = pcreset->next)
	{
		// n across all patterns in that set
		for (e = pcreset->head; e != NULL; e = e->next)
		{
			int offsets[2*10 + 10]; // 1/3 reserved for temp space required by pcre_exec

			// perform pattern match
			int r = libpcre->exec(e->pcre_, e->pcre_extra_, msg, len, 0, 0, offsets, ARRAYLENGTH(offsets));
			if (r > 0)
			{
				// save out the matched strings
				for (i = 0; i < r; i++)
				{
					char var[6], val[255];
					snprintf(var, sizeof(var), "$@p%i$", i);
					libpcre->copy_substring(msg, offsets, r, i, val, sizeof(val));
					script->set_var(sd, var, val);
				}

				// find the target label.. this sucks..
				lst = nd->u.scr.label_list;
				ARR_FIND(0, nd->u.scr.label_list_num, i, strncmp(lst[i].name, e->label, sizeof(lst[i].name)) == 0);
				if (i == nd->u.scr.label_list_num) {
					ShowWarning("npc_chat_sub: Nao foi possivel localizar a label: %s\n", e->label);
					return 0;
				}

				// run the npc script
				script->run_npc(nd->u.scr.script,lst[i].pos,sd->bl.id,nd->bl.id);
				return 0;
			}
		}
	}
	return 0;
}