1. <?php
    2. require_once __DIR__ . '/vendor/autoload.php';
    3. require_once __DIR__ . '/vendor/mysql-master/src/Connection.php';
    4. require_once __DIR__ . '/func_game.php';
    5. require_once __DIR__ . '/channel/Server.php';
    6. require_once __DIR__ . '/channel/Client.php';
    7. use Clue\React\Redis\Factory;
    8. use Clue\React\Redis\Client;
    9. use Workerman\Worker;
    10. use Workerman\Lib\Timer;
    11. $s=new Worker('tcp://0.0.0.0:1234'); // workerman对象
    12. $s->count = 1; // 启动1个进程对外提供服务
    13. $css = []; // 连接数组
    14. $roomusers = []; // 房间的用户
    15. $uconn = []; // 用户id和连接的kv
    16. $tconn = []; // 用户id和连接时间戳kv
    17. $temp_css = []; // 连接上放入临时数组,注册验证过后,再放入正式数组 $css
    18. $db = false; // 数据库对象
    19. $roundinfo = []; // 所有局游戏的信息
    20. // $key is our base64 encoded 256bit key that we created earlier. You will probably store and define this
    21. // key in a config file.
    22. $publickey = 'bRuD5WYw5wd0rdHR9yLlM6wt2vteuiniQBqE70nAuhU=';
    23. // workerman 开启
    24. $s->onWorkerStart = function($worker){
    25. global $db;
    26. $db=new \Workerman\MySQL\Connection(C['dbhost'],C['dbport'],C['dbuname'],C['dbpwd'],C['dbname']);
    27. pay_callback(); // 支付成功后的回调
    28. // 检测超时的正式连接
    29. Timer::add(120, function(){
    30. close_timeout_official_connection(120);
    31. });
    32. // 检查超时的临时连接
    33. Timer::add(10, function(){
    34. close_timeout_temp_connection(10);
    35. });
    36. // 每隔5秒去检查加入房间的用户数组
    37. Timer::add(5, function(){
    38. global $roomusers;
    39. // 剔除重复的玩家
    40. $_data = [];
    41. foreach ($roomusers as $key => $roomuser) {
    42. if (count($roomuser) == 0) {
    43. continue;
    44. }
    45. foreach ($roomuser as $k=>$v) {
    46. if (isset($_data[$key][$v['userid']])) {
    47. // found duplicate
    48. continue;
    49. }
    50. // remember unique item
    51. $_data[$key][$v['userid']] = ($v);
    52. }
    53. $_data[$key] = array_values($_data[$key]);
    54. $roomusers = $_data;
    55. }
    56. logs("----房间里面的玩家----".json_encode($roomusers));
    57. match_allroom_players($roomusers, 15); // 匹配玩家 等待15秒就超时
    58. });
    59. // 每2秒检查心跳
    60. Timer::add(2, function(){
    61. check_matchplayers_heart(2);
    62. });
    63. // 每秒检查roundinfo是否开启游戏
    64. Timer::add(1, function(){
    65. // global $roundinfo;
    66. // $r = red();
    67. // logs("*****redset******");
    68. // var_dump($roundinfo);
    69. // $r->set("roundinfo", json_encode($roundinfo));
    70. game_control();
    71. });
    72. };
    73. // 控制游戏开始结束
    74. function game_control(){
    75. global $roundinfo, $uconn;
    76. logs("-------roundinfo--------".json_encode($roundinfo));
    77. foreach ($roundinfo as $key => $value) {
    78. $userid = $value['userid']; // 发起玩家id
    79. $orders = $value['orders']; // 场次
    80. $touserid = $value['touserid']; // 匹配玩家id
    81. $roomid = $value['roomid']; // 房间id
    82. $lev = $value['lev']; // 玩家级别
    83. $tolev = $value['tolev']; // 对手级别
    84. $user_rounds = $value['userrounds']; // 玩家总局数
    85. $touser_rounds = $value['touserrounds']; // 对手总局数
    86. $timeinterval = $value['endtimestamp'] - time(); // 游戏结束时间戳和当期时间的差值
    87. $reward_user = $value['reward_user_' . $userid]; // 游戏的奖励分数
    88. $reward_touser = $value['reward_user_' . $touserid];
    89. $reward_user_coinlist = $value['reward_user_coinlist_' . $userid]; // 游戏的奖励各种币的累加分数
    90. $reward_touser_coinlist = $value['reward_user_coinlist_' . $touserid];
    91. $reward_room = $value["reward_room"]; // 房间的奖励分数
    92. $coin_reward_room = $value['coin_reward_room']; // 房间奖励币种
    93. $roundmodelid = $value["roundmodelid"]; // 游戏模型id
    94. $roundsid = $key; // 游戏局id
    95. $c = $uconn[$userid]; // 发起者连接
    96. $c1 = $uconn[$touserid]; // 匹配者连接
    97. // 检测到 0 < 开始时间 <= 当前时间 才发送游戏信息
    98. // 开始时间多加5秒保证前台渲染顺利
    99. if ($value['starttimestamp'] + 5 <= time() && $value['starttimestamp'] > 0) {
    100. // if ($value['starttimestamp'] <= time() && $value['starttimestamp'] > 0) {
    101. $roundinfo[$key]['starttimestamp'] = 0; // 开始时间戳置空
    102. wd($c, suc('thisroomgamemodel', $value['gameinfo'])); // 发送游戏渲染信息给发起人
    103. wd($c1, suc('thisroomgamemodel', $value['gameinfo'])); // 发送游戏渲染信息给匹配人
    104. unset($roundinfo[$key]['gameinfo']);
    105. }
    106. // 结束游戏,显示一局结果
    107. if ($timeinterval <= 0) {
    108. // 给赢的玩家加币种
    109. if ($reward_user > $reward_touser) {
    110. $winneruuid = $value['uuid'];
    111. // 只在第一场才奖励
    112. if ($orders == 1) {
    113. // 房间奖励
    114. $tips = "房间胜利奖励{$coin_reward_room}+{$reward_room}";
    115. add_user_coin_notice($userid, $coin_reward_room, $reward_room, $tips, $roundsid);
    116. }
    117. // 更新玩家战绩
    118. $sql = "update users set countwin=countwin+1 where userid='$userid'";
    119. $updateid = query($sql);
    120. if ($updateid === false) {
    121. err("更新胜利场次失败", "update_countwin");
    122. }
    123. $sql = "update users set countfail=countfail+1 where userid='$touserid'";
    124. $updateid = query($sql);
    125. if ($updateid === false) {
    126. err("更新失败场次失败", "update_countfail");
    127. }
    128. } elseif ($reward_user < $reward_touser) {
    129. $winneruuid = $value['touuid'];
    130. // 只在第一场才奖励
    131. if ($orders == 1) {
    132. // 房间胜利奖励
    133. $tips = "房间胜利奖励{$coin_reward_room}+{$reward_room}";
    134. add_user_coin_notice( $touserid, $coin_reward_room, $reward_room, $tips, $roundsid );
    135. }
    136. // 更新玩家战绩
    137. $sql = "update users set countwin=countwin+1 where userid='$touserid'";
    138. $updateid = query($sql);
    139. if ($updateid === false) {
    140. err("更新胜利场次失败", "update_countwin");
    141. }
    142. $sql = "update users set countfail=countfail+1 where userid='$userid'";
    143. $updateid = query($sql);
    144. if ($updateid === false) {
    145. err("更新失败场次失败", "update_countfail");
    146. }
    147. } else {
    148. $winneruuid = "";
    149. // 更新玩家战绩
    150. $sql = "update users set countdraw=countdraw+1 where userid='$touserid'";
    151. $updateid = query($sql);
    152. if ($updateid === false) {
    153. err("更新平局场次失败", "update_countdraw");
    154. }
    155. $sql = "update users set countdraw=countdraw+1 where userid='$userid'";
    156. $updateid = query($sql);
    157. if ($updateid === false) {
    158. err("更新平局场次失败", "update_countdraw");
    159. }
    160. }
    161. // 通知游戏结果, 有下一局返回结果加上广告链接,没有的话直接返回游戏结束。
    162. $row = get_next_round($roomid, $roundmodelid); // 获取下一局的游戏模型
    163. $adurl = isset($row['adurl']) ? $row['adurl'] : ""; // 下一局的广告地址
    164. $gameresult = "next"; // 还有下一局
    165. if (!count($row)) {
    166. $gameresult = "over"; // 没有下一局了
    167. }
    168. logs("---------------1111----------------");
    169. // 返回给前台本局游戏结果
    170. wd($c, suc("syncgamestatus", compact('reward_user', 'reward_touser', "winneruuid", "gameresult", "adurl",
    171. "next_round_projectcoins", "reward_user_coinlist", "reward_touser_coinlist")));
    172. wd($c1, suc("syncgamestatus", [
    173. 'reward_user' => $reward_touser,
    174. 'reward_touser' => $reward_user,
    175. "winneruuid" => $winneruuid,
    176. "gameresult" => $gameresult,
    177. "adurl" => $adurl,
    178. "reward_user_coinlist" => $reward_touser_coinlist,
    179. "reward_touser_coinlist" => $reward_user_coinlist,
    180. ]
    181. ));
    182. logs("---------------121212----------------");
    183. // 更新本轮游戏奖励到游戏局表round
    184. $flag = update_player_reward($roundsid, $reward_user, $reward_touser);
    185. if (!$flag) {
    186. return err("syncgamestatus", "更新本轮奖励失败");
    187. }
    188. // 更新币奖励到用户资产并发通知
    189. // 给玩家加币
    190. logs("-----游戏结束给玩家加币----".json_encode($reward_user_coinlist));
    191. foreach ($reward_user_coinlist as $k=>$v) {
    192. $tips = "玩家抓币奖励" . $k . "+" . $v;
    193. add_user_coin_notice($userid, $k, $v, $tips, $roundsid);
    194. }
    195. // 给对手加币
    196. logs("-----游戏结束给对手加币----".json_encode($reward_touser_coinlist));
    197. foreach ($reward_touser_coinlist as $k=>$v) {
    198. $tips = "玩家抓币奖励" . $k . "+" . $v;
    199. add_user_coin_notice($touserid, $k, $v, $tips, $roundsid);
    200. }
    201. logs("---------前台的局情况------------");
    202. $rounds = cal_rounds($lev); // 当前级别需要的局数
    203. $torounds = cal_rounds($tolev); // 对手当前级别需要的局数
    204. $lev2 = $lev;
    205. logs("-----{$userid}要升到的级别$lev2------" );
    206. logs("----需要的局数----".$rounds);
    207. logs("----玩了多少局----".$user_rounds);
    208. // 当前总局数和需要达到的局数相等 添加升级信息
    209. $upgradeconfigs = '';
    210. $toupgradeconfigs = '';
    211. if ($rounds <= $user_rounds) {
    212. // 生成升级信息
    213. $upgradeconfigs = $value['upgradeconfigs']; // 升级信息
    214. $roundinfo[$key]['upgrade'] = $upgradeconfigs;
    215. logs("----生成升级信息----". json_encode($upgradeconfigs));
    216. }
    217. if ($torounds <= $touser_rounds) {
    218. $toupgradeconfigs = $value['toupgradeconfigs']; // 对手升级信息
    219. // 生成升级信息
    220. $roundinfo[$key]['toupgrade'] = $toupgradeconfigs;
    221. logs("----对手生成升级信息----". json_encode($toupgradeconfigs));
    222. }
    223. logs("---------------2222----------------");
    224. $next_round_projectcoins = []; // 下一轮投放的币
    225. // 开始新一局
    226. if ($gameresult == 'next') {
    227. // 如果还有下一局,删掉当前局的升级信息,放到下一局的升级信息
    228. $result = get_one_room($roomid);
    229. $row['fee'] = $result['fee']; // 房间费用
    230. $row['backpercent'] = $result['backpercent']; // 比率
    231. $row['projectcoinid'] = $result['projectcoinid']; // 项目币id
    232. logs("---新的一局".json_encode($row));
    233. $models = get_room_gamemodel( $roomid, $userid, $touserid, $row, $lev, $tolev, $upgradeconfigs, $toupgradeconfigs, $roundinfo[$key]['orders']);
    234. logs("---models". json_encode($models));
    235. if (isset($roundinfo[$key]['upgrade'])) {
    236. unset($roundinfo[$key]['upgrade']);
    237. }
    238. if (isset($roundinfo[$key]['toupgrade'])) {
    239. unset($roundinfo[$key]['toupgrade']);
    240. }
    241. if (is_string($models) && in_array($models, ['no_model', 'no_items', 'no_roomid', 'no_userid', 'no_insertid', "not_enough_coins", "upgrade_fail"])) {
    242. logs("models error msg");
    243. wd($c, err('thisroomgamemodel', "游戏渲染出错,错误原因" . $models));
    244. wd($c1, err('thisroomgamemodel', "游戏渲染出错,错误原因" . $models));
    245. return false;
    246. }
    247. $next_round_projectcoins = array_map("get_coinname", $models);
    248. }
    249. // 发送下一次的币种的信息
    250. wd($c, suc("next_round_projectcoins", $next_round_projectcoins));
    251. wd($c1, suc("next_round_projectcoins", $next_round_projectcoins));
    252. // 发送升级信息
    253. if (isset($roundinfo[$roundsid]['upgrade'])) {
    254. logs("----发送升级消息----");
    255. var_dump($roundinfo[$roundsid]['upgrade']);
    256. wd($c, suc("send_upgrademsg", $roundinfo[$roundsid]['upgrade']));
    257. }
    258. if (isset($roundinfo[$roundsid]['toupgrade'])) {
    259. logs("----发送升级消息----");
    260. var_dump($roundinfo[$roundsid]['toupgrade']);
    261. wd($c1, suc("send_upgrademsg", $roundinfo[$roundsid]['toupgrade']));
    262. }
    263. logs("---------------3333----------------");
    264. // 只在第一场才奖励
    265. // 分成
    266. if ($orders == 1) {
    267. divided_into( $reward_room * 0.1, $userid, $touserid, $coin_reward_room );
    268. }
    269. // 销毁roundinfo变量
    270. logs("销毁的roundsid-场次:" . $roundsid . "-" . $orders);
    271. unset ($roundinfo[$roundsid]);
    272. }
    273. }
    274. }
    275. // 发送升级信息
    276. //function send_upgrademsg($c, $msg){
    277. // var_dump($msg);
    278. // $timer_id = Timer::add(5, function()use($c, $msg){
    279. // logs("-----升级信息------".json_encode($msg));
    280. // wd($c, suc('upgrademsg', $msg));
    281. // });
    282. // Timer::del($timer_id); // 删除定时器
    283. //}
    284. // 检查是否有下一局 $roundmodelid 上一局的modelid
    285. function get_next_round($roomid, $roundmodelid){
    286. $sql = "select roundorder from roundmodel where roomid='$roomid' and roundmodelid='$roundmodelid'";
    287. $row = query($sql);
    288. $roundorder = $row[0]['roundorder']; // 上一局的 order
    289. // order比上一局大的
    290. $sql = "select * from roundmodel where roundorder>'$roundorder' and roomid='$roomid' ORDER BY roundorder, RAND() LIMIT 0,1";
    291. $row = query($sql); // 大于上一局的order
    292. $data = isset($row[0]) ? $row[0] : [];
    293. return $data;
    294. }
    295. // 连接上
    296. $s->onConnect=function($connection){
    297. global $temp_css;
    298. $temp_css[] = [
    299. 'c' => $connection,
    300. 'timestamp' => time(),
    301. 'userid' => 0,
    302. ];
    303. };
    304. // 当客户端发送消息过来时,转发
    305. $s->onMessage=function($c,$data){
    306. // logs("@@@@@@@@@@@@@@@" . $data);
    307. // 客户端的请求必须是 h开头 或者一个 json字符串
    308. if (substr($data, 0, 1) != 'h' && substr($data, 0, 1) != '{') {
    309. $c->close(); // 关闭连接
    310. return;
    311. }
    312. // 处理 h{...的数据
    313. if ($data[0] == "h" && strpos($data, '{') === false) {
    314. $data = "h";
    315. }
    316. // 打印消息
    317. if ($data != "h") {
    318. logs("-----onmessage-----");
    319. echo $data . "\n";
    320. }
    321. if($data==''){
    322. $c->close();
    323. }else if($data=='h'){
    324. global $css, $tconn;
    325. $find = 0; // 匹配到当前连接
    326. foreach ($css as $key => $v) {
    327. if ($c == $v['c']) {
    328. $c->send('h');
    329. // logs('----更新当前连接的时间戳----');
    330. $css[$key]['timestamp'] = time();
    331. $tconn[$css[$key]['userid']] = time();
    332. $find = 1;
    333. break;
    334. }
    335. }
    336. if (!$find) {
    337. logs("------关掉了!!");
    338. $c->close();
    339. }
    340. }else{
    341. $odata = $data;
    342. $data = trim($odata, "h");
    343. // 遇到 h{a:2,....} 或者 {a:2,....}h 多发一条心跳
    344. if (strlen($data) != strlen($odata)) {
    345. wd($c, "h");
    346. }
    347. $d=trim($odata,'h');
    348. $str = "";
    349. $str=$str.$d;
    350. $str=str_replace('}h{','}{',$str);
    351. $str=str_replace('}hh{','}{',$str);
    352. //logs('get msg : '.json_encode(json_decode($str),JSON_UNESCAPED_UNICODE));
    353. if(strpos($str,'}{')!==false){
    354. $str=str_replace('}{','}###{',$str);
    355. $dataarr=explode('###',$str);
    356. $str=str_replace('###','',$str);
    357. foreach($dataarr as $k=>$v){
    358. $obj=json_decode($v,true);
    359. if($obj){
    360. $str=str_replace($v,'',$str);
    361. $d=getd($obj,$c);
    362. wd($c,$d);
    363. }else{
    364. logs(' wrong json format : '.$str);
    365. }
    366. }
    367. }else{
    368. $obj=json_decode($str,true);
    369. if($obj){
    370. $d=getd($obj,$c);
    371. wd($c,$d);
    372. }else{
    373. logs('decode data error : data = '.$data);
    374. }
    375. }
    376. // // 如果遇到两个json连在一起 {"ac":"getmapadv"}{"ac":"getrooms"}
    377. // if (strpos($data, "}{") !== false) {
    378. //
    379. // }
    380. // $obj=json_decode($data,true);
    381. // if($obj){
    382. // $d=getd($obj,$c);
    383. // wd($c,$d);
    384. // }else{
    385. // logs('decode data error : data = '.$data);
    386. // }
    387. }
    388. };
    389. // 关闭连接
    390. $s->onClose=function($connection){
    391. global $css;
    392. foreach($css as $k=>$v){
    393. if($connection==$v['c']){
    394. unset($css[$k]);
    395. logs('----服务器端关闭连接----');
    396. }
    397. }
    398. };
    399. // 关闭超时的正式连接
    400. function close_timeout_official_connection($timeout){
    401. global $css;
    402. logs("------关闭超时的连接---");
    403. foreach ($css as $k => $v) {
    404. // 如果超过两分钟就关闭连接
    405. if (time() - $v['timestamp'] > $timeout) {
    406. logs('----关闭超过'.$timeout.'秒的正式socket连接----');
    407. $v['c']->close();
    408. unset($css[$k]);
    409. }
    410. }
    411. }
    412. // 关闭超时的临时连接
    413. function close_timeout_temp_connection($timeout){
    414. global $temp_css;
    415. logs("------关闭超时的连接---");
    416. foreach ($temp_css as $k => $v) {
    417. if (time() - $v['timestamp'] > $timeout) {
    418. logs('----关闭超过'.$timeout.'秒的临时socket连接----');
    419. $v['c']->close();
    420. unset($timeout[$k]);
    421. }
    422. }
    423. }
    424. // 关闭超时的roundinfo
    425. //function unset_timeout_roundsinfo(){
    426. // global $roundinfo;
    427. // if (!count($roundinfo)) {
    428. // return false;
    429. // }
    430. // foreach ($roundinfo as $key=>$value) {
    431. // if ($value['endtimestamp'] < time()) {
    432. // unset($roundinfo[$key]);
    433. // }
    434. // }
    435. // return true;
    436. //}
    437. // 更新连接数
    438. function updateconnectionnumber($r){
    439. global $css;
    440. $clen=[];
    441. $clen['allcount']=count($css);
    442. $clen['uidcount']=0;
    443. $clen['regcount']=0;
    444. $clen['emptycount']=0;
    445. global $css;
    446. foreach($css as $k=>$v){
    447. if(!empty($v['userid'])){
    448. $clen['uidcount']++;
    449. }else if(!empty($v['timestamp'])){
    450. $clen['regcount']++;
    451. }else{
    452. $clen['emptycount']++;
    453. }
    454. }
    455. $r->set('socket', json_encode($clen));
    456. }
    457. // 给客户端发送消息
    458. function wd($c,$d){
    459. if ($d) {
    460. if(is_array($d))$d=json_encode($d);
    461. logs("-------给客户端发送消息:".$d);
    462. $c->send($d);
    463. }
    464. }
    465. // 获取玩家的胜负情况
    466. //function get_user_rounds_condition($userid){
    467. // $condition = [];
    468. // // 胜
    469. // $sql = "select count(*) win from rounds where (userid={$userid} and award>toaward) or (touserid={$userid} and award<toaward)";
    470. // $row = query($sql);
    471. // $condition['win'] = $row[0]["win"];
    472. // // 平
    473. // $sql = "select count(*) draw from rounds where (userid={$userid} and award=toaward)";
    474. // $row = query($sql);
    475. // $condition['draw'] = $row[0]["draw"];
    476. // // 总局数
    477. // $sql = "select count(*) counts from rounds where userid={$userid} or touserid={$userid}";
    478. // $row = query($sql);
    479. // $condition['lost'] = $row[0]["counts"] - $condition['win'] - $condition['draw'];
    480. //
    481. // return $condition;
    482. //}
    483. function getd($d, $c){
    484. global $publickey, $css, $uconn, $roomusers, $roundinfo;
    485. $data = [];
    486. switch($d['ac']){
    487. case 'socketreg': //socket注册 初始化
    488. if (check_violation_request()) {
    489. delete_connection_from_temp_css($c); // 从临时连接数组删除
    490. }
    491. // 放入到正式连接数组
    492. $css[] = [
    493. 'c' => $c,
    494. 'timestamp' => time(),
    495. 'userid' => 0,
    496. ];
    497. break;
    498. case 'login': // 登录
    499. $phone = $d['phone'];
    500. $pwd = $d['pwd'];
    501. $sql = "select userid, pwd pwdhash from users where phone='$phone'";
    502. $row = query($sql);
    503. if (!isset($row['0']['pwdhash']) || !password_verify($pwd, $row['0']['pwdhash'])){
    504. return err("login", "用户名或密码有误,请核对后重试");
    505. }
    506. $userid = $row['0']['userid'];
    507. $uid_encrypted = my_encrypt($userid, $publickey);
    508. $data = ['uuid' => $uid_encrypted, 'phone' => $phone]; // 返回加密后的uid
    509. // @todo 要加登录限制 同一个号只能登录在一个设备
    510. // if (isset($uconn[$userid])) {
    511. // wd($uconn[$userid], err("login_limit","您的账号已经在其他设备登录,"));
    512. // $uconn[$userid]->close();
    513. // unset($uconn[$userid]);
    514. // }
    515. $uconn[$userid] = $c; // 创建用户id和连接的kv
    516. // 修改socket数组信息
    517. foreach ($css as $key=>$value) {
    518. if ($c == $value['c']) {
    519. $css[$key]['timestamp'] = time();
    520. $css[$key]['userid'] = $userid;
    521. }
    522. }
    523. logs("---login---");
    524. break;
    525. case 'getuserinfo': // 获取用户信息
    526. // 获取用户基本信息
    527. if (!$d['uuid']) {
    528. return err( "getuserinfo", "缺少关键信息" );
    529. }
    530. $userid = my_decrypt($d['uuid'], $publickey);
    531. logs("------userid=".$userid);
    532. if (!$userid) {
    533. return err( "getuserinfo", "您还没登录哦" );
    534. }
    535. $sql = "SELECT countwin win, countdraw draw, countfail lost, phone,nickname,faceimage,lev,power,invitecode,
    536. levp, isverify, isworking, canbuyparterner, ispartner, sex FROM users WHERE userid ='$userid'";
    537. $row = query($sql);
    538. $user = isset($row[0]) && count($row[0])>0 ? $row[0] : [];
    539. if (0 == count($user)) {
    540. return err( "userneedremove", "用户不存在" );
    541. }
    542. $user['faceimage'] = !empty($user['faceimage']) ? $user['faceimage'] : '/assets/img/defaultface.png';
    543. // 统计该用户邀请的人数
    544. $invitecode = isset($user['invitecode']) ? $user['invitecode'] : '';
    545. $invitecounts = getinvitecounts($invitecode);
    546. // 获取该用户的资产
    547. $projectcoinid = get_pojectcoinid('GMC');
    548. $sql = "SELECT amount FROM asset WHERE userid = '$userid' AND projectcoinid = '$projectcoinid'"; // gmc的数量
    549. logs("-----用户资产sql----".$sql);
    550. $assets = query($sql);
    551. $assets = isset($assets[0]) ? shownum($assets[0]['amount']) : 0; // 数字显示
    552. // 获取用户的未读通知
    553. $sql = "select count(*) counts from notice where isview='0' and userid='$userid'";
    554. $row = query($sql);
    555. $newmsgcounts = $row['0']['counts'] ? $row['0']['counts'] : 0;
    556. $giftreceivestatus = '0'; // 认证礼包标识
    557. // 查看用是否领取了礼包
    558. $sql = "select truename_gift from userverify where userid='$userid'";
    559. $row = query($sql);
    560. if (isset($row[0]['truename_gift']) && !empty($row[0]['truename_gift'])) {
    561. $giftreceivestatus = 1;
    562. }
    563. $configsid = get_machine($userid); // 矿机
    564. $plate = get_machine_plate($userid); // 车牌
    565. // 拼装数组
    566. $invitecodeurl = "/admin/game/users/invitepage/invitecode/$invitecode"; // 邀请链接
    567. $rows = array_merge($user, compact('configsid', 'invitecounts', 'newmsgcounts','assets', 'giftreceivestatus', 'invitecodeurl'));
    568. $rows['plate'] = $plate;
    569. $data = ['rows' => $rows];
    570. logs("---getuserinfo---");
    571. $uconn[$userid] = $c; // 创建用户id和连接的kv
    572. break;
    573. case 'edituserinfo': // 编辑用户信息
    574. $nickname = isset($d['nickname']) ? $d['nickname'] : '';
    575. $userid = my_decrypt($d['uuid'], $publickey);
    576. $faceimage = isset($d['faceimage']) ? $d['faceimage'] : '';
    577. if (!$userid) {
    578. return err("edituserinfo", "您还没登录哦");
    579. }
    580. $sql = "update users set nickname='$nickname', faceimage='$faceimage' where userid='$userid'";
    581. $updateid = query($sql);
    582. if (false === $updateid) {
    583. return err( "edituserinfo", "编辑用户信息失败" );
    584. }
    585. break;
    586. case 'getrooms': // 获取房间配置
    587. if (!isset($d['uuid'])) {
    588. return err("getrooms", "缺少关键信息");
    589. }
    590. $userid = my_decrypt($d['uuid'], $publickey);
    591. if (!$userid) {
    592. return err("getrooms", "您还没登录哦");
    593. }
    594. // @TODO 只给初级以上的合伙人开放竞技(不包含初级)
    595. $user_info = get_playerinfo($userid);
    596. $partner = $user_info['ispartner']; // 合伙人等级
    597. $partner_levs = ['否' => 0, '初级' => 0, '中级' => 1, '高级'=>2, '特级'=>3, '至尊' => 4];
    598. $plev = $partner_levs[$partner];
    599. if (!isset($partner_levs[$partner])) {
    600. $plev = 0;
    601. }
    602. if ($plev <= 0) {
    603. // return err("getrooms", "此功能正在开发中");
    604. }
    605. $sql = "SELECT
    606. R.*, P.coinname
    607. FROM
    608. room R
    609. LEFT JOIN projectcoin P ON R.projectcoinid = P.projectcoinid";
    610. $rows = query($sql);
    611. if (!$rows) {
    612. return err("getrooms", "没有获取到房间哦");
    613. }
    614. foreach ($rows as $key=>$row) {
    615. if (isset($roomusers[$row['roomid']])) {
    616. $rows[$key]['usercounts'] = count($roomusers[$row['roomid']]); // 该房间里的玩家总数
    617. } else {
    618. $rows[$key]['usercounts'] = 0;
    619. }
    620. if (isset($row['iconpicid'])) {
    621. $rows[$key]['pathimage'] = get_iconpic_path($row['iconpicid']);
    622. }
    623. unset($rows[$key]['iconpicid']);
    624. }
    625. $data = ['rows' => $rows];
    626. break;
    627. case 'matchsync': // 匹配用户 ['roomid' => 2, 'player'=>['uuid'=>'2l3k4j9dfa8wei833upw', 'lev'=>2]
    628. $t = $d['playerinfo'];
    629. $userid = my_decrypt($t['player']['uuid'], $publickey);
    630. $roomid = $t['roomid'];
    631. $result = query("select projectcoinid from room where roomid='$roomid'");
    632. $projectcoinid = 0;
    633. if ($result) {
    634. $projectcoinid = $result[0]['projectcoinid'];
    635. }
    636. if (!$projectcoinid) {
    637. return err($d['ac'], "该房间的入门币种不存在");
    638. }
    639. // 检查玩家是不是已经处于某一局
    640. $round = get_player_roundsid($userid);
    641. if ($round['roundsid']) {
    642. // {$round['interval']} 还差多少秒结束
    643. // return err($d['ac'], "您还有未结束的游戏,请稍后重新进入");
    644. $data = get_reconnect_round($userid, $c); // 返回重连游戏的信息
    645. return suc($d['ac'], $data);
    646. }
    647. // 匹配前要检查玩家的资产金额是否大于房间的入门费
    648. if (!isset($t['roomid'])) {
    649. return err($d['ac'], "未查询到到当前房间id");
    650. }
    651. if (!check_player_asset_is_higher_for_roomfee($t['roomid'], $userid, $projectcoinid)) {
    652. return err($d['ac'], "入场费不够哦");
    653. }
    654. logs("----matchsync-----" . $userid);
    655. $roomusers[$t['roomid']][] = ['userid' => $userid, 'lev' => $t['player']['lev'], 'timestamp' => time()];
    656. return suc($d['ac'], [], '已接收到玩家信息,开始匹配……');
    657. break;
    658. case 'leaveroom': // 玩家离开房间
    659. $uid_encrypted = $d['uuid'];
    660. $userid = my_decrypt($uid_encrypted, $publickey);
    661. $flag = kick_out_player($userid);
    662. if (!$flag) {
    663. return err($d['ac'], "缺少关键信息");
    664. }
    665. return suc($d['ac'], [], '玩家已经离开房间');
    666. break;
    667. case 'syncgamestatus': // 同步游戏状态 ['ac' => 'catchcoin', 'angle' => 50, 'uuid' => 'xxxxxxxxxx', 'throw': 0];
    668. $userid = my_decrypt($d['uuid'], $publickey);
    669. $touserid = my_decrypt($d['touuid'], $publickey);
    670. logs("+++++++++++++++++" . $userid);
    671. logs("+++++++++++++++++" . $touserid);
    672. $roundsid = $d['roundsid'];
    673. if (!$userid || !$touserid || !$roundsid) {
    674. return err($d['ac'], "缺失关键信息");
    675. }
    676. $c1 = $uconn[$touserid]; // 对手的连接
    677. // 把自己的钩子角度发给对方玩家
    678. logs('---发送钩子角度---');
    679. $endtimestamp = isset($roundinfo[$roundsid]['endtimestamp']) ? $roundinfo[$roundsid]['endtimestamp'] : 0; // 游戏结束时间
    680. $remainsecond = $endtimestamp - time();
    681. if ($remainsecond < 0) {
    682. $remainsecond = 0;
    683. }
    684. wd($c1, suc($d['ac'], ['uuid' => $d['uuid'], 'angle' => $d['angle'], 'throw' => $d['throw'],
    685. "remainsecond" => $remainsecond, ]));
    686. break;
    687. case 'caughtcoin': // 抓到币 ['ac' => 'caughtcoin', 'itemid' => 50, 'userid' => 'xxxxxxxxxx'];
    688. // 看一下这个道具有没有被人抓住,没有的话再更新rounditem表
    689. $userid = my_decrypt($d['uuid'], $publickey);
    690. $itemid = $d['itemid'];
    691. $touserid = my_decrypt($d['touuid'], $publickey);
    692. $roundsid = $d['roundsid'];
    693. if (!$userid || !$touserid || !$roundsid) {
    694. return err($d['ac'], "缺失关键信息");
    695. }
    696. // 检查道具合法性
    697. $flag = false;
    698. $round = isset($roundinfo[$roundsid]) ? $roundinfo[$roundsid] : [];
    699. if (!count($round)) {
    700. // return err($d['ac'], "当前场次不存在");
    701. return;
    702. }
    703. foreach ($round as $key=>$value) {
    704. if (strpos($key, "item_") === false) {
    705. continue;
    706. }
    707. if (strpos($key, "$itemid") === false) {
    708. continue;
    709. }
    710. $flag = true;
    711. break;
    712. }
    713. if (!$flag) {
    714. return err($d['ac'], "当前游戏场次不存在此道具");
    715. }
    716. $sql = "select userid,projectcoinid,amount from roundsitem where roundsitemid='$itemid' and roundsid='$roundsid'";
    717. $row = query($sql);
    718. if ($row[0]['userid']) {
    719. return err($d['ac'], "该道具已被对手抓走了");
    720. }
    721. // 两次抓到币的时间间隔不能小于2秒
    722. if (time() - $roundinfo[$roundsid]["caughtcointimestamp" . $userid] < 2) {
    723. // $c->close();
    724. }
    725. $roundinfo[$roundsid]["caughtcointimestamp" . $userid] = time();
    726. // try {
    727. // beginTrans(); // 开启事务
    728. // $now_time = time();
    729. // $sql = "update roundsitem set userid='$userid', obtiantime='$now_time' where roundsitemid = '$itemid'";
    730. // $updateid = query($sql);
    731. // if ($updateid === false) {
    732. // rollBackTrans();
    733. // return err($d['ac'], '更新道具信息失败');
    734. // }
    735. $projectcoinid = $row[0]['projectcoinid']; // 项目方币id
    736. $amount = shownum($row[0]['amount']); // 增加的金额
    737. // // 项目方总币数减 给玩家加币
    738. // $sql = "select last from projectcoin where projectcoinid='$projectcoinid'";
    739. // $row = query($sql);
    740. // $last = 0;
    741. // if ($row) {
    742. // $last = $row[0]['last'];
    743. // }
    744. // if ($last - $amount < 0 ) {
    745. //// rollBackTrans();
    746. //// return err($d['ac'], '项目方币的数量不够');
    747. // }
    748. // $sql = "update projectcoin set last=last-'$amount' where projectcoinid='$projectcoinid'";
    749. // $updateid = query($sql);
    750. // if ($updateid === false) {
    751. // rollBackTrans();
    752. // return err($d['ac'], '项目方币的数量更新失败');
    753. // }
    754. // $sql = "update asset set amount=amount+'$amount' where projectcoinid='$projectcoinid' and userid='$userid'";
    755. //
    756. // $updateid = query($sql);
    757. //
    758. // if ($updateid === false){
    759. // rollBackTrans();
    760. // return err($d['ac'], '用户资产更新失败');
    761. // }
    762. // 添加金币增加记录
    763. // $sql = "insert into notice (`roundsid`, `projectcoinid`, `isview`, `number`, `userid`, `tips`, `createtime`)
    764. // values ('$roundsid', '$projectcoinid', '1', '$amount', '$userid', '抓币奖励', '$now_time')";
    765. // $insertid = query($sql);
    766. // if (false === $insertid) {
    767. // rollBackTrans();
    768. // return err($d['ac'], '用户通知记录更新失败');
    769. // }
    770. $coinname = get_coinname($projectcoinid); // 币名称
    771. logs("--------coinname");
    772. var_dump($coinname);
    773. // 统计各种币累加的结果
    774. if (isset($roundinfo[$roundsid]['reward_user_coinlist_' . $userid])) {
    775. if (isset($roundinfo[$roundsid]['reward_user_coinlist_' . $userid][$coinname])) {
    776. $roundinfo[$roundsid]['reward_user_coinlist_' . $userid][$coinname] += $amount;
    777. }
    778. else {
    779. $roundinfo[$roundsid]['reward_user_coinlist_' . $userid][$coinname] = $amount;
    780. }
    781. }
    782. if (isset($roundinfo[$roundsid]['reward_user_' . $userid])) {
    783. $roundinfo[$roundsid]['reward_user_' . $userid] += $amount;
    784. }
    785. // commitTrans();
    786. // } catch (Exception $e) {
    787. // logs("-----事务错误-----" . $e->getMessage());
    788. // }
    789. $c1 = $uconn[$touserid];
    790. wd($c1, suc($d['ac'], ['uuid' => $d['uuid'], "itemid" => $d['itemid'], "amount" => $roundinfo[$roundsid]['reward_user_' . $userid]])); // 给对手发消息
    791. wd($c, suc($d['ac'], ['uuid' => $d['uuid'], "itemid" => $d['itemid'], "amount" => $roundinfo[$roundsid]['reward_user_' . $userid]])); // 给自己发消息
    792. return;
    793. break;
    794. case 'reconnectround': // 重连当前局
    795. if (!$d['uuid']) {
    796. return err($d['ac'], "缺少关键信息");
    797. }
    798. $userid = my_decrypt($d['uuid'], $publickey);
    799. $data = get_reconnect_round($userid, $c); // 获取用户当前的局数据
    800. break;
    801. case 'getuserasset': // 获取用户资产
    802. $userid = my_decrypt($d['uuid'], $publickey); // 用户id
    803. $where = " A.userid = '$userid' and P.coinname != 'GMS'";
    804. if ($d['assettype']) {
    805. $where .= " and A.amount>0 ";
    806. }
    807. $sql = "SELECT
    808. A.amount, P.coinname, P.cnyrate, I.pathimage
    809. FROM
    810. asset A
    811. LEFT JOIN projectcoin P ON A.projectcoinid = P.projectcoinid
    812. LEFT JOIN iconpic I ON I.iconpicid = P.iconpicid
    813. WHERE {$where} ";
    814. $rows = query($sql);
    815. foreach ($rows as $k => $row) {
    816. $rows[$k]['amount'] = shownum($row['amount']); // 数字显示
    817. }
    818. $data = $rows;
    819. break;
    820. case 'getusergms': // 获取用户积分(gms)
    821. $userid = my_decrypt($d['uuid'], $publickey); // 用户id
    822. $coin_id = get_pojectcoinid('GMS');
    823. $sql = "select amount from asset where projectcoinid ='$coin_id' and userid='$userid'";
    824. $row = query($sql);
    825. $all_amounts = 0;
    826. if ($row) {
    827. $all_amounts = $row[0]['amount'];
    828. }
    829. // 按积分类别统计
    830. $sql = "SELECT
    831. sum(number) amounts, tips
    832. FROM
    833. notice
    834. WHERE
    835. projectcoinid = (select projectcoinid from projectcoin where coinname='GMS') and userid={$userid}
    836. GROUP BY tips";
    837. $rows = query($sql);
    838. if (!$rows) {
    839. $data = [];
    840. } else {
    841. foreach ($rows as $key=>$row) {
    842. $rows[$key]['amounts'] = shownum($row['amounts']);
    843. $rows[$key]['tips'] = mb_substr($row['tips'], 0, 6); // 取前6个字符
    844. $rows[$key]['all_amounts'] = shownum($all_amounts); // 总的积分
    845. }
    846. $data = $rows;
    847. }
    848. break;
    849. case 'getroomusers': // 获取房间的用户
    850. $data = array_map(function($roomuser){
    851. return array_values($roomuser);
    852. },$roomusers);
    853. return suc($d['ac'], $data, "success", 1);
    854. break;
    855. case 'getuseritems': // 获取用户道具列表
    856. if (!isset($d['uuid'])) {
    857. return err($d['ac'], "缺少关键信息");
    858. }
    859. $userid = my_decrypt($d['uuid'], $publickey); // 用户id
    860. if (!$userid) {
    861. return err($d['ac'], "用户尚未登录");
    862. }
    863. $rows = get_user_items($userid);
    864. return suc($d['ac'], $rows);
    865. break;
    866. case 'gettouseritems': // 获取对手用户道具列表
    867. $userid = my_decrypt($d['uuid'], $publickey); // 用户的id
    868. $touserid = my_decrypt($d['touuid'], $publickey); // 对手用户的id
    869. if (!$userid || !$touserid) {
    870. return err($d['ac'], "用户尚未登录");
    871. }
    872. $rows = get_user_items($userid);
    873. $rows2 = get_user_items($touserid);
    874. return suc($d['ac'], ['user'=>$rows, 'touser'=>$rows2]);
    875. break;
    876. case 'itemused': // 道具使用
    877. $roundsid = $d['roundsid']; // 使用的局id
    878. $configsid = $d['configsid']; // 道具的id
    879. $userid = my_decrypt($d['uuid'], $publickey); // 用户id
    880. $touserid = my_decrypt($d['touuid'], $publickey); // 用户id
    881. $c1 = $uconn[$touserid]; // 对手连接
    882. if (!$roundsid || !$configsid || !$userid) {
    883. return err($d['ac'], "缺少关键信息");
    884. }
    885. $sql = "select remain from user_items where configsid = '$configsid'
    886. AND userid = '$userid'";
    887. $res = query($sql);
    888. if (!$res) {
    889. return err($d['ac'], "道具不足");
    890. }
    891. if ($res[0]['remain'] < 1) {
    892. return err($d['ac'], "道具不足");
    893. }
    894. $sql = "UPDATE user_items
    895. SET
    896. remain = remain-1,
    897. roundsid = '$roundsid'
    898. WHERE
    899. configsid = '$configsid'
    900. AND userid = '$userid'";
    901. $updateid = query($sql);
    902. if (false === $updateid) {
    903. return err($d['ac'], "道具使用失败");
    904. }
    905. wd($c1, suc($d['ac'], ['configsid' => $configsid])); // 发给对手道具id
    906. break;
    907. case 'submituserverify': // 提交身份认证信息
    908. $userid = my_decrypt($d['uuid'], $publickey);
    909. $truename = $d['truename']; // 真实姓名
    910. $cardnumber = $d['cardnumber']; // 身份证
    911. $pic1 = $d['pic1']; // 正面
    912. $pic2 = $d['pic2']; // 反面
    913. $pic3 = $d['pic3']; // 手持
    914. if (!$userid || !$truename || !$cardnumber || !$pic1 || !$pic2 || !$pic3) {
    915. return err($d['ac'], '提交认证信息缺失,请核对后重试');
    916. }
    917. $pattern = "/(^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}$)/";
    918. if (!preg_match($pattern, $cardnumber, $matches)) {
    919. return err($d['ac'], '您提交的身份证号码有误,请核对后重试');
    920. }
    921. // 检查是否已经提交
    922. $isexist = check_exist_verifyinfo($cardnumber);
    923. if ($isexist) {
    924. return err($d['ac'], '您提交的身份证已被使用');
    925. }
    926. // 判断是否领取过新人礼包
    927. $sql = "select count(*) counts from user_items where userid='$userid' and configsid in (8,9,10,11,12,13)";
    928. $row = query($sql);
    929. if (!$row[0]['counts']) {
    930. return err($d['ac'], "您需要先取过新人大礼包");
    931. }
    932. beginTrans(); // 开启事务
    933. // 插入身份认证信息
    934. $sql = "insert into userverify (`userid`, `truename`, `cardnumber`, `pic1`, `pic2`, `pic3`) values
    935. ({$userid}, '{$truename}', '{$cardnumber}', '{$pic1}', '{$pic2}', '{$pic3}') ";
    936. $flag = query($sql);
    937. if ($flag === false) {
    938. rollBackTrans();
    939. return err($d['ac'], '提交认证信息失败');
    940. }
    941. // 更改认证状态为 处理中
    942. $sql = "update users set isverify='处理中' where userid='$userid'";
    943. query($sql);
    944. if ($flag === false) {
    945. rollBackTrans();
    946. return err($d['ac'], '认证状态更新失败');
    947. }
    948. // 设置性别
    949. $sex = get_sex_by_cardnumber($cardnumber);
    950. $sql = "update users set sex='$sex' where userid='$userid'";
    951. $flag = query($sql);
    952. if ($flag === false) {
    953. rollBackTrans();
    954. return err($d['ac'], '性别更改失败');
    955. }
    956. commitTrans();
    957. break;
    958. case 'getuserverify': // 获取用户认证信息
    959. $userid = my_decrypt($d['uuid'], $publickey);
    960. $sql = "select V.truename, V.cardnumber, V.pic1, V.pic2, V.pic3, U.verifyinfo, U.userid
    961. from userverify V right join users U on U.userid=V.userid where U.userid='$userid'";
    962. $row = query($sql);
    963. $data = [];
    964. if (isset($row[0])) {
    965. $data = $row[0];
    966. $data['truename'] = isset($data['truename']) ? substr_cut($data['truename']) : '';
    967. }
    968. break;
    969. case 'generateplate': // 生成车牌
    970. $userid = my_decrypt($d['uuid'], $publickey);
    971. $cardnumber = get_cardnumber($userid);
    972. if (!$cardnumber) {
    973. return err($d['ac'], "您还未实名认证哦");
    974. }
    975. $city = get_province_city($cardnumber);
    976. $plate = get_plate_by_city($city);
    977. if (!$plate) {
    978. return err($d['ac'], "当前身份证所在地区车牌已分配完");
    979. }
    980. $data = ['plate' => $plate];
    981. break;
    982. case 'workswitch': // 挖矿开关
    983. $userid = my_decrypt($d['uuid'], $publickey);
    984. $isworking = $d['isworking'];
    985. $sql = "update users set isworking='{$isworking}' where userid={$userid}";
    986. $updateid = query($sql);
    987. if ($updateid === false) {
    988. return err($d['ac'], "更新失败");
    989. }
    990. // 插入开关记录
    991. $sql = "insert into userdigrecord (`userid`, `isworking`) values ('$userid', '$isworking')";
    992. $insertid = query($sql);
    993. if ($insertid === false) {
    994. return err($d['ac'], "插入开关记录失败");
    995. }
    996. $data = ['isworking' => $isworking];
    997. break;
    998. case 'machines': // 矿机列表
    999. $sql = "select * from configs where configsid in (8,9,10,11,12,13)";
    1000. $rows = query($sql);
    1001. $data = $rows;
    1002. break;
    1003. case 'refine': // 提炼
    1004. $userid = my_decrypt($d['uuid'], $publickey);
    1005. // 修改金块的状态,更新用户的gmc资产
    1006. $sql = "select amount, id from cointmp where userid='$userid' and isburn=0 limit 0, 1";
    1007. $row = query($sql);
    1008. if (!isset($row[0]) || !count($row[0])) {
    1009. return err($d['ac'], "未查询到您的金块");
    1010. }
    1011. $amount = $row[0]['amount'];
    1012. $id = $row[0]['id'];
    1013. $time = time(); // 提炼时间
    1014. $sql = "update cointmp set isburn=1, burntime='$time' where id='$id'";
    1015. $updateid = query($sql);
    1016. if (false === $updateid) {
    1017. return err($d['ac'], "提炼失败");
    1018. }
    1019. $amount = shownum($amount);
    1020. add_user_coin_notice($userid, 'GMC', $amount, "提炼奖励GMC+{$amount}"); // 更新用户gmc数量
    1021. // 修改缓存
    1022. curl_get("http://manage.gmc.ink/index/index/remotecall?userid=$userid&type=1");
    1023. $projectcoinid = get_pojectcoinid('GMC');
    1024. $sql = "select amount from asset where userid='$userid' and projectcoinid='$projectcoinid'";
    1025. $row = query($sql);
    1026. $amount = !empty($row[0]['amount']) ? $row[0]['amount'] : 0; // GMC 用户此刻的gmc数量
    1027. $data = ['amount' => $amount];
    1028. break;
    1029. case 'warehouse': // 仓库
    1030. $userid = my_decrypt($d['uuid'], $publickey);
    1031. $machine_cost=['8'=>0.0875,'9'=>0.075,'10'=>0.05,'11'=>0.025,'12'=>0.0125,'13'=>0];//油耗
    1032. // 未提炼的金块
    1033. $sql = "select count(*) counts from cointmp where isburn=0 and userid='$userid'";
    1034. $row = query($sql);
    1035. $not_refineds = isset($row[0]['counts']) ? $row[0]['counts'] : 0; // 未提炼的金块
    1036. // 汽油剩余量
    1037. $sql = "select remain from user_items where userid='$userid' and configsid=14";
    1038. $row = query($sql);
    1039. $gasoline_remain = isset($row[0]['remain']) ? shownum($row[0]['remain']) : 0; // 汽油剩余量
    1040. // 仓位
    1041. $sql = "select remain from user_items where userid='$userid' and configsid=15";
    1042. $row = query($sql);
    1043. $positions = isset($row[0]['remain']) ? shownum($row[0]['remain']) : 0; // 总仓位
    1044. $position_remain = $positions - $not_refineds; // 仓位剩余量
    1045. // 查出矿机
    1046. $sql = "select configsid from user_items where userid='$userid' and configsid BETWEEN 8 and 13"; // 查出矿机
    1047. $row = query($sql);
    1048. $configsid = isset($row[0]['configsid']) ? $row[0]['configsid'] : 0; // 矿机型号id
    1049. $machine_cost[$configsid] = isset($machine_cost[$configsid]) ? $machine_cost[$configsid] : 0;
    1050. // 计算紧急状态等级 1 汽油 2 仓位 3 矿机
    1051. if ($gasoline_remain < $machine_cost[$configsid]) {
    1052. $gasoline_danger = 2;
    1053. } elseif ($gasoline_remain < 0.1 && $gasoline_remain >= $machine_cost[$configsid]) {
    1054. $gasoline_danger = 1;
    1055. } else {
    1056. $gasoline_danger = 0;
    1057. }
    1058. if ($position_remain == 0) {
    1059. $position_danger = 2;
    1060. } elseif ($position_remain < 2 && $position_remain > 0) {
    1061. $position_danger = 1;
    1062. } else {
    1063. $position_danger = 0;
    1064. }
    1065. if ($gasoline_danger == 0 && $position_danger == 0) {
    1066. $machine_danger = 0;
    1067. } elseif ($position_danger == 2 || $gasoline_danger == 2) {
    1068. $machine_danger = 2;
    1069. } else {
    1070. $machine_danger = 1;
    1071. }
    1072. // 查矿机描述
    1073. $sql = "select description from configs where configsid='$configsid'";
    1074. $row = query($sql);
    1075. $description = isset($row[0]['description']) ? $row[0]['description'] : ''; // 矿机描述
    1076. // 查出矿机车牌
    1077. $sql = "select plate from user_items where userid='$userid' and configsid=16"; // 查出车牌
    1078. $row = query($sql);
    1079. $plate = isset($row[0]['plate']) ? $row[0]['plate'] : ""; // 车牌
    1080. if (!$description) {
    1081. $fuel_consume = 0;
    1082. $output = 0;
    1083. } else {
    1084. list($fuel_consume, $output) = explode('|', $description);
    1085. }
    1086. $data = [
    1087. 'not_refineds'=>$not_refineds,
    1088. 'gasoline_remain' => shownum($gasoline_remain),
    1089. 'position_remain' => $positions, // 总仓位
    1090. 'plate' => $plate,
    1091. 'configsid' => $configsid,
    1092. 'fuel_consume' => $fuel_consume,
    1093. 'output' => $output,
    1094. 'gasoline_danger' => $gasoline_danger,
    1095. 'position_danger' => $position_danger,
    1096. 'machine_danger' => $machine_danger,
    1097. ];
    1098. break;
    1099. case 'getmapadv': // 地图和广告
    1100. $sql = "select image, ismap from mappic where offline=0";
    1101. $rows = query($sql);
    1102. foreach ($rows as $k=>$v) {
    1103. if ($v['ismap']) {
    1104. $data['map'.($k+1)] = $v['image'];
    1105. } else {
    1106. $data['adv'.($k+1)] = $v['image'];
    1107. }
    1108. }
    1109. // $data = ['adv1' => '/assets/adv/adv1.png', 'adv2' => "/assets/adv/adv2.png"];
    1110. break;
    1111. case 'getgoods': // 商店商品列表
    1112. $userid = my_decrypt($d['uuid'], $publickey);
    1113. $sql = "SELECT
    1114. S.title, S.shopid,S.pic,
    1115. S.configsid,
    1116. S.price,
    1117. S.value,
    1118. S.sort, C.itemname
    1119. FROM
    1120. shop S
    1121. LEFT JOIN configs C ON C.configsid=S.configsid
    1122. WHERE
    1123. offline = '0'";
    1124. $rows = query($sql);
    1125. if (!count($rows)) {
    1126. return err('getgoods', "获取商品列表失败");
    1127. }
    1128. $position = get_positions($userid); // 仓位数
    1129. $configsid = get_machine($userid); // 获取用户的矿机
    1130. $new = [];
    1131. foreach ($rows as $key=>$value) {
    1132. if (($value['configsid'] == 15 && $value['value'] <= $position) || $value['configsid'] <= $configsid) {
    1133. $value['canbuy'] = 0;
    1134. } else {
    1135. $value['canbuy'] = 1;
    1136. }
    1137. $catname = $value['itemname'];
    1138. if (strpos($catname,'矿机') !== false) {
    1139. $catname = "machine";
    1140. }
    1141. if (strpos( $catname, '仓位') !== false) {
    1142. $catname = "position";
    1143. }
    1144. if (strpos( $catname, '汽油') !== false) {
    1145. $catname = "gasoline";
    1146. }
    1147. $new[$catname][] = $value;
    1148. }
    1149. $data = $new;
    1150. break;
    1151. case 'createorderon': // 创建订单号
    1152. $userid = my_decrypt($d['uuid'], $publickey);
    1153. if (!$d['shopid'] || !$userid) {
    1154. return err('createorderon', "缺少关键信息,订单提交失败");
    1155. };
    1156. $shopid = $d['shopid']; // 商品id
    1157. $amount = 1;
    1158. $user = get_playerinfo($userid);
    1159. $lev = $user['lev'];
    1160. $invitecode = $user['invitecode'];
    1161. $sql = "select * from shop where shopid='$shopid'";
    1162. $row = query($sql);
    1163. if (!count($row)) {
    1164. return err('createorderon', "商品id有错");
    1165. }
    1166. $configsid = $row[0]['configsid']; // 商品类别
    1167. // 如果是矿机 [8, 9, 10, 11, 12, 13]
    1168. // 等级 [0, 5, 10, 20, 30, 50] 邀请人数 [0, 5, 20, 30, 50, 500]
    1169. // 才能购买
    1170. $invitecount = getinvitecounts($invitecode);
    1171. $matcheids = [8, 9, 10, 11, 12, 13];
    1172. $check = [
    1173. 8 => [
    1174. 'lev' => 0,
    1175. 'invitecounts' => 0,
    1176. ],
    1177. 9 => [
    1178. 'lev' => 5,
    1179. 'invitecounts' => 5,
    1180. ],
    1181. 10 => [
    1182. 'lev' => 10,
    1183. 'invitecounts' => 20,
    1184. ],
    1185. 11 => [
    1186. 'lev' => 20,
    1187. 'invitecounts' => 30,
    1188. ],
    1189. 12 => [
    1190. 'lev' => 30,
    1191. 'invitecounts' => 50,
    1192. ],
    1193. 13 => [
    1194. 'lev' => 50,
    1195. 'invitecounts' => 500,
    1196. ],
    1197. ];
    1198. if (in_array($configsid, $matcheids)) {
    1199. if ($check[$configsid]['lev'] > $lev || !$check[$configsid]['invitecounts'] > $invitecount) {
    1200. return err('createorderon', "您的等级未达到" . $check[$configsid]['lev'] . "级或者" . "邀请人数未达到" . $check[$configsid]['invitecounts'] . "人");
    1201. }
    1202. }
    1203. $price = $row[0]['price'];
    1204. $today = date("Ymd");
    1205. $rand = strtoupper(substr(uniqid(sha1(time())),0,4));
    1206. $no = $today . $rand; // 订单编号
    1207. $payamount = $amount * $price; // 支付金额
    1208. // 购买合伙人
    1209. $partners = [100=>'初级', 101=>'中级', 102=>'高级', 103=>'特级', 104=>'至尊']; // 合伙人
    1210. $plevs = ['否'=>0, '初级'=>1, '中级'=>2, '高级'=>3, '特级'=>4, '至尊'=>5];
    1211. $user = get_playerinfo($userid);
    1212. $now_partner_lev = $user['ispartner'];
    1213. $now_partner_configsid = array_search($now_partner_lev, $partners);
    1214. if (isset($partners[$configsid]) && '初级' != $partners[$configsid]) {
    1215. if ($plevs[$now_partner_lev] >= $plevs[$partners[$configsid]]) {
    1216. return err(__FUNCTION__, "要升级的合伙人等级必须大于您当前的等级");
    1217. }
    1218. // 查出当前拥有的合伙人价格
    1219. $sql = "select price from shop where configsid='$now_partner_configsid'";
    1220. logs("---当前partner configsid---".$now_partner_configsid);
    1221. $res = query($sql);
    1222. $now_payamount = isset($res[0]['price']) ? $res[0]['price'] : 0;
    1223. $payamount = $payamount - $now_payamount; // 差价
    1224. if ($payamount < 1) {
    1225. $payamount = 1;
    1226. }
    1227. }
    1228. $createtime = time(); // 订单创建时间
    1229. $status = 0; // 订单状态
    1230. $sql = "insert into `order` (`no`, `userid`, `shopid`, `amount`, `price`, `payamount`, `createtime`, `status`) values
    1231. ('$no', '$userid', '$shopid', '$amount', '$price', '$payamount', '$createtime', '$status')";
    1232. $insertid = query($sql);
    1233. if (null == $insertid) {
    1234. return err('createorderon', "创建订单失败");
    1235. }
    1236. $data = compact('no');
    1237. break;
    1238. case 'getnewversion': // 获取新版本
    1239. $sql = "select version_number, version_name, tips, download_url from `version` ORDER BY id desc limit 0, 1";
    1240. $row = query($sql);
    1241. $data = isset($row[0]) ? $row[0] : [];
    1242. break;
    1243. }
    1244. return suc($d['ac'], $data);
    1245. }
    1246. // 错误信息输出
    1247. function err($ac,$msg){
    1248. return ['error'=>1,'msg'=>$msg,'ac'=>$ac,'data'=>[]];
    1249. }
    1250. // 成功信息输出
    1251. function suc($ac, $data, $message = 'success', $timestamp=0){
    1252. $data = ['error'=>0,'msg'=>$message,'ac'=>$ac,'data'=>$data, ];
    1253. if ($timestamp) {
    1254. $data['timestamp'] = time();
    1255. }
    1256. return $data;
    1257. }
    1258. // 获取性别
    1259. function get_sex_by_cardnumber($cardnumber){
    1260. // 15位身份证号码 第15位代表性别,奇数为男,偶数为女;
    1261. // 18位身份证号码 第17位代表性别,奇数为男,偶数为女。
    1262. $c_number = 1;
    1263. if (15 == strlen($cardnumber)) {
    1264. $c_number = substr($cardnumber, -1);
    1265. }
    1266. if (18 == strlen($cardnumber)) {
    1267. $c_number = substr($cardnumber, -2, 1);
    1268. }
    1269. if ($c_number % 2 == 0) {
    1270. $sex = 1;
    1271. } else {
    1272. $sex = 0;
    1273. }
    1274. return $sex;
    1275. }
    1276. // 获取重连局数
    1277. function get_reconnect_round($userid, $c){
    1278. global $roundinfo, $uconn;
    1279. $temp = [];
    1280. $res = get_player_roundsid($userid);
    1281. $roundsid = $res['roundsid']; // 获取玩家局id
    1282. $interval = $res['interval']; // 剩余秒数
    1283. // 正常情况下(也就是玩家不存在正在进行的游戏场次)请求重连接口直接返回空数组
    1284. if (!$roundsid) {
    1285. return [];
    1286. }
    1287. unset($uconn[$userid]);
    1288. $uconn[$userid] = $c; // 更新 userid - 连接 kv结构
    1289. $userid1 = $roundinfo[$roundsid]['userid'];
    1290. $touserid1 = $roundinfo[$roundsid]['touserid'];
    1291. $lev = $roundinfo[$roundsid]['lev'];
    1292. $tolev = $roundinfo[$roundsid]['tolev'];
    1293. $uuid = $roundinfo[$roundsid]['uuid'];
    1294. $touuid = $roundinfo[$roundsid]['touuid'];
    1295. $roomid = $roundinfo[$roundsid]['roomid'];
    1296. $reward_user = $roundinfo[$roundsid]["reward_user_" . $userid1];
    1297. $reward_touser = $roundinfo[$roundsid]["reward_user_" . $touserid1];
    1298. if ($userid == $userid1) { // 玩家
    1299. $temp['uuid'] = $uuid;
    1300. $temp['touuid'] = $touuid;
    1301. $temp['lev'] = $lev;
    1302. $temp['tolev'] = $tolev;
    1303. $temp['reward_user'] = $reward_user;
    1304. $temp['reward_touser'] = $reward_touser;
    1305. $temp['position'] = 'left';
    1306. $info = get_playerinfo($userid1);
    1307. $configsid = get_machine($userid1);
    1308. $plate = get_machine_plate($userid1); // 车牌
    1309. $temp['phone'] = $info['phone'];
    1310. $temp['nickname'] = $info['nickname'];
    1311. $temp['faceimage'] = $info['faceimage'];
    1312. $temp['isrobot'] = $info['isrobot'];
    1313. $temp['sex'] = $info['sex'];
    1314. $temp['configsid'] = $configsid;
    1315. $temp['plate'] = $plate;
    1316. if ($temp['isrobot']) {
    1317. $temp['configsid'] = 8;
    1318. }
    1319. $info = get_playerinfo($touserid1);
    1320. $toconfigsid = get_machine($touserid1);
    1321. $toplate = get_machine_plate($touserid1); // 车牌
    1322. $temp['tophone'] = $info['phone'];
    1323. $temp['tonickname'] = $info['nickname'];
    1324. $temp['tofaceimage'] = $info['faceimage'];
    1325. $temp['toisrobot'] = $info['isrobot'];
    1326. $temp['tosex'] = $info['sex'];
    1327. $temp['toplate'] = $toplate;
    1328. if ($temp['toisrobot']) {
    1329. $temp['configsid'] = 8;
    1330. }
    1331. $temp['toconfigsid'] = $toconfigsid;
    1332. // 查出两人未使用的游戏道具
    1333. $data['user_items'] = get_user_items($userid1);
    1334. $data['touser_items'] = get_user_items($touserid1);
    1335. } elseif ($userid == $touserid1) { // 对手
    1336. $temp['uuid'] = $touuid;
    1337. $temp['touuid'] = $uuid;
    1338. $temp['lev'] = $tolev;
    1339. $temp['tolev'] = $lev;
    1340. $temp['reward_user'] = $reward_touser;
    1341. $temp['reward_touser'] = $reward_user;
    1342. $temp['position'] = 'right';
    1343. $info = get_playerinfo($touserid1);
    1344. $configsid = get_machine($touserid1);
    1345. $plate = get_machine_plate($touserid1); // 车牌
    1346. $temp['phone'] = $info['phone'];
    1347. $temp['nickname'] = $info['nickname'];
    1348. $temp['faceimage'] = $info['faceimage'];
    1349. $temp['isrobot'] = $info['isrobot'];
    1350. $temp['sex'] = $info['sex'];
    1351. $temp['configsid'] = $configsid;
    1352. $temp['plate'] = $plate;
    1353. if ($temp['isrobot']) {
    1354. $temp['configsid'] = 8; // 如果是机器人就默认是木矿机
    1355. }
    1356. $info = get_playerinfo($userid1);
    1357. $toconfigsid = get_machine($userid1);
    1358. $toplate = get_machine_plate($userid1); // 车牌
    1359. $temp['tophone'] = $info['phone'];
    1360. $temp['tonickname'] = $info['nickname'];
    1361. $temp['tofaceimage'] = $info['faceimage'];
    1362. $temp['toisrobot'] = $info['isrobot'];
    1363. $temp['tosex'] = $info['sex'];
    1364. $temp['toconfigsid'] = $toconfigsid;
    1365. $temp['toplate'] = $toplate;
    1366. if ($temp['toisrobot']) {
    1367. $temp['configsid'] = 8; // 如果是机器人就默认是木矿机
    1368. }
    1369. // 查出两人未使用的游戏道具
    1370. $data['user_items'] = get_user_items($touserid1);
    1371. $data['touser_items'] = get_user_items($userid1);
    1372. }
    1373. $temp['roomid'] = $roomid;
    1374. $temp['roundsid'] = $roundsid;
    1375. $temp['interval'] = $interval;
    1376. $sql = "select roundsecond, roundsid, bgimg_iconpicid, bgsound_iconpicid from rounds where roundsid={$roundsid}";
    1377. $row = query($sql);
    1378. $data['bgimg_path'] = get_iconpic_path($row[0]['bgimg_iconpicid']);
    1379. $data['bgsound_path'] = get_iconpic_path($row[0]['bgsound_iconpicid']);
    1380. $data['roundsecond'] = $row[0]['roundsecond'];
    1381. $data['roundsid'] = $row[0]['roundsid'];
    1382. unset($row[0]['bgimg_iconpicid']);
    1383. unset($row[0]['bgsound_iconpicid']);
    1384. // 查出还未被抓的场景道具列表
    1385. $sql = "select roundsitemid roundmodelitemid, amount, x, y, gravity, moveable, angle, projectcoinid, iconpicid from roundsitem where roundsid={$roundsid} and userid=0";
    1386. $rows = query($sql);
    1387. foreach ($rows as $key=>$value) {
    1388. $rows[$key]['coinname'] = get_coinname($value['projectcoinid']);
    1389. $info = get_iconpic_info($value['iconpicid']);
    1390. $rows[$key]['pathimage'] = $info['pathimage'];
    1391. $rows[$key]['h'] = $info['h'];
    1392. $rows[$key]['w'] = $info['w'];
    1393. unset($rows[$key]['iconpicid']);
    1394. unset($rows[$key]['projectcoinid']);
    1395. }
    1396. $data['items'] = $rows;
    1397. $data['orders'] = $roundinfo[$roundsid]['orders']; // 次序 第几场游戏
    1398. return array_merge($data, $temp);
    1399. }
    1400. // 获取矿机牌照
    1401. function get_machine_plate($userid = 0){
    1402. $sql = "select plate from user_items where userid='$userid' and plate != ''";
    1403. $row = query($sql);
    1404. return isset($row[0]['plate']) ? $row[0]['plate'] : '';
    1405. }
    1406. // 隐藏名字中间字
    1407. function substr_cut($user_name){
    1408. $strlen = mb_strlen($user_name, 'utf-8');
    1409. $firstStr = mb_substr($user_name, 0, 1, 'utf-8');
    1410. $lastStr = mb_substr($user_name, -1, 1, 'utf-8');
    1411. return $strlen == 2 ? $firstStr . str_repeat('*', mb_strlen($user_name, 'utf-8') - 1) : $firstStr . str_repeat("*", $strlen - 2) . $lastStr;
    1412. }
    1413. // 事务方法
    1414. function beginTrans(){
    1415. global $db;
    1416. $db->beginTrans();
    1417. }
    1418. function commitTrans(){
    1419. global $db;
    1420. $db->commitTrans();
    1421. }
    1422. function rollBackTrans(){
    1423. global $db;
    1424. $db->rollBackTrans();
    1425. }
    1426. // 给买家增加道具
    1427. function update_game_items($no, $payamount, $shopid, $userid, $configsid, $value, $title, $plus){
    1428. $liquids = [1, 2, 3, 4, 5, 6, 7]; // 液体道具
    1429. $machines = [8,9,10,11,12,13]; // 矿机
    1430. $partners = [100=>'初级', 101=>'中级', 102=>'高级', 103=>'特级', 104=>'至尊']; // 合伙人
    1431. $machineids = implode(",", $machines);
    1432. beginTrans();
    1433. if (in_array($configsid, $liquids)) {
    1434. } else {
    1435. // 增加游戏道具,减少库存
    1436. if ($plus) {
    1437. // 累加
    1438. $sql = "update user_items set remain=remain+'$value' where userid='$userid' and configsid='$configsid'"; // 汽油
    1439. // 修改缓存
    1440. curl_get("http://manage.gmc.ink/index/index/remotecall?userid=$userid&type=2");
    1441. } else {
    1442. // 直接修改
    1443. $sql = "update user_items set remain='$value' where userid='$userid' and configsid='$configsid'"; // 仓位
    1444. // 修改缓存
    1445. curl_get("http://manage.gmc.ink/index/index/remotecall?userid=$userid&type=3");
    1446. // 矿机
    1447. if (in_array($configsid, $machines)) {
    1448. $sql = "select useritemsid from user_items where userid='$userid' and configsid in ({$machineids})";
    1449. $row = query($sql);
    1450. $useritemsid = $row[0]['useritemsid'];
    1451. $sql = "update user_items set configsid='$configsid' where useritemsid='$useritemsid'"; // 矿机
    1452. }
    1453. // 合伙人
    1454. if (in_array($configsid, array_keys($partners))) {
    1455. $up_partner = $partners[$configsid];
    1456. $sql = "update users set canbuyparterner='3', ispartner='$up_partner' where userid='$userid'"; // 合伙人
    1457. }
    1458. }
    1459. $updateid = query($sql);
    1460. if ($updateid === false) {
    1461. rollBackTrans();
    1462. return err(__FUNCTION__, "更新游戏道具出错");
    1463. }
    1464. }
    1465. $sql = "update shop set last=last-1 where shopid='$shopid'";
    1466. $updateid = query($sql);
    1467. if ($updateid === false) {
    1468. rollBackTrans();
    1469. return err(__FUNCTION__, "更新商店库存出错");
    1470. }
    1471. $sql = "update `order` set status=1 where no='$no'";
    1472. $updateid = query($sql);
    1473. if ($updateid === false) {
    1474. rollBackTrans();
    1475. return err(__FUNCTION__, "更新订单失败");
    1476. }
    1477. // 新增通知记录
    1478. $time = time();
    1479. // 商品是油的话,就多加 汽油 俩字
    1480. if (strpos($title, 'L') !== false) {
    1481. $title .= "汽油";
    1482. }
    1483. $sql = "insert into notice (`userid`, `number`, `tips`, `createtime`) values ('$userid', '$payamount', '购买{$title}成功', '$time')";
    1484. $insertid = query($sql);
    1485. if ($insertid === false) {
    1486. rollBackTrans();
    1487. return err(__FUNCTION__, "插入通知失败");
    1488. }
    1489. commitTrans();
    1490. return true;
    1491. }
    1492. // 获取用户的仓位
    1493. function get_positions($userid){
    1494. if (!$userid) {
    1495. err("getgoods", "缺少用户id");
    1496. }
    1497. $sql = "select remain from user_items where userid='$userid' and configsid=15";
    1498. $row = query($sql);
    1499. return isset($row[0]['remain']) ? $row[0]['remain'] : 0;
    1500. }
    1501. // 获取用户的矿机型号
    1502. function get_machine($userid){
    1503. if (!$userid) {
    1504. err("getgoods", "缺少用户id");
    1505. }
    1506. $sql = "select userid from users where userid=$userid and isrobot='1'"; // 机器人直接返回木质矿机
    1507. $row = query($sql);
    1508. if (isset($row[0]['userid']) && $row[0]['userid']) {
    1509. return 8;
    1510. }
    1511. $sql = "select configsid from user_items where userid='$userid' and configsid between 8 and 13";
    1512. $row = query($sql);
    1513. return isset($row[0]['configsid']) ? $row[0]['configsid'] : 0;
    1514. }
    1515. // 获取玩家的游戏道具
    1516. function get_user_items($userid){
    1517. $sql = "SELECT
    1518. C.configsid,
    1519. C.itemname,
    1520. C.description,
    1521. U.remain itemcounts
    1522. FROM
    1523. user_items U
    1524. LEFT JOIN configs C ON C.configsid = U.configsid
    1525. WHERE
    1526. U.configsid in (1, 2, 3, 4, 5, 6, 7) and U.userid = '$userid'";
    1527. $rows = query($sql);
    1528. foreach ($rows as $key=>$row) {
    1529. if (isset($row['itemcounts']) && !empty($row['itemcounts'])) {
    1530. $rows[$key]['itemcounts'] = intval($rows[$key]['itemcounts']);
    1531. }
    1532. }
    1533. return $rows;
    1534. }
    1535. // 统计该用户邀请的人数 必须是实名认证过的用户才可以计入
    1536. function getinvitecounts($invitecode){
    1537. $sql = "select count(*) counts from users where parent_userid=(select userid from users where invitecode='$invitecode')
    1538. and isverify='已认证';";
    1539. $row = query($sql);
    1540. return $row['0']['counts'] ? $row['0']['counts'] : 0;
    1541. }
    1542. // 获取身份证号
    1543. function get_cardnumber($userid){
    1544. global $db;
    1545. $sql = "select cardnumber from userverify where userid='$userid'";
    1546. $row = query($sql);
    1547. $cardnumber = isset($row[0]['cardnumber']) ? $row[0]['cardnumber'] : 0;
    1548. if (!$cardnumber) {
    1549. return false;
    1550. }
    1551. return $cardnumber;
    1552. }
    1553. // 是否提交过验证信息
    1554. function check_exist_verifyinfo($cardnumber){
    1555. $sql = "select count(*) counts from userverify where cardnumber='$cardnumber'";
    1556. $row = query($sql);
    1557. $isexist = isset($row[0]['counts']) && !empty($row[0]['counts']) ? true : false;
    1558. return $isexist;
    1559. }
    1560. // 获取币的名字
    1561. function get_coinname($projectcoinid){
    1562. $sql = "select coinname from projectcoin where projectcoinid='$projectcoinid'";
    1563. $row = query($sql);
    1564. return isset($row[0]['coinname']) ? $row[0]['coinname'] : '';
    1565. }
    1566. // 新增通知消息(和币变化有关的通知消息)
    1567. function add_user_coin_notice($userid, $coinname, $amount, $tips, $roundsid=0, $partner_room_reward_lev=0, $fromuserid=0){
    1568. if (!$userid) {
    1569. return false;
    1570. }
    1571. if (!$amount) {
    1572. return false;
    1573. }
    1574. $d['ac'] = __FUNCTION__;
    1575. try {
    1576. beginTrans(); // 开启事务
    1577. $now_time = time();
    1578. $coinname = strtoupper($coinname); // 币名称
    1579. // 项目方总币数减 给玩家加币
    1580. $sql = "select last, projectcoinid from projectcoin where coinname='$coinname'";
    1581. $row = query($sql);
    1582. if (!$row) {
    1583. return err($d['ac'], '项目方币的数量不够');
    1584. }
    1585. $last = $row[0]['last'];
    1586. $projectcoinid = $row[0]['projectcoinid'];
    1587. if ($last - $amount < 0 ) {
    1588. rollBackTrans();
    1589. return err($d['ac'], '项目方币的数量不够');
    1590. }
    1591. $sql = "update projectcoin set last=last-'$amount' where projectcoinid='$projectcoinid'";
    1592. $updateid = query($sql);
    1593. if ($updateid === false) {
    1594. rollBackTrans();
    1595. return err($d['ac'], '项目方币的数量更新失败');
    1596. }
    1597. $sql = "select amount from asset where projectcoinid='$projectcoinid' and userid='$userid'";
    1598. $res = query($sql);
    1599. if (!$res) {
    1600. rollBackTrans();
    1601. return err($d['ac'], '用户资产不足');
    1602. }
    1603. $oamount = $res[0]['amount'];
    1604. $namount = $oamount + $amount; // 改变后的金额
    1605. $sql = "update asset set amount=amount+'$amount' where projectcoinid='$projectcoinid' and userid='$userid'";
    1606. $updateid = query($sql);
    1607. if ($updateid === false){
    1608. rollBackTrans();
    1609. return err($d['ac'], '用户资产更新失败');
    1610. }
    1611. // 添加金币增加记录
    1612. $sql = "insert into notice (`projectcoinid`, `number`, `userid`, `tips`, `createtime`, `roundsid`, `award1type`, `fromuserid`, `oldval`, `newval`)
    1613. values ('$projectcoinid', '$amount', '$userid', '$tips', '$now_time', '$roundsid', '$partner_room_reward_lev', '$fromuserid', '$oamount', '$namount')";
    1614. $insertid = query($sql);
    1615. if (false === $insertid) {
    1616. rollBackTrans();
    1617. return err($d['ac'], '用户通知记录更新失败');
    1618. }
    1619. commitTrans();
    1620. } catch (Exception $e) {
    1621. logs("-----事务错误-----" . $e->getMessage());
    1622. }
    1623. return true;
    1624. }
    1625. // 新增通知消息(一般性的通知消息)
    1626. function add_normal_notice($userid, $amount, $tips, $partnerlev=0, $fromuserid=0){
    1627. $now_time = time();
    1628. $sql = "insert into notice ( `number`, `userid`, `tips`, `createtime`, `award1type`, `fromuserid`)
    1629. values ('$amount', '$userid', '$tips', '$now_time', '$partnerlev', '$fromuserid')";
    1630. $insertid = query($sql);
    1631. if (false === $insertid) {
    1632. return false;
    1633. }
    1634. return true;
    1635. }
    1636. // 获取玩家所在的局信息
    1637. function get_player_roundsid($userid){
    1638. global $roundinfo;
    1639. foreach ($roundinfo as $key=>$round) {
    1640. if ($round['userid'] == $userid || $round['touserid'] == $userid) {
    1641. return ['roundsid' => $key, 'interval' => $round['endtimestamp'] - time()];
    1642. }
    1643. }
    1644. return false;
    1645. }
    1646. // 加密方法
    1647. function my_encrypt($data, $key) {
    1648. // Remove the base64 encoding from our key
    1649. $encryption_key = base64_decode($key);
    1650. // Generate an initialization vector
    1651. // $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
    1652. $iv = "{SE<X<L@2+mP=Gms";
    1653. // Encrypt the data using AES 256 encryption in CBC mode using our encryption key and initialization vector.
    1654. $encrypted = openssl_encrypt($data, 'aes-256-cbc', $encryption_key, 0, $iv);
    1655. // The $iv is just as important as the key for decrypting, so save it with our encrypted data using a unique separator (::)
    1656. return base64_encode($encrypted . '::' . $iv);
    1657. }
    1658. // 解密方法
    1659. function my_decrypt($data, $key) {
    1660. // Remove the base64 encoding from our key
    1661. $encryption_key = base64_decode($key);
    1662. // To decrypt, split the encrypted data from our IV - our unique separator used was "::"
    1663. list($encrypted_data, $iv) = explode('::', base64_decode($data), 2);
    1664. return openssl_decrypt($encrypted_data, 'aes-256-cbc', $encryption_key, 0, $iv);
    1665. }
    1666. // 检查用户是否登录
    1667. function check_user_login($uid_encrypted){
    1668. global $publickey, $db;
    1669. if (!$uid_encrypted) {
    1670. return false;
    1671. }
    1672. $uid = my_decrypt($uid_encrypted, $publickey);
    1673. if (!$uid) {
    1674. return false;
    1675. }
    1676. $row = query("select count(*) counts from users where userid='$uid'");
    1677. if (!isset($row['0']['counts']) && $row[0]['counts'] > 0) {
    1678. return false;
    1679. }
    1680. return true;
    1681. }
    1682. // 生成邀请码
    1683. function generate_invite_code($length = 5, $test=false){
    1684. $chars = str_shuffle("ABCDEFGHJKMNPQRSTUVWXYZ23456789");
    1685. if ($test) {
    1686. $chars = str_shuffle("ABCDEFGHJKMNPQRSTUVWXYZ");
    1687. }
    1688. $randomString = substr($chars, 0, $length);
    1689. return $randomString;
    1690. }
    1691. // 匹配所有玩家
    1692. function match_allroom_players($roomusers, $timeout = 10) {
    1693. global $uconn; // 用户id和连接的kv数组
    1694. global $roomusers;
    1695. // 循环所有房间,匹配每个房间的用户
    1696. if (!count($roomusers)) {
    1697. return false;
    1698. }
    1699. foreach ($roomusers as $kk=>&$roomuser) {
    1700. // 房间只有一个玩家
    1701. if (count($roomuser) == 1) {
    1702. $userid = $roomuser[0]['userid'];
    1703. $c = $uconn[$userid];
    1704. $timestamp = $roomuser[0]['timestamp'];
    1705. if (time() - $timestamp > $timeout) {
    1706. // 时间超过10秒就删除这个玩家,发送匹配失败的消息
    1707. logs("----玩家等待超时,匹配失败----");
    1708. unset($roomusers[$kk][0]);
    1709. wd($c, err('matchsync', "未找到对手,请稍后再试"));
    1710. }
    1711. }
    1712. while (count($roomuser) > 1 ) {
    1713. $r = match_oneroom_players($roomuser);
    1714. foreach ($roomuser as $key => $user) {
    1715. if ( $user['userid'] == $r['userid']
    1716. || $user['userid'] == $r['touserid'] ) {
    1717. unset( $roomusers[$kk][ $key ] ); // 从数组中删除匹配成功的玩家
    1718. }
    1719. }
    1720. $roomusers[$kk] = array_values( $roomuser ); // 重置索引
    1721. // 给玩家发送匹配者的信息,给匹配者发送玩家的信息
    1722. $userid = $r['userid'];
    1723. $player = get_playerinfo($userid);
    1724. $player['position'] = 'left';
    1725. $touserid = $r['touserid'];
    1726. $toplayer = get_playerinfo($touserid);
    1727. $toplayer['position'] = 'right';
    1728. $c = isset($uconn[$userid]) ? $uconn[$userid] : null;
    1729. $c2 = isset($uconn[$touserid]) ? $uconn[$touserid] : null;
    1730. if (!$c) {
    1731. return err('matchsync', "玩家连接不存在");
    1732. }
    1733. if (!$c2) {
    1734. return err('matchsync', "对手连接不存在");
    1735. }
    1736. if (!$player) {
    1737. wd($c2, err('matchsync', "发起玩家不存在"));
    1738. return false;
    1739. }
    1740. if (!$toplayer) {
    1741. wd($c, err('matchsync', "匹配玩家不存在"));
    1742. return false;
    1743. }
    1744. $roomid = $kk;
    1745. $roomconfigs = prepare_room_game_configs($roomid, $userid, $touserid); // 给当前房间创建游戏配置
    1746. logs("--------游戏房间配置" . json_encode($roomconfigs));
    1747. if (is_string($roomconfigs)) {
    1748. wd($c, err('matchsync', $roomconfigs)); // 房间创建游戏配置失败
    1749. return false;
    1750. }
    1751. // 广告链接
    1752. $player['adurl'] = $roomconfigs['adurl'];
    1753. $toplayer['adurl'] = $roomconfigs['adurl'];
    1754. // 游戏矿车分类id
    1755. $configsid = get_machine($userid);
    1756. $toconfigsid = get_machine($touserid);
    1757. $player['configsid'] = $configsid;
    1758. $toplayer['configsid'] = $toconfigsid;
    1759. // 机器人固定木质矿机
    1760. if ($player['isrobot']) {
    1761. $player['configsid'] = 8;
    1762. }
    1763. if ($toplayer['isrobot']) {
    1764. $toplayer['configsid'] = 8;
    1765. }
    1766. $plate = get_machine_plate($userid); // 车牌
    1767. $toplate = get_machine_plate($touserid); // 车牌
    1768. $player['plate'] = $plate;
    1769. $toplayer['plate'] = $toplate;
    1770. wd($c, suc('matchsync', $toplayer)); // 发送给客户端匹配玩家信息
    1771. wd($c2, suc('matchsync', $player)); // 发送给客户端发起玩家信息
    1772. $lev = $player['lev']; // 级别
    1773. $tolev = $toplayer['lev']; // 对手级别
    1774. $models = get_room_gamemodel($roomid, $userid, $touserid, $roomconfigs, $lev, $tolev);
    1775. if (is_string($models) && in_array($models, ['no_model', 'no_items', 'no_roomid', 'no_userid', 'no_insertid', "not_enough_coins", "upgrade_fail"])) {
    1776. logs("models error msg");
    1777. wd($c, err('thisroomgamemodel', "游戏渲染出错,错误原因:" . $models));
    1778. wd($c2, err('thisroomgamemodel', "游戏渲染出错,错误原因:" . $models));
    1779. return false;
    1780. }
    1781. }
    1782. }
    1783. logs("---匹配后房间还有谁---" . json_encode($roomusers));
    1784. }
    1785. // 创建房间游戏配置
    1786. function prepare_room_game_configs($roomid, $userid, $touserid){
    1787. // 随机取最小的order中的一条
    1788. $sql = "select * from roundmodel where roomid='$roomid' order BY roundorder, RAND() LIMIT 0, 1 ";
    1789. $row = query($sql);
    1790. $row = isset($row[0]) ? $row[0] : [];
    1791. if (!count($row)) {
    1792. return "该房间未设置游戏模型";
    1793. }
    1794. $result = get_one_room($roomid);
    1795. $row['fee'] = $result['fee']; // 房间费用
    1796. $row['backpercent'] = $result['backpercent']; // 比率
    1797. $row['projectcoinid'] = $result['projectcoinid']; // 项目币id
    1798. // 第一局才扣除玩家的入门费
    1799. $updateid1 = takeoff_player_roomfee($roomid, $userid, $row['projectcoinid']);
    1800. $updateid2 = takeoff_player_roomfee($roomid, $touserid, $row['projectcoinid']);
    1801. if ($updateid1 === false || false === $updateid2) {
    1802. return "玩家入场费扣除失败";
    1803. }
    1804. return $row;
    1805. }
    1806. // 获取房间信息
    1807. function get_one_room($roomid){
    1808. $row = query("select * from room where roomid='$roomid'");
    1809. return isset($row[0]) ? $row[0] : [];
    1810. }
    1811. // 匹配某个房间的玩家
    1812. function match_oneroom_players($thisroomusers) {
    1813. $length = count($thisroomusers);
    1814. $result = ['userid' => 0, 'touserid' => 0, 'diff' => PHP_INT_MAX];
    1815. for ($i=0; $i<$length; ++$i) {
    1816. for ($j=$i+1; $j<$length; ++$j) {
    1817. $diff = abs($thisroomusers[$i]['lev'] - $thisroomusers[$j]['lev']);
    1818. if ($diff < $result['diff']) {
    1819. $result['userid'] = $thisroomusers[$i]['userid'];
    1820. $result['touserid'] = $thisroomusers[$j]['userid'];
    1821. $result['diff'] = $diff;
    1822. }
    1823. }
    1824. }
    1825. return $result;
    1826. }
    1827. // 获取该房间的游戏模型
    1828. function get_room_gamemodel($roomid, $userid, $touserid, $row, $lev, $tolev, $upgradeconfigs='', $toupgradeconfigs='', $orders=0 ){
    1829. logs("房间id" . $roomid);
    1830. logs("userid-lev" . $userid. "-" . $lev);
    1831. global $db, $roundinfo, $publickey;
    1832. if (!$roomid) {
    1833. return "no_roomid";
    1834. }
    1835. if (!$userid || !$touserid) {
    1836. return "no_userid";
    1837. }
    1838. $roundmodelid = $row['roundmodelid'];
    1839. $roundsecond = $row['roundsecond'];
    1840. $bgimg_iconpicid = $row['bgimg_iconpicid'];
    1841. $bgsound_iconpicid = $row['bgsound_iconpicid'];
    1842. $fee = $row['fee']; // 房间费用
    1843. $backpercent = $row['backpercent']; // 比率
    1844. $reward = $fee * 2 * $backpercent * 0.01; // 这个房间的游戏奖励
    1845. logs("-------房间的配置信息---------");
    1846. $reward_coin = get_coinname($row['projectcoinid']); // 币种名字
    1847. $sql = "SELECT
    1848. I.*,
    1849. P.coinname,
    1850. C.w,
    1851. C.h,
    1852. C.pathimage
    1853. FROM
    1854. roundmodelitem I
    1855. LEFT JOIN roundmodel M ON I.roundmodelid = M.roundmodelid
    1856. LEFT JOIN projectcoin P ON P.projectcoinid = I.projectcoinid
    1857. LEFT JOIN iconpic C ON C.iconpicid = I.iconpicid
    1858. WHERE I.roundmodelid = '$roundmodelid'";
    1859. $row['items'] = query($sql);
    1860. if (!$row['items']) {
    1861. return "no_items";
    1862. }
    1863. $amounts = []; // 币id和amount kv结构
    1864. $amount_arr = [];
    1865. // 计算随机的币的数量
    1866. foreach ($row['items'] as $k => $item) {
    1867. $arr = [$item['amountmin'], $item['amountmax']];
    1868. sort($arr);
    1869. $amount = mt_rand($arr[0]*10000, $arr[1]*10000) / 10000;
    1870. $roundmodelitemid = $item['roundmodelitemid'];
    1871. $amount_arr[$roundmodelitemid] = $amount;
    1872. $projectcoinid = $item['projectcoinid'];
    1873. // 计算每种币对应的数量
    1874. if (isset($amounts[$projectcoinid])) {
    1875. $amounts[$projectcoinid] += $amount;
    1876. } else {
    1877. $amounts[$projectcoinid] = $amount;
    1878. }
    1879. }
    1880. // 检查项目方的币是否够抓
    1881. logs("---项目方币---");
    1882. var_dump($amounts);
    1883. $projectcoinids_not_enough = [];
    1884. foreach ($amounts as $key=>$amount) {
    1885. $projectcoinid = $key;
    1886. $sql = "select last from projectcoin where projectcoinid='$projectcoinid'";
    1887. $one = query($sql);
    1888. if (!$one) {
    1889. $last = 0;
    1890. } else {
    1891. $last = $one[0]['last'];
    1892. }
    1893. if (floatval($last) < $amount) { // 这种币不够抓,把它从场景道具里面删掉
    1894. $projectcoinids_not_enough[] = $key;
    1895. }
    1896. }
    1897. $_projectcoinids = [];
    1898. // 删除项目方币数不够的场景道具
    1899. foreach ($row['items'] as $k => $item) {
    1900. $projectcoinid = $item['projectcoinid'];
    1901. if (in_array($projectcoinid, $projectcoinids_not_enough)) {
    1902. // unset($row['items'][$k]);
    1903. } else {
    1904. $_projectcoinids[$projectcoinid] = $projectcoinid;
    1905. }
    1906. }
    1907. $info['coin_round'] = ""; // 当前局的币名字
    1908. // 只有一种币
    1909. if (count($_projectcoinids) == 1) {
    1910. $info['coin_round'] = get_coinname(current($_projectcoinids));
    1911. } elseif (count($_projectcoinids) == 0) {
    1912. return "not_enough_coins";
    1913. }
    1914. $createtime = time();
    1915. // 写入 rounds
    1916. beginTrans();
    1917. $sql = "insert into rounds (`userid`, `touserid`, `roundsecond`, `createtime`, `roundmodelid`, `bgimg_iconpicid`, `bgsound_iconpicid`) values
    1918. ('$userid', '$touserid', '$roundsecond', '$createtime', '$roundmodelid', '$bgimg_iconpicid', '$bgsound_iconpicid')";
    1919. $roundsid = query($sql); // 局id
    1920. $endtimestamp = $createtime + $roundsecond; // 游戏结束时间
    1921. $starttimestamp = $createtime + $row['delay']; // 创建时间加延迟时间==游戏开始时间
    1922. // 写入userid 对道具的 kv
    1923. $roundinfo[$roundsid] = [
    1924. "reward_user_" . $userid => 0, // 玩家的奖励
    1925. "reward_user_" . $touserid => 0, // 对象的奖励
    1926. "reward_user_coinlist_" . $userid => [], // 玩家的奖励
    1927. "reward_user_coinlist_" . $touserid => [], // 对象的奖励
    1928. "userid" => $userid,
    1929. "touserid" => $touserid,
    1930. "uuid" => my_encrypt($userid, $publickey),
    1931. "touuid" => my_encrypt($touserid, $publickey),
    1932. "roomid" => $roomid,
    1933. 'endtimestamp' => $endtimestamp, // 游戏结束时间戳
    1934. "starttimestamp" => $starttimestamp,
    1935. "roundmodelid" => $roundmodelid,
    1936. "caughtcointimestamp" . $userid => 0,
    1937. "caughtcointimestamp" . $touserid => 0,
    1938. "orders" => $orders+1, // 第几场
    1939. "reward_room" => $reward,
    1940. "coin_reward_room" => $reward_coin
    1941. ];
    1942. // 批量插入道具
    1943. $items_sql = "insert into roundsitem (`roundsid`, `projectcoinid`, `gravity`, `amount`, `x`, `y`, `angle`, `iconpicid`) values ";
    1944. foreach ($row['items'] as $k => $item) {
    1945. $projectcoinid = $item['projectcoinid'];
    1946. $gravity = $item['gravity'];
    1947. $roundmodelitemid = $item['roundmodelitemid'];
    1948. $amount = $amount_arr[$roundmodelitemid];
    1949. $x = $item['x'];
    1950. $y = $item['y'];
    1951. $angle = $item['angle'];
    1952. $iconpicid = $item['iconpicid'];
    1953. // 写入 roundsitem
    1954. $items_sql .= " ('$roundsid', '$projectcoinid', '$gravity', '$amount', '$x', '$y', '$angle', $iconpicid),";
    1955. $row['items'][$k]['amount'] = $amount;
    1956. unset($row['items'][$k]['amountmin']);
    1957. unset($row['items'][$k]['amountmax']);
    1958. unset($row['items'][$k]['projectcoinid']);
    1959. unset($row['items'][$k]['roundmodelid']);
    1960. unset($row['items'][$k]['showodds']);
    1961. unset($row['items'][$k]['iconpicid']);
    1962. }
    1963. // 拼insert语句
    1964. $sql = substr($items_sql, 0, -1);
    1965. $flag = query($sql);
    1966. // 是否全部写入
    1967. if ($roundsid && $flag) {
    1968. logs("---全部写入---");
    1969. commitTrans();
    1970. } else {
    1971. logs("---插入失败---");
    1972. rollBackTrans();
    1973. return "no_insertid";
    1974. }
    1975. // 查出当前局的道具列表
    1976. $sql = "select roundsitemid, amount from roundsitem where roundsid='$roundsid'";
    1977. $list = query($sql);
    1978. foreach ($list as $k => $value) {
    1979. $k2 = "item_" . $value['roundsitemid']; // 道具的id
    1980. $roundinfo[$roundsid][$k2] = $value['amount'];
    1981. $row['items'][$k]['roundmodelitemid'] = $value['roundsitemid'];
    1982. }
    1983. $info['title'] = $row['title']; // 模型标题
    1984. $info['roundsid'] = $roundsid; // 局 id
    1985. $info['roundsecond'] = $row['roundsecond'];
    1986. $info['bgimg_path'] = get_iconpic_path($row['bgimg_iconpicid']); // 背景图片
    1987. $info['bgsound_path'] = get_iconpic_path($row['bgsound_iconpicid']); // 背景音乐
    1988. $info['items'] = array_values($row['items']); // 道具集合
    1989. $info['reward_room'] = $reward; // 房间的奖金
    1990. $info['coin_reward_room'] = $reward_coin; // 房间的奖金币种
    1991. unset($row['delay']);
    1992. unset($row['adurl']);
    1993. logs("----thisroommodel----".json_encode($info));
    1994. $roundinfo[$roundsid]["gameinfo"] = $info; // 游戏信息
    1995. $user_rounds = get_user_rounds($userid); // 玩家当前真实局总数
    1996. $touser_rounds = get_user_rounds($touserid); // 玩家当前真实局总数
    1997. $roundinfo[$roundsid]['lev'] = $lev + 1;
    1998. $roundinfo[$roundsid]['tolev'] = $tolev + 1;
    1999. $roundinfo[$roundsid]["userrounds"] = $user_rounds; // 玩家当前局总数
    2000. $roundinfo[$roundsid]["touserrounds"] = $touser_rounds; // 玩家当前局总数
    2001. if ($upgradeconfigs) {
    2002. logs("wowowowowwowowowowow");
    2003. $roundinfo[$roundsid]["upgrade"] = $upgradeconfigs;
    2004. }
    2005. if ($toupgradeconfigs) {
    2006. logs("wowowowowwowowowowow");
    2007. $roundinfo[$roundsid]["toupgrade"] = $toupgradeconfigs;
    2008. }
    2009. logs("---------后台的局情况------------");
    2010. $rounds = cal_rounds($lev+1); // 当前级别升级需要的局数
    2011. $torounds = cal_rounds($tolev+1); // 对手当前级别升级需要的局数
    2012. $lev2 = $lev+1;
    2013. logs("-----{$userid}要升到的级别$lev2------" );
    2014. logs("----需要的局数----".$rounds);
    2015. logs("----玩了多少局----".$user_rounds);
    2016. if ($rounds <= $user_rounds) {
    2017. // 升级
    2018. $result = upgrade_lev($userid, $lev);
    2019. logs("----触发升级---");
    2020. if ($result === false) {
    2021. return "upgrade_fail";
    2022. }
    2023. $roundinfo[$roundsid]["upgradeconfigs"] = $result;
    2024. }
    2025. if ($torounds <= $touser_rounds) {
    2026. // 升级
    2027. $result = upgrade_lev($touserid, $tolev);
    2028. logs("----触发升级---");
    2029. if ($result === false) {
    2030. return "upgrade_fail";
    2031. }
    2032. $roundinfo[$roundsid]["toupgradeconfigs"] = $result;
    2033. }
    2034. // logs("------生成游戏模型" . json_encode($roundinfo));
    2035. return array_values($_projectcoinids);
    2036. }
    2037. // 升级 送道具 加积分 算力
    2038. function upgrade_lev($userid, $lev){
    2039. $lev = intval($lev);
    2040. if (!$userid) {
    2041. return false;
    2042. }
    2043. $rounds = cal_rounds($lev+1); // 升级需要的局数
    2044. $next_rounds = cal_rounds($lev+2); // 下次升级需要的局数
    2045. $levp = ($next_rounds-$rounds) / $next_rounds; // 距离下次升级的百分比
    2046. // 更新后的等级
    2047. $lev = $lev + 1;
    2048. $tool_nums = ceil($lev/10);
    2049. $powers = ceil($lev/10);
    2050. $gms = $lev * 10;
    2051. $oil = ceil($lev/10) * 10;
    2052. $sql = "update users set lev=lev+1, power=power+'$powers', levp='$levp' where userid='$userid'";
    2053. $flag = query($sql);
    2054. if ($flag === false) {
    2055. return false;
    2056. }
    2057. // 更新积分 +10 * lev(gms就是积分)
    2058. add_user_coin_notice($userid, "GMS", $gms, "升级奖励GMS{$gms}");
    2059. // 加油
    2060. $sql = "update user_items set remain=remain+'$oil' where userid='$userid' and configsid=14"; // 汽油
    2061. $flag = query($sql);
    2062. if ($flag === false) {
    2063. return false;
    2064. }
    2065. add_normal_notice($userid, $oil, "升级奖励汽油+{$oil}");
    2066. gain_configs($userid, $tool_nums, "升级奖励");
    2067. logs("**************升级!!!!*************");
    2068. return compact('lev', 'tool_nums', 'gms', 'powers', 'oil'); // 送道具
    2069. }
    2070. // 送道具
    2071. function gain_configs($userid, $num, $tips=''){
    2072. // 送随机道具 只有1-7 xx液
    2073. $time = time();
    2074. $tools = [1=>0, 2=>0, 3=>0, 4=>0, 5=>0, 6=>0, 7=>0];
    2075. for ($i=0; $i<$num; ++$i) {
    2076. $random = rand(1, 7);
    2077. $tools[$random] = ++$tools[$random];
    2078. }
    2079. foreach ($tools as $k=>$v) {
    2080. if (!$v) {
    2081. continue;
    2082. }
    2083. $sql = "select count(*) counts from user_items where configsid='$k' and userid='$userid'";
    2084. $row = query($sql);
    2085. if ($row[0]['counts']) {
    2086. $sql = "update user_items set remain=remain+'$v' where configsid='$k' and userid='$userid'";
    2087. query($sql);
    2088. } else {
    2089. $sql = "insert into user_items (`userid`, `configsid`, `obtaintime`, `obtainway`, `remain`)
    2090. values ('$userid', '$k', '$time', '$tips', '$v')";
    2091. query($sql);
    2092. }
    2093. }
    2094. $tips = $tips . "道具+{$num}个";
    2095. add_normal_notice($userid, $num, $tips);
    2096. $tips = $tips . "道具+{$num}个";
    2097. add_normal_notice($userid, $num, $tips);
    2098. return 1;
    2099. }
    2100. // 获取玩家局总数
    2101. function get_user_rounds($userid){
    2102. if (!$userid) {
    2103. return false;
    2104. }
    2105. $sql = "select count(*) counts from rounds where userid={$userid} or touserid={$userid}";
    2106. $row = query($sql);
    2107. return isset($row[0]['counts']) ? $row[0]['counts'] : 0;
    2108. }
    2109. // 获取素材路径
    2110. function get_iconpic_path($iconpicid){
    2111. global $db;
    2112. if (!$iconpicid) {
    2113. return null;
    2114. }
    2115. $sql = "select pathimage from iconpic where iconpicid={$iconpicid}";
    2116. $row = query($sql);
    2117. return isset($row[0]['pathimage']) ? $row[0]['pathimage'] : null;
    2118. }
    2119. // 获取素材路径
    2120. function get_iconpic_info($iconpicid){
    2121. global $db;
    2122. if (!$iconpicid) {
    2123. return null;
    2124. }
    2125. $sql = "select pathimage, w, h from iconpic where iconpicid={$iconpicid}";
    2126. $row = query($sql);
    2127. return isset($row[0]) ? $row[0] : null;
    2128. }
    2129. // 打印日志
    2130. function logs($msg){
    2131. echo date('Y-m-d H:i:s').' '.$msg.PHP_EOL;
    2132. }
    2133. // 从临时连接数组删除当前连接
    2134. function delete_connection_from_temp_css($c){
    2135. global $temp_css;
    2136. foreach ($temp_css as $key => $v) {
    2137. if ($c == $v['c']) {
    2138. logs('----从临时连接数组删除----');
    2139. unset($temp_css[$key]);
    2140. }
    2141. }
    2142. }
    2143. // 检查请求是否违规
    2144. function check_violation_request() {
    2145. return true;
    2146. }
    2147. // 获取ip
    2148. function get_ip(){
    2149. $ipaddress = '';
    2150. if (getenv('HTTP_CLIENT_IP'))
    2151. $ipaddress = getenv('HTTP_CLIENT_IP');
    2152. else if(getenv('HTTP_X_FORWARDED_FOR'))
    2153. $ipaddress = getenv('HTTP_X_FORWARDED_FOR');
    2154. else if(getenv('HTTP_X_FORWARDED'))
    2155. $ipaddress = getenv('HTTP_X_FORWARDED');
    2156. else if(getenv('HTTP_FORWARDED_FOR'))
    2157. $ipaddress = getenv('HTTP_FORWARDED_FOR');
    2158. else if(getenv('HTTP_FORWARDED'))
    2159. $ipaddress = getenv('HTTP_FORWARDED');
    2160. else if(getenv('REMOTE_ADDR'))
    2161. $ipaddress = getenv('REMOTE_ADDR');
    2162. else
    2163. $ipaddress = 'UNKNOWN';
    2164. return $ipaddress;
    2165. }
    2166. // 如果超过两秒就剔除房间的用户
    2167. function check_matchplayers_heart($timeout = 2){
    2168. global $tconn, $roomusers;
    2169. // $roomusers = [
    2170. // '3'=>[
    2171. // ['userid' => 100, 'lev' => 0],
    2172. // ['userid' => 55, 'lev' => 10],
    2173. // ['userid' => 83, 'lev' => 1],
    2174. // ['userid' => 22, 'lev' => 17],
    2175. // ['userid' => 52, 'lev' => 18],
    2176. // ['userid' => 53, 'lev' => 18],
    2177. // ], // 二号房间的玩家
    2178. // '4'=>[
    2179. // ['userid' => 12, 'lev' => 0],
    2180. // ['userid' => 13, 'lev' => 10],
    2181. // ['userid' => 14, 'lev' => 1],
    2182. // ['userid' => 15, 'lev' => 17],
    2183. // ['userid' => 18, 'lev' => 18],
    2184. // ['userid' => 20, 'lev' => 18],
    2185. // ],
    2186. // ];
    2187. if (!count($roomusers)) {
    2188. return;
    2189. }
    2190. foreach ($roomusers as $key => $roomuser) {
    2191. if (count($roomuser) == 0) {
    2192. continue;
    2193. }
    2194. foreach ($roomuser as $kk => $user) {
    2195. $timestamp = isset($tconn[$user['userid']]) ? $tconn[$user['userid']] : PHP_INT_MAX;
    2196. logs("-------加入房间的时间戳----" . date("Y-m-d H:i:s", $timestamp));
    2197. // 如果超过两秒就剔除房间的用户
    2198. if (time() - $timestamp > $timeout) {
    2199. logs('----删除超过'. $timeout .'秒的玩家----');
    2200. unset($roomusers[$key][$kk]);
    2201. }
    2202. $roomusers[$key] = array_values( $roomuser ); // 重置索引
    2203. }
    2204. }
    2205. }
    2206. // 剔除房间的玩家
    2207. function kick_out_player($userid){
    2208. global $roomusers;
    2209. if (!$userid) {
    2210. return false;
    2211. }
    2212. foreach ($roomusers as $key => $roomuser) {
    2213. foreach ($roomuser as $kk => $user) {
    2214. if ($user['userid'] == $userid) {
    2215. logs('----剔除玩家----'. $userid);
    2216. unset($roomusers[$key][$kk]);
    2217. }
    2218. }
    2219. }
    2220. $roomusers = array_values( $roomusers ); // 重置索引
    2221. return true;
    2222. }
    2223. // 获取玩家信息
    2224. function get_playerinfo($playerid){
    2225. global $publickey;
    2226. $sql = "select userid, phone, nickname, sex, faceimage, isrobot, levp, lev, invitecode, ispartner from users where userid='$playerid'";
    2227. $row = query($sql);
    2228. if (!isset($row[0]) || !count($row[0])) {
    2229. return 0;
    2230. }
    2231. $row[0]['uuid'] = my_encrypt($row[0]['userid'], $publickey);
    2232. unset($row[0]['userid']);
    2233. return $row[0];
    2234. }
    2235. // 匹配前要检查玩家的资产金额是否大于房间的入门费
    2236. function check_player_asset_is_higher_for_roomfee($roomid, $playerid, $projectcoinid='0') {
    2237. // 入门费
    2238. $sql = "select fee from room where roomid='$roomid'";
    2239. $row = query($sql);
    2240. $fee = $row[0]['fee'];
    2241. // 用户资产
    2242. $sql = "select amount from asset where userid='$playerid' and projectcoinid='$projectcoinid'";
    2243. $row = query($sql);
    2244. $amount = isset($row[0]['amount']) ? $row[0]['amount'] : 0;
    2245. if ($amount < $fee) {
    2246. return false;
    2247. }
    2248. return true;
    2249. };
    2250. // 扣除玩家的房间的入场费
    2251. function takeoff_player_roomfee($roomid, $playerid, $projectcoinid='0'){
    2252. // 入门费
    2253. $sql = "select fee from room where roomid='$roomid'";
    2254. $row = query($sql);
    2255. $fee = $row[0]['fee'];
    2256. $sql = "update asset set amount=amount-'$fee' where userid='$playerid' and projectcoinid='$projectcoinid' and amount>0";
    2257. $flag = query($sql);
    2258. if ($flag === false) {
    2259. return false;
    2260. }
    2261. return true;
    2262. }
    2263. // 给玩家添加房间奖励币
    2264. function add_user_room_reward($userid, $reward, $coinname) {
    2265. global $db;
    2266. $projectcoinid = get_pojectcoinid($coinname);
    2267. $sql = "update asset set amount=amount+'$reward' where userid='$userid' and projectcoinid='$projectcoinid'";
    2268. $insertid = query($sql);
    2269. if (!$insertid) {
    2270. return false;
    2271. }
    2272. return true;
    2273. }
    2274. // 获取coin id
    2275. function get_pojectcoinid($coinname){
    2276. $sql = "select projectcoinid from projectcoin where coinname='$coinname'";
    2277. $row = query($sql);
    2278. return isset($row[0]['projectcoinid']) ? $row[0]['projectcoinid'] : 0;
    2279. }
    2280. // 把各自的奖励写入这一轮的 award 和 toaward 字段
    2281. function update_player_reward($roundsid, $reward_user=0, $reward_touser=0) {
    2282. $sql = "update rounds set award='$reward_user', toaward='$reward_touser' where roundsid='$roundsid'";
    2283. $updateid = query($sql);
    2284. if ($updateid === false) {
    2285. return false;
    2286. }
    2287. return true;
    2288. }
    2289. // 注册成功后,给每一个用户创建一套项目方的币种
    2290. function init_user_projectcoin($userid){
    2291. // 查出项目方的币
    2292. global $db;
    2293. $sql = "select projectcoinid from projectcoin";
    2294. $rows = query($sql);
    2295. foreach ($rows as $key=>$row) {
    2296. $projectcoinid = $row['projectcoinid'];
    2297. $sql = "select count(*) counts from asset where userid='$userid' and projectcoinid = '$projectcoinid'";
    2298. $row = query($sql);
    2299. if (isset($row[0]['counts']) && $row[0]['counts']) {
    2300. continue;
    2301. }
    2302. $sql = "insert into asset (`userid`, `projectcoinid`, `amount`) values ('$userid', '$projectcoinid', '0')";
    2303. query($sql);
    2304. }
    2305. }
    2306. // 批量生成用户
    2307. function generate_robot_user(){
    2308. $db=new \Workerman\MySQL\Connection(C['dbhost'],C['dbport'],C['dbuname'],C['dbpwd'],C['dbname']);
    2309. $phone = 15600000003;
    2310. $arr = [];
    2311. for ($i=0; $i<100; ++$i) {
    2312. // 执行注册
    2313. $pwd = generate_invite_code(6);
    2314. $arr[] = ['phone' => $phone, 'pwd' => $pwd];
    2315. $pwd = password_hash($pwd, PASSWORD_DEFAULT);
    2316. $invitecode = generate_invite_code(5); // 生成自己的邀请码
    2317. $sql = "insert into users (`phone`, `pwd`, `invitecode`, `parent_userid`) values ('$phone', '$pwd', '$invitecode', '0')";
    2318. $id = query($sql);
    2319. ++ $phone;
    2320. }
    2321. file_put_contents("abc.txt", json_encode($arr));
    2322. }
    2323. // 计算这个等级需要的局数
    2324. function cal_rounds($level){
    2325. $level = intval($level);
    2326. if ($level == 1) {
    2327. return 1;
    2328. }
    2329. return 10 * ( ($level+1) * $level / 2 - 1 ) + 1;
    2330. }
    2331. // 抽成
    2332. function divided_into($money, $userid, $touserid, $coinname='GMC'){
    2333. // 合伙人的等级
    2334. $lev = get_partner_lev($userid);
    2335. $tolev = get_partner_lev($touserid);
    2336. // 合伙人分成
    2337. if ($lev) {
    2338. distribute_benefits($lev, $coinname, $money, $userid);
    2339. }
    2340. if ($tolev) {
    2341. distribute_benefits($tolev, $coinname, $money, $touserid);
    2342. }
    2343. }
    2344. // 找合伙人的分级
    2345. function get_partner_lev($userid){
    2346. $sql = "select ispartner from users where userid='$userid'";
    2347. $row = query($sql);
    2348. $partner_lev = isset($row[0]['ispartner']) ? $row[0]['ispartner'] : '';
    2349. return $partner_lev;
    2350. }
    2351. // 分配三级收益
    2352. function distribute_benefits($lev, $coinname, $money, $userid){
    2353. $rate = [
    2354. '初级' => [0.02, 0.005, 0.0025],
    2355. '中级' => [0.03038, 0.006, 0.003],
    2356. '高级' => [0.0491, 0.0078, 0.0039],
    2357. '特级' => [0.08425, 0.0109, 0.00545],
    2358. '至尊' => [0.15275, 0.0164, 0.000082],
    2359. ];
    2360. switch ($lev) {
    2361. case '初级':
    2362. add_coin_triple($userid, $coinname, $money, $rate[$lev]);
    2363. break;
    2364. case '中级':
    2365. add_coin_triple($userid, $coinname, $money, $rate[$lev]);
    2366. break;
    2367. case '高级':
    2368. add_coin_triple($userid, $coinname, $money, $rate[$lev]);
    2369. break;
    2370. case '特级':
    2371. add_coin_triple($userid, $coinname, $money, $rate[$lev]);
    2372. break;
    2373. case '至尊':
    2374. add_coin_triple($userid, $coinname, $money, $rate[$lev]);
    2375. break;
    2376. }
    2377. }
    2378. // 增加三个层级的用户的币
    2379. function add_coin_triple($userid, $coinname, $money, $rates){
    2380. // 一层
    2381. $sql = "select userid from users where parent_userid='$userid'";
    2382. $row = query($sql);
    2383. $userid1 = isset($row[0]['userid']) ? $row[0]['userid'] : 0;
    2384. add_user_coin_notice($userid1, $coinname, $money*$rates[0], "合伙人房间奖励", 1, $userid);
    2385. // 二层
    2386. $sql = "select userid from users where parent_userid='$userid1'";
    2387. $row = query($sql);
    2388. $userid2 = isset($row[0]['userid']) ? $row[0]['userid'] : 0;
    2389. add_user_coin_notice($userid2, $coinname, $money*$rates[1], "合伙人房间奖励", 2, $userid1);
    2390. // 三层
    2391. $sql = "select userid from users where parent_userid='$userid2'";
    2392. $row = query($sql);
    2393. $userid3 = isset($row[0]['userid']) ? $row[0]['userid'] : 0;
    2394. add_user_coin_notice($userid3, $coinname, $money*$rates[2], "合伙人房间奖励", 3, $userid2);
    2395. return;
    2396. }
    2397. // sql查询
    2398. function query($sql) {
    2399. global $db;
    2400. return $db->query($sql);
    2401. }
    2402. // curl get
    2403. function curl_get($url){
    2404. $agent= 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322)';
    2405. $ch = curl_init();
    2406. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    2407. curl_setopt($ch, CURLOPT_VERBOSE, true);
    2408. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    2409. curl_setopt($ch, CURLOPT_USERAGENT, $agent);
    2410. curl_setopt($ch, CURLOPT_URL,$url);
    2411. curl_exec($ch);
    2412. }
    2413. // 支付回调
    2414. function pay_callback(){
    2415. $s2=new Worker('http://0.0.0.0:8888');
    2416. $s2->count=1;
    2417. $s2->onWorkerStart = function ($worker) {
    2418. global $db;
    2419. $db=new \Workerman\MySQL\Connection(C['dbhost'],C['dbport'],C['dbuname'],C['dbpwd'],C['dbname']);
    2420. };
    2421. $s2->onMessage=function($c,$d){
    2422. global $uconn;
    2423. if (empty($d['get']['ac']) || "callback" != $d['get']['ac']) {
    2424. $c->send('缺少关键信息');
    2425. return;
    2426. }
    2427. if ("120.78.91.214" != get_ip()) {
    2428. // $c->send('非法ip');
    2429. // return;
    2430. }
    2431. if (isset($d['get']['no']) && $d['get']['no']) {
    2432. // 执行购买道具
    2433. // 直接返回支付成功的消息给客户端
    2434. $no = $d['get']['no']; // 订单号
    2435. $sql = "select shopid,userid,status,payamount from `order` where no='$no'";
    2436. $row = query($sql);
    2437. $shopid = isset($row[0]['shopid']) ? $row[0]['shopid'] : 0;
    2438. $userid = isset($row[0]['userid']) ? $row[0]['userid'] : 0;
    2439. $status = isset($row[0]['status']) ? $row[0]['status'] : 0;
    2440. $payamount = isset($row[0]['payamount']) ? $row[0]['payamount'] : 0;
    2441. if (!$shopid || !$userid) {
    2442. $c->send('缺少关键信息');
    2443. return;
    2444. }
    2445. if ($status) {
    2446. $c->send('该订单已处理过');
    2447. return;
    2448. }
    2449. $sql = "select title, pic, configsid, value, amount, plus from shop where shopid='$shopid'";
    2450. $row = query($sql);
    2451. $configsid = isset($row[0]['configsid']) ? $row[0]['configsid'] : 0;
    2452. $value = isset($row[0]['value']) ? $row[0]['value'] : 0;
    2453. $amount = isset($row[0]['amount']) ? $row[0]['amount'] : 0;
    2454. $plus = isset($row[0]['plus']) ? $row[0]['plus'] : 0;
    2455. $title = isset($row[0]['title']) ? $row[0]['title'] : 0;
    2456. $price = isset($row[0]['price']) ? $row[0]['price'] : 0;
    2457. $pic = isset($row[0]['pic']) ? $row[0]['pic'] : 0;
    2458. // 获取分类名称
    2459. $sql = "select itemname from configs where configsid='$configsid'";
    2460. $row = query($sql);
    2461. $catname = $row[0]['itemname'];
    2462. $arr = [$no, $payamount, $shopid, $userid, $configsid, $value, $amount, $plus];
    2463. logs("---arr---". json_encode($arr));
    2464. $status = update_game_items($no, $payamount, $shopid, $userid, $configsid, $value, $title, $plus); // 增加游戏道具
    2465. if (!$status) {
    2466. $c->send('购买失败');
    2467. return;
    2468. }
    2469. if (isset($uconn[$userid]) && $uconn[$userid]) {
    2470. wd($uconn[$userid], suc('payover', compact('catname', 'title', 'pic', 'price', 'amount', 'value', 'status')));
    2471. $c->send('支付成功');
    2472. return;
    2473. } else {
    2474. $c->send('---' .json_encode($row));
    2475. return;
    2476. }
    2477. } else {
    2478. $c->send('缺少关键信息2');
    2479. return;
    2480. }
    2481. };
    2482. $s2->listen();
    2483. }
    2484. Worker::runAll();