腾讯云新用户 · 限时秒杀4核4G3M 300GB/月 38元一年抢购脚本

腾讯云新用户38一年的服务器,抢了好几天都没抢到就让gpt写了个脚本 购买地址: https://cloud.tencent.com/act/pro/featured-202604?from=29774 // ==UserScript== // @name Tencent Cloud Flash H...
腾讯云新用户 · 限时秒杀4核4G3M 300GB/月 38元一年抢购脚本
腾讯云新用户 · 限时秒杀4核4G3M 300GB/月 38元一年抢购脚本

腾讯云新用户38一年的服务器,抢了好几天都没抢到就让gpt写了个脚本

image
购买地址:https://cloud.tencent.com/act/pro/featured-202604?from=29774

// ==UserScript==
// @name         Tencent Cloud Flash Helper
// @namespace    local.tencent.cloud.flash
// @version      0.1.0
// @author       GPT5.5
// @description  Region-selectable bounded request helper for Tencent Cloud activity page.
// @match        https://cloud.tencent.com/act/pro/featured-202604*
// @run-at       document-idle
// @grant        none
// ==/UserScript==

(function () {
  'use strict';

  const API_URL = 'https://act-api.cloud.tencent.com/dianshi/do-goods';
  const STORAGE_KEY = 'tencentCloudFlashHelperState';
  const DEFAULT_INTERVAL_MS = 200;
  const DEFAULT_DURATION_MS = 15 * 1000;
  const EARLY_START_MS = 500;
  const REGIONS = [
    { id: 4, label: '上海' },
    { id: 8, label: '广州' },
    { id: 1, label: '北京' },
  ];

  const PAYLOAD_TEMPLATE = {
    activity_id: 162634773874417,
    goods: [
      {
        act_id: 1784747698901873,
        type: 'lighthouse_v5',
        goods_param: {
          zone: '',
          timeSpanUnit: '12m',
          scenario: '0',
          goodsNum: 1,
          ddocUnionConnect: 0,
          area: 1,
          regionId: 4,
          BlueprintId: 'LINUX_UNIX',
          imageId: 'lhbp-qje6xg9k',
          type: 'bundle_budget_mc_lg4_01',
        },
        page_from: 'act_buy',
      },
    ],
    preview: 0,
    agent_channel: {
      fromChannel: '',
      fromSales: '',
      isAgentClient: false,
      fromUrl:
        'https://cloud.tencent.com/act/pro/featured-202604?fromSource=gwzcw.12145564.12145564.12145564&utm_medium=cpc&utm_id=gwzcw.12145564.12145564.12145564&thirdparty=1&tk=3af777ac-73d2-4b06-8f39-5ed1b50d11c5#MS',
      agent_key: '',
    },
    business: {
      id: 23544,
      from: 'lightningDeals',
    },
  };

  function clone(value) {
    return JSON.parse(JSON.stringify(value));
  }

  function buildPayload(regionId) {
    const payload = clone(PAYLOAD_TEMPLATE);
    payload.goods[0].goods_param.regionId = Number(regionId);
    return payload;
  }

  function parseCookie(cookieText) {
    return String(cookieText || '')
      .split(';')
      .map((item) => item.trim())
      .filter(Boolean)
      .reduce((cookies, item) => {
        const eqIndex = item.indexOf('=');
        if (eqIndex === -1) return cookies;
        const key = item.slice(0, eqIndex);
        const value = item.slice(eqIndex + 1);
        cookies[key] = decodeURIComponent(value);
        return cookies;
      }, {});
  }

  function hash33(text) {
    let hash = 5381;
    for (let i = 0; i < text.length; i += 1) {
      hash += (hash << 5) + text.charCodeAt(i);
    }
    return String(hash & 0x7fffffff);
  }

  function deriveCsrfToken(cookieText) {
    const cookies = parseCookie(cookieText);
    if (cookies.skey) return hash33(cookies.skey);
    if (cookies.p_skey) return hash33(cookies.p_skey);
    if (cookies.qcmainCSRFToken) return cookies.qcmainCSRFToken;
    return '';
  }

  function resolveCsrfToken(cookieText) {
    const cookies = parseCookie(cookieText);
    if (cookies.skey) return { token: hash33(cookies.skey), source: 'skey' };
    if (cookies.p_skey) return { token: hash33(cookies.p_skey), source: 'p_skey' };
    if (cookies.qcmainCSRFToken) return { token: cookies.qcmainCSRFToken, source: 'qcmainCSRFToken' };
    return { token: '', source: '' };
  }

  function maskSecret(value) {
    const text = String(value || '');
    if (!text) return '';
    if (text.length <= 8) return `${text.slice(0, 2)}****`;
    return `${text.slice(0, 4)}****${text.slice(-3)}`;
  }

  function inspectAuthState(cookieText) {
    const cookies = parseCookie(cookieText);
    const keys = Object.keys(cookies);
    const resolved = resolveCsrfToken(cookieText);
    return {
      cookieFound: keys.length > 0,
      cookieCount: keys.length,
      hasSkey: Boolean(cookies.skey),
      hasPSkey: Boolean(cookies.p_skey),
      hasUin: Boolean(cookies.uin),
      csrfFound: Boolean(resolved.token),
      csrfSource: resolved.source,
      csrfMasked: maskSecret(resolved.token),
    };
  }

  function clamp(value, min, max) {
    return Math.min(Math.max(value, min), max);
  }

  function calculatePanelPosition(options) {
    const margin = 8;
    const maxLeft = Math.max(margin, options.viewportWidth - options.panelWidth - margin);
    const maxTop = Math.max(margin, options.viewportHeight - options.panelHeight - margin);
    return {
      left: clamp(options.pointerX - options.offsetX, margin, maxLeft),
      top: clamp(options.pointerY - options.offsetY, margin, maxTop),
    };
  }

  function getNextWindow(now = new Date()) {
    const saleTimes = [
      { hour: 10, minute: 0, label: '10:00' },
      { hour: 15, minute: 0, label: '15:00' },
    ];
    for (const sale of saleTimes) {
      const saleAt = new Date(now);
      saleAt.setHours(sale.hour, sale.minute, 0, 0);
      const startAt = new Date(saleAt.getTime() - EARLY_START_MS);
      if (now < new Date(saleAt.getTime() + DEFAULT_DURATION_MS)) {
        return {
          saleLabel: sale.label,
          saleAt,
          startAt,
          endAt: new Date(startAt.getTime() + DEFAULT_DURATION_MS),
        };
      }
    }

    const tomorrow = new Date(now);
    tomorrow.setDate(tomorrow.getDate() + 1);
    tomorrow.setHours(10, 0, 0, 0);
    return {
      saleLabel: '10:00',
      saleAt: tomorrow,
      startAt: new Date(tomorrow.getTime() - EARLY_START_MS),
      endAt: new Date(tomorrow.getTime() - EARLY_START_MS + DEFAULT_DURATION_MS),
    };
  }

  function isSuccessResponse(data) {
    if (!data || typeof data !== 'object') return false;
    if (data.code === 0) return true;
    if (typeof data.msg === 'string' && data.msg.toLowerCase() === 'ok') return true;
    return false;
  }

  const core = {
    API_URL,
    REGIONS,
    buildPayload,
    calculatePanelPosition,
    deriveCsrfToken,
    inspectAuthState,
    getNextWindow,
    isSuccessResponse,
    maskSecret,
    parseCookie,
  };

  window.__TencentCloudFlashCore = core;

  if (!window.document || !document.body) return;

  let timer = null;
  let sender = null;
  let countdown = null;
  let running = false;
  let panel;

  function loadState() {
    try {
      return JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}');
    } catch (_) {
      return {};
    }
  }

  function saveState(state) {
    localStorage.setItem(STORAGE_KEY, JSON.stringify({ ...loadState(), ...state }));
  }

  function formatTime(date) {
    return date.toLocaleTimeString('zh-CN', { hour12: false });
  }

  function getEls() {
    return {
      region: panel.querySelector('[data-role="region"]'),
      arm: panel.querySelector('[data-role="arm"]'),
      testSend: panel.querySelector('[data-role="test-send"]'),
      cookieState: panel.querySelector('[data-role="cookie-state"]'),
      csrfState: panel.querySelector('[data-role="csrf-state"]'),
      status: panel.querySelector('[data-role="status"]'),
      log: panel.querySelector('[data-role="log"]'),
    };
  }

  function setStatus(message) {
    getEls().status.textContent = message;
  }

  function setRunningControls(isRunning) {
    const els = getEls();
    els.arm.textContent = isRunning ? '停止' : '开始';
    els.arm.classList.toggle('is-stop', isRunning);
  }

  function applyPanelPosition(position) {
    if (!position || typeof position.left !== 'number' || typeof position.top !== 'number') return;
    const rect = panel.getBoundingClientRect();
    const next = calculatePanelPosition({
      pointerX: position.left,
      pointerY: position.top,
      offsetX: 0,
      offsetY: 0,
      panelWidth: rect.width,
      panelHeight: rect.height,
      viewportWidth: window.innerWidth,
      viewportHeight: window.innerHeight,
    });
    panel.style.left = `${next.left}px`;
    panel.style.top = `${next.top}px`;
    panel.style.right = 'auto';
    panel.style.bottom = 'auto';
  }

  function enablePanelDrag() {
    const handle = panel.querySelector('[data-role="drag-handle"]');
    if (!handle) return;

    handle.addEventListener('pointerdown', (event) => {
      if (event.button !== 0) return;
      const rect = panel.getBoundingClientRect();
      const offsetX = event.clientX - rect.left;
      const offsetY = event.clientY - rect.top;
      handle.setPointerCapture?.(event.pointerId);
      event.preventDefault();

      function movePanel(moveEvent) {
        const next = calculatePanelPosition({
          pointerX: moveEvent.clientX,
          pointerY: moveEvent.clientY,
          offsetX,
          offsetY,
          panelWidth: rect.width,
          panelHeight: rect.height,
          viewportWidth: window.innerWidth,
          viewportHeight: window.innerHeight,
        });
        panel.style.left = `${next.left}px`;
        panel.style.top = `${next.top}px`;
        panel.style.right = 'auto';
        panel.style.bottom = 'auto';
      }

      function stopDragging(upEvent) {
        document.removeEventListener('pointermove', movePanel);
        document.removeEventListener('pointerup', stopDragging);
        handle.releasePointerCapture?.(upEvent.pointerId);
        const finalRect = panel.getBoundingClientRect();
        saveState({ panelPosition: { left: finalRect.left, top: finalRect.top } });
      }

      document.addEventListener('pointermove', movePanel);
      document.addEventListener('pointerup', stopDragging);
    });
  }

  function addLog(message, data) {
    const log = getEls().log;
    const line = document.createElement('div');
    const time = formatTime(new Date());
    const suffix = data === undefined ? '' : ` ${JSON.stringify(data).slice(0, 260)}`;
    line.textContent = `[${time}] ${message}${suffix}`;
    log.prepend(line);
    while (log.children.length > 12) {
      log.removeChild(log.lastChild);
    }
  }

  function readConfig() {
    const els = getEls();
    const state = {
      regionId: Number(els.region.value),
    };
    saveState(state);
    return state;
  }

  function buildHeaders(config) {
    const token = resolveCsrfToken(document.cookie).token;
    const headers = {
      Accept: 'application/json, text/plain, */*',
      'Content-Type': 'application/json',
      'X-Requested-With': 'XMLHttpRequest',
    };
    if (token) headers['X-CSRF-TOKEN'] = token;
    return headers;
  }

  function formatAuthState(authState) {
    const cookieText = authState.cookieFound
      ? `已检测可读项(${authState.cookieCount} 项,skey:${authState.hasSkey ? '有' : '无'},p_skey:${authState.hasPSkey ? '有' : '无'},uin:${authState.hasUin ? '有' : '无'})`
      : '未检测到可读 Cookie,HttpOnly Cookie 仍可能由浏览器自动携带';
    const csrfText = authState.csrfFound
      ? `已获取(来源:${authState.csrfSource},${authState.csrfMasked})`
      : '未获取,请确认已登录腾讯云';
    return { cookieText, csrfText };
  }

  function refreshAuthState(writeLog = false) {
    const els = getEls();
    const authState = inspectAuthState(document.cookie);
    const formatted = formatAuthState(authState);
    els.cookieState.textContent = formatted.cookieText;
    els.csrfState.textContent = formatted.csrfText;
    if (writeLog) {
      addLog(`登录态检测:可读 Cookie ${authState.cookieFound ? '已检测' : '未检测'},CSRF ${authState.csrfFound ? '已获取' : '未获取'}`);
    }
    return authState;
  }

  async function sendOnce(config) {
    const response = await fetch(API_URL, {
      method: 'POST',
      mode: 'cors',
      credentials: 'include',
      headers: buildHeaders(config),
      body: JSON.stringify(buildPayload(config.regionId)),
    });
    const text = await response.text();
    let data;
    try {
      data = JSON.parse(text);
    } catch (_) {
      data = { status: response.status, body: text.slice(0, 500) };
    }
    return { ok: response.ok, status: response.status, data };
  }

  function stop(reason) {
    running = false;
    if (timer) clearTimeout(timer);
    if (sender) clearInterval(sender);
    if (countdown) clearInterval(countdown);
    timer = null;
    sender = null;
    countdown = null;
    setRunningControls(false);
    setStatus(reason || '已停止');
  }

  function clearScheduledWork() {
    if (timer) clearTimeout(timer);
    if (sender) clearInterval(sender);
    if (countdown) clearInterval(countdown);
    timer = null;
    sender = null;
    countdown = null;
  }

  function startSending(config, activeWindow) {
    if (running) return;
    running = true;
    setRunningControls(true);
    const startedAt = Date.now();
    let attempts = 0;
    setStatus(`发送中:${activeWindow.saleLabel}`);
    addLog(`开始发送,地区 ${config.regionId}`);

    sender = setInterval(async () => {
      attempts += 1;
      if (Date.now() - startedAt >= DEFAULT_DURATION_MS) {
        addLog(`到达 15 秒上限,共 ${attempts} 次`);
        stop('已到达发送上限');
        return;
      }

      try {
        const result = await sendOnce(config);
        addLog(`第 ${attempts} 次,HTTP ${result.status}`, result.data);
        if (result.ok && isSuccessResponse(result.data)) {
          stop(`检测到成功响应,共 ${attempts} 次`);
        }
      } catch (error) {
        addLog(`第 ${attempts} 次失败`, { message: error.message });
      }
    }, DEFAULT_INTERVAL_MS);
  }

  function arm() {
    clearScheduledWork();
    running = false;
    setRunningControls(true);
    const config = readConfig();
    const authState = refreshAuthState(true);
    const activeWindow = getNextWindow(new Date());
    const waitMs = Math.max(0, activeWindow.startAt.getTime() - Date.now());
    setStatus(`已设置:${activeWindow.saleLabel},${formatTime(activeWindow.startAt)} 开始`);
    addLog(`等待 ${activeWindow.saleLabel},提前 0.5 秒开始,地区 ${config.regionId}`);
    if (!authState.cookieFound || !authState.csrfFound) {
      addLog('提示:Cookie 或 CSRF 未检测完整,请确认已登录腾讯云');
    }

    countdown = setInterval(() => {
      const leftMs = activeWindow.startAt.getTime() - Date.now();
      if (leftMs <= 0) {
        setStatus(`即将发送:${activeWindow.saleLabel}`);
        return;
      }
      setStatus(`已设置:${activeWindow.saleLabel},剩余 ${Math.ceil(leftMs / 1000)} 秒`);
    }, 1000);

    timer = setTimeout(() => {
      if (countdown) clearInterval(countdown);
      countdown = null;
      startSending(config, activeWindow);
    }, waitMs);
  }

  function toggleRun() {
    if (timer || sender || countdown || running) {
      stop('手动停止');
      return;
    }
    arm();
  }

  async function testSendOnce() {
    const config = readConfig();
    const authState = refreshAuthState(true);
    setStatus('正在发送测试请求...');
    addLog(`测试请求:立即发送一次,地区 ${config.regionId}`);
    if (!authState.cookieFound || !authState.csrfFound) {
      addLog('提示:Cookie 或 CSRF 未检测完整,请确认已登录腾讯云');
    }

    try {
      const result = await sendOnce(config);
      addLog(`测试请求完成,HTTP ${result.status}`, result.data);
      setStatus(`测试请求完成:HTTP ${result.status}`);
    } catch (error) {
      addLog('测试请求失败', { message: error.message });
      setStatus('测试请求失败');
    }
  }

  function createPanel() {
    const state = loadState();
    panel = document.createElement('div');
    panel.id = 'tencent-cloud-flash-helper';
    panel.innerHTML = `
      <style>
        #tencent-cloud-flash-helper {
          position: fixed;
          right: 16px;
          bottom: 16px;
          z-index: 2147483647;
          width: 320px;
          box-sizing: border-box;
          padding: 12px;
          border: 1px solid rgba(0, 0, 0, 0.14);
          border-radius: 8px;
          background: #ffffff;
          color: #1f2329;
          font: 13px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
          box-shadow: 0 8px 26px rgba(0, 0, 0, 0.18);
        }
        #tencent-cloud-flash-helper * { box-sizing: border-box; }
        #tencent-cloud-flash-helper .tc-row {
          display: grid;
          grid-template-columns: 70px 1fr;
          gap: 8px;
          align-items: center;
          margin-top: 8px;
        }
        #tencent-cloud-flash-helper label { color: #4e5969; }
        #tencent-cloud-flash-helper input,
        #tencent-cloud-flash-helper select {
          width: 100%;
          height: 30px;
          border: 1px solid #c9cdd4;
          border-radius: 4px;
          padding: 4px 8px;
          font: inherit;
        }
        #tencent-cloud-flash-helper .tc-title {
          display: flex;
          justify-content: space-between;
          align-items: center;
          font-weight: 600;
          cursor: move;
          user-select: none;
          touch-action: none;
        }
        #tencent-cloud-flash-helper .tc-actions {
          display: grid;
          grid-template-columns: 1fr 1fr;
          gap: 8px;
          margin-top: 10px;
        }
        #tencent-cloud-flash-helper button {
          height: 32px;
          border: 0;
          border-radius: 4px;
          background: #176bff;
          color: #fff;
          cursor: pointer;
          font: inherit;
        }
        #tencent-cloud-flash-helper button.is-stop { background: #d54941; }
        #tencent-cloud-flash-helper .tc-status {
          margin-top: 10px;
          padding: 8px;
          border-radius: 4px;
          background: #f2f3f5;
          color: #1f2329;
        }
        #tencent-cloud-flash-helper .tc-auth {
          margin-top: 10px;
          padding: 8px;
          border-radius: 4px;
          background: #f7f8fa;
          color: #1f2329;
        }
        #tencent-cloud-flash-helper .tc-auth div {
          margin-top: 4px;
          word-break: break-word;
        }
        #tencent-cloud-flash-helper .tc-log {
          margin-top: 8px;
          max-height: 180px;
          overflow: auto;
          font-size: 12px;
          color: #4e5969;
          word-break: break-all;
        }
      </style>
      <div class="tc-title" data-role="drag-handle">
        <span>腾讯云抢购辅助</span>
        <span>10:00 / 15:00</span>
      </div>
      <div class="tc-row">
        <label>地区</label>
        <select data-role="region">
          ${REGIONS.map((region) => `<option value="${region.id}">${region.label}</option>`).join('')}
        </select>
      </div>
      <div class="tc-auth">
        <div><strong>可读 Cookie:</strong><span data-role="cookie-state">待检测</span></div>
        <div><strong>X-CSRF-TOKEN:</strong><span data-role="csrf-state">待检测</span></div>
      </div>
      <div class="tc-actions">
        <button type="button" data-role="arm">开始</button>
        <button type="button" data-role="test-send">测试请求</button>
      </div>
      <div class="tc-status" data-role="status">请选择地区并点击开始</div>
      <div class="tc-log" data-role="log"></div>
    `;
    document.body.appendChild(panel);
    applyPanelPosition(state.panelPosition);
    enablePanelDrag();

    const els = getEls();
    els.region.value = String(state.regionId || 4);
    setRunningControls(false);
    els.arm.addEventListener('click', toggleRun);
    els.testSend.addEventListener('click', testSendOnce);

    refreshAuthState(false);
  }

  createPanel();
})();

7 个帖子 - 6 位参与者

阅读完整话题

来源: LinuxDo 最新话题查看原文