task.cpp 9.34 KB
#include "task.h"
#include "event.h"
#include "user.h"
#include <gateway_msg.pb.h>
#include "gateway.h"

task_cfg_mgr_t* g_task_cfg_mgr;

task_mgr_t::task_mgr_t()
{
	this->user = NULL;
}

void task_mgr_t::listen_daily_task( TASK_ID task_id, uint32_t param1 )
{
	// 该游戏没有这个任务 ,则返回 	
	if (NULL == g_task_cfg_mgr->find_daily(task_id)){
		return;
	}
	
	EVENT_ID event_id = task_id;
	if (this->do_task_set.end() == this->do_task_set.find(event_id)){
		return;
	}
	
	event_t* event = this->user->event_mgr.find(common_msg::DAILY_EVENT_TASK, event_id);
	if (NULL == event){
		this->user->event_mgr.update_event(this->user->uid(), common_msg::DAILY_EVENT_TASK,
			event_id, param1, el::lib_time_t::day_start_time(g_timer->now_sec()) - 1 + el::lib_time_t::ONE_DAY_SEC, "0");
		event = this->user->event_mgr.find(common_msg::DAILY_EVENT_TASK, event_id);
	} else {
		switch (task_id)
		{
		case share_msg::E_TASK_DAILY_TYPE_1:
		case share_msg::E_TASK_DAILY_TYPE_2:
		case share_msg::E_TASK_DAILY_TYPE_3:
		case share_msg::E_TASK_DAILY_TYPE_4:
		case share_msg::E_TASK_DAILY_TYPE_5:
		case share_msg::E_TASK_DAILY_TYPE_6:
		case share_msg::E_TASK_DAILY_TYPE_7:
		case share_msg::E_TASK_DAILY_TYPE_8:
		case share_msg::E_TASK_DAILY_TYPE_9:
		case share_msg::E_TASK_DAILY_TYPE_10:
			this->user->event_mgr.update_event(this->user->uid(), event->type, event_id, event->data + param1, event->time, event->str_data);
			break;
		default:
			break;
		}
	}

	this->notify_all();
// 	{
// 		gateway_msg::notify_task_daily_msg_res out;
// 		gateway_msg::task_daily_t* td = out.add_task_daily();
// 		td->set_type(task_id);
// 		td->set_param((uint32_t)event->data);
// 
// 		this->user->send_msg(cli_notify_task_daily_msg_cmd, &out);
// 	}
}

void task_mgr_t::update()
{
	this->do_task_set.clear();
	this->finish_task_set.clear();

	{
		std::map<EVENT_ID, event_t>& events = user->event_mgr.find_events(common_msg::DAILY_EVENT_TASK);

		{
			FOREACH(events, it){
				event_t& event = it->second;
				uint32_t task_id = (uint32_t)event.id;

				uint32_t step_id = 0;
				el::convert_from_string(step_id, event.str_data);
				if (this->is_finish(task_id, step_id)){
					this->finish_task_set.insert(event.id);
				} else {
					this->do_task_set.insert(event.id);
				}
			}
		}
	}
}

bool task_mgr_t::is_finish( TASK_ID task_id, STEP_ID step_id )
{
	task_daily_cfg_t* tdc = g_task_cfg_mgr->find_daily(task_id);
	if (NULL == tdc){
		return false;
	}
	return step_id == tdc->step_id_max;
}

void task_mgr_t::create()
{
	if (g_task_cfg_mgr->daily_task_cnt_max <= this->do_task_set.size() + this->finish_task_set.size()){
		return;
	}

	int need = g_task_cfg_mgr->daily_task_cnt_max - this->do_task_set.size() - this->finish_task_set.size();
	std::vector<TASK_ID> task_id_vec;
	{
		FOREACH(g_task_cfg_mgr->daily_cfg_map, it){
			TASK_ID ti = it->first;
			if (this->do_task_set.end() != this->do_task_set.find(ti)){
				continue;
			}
			if (this->finish_task_set.end() != this->finish_task_set.find(ti)){
				continue;
			}
			task_id_vec.push_back(it->first);
		}
	}

	std::random_shuffle(task_id_vec.begin(), task_id_vec.end());
	for (int i = 0; i < need; i++){
		TASK_ID taskid = task_id_vec[i];

		this->user->event_mgr.update_event(this->user->uid(), common_msg::DAILY_EVENT_TASK,
			taskid, 0, el::lib_time_t::day_start_time(g_timer->now_sec()) - 1 + el::lib_time_t::ONE_DAY_SEC, "0");

		this->do_task_set.insert(taskid);
	}
}

