%%%-------------------------------------------------------------------
%%% @doc    宠物声援具体逻辑处理
%%% Module  : lib_pet_data.erl
%%% Created : 2019-12-09
%%% @Author : tyl
%%%-------------------------------------------------------------------
-module(lib_pet_support_mod).

-include("common.hrl").
-include("server.hrl").
-include("pet.hrl").
-include("figure.hrl").
-include("errcode.hrl").
-include("def_module.hrl").
-include("predefine.hrl").
-include("def_goods.hrl").
-include("designation.hrl").
-include("role.hrl").
-include("goods.hrl").
-include("czone.hrl").

-export([
	%% API
	send_pet_power_rank/2               %% 查询全/跨服今天宠物战力列表
	,center_send_pet_power_rank/4
	,send_server_yest_power_rank/2	    %% 查询全/跨服昨日战力前八名宠物信息列表
	,center_send_yest_power_rank/4
	,vote_pet_info/4                    %% 宠物投票信息
	,server_vote_for_pet/3              %% 宠物投票
	,center_vote_for_pet/5
	,send_reward_receive_info/3         %% 查询昨日榜奖励领取状态
	,receive_rank_reward/3              %% 领取全/跨服昨日投票排行奖励
	,center_receive_rank_reward/5
	,upload_pet_info_to_center/3        %% 游戏服上报宠物排行数据到跨服

	,sort_rank_list/1
	,daily_refresh/1                    %% 0点计算宠物昨天战力榜
	,player_receive_reward/3            %% 玩家更新昨日榜领取数据

	,pet_power_change/5                 %% 宠物战力变更
	,refresh_player_power_on_rank/3     %% 玩家战力变更,刷新排行榜上玩家数据

	,center_send_rank_reward/1          %% 跨服发放排行奖励
	,send_rank_reward_core/3

	,check_enter_center/0               %% 判断是否已经进入跨服节奏

	%% gm操作
	,gm_imitate_fake_player_login/1		%% 模拟玩家登陆,刷新排行榜
]).


%% 关于战力排名：
%% 暂时的设定是战力相等时,分先后排名

%% 关于排行榜最高战力玩家刷新:
%% 1. 同一玩家战力提升,刷新排行榜上战力;战力下降不刷新
%% 2. 非同一玩家战力提升,选战力最大者上榜
%% 3. 由于玩家战力变更 和 宠物战力变更是相对比较频繁的行为，
%%    所以由游戏服1小时上报一次。重启服务器也是由游戏服上报
%% 4. 游戏服重启时需要将战力最高者存库

%% ---------------------------------------------------------------
%% @doc 判断是否已经进入跨服节奏 @end
%% ---------------------------------------------------------------
check_enter_center() ->
	case czone_api:env_get_zone() of
		#czone_svr_local{
			zone_id = ZoneId,
			stage = Stage
		} when Stage > 0 -> {Stage, ZoneId};
		_ -> false
	end.

%% ---------------------------------------------------------------
%% @doc 查询全/跨服今天投票宠物列表(暂时不使用) @end
%% ---------------------------------------------------------------
send_pet_power_rank(State, RoleId) ->
	#pet_power_rank_state{rank_info_list = RankInfoList} = State,
	PackRankList = pack_rank_list(RankInfoList),
	{ok, Bin} = pt_163:write(16312, [PackRankList]),
	lib_server_send:send_to_uid(RoleId, Bin).

center_send_pet_power_rank(State, ZoneId, ServerId, RoleId) ->
	#pet_power_rank_center_state{rank_info_map = RankInfoMap} = State,
	RankInfoList = maps:get(ZoneId, RankInfoMap, []),
	PackRankList = pack_rank_list(RankInfoList),
	{ok, Bin} = pt_163:write(16312, [PackRankList]),
	clusters_center:apply_cast(ServerId, lib_server_send, send_to_uid, [RoleId, Bin]),
	ok.

