Commit 3bf97d48 authored by 陈冲's avatar 陈冲

fix: 已上榜的玩家不显示在大屏

parent 2ce3787b
...@@ -60,4 +60,43 @@ impl Game { ...@@ -60,4 +60,43 @@ impl Game {
} }
} }
} }
pub async fn get_rank(wechat_id: &str) -> i32 {
let Some(_) = &config.db else {
println!("没有配置数据库, get_rank return 0;");
return 0;
};
let res = crate::db::db_query(
r#"SELECT COUNT(1) AS rank_count FROM tb_game WHERE wechat_id = ?
AND game_rank <= 10"#,
vec![json!(&wechat_id)],
)
.await;
match res {
Ok(res) => res
.first()
.and_then(|row| row.get("rank_count"))
.and_then(|value| value.as_i64().or_else(|| value.as_u64().map(|v| v as i64)))
.unwrap_or(0) as i32,
Err(err) => {
// dbg!(&err);
// let log = Log {
// id: 0,
// msg: err,
// params: json!({
// "wechat_id": self.wechat_id,
// "nickname": self.nickname,
// "avatar": self.avatar,
// "item_num": self.item_num,
// "game_rank":self.game_rank,
// "score": self.score,
// }),
// create_date: None,
// };
// log.insert().await;
0
}
}
}
} }
...@@ -24,6 +24,7 @@ lazy_static::lazy_static! { ...@@ -24,6 +24,7 @@ lazy_static::lazy_static! {
/// 当前唯一在线管理员:(token, socket)。 /// 当前唯一在线管理员:(token, socket)。
static ref CLIENT_ADMIN_SESSION: std::sync::Mutex<AdminSession> = std::sync::Mutex::new(AdminSession::default()); static ref CLIENT_ADMIN_SESSION: std::sync::Mutex<AdminSession> = std::sync::Mutex::new(AdminSession::default());
static ref CLIENT_PLAYER_MAP: DashMap<String, (i32,SocketRef)> = DashMap::new(); // 1: 正在游戏中 static ref CLIENT_PLAYER_MAP: DashMap<String, (i32,SocketRef)> = DashMap::new(); // 1: 正在游戏中
static ref CLIENT_TOP_RANKED_MAP: DashMap<String, bool> = DashMap::new();
static ref ROOM_STATE: std::sync::Mutex<RoomState> = std::sync::Mutex::new(RoomState::default()); static ref ROOM_STATE: std::sync::Mutex<RoomState> = std::sync::Mutex::new(RoomState::default());
} }
...@@ -65,6 +66,8 @@ struct RoomPlayer { ...@@ -65,6 +66,8 @@ struct RoomPlayer {
nickname: String, nickname: String,
/// 头像 /// 头像
avatar: String, avatar: String,
/// 是否曾经进入过历史前十榜,已上榜玩家本轮不再进入前十展示。
already_top_ranked: bool,
} }
#[derive(Clone)] #[derive(Clone)]
...@@ -73,6 +76,7 @@ struct RankingPlayer { ...@@ -73,6 +76,7 @@ struct RankingPlayer {
score: i64, score: i64,
nickname: String, nickname: String,
avatar: String, avatar: String,
already_top_ranked: bool,
} }
#[derive(Clone, Copy, Default, PartialEq, Eq)] #[derive(Clone, Copy, Default, PartialEq, Eq)]
...@@ -130,6 +134,7 @@ impl RoomState { ...@@ -130,6 +134,7 @@ impl RoomState {
score: player.score, score: player.score,
nickname: player.nickname.clone(), nickname: player.nickname.clone(),
avatar: player.avatar.clone(), avatar: player.avatar.clone(),
already_top_ranked: player.already_top_ranked,
} }
} }
...@@ -173,8 +178,19 @@ impl RoomState { ...@@ -173,8 +178,19 @@ impl RoomState {
ranking ranking
} }
fn eligible_score_ranking(&self) -> Vec<RankingPlayer> {
let mut ranking: Vec<RankingPlayer> = self
.players
.iter()
.filter(|(_, player)| !player.already_top_ranked)
.map(|(userid, player)| Self::ranking_from_player(userid, player))
.collect();
Self::sort_score_ranking(&mut ranking);
ranking
}
fn score_ranking(&self) -> Vec<RankingPlayer> { fn score_ranking(&self) -> Vec<RankingPlayer> {
let mut ranking = self.full_score_ranking(); let mut ranking = self.eligible_score_ranking();
ranking.truncate(ROOM_SCORE_RANK_LIMIT); ranking.truncate(ROOM_SCORE_RANK_LIMIT);
ranking ranking
} }
...@@ -189,7 +205,7 @@ impl RoomState { ...@@ -189,7 +205,7 @@ impl RoomState {
} }
fn player_rank(&self, userid: &str) -> Option<usize> { fn player_rank(&self, userid: &str) -> Option<usize> {
self.full_score_ranking() self.eligible_score_ranking()
.iter() .iter()
.position(|player| player.wechat == userid) .position(|player| player.wechat == userid)
.map(|index| index + 1) .map(|index| index + 1)
...@@ -214,6 +230,8 @@ impl RoomState { ...@@ -214,6 +230,8 @@ impl RoomState {
"gameId": self.current_game_id, "gameId": self.current_game_id,
"score": player.score, "score": player.score,
"rank": self.player_rank(userid), "rank": self.player_rank(userid),
"flag": if player.already_top_ranked { 1 } else { 0 },
"alreadyTopRanked": player.already_top_ranked,
"remainingSeconds": self.remaining_running_secs(), "remainingSeconds": self.remaining_running_secs(),
})) }))
} }
...@@ -408,6 +426,7 @@ fn spawn_deactivate_players_if_admin_absent(version: u64) { ...@@ -408,6 +426,7 @@ fn spawn_deactivate_players_if_admin_absent(version: u64) {
for mut player in CLIENT_PLAYER_MAP.iter_mut() { for mut player in CLIENT_PLAYER_MAP.iter_mut() {
player.value_mut().0 = 0; player.value_mut().0 = 0;
} }
CLIENT_TOP_RANKED_MAP.clear();
}); });
} }
/// 发送给所有管理员和玩家 /// 发送给所有管理员和玩家
...@@ -475,26 +494,34 @@ fn is_current_player_socket(userid: &str, socket: &SocketRef) -> bool { ...@@ -475,26 +494,34 @@ fn is_current_player_socket(userid: &str, socket: &SocketRef) -> bool {
fn push_room_score_ranking() -> bool { fn push_room_score_ranking() -> bool {
let (ranking, player_results, current_player_ids) = if let Ok(state) = ROOM_STATE.lock() { let (ranking, player_results, current_player_ids) = if let Ok(state) = ROOM_STATE.lock() {
let full_ranking = state.full_score_ranking(); let full_ranking = state.full_score_ranking();
let eligible_ranking = state.eligible_score_ranking();
let remaining_seconds = state.remaining_running_secs(); let remaining_seconds = state.remaining_running_secs();
let ranking = RoomState::ranking_payload( let ranking = RoomState::ranking_payload(
&full_ranking &eligible_ranking
.iter() .iter()
.take(ROOM_SCORE_RANK_LIMIT) .take(ROOM_SCORE_RANK_LIMIT)
.cloned() .cloned()
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
); );
let eligible_rank_map = eligible_ranking
.iter()
.enumerate()
.map(|(index, player)| (player.wechat.clone(), index + 1))
.collect::<HashMap<_, _>>();
let player_results = full_ranking let player_results = full_ranking
.into_iter() .into_iter()
.enumerate() .map(|player| {
.map(|(index, player)| { let rank = eligible_rank_map.get(&player.wechat).cloned();
( let mut result = json!({
player.wechat, "score": player.score,
json!({ "rank": rank,
"score": player.score, "remainingSeconds": remaining_seconds
"rank": index + 1, });
"remainingSeconds": remaining_seconds if player.already_top_ranked {
}), result["alreadyTopRanked"] = json!(true);
) result["message"] = json!("一人只能上榜领奖一次,您的福利已到手,把机会留给其他玩家吧");
}
(player.wechat, result)
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let current_player_ids = state.players.keys().cloned().collect::<HashSet<_>>(); let current_player_ids = state.players.keys().cloned().collect::<HashSet<_>>();
...@@ -616,8 +643,8 @@ async fn handle_room_command( ...@@ -616,8 +643,8 @@ async fn handle_room_command(
let evt = &format!("{cmd}_result"); let evt = &format!("{cmd}_result");
match cmd { match cmd {
//回到首页时 //回到首页时
"home"=>{ "home" => {
if !is_admin{ if !is_admin {
return; return;
} }
GAME_ROUND_ID.fetch_add(1, Ordering::SeqCst); GAME_ROUND_ID.fetch_add(1, Ordering::SeqCst);
...@@ -683,11 +710,14 @@ async fn handle_room_command( ...@@ -683,11 +710,14 @@ async fn handle_room_command(
.and_then(|value| value.as_str()) .and_then(|value| value.as_str())
.unwrap_or("") .unwrap_or("")
.to_string(); .to_string();
let already_top_ranked = CLIENT_TOP_RANKED_MAP
.get(userid)
.map(|value| *value)
.unwrap_or(false);
if let Ok(mut state) = ROOM_STATE.lock() { if let Ok(mut state) = ROOM_STATE.lock() {
// 当前h5进入的不是大屏开启的游戏房间 // 当前h5进入的不是大屏开启的游戏房间
if gameId != state.current_game_id.clone().unwrap_or_default() { if gameId != state.current_game_id.clone().unwrap_or_default() {
drop(state); drop(state);
emit_msgpack( emit_msgpack(
&socket, &socket,
...@@ -708,6 +738,7 @@ async fn handle_room_command( ...@@ -708,6 +738,7 @@ async fn handle_room_command(
player.online = true; player.online = true;
player.nickname = nickname.to_string(); player.nickname = nickname.to_string();
player.avatar = avatar.to_string(); player.avatar = avatar.to_string();
player.already_top_ranked = already_top_ranked;
} }
let reconnect_payload = state.reconnect_payload(userid); let reconnect_payload = state.reconnect_payload(userid);
drop(state); drop(state);
...@@ -738,6 +769,7 @@ async fn handle_room_command( ...@@ -738,6 +769,7 @@ async fn handle_room_command(
player.online = true; player.online = true;
player.nickname = nickname.to_string(); player.nickname = nickname.to_string();
player.avatar = avatar.to_string(); player.avatar = avatar.to_string();
player.already_top_ranked = already_top_ranked;
}) })
.or_insert(RoomPlayer { .or_insert(RoomPlayer {
score: 0, score: 0,
...@@ -745,6 +777,7 @@ async fn handle_room_command( ...@@ -745,6 +777,7 @@ async fn handle_room_command(
entry_order, entry_order,
nickname: nickname.to_string(), nickname: nickname.to_string(),
avatar: avatar.to_string(), avatar: avatar.to_string(),
already_top_ranked,
}); });
let count = state.players.len(); let count = state.players.len();
let ranking = state.current_ranking_payload(); let ranking = state.current_ranking_payload();
...@@ -754,7 +787,10 @@ async fn handle_room_command( ...@@ -754,7 +787,10 @@ async fn handle_room_command(
if let Some(mut player) = CLIENT_PLAYER_MAP.get_mut(userid) { if let Some(mut player) = CLIENT_PLAYER_MAP.get_mut(userid) {
player.0 = 1; player.0 = 1;
} }
emit_msgpack(&socket, evt, &ok_resp(Some(json!(gameId)))); emit_msgpack(&socket, evt, &ok_resp(Some(json!({
"gameId":gameId,//当前游戏
"alreadyTopRanked": already_top_ranked,//是否上过前十榜
}))));
// 给所有管理员广播房间状态更新 // 给所有管理员广播房间状态更新
broadcast_msgpack_all_admin( broadcast_msgpack_all_admin(
evt, evt,
...@@ -826,20 +862,24 @@ async fn handle_room_command( ...@@ -826,20 +862,24 @@ async fn handle_room_command(
// player.wechat = wechat.to_string(); // player.wechat = wechat.to_string();
player.online = true; player.online = true;
let score = player.score; let score = player.score;
let rank = state.player_rank(userid); let already_top_ranked = player.already_top_ranked;
let rank = if already_top_ranked {
None
} else {
state.player_rank(userid)
};
let remaining_seconds = state.remaining_running_secs(); let remaining_seconds = state.remaining_running_secs();
drop(state); drop(state);
emit_msgpack( let mut result = json!({
&socket, "score": score,
evt, "rank": rank,
&ok_resp(rank.map(|rank| { "remainingSeconds": remaining_seconds
json!({ });
"score": score, if already_top_ranked {
"rank": rank, result["alreadyTopRanked"] = json!(true);
"remainingSeconds": remaining_seconds result["message"] = json!("一人只能上榜领奖一次,您的福利已到手,把机会留给其他玩家吧s");
}) }
})), emit_msgpack(&socket, evt, &ok_resp(Some(result)));
);
return; return;
// 方案1:每有一名玩家提交时发送给所有玩家跟管理员,玩家过多时发送太频繁, // 方案1:每有一名玩家提交时发送给所有玩家跟管理员,玩家过多时发送太频繁,
...@@ -870,35 +910,45 @@ async fn handle_room_command( ...@@ -870,35 +910,45 @@ async fn handle_room_command(
if wechat.is_empty() { if wechat.is_empty() {
return; return;
} }
let (score, rank, ranking) = if let Ok(state) = ROOM_STATE.lock() { let (score, rank, ranking, already_top_ranked) =
//防止客户端提交的状态还在Running中 if let Ok(state) = ROOM_STATE.lock() {
if !matches!(state.status, RoomStatus::Submit | RoomStatus::Running) { //防止客户端提交的状态还在Running中
if !matches!(state.status, RoomStatus::Submit | RoomStatus::Running) {
drop(state);
return;
}
let eligible_ranking = state.eligible_score_ranking();
let ranking = RoomState::ranking_payload(
&eligible_ranking
.iter()
.take(ROOM_SCORE_RANK_LIMIT)
.cloned()
.collect::<Vec<_>>(),
);
let server_score = state
.players
.get(userid)
.map(|player| player.score)
.unwrap_or(score);
let already_top_ranked = state
.players
.get(userid)
.map(|player| player.already_top_ranked)
.unwrap_or(false);
let server_rank = if already_top_ranked {
0
} else {
eligible_ranking
.iter()
.position(|player| player.wechat == userid)
.map(|index| (index + 1) as i64)
.unwrap_or(rank)
};
drop(state); drop(state);
return; (server_score, server_rank, ranking, already_top_ranked)
} } else {
let full_ranking = state.full_score_ranking(); (score, rank, Vec::new(), false)
let ranking = RoomState::ranking_payload( };
&full_ranking
.iter()
.take(ROOM_SCORE_RANK_LIMIT)
.cloned()
.collect::<Vec<_>>(),
);
let server_score = state
.players
.get(userid)
.map(|player| player.score)
.unwrap_or(score);
let server_rank = full_ranking
.iter()
.position(|player| player.wechat == userid)
.map(|index| (index + 1) as i64)
.unwrap_or(rank);
drop(state);
(server_score, server_rank, ranking)
} else {
(score, rank, Vec::new())
};
let action = async |msg: &str| { let action = async |msg: &str| {
let log = Log { let log = Log {
...@@ -927,6 +977,9 @@ async fn handle_room_command( ...@@ -927,6 +977,9 @@ async fn handle_room_command(
}; };
if game.insert().await { if game.insert().await {
if !already_top_ranked && (1..=ROOM_SCORE_RANK_LIMIT as i64).contains(&rank) {
CLIENT_TOP_RANKED_MAP.insert(userid.to_string(), true);
}
//还需要提交给后台 //还需要提交给后台
// match utils::post(wechat, item_num).await { // match utils::post(wechat, item_num).await {
// Ok(res) => { // Ok(res) => {
...@@ -939,14 +992,15 @@ async fn handle_room_command( ...@@ -939,14 +992,15 @@ async fn handle_room_command(
// } // }
// }; // };
emit_msgpack( let mut payload = json!({
&socket, "list": ranking,
evt, "rank": if already_top_ranked { Value::Null } else { json!(rank) }
&ok_resp(Some(json!({ });
"list": ranking, if already_top_ranked {
"rank": rank payload["alreadyTopRanked"] = json!(true);
}))), payload["message"] = json!("一人只能上榜领奖一次,您的福利已到手,把机会留给其他玩家吧");
); }
emit_msgpack(&socket, evt, &ok_resp(Some(payload)));
} else { } else {
emit_msgpack(&socket, evt, &err_resp("提交异常", None)); emit_msgpack(&socket, evt, &err_resp("提交异常", None));
} }
...@@ -967,8 +1021,7 @@ async fn handle_room_command( ...@@ -967,8 +1021,7 @@ async fn handle_room_command(
.map(|player| player.value().1.clone()) .map(|player| player.value().1.clone())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
CLIENT_PLAYER_MAP.clear(); CLIENT_PLAYER_MAP.clear();
CLIENT_TOP_RANKED_MAP.clear();
emit_msgpack(&socket, evt, &ok_resp(None)); emit_msgpack(&socket, evt, &ok_resp(None));
// broadcast_msgpack_all_player_2(evt, &ok_resp(None)); // broadcast_msgpack_all_player_2(evt, &ok_resp(None));
...@@ -1073,6 +1126,9 @@ pub async fn on_connect(_io: SocketIo, socket: SocketRef, Data(data): Data<Value ...@@ -1073,6 +1126,9 @@ pub async fn on_connect(_io: SocketIo, socket: SocketRef, Data(data): Data<Value
} }
} }
} else { } else {
let already_top_ranked = Game::get_rank(&userid).await > 0;
CLIENT_TOP_RANKED_MAP.insert(userid.clone(), already_top_ranked);
if get_admin_count() == 0 { if get_admin_count() == 0 {
match CLIENT_PLAYER_MAP.entry(userid.clone()) { match CLIENT_PLAYER_MAP.entry(userid.clone()) {
Entry::Occupied(mut entry) => { Entry::Occupied(mut entry) => {
...@@ -1151,10 +1207,12 @@ pub async fn on_connect(_io: SocketIo, socket: SocketRef, Data(data): Data<Value ...@@ -1151,10 +1207,12 @@ pub async fn on_connect(_io: SocketIo, socket: SocketRef, Data(data): Data<Value
match state.status { match state.status {
RoomStatus::Closed => { RoomStatus::Closed => {
CLIENT_PLAYER_MAP.remove(&userid); CLIENT_PLAYER_MAP.remove(&userid);
CLIENT_TOP_RANKED_MAP.remove(&userid);
state.players.remove(&userid); state.players.remove(&userid);
} }
RoomStatus::Loading => { RoomStatus::Loading => {
CLIENT_PLAYER_MAP.remove(&userid); CLIENT_PLAYER_MAP.remove(&userid);
CLIENT_TOP_RANKED_MAP.remove(&userid);
if state.players.remove(&userid).is_none() { if state.players.remove(&userid).is_none() {
return; return;
} }
......
...@@ -326,11 +326,11 @@ export function $read_socket_storge(): any | null { ...@@ -326,11 +326,11 @@ export function $read_socket_storge(): any | null {
export function $getWechat(): any | null { export function $getWechat(): any | null {
const q = $query(['token', 'nickname', 'avatar']); const q = $query(['token', 'nickname', 'avatar','userno']);
if (q && q.length == 3) { if (q && q.length == 4) {
return { return {
token: SHA256(q[0]).toString(), //原token很长,这里压缩下,压缩后不能还原,最后提交成绩时要提交原始token token: q[3], //玩家的唯一码,不用做压缩
token_origin: q[0], token_origin: q[0],//这个token要提交给api.guocai365.org.cn做验证
nickname: q[1], nickname: q[1],
avatar: q[2], avatar: q[2],
}; };
...@@ -349,47 +349,12 @@ export function $getWechat(): any | null { ...@@ -349,47 +349,12 @@ export function $getWechat(): any | null {
return null; return null;
} }
export async function postJson(token: string, index: number) { export async function postScreenGameScore(gameCode: string, score: number) {
const url = "https://api.guocai365.org.cn/adminapi/offline_clearance/score/list";
let arr = ['', 'JGQF', 'JBJF', 'MSYF', 'CMYF', 'QCNF', 'FYDT'];
try {
const resp = await fetch(url, {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
activity_id: 1,
game_code: arr[index],
page: 1,
pageSize: 20,
}),
});
const text = await resp.text();
if (!resp.ok) {
console.error("请求失败:", resp.status, text);
return;
}
// 如果返回的是 JSON
const data = JSON.parse(text);
console.log("响应:", data);
} catch (err) {
console.error("请求异常:", err);
}
}
export async function postScreenGameScore(token: string, gameCode: string, score: number) {
try { try {
const resp = await fetch('https://api.guocai365.org.cn/api/offline_clearance/user/screen_game_score', { const resp = await fetch('https://api.guocai365.org.cn/api/offline_clearance/user/screen_game_score', {
method: 'POST', method: 'POST',
headers: { headers: {
Authorization: token, Authorization: $getWechat()?.token_origin,
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}, },
body: JSON.stringify({ body: JSON.stringify({
......
...@@ -55,6 +55,7 @@ export function sendGameMessage(cmd: string, data: any = {}) { ...@@ -55,6 +55,7 @@ export function sendGameMessage(cmd: string, data: any = {}) {
return sendSocketMessage(cmd, data) return sendSocketMessage(cmd, data)
} }
export const userJoinStatus = ref(false) export const userJoinStatus = ref(false)
export const userTop10RankStatus = ref(false)
export function useGameSocket(options: GameSocketOptions) { export function useGameSocket(options: GameSocketOptions) {
const router = useRouter() const router = useRouter()
...@@ -96,7 +97,7 @@ export function useGameSocket(options: GameSocketOptions) { ...@@ -96,7 +97,7 @@ export function useGameSocket(options: GameSocketOptions) {
// router.replace('/loading').then(() => { }); // router.replace('/loading').then(() => { });
return; return;
} }
if (evt == 'submit_score_save') { if (evt == 'submit_score_save_result') {
//提交分数的情况下有问题的情况下,只重试3次 //提交分数的情况下有问题的情况下,只重试3次
if (resubmitcount >= 3) { if (resubmitcount >= 3) {
return; return;
...@@ -111,12 +112,6 @@ export function useGameSocket(options: GameSocketOptions) { ...@@ -111,12 +112,6 @@ export function useGameSocket(options: GameSocketOptions) {
return; return;
} }
if (state === 0) {
// alert(msg)
$toast(msg)
return
}
switch (evt) { switch (evt) {
case 'room_create_result': { case 'room_create_result': {
// if (`game${data}` == options.gameId) { // if (`game${data}` == options.gameId) {
...@@ -133,10 +128,12 @@ export function useGameSocket(options: GameSocketOptions) { ...@@ -133,10 +128,12 @@ export function useGameSocket(options: GameSocketOptions) {
// break // break
} }
case 'room_join_result': { case 'room_join_result': {
if (data != options.gameId) { if (data.gameId != options.gameId) {
// debugger // debugger
return; return;
} }
//是否上过前十榜
userTop10RankStatus.value = data.alreadyTopRanked
$toast('您已进入游戏房间') $toast('您已进入游戏房间')
userJoinStatus.value = true userJoinStatus.value = true
break break
...@@ -163,10 +160,12 @@ export function useGameSocket(options: GameSocketOptions) { ...@@ -163,10 +160,12 @@ export function useGameSocket(options: GameSocketOptions) {
break break
} }
case 'submit_score_save_result': { case 'submit_score_save_result': {
const submittedScore = options.onScoreSubmitted?.(true, data) if (!userTop10RankStatus) {
const token = $getWechat()?.token_origin const submittedScore = options.onScoreSubmitted?.(true, data)
if (token && submittedScore && Number.isFinite(submittedScore.score)) { const token_origin = $getWechat()?.token_origin
void postScreenGameScore(token, submittedScore.code, submittedScore.score) if (token_origin && submittedScore && Number.isFinite(submittedScore.score)) {
void postScreenGameScore(submittedScore.code, submittedScore.score)
}
} }
break break
} }
...@@ -199,6 +198,7 @@ export function useGameSocket(options: GameSocketOptions) { ...@@ -199,6 +198,7 @@ export function useGameSocket(options: GameSocketOptions) {
return { return {
socket, socket,
userJoinStatus, userJoinStatus,
userTop10RankStatus,
offSocketMessage offSocketMessage
} }
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
import { onBeforeUnmount, onMounted, ref, watch } from 'vue' import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { cssAssetUrl } from '@/commons/assets.ts' import { cssAssetUrl } from '@/commons/assets.ts'
import MobileStage from '@/components/MobileStage.vue' import MobileStage from '@/components/MobileStage.vue'
import { useGameSocket, sendGameMessage, userJoinStatus, joinSharedRoom } from '@/composables/useGameSocket' import { useGameSocket, sendGameMessage, userJoinStatus,userTop10RankStatus, joinSharedRoom } from '@/composables/useGameSocket'
import LoadingView from './views/LoadingView.vue' import LoadingView from './views/LoadingView.vue'
import PlayingView from './views/PlayingView.vue' import PlayingView from './views/PlayingView.vue'
import ScoreView from './views/ScoreView.vue' import ScoreView from './views/ScoreView.vue'
...@@ -69,7 +69,7 @@ function submitScore(save: boolean = false) { ...@@ -69,7 +69,7 @@ function submitScore(save: boolean = false) {
//wechat 原始token //wechat 原始token
sendGameMessage('submit_score_save', { sendGameMessage('submit_score_save', {
score: tick.value, score: tick.value,
wechat: wechat.token_origin, wechat: wechat.token,
item_num: 1, item_num: 1,
nickname: wechat.nickname, nickname: wechat.nickname,
avatar: wechat.avatar, avatar: wechat.avatar,
...@@ -143,7 +143,13 @@ function showScoreView() { ...@@ -143,7 +143,13 @@ function showScoreView() {
showGameRule.value = false; showGameRule.value = false;
stopGameCountdown() stopGameCountdown()
setDivDescVisible(false) setDivDescVisible(false)
currentView.value = 'score' if(userTop10RankStatus.value){
currentView.value = 'loading'
userJoinStatus.value = false;
$toast('一人只能上榜领奖一次,您的福利已到手,把机会留给其他玩家吧',30000)
}else{
currentView.value = 'score'
}
} }
const touchHandler = () => { const touchHandler = () => {
...@@ -290,7 +296,7 @@ const showGameRuleHandler = () => { ...@@ -290,7 +296,7 @@ const showGameRuleHandler = () => {
@touchGameRule="showGameRuleHandler" /> @touchGameRule="showGameRuleHandler" />
<PlayingView v-else-if="currentView === 'playing'" :image-urls="imageUrls" :tick="tick" :rank="rank" <PlayingView v-else-if="currentView === 'playing'" :image-urls="imageUrls" :tick="tick" :rank="rank"
:current-gu-frame="currentGuFrame" :countdown-interval="countdownInterval" :is-div-desc-visible="isDivDescVisible" :current-gu-frame="currentGuFrame" :countdown-interval="countdownInterval" :is-div-desc-visible="isDivDescVisible"
@touch="touchHandler" /> @touch="touchHandler" :userTop10RankStatus="userTop10RankStatus" />
<ScoreView v-else :image-urls="imageUrls" :rank="rank" :tick="tick" /> <ScoreView v-else :image-urls="imageUrls" :rank="rank" :tick="tick" />
</MobileStage> </MobileStage>
<div v-else style="text-align: center; width: 100vw; height: 100vh; line-height: 30; font-size: 20px;"> <div v-else style="text-align: center; width: 100vw; height: 100vh; line-height: 30; font-size: 20px;">
......
...@@ -5,7 +5,8 @@ defineProps<{ ...@@ -5,7 +5,8 @@ defineProps<{
isDivDescVisible: boolean isDivDescVisible: boolean
tick: number tick: number
rank: number rank: number
currentGuFrame: number currentGuFrame: number,
userTop10RankStatus: boolean,
}>() }>()
defineEmits<{ defineEmits<{
...@@ -25,7 +26,7 @@ defineEmits<{ ...@@ -25,7 +26,7 @@ defineEmits<{
<div class="play-content"> <div class="play-content">
<div>当前击鼓积分</div> <div>当前击鼓积分</div>
<div>{{ tick }}</div> <div>{{ tick }}</div>
<div>当前排名: &nbsp;&nbsp;<label>{{ rank }}</label>&nbsp;</div> <div v-if="!userTop10RankStatus">当前排名: &nbsp;&nbsp;<label>{{ rank }}</label>&nbsp;</div>
</div> </div>
<div class="bg-bottom"></div> <div class="bg-bottom"></div>
<div class="play-gu" :style="{ backgroundPosition: `-${currentGuFrame * 400}px 0` }" @click="$emit('touch')"></div> <div class="play-gu" :style="{ backgroundPosition: `-${currentGuFrame * 400}px 0` }" @click="$emit('touch')"></div>
......
...@@ -94,7 +94,7 @@ function submitScore(save: boolean = false, currentTick = score.value) { ...@@ -94,7 +94,7 @@ function submitScore(save: boolean = false, currentTick = score.value) {
//wechat 原始token //wechat 原始token
sendGameMessage('submit_score_save', { sendGameMessage('submit_score_save', {
score: currentTick, score: currentTick,
wechat: wechat.token_origin, wechat: wechat.token,
item_num: 2, item_num: 2,
nickname: wechat.nickname, nickname: wechat.nickname,
avatar: wechat.avatar, avatar: wechat.avatar,
......
...@@ -108,7 +108,7 @@ function submitScore(save: boolean = false, currentTick = score.value) { ...@@ -108,7 +108,7 @@ function submitScore(save: boolean = false, currentTick = score.value) {
} }
sendGameMessage('submit_score_save', { sendGameMessage('submit_score_save', {
score: currentTick, score: currentTick,
wechat: wechat.token_origin, wechat: wechat.token,
item_num: 3, item_num: 3,
nickname: wechat.nickname, nickname: wechat.nickname,
avatar: wechat.avatar, avatar: wechat.avatar,
...@@ -244,6 +244,7 @@ if (wechat) { ...@@ -244,6 +244,7 @@ if (wechat) {
rank.value = nextRank rank.value = nextRank
} }
} }
return { code: 'MSYF', score: score.value }
}, },
onRescoreSubmitted: (_recount) => { onRescoreSubmitted: (_recount) => {
submitScore(true); submitScore(true);
......
...@@ -89,7 +89,7 @@ function submitScore(save: boolean = false) { ...@@ -89,7 +89,7 @@ function submitScore(save: boolean = false) {
// wechat 原始token // wechat 原始token
sendGameMessage("submit_score_save", { sendGameMessage("submit_score_save", {
score: tick.value, score: tick.value,
wechat: wechat.token_origin, wechat: wechat.token,
item_num: 4, item_num: 4,
nickname: wechat.nickname, nickname: wechat.nickname,
avatar: wechat.avatar, avatar: wechat.avatar,
......
...@@ -136,7 +136,7 @@ function submitScore(save: boolean = false) { ...@@ -136,7 +136,7 @@ function submitScore(save: boolean = false) {
//wechat 原始token //wechat 原始token
const data = { const data = {
score: tick.value, score: tick.value,
wechat: wechat.token_origin, wechat: wechat.token,
item_num: 1, item_num: 1,
nickname: wechat.nickname, nickname: wechat.nickname,
avatar: wechat.avatar, avatar: wechat.avatar,
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
import { computed, onBeforeUnmount, onMounted, ref } from 'vue' import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
import { cssAssetUrl } from '@/commons/assets.ts' import { cssAssetUrl } from '@/commons/assets.ts'
import MobileStage from '@/components/MobileStage.vue' import MobileStage from '@/components/MobileStage.vue'
import { useGameSocket, sendGameMessage, userJoinStatus, joinSharedRoom } from '@/composables/useGameSocket' import { useGameSocket, sendGameMessage, userJoinStatus, userTop10RankStatus, joinSharedRoom } from '@/composables/useGameSocket'
import LoadingView from './views/LoadingView.vue' import LoadingView from './views/LoadingView.vue'
import PlayingView from './views/PlayingView.vue' import PlayingView from './views/PlayingView.vue'
import { $format_str, $getWechat, $toast } from '@/commons/utils.ts' import { $format_str, $getWechat, $toast } from '@/commons/utils.ts'
...@@ -101,7 +101,7 @@ function submitScore(save: boolean = false, currentTick = score.value) { ...@@ -101,7 +101,7 @@ function submitScore(save: boolean = false, currentTick = score.value) {
//wechat 原始token //wechat 原始token
sendGameMessage('submit_score_save', { sendGameMessage('submit_score_save', {
score: currentTick, score: currentTick,
wechat: wechat.token_origin, wechat: wechat.token,
item_num: 6, item_num: 6,
nickname: wechat.nickname, nickname: wechat.nickname,
avatar: wechat.avatar, avatar: wechat.avatar,
...@@ -123,9 +123,16 @@ function startGameCountdown(seconds = 60) { ...@@ -123,9 +123,16 @@ function startGameCountdown(seconds = 60) {
if (countdownInterval.value <= 0) { if (countdownInterval.value <= 0) {
countdownInterval.value = 0 countdownInterval.value = 0
gameCountdownTimer = undefined gameCountdownTimer = undefined
setDivDescVisible(false) currentView.value = 'loading'
submitScore(true) if (userTop10RankStatus.value) {
showGameOverRank() userJoinStatus.value = false;
showGameRank.value = false;
$toast('一人只能上榜领奖一次,您的福利已到手,把机会留给其他玩家吧', 30000)
} else {
setDivDescVisible(false)
submitScore(true)
showGameOverRank()
}
return return
} }
...@@ -343,7 +350,7 @@ const rankCloseHandler = () => { ...@@ -343,7 +350,7 @@ const rankCloseHandler = () => {
<div class="col-2"> <div class="col-2">
<div class="avatar" <div class="avatar"
:style="item.avatar ? { backgroundImage: `url(${item.avatar})` } : {}"></div> :style="item.avatar ? { backgroundImage: `url(${item.avatar})` } : {}"></div>
<div>{{ $format_str(item.nickname,12) }}</div> <div>{{ $format_str(item.nickname, 12) }}</div>
</div> </div>
<div class="col-3">{{ item.score }}</div> <div class="col-3">{{ item.score }}</div>
</div> </div>
...@@ -358,12 +365,12 @@ const rankCloseHandler = () => { ...@@ -358,12 +365,12 @@ const rankCloseHandler = () => {
</div> </div>
</div> </div>
<div class="img-close" @click="rankCloseHandler"></div> <div class="img-close" @click="rankCloseHandler"></div>
</div> </div>
</template> </template>
<LoadingView v-if="currentView === 'loading'" :image-urls="imageUrls" :user-join-status="userJoinStatus" <LoadingView v-if="currentView === 'loading'" :image-urls="imageUrls" :user-join-status="userJoinStatus"
@touchGameRule="showGameRuleHandler" /> @touchGameRule="showGameRuleHandler" />
<PlayingView v-else :image-urls="imageUrls" :tick="score" :rank="rank" :countdown-interval="countdownInterval" <PlayingView v-else :image-urls="imageUrls" :tick="score" :rank="rank" :countdown-interval="countdownInterval"
:is-div-desc-visible="isDivDescVisible" @touch="touchHandler" /> :is-div-desc-visible="isDivDescVisible" @touch="touchHandler" :userTop10RankStatus="userTop10RankStatus" />
</MobileStage> </MobileStage>
<div v-else style="text-align: center; width: 100vw; height: 100vh; line-height: 30; font-size: 20px;"> <div v-else style="text-align: center; width: 100vw; height: 100vh; line-height: 30; font-size: 20px;">
请使用微信扫码进入游戏 请使用微信扫码进入游戏
...@@ -399,7 +406,7 @@ const rankCloseHandler = () => { ...@@ -399,7 +406,7 @@ const rankCloseHandler = () => {
width: 57px; width: 57px;
height: 57px; height: 57px;
background: v-bind('imageUrls.close') center / cover no-repeat; background: v-bind('imageUrls.close') center / cover no-repeat;
transform: translateX(-50%) scale(1.5); transform: translateX(-50%) scale(1.5);
position: absolute; position: absolute;
top: -73px; top: -73px;
left: 100%; left: 100%;
......
...@@ -4,7 +4,7 @@ import { onMounted, ref } from 'vue'; ...@@ -4,7 +4,7 @@ import { onMounted, ref } from 'vue';
defineProps<{ defineProps<{
imageUrls: Record<string, string> imageUrls: Record<string, string>
userJoinStatus: boolean userJoinStatus: boolean,
}>(); }>();
const nickname = ref(''); const nickname = ref('');
const avatar = ref(''); const avatar = ref('');
......
...@@ -7,7 +7,7 @@ defineProps<{ ...@@ -7,7 +7,7 @@ defineProps<{
isDivDescVisible: boolean isDivDescVisible: boolean
tick: number tick: number
rank: number rank: number
// currentGu: string userTop10RankStatus:boolean
}>() }>()
const emit = defineEmits<{ const emit = defineEmits<{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment