From f499949d3e3709e43206f6725529eb7a38d44e09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=8D=8E=E6=B8=85?= <18691022700@163.com> Date: Fri, 19 Sep 2025 15:40:22 +0800 Subject: [PATCH] =?UTF-8?q?=E6=88=BF=E9=97=B4=E7=B1=BB=E5=9E=8B=E5=90=88?= =?UTF-8?q?=E5=B9=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/api/controller/Index.php | 2 +- application/api/model/Room.php | 239 ++++----------------------- 2 files changed, 30 insertions(+), 211 deletions(-) diff --git a/application/api/controller/Index.php b/application/api/controller/Index.php index 0d91d19..3a10948 100644 --- a/application/api/controller/Index.php +++ b/application/api/controller/Index.php @@ -29,7 +29,7 @@ class Index extends BaseCom //房间类型列表 public function room_type_list() { - $list = db::name('vs_room_type')->where('status', 1)->field('id,type_name as label_name')->order('sort asc')->select(); + $list = db::name('vs_room_type')->where(['status' => 1, 'deletetime' => 0])->field('id,type_name as label_name')->order('sort asc')->select(); //给前面添加一组数据 array_unshift($list, ['id' => -1, 'label_name' => '热门']); return V(1, '获取成功', $list); diff --git a/application/api/model/Room.php b/application/api/model/Room.php index ce2e155..862426c 100644 --- a/application/api/model/Room.php +++ b/application/api/model/Room.php @@ -198,23 +198,13 @@ class Room extends Model $list = db::name('vs_room')->field('id as room_id,room_number,user_id,room_name,room_cover,room_password,today_hot_value as hot_value,label_id,is_show_room') ->where($map)->order('hot_value desc, id asc')->page($page, $page_limit)->select(); -// var_dump($list); - foreach ($list as $k => &$v){ -// if($v['is_show_room'] == 2){ //是否显示房间 1是2否 -// //查询当前房间是否有主持在麦上 -// $room_host_info = db::name('vs_room_pit')->where(['room_id' => $v['room_id'], 'pit_number' => 9])->value('user_id'); -// if($room_host_info == 0){ -// unset($list[$k]); -// continue; -// } -// } -// $v['hot_value'] = $v['hot_value'] * 10; + + foreach ($list as &$v){ $v['user_list'] = model('RoomUser')->get_room_user_list($v['room_id']); $v['label_name'] = db::name('vs_room_label')->where('id', $v['label_id'])->value('label_name'); $v['label_icon'] = db::name('vs_room_label')->where('id', $v['label_id'])->value('label_icon'); } - //$list 不为空 数组重组 -// $list = array_values((array)$list); + //版本号 $app_version = request()->header('App-Version'); $system = request()->header('system'); @@ -230,32 +220,6 @@ class Room extends Model return ['code' => 1, 'msg' => '获取成功', 'data' => $list, 'api_version' => $api_version]; } - //关注的用户现在所在房间(废弃) - public function user_follow_in_room_list($uid ,$page, $page_limit) - { - //关注的用户列表 - $follow_list = db::name('user_follow')->where('user_id', $uid)->field('follow_user_id')->select(); - if(!empty($follow_list)){ - $user_room_list = []; - foreach ($follow_list as $k => $v){ - //用户是否在房间中 - $user_room_info = db::name('vs_room_visitor')->where('user_id', $v['follow_user_id'])->field('room_id')->find(); - if(!empty($user_room_info)){ - $user_room_list[] = $user_room_info['room_id']; - } - } - } - if(!empty($user_room_list)){ - $list = db::name('vs_room')->field('id as room_id,room_number,user_id,room_name,room_cover,room_password,today_hot_value as hot_value') - ->where('id', 'in', $user_room_list)->order('hot_value desc')->page($page, $page_limit)->select(); - foreach ($list as $k => &$v){ -// $v['hot_value'] = $v['hot_value'] * 10; - $v['user_list'] = model('RoomUser')->get_room_user_list($v['id']); - } - return ['code' => 1, 'msg' => '获取成功', 'data' => $list]; - } - return ['code' => 1, 'msg' => '获取成功', 'data' => []]; - } //首页弹出的房间 public function index_recommend_room() @@ -374,7 +338,6 @@ class Room extends Model } $cp_room[$i]['room_id'] = $v['room_id']; -// $cp_room[$i]['room_name'] = '我 ❤️ '.$room_name.db::name('vs_room')->where('id', $v['room_id'])->value('room_name'); $cp_room[$i]['room_name'] = '我 ❤️ '.$room_name; $cp_room[$i]['room_number'] = db::name('vs_room')->where('id', $v['room_id'])->value('room_number'); $cp_room[$i]['end_time'] = $v['time_day']; @@ -494,17 +457,8 @@ class Room extends Model if(!$room){ return ['code' => 0, 'msg' => '房间不存在', 'data' => null]; } - //获取房间名称 -// $room_name = $room['room_name']; - //查询房主是否加入公会 -// $guild_id = model('Guild')->user_is_join($room['user_id']); -// //获取房主收益比例 -// if($guild_id > 0){ -// $room_user_ratio = get_system_config_value('room_author_guild_ratio')/100; -// }else{ - $room_user_ratio = get_system_config_value('room_author_ratio')/100; -// } + $room_user_ratio = get_system_config_value('room_author_ratio')/100; //根据日期查询房间流水 $field = "b.nickname as sender_nickname,b.avatar as sender_avatar,c.nickname as receive_nickname,c.avatar as receive_avatar,dd.gift_name,a.number,a.total_price,{$group_field} as time"; @@ -520,17 +474,9 @@ class Room extends Model $where['a.createtime'] = ['between', [$begin_time, $end_time]]; } -// $count = db::name('vs_give_gift')->alias('a')->field($field) -// ->join('user b', 'a.user_id = b.id') -// ->join('user c', 'a.gift_user = c.id') -// ->join('vs_give_gift d', 'a.gift_id = d.id') -// ->where($where) -// ->count(); - $list = db::name('vs_give_gift')->alias('a')->field($field) ->join('user b', 'a.user_id = b.id') ->join('user c', 'a.gift_user = c.id') -// ->join('vs_give_gift d', 'a.gift_id = d.id') ->join('vs_gift dd', 'a.gift_id = dd.gid') ->where($where) ->page($page,$page_limit) @@ -617,19 +563,18 @@ class Room extends Model } //用户是否在其他房间 - $room_user = db::name('vs_room_visitor')->where(['user_id' => $user_id])->value('room_id'); + $room_user = db::name('vs_room_visitor')->where(['user_id' => $user_id])->order('id desc')->value('room_id'); if (isset($room_user) && $room_user != $room_id) { -// return ['code' => 0, 'msg' => '您已在其他房间', 'data' => '']; - //根据房间状态判断是否要退出房间并且下麦 + //根据所在房间状态判断是否要退出房间并且下麦 $roomInfo = db::name('vs_room')->where(['id' => $room_user,'apply_status' => 2])->find(); - if(($roomInfo['type_id'] == 1 || $roomInfo['type_id'] == 3 || $roomInfo['type_id'] == 4)&& $roomInfo['label_id'] == 1){ + if(($roomInfo['type_id'] == 1 || $roomInfo['type_id'] == 3 || $roomInfo['type_id'] == 4 || $roomInfo['type_id'] == 8)&& $roomInfo['label_id'] == 1){ //退出其他房间 $this->quit_room($user_id, $room_user,$user_id); - }elseif(($roomInfo['type_id'] == 1 || $roomInfo['type_id'] == 3 || $roomInfo['type_id'] == 4)&& $roomInfo['label_id'] == 2){//k歌 + }elseif(($roomInfo['type_id'] == 1 || $roomInfo['type_id'] == 3 || $roomInfo['type_id'] == 4 || $roomInfo['type_id'] == 8)&& $roomInfo['label_id'] == 2){//k歌 //他的点歌列表 $song_list = db::name('vs_room_song')->where(['room_id' => $room_user, 'user_id' => $user_id])->select(); if(count($song_list) > 0){ - foreach ($song_list as $key => $value){ + foreach ($song_list as $value){ if($value['status'] == 2 && $value['times_status'] == 1){ //切歌 model('api/RoomSong')->change_song($room_id,$value['did']); @@ -641,7 +586,7 @@ class Room extends Model } //记录用户退出房 $this->quit_room($user_id, $room_user,$user_id); - }elseif($roomInfo['type_id'] == 3){ + }elseif($roomInfo['type_id'] == 2){ //是否在拍卖位 $pitNumber = Cache::get('auction_user_'.$room_user); if(isset($pitNumber) && $pitNumber == $user_id){ @@ -669,7 +614,7 @@ class Room extends Model $user_pit = 0; $pit_list = []; $cp_users = null; - if($room['type_id'] == 1 || $room['type_id'] == 3 || $room['type_id'] == 4 || $room['type_id'] == 7) {//1点唱,3男神,4女神 + if($room['type_id'] == 1 || $room['type_id'] == 3 || $room['type_id'] == 4 || $room['type_id'] == 7 || $room['type_id'] == 8) {//1点唱,3男神,4女神 if($room['label_id'] == 2){//K歌 $song = $this->get_song_info($room_id,$user_id); $song_list = $song['song_user_info']; @@ -1117,9 +1062,9 @@ class Room extends Model $room_label = $res['data']['label_id']; $room_type = $res['data']['type_id']; $apply_type = 0; - if($room_label == 1 && ($room_type == 1 || $room_type == 3 || $room_type == 4)){ + if($room_label == 1 && ($room_type == 1 || $room_type == 3 || $room_type == 4 || $room_type == 8)){ $apply_type = 1; - }elseif ($room_label == 2 && ($room_type == 1 || $room_type == 3 || $room_type == 4)){ + }elseif ($room_label == 2 && ($room_type == 1 || $room_type == 3 || $room_type == 4 || $room_type == 8)){ $apply_type = 2; }elseif ($room_type == 7){//交友房 再开始阶段在麦位上不下麦 $apply_type = 3; @@ -1234,13 +1179,6 @@ class Room extends Model $where['a.createtime'] = ['between', [strtotime('this week Monday'), time()]]; } if($type == 1){//1财富榜,2魅力榜 -// $list = db::name('vs_room_user_charm')->alias('a') -// ->join('user b', 'a.user_id = b.id') -// ->field('a.user_id,b.nickname,b.avatar,a.total_wealth as total') -// ->where($where) -// ->order('a.total_wealth desc') -// ->page($page, $limit) -// ->select(); $list = db::name('vs_give_gift')->alias('a') ->join('user b', 'a.user_id = b.id') ->field('a.user_id,b.nickname,b.avatar,sum(a.total_price) * 10 as total') @@ -1250,13 +1188,6 @@ class Room extends Model ->page($page, $limit) ->select(); }else{ -// $list = db::name('vs_room_user_charm')->alias('a') -// ->join('user b', 'a.user_id = b.id') -// ->field('a.user_id,b.nickname,b.avatar,a.total_charm as total') -// ->where($where) -// ->order('a.total_charm desc') -// ->page($page, $limit) -// ->select(); $list = db::name('vs_give_gift')->alias('a') ->join('user b', 'a.gift_user = b.id') ->field('a.gift_user as user_id,b.nickname,b.avatar,sum(a.total_price) * 10 as total') @@ -1296,7 +1227,7 @@ class Room extends Model //送礼人,接收者(群),礼物id,礼物数量,来源,类型,来源id(房间id),麦位 $res = model('GiveGift')->give_gift($uid, $to_uid, $gift_id, $gift_num,2,$type, $room_id,$pit_number,0,$give_gift_ext); return $res; - }elseif (($label_type['data']['type_id'] == 1 || $label_type['data']['type_id'] == 3 || $label_type['data']['type_id'] == 4) && $label_type['data']['label_id'] == 2)//K歌,type_id = 1,label_id = 2 + }elseif (($label_type['data']['type_id'] == 1 || $label_type['data']['type_id'] == 3 || $label_type['data']['type_id'] == 4 || $label_type['data']['type_id'] == 8) && $label_type['data']['label_id'] == 2)//K歌,type_id = 1,label_id = 2 { $res = model('GiveGift')->give_gift($uid, $to_uid, $gift_id, $gift_num,2,$type, $room_id,$pit_number,0,$give_gift_ext); if($res['code'] == 1){ @@ -1316,8 +1247,7 @@ class Room extends Model }elseif($label_type['data']['type_id'] == 7){ return model('Friend')->room_give_gift($uid, $to_uid, $gift_id, $gift_num,2,$type, $room_id,$pit_number,$heart_id,$give_gift_ext); }else{ - $res = model('GiveGift')->give_gift($uid, $to_uid, $gift_id, $gift_num,2,$type, $room_id,$pit_number,0,$give_gift_ext); - return $res; + return model('GiveGift')->give_gift($uid, $to_uid, $gift_id, $gift_num,2,$type, $room_id,$pit_number,0,$give_gift_ext); } } @@ -1349,78 +1279,6 @@ class Room extends Model return ['code' => 0, 'msg' => '房间不存在', 'data' => null]; } -// //获取在房间的用户 -//// $in_room_users = db::name('vs_room_visitor')->where(['room_id' => $room_id])->field('user_id')->select(); -//// if($in_room_users){ -//// foreach ($in_room_users as $v){ -//// $userss = db::name('user')->where(['id' => $v['user_id']])->field('is_online,is_robot')->find(); -//// if($userss['is_online'] == 1 && $userss['is_robot'] == 1){//在线或者机器人都设置为在线 -//// db::name('vs_room_visitor')->where(['id' => $v['id']])->update(['on_line' => 1]); -//// }else{ -//// db::name('vs_room_visitor')->where(['id' => $v['id']])->update(['on_line' => 0]); -//// } -//// } -//// } -// -// //查找数据库用户 -// $dblist = db::name('vs_room_visitor')->where(['room_id' => $room_id])->field('user_id')->select(); -// //循环获取在线用户ID 拼接数据 -// $user_id_array = []; -// //机器人user_id -// $robot_user_id = []; -// foreach ($dblist as $v) { -// //机器人 -// if(db::name('user')->where(['id' => $v['user_id']])->value('is_robot')){ -// $robot_user_id[] = $v['user_id']; -// continue; -// } -// $user_id_array[] = 'u'.$v['user_id']; -// } -// //获取腾讯的在线用户 -// $online_users = model('Tencent')->query_user_online_status($user_id_array); -// $online_user = []; -// if(isset($online_users['ActionStatus']) && $online_users['ActionStatus'] == 'OK'){ -// if($online_users['QueryResult']){ -// foreach ($online_users['QueryResult'] as $v){ -// if($v['Status'] == "Online"){ -// //截取用户ID前面的 u 并获取用户ID -// $user_id = substr($v['To_Account'],1); -// $online_user[] = $user_id; -// } -// } -// } -// } -// -// if($dblist){ -// $onpit = db::name('vs_room_pit')->field('user_id')->where(['room_id' => $room_id])->select(); -// //合并数组 -// $array = array_merge($online_user,$robot_user_id); -//// $array = $online_user; -// $arraypit = array_values((array)$onpit); -// foreach ($dblist as &$v){ -//// if(in_array($v['user_id'],$arraypit)){ -//// //跳过本次循环 -//// continue; -//// } -// if(!in_array($v['user_id'],$array)){ -// //修改他的状态 -// db::name('vs_room_visitor')->where(['user_id' => $v['user_id'],'room_id'=>$room_id])->update(['on_line' => 0]); -// //查询他是否在其他房间 -// $room_id_list = db::name('vs_room_visitor')->where(['user_id' => $v['user_id'],'room_id'=>['neq',$room_id]])->find(); -// if($room_id_list){ -// db::name('vs_room_visitor')->where(['user_id' => $v['user_id']])->delete(); -// } -// }else{ -// //修改他的状态 -// db::name('vs_room_visitor')->where(['user_id' => $v['user_id'],'room_id'=>$room_id])->update(['on_line' => 1]); -// } -// } -// }else{ -// $lists = ['on_pit' => [], 'off_pit' => []]; -// return ['code' => 1, 'msg' => '成功', 'data' => $lists]; -// } - - $list = db::name('vs_room_visitor')->alias('a') ->join('user b', 'a.user_id = b.id') ->field('a.user_id,b.nickname,b.avatar') @@ -1446,17 +1304,16 @@ class Room extends Model }); } - if($label_type['data']['type_id'] == 7 || ($label_type['data']['type_id'] == 1 || $label_type['data']['type_id'] == 3 || $label_type['data']['type_id'] == 4) && $label_type['data']['label_id'] == 1) {//2卡八麦(聊天)type_id = 1 || 7(交友),label_id = 1 - foreach ($list as &$val) { + if($label_type['data']['type_id'] == 7 || ($label_type['data']['type_id'] == 1 || $label_type['data']['type_id'] == 3 || $label_type['data']['type_id'] == 4 || $label_type['data']['type_id'] == 8) && $label_type['data']['label_id'] == 1) {//2卡八麦(聊天)type_id = 1 || 7(交友),label_id = 1 + foreach ($list as $val) { if ($val['pit_number'] > 0) { $lists['on_pit'][] = $val; } else { $lists['off_pit'][] = $val; } } - }elseif(($label_type['data']['type_id'] == 1 || $label_type['data']['type_id'] == 3 || $label_type['data']['type_id'] == 4) && $label_type['data']['label_id'] == 2){ - foreach ($list as &$val) { -// var_dump($val['pit_number']);exit; + }elseif(($label_type['data']['type_id'] == 1 || $label_type['data']['type_id'] == 3 || $label_type['data']['type_id'] == 4 || $label_type['data']['type_id'] == 8) && $label_type['data']['label_id'] == 2){ + foreach ($list as $val) { if (db::name('vs_room_pit_simulate')->where(['room_id' => $room_id,'user_id' => $val['user_id']])->find() || $val['pit_number'] > 0) { $lists['on_pit'][] = $val; } else { @@ -1476,7 +1333,7 @@ class Room extends Model if($auct){ //获取数组里面的用户ID 组成新的数组 $user_ids = array_column((array)$auct, 'user_id'); - foreach ($list as &$val) { + foreach ($list as $val) { if (in_array($val['user_id'], $user_ids) || $val['pit_number'] > 0) { $lists['on_pit'][] = $val; } else { @@ -1484,7 +1341,7 @@ class Room extends Model } } }else{ - foreach ($list as &$val) { + foreach ($list as $val) { if ($val['pit_number'] > 0) { $lists['on_pit'][] = $val; } else { @@ -1494,8 +1351,7 @@ class Room extends Model } }else{ - foreach ($list as &$val) { -// $lists['off_pit'][] = $val; + foreach ($list as $val) { if ($val['pit_number'] > 0) { $lists['on_pit'][] = $val; } else { @@ -1557,7 +1413,7 @@ class Room extends Model $user_info['is_in_pit'] = 1; } } - }elseif ($room_type['type_id'] == 7 || ($room_type['type_id'] == 1 || $room_type['type_id'] == 3 || $room_type['type_id'] == 4) && $room_type['label_id'] == 1){ + }elseif ($room_type['type_id'] == 7 || ($room_type['type_id'] == 1 || $room_type['type_id'] == 3 || $room_type['type_id'] == 4 || $room_type['type_id'] == 8) && $room_type['label_id'] == 1){ $hah = db::name('vs_room_pit')->where(['room_id' => $room_id, 'user_id' => $user_id])->find(); if($hah){ $user_info['is_in_pit'] = 1; @@ -1643,6 +1499,7 @@ class Room extends Model 'GiftInfo' => null, 'GiftNum' => null ]; + $typee = 0; if($type == 1){//1-主持,2管理 if($is_add == 1){//1-添加,2-删除 $typee = 1007; @@ -1729,8 +1586,6 @@ class Room extends Model //清除房间用户的魅力值 public function clear_user_charm($user_id ,$room_id,$uid='') { - //判断用户是否在主持麦 -// $is_host = db::name('vs_room_pit')->where(['room_id' => $room_id,'user_id' => $user_id,'pit_number' => 9])->find(); $owner = db::name('vs_room')->where(['id' => $room_id, 'user_id' => $user_id])->field('id')->find(); $management = db::name('vs_room_host')->where(['room_id' => $room_id, 'user_id' => $user_id,'delete_time' => null])->find(); if(!$owner && !$management){ @@ -1739,23 +1594,11 @@ class Room extends Model if($uid <= 0){ db::name('vs_room_user_charm')->where(['room_id' => $room_id])->update(['charm' => 0,'clear_time' => time()]); - //获取房间内所有用户 -// $list = db::name('vs_room_visitor')->field('user_id')->where(['room_id' => $room_id])->select(); -// -// //循环清除用户魅力值 -// if($list){ -// foreach ($list as $v){ -// //清除有魅力值的用户 -// if(db::name('vs_room_user_charm')->where(['room_id' => $room_id,'user_id' => $v['user_id']])->find()){ -// db::name('vs_room_user_charm')->where(['room_id' => $room_id,'user_id' => $v['user_id']])->update(['charm' => 0,'clear_time' => time()]); -// } -// } -// } //发送消息 $text['text'] = '清除魅力成功'; model('Chat')->sendMsg(1021,$room_id,$text); }else{ - $dd = db::name('vs_room_user_charm')->where(['room_id' => $room_id,'user_id' => $uid])->update(['charm' => 0,'clear_time' => time()]); + db::name('vs_room_user_charm')->where(['room_id' => $room_id,'user_id' => $uid])->update(['charm' => 0,'clear_time' => time()]); //发送消息 $text['text'] = '清除魅力成功'; $text['user_id'] = $uid; @@ -1799,7 +1642,7 @@ class Room extends Model //开启事务 db::startTrans(); $data = []; - if($type == 1 || $type == 3 || $type == 4){ + if($type == 1 || $type == 3 || $type == 4 || $type == 8){ $data = [ 'label_id' => 1, 'type_id' => $type, @@ -1815,7 +1658,7 @@ class Room extends Model 'is_song' => 1 ]; } - //交友房 + //交友房(互娱) if($type == 7){ $data = [ 'label_id' => 5, @@ -1929,7 +1772,7 @@ class Room extends Model $pit_list = null; $roomauction = null; $cp_users = null; - if($room['type_id'] == 1 || $room['type_id'] == 3 || $room['type_id'] == 4 || $room['type_id'] == 7) { + if($room['type_id'] == 1 || $room['type_id'] == 3 || $room['type_id'] == 4 || $room['type_id'] == 7 || $room['type_id'] == 8) { if($room['label_id'] == 1 || $room['label_id'] == 5){ //麦位信息 $pit_list = db::name('vs_room_pit')->alias('a')->join('user b', 'a.user_id = b.id', 'left') @@ -2158,11 +2001,7 @@ class Room extends Model if(!$is_host && !$is_room_owner){ return ['code' => 0, 'msg' => '您没有权限', 'data' => null]; } - //是否在主持麦位上 -// $is_pit = db::name('vs_room_pit')->where(['room_id' => $room_id,'pit_number' => 9])->value('user_id'); -// if($uid != $is_pit){ -// return ['code' => 0, 'msg' => '您没有权限', 'data' => null]; -// } + if(!in_array($is_mute, [1,2,3,4])){ return ['code' => 0, 'msg' => '参数错误!', 'data' => null]; } @@ -2617,26 +2456,6 @@ class Room extends Model $friend['friend_id'] = $friend_info['id']; $friend['end_time'] = $friend_info['end_time']; $friend['heart_list'] = model('Friend')->pullHeartChange($room_id, $friend_info['id']); - //获取麦上CP心动值列表 -// $heart_list = db::name('vs_user_friending_heart')->where(['room_id' => $room_id, 'friend_id' => $friend_info['id'], 'status' => 1])->order('heart_value', 'desc')->limit(3)->select(); -// if($heart_list){ -// $heart_list_data = []; -//// $heart_list = $heart_list->toArray(); -// $pit_number_array_reverse = [0=>[2,5],1=>[1,6],2=>[3,4]]; -// foreach($heart_list as $k=>$v){ -// $heart_list_data[$k]['heartId'] = $v['id']; -// $pitnum1 = db::name('vs_room_pit')->where(['room_id' =>$room_id, 'user_id' => $v['user1_id']])->value('pit_number'); -// $pitnum2 = db::name('vs_room_pit')->where(['room_id' =>$room_id, 'user_id' => $v['user2_id']])->value('pit_number'); -// if(in_array($pitnum1,$pit_number_array_reverse[$k]) && in_array($pitnum2,$pit_number_array_reverse[$k])){ -// $heart_list_data[$k]['heartNum'] = $v['heart_value']; -// }else{ -// $heart_list_data[$k]['heartNum'] = 0; -// } -// } -// $friend['heart_list'] =$heart_list_data; -// }else{ -// $friend['heart_list'] = []; -// } } return $friend; }