void task_mgr_t::notify_all()
{
	// 通知全部的任务状态 [2018/10/30 Administrator]
	gateway_msg::notify_task_daily_msg_res out;
	{
		FOREACH(user->task_mgr.do_task_set, it){
			EVENT_ID event_id = *it;
			event_t* event = user->event_mgr.find(common_msg::DAILY_EVENT_TASK, event_id);

			gateway_msg::task_daily_t* task_daily = out.add_task_daily();
			task_daily->set_type(event->id);
			task_daily->set_param((uint32_t)event->data);
			uint32_t step_id = 0;
			el::convert_from_string(step_id, event->str_data);
			task_daily->set_step_id(step_id);
		}
	}
	{
		FOREACH(user->task_mgr.finish_task_set, it){
			EVENT_ID event_id = *it;
			event_t* event = user->event_mgr.find(common_msg::DAILY_EVENT_TASK, event_id);

			gateway_msg::task_daily_t* task_daily = out.add_task_daily();
			task_daily->set_type(event->id);
			task_daily->set_param((uint32_t)event->data);
			uint32_t step_id = 0;
			el::convert_from_string(step_id, event->str_data);
			task_daily->set_step_id(step_id);
		}
	}
	user->send_msg(cli_notify_task_daily_msg_cmd, &out);
}



task_daily_cfg_t::task_daily_cfg_t()
{
	this->id = 0;
	this->step_id_max = 0;
}

task_daily_step_cfg_t* task_daily_cfg_t::find( STEP_ID step_id )
{
	auto it = this->step_map.find(step_id);
	if (this->step_map.end() == it){
		return NULL;
	}
	return &it->second;
}

bool task_cfg_mgr_t::load_cfg()
{
	const std::string cfg_path = "./cfg/task_daily.xml";

	el::lib_xmlparser_t xml;
	int ret = xml.open(cfg_path.c_str());
	if (SUCC != ret){
		ALERT_LOG("open");
		return false;
	}

	this->init();

	xml.move2children_node();
	xmlNodePtr cur = xml.node_ptr;

	while (cur) {
		if (!xmlStrcmp(cur->name, (const xmlChar *)"data")) {
			xml.get_xml_prop(cur, this->daily_task_cnt_max, "dailyTaskCnt");
		} else if (!xmlStrcmp(cur->name, (const xmlChar *)"task")) {
			task_daily_cfg_t task_daily_cfg;
			xml.get_xml_prop(cur, task_daily_cfg.id, "id");

			xmlNodePtr child_cur = cur->xmlChildrenNode;
			while (child_cur) {
				if (!xmlStrcmp(child_cur->name, (const xmlChar *)"step")) {
					task_daily_step_cfg_t task_daily_step_cfg;
					xml.get_xml_prop(child_cur, task_daily_step_cfg.step, "id");

					if (task_daily_step_cfg.step <= task_daily_cfg.step_id_max){
						return false;
					}
					task_daily_cfg.step_id_max = task_daily_step_cfg.step;

					std::string str_def;
					std::string str_reward;
					xml.get_xml_prop_def(child_cur, str_reward, "reward", str_def);

					std::vector<uint_pair> uint_pair_val;
					str_split_uint(str_reward, uint_pair_val);
					FOREACH(uint_pair_val, it) {
						if (NULL == g_item_cfg_mgr->find(it->key)){
							ALERT_LOG("[reward:%u]", it->key);
							return false;
						}

						if (!task_daily_step_cfg.reward_map.insert(std::make_pair(it->key, it->val)).second) {
							ALERT_LOG("[reward:%u]", it->key);
							return false;
						}
					}
					if (!task_daily_cfg.step_map.insert(std::make_pair(task_daily_step_cfg.step, task_daily_step_cfg)).second) {
						ALERT_LOG("[step_id:%u]", task_daily_step_cfg.step);
						return false;
					}
				}

				child_cur = child_cur->next;
			}//while

			if (!this->daily_cfg_map.insert(std::make_pair(task_daily_cfg.id, task_daily_cfg)).second) {
				ALERT_LOG("[id:%u]", task_daily_cfg.id);
				return false;
			}
		}

		cur = cur->next;
	}//while

// 	if (this->daily_task_cnt_max < this->daily_cfg_map.size()){
// 		ALERT_LOG("");
// 		return false;
// 	}
	
	return true;
}

