public function run() { $sessions = $this->redis()->keys("sess:sid:*"); $online_num = count($sessions); #临时 $cc = shell_exec("netstat -natp |grep :19707 |grep -c ESTABLISHED"); $cc = trim($cc); $online_num = (int) $cc; # $ip = array(); if ($sessions) { foreach ($sessions as $val) { $data = $this->redis()->hash_get($val); $ip[$data['client_ip']] = 1; } } #上报在线人数 $arrData = array(); $arrData['gameid'] = GAME_ID; $arrData['type'] = 'online'; $arrData['appid'] = 3248; $arrData['appkey'] = 'd2f83a02a38e0a7c027b8bc7dccf4628'; $arrData['timeline'] = time(); $arrData['value'][] = array('opid' => OPERATOR_ID, 'server' => SERVER_ID ? SERVER_ID : 0, 'area' => AREA_ID ? AREA_ID : 0, 'value' => $online_num); $url = "http://monitor.uuzuonline.com/onlineReport"; Com_System::open_url($url, 'post', json_encode(array($arrData))); $ip_num = count($ip); $now = time(); $sql = "INSERT INTO `log_online` (`num`, `ip_num`, `add_time`) VALUES ( '{$online_num}', '{$ip_num}', '{$now}')"; $result = Com_Db::factory('log')->query($sql); echo "time:{$now} result:" . var_export($result, true) . "\n"; Com_DataCenter::getInstance()->publish_data(0, 'ser', array('time' => $now, 'online_num' => $online_num)); }
public function add_charge_log($player_id, $level, $vip_level, $vip_special_level, $order_id, $gold, $u_money, $amount, $before = 0) { $item = array('player_id' => $player_id, 'player_level' => $level, 'vip_level' => $vip_level, 'vip_special_level' => $vip_special_level, 'order_id' => $order_id, 'gold' => $gold, 'u_money' => $u_money, 'after_amount' => $amount, 'amount' => $before); #推送数据中心 $center_data = array('pay_type' => 1, 'channel' => 4, 'money_coin' => $gold, 'order_id' => $order_id, 'time' => time()); Com_DataCenter::getInstance()->publish_data($player_id, 'pay', $center_data); Log_Common::getInstance()->add_resource_log($player_id, $level, $vip_level, $vip_special_level, 1032, 1, 2, $gold, $amount); return $this->add_log($item); }
/** * 添加多种资源 资源是指 黄金 钻石 等这些资源 * @param $player_id 用户id * @param $level 用户等级 * @param $vip_level vip等级 * @param $cmd_id cmd2 指令 * @param $data array('type',item_id,item_num,amount) 具体含义 参照 add_resource_log 里的 $item * @param $arr_consume array('price',gold,ticket,count) or array() 同 Data/Player.php update_player_resource 里的 $arr_consume * @return bool */ public function add_multi_resource_log($player_id, $level, $vip_level, $vip_special_level, $cmd_id, $data, $arr_consume = array()) { $arr_async = array(); if (Com_Array::is_arr2($data)) { foreach ($data as $param) { if ($param['item_num'] > 0) { $this->add_resource_log($player_id, $level, $vip_level, $vip_special_level, $cmd_id, $param['type'], $param['item_id'], $param['item_num'], $param['amount'], $param['front_attr'], $param['after_attr']); } $key = Cache_Currency::getInstance()->get_key($param['item_id']); if (isset($param['is_async']) && $param['is_async'] == 0) { #这时候是不推送的 做不推送的操作 具体啥操作 待定 } else { if ($param['type'] == 1) { $arr_async[$key] = $param['amount'] + $param['item_num']; } elseif ($param['type'] == 2) { $arr_async[$key] = $param['amount'] - $param['item_num']; ############################################################################### # 道具消费,上报数据 if (OPERATOR_ID == 82) { $playerData = TenYear::getInstance("Data_player")->get_player_info($player_id, array("session_id")); $arrUpload = TenYear::getInstance("Game_online")->get_session($playerData['session_id']); $platform = $arrUpload['platform']; $serverId = $arrUpload['server_id']; $openid = $arrUpload['openid']; Com_TencentDataUpload::getInstance()->init($platform, $serverId, $player_id, $openid); $arr_consume_upload = array("level" => $level, "itemid" => $data['item_id'], "itemtype" => $data['type'], "itemcnt" => $data['item_num']); if (!($res = Com_TencentDataUpload::getInstance()->consume_data_upload($arr_consume_upload))) { Com_Log::write("uploadDataError", "consume_data_upload failed!"); } } ############################################################################### } } } } else { if ($data['item_num'] > 0) { $this->add_resource_log($player_id, $level, $vip_level, $vip_special_level, $cmd_id, $data['type'], $data['item_id'], $data['item_num'], $data['amount'], $data['front_attr'], $data['after_attr']); } $key = Cache_Currency::getInstance()->get_key($data['item_id']); if (isset($data['is_async']) && $data['is_async'] == 0) { #检查否同步前端 #这时候是不推送的 做不推送的操作 具体啥操作 待定 } else { if ($data['type'] == 1) { $arr_async[$key] = $data['amount'] + $data['item_num']; } elseif ($data['type'] == 2) { $arr_async[$key] = $data['amount'] - $data['item_num']; } } } if ($arr_consume) { $params['act'] = $cmd_id; $params['level'] = $level; $params['price'] = $arr_consume['price']; $params['gold'] = $arr_consume['gold']; $params['black_gold'] = $arr_consume['ticket']; $params['count'] = $arr_consume['count']; $params['time'] = time(); Com_DataCenter::getInstance()->publish_data($player_id, 'prop', $params); } # 先注释了 if ($arr_async) { Protocol_Player::p2c_part_update($player_id, $arr_async); #同步资 } return true; }
} $ad_info = $strAdInfo > 0 ? 1 : 0; Com_DataCenter::getInstance()->publish_data($player_id, 'est', array('ad_info' => $ad_info, 'step' => 'create', 'time' => time())); $log_data = array('player_id' => $player_id, 'channel' => 1, 'client_ip' => $strIp, 'game_client_ip' => $client_ip, 'reg_time' => time(), 'ad_info' => $strAdInfo, 'player_level' => 1); #Log_Login::getInstance()->add_log($log_data); Log_Common::getInstance()->add_log($log_data, 'day'); $arr_cache = array('player_id' => $player_id, 'name' => $arrData["name"], 'user_account' => $strUserAccount, 'ad_info' => $arrData['ad_Info'], 'reg_time' => time(), 'career_type' => $arrData['career_type'], 'first_load' => 0); $objPlayer = TenYear::getInstance('Data_Player'); $objPlayer->set_rookie_loading_cache($player_id, $arr_cache); #广告系统用户推送激活 $activelog = Com_System::send_request(array('user_account' => $arrData['user_account']), 'active'); #广告系统用户推送每天首次登陆 $activelog = Com_System::send_request(array('user_account' => $arrData['user_account']), 'login'); #记录登陆登出信息 TenYear::getInstance('Data_Online')->set_online_list($player_id, array('login_time' => time(), 'logout_time' => time())); Com_DataCenter::getInstance()->publish_data($player_id, 'login', array('ad_info' => $ad_info, 'status' => 'on', 'keep_time' => 0, 'time' => time())); TenYear::getInstance('Game_DailySign')->init_daily_sign_info($player_id); #TenYear::getInstance('Game_PackageCode')->async_send_old_account_login_reward($player_id, $arrData['user_account'], $_SESSION['sid']); $rurl = $webUrl . '/index.php'; if ($bAjax) { echo "result=1&msg=" . urlencode($rurl); } else { echo "<meta http-equiv=refresh content='0; url=" . $rurl . "'>"; } } else { //激活用户失败 if ($bAjax) { echo "result=0&msg=" . $arrLanguage["10218"]['content']; } else { Com_System::url_redirect($strTenYearUrl); }
public function CMD2_526() { $online_num = $this->_param[0]; $ip_num = $this->_param[1]; $now = time(); $log_data = array('num' => $online_num, 'ip_num' => $ip_num, 'add_time' => $now); $this->get_game('Online')->async_online_stat($log_data); //echo "time:{$now} result:".var_export($result,true)."\n"; Com_DataCenter::getInstance()->publish_data(0, 'ser', array('time' => $now, 'online_num' => $online_num)); $data = array('reserved' => 1); Protocol::input(0, 5, 4, 526, $data); }
<?php /** * 数据中心 发送数据 * Created by PhpStorm. * User: imo * Date: 15/1/27 * Time: 下午4:00 */ require dirname(__FILE__) . '/../global.php'; TenYear::getInstance(); ini_set('default_socket_timeout', -1); Com_AdCache::factory()->set_timeout(0); define('THRIFT_ROOT', INCLUDE_PATH . '/Scribe'); require INCLUDE_PATH . "/Scribe/dataCenterLog.php"; //注册LOG接收 $objLog = new Com_DataCenter(); $objLog->receive_data(); echo "register log receive \r\n"; echo "start receive \r\n"; //开始接收 Com_Queued::receive_all();
public function doAction() { $userInfo_json = base64_decode($_POST['data']); $userInfo_array = json_decode($userInfo_json, true); //if($userInfo_array['type'] == 'user_id') $reward_1 = explode('|', $userInfo_array['goods_list']); $data_center = array(); $reward = array(); foreach ($reward_1 as $v) { if (!empty($v)) { $reward_tmp = explode(':', $v); $reward_tmp[1] = abs($reward_tmp[1]); if ($reward_tmp[0] == '1') { $reward[] = array('type' => 'exp', 'item_id' => 1, 'item_num' => $reward_tmp[1]); } if ($reward_tmp[0] == '2') { $reward[] = array('type' => 'gold', 'item_id' => 2, 'item_num' => $reward_tmp[1]); $data_center['gold'] += $reward_tmp[1]; } if ($reward_tmp[0] == '3') { $reward[] = array('type' => 'silver', 'item_id' => 3, 'item_num' => $reward_tmp[1]); } if ($reward_tmp[0] == '4') { $reward[] = array('type' => 'ticket', 'item_id' => 4, 'item_num' => $reward_tmp[1]); $data_center['ticket'] += $reward_tmp[1]; } if ($reward_tmp[0] == '5') { $reward[] = array('type' => 'chips', 'item_id' => 5, 'item_num' => $reward_tmp[1]); } if ($reward_tmp[0] == '6') { $reward[] = array('type' => 'kf_coin', 'item_id' => 6, 'item_num' => $reward_tmp[1]); } if ($reward_tmp[0] == '7') { $reward[] = array('type' => 'honor', 'item_id' => 7, 'item_num' => $reward_tmp[1]); } if ($reward_tmp[0] == '11') { $reward[] = array('type' => 'gh_con', 'item_id' => 11, 'item_num' => $reward_tmp[1]); } if ($reward_tmp[0] == '15') { $reward[] = array('type' => 'crystal', 'item_id' => 13, 'item_num' => $reward_tmp[1]); } if ($reward_tmp[0] == '16') { $reward[] = array('type' => 'fame', 'item_id' => 14, 'item_num' => $reward_tmp[1]); } if ($reward_tmp[0] > 10000) { // $reward_tmp_items = explode('|', $reward_tmp[1]); // $reward[] = array('type'=>'prop','item_id'=>$reward_tmp_items[0],'item_num'=>$reward_tmp_items[1]); $reward[] = array('type' => 'prop', 'item_id' => $reward_tmp[0], 'item_num' => $reward_tmp[1]); } } } $user_list = explode(',', $userInfo_array['user_list']); $prop_tag = array('exp' => '经验', 'gold' => '钻石', 'silver' => '金币', 'ticket' => '彩钻', 'chips' => '灵魂碎片', 'honor' => '荣誉值', 'prop' => '道具'); $result['data'] = array(); if (empty($reward)) { $result['status'] = 0; echo json_encode($result); } foreach ($user_list as $v) { if (!empty($v)) { if ($userInfo_array['type'] == 'player_id') { $player_id['player_id'] = $v; //$r = $this->get_game('Reward')->send_reward($v,$reward); foreach ($reward as $m => $n) { if ($n['type'] == 'prop') { /* $arr_player_prop_detail = $this->get_data('PlayerProp')->get_player_prop_detail($v, $n['item_id']); $status = $this->get_data('PlayerProp')->update_prop_num($v,$arr_player_prop_detail,$n['item_num'],'-'); */ $arrLogs = array(); $status = $this->get_game('Prop')->deduct_prop_by_prop_id($v, $n['item_id'], $n['item_num'], $arrLogs); } else { $hasNums = $this->get_data('Player')->get_player_info($v, $n['type']); if ($hasNums < $n['item_num']) { $item_num = '-' . $hasNums; } else { $item_num = '-' . $n['item_num']; } $status = $this->get_data('Player')->update_player_info($v, array($n['type'] => $item_num)); } if ($status) { $delstatus[$n['type']][$v] = 'success'; //'binggo,扣除成功'; } else { $delstatus[$n['type']][$v] = 'fail'; //很可惜扣除失败,可扣除的数量不够'; } } } else { $acc = array(); $acc[0] = $userInfo_array['type']; $acc[1] = $v; $player_id = $this->get_data('Account')->get_player_id($acc); foreach ($reward as $m => $n) { if ($n['type'] == 'prop') { /* $arr_player_prop_detail = $this->get_data('PlayerProp')->get_player_prop_detail($player_id['player_id'], $n['item_id']); $status = $this->get_data('PlayerProp')->update_prop_num($player_id['player_id'],$arr_player_prop_detail,$n['item_num'],'-'); */ $arrLogs = array(); $status = $this->get_game('Prop')->deduct_prop_by_prop_id($player_id['player_id'], $n['item_id'], $n['item_num'], $arrLogs); } else { $hasNums = $this->get_data('Player')->get_player_info($player_id['player_id'], $n['type']); if ($hasNums < $n['item_num']) { $item_num = '-' . $hasNums; } else { $item_num = '-' . $n['item_num']; } $status = $this->get_data('Player')->update_player_info($player_id['player_id'], array($n['type'] => $item_num)); } if ($status) { $delstatus[$n['type']][$player_id['player_id']] = 'success'; //'binggo,扣除成功'; } else { $delstatus[$n['type']][$player_id['player_id']] = 'fail'; //很可惜扣除失败,可扣除的数量不够'; } } } if ($status && ($data_center['gold'] || $data_center['ticket'])) { #数据中心 $cont = intval($data_center['ticket']) + intval($data_center['gold']); $params['subtype'] = 13; $params['act'] = 'gm del'; $params['total'] = intval($data_center['gold']) + intval($data_center['ticket']); $params['order_id'] = 0; $params['gold'] = $data_center['gold']; $params['black_gold'] = $data_center['ticket']; $params['time'] = time(); Com_DataCenter::getInstance()->publish_data($player_id['player_id'], 'sub', $params); } } } $success_head = '用户ID:<br>'; $fail_head = '用户ID:<br>'; $success = ''; $fail = ''; foreach ($delstatus as $k => $v) { foreach ($v as $m => $n) { if ($n == 'success') { $success .= $m . ';<br>'; } else { $fail .= $m . ';<br>'; } } if ($success) { $success = $success_head . $success . 'binggo,扣除' . $prop_tag[$k] . '成功~<br>'; $result['data']['success'] = $success; } if ($fail) { $fail = $fail_head . $fail . '很可惜扣除失败,扣除' . $prop_tag[$k] . '失败~<br>'; $result['data']['fail'] = $fail; } } $result['status'] = 1; echo json_encode($result); }
public function run() { $rurl = MAIN_DOMAIN_URL; $arrData = $this->_parseData; $strUserAccount = isset($arrData["account"]) ? trim($arrData["account"]) : ""; $iAdultFlag = isset($arrData["adult_flag"]) ? $arrData["adult_flag"] : 0; $iAdultGameTime = isset($arrData["game_time"]) ? $arrData["game_time"] : 0; $strClientIp = isset($arrData["ip"]) ? $arrData["ip"] : ""; $strAdInfo = isset($arrData["ad_info"]) ? trim($arrData["ad_info"]) : ""; $strTocken = isset($arrData['tocken']) ? $arrData['tocken'] : ""; $serverId = isset($arrData['sid']) ? $arrData['sid'] : 0; $active_type = isset($arrData['active_type']) ? $arrData['active_type'] : 1; if ($iAdultFlag == 0 && $iAdultGameTime >= 3 * 3600) { $msg = Cache_Language::getInstance()->get_language_info(10306); Com_System::url_msg_redirect($msg['content'], $rurl); exit; } $account_info = $this->get_data('Account')->get_account_info($strUserAccount); if (!$account_info || empty($account_info['name'])) { $_SESSION = array(); $_SESSION['sid'] = session_id(); $_SESSION["account"] = $strUserAccount; $_SESSION['client_ip'] = $strClientIp; $_SESSION['ad_Info'] = $strAdInfo; $_SESSION['server_id'] = $serverId; $_SESSION['vip'] = 0; $_SESSION['level'] = 0; $ad_info = $strAdInfo > 0 ? 1 : 0; if (isset($account_info['player_id']) && $account_info['player_id']) { $playerid = $account_info['player_id']; Com_DataCenter::getInstance()->publish_data($playerid, 'login', array('ad_info' => $ad_info, 'status' => 'on', 'keep_time' => 0, 'time' => $this->current_time)); } else { $playerid = $this->get_data('Account')->add_account($strUserAccount, '', $serverId, $strAdInfo); $log_data = array('player_id' => $playerid, 'channel' => 2, 'user_account' => $strUserAccount, 'ad_info' => $strAdInfo, 'client_ip' => $strClientIp, 'reg_time' => $this->current_time, 'type' => 0, 'add_time' => $this->current_time); Log_Common::getInstance()->add_log($log_data); Com_DataCenter::getInstance()->publish_data($playerid, 'est', array('ad_info' => $ad_info, 'step' => 'get', 'time' => $this->current_time)); } $_SESSION['player_id'] = $playerid; $_SESSION['name'] = ''; #zhe shi hou hai mei ming zi $_SESSION['career_type'] = ''; #zhe shi hou hai mei ming zi $_SESSION['active_type'] = $active_type; $_SESSION['adult_flag'] = $iAdultFlag; $this->get_game('Online')->write_session(); $arr_cache = array('player_id' => $playerid, 'name' => '', 'user_account' => $strUserAccount, 'ad_info' => $strAdInfo, 'reg_time' => 0, 'career_type' => 0, 'first_load' => 0); $this->get_data('Player')->set_rookie_loading_cache($playerid, $arr_cache); # -------------------------------------------------------------------- # 活动日志记录 # -------------------------------------------------------------------- /** $event_log_info = array( 'log_type' => 'login', 'player_id' => $_SESSION['player_id'], 'login_time' => $this->current_time, 'logout_time' => 0, ); $this->get_game('Event')->async_deal_event_log($event_log_info); **/ if ($iAdultFlag == 0) { $this->get_game('Adlut')->add_timer($playerid); #放沉迷定时器 } Com_System::url_redirect(SERVER_DOMAIN . '/index.php'); } else { if ($iAdultFlag == 0) { $flag = $this->get_data('Online')->get_adlut_ban($account_info['player_id']); if (!$flag) { $this->get_game('Adlut')->add_timer($account_info['player_id']); #放沉迷定时器 } if ($flag) { $msg = Cache_Language::getInstance()->get_language_info(10306); Com_System::url_msg_redirect($msg['content'], $rurl); exit; } } $client_ip = Com_System::get_client_ip(); $this->get_game('DailySign')->async_trigger_login_times($account_info['player_id']); $objPlayerData = $this->get_data('Player'); if ($account_info['player_id'] == $_SESSION['player_id']) { // Com_Log::log("account:{$account_info['player_id']} session:{$_SESSION['player_id']} sid:{$_SESSION['']}",'login_test',1); $up_arr = array('session_id' => $_SESSION['sid'], 'adult_flag' => $iAdultFlag, 'client_ip' => $client_ip); //上一次离线时长计算 $pinfo = $objPlayerData->get_player_info($account_info['player_id'], array('logout_time', 'heart_time', 'offline_reward_time')); $logout_time = max($pinfo['logout_time'], $pinfo['heart_time'], $pinfo['offline_reward_time']); $last_offline_time = $this->current_time - $logout_time; $up_arr['last_offline_time'] = $last_offline_time; $up_arr['offline_reward_time'] = $this->current_time; if ($last_offline_time >= 3600) { //1小时以上给奖励 $up_arr['offline_reward_status'] = 1; } else { $up_arr['offline_reward_status'] = 0; } //已经登录 $objPlayerData->update_player_info($account_info['player_id'], $up_arr); Com_System::url_redirect(SERVER_DOMAIN . '/index.php'); exit; } $arrUser = $objPlayerData->get_player_info($account_info['player_id']); if ($arrUser['is_ban'] == 3) { #封号了 Com_System::url_msg_redirect("亲爱的魔法师,由于您的账号数据存在异常,魔法管理员已暂时将您的账号封停,如有疑问可联系客服咨询。", $rurl); exit; } if (empty($arrData['nologin']) && $arrUser['ban_time'] > $this->current_time) { Com_System::url_redirect(SERVER_DOMAIN . '/index.php' . "?ecode=-15"); } $oldPlayerId = isset($_SESSION['player_id']) ? $_SESSION['player_id'] : 0; if ($oldPlayerId) { //如果有老的playerid 则生成新的session_id // session_regenerate_id(); } $_SESSION = array(); $_SESSION['sid'] = session_id(); $_SESSION["player_id"] = $arrUser["player_id"]; $_SESSION['active_type'] = 0; $_SESSION['name'] = $arrUser["name"]; $_SESSION["account"] = $strUserAccount; $_SESSION['career_type'] = $arrUser['career_type']; $_SESSION['adult_flag'] = $iAdultFlag; $_SESSION['ad_Info'] = $arrUser['ad_Info']; $_SESSION['client_ip'] = $strClientIp; $_SESSION['server_id'] = $serverId; $_SESSION['vip'] = $arrUser['vip']; $_SESSION['level'] = $arrUser['level']; $objOnline = $this->get_game('Online'); $objOnline->write_session(); $up_arr = array('session_id' => $_SESSION['sid'], 'adult_flag' => $iAdultFlag, 'client_ip' => $client_ip); //上一次离线时长计算 $logout_time = max($arrUser['logout_time'], $arrUser['heart_time'], $arrUser['offline_reward_time']); $last_offline_time = $this->current_time - $logout_time; $up_arr['last_offline_time'] = $last_offline_time; $up_arr['offline_reward_time'] = $this->current_time; if ($last_offline_time >= 3600) { //1个小时以上给奖励 $up_arr['offline_reward_status'] = 1; } else { $up_arr['offline_reward_status'] = 0; } $objPlayerData->update_player_info($arrUser["player_id"], $up_arr); //更新下session $log_data = array('player_id' => $arrUser["player_id"], 'channel' => 1, 'client_ip' => $strClientIp, 'game_client_ip' => $client_ip, 'reg_time' => $arrUser['reg_time'], 'ad_info' => $arrUser['ad_Info'], 'player_level' => $arrUser['level'], 'vip_level' => $arrUser['vip'], 'vip_special_level' => $arrUser['privilege_level']); #Log_Login::getInstance()->add_log($log_data); Log_Common::getInstance()->add_log($log_data, 'day'); $arr_cache = array('player_id' => $arrUser["player_id"], 'name' => $arrUser["name"], 'user_account' => $strUserAccount, 'ad_info' => $arrUser['ad_Info'], 'reg_time' => $arrUser['reg_time'], 'career_type' => $arrUser['career_type'], 'first_load' => $arrUser['first_load']); $this->get_data('Player')->set_rookie_loading_cache($arrUser["player_id"], $arr_cache); $ad_info = $strAdInfo > 0 ? 1 : 0; Com_DataCenter::getInstance()->publish_data($arrUser["player_id"], 'login', array('ad_info' => $ad_info, 'status' => 'on', 'keep_time' => 0, 'time' => $this->current_time)); if ($ad_info == 1) { #广告系统用户推送每天首次登陆 if (date('Ymd', $arrUser["reg_time"]) != date('Ymd') && date('Ymd') != date('Ymd', $arrUser["login_time"])) { $activelog = Com_System::send_request(array('user_account' => $arrUser['user_account']), 'login'); } } #记录登陆登出信息 $this->get_data('Online')->set_online_list($arrUser["player_id"], array('login_time' => $this->current_time, 'logout_time' => $arrUser['logout_time'])); // Com_Log::log("arrUser:{$arrUser["player_id"]} session:{$_SESSION['player_id']} sid:{$_SESSION['sid']}",'login_test',1); # -------------------------------------------------------------------- # 活动日志记录 # -------------------------------------------------------------------- /** $event_log_info = array( 'log_type' => 'login', 'player_id' => $_SESSION['player_id'], 'login_time' => $this->current_time, 'logout_time' => 0, ); $this->get_game('Event')->async_deal_event_log($event_log_info); **/ Com_System::url_redirect(SERVER_DOMAIN . '/index.php'); } }