PVPProc.php 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  1. <?php
  2. //
  3. //namespace loyalsoft;
  4. //
  5. ///**
  6. // * PVPProc 竞技场 战斗模块, 挑战玩家镜像
  7. // * @version
  8. // * 1.0.0 Created at 2017-6-26. by --gwang
  9. // * @author gwang (mail@wanggangzero.cn)
  10. // * @copyright ? 2017-6-26, SJZ LoyalSoft Corporation & gwang. All rights reserved.
  11. // */
  12. //class PVPProc {
  13. // //
  14. // // <editor-fold defaultstate="collapsed" desc=" 常量 ">
  15. //
  16. // /**
  17. // * 挑战记录最大条数
  18. // */
  19. // const maxLogCount = 49;
  20. //
  21. // /**
  22. // * 查找对手数量
  23. // */
  24. // const matchCount = 5;
  25. //
  26. // /**
  27. // * 竞技场赛季起始时间戳
  28. // */
  29. // const pvpStartTs = 1588521600; # 2020年5月4日 0时0分0秒
  30. //
  31. // /**
  32. // * 每个赛季持续时常
  33. // */
  34. // const pvpSeasonLengt = 86400 * 14; # 2周
  35. //
  36. // /**
  37. // * 竞技场初始积分
  38. // */
  39. // const pvpBaseScore = 1000;
  40. //
  41. // /**
  42. // * 竞技场 最大上榜人数
  43. // */
  44. // const pvpMaxRank = 500;
  45. //
  46. //// </editor-fold>
  47. //
  48. // /**
  49. // * [6803] 挑战 - 查询对手信息 等级、头像、昵称、战队信息(言灵师,等级,星级,武器,技能,言灵)
  50. // */
  51. // public static function GetChallengeAdversaryInfo() {
  52. // $targetUID = req()->paras[0]; # 参数: 对手的UID
  53. // $game = UserProc::getUserGame(req()->zoneid, $targetUID); # 读取玩家信息
  54. // if (null == $game) {
  55. // Err(ErrCode::user_no_err);
  56. // }
  57. //// $game = UserProc::getUserGame(req()->zoneid, $targetUID);
  58. // $team = JsonUtil::decode($game->heroTeamConfig);
  59. //
  60. // $heros = new \stdClass();
  61. // $curTeamId = $team->curUseTeamID;
  62. // foreach ($team->teamDic->$curTeamId->heros as $i => $hid) {
  63. // if ($hid > 0) {
  64. // $n_hid = $hid - 10000;
  65. // $heros->$n_hid = $game->heros->collectHeros->$hid;
  66. // }
  67. // }
  68. //
  69. // $adversary = array(# # 拼装玩家信息
  70. // 'uid' => $targetUID,
  71. // 'name' => my_null_default($game->base()->name, ""),
  72. // 'level' => my_null_default($game->base()->level, 1),
  73. // 'headImg' => my_null_default($game->base()->headImg, ""),
  74. //// 'skills' => null, # # skills暂时没有实例数据
  75. // 'equipment' => array("equipments" => my_null_default($game->store->equipment, new \stdClass())), # 武器
  76. // 'yanling' => array("items" => my_null_default($game->store->yanling, new \stdClass())), # 言灵
  77. // 'heros' => my_null_default($heros, new \stdClass()), # # 英雄集合
  78. // );
  79. //
  80. // $result = array(# # 拼装返回值
  81. // "adversaryInfo" => $adversary
  82. // );
  83. // return Resp::ok($result);
  84. // }
  85. //
  86. // /**
  87. // * [6804] 挑战 - 记录挑战结果
  88. // */
  89. // static function LogChallengeInfo() {
  90. // list($targetUID, $name, $headImg, $win, $msg) = req()->paras; // 参数: 对手uid,对手昵称,对手头像, 对战结果, 胜利者的留言(失败时无法留言"")
  91. // $key_mine = MemKey_User::OffensiveLog_zset(req()->zoneid, req()->uid);
  92. // $key_target = MemKey_User::DefensiveLog_zset(req()->zoneid, $targetUID);
  93. // $ts = now(); # 记录时间戳
  94. // gMem()->zadd($key_mine, array(# # 组装被挑战对手信息
  95. // JsonUtil::encode(array(
  96. // 'uid' => my_null_default($targetUID, "-"),
  97. // 'name' => my_null_default($name, ""),
  98. // 'headImg' => my_null_default($headImg, ""),
  99. // 'win' => my_null_default($win, false),
  100. // 'msg' => my_null_default($msg, ""),
  101. // 'ts' => $ts
  102. // )) => $ts));
  103. // gMem()->zremrangebyrank($key_mine, self::maxLogCount, -1); # 保留50条数据
  104. // gMem()->zadd($key_target, array(# # 组装挑战者信息
  105. // JsonUtil::encode(array(
  106. // 'uid' => req()->uid,
  107. // 'name' => ctx()->baseInfo->name,
  108. // 'headImg' => ctx()->baseInfo->headImg,
  109. // 'win' => !my_null_default($win, false),
  110. // 'msg' => my_null_default($msg, ""),
  111. // 'ts' => $ts
  112. // )) => $ts));
  113. // gMem()->zremrangebyrank($key_target, self::maxLogCount, -1); # 保留50条数据
  114. // // 暂无发放奖励流程
  115. // TaskProc::OnRankChalenge(); // 更新每日任务
  116. // UserProc::updateUserInfo();
  117. // return Resp::ok(); # 返回成功
  118. // }
  119. //
  120. // /**
  121. // * [6805] 挑战 - 拉取挑战记录
  122. // */
  123. // static function GetChagllengeLog() {
  124. // // 参数:无
  125. // $key_off = MemKey_User::OffensiveLog_zset(req()->zoneid, req()->uid);
  126. // $key_def = MemKey_User::DefensiveLog_zset(req()->zoneid, req()->uid);
  127. // // 拉取自己的挑战记录
  128. // $offLog = gMem()->zrange($key_off, 0, self::maxLogCount);
  129. // $defLog = gMem()->zrange($key_def, 0, self::maxLogCount);
  130. // // Ps. 挑战记录分为2个榜, 且按照时间戳记录,晚于指定时间戳的判定为未读消息,挑战记录最多记录50条
  131. //// if (!CommUtil::isPropertyExists($req->userInfo->game->privateState, "lastCheckDefLog")) {
  132. // ctx()->privateState->lastCheckDefLog_ts = now(); # 记录时间戳
  133. //// }
  134. // UserProc::updateUserInfo(); # 回写数据
  135. // // 记录拉取时间戳(在主界面有个未读消息条数显示, 需要靠最后拉取时间戳对比, 时间戳之后的消息是未读消息)
  136. // // 回传数据记录
  137. // array_walk($offLog, function (&$i) { # 解码一下
  138. // $i = JsonUtil::decode($i);
  139. // });
  140. // array_walk($defLog, function (&$i) { # 解码一下
  141. // $i = JsonUtil::decode($i);
  142. // });
  143. // return Resp::ok(array(
  144. // 'offLog' => $offLog,
  145. // 'defLog' => $defLog
  146. // ));
  147. // }
  148. //
  149. // // <editor-fold defaultstate="collapsed" desc=" 竞技商店 ">
  150. // /**
  151. // * 王刚 16:23:39 (2020.5.9)
  152. // 商店现在的模式定位:
  153. // 商店显示所有物品, 刷新时是重置购买/售罄记录
  154. // 刘海 16:24:23 (2020.5.9)
  155. // 没错
  156. // */
  157. //
  158. // /**
  159. // * [6820] 竞技商店 主界面
  160. // */
  161. // public static function pvpShopMain() {
  162. // $pvp = new Info_UserPVP(ctx()->pvp); # PVP信息
  163. // if ($pvp->shopRefreshTs < now()) { # 检查刷新时间<now => 刷新商品列表
  164. // $pvp->shopRefreshTs = now() + glc()->PVP_shop_refresh_interval; # 更新刷新时间
  165. // $pvp->curShopItems = GameConfig::pvp_shop(); # 重刷道具
  166. // ctx()->pvp = $pvp; # 回写
  167. // UserProc::updateUserInfo();
  168. // }
  169. // return Resp::ok($pvp); // 返回
  170. // }
  171. //
  172. // /**
  173. // * [6821] 竞技 商店 购买道具
  174. // */
  175. // public static function pvpShopBuy() {
  176. // $index = req()->paras[0]; # 参数:道具索引(typeId)
  177. // $pvp = new Info_UserPVP(ctx()->pvp); # PVP 数据
  178. // my_Assert(CommUtil::isPropertyExists($pvp->curShopItems, $index), ErrCode::err_innerfault); # 没有找到改商品
  179. //// isEditor() && $citem = new \sm_pvp_shop();
  180. // $citem = $pvp->curShopItems->$index; # 查询物品数据
  181. // my_Assert($citem->sold == 0, ErrCode::pvp_item_soldout); # 防御道具已售罄
  182. //// var_dump($citem);
  183. // my_Assert($citem->priceType == 5, ErrCode::pay_price_err); # 防御定价异常
  184. // my_Assert($pvp->pvpCoins > $citem->price, ErrCode::pvp_coinnotenough); # pvp币不足
  185. // $citem->sold += 1; # 设置已售罄/已购买标志
  186. // $pvp->pvpCoins -= $citem->price; # 扣除竞技币
  187. // StoreProc::AddMultiItemInStore($citem->goods); # 发放道具
  188. // ctx()->pvp = $pvp; // 回写数据
  189. // UserProc::updateUserInfo();
  190. // return Resp::ok(array('pvp' => $pvp, 'store' => ctx()->store)); # 返回
  191. // }
  192. //
  193. // /**
  194. // * [6822] 竞技 商店 刷新道具
  195. // */
  196. // public static function pvpShopRefresh() {
  197. // // 扣除刷新消耗
  198. // $pvp = ctx()->pvp();
  199. // $costCash = glc()->PVP_shop_refresh_cash;
  200. // my_Assert(ctx()->base()->Consume_Cash($costCash), ErrCode::notenough_cash_msg);
  201. //// $pvp->shopRefreshTs = now() + glc()->PVP_shop_refresh_interval; # 更新刷新时间
  202. // $pvp->curShopItems = GameConfig::pvp_shop(); # 重刷道具
  203. //// ctx()->pvp = $pvp; # 回写
  204. // UserProc::updateUserInfo(); # 回写玩家数据
  205. // return Resp::ok($pvp); # 返回
  206. // }
  207. //
  208. //// // </editor-fold>
  209. // //
  210. // // <editor-fold defaultstate="collapsed" desc=" 竞技场 681x">
  211. // //
  212. //
  213. // /**
  214. // * 辅助方法:取当前赛季的编号(从赛季起始开始算起)
  215. // * @return int
  216. // */
  217. // public static function GetCurSeasonID() {
  218. // $n = ceil((now() - self::pvpStartTs ) / self::pvpSeasonLengt); # 进一取整
  219. // return $n;
  220. // }
  221. //
  222. // /**
  223. // * 辅助方法:取指定赛季的结束时间戳
  224. // * @param int $seasonID
  225. // * @return int
  226. // */
  227. // public static function GetSeasonEndTs($seasonID) {
  228. // $ts = self::pvpStartTs + $seasonID * self::pvpSeasonLengt; # 从起始点开始 + n个赛季时常
  229. // return $ts;
  230. // }
  231. //
  232. // /**
  233. // * [6810] 竞技场 拉取主界面信息
  234. // */
  235. // static function pvpMainInfo() {
  236. // $uid = req()->uid; # 快速访问UID
  237. // $zoneid = req()->zoneid; # 快速访问zoneid
  238. // $pvp = new Info_UserPVP(ctx()->pvp); # 设计玩家pvp数据结构
  239. // $pvp->refreshDailyData(); # 刷新免费挑战次数
  240. // $seasonId = self::GetCurSeasonID(); # 当前赛季ID
  241. // $key = MemKey_GameRun::Game_PVPScoreByZoneSeason_zset($zoneid, $seasonId); # 积分总榜
  242. //
  243. // $score = self::_getScore_by_uid($uid, $key); # 玩家积分
  244. // $rank = self::_getRank_by_uid($uid, $key); # 玩家排名
  245. // $fPower = HeroProc::CalcUserFightPower($zoneid, $uid, ctx()); # 玩家总战力?还是当前防守队伍的战斗力?
  246. // $numNewLog = 0; // todo: 真正查询是否有新战报
  247. // $matches = self::getNewMatches($pvp, $uid, $zoneid); # 获得新的匹配对手
  248. // $pvp->sendRewardEmail($zoneid, $uid, $seasonId); # 发奖励邮件
  249. // ctx()->pvp = $pvp;
  250. // UserProc::updateUserInfo();
  251. // $ret = array(# # 组装 返回值结构
  252. // 'score' => $score, # # 自己的积分
  253. // 'rank' => $rank, # # 自己的排名
  254. // 'pvpCoins' => $pvp->pvpCoins, # # 自己的竞技币
  255. // 'fPower' => $fPower, # # 自己的总战力
  256. // 'fightTicket' => $pvp->fightTicket, # # 自己的挑战票
  257. // 'defTeam' => $pvp->defTeam, # # 自己的防守队伍
  258. // 'bHasNewFightLog' => $numNewLog, # # 是否有战报刷新
  259. // 'matches' => my_null_default($matches, array()), # # 对手列表
  260. // );
  261. // return Resp::ok($ret); # 返回
  262. // }
  263. //
  264. // /**
  265. // * [6811] 竞技场 刷新对手
  266. // */
  267. // static function pvp_Refresh() {
  268. // // 刷新无花费, 间隔时间3秒(客户端控制得了)
  269. // $pvp = new Info_UserPVP(ctx()->pvp);
  270. // $ts = now();
  271. // my_Assert($pvp->nextRefreshTs < $ts, ErrCode::pvp_refresh_time); # 验证时间间隔
  272. // $pvp->curMatches = self::getNewMatches($pvp, req()->uid, req()->zoneid);
  273. // $pvp->nextRefreshTs = now(3);
  274. // ctx()->pvp = $pvp;
  275. // UserProc::updateUserInfo(); # 回写数据
  276. // $ret = array(
  277. // 'curMatches' => my_null_default($pvp->curMatches, array()), # # 当前对手清单
  278. // );
  279. // return Resp::ok($ret);
  280. // }
  281. //
  282. // /**
  283. // * [6812] 竞技场 挑战对手xx
  284. // */
  285. // static function pvp_PK() {
  286. // $uid = req()->uid;
  287. // $zoneid = req()->zoneid;
  288. // $baseInfo = ctx()->baseInfo;
  289. // list($target_uid, $result, $target_name, $target_HeadImg) = req()->paras; # 对手id,胜负结果 0负,1胜
  290. //
  291. // $pvp = ctx()->pvp;
  292. //
  293. // if ($pvp->freeFightTickets > 0) { # 有免费挑战票,先扣除免费的
  294. // $pvp->freeFightTickets -= 1;
  295. // } else {
  296. // my_Assert($pvp->fightTicket > 0, ErrCode::pvp_no_tickets); # 防御: 挑战票不足
  297. // $pvp->fightTicket -= 1; # 扣除挑战票
  298. // }
  299. //
  300. // $season = self::GetCurSeasonID(); # 当前赛季
  301. // $key = MemKey_GameRun::Game_PVPScoreByZoneSeason_zset($zoneid, $season); # redis key
  302. // $RA = self::_getScore_by_uid($uid, $key); # A的积分
  303. // $RB = self::_getScore_by_uid($target_uid, $key); # B的积分
  304. // $EA = 1 / (1 + pow(10, ($RA - $RB) / 400)); # A的胜率期望值
  305. // $EB = 1 / (1 + pow(10, ($RB - $RA) / 400)); # B的胜率期望值
  306. // $K = 32; # 浮动系数, 暂定为32
  307. // $SA = $result ? 1 : 0; # 我的胜负结果
  308. // $SB = $result ? 0 : 1; # 对手的胜负结果
  309. // $R_A = intval($RA + $K * ($SA - $EA )); # 我的最终积分
  310. // $R_B = intval($RB + $K * ($SB - $EB)); # 对手的最终积分
  311. // #
  312. // $myOldRank = self::_getRank_by_uid($uid, $key); # 记录下战前排名
  313. // self::_addScore_by_uid($zoneid, $uid, $R_A - $RA); # 更新A的积分
  314. // $B_Change = $result ? $R_B - $RB : 0; # 计算对方的积分变化:对方输了的情况下扣分,我输了的情况下,不加分
  315. // if ($B_Change != 0) { #
  316. // self::_addScore_by_uid($zoneid, $target_uid, $B_Change); # 更新B的积分
  317. // }
  318. // $myNewRank = self::_getRank_by_uid($uid, $key); # 查询战后排名
  319. // if ($result) {
  320. // $pvp->totalWin += 1;
  321. // TaskProc::OnPvPWinN($pvp->totalWin);
  322. // TaskProc::OnPvPScoreN($R_A);
  323. // }
  324. // ctx()->pvp = $pvp;
  325. // TaskProc::OnPvp(); # 每日PVP挑战即可
  326. // UserProc::updateUserInfo(); # 回写数据
  327. // // 写挑战记录
  328. // $key_mine = MemKey_User::PVP_OffensiveLog_zset($zoneid, $uid); # 我的主动挑战记录
  329. // self::_Log_PVP_PK_Info($key_mine, $target_uid, $target_name, $target_HeadImg, $result, $R_A - $RA); # 自己的挑战记录
  330. // $key_target = MemKey_User::PVP_DefensiveLog_zset($zoneid, $target_uid); # 对手的被挑战记录
  331. // self::_Log_PVP_PK_Info($key_target, $uid, $baseInfo->name, $baseInfo->headImg, !$result, $B_Change); # 对手的被挑战记录
  332. //
  333. // $ret = array(# # 组装返回值
  334. // 'freeFightTickets' => $pvp->freeFightTickets, # # 自己剩余免费票
  335. // 'fightTicket' => $pvp->fightTicket, # # 自己剩余挑战票
  336. // 'RA' => $RA, # # 自己挑战之前积分
  337. // 'RB' => $RB, # # 对手挑战之前积分
  338. // 'R_A' => $R_A, # # 自己最新积分
  339. // 'R_B' => $R_B, # # 对手最新积分
  340. // 'rank_diff' => $myNewRank - $myOldRank, # # 自己的排名变化
  341. // 'rank_new' => $myNewRank, # # 最新排名
  342. // );
  343. // return Resp::ok($ret); # 返回
  344. // }
  345. //
  346. // /**
  347. // * [6813] 竞技场 设置防守队伍
  348. // */
  349. // public static function pvp_setTeam() {
  350. // $heros = req()->paras[0]; # para: 新阵容
  351. // $pvp = new Info_UserPVP(ctx()->pvp);
  352. // my_Assert(is_array($heros), ErrCode::paras_err); # 参数检查
  353. // $pvp->defTeam = $heros; # 更新阵容
  354. // ctx()->pvp = $pvp;
  355. // UserProc::updateUserInfo(); # 回存数据
  356. // return Resp::ok($pvp); # 返回
  357. // }
  358. //
  359. // /**
  360. // * [6814] 购买挑战票
  361. // * @return Resp
  362. // */
  363. // static function pvp_buyticket() {
  364. // $amt = req()->paras[0]; # 购买数量
  365. // my_Assert($amt > 0, ErrCode::paras_err); # 数量>0
  366. // $pvp = ctx()->pvp();
  367. // $g = glc();
  368. // $costCash = $g->PVP_pk_ticket_price * $amt; # 计算消耗钻石
  369. // my_Assert($costCash > 0, ErrCode::pvp_ticket_cost_ilegal); # 定价数据异常
  370. // my_Assert(ctx()->base()->Consume_Cash($costCash), ErrCode::notenough_cash_msg); # 扣除钻石失败
  371. //
  372. // $pvp->fightTicket += $amt; # 发放挑战票
  373. //// ctx()->pvp = $pvp;
  374. // UserProc::updateUserInfo(); # 回写玩家数据
  375. // $ret = array(
  376. // 'fightTicket' => $pvp->fightTicket,
  377. // 'costCash' => $costCash,
  378. // 'userCash' => ctx()->baseInfo->cash
  379. // );
  380. // return Resp::ok($ret); # 返回
  381. // }
  382. //
  383. // /**
  384. // * [6815] 竞技场 拉取榜单数据
  385. // */
  386. // static function pvp_getRank() {
  387. // $maxAmt = 10; # 一次最多取10个玩家信息
  388. // $zoneid = req()->zoneid;
  389. // list($index, $n) = req()->paras; # 起始(0), 数量(n<=max)
  390. // if ($n < 1 || $n > $maxAmt) { # 防御非法情况
  391. // $n = $maxAmt;
  392. // }
  393. // $arr = self::getRankPlayers($zoneid, $index - 1, ($index + $n) - 1); // 上榜玩家
  394. // $rankId = $index;
  395. // $result = ObjectInit();
  396. // if (count($arr)) {
  397. // foreach ($arr as $key => $value) { // $value 的数据类型是array
  398. // $value["uid"] = $key;
  399. // $result->$rankId = $value;
  400. // $rankId += 1;
  401. // }
  402. // }
  403. // $key_rank = MemKey_GameRun::Game_PVPScoreByZoneSeason_zset($zoneid, self::GetCurSeasonID());
  404. // $myRank = self::_getRank_by_uid(req()->uid, $key_rank);
  405. // $myScore = self::_getScore_by_uid(req()->uid, $key_rank);
  406. // $ret = array(
  407. // 'dic' => $result,
  408. // 'myRank' => $myRank,
  409. // 'myScore' => $myScore
  410. // );
  411. // return Resp::ok($ret);
  412. // }
  413. //
  414. // /**
  415. // * [6816] 竞技场 查看战报
  416. // */
  417. // static function pvp_getFightLogs() {
  418. // // 提取主动挑战+被挑战记录
  419. // // 更新下刷新时间
  420. // // 返回
  421. // // 参数:无
  422. // $key_off = MemKey_User::PVP_OffensiveLog_zset(req()->zoneid, req()->uid);
  423. // $key_def = MemKey_User::PVP_DefensiveLog_zset(req()->zoneid, req()->uid);
  424. // // 拉取自己的挑战记录
  425. // $offLog = gMem()->zrange($key_off, 0, self::maxLogCount); # 主动挑战数据
  426. // $defLog = gMem()->zrange($key_def, 0, self::maxLogCount); # 防守数据
  427. // // Ps. 挑战记录分为2个榜, 且按照时间戳记录,晚于指定时间戳的判定为未读消息,挑战记录最多记录50条
  428. // $pvp = new Info_UserPVP(ctx()->pvp); # 玩家竞技场数据
  429. // $pvp->lastCheckDefLog_ts = now(); # 记录时间戳
  430. // UserProc::updateUserInfo(); # 回写数据
  431. // array_walk($offLog, function (&$i) { # 解码一下
  432. // $i = JsonUtil::decode($i);
  433. // });
  434. // array_walk($defLog, function (&$i) { # 解码一下
  435. // $i = JsonUtil::decode($i);
  436. // });
  437. // return Resp::ok(array(
  438. // 'offLog' => $offLog,
  439. // 'defLog' => $defLog
  440. // ));
  441. // }
  442. //
  443. //// ---------------- 辅助函数 -----------------------
  444. //// <editor-fold defaultstate="collapsed" desc=" 辅助 函数 ">
  445. //
  446. // /**
  447. // * 竞技场 - 记录挑战结果
  448. // */
  449. // private static function _Log_PVP_PK_Info($key, $oppUID, $name, $headImg, $win, $score) {
  450. // $ts = now(); # 记录时间戳
  451. // gMem()->zadd($key, array(# # 组装被挑战对手信息
  452. // JsonUtil::encode(array(
  453. // 'uid' => my_null_default($oppUID, "-"), # # 对手uid
  454. // 'name' => my_null_default($name, ""), # # 对手昵称
  455. // 'headImg' => my_null_default($headImg, ""), # # 对手头像
  456. // 'win' => my_null_default($win, false), # # 胜负结果
  457. // 'msg' => "竞技场中没有留言羞辱对手的设定.", # # 胜利者留言
  458. // 'scoreInfo' => my_null_default($score, 0), # # 积分变动
  459. // 'ts' => $ts, # # 时间戳
  460. // )) => $ts));
  461. // gMem()->zremrangebyrank($key, self::maxLogCount, -1); # 保留50条数据
  462. // }
  463. //
  464. // /**
  465. // * 修改积分
  466. // * @param int $zoneid
  467. // * @param string $uid
  468. // * @param int $addValue 可以是负值
  469. // */
  470. // private static function _addScore_by_uid($zoneid, $uid, $addValue) {
  471. // $mem = gMem();
  472. // $seasonId = self::GetCurSeasonID();
  473. // $key = MemKey_GameRun::Game_PVPScoreByZoneSeason_zset($zoneid, $seasonId); # 积分榜
  474. // $score = $mem->zscore($key, $uid);
  475. // if (is_null($score) || $score <= 0) { # 分数异常, 理论上不会出现负分
  476. // $score = self::pvpBaseScore; # 新手基础分
  477. // $mem->zadd($key, array($uid => $score)); # 重置玩家积分
  478. // }
  479. // $newscore = $mem->zincrby($key, $uid, $addValue); # 返回最新值
  480. //// var_dump($newscore);
  481. // return $newscore;
  482. // }
  483. //
  484. // /**
  485. // * 竞技场 查询玩家的积分
  486. // * @param type $uid
  487. // * @return int
  488. // */
  489. // static function _getScore_by_uid($uid, $key) {
  490. // if ("" == $uid) {
  491. // CLog::err('"uid" is Null!');
  492. // return 10; # 记录错误并返回一个极低分
  493. // }
  494. // $mem = gMem();
  495. //// var_dump($key);
  496. // $score = $mem->zscore($key, $uid);
  497. // if (is_null($score) || $score <= 0) { # 分数异常
  498. // $score = self::pvpBaseScore; # 新手基础分
  499. // $mem->zadd($key, array($uid => $score)); # 更新玩家积分
  500. // }
  501. // return $score;
  502. // }
  503. //
  504. // /**
  505. // * 竞技场 查询玩家的排名
  506. // * @param string $uid
  507. // * @param string $key
  508. // * @return int
  509. // */
  510. // static function _getRank_by_uid($uid, $key) {
  511. // $rank = self::pvpMaxRank + 1; # 未上榜
  512. // if ("" == $uid) {
  513. // CLog::err('"uid" is Null!');
  514. // return $rank; # 记录错误并返回未上榜
  515. // }
  516. // $mem = gMem();
  517. //
  518. // $r = $mem->zrevrank($key, $uid);
  519. // if (!is_null($r)) {
  520. // $rank = $r + 1; # 有名次,更新(zset从0开始排序)
  521. // }
  522. // return $rank; # 返回
  523. // }
  524. //
  525. // /**
  526. // * 获取对手匹配结果
  527. // * @param Info_UserPVP $pvp
  528. // * @param CRedisutil $mem
  529. // * @param type $uid
  530. // * @param type $zoneid
  531. // */
  532. // private static function getNewMatches($pvp, $uid, $zoneid) {
  533. // $seasonID = self::GetCurSeasonID();
  534. // $key = MemKey_GameRun::Game_PVPScoreByZoneSeason_zset($zoneid, $seasonID); # redis key
  535. // $arr = self::findmatcher($key, $uid); # 积分榜查找
  536. // if (count($arr) < self::matchCount) { # 再不行, 准备机器人吧
  537. // CLog::err('PVP刷对手数量不足, 赶快考虑加入机器人.', 'PVP'); // todo: 这里引入gm对手数据,
  538. // }
  539. // $ret = self::GetPlayerInfosForPVP($zoneid, $arr);
  540. // return $ret;
  541. // }
  542. //
  543. // /**
  544. // * 查找匹配的对手
  545. // * @param type $key
  546. // * @param type $uid
  547. // */
  548. // private static function findmatcher($key, $uid) {
  549. // // 根据匹配规格获得5个对手即可(1. 排除自己, 2. 最好不要出现已经刷到过的对手)
  550. // // 低于玩家当前积分 -- 1个 -5%~-20%之间
  551. // // 与玩家当前积分基本持平 2个, ±5%之间
  552. // // 高于玩家当前积分 -- 1个 +5%~+40%之间
  553. // $score = self::_getScore_by_uid($uid, $key); # 查积分
  554. // // 计算 比自己弱的 上线下线
  555. // $bH = ceil($score * (1 - 0.05)); # 低于当前玩家积分5%
  556. // $bL = ceil($score * (1 - 0.2)); # 低于当前玩家积分20%
  557. // $aL = ceil($score * (1 + 0.05)); # 高于当前玩家积分5%
  558. // $aH = ceil($score * (1 + 0.2)); # 高于当前玩家积分20%
  559. // $bPlayerUIDs = gMem()->zrevrangebyscore($key, $bH, $bL, true, true, 0, 10); # 取低于玩家积分的uids1个
  560. // $mPlayerUIDs = gMem()->zrevrangebyscore($key, $aL, $bH, true, true, 0, 13); # 取玩家相当的uid2个(以防包含玩家自己)
  561. // $aPlayerUIDs = gMem()->zrevrangebyscore($key, $aH, $aL, true, true, 0, 10); # 取高于玩家的uids1个
  562. // if (array_key_exists($uid, $mPlayerUIDs)) { # 如果积分相近的那一组包含自己
  563. // unset($mPlayerUIDs[$uid]); # 剔除掉
  564. // } else { # 或者不包含自己
  565. // array_pop($mPlayerUIDs); # 那多一个人,踢掉一个
  566. // }
  567. //
  568. // $bPlayerUIDs = self::array_random_assoc($bPlayerUIDs, 1);
  569. // $mPlayerUIDs = self::array_random_assoc($mPlayerUIDs, 2);
  570. // $aPlayerUIDs = self::array_random_assoc($aPlayerUIDs, 1);
  571. //
  572. // $uidWithScore = array_merge($bPlayerUIDs, $mPlayerUIDs, $aPlayerUIDs); # 合并为玩家列表
  573. //
  574. // return $uidWithScore; # 返回uid集合
  575. // }
  576. //
  577. // /**
  578. // * 随机关联数组
  579. // * @param type $arr
  580. // * @param type $num
  581. // * @return type
  582. // */
  583. // private static function array_random_assoc($arr, $num = 1) {
  584. // $keys = array_keys($arr);
  585. // shuffle($keys);
  586. //
  587. // if ($num > count($arr)) {
  588. // $num = count($keys);
  589. // }
  590. //
  591. // $r = array();
  592. // for ($i = 0; $i < $num; $i++) {
  593. // $r[$keys[$i]] = $arr[$keys[$i]];
  594. // }
  595. // return $r;
  596. // }
  597. //
  598. // /**
  599. // * 获取榜单玩家
  600. // * @param Credisutil $mem
  601. // * @param int $zoneid
  602. // * @param int $start
  603. // * @param int $stop
  604. // * @return type
  605. // */
  606. // private static function getRankPlayers($zoneid, $start, $stop) {
  607. // $key = MemKey_GameRun::Game_PVPScoreByZoneSeason_zset($zoneid, self::GetCurSeasonID());
  608. // $retUidsWithScore = gMem()->zrevrange($key, $start, $stop, true);
  609. // return self::GetPlayerInfosForPVP($zoneid, $retUidsWithScore);
  610. // }
  611. //
  612. //// private static function get
  613. //
  614. // /**
  615. // * 拉取玩家信息-pvp模块专用信息
  616. // * @param CredisUtil $mem
  617. // * @param type $zoneid
  618. // * @param type $retUidsWithScore
  619. // * @return type
  620. // */
  621. // private static function GetPlayerInfosForPVP($zoneid, $retUidsWithScore) {
  622. // $arr = ArrayInit();
  623. // foreach ($retUidsWithScore as $uid => $score) {
  624. // $game = UserProc::getUserGame($zoneid, $uid); # 玩家数据
  625. // $teamConfig = $game->pvp->defTeam; # 防守阵容
  626. // $heros = new \stdClass(); # 英雄集合
  627. // foreach ($teamConfig as $hid) {
  628. // if ($hid > 0) {
  629. // $n_hid = $hid - 10000;
  630. // $heros->$n_hid = $game->heros->collectHeros->$hid;
  631. // }
  632. // }
  633. // $fpower = HeroProc::CalcUserFightPower($zoneid, $uid, $game); # 计算总战力
  634. // $adversary = array(# # 拼装玩家信息
  635. // 'uid' => $uid,
  636. // 'name' => my_null_default($game->baseInfo->name, ""),
  637. // 'level' => my_null_default($game->baseInfo->level, 1),
  638. // 'headImg' => my_null_default($game->baseInfo->headImg, ""),
  639. //// 'skills' => null, # # skills暂时没有实例数据
  640. // 'equipment' => array("equipments" => my_null_default($game->store->equipment, new \stdClass())), # 武器
  641. // 'yanling' => array("items" => my_null_default($game->store->yanling, new \stdClass())), # 言灵
  642. // 'heros' => my_null_default($heros, new \stdClass()), # # 英雄集合
  643. // 'score' => $score, # # 积分
  644. // 'fpower' => $fpower, # # 总战力
  645. // );
  646. //// $arr[$uid] = $adversary;
  647. // $arr[] = $adversary;
  648. // }
  649. //
  650. // if (count($arr) <= 0) {
  651. // $arr = null;
  652. // }
  653. // return $arr;
  654. // }
  655. //
  656. //// </editor-fold>
  657. ////
  658. //// </editor-fold>
  659. ////
  660. //}