task_daily_step_cfg_t* task_cfg_mgr_t::find_daily_step( TASK_ID task_id, STEP_ID step_id )
{
	auto it_task = this->daily_cfg_map.find(task_id);
	if (this->daily_cfg_map.end() == it_task){
		return NULL;
	}
	task_daily_cfg_t& tdc = it_task->second;
	return tdc.find(step_id);
}

task_daily_cfg_t* task_cfg_mgr_t::find_daily( TASK_ID task_id )
{
	auto it_task = this->daily_cfg_map.find(task_id);
	if (this->daily_cfg_map.end() == it_task){
		return NULL;
	}
	return &it_task->second;
}

task_daily_step_cfg_t::task_daily_step_cfg_t()
{
	this->step = 0;
}

//////////////////////////////////////////////////////////////////////////

int gateway_t::on_get_task_daily_reward_msg(el::lib_tcp_peer_info_t* peer_fd_info,
							   google::protobuf::Message* msg,
							   user_t* user)
{
	auto in = (gateway_msg::get_task_daily_reward_msg*)msg;
	TASK_ID task_id = in->task_id();
	STEP_ID step_id = in->step_id();

	task_daily_step_cfg_t* tdsc = g_task_cfg_mgr->find_daily_step(task_id, step_id);
	if (NULL == tdsc){
		return share_msg::EC_VALUE_INVALID;
	}

	EVENT_ID event_id = task_id;
	if (user->task_mgr.do_task_set.end() == user->task_mgr.do_task_set.find(event_id)){
		return share_msg::EC_VALUE_INVALID;
	}
	
	event_t* event = user->event_mgr.find(common_msg::DAILY_EVENT_TASK, event_id);
	if (NULL == event){
		return share_msg::EC_VALUE_INVALID;
	}
	
	if ( event->data < step_id){
		return share_msg::EC_VALUE_INVALID;
	}

	uint32_t param = 0;
	el::convert_from_string(param, event->str_data);
	if (step_id <= param){
		return share_msg::EC_VALUE_INVALID;
	}

	std::string str_step_id = el::convert_to_string(step_id);

	user->event_mgr.update_event(user->uid(), event->type, event->id, event->data, event->time, str_step_id);

	{
		gateway_msg::get_task_daily_reward_msg_res out;
		user->send_msg(cli_get_task_daily_reward_msg_cmd, &out);
	}

	FOREACH(tdsc->reward_map, it){
		user->item_mgr.add(it->first, it->second);
	}

	user->task_mgr.update();
	user->task_mgr.notify_all();
// 	{// 领取奖励后,判断任务是否完成,完成后,刷新新的任务. 	
// 		gateway_msg::notify_do_task_daily_msg_res out;
// 		FOREACH(user->task_mgr.do_task_set, it){
// 			EVENT_ID event_id = *it;
// 			event_t* event = user->event_mgr.find(common_msg::DAILY_EVENT_TASK, event_id);
// 
// 			gateway_msg::task_daily_t* task_daily = out.add_task_daily();
// 			task_daily->set_type(event->id);
// 			task_daily->set_param((uint32_t)event->data);
// 			uint32_t step_id = 0;
// 			el::convert_from_string(step_id, event->str_data);
// 			task_daily->set_step_id(step_id);
// 		}
// 		user->send_msg(cli_notify_do_task_daily_msg_cmd, &out);
// 	}

	user->achievement_mgr.update(1, 1);
	return 0;
}