mail.cpp 7.28 KB
#include "mail.h"
#include "user.h"
#include <db.pb.h>
#include "dbproxy.h"
#include "gateway.h"
#include "gateway_msg.pb.h"

#include "sys.h"


mail_conf_t* g_mail_conf;

void mail_mgr_t::load( const share_msg::mail_t& r )
{
	this->mail_map[r.idx()] = r;
}

share_msg::mail_t* mail_mgr_t::find( MAIL_IDX mail_idx )
{
	auto it = this->mail_map.find(mail_idx);
	if (this->mail_map.end() == it){
		return NULL;
	}
	return &it->second;
}

void mail_mgr_t::del( MAIL_IDX mail_idx )
{
	this->mail_map.erase(mail_idx);

	{//db	
		db_msg::del_mail_msg out;
		out.set_idx(mail_idx);

		g_dbproxy->send_msg(&out, this->user->uid(), db_del_mail_msg_cmd, NULL);
	}
}

uint32_t mail_mgr_t::add_record( user_t* user, USER_ID user_id, MAIL_ID mail_id, ::google::protobuf::Message* msg )
{
	uint32_t idx = 0;
	if (NULL != user){
		idx = (uint32_t)user->gen_idx();
	}

	db_msg::add_mail_msg out;
	share_msg::mail_t* mail = out.mutable_mail();

	if (NULL != msg){
		std::string bin_new = g_serialize_to_string(msg);
		mail->set_bin_data(bin_new);
	}

	{//db
		mail->set_idx(idx);
		mail->set_uid(user_id);
		mail->set_mail_id(mail_id);
		mail->set_time(el_async::get_now_sec() + g_mail_conf->time_out_sec);
		g_dbproxy->send_msg(&out, user_id, db_add_mail_msg_cmd, 0);
	}

	if (NULL != user){
		//momory
		user->mail_mgr.load(*mail);

		{//notify
			gateway_msg::notify_mail_msg_res notify_out;
			notify_out.mutable_mail()->CopyFrom(*mail);
			notify_out.mutable_mail()->set_time(mail->time() - g_mail_conf->time_out_sec);
			user->send_msg(cli_notify_mail_msg_cmd, &notify_out);
		}
	}

	return idx;
}


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

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

	this->mail_map.clear();

	xml.move2children_node();
	xmlNodePtr cur = xml.node_ptr;
	while (cur){
		if (0 != xml.strcmp(cur, "mail")){
			cur = cur->next;
			continue;
		}
		MAIL_ID id = 0;

		xml.get_xml_prop(cur, id, "id");

		std::vector<share_msg::item_t> item_vec;

		std::string str_items;
		const std::string str_def;
		xml.get_xml_prop_def(cur, str_items, "item", str_def);
		if (!str_items.empty()){
			std::vector<std::vector<uint32_t> > para_vec;
			para_vec = el::g_cat_string<uint32_t>(str_items, ';', ',');

			FOREACH(para_vec, it){
				std::vector<uint32_t>& u_vec = *it;
				if (2 != u_vec.size()){
					ALERT_LOG("[id:%u, size:%lu]", id, u_vec.size());
					return false;
				}
				uint32_t id = u_vec[0];
				uint32_t cnt = u_vec[1];

				share_msg::item_t tt_item;
				tt_item.set_id(id);
				tt_item.set_cnt(cnt);

				item_vec.push_back(tt_item);

				if (NULL == g_item_cfg_mgr->find(id)){
					ALERT_LOG("");
					return false;
				}
				
			}
		}

		if (!this->mail_map.insert(std::make_pair(id, item_vec)).second) {
			ALERT_LOG("");
			return false;
		}		

		cur = cur->next;
	}

	return true;
}

std::vector<share_msg::item_t>* mail_conf_t::find( MAIL_ID mail_id )
{
	auto it = this->mail_map.find(mail_id);
	if (this->mail_map.end() == it){
		return NULL;
	}
	return &it->second;
}

mail_conf_t::mail_conf_t()
{
	this->time_out_sec = el::lib_time_t::ONE_DAY_SEC*30;
}

MAIL_ID mail_conf_t::find_new_version()
{
	MAIL_ID new_version_mail_id = 0;
	FOREACH(this->mail_map, it){
		MAIL_ID id = it->first;
		if (common_msg::E_MAIL_ID_400000 <= id && id <= common_msg::E_MAIL_ID_499999){
			new_version_mail_id = id;
		}
	}
	return new_version_mail_id;
}


//////////////////////////////////////////////////////////////////////////
int gateway_t::on_mail_read_msg(el::lib_tcp_peer_info_t* peer_fd_info,
								google::protobuf::Message* msg,
								user_t* user)
{
	auto in = (gateway_msg::mail_read_msg*)msg;

	auto mail = user->mail_mgr.find(in->idx());
	if (NULL == mail){
		WARN_LOG("");
		return share_msg::EC_MAIL_INEXISTENT;
	}

	mail->set_state(share_msg::E_MAIL_STATE_READ);

	{//db
		db_msg::update_mail_state_msg out;
		out.mutable_mail()->CopyFrom(*mail);

		g_dbproxy->send_msg(&out, user->uid(), db_update_mail_state_msg_cmd, NULL);
	}

	{//return client
		gateway_msg::mail_read_msg_res out;
		user->send_msg_res(&out);
	}
	return 0;
}

