update:新版本websocket
This commit is contained in:
+4
-4
@@ -8,8 +8,8 @@ try {
|
|||||||
|
|
||||||
switch (envVersion) {
|
switch (envVersion) {
|
||||||
case "develop": // 开发版
|
case "develop": // 开发版
|
||||||
BASE_URL = "http://192.168.1.2:8000/api/shoot";
|
// BASE_URL = "http://192.168.1.2:8000/api/shoot";
|
||||||
// BASE_URL = "https://apitest.shelingxingqiu.com/api/shoot";
|
BASE_URL = "https://apitest.shelingxingqiu.com/api/shoot";
|
||||||
break;
|
break;
|
||||||
case "trial": // 体验版
|
case "trial": // 体验版
|
||||||
BASE_URL = "https://apitest.shelingxingqiu.com/api/shoot";
|
BASE_URL = "https://apitest.shelingxingqiu.com/api/shoot";
|
||||||
@@ -277,8 +277,8 @@ export const startPractiseAPI = (id) => {
|
|||||||
return request("POST", "/user/practice/begin", { id });
|
return request("POST", "/user/practice/begin", { id });
|
||||||
};
|
};
|
||||||
|
|
||||||
export const endPractiseAPI = () => {
|
export const endPractiseAPI = (id) => {
|
||||||
return request("POST", "/user/practice/stop");
|
return request("POST", "/user/practice/stop", { id });
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getPractiseAPI = async (id) => {
|
export const getPractiseAPI = async (id) => {
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ async function onReceiveMessage(msg) {
|
|||||||
if (msg.details && Array.isArray(msg.details)) {
|
if (msg.details && Array.isArray(msg.details)) {
|
||||||
arrow = msg.details[msg.details.length - 1];
|
arrow = msg.details[msg.details.length - 1];
|
||||||
} else {
|
} else {
|
||||||
if (msg.shootData.playerId !== user.value.id) return;
|
if (!msg.shootData || String(msg.shootData.playerId) !== String(user.value.id)) return;
|
||||||
if (msg.shootData) arrow = msg.shootData;
|
if (msg.shootData) arrow = msg.shootData;
|
||||||
}
|
}
|
||||||
let key = [];
|
let key = [];
|
||||||
|
|||||||
+93
-8
@@ -30,6 +30,7 @@ const pendingAcks = [];
|
|||||||
const ACK_AUDIO_TIMEOUT_MS = 9000;
|
const ACK_AUDIO_TIMEOUT_MS = 9000;
|
||||||
const READY_ROUTE_FALLBACK_DELAY_MS = 300;
|
const READY_ROUTE_FALLBACK_DELAY_MS = 300;
|
||||||
const ROUND_AUDIO_NAMES = ["一", "二", "三", "四", "五"];
|
const ROUND_AUDIO_NAMES = ["一", "二", "三", "四", "五"];
|
||||||
|
const MATCH_STATUS_HALF_REST = 3;
|
||||||
|
|
||||||
// 比赛服消息类型先映射成项目里已有的 V2 业务消息,页面仍然复用原来的 socket-inbox 流程。
|
// 比赛服消息类型先映射成项目里已有的 V2 业务消息,页面仍然复用原来的 socket-inbox 流程。
|
||||||
const BUSINESS_TYPE_BY_SERVER_TYPE = {
|
const BUSINESS_TYPE_BY_SERVER_TYPE = {
|
||||||
@@ -39,7 +40,6 @@ const BUSINESS_TYPE_BY_SERVER_TYPE = {
|
|||||||
[ServerMessageType.SERVER_MSG_SHOT]: MESSAGETYPESV2.ShootResult,
|
[ServerMessageType.SERVER_MSG_SHOT]: MESSAGETYPESV2.ShootResult,
|
||||||
[ServerMessageType.SERVER_MSG_NEW_ROUND]: MESSAGETYPESV2.NewRound,
|
[ServerMessageType.SERVER_MSG_NEW_ROUND]: MESSAGETYPESV2.NewRound,
|
||||||
[ServerMessageType.SERVER_MSG_MATCH_END]: MESSAGETYPESV2.BattleEnd,
|
[ServerMessageType.SERVER_MSG_MATCH_END]: MESSAGETYPESV2.BattleEnd,
|
||||||
[ServerMessageType.SERVER_MSG_TIMEOUT]: MESSAGETYPESV2.BattleEnd,
|
|
||||||
[ServerMessageType.SERVER_MSG_CHECK]: MESSAGETYPESV2.TestDistance,
|
[ServerMessageType.SERVER_MSG_CHECK]: MESSAGETYPESV2.TestDistance,
|
||||||
[ServerMessageType.SERVER_MSG_NOT_ENOUGH_DISTANCE]: MESSAGETYPESV2.InvalidShot,
|
[ServerMessageType.SERVER_MSG_NOT_ENOUGH_DISTANCE]: MESSAGETYPESV2.InvalidShot,
|
||||||
[ServerMessageType.SERVER_MSG_PRACTICE_END]: MESSAGETYPESV2.BattleEnd,
|
[ServerMessageType.SERVER_MSG_PRACTICE_END]: MESSAGETYPESV2.BattleEnd,
|
||||||
@@ -76,12 +76,73 @@ function normalizePracticeInfo(practiceInfo = {}) {
|
|||||||
return normalized;
|
return normalized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getCurrentMode(message = {}, normalizedInfo = {}) {
|
||||||
|
const mode = Number(
|
||||||
|
pickField(message, "mode") ??
|
||||||
|
normalizedInfo.mode ??
|
||||||
|
currentContext?.mode
|
||||||
|
);
|
||||||
|
return Number.isFinite(mode) ? mode : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isMeleeMessage(message = {}, normalizedInfo = {}) {
|
||||||
|
const mode = getCurrentMode(message, normalizedInfo);
|
||||||
|
if (mode !== undefined) return mode > 3;
|
||||||
|
if (currentContext?.isMelee !== undefined) return currentContext.isMelee;
|
||||||
|
return normalizeRoute(getCurrentPageInfo()?.route) === "pages/melee-battle";
|
||||||
|
}
|
||||||
|
|
||||||
|
function isHalfRestTimeout(message = {}, matchInfo = {}) {
|
||||||
|
if (message.type !== ServerMessageType.SERVER_MSG_TIMEOUT) return false;
|
||||||
|
if (!isMeleeMessage(message, matchInfo)) return false;
|
||||||
|
|
||||||
|
const status = Number(pickField(message, "status") ?? matchInfo.status);
|
||||||
|
return status === MATCH_STATUS_HALF_REST || !Number.isFinite(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBusinessType(message, matchInfo) {
|
||||||
|
if (isHalfRestTimeout(message, matchInfo)) return MESSAGETYPESV2.HalfRest;
|
||||||
|
if (message.type === ServerMessageType.SERVER_MSG_TIMEOUT) {
|
||||||
|
return MESSAGETYPESV2.BattleEnd;
|
||||||
|
}
|
||||||
|
return BUSINESS_TYPE_BY_SERVER_TYPE[message.type];
|
||||||
|
}
|
||||||
|
|
||||||
function buildBusinessMessage(message) {
|
function buildBusinessMessage(message) {
|
||||||
const businessType = BUSINESS_TYPE_BY_SERVER_TYPE[message.type];
|
const matchInfo = normalizeMatchInfo(message.match_info);
|
||||||
|
if (
|
||||||
|
message.type === ServerMessageType.SERVER_MSG_MATCH_READY &&
|
||||||
|
(matchInfo.status === undefined ||
|
||||||
|
matchInfo.status === null ||
|
||||||
|
matchInfo.status === "")
|
||||||
|
) {
|
||||||
|
matchInfo.status = 0;
|
||||||
|
}
|
||||||
|
const practiceInfo = normalizePracticeInfo(message.practice_info);
|
||||||
|
const businessType = getBusinessType(message, matchInfo);
|
||||||
if (!businessType) return null;
|
if (!businessType) return null;
|
||||||
|
|
||||||
const matchInfo = normalizeMatchInfo(message.match_info);
|
const mode = getCurrentMode(message, matchInfo);
|
||||||
const practiceInfo = normalizePracticeInfo(message.practice_info);
|
const isMelee = isMeleeMessage(message, matchInfo);
|
||||||
|
const isSecondHalfStart =
|
||||||
|
message.type === ServerMessageType.SERVER_MSG_MATCH_START &&
|
||||||
|
isMelee &&
|
||||||
|
currentContext?.meleeHalfRest === true;
|
||||||
|
|
||||||
|
if (currentContext) {
|
||||||
|
if (mode !== undefined) {
|
||||||
|
currentContext.mode = mode;
|
||||||
|
currentContext.isMelee = isMelee;
|
||||||
|
} else if (isMelee) {
|
||||||
|
currentContext.isMelee = true;
|
||||||
|
}
|
||||||
|
if (businessType === MESSAGETYPESV2.HalfRest) {
|
||||||
|
currentContext.meleeHalfRest = true;
|
||||||
|
} else if (message.type === ServerMessageType.SERVER_MSG_MATCH_START) {
|
||||||
|
currentContext.meleeHalfRest = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const matchId = normalizeId(
|
const matchId = normalizeId(
|
||||||
pickField(message, "matchId", "match_id") ||
|
pickField(message, "matchId", "match_id") ||
|
||||||
matchInfo.matchId ||
|
matchInfo.matchId ||
|
||||||
@@ -109,6 +170,7 @@ function buildBusinessMessage(message) {
|
|||||||
timestamp: message.timestamp,
|
timestamp: message.timestamp,
|
||||||
matchWsType: message.type,
|
matchWsType: message.type,
|
||||||
matchWsTypeName: getServerMessageTypeName(message.type),
|
matchWsTypeName: getServerMessageTypeName(message.type),
|
||||||
|
isSecondHalfStart,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,13 +312,23 @@ function getTestDistanceAudioKeys(shootData) {
|
|||||||
function getAckAudioKeys(message, businessMessage) {
|
function getAckAudioKeys(message, businessMessage) {
|
||||||
switch (message.type) {
|
switch (message.type) {
|
||||||
case ServerMessageType.SERVER_MSG_MATCH_START:
|
case ServerMessageType.SERVER_MSG_MATCH_START:
|
||||||
return ["比赛开始"];
|
return [businessMessage?.isSecondHalfStart ? "下半场开始" : "比赛开始"];
|
||||||
case ServerMessageType.SERVER_MSG_NOW_YOU:
|
case ServerMessageType.SERVER_MSG_NOW_YOU:
|
||||||
|
if (isMeleeMessage(message, businessMessage)) return [];
|
||||||
return getNowYouAudioKeys(businessMessage);
|
return getNowYouAudioKeys(businessMessage);
|
||||||
case ServerMessageType.SERVER_MSG_SHOT:
|
case ServerMessageType.SERVER_MSG_SHOT:
|
||||||
|
if (
|
||||||
|
isMeleeMessage(message, businessMessage) &&
|
||||||
|
String(businessMessage?.shootData?.playerId) !== String(currentContext?.userId)
|
||||||
|
) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
return getShootResultAudioKeys(businessMessage?.shootData);
|
return getShootResultAudioKeys(businessMessage?.shootData);
|
||||||
case ServerMessageType.SERVER_MSG_MATCH_END:
|
case ServerMessageType.SERVER_MSG_MATCH_END:
|
||||||
|
return ["比赛结束"];
|
||||||
case ServerMessageType.SERVER_MSG_TIMEOUT:
|
case ServerMessageType.SERVER_MSG_TIMEOUT:
|
||||||
|
if (businessMessage?.type === MESSAGETYPESV2.HalfRest) return ["中场休息"];
|
||||||
|
return ["比赛结束"];
|
||||||
case ServerMessageType.SERVER_MSG_PRACTICE_END:
|
case ServerMessageType.SERVER_MSG_PRACTICE_END:
|
||||||
return ["比赛结束"];
|
return ["比赛结束"];
|
||||||
case ServerMessageType.SERVER_MSG_CHECK:
|
case ServerMessageType.SERVER_MSG_CHECK:
|
||||||
@@ -268,7 +340,14 @@ function getAckAudioKeys(message, businessMessage) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function shouldCloseAfterAck(message) {
|
function shouldCloseAfterAck(message, businessMessage) {
|
||||||
|
if (
|
||||||
|
message.type === ServerMessageType.SERVER_MSG_TIMEOUT &&
|
||||||
|
businessMessage?.type === MESSAGETYPESV2.HalfRest
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
message.type === ServerMessageType.SERVER_MSG_MATCH_END ||
|
message.type === ServerMessageType.SERVER_MSG_MATCH_END ||
|
||||||
message.type === ServerMessageType.SERVER_MSG_TIMEOUT ||
|
message.type === ServerMessageType.SERVER_MSG_TIMEOUT ||
|
||||||
@@ -416,7 +495,7 @@ function queueAckAfterAudio(message, businessMessage) {
|
|||||||
pickField(message, "matchId", "match_id") || currentContext?.matchId
|
pickField(message, "matchId", "match_id") || currentContext?.matchId
|
||||||
),
|
),
|
||||||
sequence: message.sequence,
|
sequence: message.sequence,
|
||||||
leaveAfterAck: shouldCloseAfterAck(message),
|
leaveAfterAck: shouldCloseAfterAck(message, businessMessage),
|
||||||
};
|
};
|
||||||
|
|
||||||
const audioKeys = getAckAudioKeys(message, businessMessage).filter(Boolean);
|
const audioKeys = getAckAudioKeys(message, businessMessage).filter(Boolean);
|
||||||
@@ -503,10 +582,11 @@ function sendLeave() {
|
|||||||
|
|
||||||
export function connectMatchWebSocket(options = {}) {
|
export function connectMatchWebSocket(options = {}) {
|
||||||
// 入口参数来自原 websocket 的比赛服地址通知,不影响原有 websocket 连接。
|
// 入口参数来自原 websocket 的比赛服地址通知,不影响原有 websocket 连接。
|
||||||
const { serverAddr, matchId, userId, token } = options;
|
const { serverAddr, matchId, userId, token, mode } = options;
|
||||||
const url = normalizeServerUrl(serverAddr, token);
|
const url = normalizeServerUrl(serverAddr, token);
|
||||||
const normalizedMatchId = normalizeId(matchId);
|
const normalizedMatchId = normalizeId(matchId);
|
||||||
const normalizedUserId = normalizeId(userId);
|
const normalizedUserId = normalizeId(userId);
|
||||||
|
const normalizedMode = Number(mode);
|
||||||
|
|
||||||
if (!url || !normalizedMatchId) {
|
if (!url || !normalizedMatchId) {
|
||||||
console.log("[match-ws] missing serverAddr or matchId", options);
|
console.log("[match-ws] missing serverAddr or matchId", options);
|
||||||
@@ -536,6 +616,10 @@ export function connectMatchWebSocket(options = {}) {
|
|||||||
matchId: normalizedMatchId,
|
matchId: normalizedMatchId,
|
||||||
userId: normalizedUserId,
|
userId: normalizedUserId,
|
||||||
url,
|
url,
|
||||||
|
mode: Number.isFinite(normalizedMode) ? normalizedMode : undefined,
|
||||||
|
isMelee:
|
||||||
|
Number.isFinite(normalizedMode) ? normalizedMode > 3 : undefined,
|
||||||
|
meleeHalfRest: false,
|
||||||
};
|
};
|
||||||
ensureAudioAckListener();
|
ensureAudioAckListener();
|
||||||
|
|
||||||
@@ -596,6 +680,7 @@ export function connectMatchWebSocketFromNotice(notice, fallbackUserId) {
|
|||||||
serverAddr: pickField(notice, "serverAddr", "server_addr"),
|
serverAddr: pickField(notice, "serverAddr", "server_addr"),
|
||||||
matchId: pickField(notice, "matchId", "match_id"),
|
matchId: pickField(notice, "matchId", "match_id"),
|
||||||
userId: pickField(notice, "userId", "user_id") || fallbackUserId,
|
userId: pickField(notice, "userId", "user_id") || fallbackUserId,
|
||||||
|
mode: pickField(notice, "mode"),
|
||||||
token: notice.token || notice.wsToken || notice.ws_token,
|
token: notice.token || notice.wsToken || notice.ws_token,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ const gameType = ref(0);
|
|||||||
const teamSize = ref(0);
|
const teamSize = ref(0);
|
||||||
const onComplete = ref(null);
|
const onComplete = ref(null);
|
||||||
const showLimitModal = ref(false);
|
const showLimitModal = ref(false);
|
||||||
|
const MATCH_READY_SNAPSHOT_PREFIX = "match-ready-snapshot:";
|
||||||
|
|
||||||
/** 匹配超时计时器,用于检测 WS 消息丢失或真正超时 */
|
/** 匹配超时计时器,用于检测 WS 消息丢失或真正超时 */
|
||||||
const matchTimeoutTimer = ref(null);
|
const matchTimeoutTimer = ref(null);
|
||||||
@@ -27,6 +28,17 @@ const clearMatchTimeout = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const cacheReadyBattle = (battle) => {
|
||||||
|
const matchId = String(battle?.matchId || "");
|
||||||
|
if (!matchId) return;
|
||||||
|
|
||||||
|
uni.setStorageSync(`${MATCH_READY_SNAPSHOT_PREFIX}${matchId}`, {
|
||||||
|
...battle,
|
||||||
|
status: battle.status == null ? 0 : Number(battle.status),
|
||||||
|
savedAt: Date.now(),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 超时处理:查询后端是否已分配对局
|
* 超时处理:查询后端是否已分配对局
|
||||||
* - 有对局 → WS 消息丢失场景,自动跳入
|
* - 有对局 → WS 消息丢失场景,自动跳入
|
||||||
@@ -36,6 +48,7 @@ const handleMatchTimeout = async () => {
|
|||||||
try {
|
try {
|
||||||
const battle = await getBattleAPI();
|
const battle = await getBattleAPI();
|
||||||
if (battle && battle.matchId) {
|
if (battle && battle.matchId) {
|
||||||
|
cacheReadyBattle(battle);
|
||||||
uni.showToast({ title: "匹配成功,正在进入...", icon: "none" });
|
uni.showToast({ title: "匹配成功,正在进入...", icon: "none" });
|
||||||
if (battle.mode <= 3) {
|
if (battle.mode <= 3) {
|
||||||
uni.redirectTo({ url: `/pages/team-battle/index?battleId=${battle.matchId}` });
|
uni.redirectTo({ url: `/pages/team-battle/index?battleId=${battle.matchId}` });
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ const playersSorted = ref([]);
|
|||||||
const playersScores = ref([]);
|
const playersScores = ref([]);
|
||||||
const halfTimeTip = ref(false);
|
const halfTimeTip = ref(false);
|
||||||
const halfRest = ref(false);
|
const halfRest = ref(false);
|
||||||
|
const DEFAULT_READY_TIME = 15;
|
||||||
const HALF_REST_SECONDS = 20;
|
const HALF_REST_SECONDS = 20;
|
||||||
const MATCH_READY_SNAPSHOT_PREFIX = "match-ready-snapshot:";
|
const MATCH_READY_SNAPSHOT_PREFIX = "match-ready-snapshot:";
|
||||||
const MATCH_STATUS_BY_TEXT = {
|
const MATCH_STATUS_BY_TEXT = {
|
||||||
@@ -46,6 +47,7 @@ const MATCH_STATUS_BY_TEXT = {
|
|||||||
MATCH_STATUS_UNEXPECTEDLY: 4,
|
MATCH_STATUS_UNEXPECTEDLY: 4,
|
||||||
};
|
};
|
||||||
const halfRestRemain = ref(HALF_REST_SECONDS);
|
const halfRestRemain = ref(HALF_REST_SECONDS);
|
||||||
|
const readyTime = ref(DEFAULT_READY_TIME);
|
||||||
let halfRestTimer = null;
|
let halfRestTimer = null;
|
||||||
/** 控制设备离线提示弹窗的显示状态 */
|
/** 控制设备离线提示弹窗的显示状态 */
|
||||||
const showOfflineModal = ref(false);
|
const showOfflineModal = ref(false);
|
||||||
@@ -132,6 +134,27 @@ function normalizeBattleInfo(battleInfo) {
|
|||||||
return battleInfo;
|
return battleInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeTimestamp(value) {
|
||||||
|
const numberValue = Number(value || 0);
|
||||||
|
if (!numberValue) return 0;
|
||||||
|
return numberValue < 1000000000000 ? numberValue * 1000 : numberValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getReadyTime(battleInfo) {
|
||||||
|
const value = Number(battleInfo?.readyTime);
|
||||||
|
return Number.isFinite(value) && value > 0 ? value : DEFAULT_READY_TIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getReadyRemainingSeconds(battleInfo) {
|
||||||
|
const total = getReadyTime(battleInfo);
|
||||||
|
const countdownStartTime = normalizeTimestamp(battleInfo?.countdownStartTime);
|
||||||
|
if (!countdownStartTime) return total;
|
||||||
|
|
||||||
|
const elapsed = Math.max(0, (Date.now() - countdownStartTime) / 1000);
|
||||||
|
console.log('11111111111111111111111111111', total, countdownStartTime, Math.max(0, (Date.now() - countdownStartTime) / 1000))
|
||||||
|
return Math.max(0, total - elapsed);
|
||||||
|
}
|
||||||
|
|
||||||
function hasKnownStatus(battleInfo) {
|
function hasKnownStatus(battleInfo) {
|
||||||
return !(
|
return !(
|
||||||
battleInfo?.status === undefined ||
|
battleInfo?.status === undefined ||
|
||||||
@@ -168,6 +191,7 @@ function reconnectMatchServer(battleInfo) {
|
|||||||
serverAddr: battleInfo.serverAddr,
|
serverAddr: battleInfo.serverAddr,
|
||||||
matchId: battleInfo.matchId || battleId.value,
|
matchId: battleInfo.matchId || battleId.value,
|
||||||
userId: user.value.id,
|
userId: user.value.id,
|
||||||
|
mode: battleInfo.mode,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,10 +259,10 @@ function recoverData(battleInfo, { force = false } = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (battleInfo.status === 0) {
|
if (battleInfo.status === 0) {
|
||||||
const readyRemain = (Date.now() - (battleInfo.serverTime || Date.now())) / 1000;
|
readyTime.value = getReadyTime(battleInfo);
|
||||||
if (readyRemain > 0 && readyRemain < 15) {
|
setTimeout(() => {
|
||||||
setTimeout(() => uni.$emit("update-timer", 15 - readyRemain - 0.2), 200);
|
uni.$emit("update-timer", getReadyRemainingSeconds(battleInfo));
|
||||||
}
|
}, 200);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,7 +317,11 @@ onLoad(async (options) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const readySnapshot = takeReadySnapshot(battleId.value);
|
const readySnapshot = takeReadySnapshot(battleId.value);
|
||||||
if (readySnapshot?.status === 0) recoverData(readySnapshot);
|
if (readySnapshot?.status === 0) {
|
||||||
|
skipNextRestoreOnShow = true;
|
||||||
|
reconnectMatchServer(readySnapshot);
|
||||||
|
recoverData(readySnapshot);
|
||||||
|
}
|
||||||
// uni.enableAlertBeforeUnload({
|
// uni.enableAlertBeforeUnload({
|
||||||
// message: "离开比赛可能导致比赛失败,是否继续?",
|
// message: "离开比赛可能导致比赛失败,是否继续?",
|
||||||
// success: (res) => {
|
// success: (res) => {
|
||||||
@@ -426,7 +454,12 @@ onShow(async () => {
|
|||||||
<Container :title="title" :bgType="1">
|
<Container :title="title" :bgType="1">
|
||||||
<view class="container">
|
<view class="container">
|
||||||
<BattleHeader v-if="!start" :players="players" />
|
<BattleHeader v-if="!start" :players="players" />
|
||||||
<TestDistance v-if="start === false" :guide="false" :isBattle="true" />
|
<TestDistance
|
||||||
|
v-if="start === false"
|
||||||
|
:guide="false"
|
||||||
|
:isBattle="true"
|
||||||
|
:count="readyTime"
|
||||||
|
/>
|
||||||
<ShootProgress
|
<ShootProgress
|
||||||
:show="start"
|
:show="start"
|
||||||
:start="start && !halfRest"
|
:start="start && !halfRest"
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import audioManager from "@/audioManager";
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
createPractiseAPI,
|
createPractiseAPI,
|
||||||
|
endPractiseAPI,
|
||||||
getPractiseAPI,
|
getPractiseAPI,
|
||||||
startPractiseAPI,
|
startPractiseAPI,
|
||||||
} from "@/apis";
|
} from "@/apis";
|
||||||
@@ -40,6 +41,7 @@ const showGuide = ref(false);
|
|||||||
const tips = ref("");
|
const tips = ref("");
|
||||||
const targetType = ref(1);
|
const targetType = ref(1);
|
||||||
const sharing = ref(false);
|
const sharing = ref(false);
|
||||||
|
const exiting = ref(false);
|
||||||
const RESULT_TIP_CDN = "https://static.shelingxingqiu.com/shootmini/static";
|
const RESULT_TIP_CDN = "https://static.shelingxingqiu.com/shootmini/static";
|
||||||
|
|
||||||
onLoad((options) => {
|
onLoad((options) => {
|
||||||
@@ -155,6 +157,21 @@ async function onComplete() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function exitPractise() {
|
||||||
|
if (exiting.value) return;
|
||||||
|
exiting.value = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (practiseId.value && !practiseResult.value?.details) {
|
||||||
|
await endPractiseAPI(practiseId.value);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to stop practice", error);
|
||||||
|
} finally {
|
||||||
|
uni.navigateBack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const getResultTipSrc = (result = {}) => {
|
const getResultTipSrc = (result = {}) => {
|
||||||
const validCount = (result.details || []).filter(
|
const validCount = (result.details || []).filter(
|
||||||
(arrow) => arrow.x !== -30 && arrow.y !== -30
|
(arrow) => arrow.x !== -30 && arrow.y !== -30
|
||||||
@@ -204,6 +221,7 @@ onBeforeUnmount(() => {
|
|||||||
:bgType="1"
|
:bgType="1"
|
||||||
title="个人单组练习"
|
title="个人单组练习"
|
||||||
:showBottom="!start && !scores.length"
|
:showBottom="!start && !scores.length"
|
||||||
|
:onBack="exitPractise"
|
||||||
>
|
>
|
||||||
<view>
|
<view>
|
||||||
<TestDistance v-if="!start && !practiseResult.id" />
|
<TestDistance v-if="!start && !practiseResult.id" />
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import audioManager from "@/audioManager";
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
createPractiseAPI,
|
createPractiseAPI,
|
||||||
|
endPractiseAPI,
|
||||||
getPractiseAPI,
|
getPractiseAPI,
|
||||||
startPractiseAPI,
|
startPractiseAPI,
|
||||||
} from "@/apis";
|
} from "@/apis";
|
||||||
@@ -39,6 +40,7 @@ const practiseId = ref("");
|
|||||||
const showGuide = ref(false);
|
const showGuide = ref(false);
|
||||||
const targetType = ref(1);
|
const targetType = ref(1);
|
||||||
const sharing = ref(false);
|
const sharing = ref(false);
|
||||||
|
const exiting = ref(false);
|
||||||
const RESULT_TIP_CDN = "https://static.shelingxingqiu.com/shootmini/static";
|
const RESULT_TIP_CDN = "https://static.shelingxingqiu.com/shootmini/static";
|
||||||
|
|
||||||
onLoad((options) => {
|
onLoad((options) => {
|
||||||
@@ -170,6 +172,21 @@ async function onComplete() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function exitPractise() {
|
||||||
|
if (exiting.value) return;
|
||||||
|
exiting.value = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (practiseId.value && !practiseResult.value?.details) {
|
||||||
|
await endPractiseAPI(practiseId.value);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to stop practice", error);
|
||||||
|
} finally {
|
||||||
|
uni.navigateBack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const getResultTipSrc = (result = {}) => {
|
const getResultTipSrc = (result = {}) => {
|
||||||
const validCount = (result.details || []).filter(
|
const validCount = (result.details || []).filter(
|
||||||
(arrow) => arrow.x !== -30 && arrow.y !== -30
|
(arrow) => arrow.x !== -30 && arrow.y !== -30
|
||||||
@@ -218,6 +235,7 @@ onBeforeUnmount(() => {
|
|||||||
:bgType="1"
|
:bgType="1"
|
||||||
title="日常耐力挑战"
|
title="日常耐力挑战"
|
||||||
:showBottom="!start && !scores.length"
|
:showBottom="!start && !scores.length"
|
||||||
|
:onBack="exitPractise"
|
||||||
>
|
>
|
||||||
<view>
|
<view>
|
||||||
<TestDistance v-if="!start && !practiseResult.id" />
|
<TestDistance v-if="!start && !practiseResult.id" />
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ const store = useStore();
|
|||||||
const { user, online } = storeToRefs(store);
|
const { user, online } = storeToRefs(store);
|
||||||
|
|
||||||
const DEFAULT_SHOOT_TIME = 15;
|
const DEFAULT_SHOOT_TIME = 15;
|
||||||
const READY_SECONDS = 15;
|
const DEFAULT_READY_TIME = 15;
|
||||||
const READY_TIMER_EMIT_DELAY = 200;
|
const READY_TIMER_EMIT_DELAY = 200;
|
||||||
const RESTORE_DELAY = 300;
|
const RESTORE_DELAY = 300;
|
||||||
const RESTORE_EMPTY_ID_RETRY_DELAY = 50;
|
const RESTORE_EMPTY_ID_RETRY_DELAY = 50;
|
||||||
@@ -81,6 +81,7 @@ const showRoundTip = ref(false);
|
|||||||
const isFinalShoot = ref(false);
|
const isFinalShoot = ref(false);
|
||||||
const matchStatus = ref(undefined);
|
const matchStatus = ref(undefined);
|
||||||
const shootTimeTotal = ref(DEFAULT_SHOOT_TIME);
|
const shootTimeTotal = ref(DEFAULT_SHOOT_TIME);
|
||||||
|
const readyTime = ref(DEFAULT_READY_TIME);
|
||||||
const showOfflineModal = ref(false);
|
const showOfflineModal = ref(false);
|
||||||
const restoreLoading = ref(false);
|
const restoreLoading = ref(false);
|
||||||
const xRingStreaks = ref({});
|
const xRingStreaks = ref({});
|
||||||
@@ -144,6 +145,20 @@ function normalizeTimestamp(value) {
|
|||||||
return numberValue < 1000000000000 ? numberValue * 1000 : numberValue;
|
return numberValue < 1000000000000 ? numberValue * 1000 : numberValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getReadyTime(battleInfo) {
|
||||||
|
const value = Number(battleInfo?.readyTime);
|
||||||
|
return Number.isFinite(value) && value > 0 ? value : DEFAULT_READY_TIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getReadyRemainingSeconds(battleInfo) {
|
||||||
|
const total = getReadyTime(battleInfo);
|
||||||
|
const countdownStartTime = normalizeTimestamp(battleInfo?.countdownStartTime);
|
||||||
|
if (!countdownStartTime) return total;
|
||||||
|
|
||||||
|
const elapsed = Math.max(0, (Date.now() - countdownStartTime) / 1000);
|
||||||
|
return Math.max(0, total - elapsed);
|
||||||
|
}
|
||||||
|
|
||||||
function getReadySnapshotKey(matchId) {
|
function getReadySnapshotKey(matchId) {
|
||||||
return `${MATCH_READY_SNAPSHOT_PREFIX}${String(matchId || "")}`;
|
return `${MATCH_READY_SNAPSHOT_PREFIX}${String(matchId || "")}`;
|
||||||
}
|
}
|
||||||
@@ -830,6 +845,7 @@ function stopProgressAfterMount() {
|
|||||||
// 待开局状态:清理比赛态展示,并恢复准备倒计时。
|
// 待开局状态:清理比赛态展示,并恢复准备倒计时。
|
||||||
function applyReadyState(battleInfo) {
|
function applyReadyState(battleInfo) {
|
||||||
hideRestoreLoading();
|
hideRestoreLoading();
|
||||||
|
readyTime.value = getReadyTime(battleInfo);
|
||||||
start.value = false;
|
start.value = false;
|
||||||
showRoundTip.value = false;
|
showRoundTip.value = false;
|
||||||
currentShooterId.value = 0;
|
currentShooterId.value = 0;
|
||||||
@@ -841,13 +857,9 @@ function applyReadyState(battleInfo) {
|
|||||||
clearProgressZeroWaiters();
|
clearProgressZeroWaiters();
|
||||||
cancelRoundTipDisplay();
|
cancelRoundTipDisplay();
|
||||||
|
|
||||||
const serverTime = normalizeTimestamp(battleInfo?.serverTime || Date.now());
|
setTimeout(() => {
|
||||||
const readyElapsed = (Date.now() - serverTime) / 1000;
|
uni.$emit("update-timer", getReadyRemainingSeconds(battleInfo));
|
||||||
if (readyElapsed > 0 && readyElapsed < READY_SECONDS) {
|
}, READY_TIMER_EMIT_DELAY);
|
||||||
setTimeout(() => {
|
|
||||||
uni.$emit("update-timer", READY_SECONDS - readyElapsed - 0.2);
|
|
||||||
}, READY_TIMER_EMIT_DELAY);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 快照恢复入口:只把页面拉到服务端最新状态,不重放已经发生过的语音。
|
// 快照恢复入口:只把页面拉到服务端最新状态,不重放已经发生过的语音。
|
||||||
@@ -1346,7 +1358,12 @@ onShow(() => {
|
|||||||
:blueTeam="blueTeam"
|
:blueTeam="blueTeam"
|
||||||
:winner="0"
|
:winner="0"
|
||||||
/>
|
/>
|
||||||
<TestDistance v-if="start === false" :guide="false" :isBattle="true"/>
|
<TestDistance
|
||||||
|
v-if="start === false"
|
||||||
|
:guide="false"
|
||||||
|
:isBattle="true"
|
||||||
|
:count="readyTime"
|
||||||
|
/>
|
||||||
<!-- 比赛进行中显示:左右队伍、进度条、靶面和底部比分。 -->
|
<!-- 比赛进行中显示:左右队伍、进度条、靶面和底部比分。 -->
|
||||||
<view v-if="start" class="players-row">
|
<view v-if="start" class="players-row">
|
||||||
<TeamAvatars
|
<TeamAvatars
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import * as $protobuf from "protobufjs";
|
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},ClientMessageType:{CLIENT_MSG_UNKNOWN:0,CLIENT_MSG_HEARTBEAT_ACK:1,CLIENT_MSG_SHOOT_DATA:2,CLIENT_MSG_ACK:3,CLIENT_MSG_LEAVE:4},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}}},MatchShootList:{fields:{items:{rule:"repeated",type:"MatchShoot",id:1}}},RoundScore:{fields:{total_ring:{type:"int32",id:1},score:{type:"int32",id:2},if_win:{type:"bool",id:3}}},MatchRound:{fields:{shoots:{rule:"map",type:"MatchShootList",id:1,keytype:"int64"},scores:{rule:"map",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}}},TeamInfo:{fields:{players:{rule:"repeated",type:"PlayerFull",id:1},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:{rule:"map",type:"int32",id:9,keytype:"int64"}}},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}}},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:{rule:"repeated",type:"MatchShoot",id:11}}},MatchInfo:{fields:{match_id:{type:"int64",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:{rule:"repeated",type:"MatchRound",id:12},teams:{rule:"map",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:{rule:"repeated",type:"PlayerMatchResult",id:20},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}}},ServerMessage:{fields:{type:{type:"ServerMessageType",id:1},match_id:{type:"int64",id:2},timestamp:{type:"int64",id:3},match_info:{type:"MatchInfo",id:4,oneof:"payload"},shoot_data:{type:"ShootData",id:5,oneof:"payload"},practice_info:{type:"PracticeInfo",id:6,oneof:"payload"},sequence:{type:"int64",id:7}}},ClientMessage:{fields:{type:{type:"ClientMessageType",id:1},match_id:{type:"int64",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},ClientMessageType:{CLIENT_MSG_UNKNOWN:0,CLIENT_MSG_HEARTBEAT_ACK:1,CLIENT_MSG_SHOOT_DATA:2,CLIENT_MSG_ACK:3,CLIENT_MSG_LEAVE:4},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}}},MatchShootList:{fields:{items:{rule:"repeated",type:"MatchShoot",id:1}}},RoundScore:{fields:{total_ring:{type:"int32",id:1},score:{type:"int32",id:2},if_win:{type:"bool",id:3}}},MatchRound:{fields:{shoots:{rule:"map",type:"MatchShootList",id:1,keytype:"int64"},scores:{rule:"map",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}}},TeamInfo:{fields:{players:{rule:"repeated",type:"PlayerFull",id:1},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:{rule:"map",type:"int32",id:9,keytype:"int64"}}},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}}},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:{rule:"repeated",type:"MatchShoot",id:11}}},MatchInfo:{fields:{match_id:{type:"int64",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:{rule:"repeated",type:"MatchRound",id:12},teams:{rule:"map",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:{rule:"repeated",type:"PlayerMatchResult",id:20},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:"int64",id:2},timestamp:{type:"int64",id:3},match_info:{type:"MatchInfo",id:4,oneof:"payload"},shoot_data:{type:"ShootData",id:5,oneof:"payload"},practice_info:{type:"PracticeInfo",id:6,oneof:"payload"},sequence:{type:"int64",id:7}}},ClientMessage:{fields:{type:{type:"ClientMessageType",id:1},match_id:{type:"int64",id:2},user_id:{type:"int64",id:3},sequence:{type:"int64",id:4},data:{type:"bytes",id:5}}}}}});
|
||||||
export default $root;
|
export default $root;
|
||||||
|
|||||||
@@ -184,6 +184,7 @@ const SCHEMAS = {
|
|||||||
23: { name: "event_type", kind: "int32" },
|
23: { name: "event_type", kind: "int32" },
|
||||||
24: { name: "timeout", kind: "int32" },
|
24: { name: "timeout", kind: "int32" },
|
||||||
25: { name: "server_addr", kind: "string" },
|
25: { name: "server_addr", kind: "string" },
|
||||||
|
26: { name: "countdown_start_time", kind: "int64" },
|
||||||
},
|
},
|
||||||
ServerMessage: {
|
ServerMessage: {
|
||||||
1: { name: "type", kind: "int32" },
|
1: { name: "type", kind: "int32" },
|
||||||
|
|||||||
+2
-2
@@ -24,8 +24,8 @@ function createWebSocket(token, onMessage) {
|
|||||||
|
|
||||||
switch (envVersion) {
|
switch (envVersion) {
|
||||||
case "develop": // 开发版
|
case "develop": // 开发版
|
||||||
url = "ws://192.168.1.2:8000/socket";
|
// url = "ws://192.168.1.2:8000/socket";
|
||||||
// url = "wss://apitest.shelingxingqiu.com/socket";
|
url = "wss://apitest.shelingxingqiu.com/socket";
|
||||||
break;
|
break;
|
||||||
case "trial": // 体验版
|
case "trial": // 体验版
|
||||||
url = "wss://apitest.shelingxingqiu.com/socket";
|
url = "wss://apitest.shelingxingqiu.com/socket";
|
||||||
|
|||||||
Reference in New Issue
Block a user