%% ---------------------------------------------------------------
%% @doc 查询全/跨服昨日投票宠物列表 @end
%% ---------------------------------------------------------------
send_server_yest_power_rank(State, RoleId) ->
	#pet_power_rank_state{yest_rank_info_list = YestRankList} = State,
	% F = fun(Info1, Info2) -> Info1#pet_rank_info.rank > Info2#pet_rank_info.rank end,
	% SortRankList = lists:sort(F, RankList),
	F = fun(#pet_power_rank_info{rank = Rank}) -> Rank =< ?PET_POWER_RANK_LEN end,        %% todo
	SplitList = lists:filter(F, YestRankList),
	PackList  = pack_yest_rank_list(SplitList),
	{ok, Bin} = pt_163:write(16309, [PackList]),
	lib_server_send:send_to_uid(RoleId, Bin).

center_send_yest_power_rank(State, ZoneId, ServerId, RoleId) ->
	#pet_power_rank_center_state{yest_rank_info_map = YestRankMap} = State,
	YestRankList = maps:get(ZoneId, YestRankMap, []),
	F = fun(#pet_power_rank_info{rank = Rank}) -> Rank =< ?PET_POWER_RANK_LEN end,
	SplitList = lists:filter(F, YestRankList),
	PackList  = center_pack_yest_rank_list(SplitList),
	{ok, Bin} = pt_163:write(16309, [PackList]),
	clusters_center:apply_cast(ServerId, lib_server_send, send_to_uid, [RoleId, Bin]).

%% ---------------------------------------------------------------
%% @doc 查询昨日榜奖励领取状态 @end
%% ---------------------------------------------------------------
send_reward_receive_info(State, RoleId, ReceiveList) ->
	#pet_power_rank_state{
		yest_rank_info_list = YestRankList
		,center_rank_length = CenterRankLen
	} = State,
	RankLen =
	case check_enter_center() of
		{Stage, ZoneId} when Stage == 1, is_integer(ZoneId) ->
			case CenterRankLen of
				0 -> erlang:length(YestRankList);
				_ -> CenterRankLen
			end;
		{_, ZoneId} when is_integer(ZoneId) -> CenterRankLen;
		_ -> erlang:length(YestRankList)
	end,
	PackList = receive_info_core(ReceiveList),
	lib_server_send:send_to_uid(RoleId, pt_163, 16310, [PackList, RankLen]),
	ok.

receive_info_core(ReceiveList) ->
	F = fun(PetId, TList) ->
		[{PetId, 1}|TList]
	    end,
	PackList = lists:foldl(F, [], ReceiveList),
	PackList.

%% ---------------------------------------------------------------
%% @doc 领取全服昨日投票排行奖励 @end
%% ---------------------------------------------------------------
receive_rank_reward(State, RoleId, PetId) ->
	#pet_power_rank_state{yest_rank_info_list = YestRankList} = State,
	case lists:keyfind(PetId, #pet_power_rank_info.pet_id, YestRankList) of
		#pet_power_rank_info{rank = Rank} ->
			case data_pet:get_pet_support_rank_cfg(Rank) of
				#pet_support_rank_cfg{server_reward = Reward} ->
					%% 发放奖励 && 玩家刷新领取状态
					lib_player:apply_cast(RoleId, ?APPLY_CAST_SAVE, ?MODULE, player_receive_reward, [PetId, Reward]),
					ok;
				_ ->
					{ok, Bin} = pt_163:write(16315, [?ERRCODE(err163_not_reward), PetId]),
					lib_server_send:send_to_uid(RoleId, Bin)
			end;
		_ ->
			ignore
	end.

center_receive_rank_reward(State, ZoneId, Node, RoleId, PetId) ->
	#pet_power_rank_center_state{yest_rank_info_map = YestRankMap} = State,
	YestRankList = maps:get(ZoneId, YestRankMap, []),
	case lists:keyfind(PetId, #pet_power_rank_info.pet_id, YestRankList) of
		#pet_power_rank_info{rank = Rank} ->
			case data_pet:get_pet_support_rank_cfg(Rank) of
				#pet_support_rank_cfg{server_reward = Reward} ->
					Args = [RoleId, ?APPLY_CAST_SAVE, ?MODULE, player_receive_reward, [PetId, Reward]],
					clusters_center:apply_cast(Node, lib_player, apply_cast, Args);
				_ ->
					{ok, Bin} = pt_163:write(16315, [?ERRCODE(err163_not_reward), PetId]),
					lib_server_send:send_to_uid(Node, RoleId, Bin)
			end;
		_ ->
			ignore
	end.

%% todo： 领取信息在请求协议的时候先修改
player_receive_reward(#player_status{id = RoleId, status_pet = StatusPet} = Player, PetId, Reward) ->
	%% 发放奖励
	Produce = #produce{reward = Reward, type = pet_rank_reward, remark = "yesterday rank reward"},
	lib_goods_api:send_reward_with_mail(RoleId, Produce, ?MOD_PET),
	{ok, Bin} = pt_163:write(16315, [?SUCCESS, PetId]),
	lib_server_send:send_to_uid(RoleId, Bin),
	%% 更新领取信息
	#status_pet{support_times = SupportTimes, vote_list = VoteList, receive_pet_list = ReceiveList} = StatusPet,
	NewReceiveList = [PetId|lists:delete(PetId, ReceiveList)],
	NewStatusPet = StatusPet#status_pet{receive_pet_list = NewReceiveList},
	lib_pet_data:save_db_pet_vote_info(RoleId, SupportTimes, VoteList, NewReceiveList),
	NewPlayer = lib_pet_data:save_dict_status_pet(Player, NewStatusPet),
	{ok, NewPlayer}.

%% ---------------------------------------------------------------
%% @doc 点赞信息 @end
%% ---------------------------------------------------------------
vote_pet_info(State, RoleId, VoteList, SupportTimes) ->
	#pet_power_rank_state{
		yest_rank_info_list = YestVoteInfoList
		,center_rank_length = CenterRankLen
	} = State,
	RankLen =
	case check_enter_center() of
		{Stage, ZoneId} when Stage == 1 andalso is_integer(ZoneId) ->
			case CenterRankLen of
				0 -> erlang:length(YestVoteInfoList);
				_ -> CenterRankLen
			end;
		{_, ZoneId} when is_integer(ZoneId) -> CenterRankLen;
		_ ->
			erlang:length(YestVoteInfoList)
	end,
	lib_server_send:send_to_uid(RoleId, pt_163, 16313,
		[VoteList, SupportTimes, RankLen]
	),
	ok.

%% ---------------------------------------------------------------
%% @doc 点赞，发放奖励 @end
%% ---------------------------------------------------------------
server_vote_for_pet(State, RoleId, PetId) ->
	#pet_power_rank_state{rank_info_list = VoteInfoList} = State,
	RankLen = case data_pet:get_pet_kv(pet_power_rank) of
				  Len when is_integer(Len) -> Len;
				  _ -> ?PET_POWER_RANK_LEN
	          end,
	case lists:keyfind(PetId, #pet_power_rank_info.pet_id, VoteInfoList) of
		#pet_power_rank_info{rank = Rank} when Rank =< RankLen ->
			case data_pet:get_pet_kv(pet_vote_reward) of
				[_|_] = Reward ->
					Produce = #produce{reward = Reward, type = pet_vote},
					lib_goods_api:send_reward_with_mail(RoleId, Produce, ?MOD_PET);
				_ ->
					ignore
			end;
		_ ->
			ignore
	end.

center_vote_for_pet(State, ZoneId, Node, RoleId, PetId) ->
	#pet_power_rank_center_state{yest_rank_info_map = VoteInfoMap} = State,
	VoteInfoList = maps:get(ZoneId, VoteInfoMap, []),
	RankLen = case data_pet:get_pet_kv(pet_power_rank) of
		          Len when is_integer(Len) -> Len;
		          _ -> ?PET_POWER_RANK_LEN
	          end,
	case lists:keyfind(PetId, #pet_power_rank_info.pet_id, VoteInfoList) of
		#pet_power_rank_info{rank = Rank} when Rank =< RankLen ->
			case data_pet:get_pet_kv(pet_vote_reward) of
				[_|_] = Reward ->
					Produce = #produce{reward = Reward, type = pet_vote},
					clusters_center:apply_cast(
						Node, lib_goods_api, send_reward_with_mail,
						[RoleId, Produce, ?MOD_PET]
					),
					ok;
				_ ->
					ignore
			end;
		_ ->
			ignore
	end.

upload_pet_info_to_center(State, ZoneId, UpInfoList) ->
	#pet_power_rank_center_state{tmp_rank_info_map = TmpRankInfoMap} = State,
	RankInfoList = maps:get(ZoneId, TmpRankInfoMap, []),
	F = fun(UpPetInfo, TList) ->
		case UpPetInfo of
			#up_pet_info{
				pet_id = PetId
			} ->
				case lists:keyfind(PetId, #pet_power_rank_info.pet_id, TList) of
					#pet_power_rank_info{} = PetRankInfo ->
						PetRankInfo1 = compare_with_up_data(UpPetInfo, PetRankInfo);
					_ ->
						PetRankInfo1 = trans_up_data(UpPetInfo)
				end,
				lists:keystore(PetId, #pet_power_rank_info.pet_id, TList, PetRankInfo1);
			_ ->
				TList
	    end end,
	NewRankInfoList = lists:foldl(F, RankInfoList, UpInfoList),
	NTmpRankInfoMap = maps:put(ZoneId, NewRankInfoList, TmpRankInfoMap),
	State#pet_power_rank_center_state{tmp_rank_info_map = NTmpRankInfoMap}.

compare_with_up_data(UpPetInfo, PetRankInfo) ->
	#up_pet_info{
		player_id          = PlayerId
		,sex               = Sex
		,player_name       = PlayerName
		,player_power      = PlayerPower
		,vip               = Vip
		,sup_vip           = SupVip
		,dress_id          = DressId
		,photo_id          = PhotoId
		,sum_power         = SumPower
		,server_id         = ServerId
		,server_num        = ServerNum
	} = UpPetInfo,
	#pet_power_rank_info{
		player_power = OldPlayerPower
		,sum_power   = OldSumPower
	} = PetRankInfo,
	case PlayerPower > OldPlayerPower of
		true ->
			NewPetRankInfo = PetRankInfo#pet_power_rank_info{
				player_id          = PlayerId
				,sex               = Sex
				,player_name       = PlayerName
				,player_power      = PlayerPower
				,vip               = Vip
				,sup_vip           = SupVip
				,dress_id          = DressId
				,photo_id          = PhotoId
				,server_id         = ServerId
				,server_num        = ServerNum
				,sum_power         = SumPower + OldSumPower
			};
		_ ->
			NewPetRankInfo = PetRankInfo#pet_power_rank_info{
				sum_power         = SumPower + OldSumPower
			}
	end,
	NewPetRankInfo.

trans_up_data(UpPetInfo) ->
	#up_pet_info{
		pet_id             = PetId
		,player_id         = PlayerId
		,sex               = Sex
		,player_name       = PlayerName
		,player_power      = PlayerPower
		,vip               = Vip
		,sup_vip           = SupVip
		,dress_id          = DressId
		,photo_id          = PhotoId
		,server_num        = ServerNum
		,server_id         = ServerId
		,sum_power         = SumPower
	} = UpPetInfo,
	PetRankInfo = #pet_power_rank_info{
		pet_id             = PetId
		,player_id         = PlayerId
		,sex               = Sex
		,player_name       = PlayerName
		,player_power      = PlayerPower
		,vip               = Vip
		,sup_vip           = SupVip
		,dress_id          = DressId
		,photo_id          = PhotoId
		,server_num        = ServerNum
		,server_id         = ServerId
		,sum_power         = SumPower
	},
	PetRankInfo.

%% ---------------------------------------------------------------
%% @doc 宠物战力变更 @end
%% ---------------------------------------------------------------
pet_power_change(State, RoleMsg, PetId, NewPower, OldPower) ->
	#pet_power_rank_state{rank_info_list = RankList, yest_rank_info_list = YestRankList} = State,
	NewRankList = pet_power_change_core(YestRankList, RankList, RoleMsg, PetId, NewPower, OldPower),
	NewState = State#pet_power_rank_state{rank_info_list = NewRankList},
	NewState.

pet_power_change_core(YestRankList, RankList, RoleMsg, PetId, NewPower, OldPower) ->
	PetRankInfo = case lists:keyfind(PetId, #pet_power_rank_info.pet_id, RankList) of
		              #pet_power_rank_info{} = TPetRankInfo -> TPetRankInfo;
		              _ -> #pet_power_rank_info{pet_id = PetId}
	              end,
	#pet_power_rank_info{sum_power = OldSumPower} = PetRankInfo,
	NewSumPower = max(0, OldSumPower + NewPower - OldPower),
	PetRankInfo1 = PetRankInfo#pet_power_rank_info{sum_power = NewSumPower},
	NewPetRankInfo = compare_pet_power(RoleMsg, NewPower, PetRankInfo1),
	YestPetRankInfo = case lists:keyfind(PetId, #pet_power_rank_info.pet_id, YestRankList) of
		                  #pet_power_rank_info{} = TYestPetRankInfo -> TYestPetRankInfo;
		                  _ -> #pet_power_rank_info{}
	                  end,
	lib_pet_data:save_db_pet_power_info(NewPetRankInfo, YestPetRankInfo),
	NewRankList = lists:keystore(PetId, #pet_power_rank_info.pet_id, RankList, NewPetRankInfo),
	NewRankList.

compare_pet_power(RoleMsg, RolePetPower, PetRankInfo) ->
	{RoleId, RoleName, _RolePower, ServerNum} = RoleMsg,
	#pet_power_rank_info{
		pet_power  = OldPetPower
	} = PetRankInfo,
	if
		RolePetPower > OldPetPower ->
			NewRankInfo = PetRankInfo#pet_power_rank_info{
				player_id     = RoleId,
				player_name   = RoleName,
				pet_power     = RolePetPower,
				server_num    = ServerNum
			};
		true ->
			NewRankInfo = PetRankInfo
	end,
	NewRankInfo.

%% ---------------------------------------------------------------
%% @doc 0点更新昨日投票榜 @end
%% ---------------------------------------------------------------
daily_refresh(State) ->
	#pet_power_rank_state{rank_info_list = VoteInfoList} = State,
	RankList = daily_refresh_core(VoteInfoList),
	NewState = State#pet_power_rank_state{rank_info_list = RankList, yest_rank_info_list = RankList},
	NewState.

daily_refresh_core(VoteInfoList) ->
	RankList = sort_rank_list(VoteInfoList),
	%% 存库
	refresh_db_pet_power_rank(RankList),
	case lib_pet_support_mod:check_enter_center() of
		{_, ZoneId} when is_integer(ZoneId) -> ok;
		_ ->
			%% 发放奖励
			send_rank_reward(RankList)
	end,
	RankList.

send_rank_reward(RankList) ->
	%% 直接激活限时称号
	F = fun(#pet_power_rank_info{rank = Rank, player_id = RoleId}) when RoleId > 0 ->
			case data_pet:get_pet_support_rank_cfg(Rank) of
				#pet_support_rank_cfg{top_designation = DesignationId} when DesignationId > 0 ->
					send_rank_reward_core(RoleId, Rank, DesignationId);
				_ ->
					ignore
			end;
		(_) -> ignore
	end,
	lists:map(F, RankList).

center_send_rank_reward(RankList) ->
	%% 直接激活限时称号
	F = fun(#pet_power_rank_info{rank = Rank, player_id = RoleId, server_id = ServerId}) when RoleId > 0 ->
		case data_pet:get_pet_support_rank_cfg(Rank) of
			#pet_support_rank_cfg{top_designation = DesignationId} when DesignationId > 0 ->
				clusters_center:apply_cast(
					ServerId, lib_pet_support_mod, send_rank_reward_core, [RoleId, Rank, DesignationId]
				);
			_ ->
				ignore
		end;
		(_) -> ignore
	    end,
	lists:map(F, RankList).

send_rank_reward_core(RoleId, Rank, DesignationId) ->
	DsgName = case data_designation:get_by_id(DesignationId) of
		          #base_designation{name = Name} -> Name;
		          _ -> ""
	          end,
	%% 发送邮件
	Title = utext:get(1630001), Content = utext:get(1630002, [Rank, DsgName]),
	lib_mail_api:send_sys_mail([RoleId], ?MOD_PET, Title, Content, []),
	lib_designation_api:active_dsgt_common(RoleId, DesignationId),
	ok.

%% ---------------------------------------------------------------------------
%% 玩家战力变更,刷新排行榜上玩家数据
refresh_player_power_on_rank(State, RoleInfo, PetList) ->
	#pet_power_rank_state{rank_info_list = RankInfoList} = State,
	{RoleId, RoleName, RolePower} = RoleInfo,
	F = fun({PetId, IsAdopt}, TRankInfoList) ->
		case IsAdopt of
			0 -> TRankInfoList;
			_ ->
				case lists:keyfind(PetId, #pet_power_rank_info.pet_id, TRankInfoList) of
					#pet_power_rank_info{player_id = PlayerId, player_power = PlayerPower} = RankInfo ->
						if
							RoleId == PlayerId andalso RolePower > PlayerPower ->
								NewRankInfo = RankInfo#pet_power_rank_info{player_power = RolePower},
								TRankInfoList1 = lists:keystore(PetId, #pet_power_rank_info.pet_id, TRankInfoList, NewRankInfo),
								TRankInfoList1;
							RoleId /= PlayerId andalso RolePower > PlayerPower ->
								NewRankInfo = RankInfo#pet_power_rank_info{
									player_id    = RoleId,
									player_name  = RoleName,
									player_power = RolePower
								},
								lib_pet_data:update_db_pet_power_rank_power(RoleId, PetId),
								TRankInfoList1 = lists:keystore(PetId, #pet_power_rank_info.pet_id, TRankInfoList, NewRankInfo),
								TRankInfoList1;
							true ->
								TRankInfoList  %% 同一玩家战力减小不刷新
						end;
					_ -> TRankInfoList
				end
		end end,
	NewRankInfoList = lists:foldl(F, RankInfoList, PetList),
	NewState = State#pet_power_rank_state{rank_info_list = NewRankInfoList},
	NewState.

%% ---------------------- builtin function -----------------------------------
pack_rank_list(RankList) ->
	F = fun(PetPowerRankInfo, TList) ->
		case PetPowerRankInfo of
			#pet_power_rank_info{rank = Rank, pet_id = PetId, sum_power = SumPower} ->
				[{Rank, PetId, SumPower}|TList];
			_ ->
				TList
		end end,
	PackList = lists:foldl(F, [], RankList),
	PackList.

pack_yest_rank_list(RankList) ->
	F = fun(PetSupportRank, TList) ->
		#pet_power_rank_info{
			rank          = Rank,
			pet_id        = PetId,
			player_id     = PlayerId,
			server_num    = ServerNum,
			sum_power     = SumPower
		} = PetSupportRank,
		case lib_role:get_role_show(PlayerId) of
			#ets_role_show{figure = Figure} -> ok;
			_ -> Figure = #figure{}
		end,
		#figure{sex = Sex, sup_vip = SupVip, vip = VipLv, profile_photo_id = PhotoId, dress_list = DressList, name = PlayerName} = Figure,
		DressId = case lists:keyfind(2, 1, DressList) of
			          {_, TDressId} -> TDressId;
					  _ -> 0
		          end,
		[{Rank, PetId, PlayerId, PlayerName, VipLv, SupVip, Sex, DressId, PhotoId, ServerNum, SumPower}|TList]
	end,
	PackList = lists:foldl(F, [], RankList),
	PackList.

center_pack_yest_rank_list(RankList) ->
	F = fun(PetSupportRank, TList) ->
		#pet_power_rank_info{
			rank          = Rank,
			pet_id        = PetId,
			player_id     = PlayerId,
			player_name   = PlayerName,
			vip           = VipLv,
			sup_vip       = SupVip,
			sex           = Sex,
			dress_id      = DressId,
			photo_id      = PhotoId,
			server_num    = ServerNum,
			sum_power     = SumPower
		} = PetSupportRank,
		[{Rank, PetId, PlayerId, PlayerName, VipLv, SupVip, Sex, DressId, PhotoId, ServerNum, SumPower}|TList]
	    end,
	PackList = lists:foldl(F, [], RankList),
	PackList.

sort_rank_list([]) -> [];
sort_rank_list(RankList) ->
	SortF = fun(A, B) ->
		if
			A#pet_power_rank_info.sum_power == B#pet_power_rank_info.sum_power ->
				A#pet_power_rank_info.pet_id < B#pet_power_rank_info.pet_id;
			true ->
				A#pet_power_rank_info.sum_power > B#pet_power_rank_info.sum_power
		end end,
	SortList = lists:sort(SortF, RankList),
	RankF = fun(PetRankInfo, {TRankList, Rank}) ->
		NewPetRankInfo = PetRankInfo#pet_power_rank_info{rank = Rank},
		RankList1 = [NewPetRankInfo|TRankList],
		{RankList1, Rank + 1}
	end,
	{NewRankList, _} = lists:foldl(RankF, {[], 1}, SortList),
	lists:reverse(NewRankList).

refresh_db_pet_power_rank(RankList) ->
	F = fun(#pet_power_rank_info{pet_id = PetId, player_id = PlayerId, sum_power = SumPower}) ->
				Sql = io_lib:format(?SQL_UPDATE_PET_POWER_RANK_INFO, [PlayerId, SumPower, PetId]),
				db:execute(Sql)
		end,
	lists:map(F, RankList).

%% --------------------------- gm操作 ---------------------------
%% @dec 模拟玩家登陆,刷新排行榜
%% Type: 每秒钟登录人数(该操作连续10秒)
%%      1 -- 每秒登录10个人[共100人]
%% 		2 -- 每秒登录50个人[共500人]
%% 		3 -- 每秒登录100个人[共1000人]
%%    	4 -- 1秒内同时(瞬间)登录50个人(消息处理压力测试)
gm_imitate_fake_player_login(Type) ->
	FakeSupportInfo = fetch_fake_player_support_info(),
	%% 设置某时间间隔内登录人数 & 每分钟登录人数
	case Type of
		1 ->
			spawn(
				fun() -> fake_player_refresh_rank(10 div 100, FakeSupportInfo, 0, 100) end
			);
		2 ->
			spawn(
				fun() -> fake_player_refresh_rank(10 div 500, FakeSupportInfo, 0, 500) end
			);
		3 ->
			spawn(
				fun() -> fake_player_refresh_rank(10 div 1000, FakeSupportInfo, 0, 1000) end
			);
		4 ->
			spawn(
				fun() -> fake_player_refresh_rank(0, FakeSupportInfo, 0, 50) end
			);
		_ -> igonre
	end,
	ok.

fake_player_refresh_rank(_Interval, _PetSupportsInfo, Times, MaxTimes) when Times == MaxTimes -> ok;
fake_player_refresh_rank(Interval, _PetSupportsInfo, Times, MaxTimes) ->
	timer:sleep(Interval*1000),
	PetSupportsInfo1 = fetch_fake_player_support_info(),
	fake_player_refresh_rank(Interval, PetSupportsInfo1, Times + 1, MaxTimes).

fetch_fake_player_support_info() ->
	RoleIdList = [545460846580, 545460846581, 545460846582, 545460846583, 545460846584],
	RoleNameList = ["宠物测试1", "宠物测试2", "宠物测试3", "宠物测试4", "宠物测试5"],
	RolePowerList = [10500, 21325, 32457, 49832, 50930, 69345],
	SupportPets   = [101, 102, 103],
	RandRoleId = urand:list_rand(RoleIdList),
	RandName   = urand:list_rand(RoleNameList),
	RandPower  = urand:list_rand(RolePowerList),
	RandSupportPets = urand:get_rand_list(urand:list_rand([0, 1, 2, 3]), SupportPets),
	PetSupportsInfo = {RandRoleId, RandName, RandPower, RandSupportPets, 0},
	PetSupportsInfo.