int gateway_t::on_mail_attachment_msg(el::lib_tcp_peer_info_t* peer_fd_info,
									  google::protobuf::Message* msg,
									  user_t* user)
{
	auto in = (gateway_msg::mail_attachment_msg*)msg;

	auto mail = user->mail_mgr.find(in->idx());
	if (NULL == mail){
		WARN_LOG("");
		return share_msg::EC_MAIL_INEXISTENT;
	}
	if (share_msg::E_MAIL_STATE_GET_ATT == mail->state()){
		WARN_LOG("");
		return share_msg::EC_MAIL_ATTACHMENT_INEXISTENT;
	}

	if ((common_msg::E_MAIL_ID_100001 <= mail->mail_id() && mail->mail_id() <= common_msg::E_MAIL_ID_199999)
		||(common_msg::E_MAIL_ID_400000 <= mail->mail_id() && mail->mail_id() <= common_msg::E_MAIL_ID_499999)){
		auto items = g_mail_conf->find(mail->mail_id());
		if (items->empty()){
			WARN_LOG("");
			return share_msg::EC_MAIL_ATTACHMENT_INEXISTENT;
		}
		FOREACH_P(items, it){
			share_msg::item_t& item = *it;
			user->item_mgr.add(item.id(), item.cnt());
		}
	} else if (common_msg::E_MAIL_ID_200001 == mail->mail_id()){
		share_msg::mail_give_t mail_give;
		try{
			if(!mail_give.ParseFromArray(mail->bin_data().c_str(), mail->bin_data().size())){
				WARN_LOG("[cmd]");
				return share_msg::EC_MAIL_ATTACHMENT_INEXISTENT;
			}
		}catch (...){
			WARN_LOG("[cmd");
			return share_msg::EC_MAIL_ATTACHMENT_INEXISTENT;
		}
		{
			FOREACH_PB(mail_give.items, idx){
				auto& item = mail_give.items(idx);
				user->item_mgr.add(item.id(), item.cnt());	
			}
		}
	} else if (common_msg::E_MAIL_ID_500001 == mail->mail_id()){

	} else {
		return 0;
	}

	mail->set_state(share_msg::E_MAIL_STATE_GET_ATT);

	{//db
		db_msg::update_mail_state_msg out;
		out.mutable_mail()->CopyFrom(*mail);

		g_dbproxy->send_msg(&out, user->uid(), db_update_mail_state_msg_cmd, NULL);
	}

	{//return client
		gateway_msg::mail_attachment_msg_res out;
		user->send_msg_res(&out);
	}
	return 0;
}

int gateway_t::on_mail_del_msg(el::lib_tcp_peer_info_t* peer_fd_info,
							   google::protobuf::Message* msg,
							   user_t* user)
{
	auto in = (gateway_msg::mail_del_msg*)msg;

	gateway_msg::mail_del_msg_res out;
	FOREACH_PB(in->idx, index){
		auto idx = in->idx(index);
		user->mail_mgr.del(idx);

		out.add_idx(idx);
	}

	{//return client
		user->send_msg_res(&out);
	}
	return 0;
}

int gateway_t::on_mail_give_msg(el::lib_tcp_peer_info_t* peer_fd_info,
									  google::protobuf::Message* msg,
									  user_t* user)
{
	auto in = (gateway_msg::mail_give_msg*)msg;

	std::set<ITEM_ID> item_id_set;
	USER_ID recv_uid = in->recv_uid();
	recv_uid = GEN_MAIL_RECV_UID(user->uid(), recv_uid);
	{
		FOREACH_PB(in->give().items, idx){
			auto& item = in->give().items(idx);
			if (!item_id_set.insert(item.id()).second){
				return 0;
			}
			if (!user->item_mgr.is_has_all(item.id(), item.cnt())){
				return 0;
			}		
		}
	}
	{
		FOREACH_PB(in->give().items, idx){
			auto& item = in->give().items(idx);
			user->item_mgr.reduce(item.id(), item.cnt());	
		}
	}
	{
		share_msg::mail_give_t mail_give;
		mail_give.CopyFrom(in->give());
		mail_give.mutable_send_user()->CopyFrom(user->user_show);

		user_t* recv_user = g_user_mgr->find(recv_uid);
		mail_mgr_t::add_record(recv_user, recv_uid, common_msg::E_MAIL_ID_200001, &mail_give);
	}

	{//return client
		gateway_msg::mail_give_msg_res out;
		user->send_msg_res(&out);
	}
	return 0;
}