FriendProc.php 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897
  1. <?php
  2. namespace loyalsoft;
  3. /**
  4. * 好友模块各种操作类型-枚举值
  5. */
  6. class enum_Friend_op extends Enum {
  7. const __default = 0;
  8. // 删除好友
  9. const remove = 1;
  10. // 加好友
  11. const apply = 2;
  12. // 接受请求
  13. const accepted = 3;
  14. // 示好, 送心...
  15. const gift = 4;
  16. // 加好友请求的发送记录
  17. const applied = 5;
  18. // 示好,送心的记录
  19. const giftrecord = 6;
  20. }
  21. /**
  22. * 好友处理流程
  23. * @version
  24. * 1.0.0 Created at 2017-3-6. by --gwang
  25. * @author gwang (mail@wanggangzero.cn)
  26. * @copyright ? 2017-3-6, SJZ LoyalSoft Corporation & gwang. All rights reserved.
  27. */
  28. class FriendProc {
  29. /**
  30. * 好友发送消息的最大长度(超过的截断)
  31. */
  32. const MaxMessageLength = 80;
  33. /**
  34. * 逻辑分发
  35. * 所有的Proc中必须有这样一个方法
  36. * @param type $req
  37. */
  38. static function procMain($req) {
  39. switch ($req->cmd) {
  40. case CmdCode::cmd_user_friend_search: # [6110]查找好友
  41. return FriendProc::SearchFriend($req);
  42. case CmdCode::cmd_user_friend_suggestList: # [6111]添加好友界面获取一批推荐好友列表
  43. return FriendProc::GetSuggestList($req);
  44. case CmdCode::cmd_user_friend_get_list: # [6106]获取好友列表 ok下发好友个人公会信息
  45. return FriendProc::getAppFriends($req);
  46. case CmdCode::cmd_user_friend_get_infos: # [6107]获取详细信息
  47. return FriendProc::getAppFriendInfos($req);
  48. // ------------------------------------------
  49. case CmdCode::cmd_user_friend_gift_getlist: # [6113]拉取好友赠送礼物的记录
  50. return FriendProc::getAppFriendGiftList($req);
  51. case CmdCode::cmd_user_friend_gift_redraw: # [6114]领取好友赠送的礼物[并回赠]
  52. return FriendProc::getAppFriendGift($req);
  53. case CmdCode::cmd_user_friend_gift_send: # [6115]向好友发送礼物,示好
  54. return FriendProc::sendGiftToAppFriend($req);
  55. case CmdCode::cmd_user_friend_unduckmsg:
  56. return FriendProc::CheckUnduckMessage($req);
  57. //--------------------------------------------
  58. case CmdCode::cmd_user_friend_apply: # [6101]加好友
  59. return FriendProc::ApplyToAddNewFriend($req);
  60. case CmdCode::cmd_user_friend_accept: # [6102]接受好友请求
  61. return FriendProc::Accept($req);
  62. case CmdCode::cmd_user_friend_deny: # [6103]拒绝好友请求
  63. return FriendProc::Deny($req);
  64. case CmdCode::cmd_user_friend_remove: # [6104]删除好友
  65. return FriendProc::Remove($req);
  66. case CmdCode::cmd_user_friend_getapplylist: # [6105]好友请求列表
  67. return FriendProc::GetApplyList($req);
  68. //-----------------------------------------------
  69. case CmdCode::cmd_user_friend_leave_message: # [6108]给好友发消息
  70. return FriendProc::SendMessage($req);
  71. case CmdCode::cmd_user_friend_get_message: # [6109]刷新消息
  72. return FriendProc::GetNewMessage($req);
  73. //-----------------------------------------------
  74. case CmdCode::cmd_user_friend_reload: # [6112]更新好友
  75. return FriendProc::Reload($req);
  76. case CmdCode::cmd_user_friend_LookGuildInfo: # [6117]查看好友所在部落信息
  77. return FriendProc::LookGuildInfo($req);
  78. case CmdCode::cmd_user_friend_LookFriendInfo: # [6118]查看好友简介
  79. return FriendProc::LookFriendInfo($req);
  80. default:
  81. return Resp::err(ErrCode::cmd_err);
  82. }
  83. }
  84. /**
  85. * 查看好友的部落信息
  86. * @param type $req
  87. */
  88. static function LookGuildInfo($req) {
  89. $zoneid = $req->zoneid;
  90. $friendId = $req->paras[0];
  91. $mem = $req->mem;
  92. $sql = "select * from `tab_rolename` where userID = '$friendId'";
  93. $paydb = CPayInit();
  94. $rows = $paydb->fetch_array($sql);
  95. if (count($rows) == 0) {
  96. $resp = Resp::err(ErrCode::err_user_no);
  97. } else {
  98. $friendGuildInfo = GuildProc::getMemUserGuildInfo($mem, $friendId, $zoneid);
  99. if ($friendGuildInfo == null && $friendGuildInfo->guildId < 0) {
  100. $resp = Resp::err(ErrCode::err_guild_userguildinfono);
  101. } else {
  102. $guildInfo = GuildProc::getMemGuildInfo($mem, $friendGuildInfo->guildId, $zoneid);
  103. if ($guildInfo == null) { # 找不到公会
  104. $resp = Resp::err(ErrCode::err_guild_guildinfono);
  105. } else {
  106. $resp = Resp::ok($guildInfo);
  107. }
  108. }
  109. }
  110. return $resp;
  111. }
  112. /**
  113. * 查看好友简介
  114. * @param type $req
  115. */
  116. static function LookFriendInfo($req) {
  117. $mem = $req->mem;
  118. $zoneid = $req->zoneid;
  119. $uid = $req->uid;
  120. $friendId = $req->paras[0]; //好友id
  121. $sql = "select * from `tab_rolename` where userID = '$friendId'";
  122. $paydb = CPayInit();
  123. $rows = $paydb->fetch_array($sql);
  124. if (count($rows) == 0) {
  125. $resp = Resp::err(ErrCode::err_user_no);
  126. } else {
  127. $friendInfo = self::initfriendInfo($mem, $rows[0]['userID'], $rows[0]['zoneid']);
  128. if ($friendInfo == null) {
  129. $resp = Resp::err(ErrCode::err_user_no);
  130. } else {
  131. $friendInfo->fightPower = GuildProc::initFightTeamInfo($mem, $rows[0]['userID'], $rows[0]['zoneid']);
  132. $resp = Resp::ok(array(
  133. "friendInfo" => $friendInfo,
  134. ));
  135. }
  136. }
  137. return $resp;
  138. }
  139. /**
  140. * 检查玩家的好友信息是否有未处理的
  141. * @param type $req
  142. */
  143. public static function CheckUnduckMessage($req) {
  144. $mem = $req->mem;
  145. $zoneid = $req->zoneid;
  146. $uid = $req->uid;
  147. $result = -1;
  148. // 别人的赠送列表
  149. $fgiftlist = self::getOps($mem, $uid, $zoneid, enum_Friend_op::gift);
  150. if (count((array) $fgiftlist) <= 0) {
  151. $result = 0;
  152. } else {
  153. foreach ($fgiftlist as $key => $value) {
  154. if (count((array) $value) <= 0) {
  155. continue;
  156. } else {
  157. $result = 1;
  158. break;
  159. }
  160. }
  161. }
  162. //找别人发来的申请加好友的列表
  163. if ($result == 0) {
  164. $ret = FriendProc::getOps($req->mem, $req->uid, $req->zoneid, enum_Friend_op::apply);
  165. $result = (count((array) $ret) > 0) ? 1 : 0;
  166. }
  167. return Resp::ok(array('ret' => $result));
  168. }
  169. /**
  170. * [6112] 核算好友的离线操作
  171. * @param Req $req
  172. */
  173. public static function Reload($req) {
  174. $mem = $req->mem;
  175. $uid = $req->uid;
  176. $zoneid = $req->zoneid;
  177. // 刷新接受请求列表, 将已接受的好友添加到
  178. $allOps = self::getOps($mem, $uid, $zoneid);
  179. $op = new enum_Friend_op(enum_Friend_op::accepted);
  180. $ops = $allOps->$op;
  181. if (count($ops) > 0) {
  182. foreach ($ops as $u => $ts) { # 立即将对方添加到好友列表
  183. self::_AddFriend($mem, $uid, $zoneid, $u);
  184. }
  185. $ops = "{}";
  186. $allOps->$op = $ops;
  187. }
  188. // 刷新删除列表, 看谁和我解除了好友关系, 删掉他
  189. $op = new enum_Friend_op(enum_Friend_op::remove);
  190. $ops = $allOps->$op;
  191. if (count($ops) > 0) {
  192. foreach ($ops as $u => $ts) {
  193. self::_RemoveFriend($mem, $uid, $zoneid, $u);
  194. }
  195. $allOps->$op = "{}";
  196. }
  197. $g = glc();
  198. self::filterOutDateRecords($allOps, # # 清理过期的请求记录,
  199. new enum_Friend_op(enum_Friend_op::applied), $g->User_Friends_Apply_ExpireTs);
  200. self::filterOutDateRecords($allOps, # # 刷新别人发来的好友请求列表, 过期而没有处理的也删掉(莫名其妙的消失,玩家会不会不爽?要不要加上倒计时?).
  201. new enum_Friend_op(enum_Friend_op::apply), $g->User_Friends_Apply_ExpireTs);
  202. self::saveOps($mem, $uid, $zoneid, $allOps, 0); # 回存数据
  203. // 清理过期的互动记录, 不清除, 一个好友最多保留3条记录
  204. // 更新好友数量
  205. return Resp::ok(array("ret" => "ok"));
  206. }
  207. private static function filterOutDateRecords($allOps, $op, $outts) {
  208. $ops = $allOps->$op;
  209. if (count((array) $ops) > 0) {
  210. $ops = array_filter((array) $ops, function ($ts)use($outts) {
  211. return (intval($ts) + $outts) > now();
  212. });
  213. $allOps->$op = (is_null($ops) || 0 == count((array) $ops)) ? "{}" : $ops;
  214. }
  215. }
  216. //
  217. // <editor-fold defaultstate="collapsed" desc=" 聊天/留言 ">
  218. //
  219. /**
  220. * [6108]发送消息/留言
  221. * @param Req $req
  222. */
  223. public static function SendMessage($req) {
  224. // todo:检查是否好友
  225. $mem = $req->mem;
  226. $uid_from = $req->uid;
  227. $uid_to = $req->paras[0];
  228. $msg = $req->paras[1];
  229. if (strlen($msg) > self::MaxMessageLength) {
  230. $msg = substr($msg, 0, self::MaxMessageLength) . "...";
  231. }
  232. $key = MemKey_User::FriendsMsgQueue_hash($req->zoneid, $uid_to);
  233. $arr = $mem->hget($key, $uid_from);
  234. if (null == $arr) {
  235. $arr = ArrayInit();
  236. }
  237. $ts = now();
  238. array_push($arr, "{$msg}{$ts}");
  239. if (count($arr) > glc()->User_Friends_MessageCount_Max) {
  240. array_shift($arr);
  241. }
  242. $mem->hset($key, $uid_from, $arr);
  243. //
  244. $mts = isset($req->paras[2]) ? $req->paras[2] : 0;
  245. $newmsg = self::_GetNewMessage($mem, $req->zoneid, $uid_from, $uid_to, $mts);
  246. return Resp::ok(array("ret" => "ok", 'newmsg' => $newmsg));
  247. }
  248. /**
  249. * [6109]拉取最新消息/留言
  250. *
  251. * @param Req $req
  252. */
  253. public static function GetNewMessage($req) {
  254. if (count($req->paras) < 2) {
  255. return Resp::err(ErrCode::parasnotenough_msg);
  256. }
  257. $uid_filter = $req->paras[0];
  258. $ts = $req->paras[1];
  259. $arr = self::_GetNewMessage($req->mem, $req->zoneid, $req->uid, $uid_filter, $ts);
  260. return Resp::ok($arr);
  261. }
  262. /**
  263. * 取留言消息
  264. * @param CredisUtil $mem
  265. * @param int $zoneid
  266. * @param string $uid
  267. * @param string $f_uid
  268. * @param ts $ts
  269. * @return asoc_array
  270. */
  271. private static function _GetNewMessage($mem, $zoneid, $uid, $f_uid, $ts) {
  272. $key = MemKey_User::FriendsMsgQueue_hash($zoneid, $uid);
  273. $arr = array($f_uid => $mem->hget($key, $f_uid));
  274. // 依据ts时间戳,剔除客户端不需要的消息,然后传送.
  275. foreach ($arr as &$msgq) {
  276. if (null == $msgq) { // 防御
  277. continue;
  278. }
  279. $msgq = array_filter($msgq, function($msg) use($ts) {
  280. return $ts < substr($msg, -10); // 时间戳10位
  281. });
  282. }
  283. return $arr;
  284. }
  285. //
  286. //
  287. // </editor-fold>
  288. //
  289. // <editor-fold defaultstate="collapsed" desc=" 待定 ">
  290. //
  291. /**
  292. * 设置默认同意好友请求
  293. * @param Req $req
  294. */
  295. public static function SetAutoAccept($req) {
  296. }
  297. // </editor-fold>
  298. //
  299. // <editor-fold defaultstate="collapsed" desc=" 好友操作 ">
  300. //
  301. /**
  302. * [6105] 拉取好友请求列表
  303. * @param Req $req
  304. */
  305. public static function GetApplyList($req) {
  306. $ret = FriendProc::getOps($req->mem, $req->uid, $req->zoneid, enum_Friend_op::apply);
  307. return Resp::ok(array("ret" => (count((array) $ret) > 0) ? $ret : array()));
  308. }
  309. /**
  310. * [6101]添加好友
  311. * @param Req $req
  312. */
  313. public static function ApplyToAddNewFriend($req) { // 取目标玩家的ops列表插入请求
  314. $mem = $req->mem;
  315. $uid_to = $req->paras[0];
  316. $uid_from = $req->uid;
  317. if ($uid_from == $uid_to) {
  318. return Resp::err(ErrCode::paras_err, "添加的好友ID非法!");
  319. }
  320. $err = self::AddOp($mem, $req->zoneid, $uid_to, enum_Friend_op::apply, $uid_from);
  321. if (ErrCode::ok != $err) {
  322. return Resp::err($err);
  323. }
  324. $err = self::AddOp($mem, $req->zoneid, $req->uid, enum_Friend_op::applied, $uid_to);
  325. if (ErrCode::ok != $err) {
  326. return Resp::err($err);
  327. }
  328. return Resp::ok(array("ret" => "ok"));
  329. }
  330. /**
  331. * [6102]接受好友请求
  332. * @param Req $req
  333. */
  334. public static function Accept($req) { // 将对方立即放到自己的好友列表中, 并给对方发送接受的op, 删除请求记录
  335. $mem = $req->mem;
  336. $zoneid = $req->zoneid;
  337. $uid_my = $req->uid;
  338. $uid_arr = explode(',', $req->paras[0]);
  339. foreach ($uid_arr as $uid_to) {
  340. $myOp = self::getOps($mem, $req->uid, $zoneid, enum_Friend_op::apply); // 自己的请求列表
  341. unset($myOp->$uid_to); // 删除请求记录
  342. self::saveOps($mem, $req->uid, $zoneid, $myOp, enum_Friend_op::apply); // 更新自己的请求列表
  343. $err = self::AddOp($mem, $zoneid, $uid_to, enum_Friend_op::accepted, $uid_my); // 向对方的已接受列表中添加记录
  344. if ($err != ErrCode::ok) { // 出错
  345. return Resp::err($err);
  346. }
  347. self::_AddFriend($mem, $uid_my, $zoneid, $uid_to);
  348. // $mem->sadd(MemKey_User::FriendsList_set($zoneid, $req->uid), $uid_to); // 立即将对方添加到好友列表
  349. }
  350. return Resp::ok(array("ret" => "ok"));
  351. }
  352. /**
  353. * [6103]拒接好友请求
  354. * @param Req $req
  355. */
  356. public static function Deny($req) { // 直接 删除请求记录, 不通知对方了
  357. $mem = $req->mem;
  358. $zoneid = $req->zoneid;
  359. $uid_my = $req->uid;
  360. $uid_to = $req->paras[0];
  361. // 从自己的列表中删除就行了,不用通知对方
  362. $myOp = self::getOps($mem, $uid_my, $zoneid, enum_Friend_op::apply); // 自己的请求列表
  363. unset($myOp->$uid_to);
  364. self::saveOps($mem, $uid_my, $zoneid, $myOp, enum_Friend_op::apply); // 更新自己的请求列表
  365. return Resp::ok(array("ret" => "ok"));
  366. }
  367. /**
  368. * [6104]删除好友
  369. * @param Req $req
  370. */
  371. public static function Remove($req) {// 将对方立即从自己的好友列表中删除, 并给对方发送remove的op
  372. $mem = $req->mem;
  373. $zoneid = $req->zoneid;
  374. $uid_to = $req->paras[0]; // 删除谁
  375. $uid_my = $req->uid;
  376. $tOp = self::getOps($mem, $uid_to, $zoneid, enum_Friend_op::remove); // 对方的删除列表
  377. $ts = now();
  378. $userInfo_my = UserProc::getUserInfo($mem, $zoneid, $uid_my);
  379. $name = $userInfo_my->game->name;
  380. $tOp->$uid_my = $ts . "_" . $name;
  381. self::saveOps($mem, $uid_to, $zoneid, $tOp, enum_Friend_op::remove); // 更新对方的删除列表
  382. self::_RemoveFriend($mem, $uid_my, $zoneid, $uid_to);
  383. return Resp::ok(array("ret" => "ok"));
  384. }
  385. //
  386. // </editor-fold>
  387. //
  388. // <editor-fold defaultstate="collapsed" desc=" 搜索 ">
  389. /**
  390. * [6110]搜索好友
  391. * @param Req $req
  392. */
  393. static function SearchFriend($req) {
  394. //客户端参数解析
  395. if (count($req->paras) <= 1) { // 参数非法
  396. return Resp::err(ErrCode::parasnotenough_msg);
  397. }
  398. $zoneid = $req->zoneid;
  399. $filter = $req->paras[0];
  400. $start = 0;
  401. if (count($req->paras) > 1) {
  402. $start = $req->paras[1];
  403. }
  404. $max = 8; // 每次查询返回的数据条目数量
  405. $sql = "select * from `tab_rolename` where (`userID`='$filter' OR `roleName` like '%$filter%') and zoneid = $zoneid limit $start, $max ;";
  406. $paydb = CPayInit();
  407. $rows = $paydb->fetch_array($sql);
  408. $ret = ArrayInit();
  409. foreach ($rows as $row) {
  410. $uid = $row['userID'];
  411. $zone_all = $row['zoneid'];
  412. if ($uid == $req->uid) {
  413. continue;
  414. }
  415. $friendInfo = self::initfriendInfo($req->mem, $uid, $zone_all);
  416. if ($friendInfo != null) {
  417. $ret[] = $friendInfo;
  418. }
  419. }
  420. $ops = self::getOps($req->mem, $req->uid, $req->zoneid, enum_Friend_op::applied);
  421. return Resp::ok(array('fList' => $ret, 'applied' => $ops));
  422. }
  423. static function initfriendInfo($mem, $uid, $zoneid) {
  424. $userInfo = UserProc::getUserInfo($mem, $zoneid, $uid);
  425. if ($userInfo == null) {
  426. return null;
  427. }
  428. $userGuildInfo = GuildProc::getMemUserGuildInfo($mem, $uid, $zoneid);
  429. if ($userGuildInfo == null) {
  430. $userGuildInfo = ObjectInit();
  431. $userGuildInfo->guildName = "";
  432. $userGuildInfo->guildId = 0;
  433. }
  434. $key_cur = MemKey_GameRun::Game_PVPScoreByZone_zset($zoneid);
  435. $score = $mem->zscore($key_cur, $uid);
  436. $userGuildInfo->cupScore = $score == null ? 0 : $score;
  437. $friendObj = new initfriendInfoModel(null, $uid, $userInfo->game->name, $userInfo->game->level, $userInfo->game->img, #
  438. $userInfo->game->imgBorderId, $userGuildInfo->guildName, $userGuildInfo->guildId, $userGuildInfo->cupScore);
  439. return $friendObj;
  440. }
  441. /**
  442. * [6111]添加好友界面获取一批推荐好友列表
  443. * @param Req $req
  444. */
  445. static function GetSuggestList($req) {
  446. //客户端参数解析
  447. if (count($req->paras) < 1) { // 参数非法
  448. return Resp::err(ErrCode::parasnotenough_msg);
  449. }
  450. $zoneid = $req->zoneid;
  451. $start = $req->paras[0]; // 第几页
  452. $max = 8; // 每次查询返回的数据条目数量
  453. $sql = "select * from `tab_rolename` where `zoneid`=$zoneid order by ts desc limit $start, $max ;";
  454. $paydb = CPayInit();
  455. $rows = $paydb->fetch_array($sql);
  456. $arr = ArrayInit();
  457. foreach ($rows as $row) {
  458. if ($row['userID'] == $req->uid) {
  459. continue;
  460. }
  461. unset($row["tid"]);
  462. unset($row["zoneid"]);
  463. $arr[] = $row['userID'];
  464. }
  465. $applidops = self::getOps($req->mem, $req->uid, $req->zoneid, enum_Friend_op::applied);
  466. $ret = array('fList' => array_unique($arr), 'applied' => $applidops);
  467. return Resp::ok($ret);
  468. }
  469. // </editor-fold>
  470. //
  471. // <editor-fold defaultstate="collapsed" desc=" 好友列表 ">
  472. /**
  473. * [6106]获取好友ID列表
  474. * @param Req $req
  475. * @return int
  476. */
  477. static function getAppFriends($req) {
  478. self::Reload($req);
  479. $mem = $req->mem;
  480. $zoneid = $req->zoneid;
  481. //客户端参数解析
  482. $friendIds = self::_GetFriendList($mem, $req->uid, $zoneid); // 取好友列表
  483. $userArr = ArrayInit();
  484. foreach ($friendIds as $index => $uid) {
  485. $friendInfo = self::initfriendInfo($mem, $uid, $zoneid);
  486. if ($friendInfo == null) {
  487. continue;
  488. }
  489. $userArr[] = $friendInfo;
  490. }
  491. //$mygiftops = self::getOps($mem, $req->uid, $req->zoneid, enum_Friend_op::giftrecord);
  492. $resp = Resp::ok(array(
  493. #"friends" => $friendIds,
  494. 'userGuild' => $userArr,
  495. ));
  496. return $resp;
  497. }
  498. /**
  499. * 查找好友数量
  500. * @param Req $req
  501. */
  502. public static function getCurrentFriendsCount($req) {
  503. return $req->mem->scard(MemKey_User::FriendsList_set($req->zoneid, $req->uid));
  504. }
  505. /**
  506. * [6107] 获取好友信息列表
  507. * @param Req $req
  508. * @return type
  509. */
  510. static function getAppFriendInfos($req) {
  511. $mem = $req->mem;
  512. //客户端参数解析
  513. $zoneid = $req->zoneid;
  514. $fuids = explode(',', $req->paras[0]); // 逗号分割uid字符串
  515. $max = 8; # 一次最多取八个数据
  516. $n = count($fuids);
  517. // var_dump($fuids);
  518. if ($n > 0 && $n <= $max) {
  519. $fuidkeys = array_map(function ($i) use($zoneid) {
  520. return MemKey_User::Info($zoneid, $i);
  521. }, $fuids);
  522. $arr = $mem->getMulti($fuidkeys);
  523. $friendInfos = ArrayInit();
  524. $n = 0;
  525. foreach ($arr as $userInfo) {
  526. isEditor() && $userInfo = new UserGameModel;
  527. isEditor() && $shareInfo = new UserHeroModel;
  528. $uid = $fuids[$n++];
  529. if (!$userInfo # 玩家数据不为空
  530. || !property_exists($userInfo, 'heros') # 存在heros数据
  531. || !$userInfo->heros) { # heros数据不为空
  532. continue;
  533. }
  534. $sharedHeroId = $userInfo->heros->firendSupportHeroUID;
  535. if ($sharedHeroId) {
  536. $shareInfo = $userInfo->heros->collectHeros->$sharedHeroId;
  537. } else { // todo: 暂定如果没有设置共享英雄,默认取集合中第一个英雄, 征询策划是否修订规则
  538. $coll = $userInfo->heros->collectHeros;
  539. $keys = array_keys((array) $coll);
  540. if (count($keys) <= 0) {
  541. continue;
  542. }
  543. $sharedHeroId = $keys[0];
  544. $shareInfo = $userInfo->heros->collectHeros->$sharedHeroId;
  545. }
  546. // 额外将英雄的装备数据替换为实例数据
  547. self::getArmor($userInfo, $shareInfo, 'weapon');
  548. self::getArmor($userInfo, $shareInfo, 'armor');
  549. self::getArmor($userInfo, $shareInfo, 'ring');
  550. $friendInfos[$uid] = array('sharedHero' => $shareInfo,
  551. 'lastLoginTs' => isset($userInfo->lastLogin) ? $userInfo->lastLogin : 0,
  552. 'level' => $userInfo->level,
  553. 'nickname' => $userInfo->name
  554. );
  555. }
  556. if (count($friendInfos) <= 0) {
  557. $friendInfos = null;
  558. }
  559. $resp = Resp::ok(array('ret' => $friendInfos));
  560. } else {
  561. $resp = Resp::err(ErrCode::paras_err);
  562. }
  563. return $resp;
  564. }
  565. static function getArmor($userInfo, $hero, $armor) {
  566. $armorid = $hero->equip->$armor->itemuid;
  567. if ($armorid > 0 && isset($userInfo->store->equipment->$armorid)) {
  568. $hero->equip->$armor = $userInfo->store->equipment->$armorid;
  569. } else {
  570. $hero->equip->$armor = null;
  571. }
  572. }
  573. // </editor-fold>
  574. //
  575. // <editor-fold defaultstate="collapsed" desc=" 示好 ">
  576. //
  577. /**
  578. * [6115]向好友发送礼物(示好)
  579. * @param Req $req
  580. */
  581. static function sendGiftToAppFriend($req) {
  582. $mem = $req->mem;
  583. $zoneid = $req->zoneid;
  584. $uid = $req->uid;
  585. //客户端参数解析
  586. $fuids = explode(',', $req->paras[0]); // 逗号分割的uid数组
  587. // $pr = $req->paras[1]; // other参数 preserved
  588. $n = count($fuids);
  589. if ($n <= 0) {
  590. return Resp::ok(array("ret" => 0));
  591. }
  592. $mygiftrecord = self::getOps($mem, $uid, $zoneid, enum_Friend_op::giftrecord);
  593. $m = 0;
  594. for ($i = 0; $i < $n; $i++) {
  595. $fid = $fuids[$i];
  596. $tsDay = tsDay();
  597. if (property_exists($mygiftrecord, $fid) // 判断对方是否能够领取礼物(当天已经发送过,则不再发送)
  598. && $mygiftrecord->$fid >= $tsDay) {
  599. continue;
  600. }
  601. $mygiftrecord->$fid = $tsDay; # 更新发送记录
  602. $fgiftinfo = self::getOps($mem, $fid, $zoneid, enum_Friend_op::gift);
  603. if (null == $fgiftinfo) { // 防御
  604. $fgiftinfo = ObjectInit(); // 没找到好友数据, 则创建
  605. }
  606. // 给对方身上插入操作记录
  607. if (!isset($fgiftinfo->$uid) or ! is_array($fgiftinfo->$uid)) {//防御
  608. $fgiftinfo->$uid = ArrayInit();
  609. }
  610. $arr = $fgiftinfo->$uid;
  611. $arr[] = tsDay();
  612. if (count($arr) > 3) { // 最多保留3条记录
  613. sort($arr);
  614. array_shift($arr);
  615. }
  616. $fgiftinfo->$uid = $arr; // 更新下
  617. self::saveOps($mem, $fid, $zoneid, $fgiftinfo, enum_Friend_op::gift);
  618. $m++;
  619. }
  620. // 回存数据
  621. self::saveOps($mem, $uid, $zoneid, $mygiftrecord, enum_Friend_op::giftrecord);
  622. // 其他检查比如任务、成就系统
  623. // ...
  624. // 返回结果
  625. return Resp::ok(array("ret" => $m));
  626. }
  627. /**
  628. * [6113]查询游戏中哪些好友给我发送了礼物的列表
  629. * @param Req $req
  630. */
  631. static function getAppFriendGiftList($req) {
  632. $mem = $req->mem;
  633. $zoneid = $req->zoneid;
  634. $uid = $req->uid;
  635. // 别人的赠送列表
  636. $fgiftlist = self::getOps($mem, $uid, $zoneid, enum_Friend_op::gift);
  637. if (count((array) $fgiftlist) <= 0) {
  638. $fgiftlist = NULL;
  639. }
  640. return Resp::ok(array('ret' => $fgiftlist));
  641. }
  642. /**
  643. * [6114]领取来自好友的礼物[并回赠]
  644. * @param Req $req
  645. */
  646. static function getAppFriendGift($req) {
  647. $mem = $req->mem;
  648. $zoneid = $req->zoneid;
  649. $uid = $req->uid;
  650. //客户端参数解析
  651. $fuids = explode(',', $req->paras[0]); // 逗号分割的uidtsday数组
  652. $bSendback = true; // 是否回赠
  653. $arr = array();
  654. array_map(function($f)use(&$arr) {
  655. $arr[substr($f, -5)] = substr($f, 0, -5); // tsday()占5个字符
  656. }, $fuids);
  657. $fgiftlist = self::getOps($mem, $uid, $zoneid, enum_Friend_op::gift);
  658. $recieved = 0;
  659. foreach ($arr as $ts => $fid) {
  660. if (isset($fgiftlist->$fid) && in_array($ts, $fgiftlist->$fid)) {
  661. StlUtil::arrayRemove($fgiftlist->$fid, $ts);
  662. $recieved++;
  663. }
  664. }
  665. $req->userInfo->game->friendPoint += $recieved;
  666. self::saveOps($mem, $uid, $zoneid, $fgiftlist, enum_Friend_op::gift);
  667. UserProc::updateUserInfo($req);
  668. if ($bSendback && $recieved > 0) {
  669. $uids_send = array_unique(array_values($arr));
  670. $req->paras[0] = implode(',', $uids_send);
  671. // var_dump($uids_send);
  672. self::sendGiftToAppFriend($req);
  673. }
  674. // 当天领取好友礼物有没有上限? 比如100个心.
  675. // 检查是否存在对应的礼物记录,
  676. // 发送礼物
  677. // 删除礼物记录
  678. // 回写数据
  679. // 返回值
  680. return Resp::ok(array("ret" => $recieved));
  681. }
  682. /**
  683. * 玩家初始化
  684. * @param Req $req
  685. */
  686. static function Init($req) {
  687. $mem = $req->mem;
  688. $z = $req->zoneid;
  689. $uid = $req->uid;
  690. // $mem->sadd(MemKey_User::FriendsList_set($z, $uid), "");
  691. $mem->hset(MemKey_User::FriendsMsgQueue_hash($z, $uid), "sys", "");
  692. $mem->hmset(MemKey_User::FriendsOps_hash($z, $uid), array("apply" => "{}",
  693. "applied" => "{}",
  694. "gift" => "{}",
  695. "accepted" => "{}",
  696. "remove" => "{}",
  697. 'giftrecord' => "{}"));
  698. }
  699. //
  700. // </editor-fold>
  701. //
  702. //-------------以下是辅助方法-----------------
  703. //
  704. /**
  705. * 验证是否好友
  706. * @param Req $req
  707. */
  708. public static function isFriendship($zoneid, $myUid, $fUid) {
  709. return gMem()->sismember(MemKey_User::FriendsList_set($zoneid, $myUid), $fUid);
  710. }
  711. /**
  712. * 添加fuid到好友列表
  713. */
  714. private static function _AddFriend($mem, $uid, $zoneid, $fuid) {
  715. $mem->sadd(MemKey_User::FriendsList_set($zoneid, $uid), $fuid);
  716. }
  717. /**
  718. * 从好友列表中删除fuid
  719. */
  720. private static function _RemoveFriend($mem, $uid, $zoneid, $fuid) {
  721. $mem->sremove(MemKey_User::FriendsList_set($zoneid, $uid), $fuid);
  722. }
  723. private static function _GetFriendList($mem, $uid, $zoneid) {
  724. $arr = $mem->smembers(MemKey_User::FriendsList_set($zoneid, $uid));
  725. if (!$arr) { # 数据为空
  726. $arr = ArrayInit();
  727. }
  728. $friendIds = array_values(array_filter($arr, function ($a) {
  729. return $a != "";
  730. }));
  731. return $friendIds;
  732. }
  733. //
  734. // <editor-fold defaultstate="collapsed" desc=" 读写玩家好友数据 ">
  735. /**
  736. * 添加操作
  737. * @param enum_Friend_op $op
  738. * @param Req $req
  739. */
  740. private static function AddOp($mem, $zoneid, $uid, $op, $uid_from) {
  741. $enop = new enum_Friend_op($op);
  742. if (!$enop->isValidValue($op)) {
  743. return ErrCode::paras_err;
  744. }
  745. $ts = now();
  746. $tOp = FriendProc::getOps($mem, $uid, $zoneid, $op);
  747. $userInfo = UserProc::getUserInfo($mem, $zoneid, $uid_from);
  748. $userName = $userInfo->game->name;
  749. $tOp->$uid_from = $ts . "_" . $userName; # 可以按照时间戳排序
  750. return FriendProc::saveOps($mem, $uid, $zoneid, $tOp, $op);
  751. }
  752. /**
  753. * 查询好友异步操作队列
  754. * @param CRedisUtil $mem
  755. * @param string $uid
  756. * @param int $zoneid
  757. * @param enum_Friend_op $op
  758. * @return mixed
  759. */
  760. private static function getOps($mem, $uid, $zoneid, $op = 0) {
  761. $ret = ObjectInit();
  762. if ($op == enum_Friend_op::__default) {
  763. $ret = $mem->hgetall(MemKey_User::FriendsOps_hash($zoneid, $uid));
  764. } else {
  765. $ret = $mem->hget(MemKey_User::FriendsOps_hash($zoneid, $uid), new enum_Friend_op($op));
  766. }
  767. if (is_null($ret)) {
  768. $ret = ObjectInit();
  769. }
  770. return $ret;
  771. }
  772. /**
  773. * 回写好友异步操作队列
  774. * @param CRedisUtil $mem
  775. * @param string $uid
  776. * @param int $zoneid
  777. * @param mixed $data
  778. * @param int $op
  779. */
  780. private static function saveOps($mem, $uid, $zoneid, $data, $op) {
  781. $enop = new enum_Friend_op($op);
  782. if (!$enop->isValidValue($op)) {
  783. return ErrCode::paras_err;
  784. }
  785. if ($op == enum_Friend_op::__default) { # 全部数据
  786. $mem->hmset(MemKey_User::FriendsOps_hash($zoneid, $uid), $data);
  787. } else {
  788. if (is_array($data) && count($data) == 0) {
  789. $data = "{}";
  790. }
  791. $mem->hset(MemKey_User::FriendsOps_hash($zoneid, $uid), $enop, $data);
  792. }
  793. return ErrCode::ok;
  794. }
  795. //
  796. // // </editor-fold>
  797. //
  798. }
  799. class initfriendInfoModel extends Object_ext {
  800. public $uid;
  801. public $name;
  802. public $level;
  803. public $img;
  804. public $imgBorderId;
  805. public $guildName;
  806. public $guildId;
  807. public $cupScore;
  808. function __construct($tag, $uid, $name, $level, $img, $imgBorderId, $guildName, $guildId, $cupScore) {
  809. if (1 == func_num_args() && $tag) { # 默认的Object初始化方法
  810. parent::__construct($tag);
  811. } else {
  812. $this->uid = $uid;
  813. $this->name = $name;
  814. $this->level = $level;
  815. $this->img = $img;
  816. $this->imgBorderId = $imgBorderId;
  817. $this->guildName = $guildName;
  818. $this->guildId = $guildId;
  819. $this->cupScore = $cupScore;
  820. }
  821. }
  822. }