From bb224c9f29c80ccaf9d072137c5922b441260684 Mon Sep 17 00:00:00 2001
From: zhangyibo95 <690096405@qq.com>
Date: Wed, 19 Aug 2026 14:04:12 +0800
Subject: [PATCH] =?UTF-8?q?update:=E8=AF=AD=E9=9F=B3=E4=BC=98=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/audioManager.js | 12 ++++
src/components/HeaderProgress.vue | 8 ++-
src/components/ShootProgress.vue | 8 ++-
src/components/TestDistance.vue | 21 +++---
src/matchWebsocket.js | 36 +++-------
src/pages/first-try.vue | 20 +++---
.../team-battle/components/TestDistance.vue | 21 +++---
src/pages/team-battle/index.vue | 8 ++-
.../training/components/ShootProgress.vue | 8 ++-
.../training/components/TestDistance.vue | 21 +++---
src/util.js | 68 ++++++++++++++++---
src/utils/match.min.js | 2 +-
src/utils/matchProtocol.js | 6 +-
13 files changed, 153 insertions(+), 86 deletions(-)
diff --git a/src/audioManager.js b/src/audioManager.js
index 6fb4882..8d742ed 100644
--- a/src/audioManager.js
+++ b/src/audioManager.js
@@ -20,6 +20,12 @@ export const audioFils = {
"https://static.shelingxingqiu.com/attachment/2025-09-17/dcutwrda0amn5kqr4j.mp3",
距离不足:
"https://static.shelingxingqiu.com/attachment/2025-11-12/de6hr2faw28t0ianh0.mp3",
+ "靶纸不符!请更换靶纸":
+ "https://static.shelingxingqiu.com/shootmini/static/audio/%E9%9D%B6%E7%BA%B8%E4%B8%8D%E7%AC%A6%EF%BC%81%E8%AF%B7%E6%9B%B4%E6%8D%A2%E9%9D%B6%E7%BA%B8.MP3",
+ "站距与靶纸合格":
+ "https://static.shelingxingqiu.com/shootmini/static/audio/%E7%AB%99%E8%B7%9D%E4%B8%8E%E9%9D%B6%E7%BA%B8%E5%90%88%E6%A0%BC.MP3",
+ "请射箭!测试站距与靶纸":
+ "https://static.shelingxingqiu.com/shootmini/static/audio/%E8%AF%B7%E5%B0%84%E7%AE%AD%EF%BC%81%E6%B5%8B%E8%AF%95%E7%AB%99%E8%B7%9D%E4%B8%8E%E9%9D%B6%E7%BA%B8.MP3",
"未发现靶纸,请瞄准靶纸射箭":
"https://static.shelingxingqiu.com/shootmini/static/audio/%E6%9C%AA%E5%8F%91%E7%8E%B0%E9%9D%B6%E7%BA%B8%EF%BC%8C%E8%AF%B7%E7%9E%84%E5%87%86%E9%9D%B6%E7%BA%B8%E5%B0%84%E7%AE%AD.MP3",
轮到你了:
@@ -54,6 +60,8 @@ export const audioFils = {
"https://static.shelingxingqiu.com/shootmini/static/audio/%E5%B0%84%E7%AE%AD%E6%97%A0%E6%95%88%E6%A3%80%E6%9F%A5%E8%B7%9D%E7%A6%BB%E5%92%8C%E9%9D%B6%E7%BA%B8.mp3",
"射箭无效,距离不足":
"https://static.shelingxingqiu.com/shootmini/static/audio/%E5%B0%84%E7%AE%AD%E6%97%A0%E6%95%88%EF%BC%8C%E8%B7%9D%E7%A6%BB%E4%B8%8D%E8%B6%B3.MP3",
+ "射箭无效,距离不足且靶纸错误":
+ "https://static.shelingxingqiu.com/shootmini/static/audio/%E5%B0%84%E7%AE%AD%E6%97%A0%E6%95%88%EF%BC%8C%E8%B7%9D%E7%A6%BB%E4%B8%8D%E8%B6%B3%E4%B8%94%E9%9D%B6%E7%BA%B8%E9%94%99%E8%AF%AF.MP3",
"射箭无效,未识别到靶纸":
"https://static.shelingxingqiu.com/shootmini/static/audio/%E5%B0%84%E7%AE%AD%E6%97%A0%E6%95%88%EF%BC%8C%E6%9C%AA%E8%AF%86%E5%88%AB%E5%88%B0%E9%9D%B6%E7%BA%B8.MP3",
"射箭无效,靶纸错误":
@@ -126,8 +134,12 @@ const AUDIO_WARM_PRIORITY_KEYS = [
"比赛结束",
"射击无效",
"射箭无效,距离不足",
+ "射箭无效,距离不足且靶纸错误",
"射箭无效,未识别到靶纸",
"射箭无效,靶纸错误",
+ "靶纸不符!请更换靶纸",
+ "站距与靶纸合格",
+ "请射箭!测试站距与靶纸",
"中场休息",
"下半场开始",
"决金箭轮",
diff --git a/src/components/HeaderProgress.vue b/src/components/HeaderProgress.vue
index b01472b..936d5bd 100644
--- a/src/components/HeaderProgress.vue
+++ b/src/components/HeaderProgress.vue
@@ -2,7 +2,11 @@
import { ref, watch, onMounted, onBeforeUnmount } from "vue";
import audioManager from "@/audioManager";
import { MESSAGETYPESV2 } from "@/constants";
-import { getDirectionText, getInvalidShotAudioKey } from "@/util";
+import {
+ getDirectionText,
+ getInvalidShotAudioKey,
+ getInvalidShotText,
+} from "@/util";
import useStore from "@/store";
import { storeToRefs } from "pinia";
@@ -88,7 +92,7 @@ async function onReceiveMessage(message) {
currentRoundEnded.value = true;
} else if (type === MESSAGETYPESV2.InvalidShot) {
uni.showToast({
- title: "距离不足,无效",
+ title: getInvalidShotText(shootData),
icon: "none",
});
audioManager.play(getInvalidShotAudioKey(shootData));
diff --git a/src/components/ShootProgress.vue b/src/components/ShootProgress.vue
index cd0912b..5e1fea3 100644
--- a/src/components/ShootProgress.vue
+++ b/src/components/ShootProgress.vue
@@ -2,7 +2,11 @@
import { ref, watch, onMounted, onBeforeUnmount, computed } from "vue";
import audioManager from "@/audioManager";
import { MESSAGETYPESV2 } from "@/constants";
-import { getDirectionText, getInvalidShotAudioKey } from "@/util";
+import {
+ getDirectionText,
+ getInvalidShotAudioKey,
+ getInvalidShotText,
+} from "@/util";
import useStore from "@/store";
import { storeToRefs } from "pinia";
@@ -171,7 +175,7 @@ async function onReceiveMessage(msg) {
audioManager.play("中场休息");
} else if (msg.type === MESSAGETYPESV2.InvalidShot) {
uni.showToast({
- title: "距离不足,无效",
+ title: getInvalidShotText(msg.shootData),
icon: "none",
});
audioManager.play(getInvalidShotAudioKey(msg.shootData));
diff --git a/src/components/TestDistance.vue b/src/components/TestDistance.vue
index fbbb91d..7beb4f2 100644
--- a/src/components/TestDistance.vue
+++ b/src/components/TestDistance.vue
@@ -6,6 +6,7 @@ import Avatar from "@/components/Avatar.vue";
import audioManager from "@/audioManager";
import { simulShootAPI } from "@/apis";
import { MESSAGETYPESV2 } from "@/constants";
+import { getDistanceCheckAudioKey, getDistanceCheckText } from "@/util";
import useStore from "@/store";
import { storeToRefs } from "pinia";
const store = useStore();
@@ -26,6 +27,7 @@ const props = defineProps({
});
const arrow = ref({});
const distance = ref(0);
+const statusText = ref("");
const showsimul = ref(false);
const count = ref(props.count);
const timer = ref(null);
@@ -34,7 +36,7 @@ const updateTimer = (value) => {
count.value = Math.round(value);
};
onMounted(() => {
- audioManager.play("请射箭测试距离");
+ audioManager.play("请射箭!测试站距与靶纸");
if (props.isBattle) {
timer.value = setInterval(() => {
count.value -= 1;
@@ -51,14 +53,12 @@ onBeforeUnmount(() => {
async function onReceiveMessage(msg) {
if (Array.isArray(msg)) return;
if (msg.type === MESSAGETYPESV2.TestDistance) {
- const rawDistance = Number(msg.shootData?.distance);
+ const rawDistance = Number(msg.shootData?.distance ?? msg.shootData?.dst);
distance.value = Number.isFinite(rawDistance)
? Number((rawDistance / 100).toFixed(2))
: 0;
- if (rawDistance === 0) {
- audioManager.play("未发现靶纸,请瞄准靶纸射箭");
- } else if (distance.value >= 5) audioManager.play("距离合格");
- else audioManager.play("距离不足");
+ statusText.value = getDistanceCheckText(msg.shootData);
+ audioManager.play(getDistanceCheckAudioKey(msg.shootData));
}
}
@@ -101,13 +101,12 @@ onBeforeUnmount(() => {
模拟射箭
-
- 当前距离{{ distance }}米
- 已达到距离要求
- 请调整站位
+
+ 当前距离{{ distance }}米
+ {{ statusText }}
- 请射箭,测试站距
+ 请射箭,测试站距与靶纸
diff --git a/src/matchWebsocket.js b/src/matchWebsocket.js
index 734a751..ab82d89 100644
--- a/src/matchWebsocket.js
+++ b/src/matchWebsocket.js
@@ -9,7 +9,11 @@ import {
getServerMessageTypeName,
} from "@/utils/matchProtocol";
import { MESSAGETYPESV2 } from "@/constants";
-import { getDirectionText, getInvalidShotAudioKey } from "@/util";
+import {
+ getDirectionText,
+ getDistanceCheckAudioKey,
+ getInvalidShotAudioKey,
+} from "@/util";
import {
normalizeId,
normalizeMatchInfo,
@@ -49,20 +53,6 @@ const ENABLE_REALTIME_MESSAGE_LOG = (() => {
}
})();
-function getServerMessageLogSummary(message = {}) {
- const practiceInfo = message.practice_info || message.practiceInfo || {};
- const matchInfo = message.match_info || message.matchInfo || {};
- return {
- type: message.type,
- matchId: normalizeId(pickField(message, "matchId", "match_id")),
- sequence: message.sequence,
- practiceDetailCount: Array.isArray(practiceInfo.details)
- ? practiceInfo.details.length
- : 0,
- roundCount: Array.isArray(matchInfo.rounds) ? matchInfo.rounds.length : 0,
- };
-}
-
// 比赛服消息类型先映射成项目里已有的 V2 业务消息,页面仍然复用原来的 socket-inbox 流程。
const BUSINESS_TYPE_BY_SERVER_TYPE = {
[ServerMessageType.SERVER_MSG_MATCH_READY]: MESSAGETYPESV2.AboutToStart,
@@ -87,6 +77,9 @@ function normalizeShootData(shootData) {
if (normalized.distance === undefined && normalized.dst !== undefined) {
normalized.distance = normalized.dst;
}
+ if (normalized.targetOk === undefined && normalized.target_ok !== undefined) {
+ normalized.targetOk = normalized.target_ok;
+ }
return normalized;
}
@@ -368,10 +361,8 @@ function getShootResultAudioKeys(shootData) {
}
function getTestDistanceAudioKeys(shootData) {
- const distance = Number(shootData?.distance ?? shootData?.dst);
- if (Number.isNaN(distance)) return [];
- if (distance === 0) return ["未发现靶纸,请瞄准靶纸射箭"];
- return [distance / 100 >= 5 ? "\u8ddd\u79bb\u5408\u683c" : "\u8ddd\u79bb\u4e0d\u8db3"];
+ if (!shootData) return [];
+ return [getDistanceCheckAudioKey(shootData)];
}
function getAckAudioKeys(message, businessMessage) {
@@ -805,13 +796,8 @@ function handleMessage(data) {
return;
}
- const typeName = getServerMessageTypeName(message.type);
if (ENABLE_REALTIME_MESSAGE_LOG) {
- console.log(
- "收到比赛服 WebSocket 消息",
- typeName,
- getServerMessageLogSummary(message)
- );
+ console.log("收到比赛服 WebSocket 消息", message);
}
const decodedMatchId = normalizeId(pickField(message, "matchId", "match_id"));
diff --git a/src/pages/first-try.vue b/src/pages/first-try.vue
index 89d8bd4..b767cb3 100644
--- a/src/pages/first-try.vue
+++ b/src/pages/first-try.vue
@@ -22,7 +22,12 @@ import {
} from "@/apis";
import { connectMatchWebSocket, closeMatchWebSocket } from "@/matchWebsocket";
import { sharePractiseData } from "@/canvas";
-import { wxShare, debounce } from "@/util";
+import {
+ wxShare,
+ debounce,
+ getDistanceCheckAudioKey,
+ getShootValidation,
+} from "@/util";
import { MESSAGETYPESV2 } from "@/constants";
import useStore from "@/store";
import { storeToRefs } from "pinia";
@@ -154,14 +159,11 @@ async function onReceiveMessage(msg) {
} else if (msg.type === MESSAGETYPESV2.BattleEnd) {
setTimeout(() => onOver(msg), 1500);
} else if (msg.type === MESSAGETYPESV2.TestDistance && step.value === 3) {
- const rawDistance = Number(msg.shootData?.distance);
- if (rawDistance === 0) {
- audioManager.play("未发现靶纸,请瞄准靶纸射箭");
- } else if (rawDistance / 100 >= 5) {
- audioManager.play("距离合格");
- btnDisabled.value = false;
- showGuide.value = true;
- } else audioManager.play("距离不足");
+ const result = getShootValidation(msg.shootData);
+ const isQualified = result.distanceOk && result.targetOk;
+ audioManager.play(getDistanceCheckAudioKey(msg.shootData));
+ btnDisabled.value = !isQualified;
+ showGuide.value = isQualified;
}
// messages.forEach((msg) => {
// if (msg.constructor === MESSAGETYPES.ShootSyncMeArrowID) {
diff --git a/src/pages/team-battle/components/TestDistance.vue b/src/pages/team-battle/components/TestDistance.vue
index 372ab92..cc932d1 100644
--- a/src/pages/team-battle/components/TestDistance.vue
+++ b/src/pages/team-battle/components/TestDistance.vue
@@ -6,6 +6,7 @@ import Avatar from "./Avatar.vue";
import audioManager from "@/audioManager";
import { simulShootAPI } from "@/apis";
import { MESSAGETYPESV2 } from "@/constants";
+import { getDistanceCheckAudioKey, getDistanceCheckText } from "@/util";
import useStore from "@/store";
import { storeToRefs } from "pinia";
const store = useStore();
@@ -26,6 +27,7 @@ const props = defineProps({
});
const arrow = ref({});
const distance = ref(0);
+const statusText = ref("");
const showsimul = ref(false);
const count = ref(props.count);
const timer = ref(null);
@@ -34,7 +36,7 @@ const updateTimer = (value) => {
count.value = Math.round(value);
};
onMounted(() => {
- audioManager.play("请射箭测试距离");
+ audioManager.play("请射箭!测试站距与靶纸");
if (props.isBattle) {
timer.value = setInterval(() => {
count.value -= 1;
@@ -51,14 +53,12 @@ onBeforeUnmount(() => {
async function onReceiveMessage(msg) {
if (Array.isArray(msg)) return;
if (msg.type === MESSAGETYPESV2.TestDistance) {
- const rawDistance = Number(msg.shootData?.distance);
+ const rawDistance = Number(msg.shootData?.distance ?? msg.shootData?.dst);
distance.value = Number.isFinite(rawDistance)
? Number((rawDistance / 100).toFixed(2))
: 0;
- if (rawDistance === 0) {
- audioManager.play("未发现靶纸,请瞄准靶纸射箭");
- } else if (distance.value >= 5) audioManager.play("距离合格");
- else audioManager.play("距离不足");
+ statusText.value = getDistanceCheckText(msg.shootData);
+ audioManager.play(getDistanceCheckAudioKey(msg.shootData));
}
}
@@ -101,13 +101,12 @@ onBeforeUnmount(() => {
模拟射箭
-
- 当前距离{{ distance }}米
- 已达到距离要求
- 请调整站位
+
+ 当前距离{{ distance }}米
+ {{ statusText }}
- 请射箭,测试站距
+ 请射箭,测试站距与靶纸
diff --git a/src/pages/team-battle/index.vue b/src/pages/team-battle/index.vue
index 239cad1..c1580f4 100644
--- a/src/pages/team-battle/index.vue
+++ b/src/pages/team-battle/index.vue
@@ -20,7 +20,11 @@ import {
MATCH_WS_STATE_EVENT,
} from "@/matchWebsocket";
import { MESSAGETYPESV2 } from "@/constants";
-import { getDirectionText, getInvalidShotAudioKey } from "@/util";
+import {
+ getDirectionText,
+ getInvalidShotAudioKey,
+ getInvalidShotText,
+} from "@/util";
import { takeMatchReturnSnapshot } from "@/utils/matchReturn";
import audioManager, {
AUDIO_INTERRUPTION_BEGIN_EVENT,
@@ -1133,7 +1137,7 @@ async function runBattleEndTask(task, runId) {
async function runInvalidShotTask(task, runId) {
if (!isQueueAlive(runId)) return;
uni.showToast({
- title: "距离不足,无效",
+ title: getInvalidShotText(task.message?.shootData),
icon: "none",
});
await playAudioKeys(getInvalidShotAudioKey(task.message?.shootData), {
diff --git a/src/pages/training/components/ShootProgress.vue b/src/pages/training/components/ShootProgress.vue
index 7de4571..abf442d 100644
--- a/src/pages/training/components/ShootProgress.vue
+++ b/src/pages/training/components/ShootProgress.vue
@@ -2,7 +2,11 @@
import { ref, watch, onMounted, onBeforeUnmount, computed } from "vue";
import audioManager from "@/audioManager";
import { MESSAGETYPESV2 } from "@/constants";
-import { getDirectionText, getInvalidShotAudioKey } from "@/util";
+import {
+ getDirectionText,
+ getInvalidShotAudioKey,
+ getInvalidShotText,
+} from "@/util";
import Avatar from "@/components/Avatar.vue";
import useStore from "@/store";
@@ -238,7 +242,7 @@ async function onReceiveMessage(msg) {
audioManager.play("中场休息");
} else if (msg.type === MESSAGETYPESV2.InvalidShot) {
uni.showToast({
- title: "距离不足,无效",
+ title: getInvalidShotText(msg.shootData),
icon: "none",
});
audioManager.play(getInvalidShotAudioKey(msg.shootData));
diff --git a/src/pages/training/components/TestDistance.vue b/src/pages/training/components/TestDistance.vue
index 75e893b..791e621 100644
--- a/src/pages/training/components/TestDistance.vue
+++ b/src/pages/training/components/TestDistance.vue
@@ -6,6 +6,7 @@ import Avatar from "@/components/Avatar.vue";
import audioManager from "@/audioManager";
import { simulShootAPI } from "@/apis";
import { MESSAGETYPESV2 } from "@/constants";
+import { getDistanceCheckAudioKey, getDistanceCheckText } from "@/util";
import useStore from "@/store";
import { storeToRefs } from "pinia";
const store = useStore();
@@ -30,6 +31,7 @@ const props = defineProps({
});
const arrow = ref({});
const distance = ref(0);
+const statusText = ref("");
const showsimul = ref(false);
const count = ref(props.count);
const timer = ref(null);
@@ -38,7 +40,7 @@ const updateTimer = (value) => {
count.value = Math.round(value);
};
onMounted(() => {
- audioManager.play("请射箭测试距离");
+ audioManager.play("请射箭!测试站距与靶纸");
if (props.isBattle) {
timer.value = setInterval(() => {
count.value -= 1;
@@ -55,14 +57,12 @@ onBeforeUnmount(() => {
async function onReceiveMessage(msg) {
if (Array.isArray(msg)) return;
if (msg.type === MESSAGETYPESV2.TestDistance) {
- const rawDistance = Number(msg.shootData?.distance);
+ const rawDistance = Number(msg.shootData?.distance ?? msg.shootData?.dst);
distance.value = Number.isFinite(rawDistance)
? Number((rawDistance / 100).toFixed(2))
: 0;
- if (rawDistance === 0) {
- audioManager.play("未发现靶纸,请瞄准靶纸射箭");
- } else if (distance.value >= 5) audioManager.play("距离合格");
- else audioManager.play("距离不足");
+ statusText.value = getDistanceCheckText(msg.shootData);
+ audioManager.play(getDistanceCheckAudioKey(msg.shootData));
}
}
@@ -100,13 +100,12 @@ onBeforeUnmount(() => {
当前靶纸为{{ targetType }}cm全环靶
-
- 当前距离{{ distance }}米
- 已达到距离要求
- 请调整站位
+
+ 当前距离{{ distance }}米
+ {{ statusText }}
- 请射箭,测试站距
+ 请射箭,测试站距与靶纸
diff --git a/src/util.js b/src/util.js
index 0de566a..c703cf7 100644
--- a/src/util.js
+++ b/src/util.js
@@ -329,18 +329,70 @@ export const getDirectionText = (angle = 0) => {
}
};
-// 正式射箭阶段的距离单位为厘米,按距离异常类型选择对应语音。
-export const getInvalidShotAudioKey = (shootData) => {
- if (!shootData || typeof shootData !== "object") return "射击无效";
- // protobuf 会省略值为 0 的标量字段;消息体存在且距离缺失时按 0 处理。
+// 射箭数据中的距离单位为厘米;旧版本会明确上报 target_ok=true。
+export const getShootValidation = (shootData) => {
+ if (!shootData || typeof shootData !== "object") {
+ return {
+ rawDistance: 0,
+ distance: 0,
+ distanceOk: false,
+ targetOk: false,
+ targetDetected: false,
+ };
+ }
+
const rawDistance = Number(shootData.distance ?? shootData.dst ?? 0);
- if (!Number.isFinite(rawDistance)) return "射击无效";
- if (rawDistance < 0) return "射箭无效,靶纸错误";
- if (rawDistance === 0) return "射箭无效,未识别到靶纸";
- if (rawDistance / 100 < 5) return "射箭无效,距离不足";
+ const finiteDistance = Number.isFinite(rawDistance) ? rawDistance : 0;
+ const targetFlag = shootData.targetOk ?? shootData.target_ok;
+ const targetDetected = finiteDistance !== 0;
+ const targetOk = finiteDistance > 0 && targetFlag === true;
+
+ return {
+ rawDistance: finiteDistance,
+ distance: Math.max(0, finiteDistance / 100),
+ // 旧固件以负距离表示靶纸错误,此时只提示靶纸问题,不叠加距离不足。
+ distanceOk: finiteDistance < 0 || finiteDistance >= 500,
+ targetOk: targetDetected && targetOk,
+ targetDetected,
+ };
+};
+
+// 测距阶段提示音:同时校验站距和靶纸,保留旧版本距离不足音频。
+export const getDistanceCheckAudioKey = (shootData) => {
+ const result = getShootValidation(shootData);
+ if (!result.targetDetected) return "未发现靶纸,请瞄准靶纸射箭";
+ if (!result.distanceOk && !result.targetOk) {
+ return "射箭无效,距离不足且靶纸错误";
+ }
+ if (!result.targetOk) return "靶纸不符!请更换靶纸";
+ if (result.distanceOk) return "站距与靶纸合格";
+ return "距离不足";
+};
+
+export const getDistanceCheckText = (shootData) => {
+ const result = getShootValidation(shootData);
+ if (!result.targetDetected) return "未识别到靶纸,请瞄准靶纸射箭";
+ if (result.rawDistance < 0) return "靶纸错误";
+ return `${result.distanceOk ? "站距合格" : "站距过近"},${
+ result.targetOk ? "靶纸正确" : "靶纸错误"
+ }`;
+};
+
+// 正式射箭阶段的距离和靶纸异常类型选择对应语音。
+export const getInvalidShotAudioKey = (shootData) => {
+ const result = getShootValidation(shootData);
+ if (!result.targetDetected) return "射箭无效,未识别到靶纸";
+ if (!result.distanceOk && !result.targetOk) {
+ return "射箭无效,距离不足且靶纸错误";
+ }
+ if (!result.targetOk) return "射箭无效,靶纸错误";
+ if (!result.distanceOk) return "射箭无效,距离不足";
return "射击无效";
};
+export const getInvalidShotText = (shootData) =>
+ getInvalidShotAudioKey(shootData);
+
export const wxLogin = () => {
return new Promise((resolve, reject) => {
uni.login({
diff --git a/src/utils/match.min.js b/src/utils/match.min.js
index 87f6493..b0a391e 100644
--- a/src/utils/match.min.js
+++ b/src/utils/match.min.js
@@ -1,4 +1,4 @@
/* eslint-disable */
import * as $protobuf from "protobufjs";
-const $root=$protobuf.Root.create({"nested":{"rpc":{"ServerMessageType":{"SERVER_MSG_UNKNOWN":0,"SERVER_MSG_MATCH_READY":1,"SERVER_MSG_MATCH_START":2,"SERVER_MSG_NOW_YOU":3,"SERVER_MSG_SHOT":4,"SERVER_MSG_NEW_ROUND":5,"SERVER_MSG_MATCH_END":6,"SERVER_MSG_TIMEOUT":7,"SERVER_MSG_CHECK":8,"SERVER_MSG_RAND":9,"SERVER_MSG_NOT_ENOUGH_DISTANCE":10,"SERVER_MSG_PLAYER_LEFT":11,"SERVER_MSG_HEARTBEAT":12,"SERVER_MSG_PRACTICE_END":13,"SERVER_MSG_SYNC_PRACTICE_INFO":14,"SERVER_MSG_SYNC_MATCH_INFO":15},"ClientMessageType":{"CLIENT_MSG_UNKNOWN":0,"CLIENT_MSG_HEARTBEAT_ACK":1,"CLIENT_MSG_SHOOT_DATA":2,"CLIENT_MSG_ACK":3,"CLIENT_MSG_LEAVE":4,"CLIENT_MSG_SYNC_PRACTICE_INFO":5,"CLIENT_MSG_SYNC_MATCH_INFO":6},"MatchStatus":{"MATCH_STATUS_READY":0,"MATCH_STATUS_STARTED":1,"MATCH_STATUS_END":2,"MATCH_STATUS_TIMEOUT":3,"MATCH_STATUS_UNEXPECTEDLY":4},"MatchPlayerStatus":{"MATCH_PLAYER_STATUS_READY":0,"MATCH_PLAYER_STATUS_STARTED":1,"MATCH_PLAYER_STATUS_END":2},"MatchShoot":{"fields":{"player_id":{"type":"int64","id":1},"status":{"type":"int32","id":2},"x":{"type":"float","id":3},"y":{"type":"float","id":4},"ring":{"type":"int32","id":5},"ring_x":{"type":"bool","id":6},"angle":{"type":"float","id":7},"distance":{"type":"float","id":8},"three_consecutive_10_rings":{"type":"bool","id":9},"ok":{"type":"bool","id":10}}},"MatchShootList":{"fields":{"items":{"type":"MatchShoot","id":1,"rule":"repeated"}}},"RoundScore":{"fields":{"total_ring":{"type":"int32","id":1},"score":{"type":"int32","id":2},"if_win":{"type":"bool","id":3}}},"MatchRound":{"fields":{"shoots":{"type":"MatchShootList","id":1,"keytype":"int64"},"scores":{"type":"RoundScore","id":2,"keytype":"int32"},"round":{"type":"int32","id":3},"if_gold":{"type":"bool","id":4},"status":{"type":"int32","id":5},"gold_round":{"type":"int32","id":6}}},"PlayerMatchResult":{"fields":{"total_ring":{"type":"int32","id":1},"user_id":{"type":"int64","id":2},"ten_ring_count":{"type":"int32","id":3},"average_ring":{"type":"float","id":4}}},"PlayerFull":{"fields":{"id":{"type":"int64","id":1},"name":{"type":"string","id":2},"avatar":{"type":"string","id":3},"exp":{"type":"int32","id":4},"score":{"type":"int32","id":5},"level":{"type":"int32","id":6},"before_level":{"type":"int32","id":7},"before_exp":{"type":"int32","id":8},"current_exp":{"type":"int32","id":9},"upgrade_exp":{"type":"int32","id":10},"active":{"type":"int32","id":11},"device_id":{"type":"string","id":12},"s_vip":{"type":"bool","id":13},"vip":{"type":"bool","id":14},"player_match_result":{"type":"PlayerMatchResult","id":15},"rank_lvl":{"type":"int32","id":16},"rank_name":{"type":"string","id":17},"rank_icon":{"type":"string","id":18}}},"TeamInfo":{"fields":{"players":{"type":"PlayerFull","id":1,"rule":"repeated"},"id":{"type":"int32","id":2},"name":{"type":"string","id":3},"score":{"type":"int32","id":4}}},"CurrentShoot":{"fields":{"round":{"type":"int32","id":1},"round_id":{"type":"int64","id":2},"index":{"type":"int32","id":3},"start_time":{"type":"int64","id":4},"player_id":{"type":"int64","id":5},"gold_round":{"type":"bool","id":6},"start_time_text":{"type":"string","id":7},"my_index":{"type":"int32","id":8},"index_map":{"type":"int32","id":9,"keytype":"int64"},"ack_time":{"type":"int64","id":10}}},"ShootData":{"fields":{"x":{"type":"float","id":1},"y":{"type":"float","id":2},"r":{"type":"float","id":3},"dst":{"type":"float","id":4},"m":{"type":"string","id":5},"adc":{"type":"float","id":6},"device_id":{"type":"string","id":7},"shoot_id":{"type":"string","id":8},"three_consecutive_10_rings":{"type":"bool","id":9}}},"PracticeInfo":{"fields":{"id":{"type":"int64","id":1},"user_id":{"type":"int64","id":2},"status":{"type":"int32","id":3},"status_text":{"type":"string","id":4},"start_time":{"type":"int64","id":5},"target_type":{"type":"int32","id":6},"vip":{"type":"bool","id":7},"s_vip":{"type":"bool","id":8},"device_id":{"type":"string","id":9},"shoot_data":{"type":"MatchShoot","id":10},"details":{"type":"MatchShoot","id":11,"rule":"repeated"},"training_type":{"type":"string","id":12},"difficulty_level":{"type":"int32","id":13},"hit_req":{"type":"int32","id":14},"arrows_left":{"type":"int32","id":15},"target_arrows":{"type":"int32","id":16},"target_rings":{"type":"int32","id":17},"current_arrows":{"type":"int32","id":18},"current_rings":{"type":"int32","id":19},"blocks":{"type":"int32","id":20},"random_block":{"type":"int32","id":21},"random_ring_area":{"type":"int32","id":22},"score_slot":{"type":"int32","id":44},"current_energy":{"type":"int32","id":45},"energy_cost_per_sec":{"type":"int32","id":46},"energy_per_hit":{"type":"int32","id":47},"energy_req_percent":{"type":"int32","id":48},"round_time":{"type":"int32","id":50},"shoot_time":{"type":"int32","id":53},"shoot_window_start":{"type":"int64","id":51},"in_shoot_window":{"type":"bool","id":52},"time_limit":{"type":"int32","id":23},"completed":{"type":"bool","id":24},"total_arrows":{"type":"int32","id":25},"duration":{"type":"int32","id":26},"average_ring":{"type":"float","id":27},"stability":{"type":"float","id":28},"max_combo":{"type":"int32","id":29},"total_hits":{"type":"int32","id":30},"delta_total_hits":{"type":"int32","id":31},"delta_duration":{"type":"int32","id":32},"delta_max_combo":{"type":"int32","id":33},"delta_total_rings":{"type":"int32","id":34},"delta_total_arrows":{"type":"int32","id":35},"delta_average_ring":{"type":"float","id":36},"delta_stability":{"type":"float","id":37},"delta_current_energy":{"type":"int32","id":49},"before_exp":{"type":"int32","id":38},"before_level":{"type":"int32","id":39},"current_exp":{"type":"int32","id":40},"level":{"type":"int32","id":41},"upgrade_exp":{"type":"int32","id":42},"calories":{"type":"double","id":43}}},"MatchInfo":{"fields":{"match_id":{"type":"string","id":1},"create_time":{"type":"int64","id":2},"start_time":{"type":"int64","id":3},"server_time":{"type":"int64","id":4},"shoot_time":{"type":"int32","id":5},"shoot_number":{"type":"int32","id":6},"ready_time":{"type":"int32","id":7},"way":{"type":"int32","id":8},"mode":{"type":"int32","id":9},"status":{"type":"MatchStatus","id":10},"status_text":{"type":"string","id":11},"rounds":{"type":"MatchRound","id":12,"rule":"repeated"},"teams":{"type":"TeamInfo","id":13,"keytype":"int32"},"current":{"type":"CurrentShoot","id":14},"next":{"type":"CurrentShoot","id":15},"shoot_data":{"type":"MatchShoot","id":16},"win_team":{"type":"int32","id":17},"mvp":{"type":"PlayerFull","id":18},"room_id":{"type":"string","id":19},"result_list":{"type":"PlayerMatchResult","id":20,"rule":"repeated"},"timeout_time":{"type":"int64","id":21},"target_type":{"type":"int32","id":22},"event_type":{"type":"int32","id":23},"timeout":{"type":"int32","id":24},"server_addr":{"type":"string","id":25},"countdown_start_time":{"type":"int64","id":26}}},"ServerMessage":{"fields":{"type":{"type":"ServerMessageType","id":1},"match_id":{"type":"string","id":2},"timestamp":{"type":"int64","id":3},"match_info":{"type":"MatchInfo","id":4},"shoot_data":{"type":"ShootData","id":5},"practice_info":{"type":"PracticeInfo","id":6},"sequence":{"type":"int64","id":7}}},"ClientMessage":{"fields":{"type":{"type":"ClientMessageType","id":1},"match_id":{"type":"string","id":2},"user_id":{"type":"int64","id":3},"sequence":{"type":"int64","id":4},"data":{"type":"bytes","id":5}}}}}});
+const $root=$protobuf.Root.create({"nested":{"rpc":{"ServerMessageType":{"SERVER_MSG_UNKNOWN":0,"SERVER_MSG_MATCH_READY":1,"SERVER_MSG_MATCH_START":2,"SERVER_MSG_NOW_YOU":3,"SERVER_MSG_SHOT":4,"SERVER_MSG_NEW_ROUND":5,"SERVER_MSG_MATCH_END":6,"SERVER_MSG_TIMEOUT":7,"SERVER_MSG_CHECK":8,"SERVER_MSG_RAND":9,"SERVER_MSG_NOT_ENOUGH_DISTANCE":10,"SERVER_MSG_PLAYER_LEFT":11,"SERVER_MSG_HEARTBEAT":12,"SERVER_MSG_PRACTICE_END":13,"SERVER_MSG_SYNC_PRACTICE_INFO":14,"SERVER_MSG_SYNC_MATCH_INFO":15},"ClientMessageType":{"CLIENT_MSG_UNKNOWN":0,"CLIENT_MSG_HEARTBEAT_ACK":1,"CLIENT_MSG_SHOOT_DATA":2,"CLIENT_MSG_ACK":3,"CLIENT_MSG_LEAVE":4,"CLIENT_MSG_SYNC_PRACTICE_INFO":5,"CLIENT_MSG_SYNC_MATCH_INFO":6},"MatchStatus":{"MATCH_STATUS_READY":0,"MATCH_STATUS_STARTED":1,"MATCH_STATUS_END":2,"MATCH_STATUS_TIMEOUT":3,"MATCH_STATUS_UNEXPECTEDLY":4},"MatchPlayerStatus":{"MATCH_PLAYER_STATUS_READY":0,"MATCH_PLAYER_STATUS_STARTED":1,"MATCH_PLAYER_STATUS_END":2},"MatchShoot":{"fields":{"player_id":{"type":"int64","id":1},"status":{"type":"int32","id":2},"x":{"type":"float","id":3},"y":{"type":"float","id":4},"ring":{"type":"int32","id":5},"ring_x":{"type":"bool","id":6},"angle":{"type":"float","id":7},"distance":{"type":"float","id":8},"three_consecutive_10_rings":{"type":"bool","id":9},"ok":{"type":"bool","id":10},"target_ok":{"type":"bool","id":11}}},"MatchShootList":{"fields":{"items":{"type":"MatchShoot","id":1,"rule":"repeated"}}},"RoundScore":{"fields":{"total_ring":{"type":"int32","id":1},"score":{"type":"int32","id":2},"if_win":{"type":"bool","id":3}}},"MatchRound":{"fields":{"shoots":{"type":"MatchShootList","id":1,"keytype":"int64"},"scores":{"type":"RoundScore","id":2,"keytype":"int32"},"round":{"type":"int32","id":3},"if_gold":{"type":"bool","id":4},"status":{"type":"int32","id":5},"gold_round":{"type":"int32","id":6}}},"PlayerMatchResult":{"fields":{"total_ring":{"type":"int32","id":1},"user_id":{"type":"int64","id":2},"ten_ring_count":{"type":"int32","id":3},"average_ring":{"type":"float","id":4}}},"PlayerFull":{"fields":{"id":{"type":"int64","id":1},"name":{"type":"string","id":2},"avatar":{"type":"string","id":3},"exp":{"type":"int32","id":4},"score":{"type":"int32","id":5},"level":{"type":"int32","id":6},"before_level":{"type":"int32","id":7},"before_exp":{"type":"int32","id":8},"current_exp":{"type":"int32","id":9},"upgrade_exp":{"type":"int32","id":10},"active":{"type":"int32","id":11},"device_id":{"type":"string","id":12},"s_vip":{"type":"bool","id":13},"vip":{"type":"bool","id":14},"player_match_result":{"type":"PlayerMatchResult","id":15},"rank_lvl":{"type":"int32","id":16},"rank_name":{"type":"string","id":17},"rank_icon":{"type":"string","id":18}}},"TeamInfo":{"fields":{"players":{"type":"PlayerFull","id":1,"rule":"repeated"},"id":{"type":"int32","id":2},"name":{"type":"string","id":3},"score":{"type":"int32","id":4}}},"CurrentShoot":{"fields":{"round":{"type":"int32","id":1},"round_id":{"type":"int64","id":2},"index":{"type":"int32","id":3},"start_time":{"type":"int64","id":4},"player_id":{"type":"int64","id":5},"gold_round":{"type":"bool","id":6},"start_time_text":{"type":"string","id":7},"my_index":{"type":"int32","id":8},"index_map":{"type":"int32","id":9,"keytype":"int64"},"ack_time":{"type":"int64","id":10}}},"ShootData":{"fields":{"x":{"type":"float","id":1},"y":{"type":"float","id":2},"r":{"type":"float","id":3},"dst":{"type":"float","id":4},"m":{"type":"string","id":5},"adc":{"type":"float","id":6},"device_id":{"type":"string","id":7},"shoot_id":{"type":"string","id":8},"three_consecutive_10_rings":{"type":"bool","id":9},"target_ok":{"type":"bool","id":10}}},"PracticeInfo":{"fields":{"id":{"type":"int64","id":1},"user_id":{"type":"int64","id":2},"status":{"type":"int32","id":3},"status_text":{"type":"string","id":4},"start_time":{"type":"int64","id":5},"target_type":{"type":"int32","id":6},"vip":{"type":"bool","id":7},"s_vip":{"type":"bool","id":8},"device_id":{"type":"string","id":9},"shoot_data":{"type":"MatchShoot","id":10},"details":{"type":"MatchShoot","id":11,"rule":"repeated"},"training_type":{"type":"string","id":12},"difficulty_level":{"type":"int32","id":13},"hit_req":{"type":"int32","id":14},"arrows_left":{"type":"int32","id":15},"target_arrows":{"type":"int32","id":16},"target_rings":{"type":"int32","id":17},"current_arrows":{"type":"int32","id":18},"current_rings":{"type":"int32","id":19},"blocks":{"type":"int32","id":20},"random_block":{"type":"int32","id":21},"random_ring_area":{"type":"int32","id":22},"score_slot":{"type":"int32","id":44},"current_energy":{"type":"int32","id":45},"energy_cost_per_sec":{"type":"int32","id":46},"energy_per_hit":{"type":"int32","id":47},"energy_req_percent":{"type":"int32","id":48},"round_time":{"type":"int32","id":50},"shoot_time":{"type":"int32","id":53},"shoot_window_start":{"type":"int64","id":51},"in_shoot_window":{"type":"bool","id":52},"time_limit":{"type":"int32","id":23},"completed":{"type":"bool","id":24},"total_arrows":{"type":"int32","id":25},"duration":{"type":"int32","id":26},"average_ring":{"type":"float","id":27},"stability":{"type":"float","id":28},"max_combo":{"type":"int32","id":29},"total_hits":{"type":"int32","id":30},"delta_total_hits":{"type":"int32","id":31},"delta_duration":{"type":"int32","id":32},"delta_max_combo":{"type":"int32","id":33},"delta_total_rings":{"type":"int32","id":34},"delta_total_arrows":{"type":"int32","id":35},"delta_average_ring":{"type":"float","id":36},"delta_stability":{"type":"float","id":37},"delta_current_energy":{"type":"int32","id":49},"before_exp":{"type":"int32","id":38},"before_level":{"type":"int32","id":39},"current_exp":{"type":"int32","id":40},"level":{"type":"int32","id":41},"upgrade_exp":{"type":"int32","id":42},"calories":{"type":"double","id":43}}},"MatchInfo":{"fields":{"match_id":{"type":"string","id":1},"create_time":{"type":"int64","id":2},"start_time":{"type":"int64","id":3},"server_time":{"type":"int64","id":4},"shoot_time":{"type":"int32","id":5},"shoot_number":{"type":"int32","id":6},"ready_time":{"type":"int32","id":7},"way":{"type":"int32","id":8},"mode":{"type":"int32","id":9},"status":{"type":"MatchStatus","id":10},"status_text":{"type":"string","id":11},"rounds":{"type":"MatchRound","id":12,"rule":"repeated"},"teams":{"type":"TeamInfo","id":13,"keytype":"int32"},"current":{"type":"CurrentShoot","id":14},"next":{"type":"CurrentShoot","id":15},"shoot_data":{"type":"MatchShoot","id":16},"win_team":{"type":"int32","id":17},"mvp":{"type":"PlayerFull","id":18},"room_id":{"type":"string","id":19},"result_list":{"type":"PlayerMatchResult","id":20,"rule":"repeated"},"timeout_time":{"type":"int64","id":21},"target_type":{"type":"int32","id":22},"event_type":{"type":"int32","id":23},"timeout":{"type":"int32","id":24},"server_addr":{"type":"string","id":25},"countdown_start_time":{"type":"int64","id":26}}},"ServerMessage":{"fields":{"type":{"type":"ServerMessageType","id":1},"match_id":{"type":"string","id":2},"timestamp":{"type":"int64","id":3},"match_info":{"type":"MatchInfo","id":4},"shoot_data":{"type":"ShootData","id":5},"practice_info":{"type":"PracticeInfo","id":6},"sequence":{"type":"int64","id":7}}},"ClientMessage":{"fields":{"type":{"type":"ClientMessageType","id":1},"match_id":{"type":"string","id":2},"user_id":{"type":"int64","id":3},"sequence":{"type":"int64","id":4},"data":{"type":"bytes","id":5}}}}}});
export default $root;
diff --git a/src/utils/matchProtocol.js b/src/utils/matchProtocol.js
index 68fadfb..1b36c67 100644
--- a/src/utils/matchProtocol.js
+++ b/src/utils/matchProtocol.js
@@ -7,8 +7,8 @@ const { Reader, Writer } = protobuf;
// 所以这里使用 minimal Reader/Writer 做静态字段解码和客户端消息编码。
//
// 此区块由 scripts/generate-match-schema.mjs 自动生成,请勿手动修改。
-// 来源:src/utils/match.min.js(sha256: 150812589c2e6f7a)
-// 协议命名空间:rpc;消息数:12;字段数:151
+// 来源:src/utils/match.min.js(sha256: a7ab92ae43e405e7)
+// 协议命名空间:rpc;消息数:12;字段数:153
export const ServerMessageType = {
SERVER_MSG_UNKNOWN: 0,
@@ -51,6 +51,7 @@ const SCHEMAS = {
8: { name: "distance", kind: "float" },
9: { name: "three_consecutive_10_rings", kind: "bool" },
10: { name: "ok", kind: "bool" },
+ 11: { name: "target_ok", kind: "bool" },
},
MatchShootList: {
1: { name: "items", kind: "message", type: "MatchShoot", repeated: true },
@@ -139,6 +140,7 @@ const SCHEMAS = {
7: { name: "device_id", kind: "string" },
8: { name: "shoot_id", kind: "string" },
9: { name: "three_consecutive_10_rings", kind: "bool" },
+ 10: { name: "target_ok", kind: "bool" },
},
PracticeInfo: {
1: { name: "id", kind: "int64" },