加拿大28-2.8【2868】
模式
3421460 期开奖
封盘中
账户余额
100000.00 刷新余额
3421459 期开奖
6
+
7
+
7
=
20
大双
期号 开奖时间 开奖结果
加载中...
🔍 查看更多开奖纪录
欢迎来到加拿大28游戏大厅!
本游戏为模拟试玩,开奖期号为系统随机生成,祝您游戏愉快!
提示信息
'; const SYSTEM_AVATAR = '/uploads/15b396260fab6f2beadcd2ecdb8cbba7.jpg'; const ROBOT_NAME = ''; const ROBOT_AVATAR = ''; function getAvatarUrl(name) { if (name === 'Me' || name.indexOf('游客') === 0) return MAIN_AVATAR; if (name === 'System' || name === SYSTEM_NAME) return SYSTEM_AVATAR; if (ROBOT_AVATAR && AVATAR_MAP[name]) return ROBOT_AVATAR; if (AVATAR_MAP[name]) return '../../static/image/' + AVATAR_MAP[name]; return DEFAULT_BOT_AVATAR; } let botBetCounts = {}; let botBetsByRound = {}; let lastBetRound = ''; let lastNotifiedPeriod = 0; let announcedSealing = false; let isFirstLoad = true; let nextDrawTime = null; let serverTimeOffset = 0; let scratchMode = false; let scratchRevealed = false; let historyLoadedOnce = false; function toggleHistory(){ const wrap = document.getElementById('historyWrap'); const tri = document.getElementById('tri'); const showing = wrap.classList.contains('show'); if (showing){ wrap.classList.remove('show'); tri.classList.remove('down'); return; } wrap.classList.add('show'); tri.classList.add('down'); if (!historyLoadedOnce){ loadHistoryPanel(8); historyLoadedOnce = true; } } function showMoreHistory(){ window.location.href = 'history.php'; } function fmtTimeFromStr(s){ if (!s) return '--:--'; try{ const m = s.match(/(\d{2}):(\d{2})/); if (m) return m[1]+':'+m[2]; }catch(e){} return '--:--'; } function calcTag(sum){ sum = parseInt(sum||0); const bigSmall = (sum>=14) ? '大' : '小'; const oddEven = (sum%2===1) ? '单' : '双'; return bigSmall + oddEven; } function loadHistoryPanel(limit=8){ $('#historyBody').html('加载中...'); $.getJSON(CONFIG.apiUrl + 'action=history&limit=' + limit + '&t=' + Date.now(), function(res){ const list = res.data || res.history || []; if (!list.length){ $('#historyBody').html('暂无记录'); return; } let html = ''; list.forEach(item=>{ if(!item || !item.round_number) return; const rn = item.round_number; const ot = item.created_at ? fmtTimeFromStr(item.created_at) : (item.opentime ? fmtTimeFromStr(item.opentime) : '--:--'); const nums = (item.result ? item.result.split(',') : []); const sum = item.sum ?? ''; const tag = calcTag(sum); let resHtml = ''; if (nums.length>=3){ resHtml = `
${nums[0]} + ${nums[1]} + ${nums[2]} = ${sum} ${tag}
`; }else{ resHtml = `
${sum}${tag}
`; } html += ` ${rn} ${ot} ${resHtml} `; }); $('#historyBody').html(html); }).fail(function(){ $('#historyBody').html('加载失败'); }); } function updateScratchLeftUI(){ const pEl = document.getElementById('scratchNowPeriod'); const sEl = document.getElementById('scratchStatusText'); if (!pEl || !sEl) return; pEl.textContent = currentPeriod || '----'; if (isTempLocked) { sEl.textContent = '开奖中'; } else if (totalSeconds <= 30 || isLocked) { sEl.textContent = '封盘中'; } else { let displaySec = totalSeconds - 30; if (displaySec < 0) displaySec = 0; const min = Math.floor(displaySec / 60); const sec = displaySec % 60; sEl.textContent = (min < 10 ? '0'+min : min) + ':' + (sec < 10 ? '0'+sec : sec); } } function updateScratchFromDraw(draw){ if (!draw || !draw.result) return; try{ const nums = draw.result.split(','); if (nums.length < 3) return; const sum = parseInt(draw.sum); const tag = (sum>=14 ? '大' : '小') + (sum%2 ? '单' : '双'); const periodEl = document.getElementById('scratchPeriod'); const inner = document.getElementById('scratchInner'); if (periodEl) periodEl.textContent = draw.round_number; if (inner){ inner.innerHTML = `
${nums[0]}
+
${nums[1]}
+
${nums[2]}
=
${sum}
${tag}
`; } }catch(e){} } function resetScratchUI(){ scratchRevealed = false; const tip = document.getElementById('scratchTip'); if (tip) tip.style.display = 'flex'; setupScratchCanvas(); } let scratchCanvasEl = null; let scratchCtx = null; let scratchDrawing = false; function setupScratchCanvas(){ const card = document.getElementById('scratchCard'); const canvas = document.getElementById('scratchCanvas'); if (!card || !canvas) return; const rect = card.getBoundingClientRect(); const dpr = window.devicePixelRatio || 1; canvas.width = rect.width * dpr; canvas.height = rect.height * dpr; canvas.style.width = rect.width + 'px'; canvas.style.height = rect.height + 'px'; const ctx = canvas.getContext('2d'); ctx.setTransform(dpr, 0, 0, dpr, 0, 0); ctx.globalCompositeOperation = 'source-over'; ctx.fillStyle = '#d3d5dc'; ctx.fillRect(0, 0, rect.width, rect.height); ctx.globalCompositeOperation = 'destination-out'; scratchCanvasEl = canvas; scratchCtx = ctx; const start = (ev) => { if (!scratchMode) return; scratchDrawing = true; drawScratch(ev); }; const move = (ev) => { if (!scratchDrawing) return; drawScratch(ev); }; const end = () => { scratchDrawing = false; }; canvas.onmousedown = start; canvas.onmousemove = move; window.addEventListener('mouseup', end); canvas.ontouchstart = function(e){ start(e.touches[0]); e.preventDefault(); }; canvas.ontouchmove = function(e){ move(e.touches[0]); e.preventDefault(); }; window.addEventListener('touchend', end); } function drawScratch(ev){ if (!scratchCanvasEl || !scratchCtx) return; const card = document.getElementById('scratchCard'); if (!card) return; const rect = card.getBoundingClientRect(); const x = ev.clientX - rect.left; const y = ev.clientY - rect.top; const r = 18; scratchCtx.beginPath(); scratchCtx.arc(x, y, r, 0, Math.PI * 2); scratchCtx.fill(); const tip = document.getElementById('scratchTip'); if (tip) tip.style.display = 'none'; } function refreshScratchStatus(){ resetScratchUI(); fetchStatus(); } function toggleScratchMode(){ scratchMode = !scratchMode; const iconWrap = document.querySelector('.tb-sun'); const iconImg = document.getElementById('modeIcon'); const panel = document.getElementById('scratchPanel'); const lastRow = document.querySelector('.lastrow'); const statusLine = document.querySelector('.statusline'); if (scratchMode){ if (iconWrap){ iconWrap.classList.add('active'); } if (iconImg){ iconImg.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACIAAAAQCAMAAABEK11WAAAAkFBMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+WABnwAAAAL3RSTlMAZvXM9F/34aaXjHtqSxkOBuzn2tXDq3NXJiIdBPvQn4RuNC4VCu7GsJKDWlRDKdCylm4AAADbSURBVCjPfZHnEoIwEIQ3BKRIEQQUxN7rvf/beRcdxoLuj8zm9pvLzAYLK13gp5TORrCIaPSLcDi04PM5HXcTUY/DObZamGXnDiHyBIiHxDrUn0DsydydiJ/k4nv++hWoAlumwxoGKdibux9Gq6peX9Uxf46KWIjLjv4ojYDIOI/3fsgOShKtEMjNARK1fwWKMAGUlNZHn0hXYIkj1ytLz23bvM2IlmiUGkA0yDhxxIXCNo9hqJr3sjNDb1O2XYVr867Ria3+JjbyY5tnsdJ88s3MLd0uP89svw3u0qUlc8hiA8QAAAAASUVORK5CYII='; } if (panel) panel.style.display = 'block'; if (lastRow) lastRow.style.display = 'none'; if (statusLine) statusLine.style.display = 'none'; resetScratchUI(); updateScratchLeftUI(); fetchStatus(); } else { if (iconWrap){ iconWrap.classList.remove('active'); } if (iconImg){ iconImg.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACIAAAAYCAMAAACoeN87AAAAk1BMVEUAAAD////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////ROyVeAAAAMHRSTlMA9sII+4ZTgGJPBeje1nJHQhYO8c7LvrWrmZSQiV1WOO7juK94aVlNTPO8uaOfGxjSM81dAAABCklEQVQoz4WR15bDIAxEBbj3uGXjkrop2/n/r1uJmNgJx8l9YTQajMBwY8UqR+t1+dGAwUJKyRaDZljkYBCj/X6VLsoSTDz0dwGpIETpwYgzTCC22FiT6lGEYpjKB0ik3F9HsLETd23b0ZEuEH+f9LmWtmRYpgc54ZCSFarwiQzL9SL5QHS0LVpxu4tiHktdMtvpslolveP0ScP1tmgDhFiqqvImj5WfuDK/hErsVdyBB7KY/Joy36TecjAQP6oDcKS1AQP9UjKBrUpqLjUr6sv497FZAI5VinGbwtZ1gDdZgkg3gXZ8OeCD5he7U7iOcJiD6QiDOYrXkdcHmeOa6Et38IQzZ4yf771/rZ40NitV8K0AAAAASUVORK5CYII='; } if (panel) panel.style.display = 'none'; if (lastRow) lastRow.style.display = 'flex'; if (statusLine) statusLine.style.display = 'flex'; } } function refreshBalance(){ $.getJSON(CONFIG.apiUrl + 'action=status&t=' + Date.now(), function(res){ if (res && res.user && typeof res.user.coins !== 'undefined') { const val = parseFloat(res.user.coins) || 0; userCoins = val; const el = document.getElementById('userBalance'); if (el) el.textContent = val.toFixed(2); showToast('余额刷新成功', 1500); } }); } setInterval(() => { if (nextDrawTime) { const now = Math.floor(Date.now() / 1000) + serverTimeOffset; totalSeconds = nextDrawTime - now; if (totalSeconds < 0) totalSeconds = 0; updateTimerDisplay(); if (totalSeconds === 0) { fetchStatus(); } } else { if (totalSeconds > 0) { totalSeconds--; updateTimerDisplay(); } else { fetchStatus(); } } }, 1000); function updateTimerDisplay() { let displaySec = totalSeconds - 30; if (displaySec < 0) displaySec = 0; isLocked = (totalSeconds <= 30 || isTempLocked); const el = document.getElementById('countdown'); if (isTempLocked) { el.textContent = '开奖中'; el.style.background = '#3b4351'; } else if (totalSeconds <= 30) { el.textContent = '封盘中'; el.style.background = '#3b4351'; if (!announcedSealing) { announcedSealing = true; fetchBetSummaryAndShow(); } } else { const min = Math.floor(displaySec / 60); const sec = displaySec % 60; const text = (min < 10 ? '0'+min : min) + ':' + (sec < 10 ? '0'+sec : sec); el.textContent = text; el.style.background = '#3b4351'; announcedSealing = false; } if (scratchMode) updateScratchLeftUI(); } function fetchStatus() { $.getJSON(CONFIG.apiUrl + 'action=status&t=' + new Date().getTime(), function(res){ adText = res.ad_text || ''; adLink = res.ad_link || ''; ads = res.ads || ''; if (res.my_bet_count !== undefined) userBetCount = res.my_bet_count; if (res.server_time && res.next_draw_time) { const clientTime = Math.floor(Date.now() / 1000); serverTimeOffset = res.server_time - clientTime; nextDrawTime = res.next_draw_time; } const newCoins = parseFloat(res.user.coins); userCoins = newCoins; document.getElementById('userBalance').textContent = (newCoins||0).toFixed(2); if (res.history && res.history.length > 0) { const latest = res.history[0]; const latestPeriod = parseInt(latest.round_number); if (latestPeriod > lastDrawPeriod) { try { if (!isFirstLoad) { let winState = 'none'; let winAmount = 0; if (res.last_result_stats && parseInt(res.last_result_stats.round_number) == latestPeriod) { const betAmt = parseInt(res.last_result_stats.bet_amount) || 0; const winAmt = parseInt(res.last_result_stats.win_amount) || 0; if (betAmt > 0) { if (winAmt > 0) { winState = 'win'; winAmount = winAmt; } else { winState = 'loss'; } } } broadcastResult(latest, winState, winAmount); } updateLastDraw(latest); } catch(e) { console.error("Result update error:", e); } lastDrawPeriod = latestPeriod; updateTimerDisplay(); if ($('#historyWrap').hasClass('show')) loadHistoryPanel(8); } } isFirstLoad = false; if(res.round && res.round.round_number != currentPeriod) { currentPeriod = res.round.round_number; document.getElementById('currentPeriod').textContent = currentPeriod; userBetCount = 0; botBetCounts = {}; } if (newCoins < 10000) { tryRescue(); } updateTimerDisplay(); }).fail(function() { console.log("Poll failed"); }); } function updateLastDraw(draw) { if(!draw || !draw.result) return; try { const nums = draw.result.split(','); if (nums.length < 3) return; $('#lastPeriod').text(draw.round_number); $('#lastN1').text(nums[0]); $('#lastN2').text(nums[1]); $('#lastN3').text(nums[2]); $('#lastSum').text(draw.sum); const sum = parseInt(draw.sum); const tag = (sum>=14 ? '大' : '小') + (sum%2 ? '单' : '双'); $('#lastTag').text(tag); updateScratchFromDraw(draw); } catch(e) {} } function broadcastResult(draw, winState, winAmount) { if(!draw || !draw.result) return; try { announcedSealing = true; document.getElementById('audio-ding').play().catch(e => {}); setTimeout(() => { const nums = draw.result.split(',').map(Number); if (nums.length < 3) return; const sum = draw.sum; // 生成图片广告HTML let imagesHTML = ''; if (ads && ads.images && Array.isArray(ads.images)) { imagesHTML = `
`; ads.images.slice(0, 3).forEach((image, index) => { if (image && image.img_url && image.link) { imagesHTML += ` ${image.name || '广告图片'} `; } else { // 如果数据不完整,使用占位符 imagesHTML += ` 广告图片 `; } }); imagesHTML += `
`; } // 生成入口广告HTML let entriesHTML = ''; if (ads && ads.entries && Array.isArray(ads.entries)) { const colors = [ 'linear-gradient(135deg,#4cd964,#5ac8fa)', 'linear-gradient(135deg,#ff9500,#ff5e3a)', 'linear-gradient(135deg,#5856d6,#af52de)' ]; entriesHTML = `
`; ads.entries.slice(0, 3).forEach((entry, index) => { if (entry && entry.url && entry.name) { entriesHTML += ` ${entry.name} `; } else { // 如果数据不完整,使用占位符 entriesHTML += ` 入口${index + 1} `; } }); entriesHTML += `
`; } addMessage('robot', `
第${draw.round_number}期开奖结果 (${new Date().toLocaleTimeString()})
${nums[0]}+ ${nums[1]}+ ${nums[2]}= ${sum}
${imagesHTML} ${entriesHTML} ${adText ? (adLink ? `${String(adText).replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"')} 点击跳转 →` : `
${String(adText).replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"')}
`) : ''} `); // 剩余代码保持不变 if (winState === 'win') { showToast(`🎉 恭喜中奖!获得 ${winAmount} 元`, 3000); addMessage('system', `
🎉 恭喜你,中奖获得${winAmount}元!
`); playWinAnimation(winAmount); } else if (winState === 'loss') { showToast('😔 很遗憾,本期未中奖', 3000); addMessage('system', `
很遗憾,您本期未中奖
`); } isTempLocked = true; updateTimerDisplay(); let lockSec = 5; const lockMsgId = 'lock-' + Date.now(); const lockWrapId = 'lockwrap-' + Date.now(); addMessage('notice', `${lockSec} 秒后可下注`); const lockTimer = setInterval(() => { lockSec--; const el = document.getElementById(lockMsgId); if(el) el.textContent = lockSec; if (lockSec <= 0) { clearInterval(lockTimer); isTempLocked = false; updateTimerDisplay(); const wrap = document.getElementById(lockWrapId); if(wrap) wrap.innerHTML = '✅ 可以下注啦'; } }, 1000); }, 1500); } catch(e) { } } setInterval(fetchStatus, 5000); let currentInputStr = ""; function openBetKeyboard() { $('#betKeyboard').fadeIn(200).css('display', 'flex'); const numbersWrapper = document.getElementById('numbersScroll'); if (numbersWrapper.children.length === 0) { let html = ''; for(let i=0; i<=27; i++) html += ``; numbersWrapper.innerHTML = html; } currentInputStr = ""; updateKeyboardDisplay(); } function closeBetKeyboard() { $('#betKeyboard').fadeOut(200); } function selectNumber(num) { currentInputStr += num + 'T'; updateKeyboardDisplay(); } function inputAmount(val) { currentInputStr += val; updateKeyboardDisplay(); } function selectBetType(type, odds, btn) { currentInputStr += type; updateKeyboardDisplay(); } function deleteLastChar() { if (currentInputStr.length > 0) { currentInputStr = currentInputStr.slice(0, -1); updateKeyboardDisplay(); } } function clearKeyboardInput() { currentInputStr = ""; updateKeyboardDisplay(); } function cancelCurrentBet() { clearKeyboardInput(); closeBetKeyboard(); } function updateKeyboardDisplay() { const el = document.getElementById('keyboardDisplay'); if (currentInputStr) { el.textContent = currentInputStr; el.classList.add('has-value'); } else { el.textContent = '请编辑下注内容'; el.classList.remove('has-value'); } } function parseBetText(text) { const bets = []; let match; const numRegex = /(\d+)T(\d+)/g; while ((match = numRegex.exec(text)) !== null) { bets.push({ type: 'num_' + match[1], amount: parseInt(match[2]) }); } const typeRegex = /(\d+)\s*([\u4e00-\u9fa5]+)|([\u4e00-\u9fa5]+)\s*(\d+)/g; while ((match = typeRegex.exec(text)) !== null) { if (match[1]) bets.push({ type: match[2], amount: parseInt(match[1]) }); else bets.push({ type: match[3], amount: parseInt(match[4]) }); } return bets; } function confirmKeyboardBet() { if (!currentInputStr) { showToast('请输入内容'); return; } if (isTempLocked) { showToast('请等待开奖结束'); return; } if (isLocked) { showToast('已封盘,无法下注'); return; } if (userBetCount >= 2) { showToast('本期下注次数已达上限(2次)'); return; } const bets = parseBetText(currentInputStr); if (bets.length === 0) { showToast('格式错误,支持 1000大双 或 大双1000'); return; } $.ajax({ url: CONFIG.apiUrl + 'action=bet', type: 'POST', contentType: 'application/json', data: JSON.stringify({ bets: bets, round_number: currentPeriod }), success: function(res){ if (typeof res === 'string') { try { res = JSON.parse(res); } catch(e){} } if (res.success) { userBetCount++; lastBetRound = currentPeriod; showToast('下注成功'); document.getElementById('audio-tou').play().catch(e=>{}); bets.forEach(b => addMessage('self', b.type + ':' + b.amount)); if(res.new_balance) document.getElementById('userBalance').textContent = (parseFloat(res.new_balance)||0).toFixed(2); closeBetKeyboard(); currentInputStr = ""; updateKeyboardDisplay(); } else { showToast(res.error || '下注失败'); } }, error: function(){ showToast('网络错误'); } }); } function sendBet() { if (isTempLocked) { showToast('请等待开奖结束'); return; } if (isLocked) { showToast('已封盘,无法下注'); return; } if (userBetCount >= 2) { showToast('本期下注次数已达上限(2次)'); return; } const input = document.getElementById('betInput'); const val = input.value.trim(); if (!val) return; const bets = parseBetText(val); if (bets.length === 0) { showToast('格式错误,支持 1000大双 或 大双1000'); return; } $.ajax({ url: CONFIG.apiUrl + 'action=bet', type: 'POST', contentType: 'application/json', data: JSON.stringify({ bets: bets, round_number: currentPeriod }), success: function(res){ if (typeof res === 'string') { try { res = JSON.parse(res); } catch(e){} } if (res.success) { userBetCount++; lastBetRound = currentPeriod; showToast('下注成功'); document.getElementById('audio-tou').play().catch(e=>{}); input.value = ''; bets.forEach(b => addMessage('self', b.type + ':' + b.amount)); if(res.new_balance) document.getElementById('userBalance').textContent = (parseFloat(res.new_balance)||0).toFixed(2); } else { showToast(res.error || '下注失败'); } }, error: function(){ showToast('网络错误'); } }); } function linkify(text) { const urlPattern = /(https?:\/\/[^\s]+)/g; return text.replace(urlPattern, '$1'); } function mergeBotBetsIntoPlayers(apiPlayers, roundNum) { var rk = String(roundNum || currentPeriod); var botList = botBetsByRound[rk] || []; var byName = {}; apiPlayers.forEach(function(p) { var k = p.username || ('用户' + p.user_id); byName[k] = { user_id: p.user_id, username: k, total: p.total || 0, bets: p.bets || [] }; }); botList.forEach(function(b) { var k = b.username; if (!byName[k]) byName[k] = { user_id: 'bot_' + k, username: k, total: 0, bets: [] }; byName[k].total += (b.amount || 0); byName[k].bets.push({ type: b.type, amount: b.amount || 0 }); }); return Object.values(byName); } function fetchBetSummaryAndShow() { var roundForBill = String(currentPeriod); $.getJSON(CONFIG.apiUrl + 'action=bet_summary&round_number=' + encodeURIComponent(roundForBill) + '&t=' + Date.now(), function(res){ var apiPlayers = (res && res.players) ? res.players : []; var players = mergeBotBetsIntoPlayers(apiPlayers, roundForBill); addBetBillMessage(roundForBill, players); }).fail(function(){ var players = mergeBotBetsIntoPlayers([], roundForBill); addBetBillMessage(roundForBill, players); }); } let lastBetBillByRound = {}; function addBetBillMessage(roundNum, players) { lastBetBillByRound[roundNum] = players; let listHtml = ''; if (players.length === 0) { listHtml = '
暂无玩家下注
'; } else { listHtml = players.map(function(p, i) { return '' + '
' + '
' + (p.username || ('游客U' + (p.user_id || ''))) + '
' + '
' + '
'; }).join(''); } const content = '
' + '
第 ' + roundNum + ' 期玩家竞猜账单
' + '
' + listHtml + '
' + '
'; addMessage('robot', content); const chat = document.getElementById('chatArea'); const lastMsg = chat.querySelector('.c28-message:last-child'); if (lastMsg) lastMsg.querySelectorAll('.c28-bet-bill-row').forEach(function(row){ row.onclick = function(){ var rn = this.getAttribute('data-round'); var idx = parseInt(this.getAttribute('data-idx'), 10); var plist = lastBetBillByRound[rn] || []; if (plist[idx]) showPlayerBetDetail(plist[idx]); }; }); } function showPlayerBetDetail(player) { if (!player) return; var name = player.username || ('用户' + player.user_id); document.getElementById('playerBetDetailTitle').innerHTML = '' + name + '下注详情' + (player.total || 0) + '元'; var list = document.getElementById('playerBetDetailList'); var html = ''; (player.bets || []).forEach(function(b){ html += '
' + (b.type || '') + '' + (b.amount || 0) + '
'; }); list.innerHTML = html || '
无下注明细
'; document.getElementById('playerBetDetailModal').style.display = 'flex'; } function closePlayerBetDetail() { document.getElementById('playerBetDetailModal').style.display = 'none'; } function addMessage(who, content) { const chat = document.getElementById('chatArea'); const isNearBottom = chat.scrollHeight - chat.scrollTop - chat.clientHeight < 100; const div = document.createElement('div'); if (who === 'notice') { div.style.cssText = 'text-align:center;padding:8px 0;'; div.innerHTML = `${content}`; chat.appendChild(div); if(isNearBottom) chat.scrollTop = chat.scrollHeight; return; } div.className = 'c28-message ' + (who === 'self' ? 'self' : ''); let avatarHtml, username; if (who === 'self') { avatarHtml = ``; username = '我'; } else if (who === 'robot') { avatarHtml = ``; username = ROBOT_NAME || '开奖机器人'; } else { avatarHtml = ``; username = SYSTEM_NAME; } if (who === 'system') content = linkify(content); div.innerHTML = `
${avatarHtml}
${username} ${new Date().toTimeString().substr(0,8)}
${content}
`; chat.appendChild(div); if(isNearBottom || who === 'self') chat.scrollTop = chat.scrollHeight; } function showToast(msg, duration = 2000) { const el = document.getElementById('toast'); el.textContent = msg; el.classList.add('show'); setTimeout(() => el.classList.remove('show'), duration); } const BOT_NAMES = ['闪电⚡熊🐻', '孤勇者', '天涯', '快乐小狗', '在此一位', '赢赢赢', '财神到', '运气爆棚', '小小的愿望', 'MVP', '拓哥']; const BET_TYPES = ['大', '小', '单', '双', '大单', '小双', '大双', '小单']; const BET_AMOUNTS = [10, 20, 50, 100, 200, 500, 1000]; function botLoop() { const delay = Math.random() * (CONFIG.botInterval[1] - CONFIG.botInterval[0]) + CONFIG.botInterval[0]; setTimeout(() => { if (!isLocked && !isTempLocked) { let name; if(Math.random() > 0.2) name = '游客U' + Math.floor(Math.random() * 9000 + 1000); else name = BOT_NAMES[Math.floor(Math.random() * BOT_NAMES.length)]; if (!botBetCounts[name]) botBetCounts[name] = 0; if (botBetCounts[name] < 2) { const type = BET_TYPES[Math.floor(Math.random() * BET_TYPES.length)]; const amount = BET_AMOUNTS[Math.floor(Math.random() * BET_AMOUNTS.length)]; botBetCounts[name]++; var rk = String(currentPeriod); if (!botBetsByRound[rk]) botBetsByRound[rk] = []; botBetsByRound[rk].push({username: name, type: type, amount: amount}); const chat = document.getElementById('chatArea'); const isNearBottom = chat.scrollHeight - chat.scrollTop - chat.clientHeight < 100; const div = document.createElement('div'); div.className = 'c28-message'; const avatarHtml = ``; div.innerHTML = `
${avatarHtml}
${name} ${new Date().toTimeString().substr(0,8)}
${type}:${amount}
`; chat.appendChild(div); if (isNearBottom) chat.scrollTop = chat.scrollHeight; } } botLoop(); }, delay); } botLoop(); function confirmFollow(type, amount) { if (userBetCount >= 2) { showToast('本期下注次数已达上限'); return; } document.getElementById('betInput').value = type + amount; sendBet(); } function tryRescue() { $.getJSON(CONFIG.apiUrl + 'action=rescue', function(res){ if(res.success) { addMessage('system', res.msg); showToast('💰 ' + res.msg); userCoins = res.new_coins; document.getElementById('userBalance').textContent = (parseFloat(userCoins)||0).toFixed(2); } }); } document.addEventListener('DOMContentLoaded', function(){});
恭喜中奖
+0
×