mParam = $param; } public function last_time() { return intval($this->mParam['last_time']); } public function is_poor() { return (time() - intval($this->mParam['last_time']) <= shaker_helper::max_poor_period); } public function can_gain() { return (time() - intval($this->mParam['last_time']) >= shaker_helper::max_gain_period); } public function can_gain_system() { return (time() - intval($this->mParam['last_time']) >= shaker_helper::max_gain_period_system); } public function can_lost() { return (time() - intval($this->mParam['last_time']) >= shaker_helper::max_lost_period); } public function user_id() { return intval($this->mParam['user_id']); } public function count() { return intval($this->mParam['count']); } } class gain_policy { const max_amount = 5; private $strength; private $total_amount; public function __construct($strength,$amount) { $this->strength = $strength; $this->total_amount = $amount; } public function calculate() { $scale = $this->scale(); if($scale == false) { return false; } $cur_value = intval($this->total_amount) >= self::max_amount ? self::max_amount : $this->total_amount; $value = intval($this->scale() * $cur_value * 100 + 0.5); if($value == 0) { return false; } else { return $value / 100; } } private function scale() { if($this->strength == 5) { $start = 0.4; $end = 1.0; } elseif ($this->strength == 4) { $start = 0.3; $end = 0.8; } elseif ($this->strength == 3) { $start = 0.2; $end = 0.6; } elseif ($this->strength == 2) { $start = 0.1; $end = 0.4; } elseif ($this->strength == 1) { $start = 0.0; $end = 0.2; } else { return false; } $start = intval($start * 100 + 0.5); $end = intval($end * 100 + 0.5); $ret = mt_rand($start,$end); return $ret / 100; } } class shaker_helper { const max_gain_period = 12 * 3600; const max_poor_period = 1800; const max_gain_period_system = 1;//3 * 3600; const max_lost_period = 1800; const err_msg = '您此次么有抢到好友红包...邀请更多好友,更多机会哦~'; const shake_expire = 5; const direct_gain = 0; const direct_lost = 1; const max_strength = 5; private $strength = 1; private function gain(&$err) { $friends = $this->gain_friends(); $usable_amount = 0.00; $user_id = $this->find_gain_friend($friends, $usable_amount); if ($user_id != false) { $policy = new gain_policy($this->strength, $usable_amount); $value = $policy->calculate(); if($value == false) { $err = array('code' => errcode::ErrShake, 'msg' => self::err_msg); return false; } Log::record(__METHOD__ . " gain amount={$value}",Log::DEBUG); $bonus = account_helper::gain_bonus($user_id, $_SESSION['member_id'], $value); if($bonus != false) { $this->add_gained_friend(array($user_id)); } else { $err = array('code' => errcode::ErrShake, 'msg' => self::err_msg); } return $bonus; } else { if ($this->gained_system() == false) { $err = array('code' => errcode::ErrShake, 'msg' => self::err_msg); return false; } else { $policy = new gain_policy($this->strength, 10); $value = $policy->calculate(); if($value == false) { $err = array('code' => errcode::ErrShake, 'msg' => self::err_msg); return false; } Log::record(__METHOD__ . " lost amount={$value}",Log::DEBUG); $bonus = account_helper::gain_system($_SESSION['member_id'], $value); if($bonus != false) { $this->save_gained_system(); } else { $err = array('code' => errcode::ErrShake, 'msg' => self::err_msg); } return $bonus; } } } private function lost(&$err) { $pred = new bonus\account($_SESSION['member_id']); $total_amount = $pred->total_bonus(); if(intval($total_amount * 100 + 0.5) <= 0) { $err = array('code' => errcode::ErrShake,'msg' => self::err_msg); return false; } $friends = $this->lost_friends(); $user_id = $this->find_lost_friend($friends); if($user_id == false) { $err = array('code' => errcode::ErrShake, 'msg' => self::err_msg); return false; } $policy = new gain_policy($this->strength, $total_amount); $value = $policy->calculate(); if($value == false) { $err = array('code' => errcode::ErrShake, 'msg' => self::err_msg); return false; } $bonus = account_helper::lost_bonus($_SESSION['member_id'],$user_id, $value); if($bonus != false) { $this->add_lost_friend(array($user_id)); } else { $err = array('code' => errcode::ErrShake, 'msg' => self::err_msg); return false; } return $bonus; } private function find_lost_friend($friends) { while (true) { $count = count($friends); if($count == 0) { return false; } $pos = mt_rand(0,$count -1); return $friends[$pos]; } } private function find_gain_friend($friends, &$usable_amount) { while (true) { $count = count($friends); if($count == 0) return false; $pos = mt_rand(0,$count -1); $mod_bonus = Model('user_bonus'); $usable_amount = $mod_bonus->getThiefableSum($friends[$pos]); if(intval($usable_amount * 100 + 0.5) > 0) { return $friends[$pos]; } else { $this->add_poor_friend($friends[$pos]); array_splice($friends,$pos,1); } } } private function calc_strength($strength) { while (true) { $strength = intval($strength + 0.5); if($strength >= 10) { $strength = intval($strength + 0.5) / 10; } else { break; } } return $strength; } public function shake($strength,&$err) { if($this->can_shake() == false) { $period = self::shake_expire; $err = array('code' => errcode::ErrShake,'msg' => "摇得太频繁啦,{$period}秒钟只能摇一次~"); return false; } $this->strength = $this->calc_strength($strength); $direct = $this->direction(); if($direct == self::direct_gain) { $bonuses = $this->gain($err); } else { $bonuses = $this->lost($err); } if($bonuses != false) { $this->save_shake(); } return $bonuses; } private function save_gained_system() { if(isset($_SESSION['game_shake']['gained_system'])) { $_SESSION['game_shake']['gained_system'] = array(); } $system = &$_SESSION['game_shake']['gained_system']; if(empty($system)) { $system['user_id'] = $_SESSION['member_id']; $system['last_time'] = time(); $system['count'] = 1; } else { $system['user_id'] = $_SESSION['member_id']; $system['last_time'] = time(); $system['count'] = intval($system['count']) + 1; } } private function gained_system() { if(!isset($_SESSION['game_shake']['gained_system'])) { return true; } else { $param = $_SESSION['game_shake']['gained_system']; $friend = new friend($param); return $friend->can_gain_system(); } } private function add_gained_friend($user_ids) { if(!isset($_SESSION['game_shake']['gained_friends'])) { $_SESSION['game_shake']['gained_friends'] = array(); } $friends = &$_SESSION['game_shake']['gained_friends']; foreach ($user_ids as $user_id) { if(isset($friends[$user_id])) { $friends[$user_id]['user_id'] = $user_id; $friends[$user_id]['last_time'] = time(); $friends[$user_id]['count'] = intval($friends[$user_id]['count']) + 1; } else { $friends[$user_id]['user_id'] = $user_id; $friends[$user_id]['last_time'] = time(); $friends[$user_id]['count'] = 1; } } } private function add_poor_friend($user_id) { if(!isset($_SESSION['game_shake']['poor_friends'])) { $_SESSION['game_shake']['poor_friends'] = array(); } $friends = &$_SESSION['game_shake']['poor_friends']; if(isset($friends[$user_id])) { $friends[$user_id]['user_id'] = $user_id; $friends[$user_id]['last_time'] = time(); $friends[$user_id]['count'] = intval($friends[$user_id]['count']) + 1; } else { $friends[$user_id]['user_id'] = $user_id; $friends[$user_id]['last_time'] = time(); $friends[$user_id]['count'] = 1; } } private function del_poor_friend($user_id) { if(!isset($_SESSION['game_shake']['poor_friends'])) { $_SESSION['game_shake']['poor_friends'] = array(); } $friends = &$_SESSION['game_shake']['poor_friends']; if(isset($friends[$user_id])) { unset($friends[$user_id]); } } private function add_lost_friend($user_ids) { if(!isset($_SESSION['game_shake']['losted_friends'])) { $_SESSION['game_shake']['losted_friends'] = array(); } $friends = &$_SESSION['game_shake']['losted_friends']; foreach ($user_ids as $user_id) { if(isset($friends[$user_id])) { $friends[$user_id]['user_id'] = $user_id; $friends[$user_id]['last_time'] = time(); $friends[$user_id]['count'] = intval($friends[$user_id]['count']) + 1; } else { $friends[$user_id]['user_id'] = $user_id; $friends[$user_id]['last_time'] = time(); $friends[$user_id]['count'] = 1; } } } //可以偷的好友 private function gain_friends() { if(!isset($_SESSION['game_shake']['gained_friends'])) { $_SESSION['game_shake']['gained_friends'] = array(); } $friends = $_SESSION['game_shake']['gained_friends']; $exids = []; foreach ($friends as $uid => $param) { $friend = new friend($param); if($friend->can_gain() == false) { $exids[] = $friend->user_id(); } } if(!isset($_SESSION['game_shake']['poor_friends'])) { $_SESSION['game_shake']['poor_friends'] = array(); } $poor_friends = $_SESSION['game_shake']['poor_friends']; foreach ($poor_friends as $uid => $param) { $friend = new friend($param); if($friend->is_poor()) { $exids[] = $friend->user_id(); } else { $this->del_poor_friend($friend->user_id()); } } $all_friends = relation_helper::friends(session_helper::memberid()); sort($all_friends,SORT_NUMERIC); $all_friends = array_merge(array_unique($all_friends,SORT_NUMERIC),[]); sort($all_friends); foreach ($exids as $uid) { $pos = algorithm::bsearch($uid,$all_friends); if($pos != -1) { array_splice($all_friends,$pos,1); } } return $all_friends; } private function lost_friends() { if(!isset($_SESSION['game_shake']['losted_friends'])) { $_SESSION['game_shake']['losted_friends'] = array(); } $friends = $_SESSION['game_shake']['losted_friends']; $exids = array(); foreach ($friends as $param) { $friend = new friend($param); if($friend->can_lost() == false) { array_push($exids,$friend->user_id()); } } $subscriber = relation_helper::subscriber($_SESSION['member_id']); $follower = relation_helper::follower($_SESSION['member_id']); $all_friends = array_merge($subscriber,$follower); sort($all_friends,SORT_NUMERIC); $all_friends = array_merge(array_unique($all_friends,SORT_NUMERIC),[]); sort($all_friends,SORT_NUMERIC); foreach ($exids as $uid) { $pos = algorithm::bsearch($uid,$all_friends); if($pos != -1) { array_splice($all_friends,$pos,1); } } return $all_friends; } private function can_shake() { if(!isset($_SESSION['game_shake'])) { $_SESSION['game_shake'] = array(); } if(isset($_SESSION['game_shake']['last_time'])) { $last_time = intval($_SESSION['game_shake']['last_time']); if($last_time + self::shake_expire >= time()) { return false; } else { return true; } } else { return true; } } private function save_shake() { if(!isset($_SESSION['game_shake'])) { $_SESSION['game_shake'] = array(); } $_SESSION['game_shake']['last_time'] = time(); } private function direction() { if(!isset($_SESSION['game_shake'])) { $_SESSION['game_shake'] = array(); } if(!isset($_SESSION['game_shake']['direction'])) { $_SESSION['game_shake']['direction'] = self::direct_gain; } else { $rand = mt_rand(1,100); $direct = ($rand % 5) == 0 ? self::direct_lost : self::direct_gain; $_SESSION['game_shake']['direction'] = $direct; } return $_SESSION['game_shake']['direction']; } }