Florr.io Super Ping(开发版)

Detects Super spawns in Florr.io, displays notifications, styled Super Ping messages, always visible, edge collision, language support, resizable UI, and hotkey recording. Includes a movable log window and UI toggles, with persistent UI positions.

  1. // ==UserScript==
  2. // @name Florr.io Super Ping(开发版)
  3. // @namespace http://tampermonkey.net/
  4. // @version 2.1
  5. // @license MIT
  6. // @description Detects Super spawns in Florr.io, displays notifications, styled Super Ping messages, always visible, edge collision, language support, resizable UI, and hotkey recording. Includes a movable log window and UI toggles, with persistent UI positions.
  7. // @author william
  8. // @match https://florr.io/*
  9. // @grant GM_addStyle
  10. // @grant GM_getValue
  11. // @grant GM_setValue
  12. // @grant GM_registerMenuCommand
  13. // @require https://code.jquery.com/jquery-3.6.0.min.js
  14. // ==/UserScript==
  15.  
  16. (function() {
  17. 'use strict';
  18.  
  19. // 添加 CSS 样式
  20. GM_addStyle(`
  21. /* 设置按钮和语言按钮的共同容器 */
  22. #button-container {
  23. position: fixed;
  24. bottom: 10px;
  25. right: 10px;
  26. display: flex; /* 使用 Flexbox 布局 */
  27. align-items: center; /* 垂直居中 */
  28. gap: 5px; /* 按钮之间的间距 */
  29. z-index: 10001; /* 确保按钮在容器上方 */
  30. }
  31.  
  32. #super-ping-container {
  33. position: fixed;
  34. top: 50%; /* 垂直居中 */
  35. right: 10px; /* 靠右侧 */
  36. transform: translateY(-50%); /* 垂直居中 */
  37. background-color: rgba(0, 100, 0, 0.7); /* 深绿色背景 */
  38. color: white;
  39. padding: 15px; /* 增加内边距 */
  40. border-radius: 5px;
  41. z-index: 9999;
  42. resize: both; /* 允许用户调整大小 */
  43. overflow: auto; /* 确保内容不会溢出 */
  44. font-family: sans-serif; /* 使用更清晰的字体 */
  45. border: 2px solid #8FBC8F; /* 添加边框 */
  46. box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3); /* 添加阴影 */
  47. font-size: 1.0em; /* 稍微增大字体大小 */
  48. width: 300px; /* 设置初始宽度 */
  49. height: 200px; /* 设置初始高度 */
  50. }
  51.  
  52. #super-ping-container h3 {
  53. margin-top: 0;
  54. margin-bottom: 5px;
  55. font-size: 1.4em; /* 稍微增大标题字体 */
  56. text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); /* 添加文字阴影 */
  57. }
  58.  
  59. #super-ping-container p {
  60. margin: 0;
  61. font-size: 1.0em; /* 稍微增大字体大小 */
  62. line-height: 1.4; /* 增加行高 */
  63. }
  64.  
  65. #super-ping-history {
  66. max-height: 200px; /* 增加历史记录高度 */
  67. overflow-y: auto;
  68. margin-top: 10px;
  69. padding: 5px;
  70. border: 1px solid #555;
  71. border-radius: 3px;
  72. background-color: rgba(0, 0, 0, 0.3); /* 历史记录背景 */
  73. }
  74.  
  75. #super-ping-history p {
  76. margin: 5px 0; /* 增加历史记录条目间距 */
  77. font-size: 0.9em;
  78. border-bottom: 1px solid #444; /* 添加分割线 */
  79. padding-bottom: 5px; /* 增加底部内边距 */
  80. }
  81.  
  82. #super-ping-history p:last-child {
  83. border-bottom: none; /* 移除最后一个条目的分割线 */
  84. }
  85.  
  86. #settings-container {
  87. position: fixed;
  88. top: 50%;
  89. left: 50%;
  90. transform: translate(-50%, -50%);
  91. background-color: rgba(0, 0, 0, 0.8);
  92. color: white;
  93. padding: 20px;
  94. border-radius: 10px;
  95. z-index: 10000;
  96. display: none; /* 初始状态隐藏 */
  97. }
  98.  
  99. #settings-container label {
  100. display: block;
  101. margin-bottom: 5px;
  102. }
  103.  
  104. #settings-container input,
  105. #settings-container select {
  106. margin-bottom: 10px;
  107. padding: 5px;
  108. border-radius: 3px;
  109. border: none;
  110. background-color: #333;
  111. color: white;
  112. }
  113.  
  114. #settings-container button {
  115. background-color: #4CAF50;
  116. color: white;
  117. padding: 10px 15px;
  118. border: none;
  119. border-radius: 5px;
  120. cursor: pointer;
  121. }
  122.  
  123. #settings-container button:hover {
  124. background-color: #3e8e41;
  125. }
  126.  
  127. /* 调整大小手柄的样式 (可选) */
  128. #super-ping-container::-webkit-resizer {
  129. background: #444;
  130. border: 1px solid #666;
  131. }
  132.  
  133. /* Super Ping 消息样式 */
  134. .super-text {
  135. color: yellow; /* 修改为黄色 */
  136. font-weight: bold; /* 加粗 */
  137. text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); /* 添加文字阴影 */
  138. }
  139.  
  140. .entity-text {
  141. color: lightblue; /* 修改为淡蓝色 */
  142. }
  143.  
  144. /* 设置按钮样式 */
  145. #settings-button {
  146. background-color: rgba(0, 0, 0, 0.5);
  147. color: white;
  148. width: auto; /* 宽度自适应内容 */
  149. height: auto; /* 高度自适应内容 */
  150. min-width: 50px; /* 最小宽度 */
  151. min-height: 50px; /* 最小高度 */
  152. padding: 8px 12px; /* 内边距 */
  153. border-radius: 0px; /* 设置为方形 */
  154. cursor: pointer;
  155. border: none; /* 移除边框 */
  156. font-size: 16px; /* 调整字体大小 */
  157. display: flex; /* 使用 Flexbox 布局 */
  158. justify-content: center; /* 水平居中 */
  159. align-items: center; /* 垂直居中 */
  160. text-align: center; /* 确保文字居中 */
  161. box-sizing: border-box; /* 确保内边距不影响总尺寸 */
  162. }
  163.  
  164. #settings-button:hover {
  165. background-color: rgba(0, 0, 0, 0.8);
  166. }
  167.  
  168. /* 快捷语言切换按钮样式 */
  169. #language-switch-button {
  170. background-color: rgba(0, 0, 0, 0.5);
  171. color: white;
  172. width: auto; /* 宽度自适应内容 */
  173. height: auto; /* 高度自适应内容 */
  174. min-width: 50px; /* 最小宽度 */
  175. min-height: 50px; /* 最小高度 */
  176. padding: 8px 12px; /* 内边距 */
  177. border-radius: 0px; /* 设置为方形 */
  178. cursor: pointer;
  179. border: none; /* 移除边框 */
  180. font-size: 16px; /* 调整字体大小 */
  181. display: flex; /* 使用 Flexbox 布局 */
  182. justify-content: center; /* 水平居中 */
  183. align-items: center; /* 垂直居中 */
  184. text-align: center; /* 确保文字居中 */
  185. box-sizing: border-box; /* 确保内边距不影响总尺寸 */
  186. /* 限制语言切换按钮的最大宽度 */
  187. max-width: 80px; /* 根据需要调整 */
  188. overflow: hidden; /* 隐藏溢出的文本 */
  189. white-space: nowrap; /* 防止文本换行 */
  190. }
  191.  
  192. #language-switch-button:hover {
  193. background-color: rgba(0, 0, 0, 0.8);
  194. }
  195.  
  196. /* 快捷键录制样式 */
  197. #hotkey-input {
  198. cursor: pointer; /* 指示可点击 */
  199. }
  200.  
  201. #hotkey-input.recording {
  202. background-color: #ffc107; /* 醒目的颜色 */
  203. color: black;
  204. cursor: wait; /* 指示正在录制 */
  205. }
  206.  
  207. /* 最后的 Super 样式 */
  208. #last-super-info {
  209. font-size: 1.2em; /* 增大字体 */
  210. font-weight: bold; /* 加粗 */
  211. margin-bottom: 5px; /* 增加间距 */
  212. text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); /* 添加文字阴影 */
  213. }
  214.  
  215. /* Super 和 Server 标签样式 */
  216. #super-type-label,
  217. #super-server-label {
  218. font-size: 0.9em; /* 减小字体 */
  219. text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); /* 添加文字阴影 */
  220. }
  221.  
  222. /* Super 类型图标样式 */
  223. #super-type {
  224. display: inline-block; /* 确保 span 可以设置宽度和高度 */
  225. width: 20px; /* 设置图标宽度 */
  226. height: 20px; /* 设置图标高度 */
  227. background-size: contain; /* 确保图标缩放到合适的大小 */
  228. background-repeat: no-repeat; /* 防止图标重复 */
  229. background-position: center; /* 居中显示图标 */
  230. margin-right: 5px; /* 调整图标与文字的间距 */
  231. }
  232.  
  233. /* Log Window Styles */
  234. #log-container {
  235. position: fixed;
  236. top: 20px;
  237. right: 20px;
  238. background-color: rgba(0, 0, 0, 0.7); /* 半透明黑色背景 */
  239. color: white;
  240. padding: 10px;
  241. border-radius: 5px;
  242. z-index: 9998; /* 确保在 Super Ping 容器下方 */
  243. resize: both;
  244. overflow: auto;
  245. font-family: monospace; /* 使用等宽字体 */
  246. border: 1px solid #555;
  247. box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);
  248. max-height: 400px; /* 设置最大高度 */
  249. max-width: 500px; /* 设置最大宽度 */
  250. font-size: 0.9em; /* 稍微增大字体大小 */
  251. line-height: 1.4; /* 增加行高 */
  252. min-width: 200px; /* 添加最小宽度 */
  253. min-height: 100px; /* 添加最小高度 */
  254. display: none; /* 初始状态隐藏 */
  255. }
  256.  
  257. #log-container h3 {
  258. margin-top: 0;
  259. margin-bottom: 5px;
  260. font-size: 1.1em;
  261. text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
  262. }
  263.  
  264. #log-output {
  265. white-space: pre-wrap; /* 保留空格和换行 */
  266. font-size: 0.8em;
  267. line-height: 1.3;
  268. word-break: break-word; /* 允许单词断行 */
  269. }
  270.  
  271. /* Server Info Styles */
  272. #server-info-container {
  273. position: fixed;
  274. bottom: 70px; /* 调整到 Settings 按钮上方 */
  275. right: 10px; /* 与 Settings 按钮对齐 */
  276. background-color: rgba(0, 0, 0, 0.5);
  277. color: white;
  278. padding: 8px;
  279. border-radius: 3px;
  280. font-size: 0.9em;
  281. text-align: center;
  282. z-index: 9997; /* 确保在 Super Ping 容器下方 */
  283. display: none; /* 初始状态隐藏 */
  284. }
  285.  
  286. /* Fullscreen Suggestion Styles */
  287. #fullscreen-suggestion {
  288. position: fixed;
  289. top: 10px;
  290. left: 50%;
  291. transform: translateX(-50%);
  292. background-color: rgba(255, 0, 0, 0.7); /* 设置背景颜色为红色,透明度为 0.7 */
  293. color: yellow; /* 设置字体颜色为黄色 */
  294. padding: 5px 10px; /* 稍微减小内边距 */
  295. border-radius: 5px;
  296. z-index: 10002; /* 确保在所有其他 UI 元素之上 */
  297. font-size: 0.8em; /* 稍微减小字体大小 */
  298. font-weight: bold;
  299. text-align: center;
  300. opacity: 0.9; /* 设置初始透明度 */
  301. transition: opacity 1s ease-in-out; /* 添加过渡效果 */
  302. display: flex; /* 使用 Flexbox 布局 */
  303. align-items: center; /* 垂直居中 */
  304. justify-content: center; /* 水平居中 */
  305. }
  306.  
  307. #fullscreen-suggestion.fade-out {
  308. opacity: 0; /* 设置透明度为 0 */
  309. }
  310.  
  311. /* 警示图标样式 */
  312. #fullscreen-suggestion::before {
  313. content: "\\26A0"; /* Unicode 字符,表示警告符号 */
  314. margin-right: 5px; /* 调整图标与文字的间距 */
  315. font-size: 1em; /* 调整图标大小 */
  316. }
  317.  
  318. /* FPS Counter Styles */
  319. #fps-counter {
  320. position: fixed;
  321. bottom: 10px;
  322. right: 150px; /* Adjust as needed to position next to other buttons */
  323. background-color: rgba(0, 0, 0, 0.5);
  324. color: white;
  325. padding: 5px;
  326. border-radius: 3px;
  327. font-size: 0.9em;
  328. z-index: 10001;
  329. }
  330. `);
  331.  
  332. // 全局变量
  333. let lastSuperType = 'N/A';
  334. let lastLocation = 'N/A';
  335. let lastDirection = 'N/A';
  336. let settingsVisible = false; // 添加一个变量来跟踪设置的可见性
  337.  
  338. // Super 类型图标映射
  339. const superTypeIcons = {
  340. 'Super Queen Ant': 'https://i.imgur.com/your_queen_ant_icon.png',
  341. 'Super Beetle': 'https://i.imgur.com/your_beetle_icon.png',
  342. 'Super Spider': 'https://i.imgur.com/your_spider_icon.png'
  343. };
  344.  
  345. // 服务器信息相关变量
  346. let serverInfo = {
  347. serverId: 'N/A'
  348. };
  349.  
  350. // 函数:提取服务器 ID
  351. function extractServerId(url) {
  352. const match = url.match(/wss:\/\/([a-z0-9]*).s.m28n.net\//);
  353. return match ? match[1] : null;
  354. }
  355.  
  356. // 函数:获取服务器信息
  357. function getServerInfo() {
  358. const wsAddress = window.WebSocket.address; // 假设 WebSocket 地址存储在这个变量中
  359. if (!wsAddress) return;
  360.  
  361. const serverId = extractServerId(wsAddress);
  362. if (serverId) {
  363. serverInfo.serverId = serverId;
  364. updateServerInfoDisplay();
  365. }
  366. }
  367.  
  368. // 延迟执行,确保页面加载完成
  369. setTimeout(() => {
  370. // 创建 Super Ping 容器
  371. let superPingContainer = document.createElement('div');
  372. superPingContainer.id = 'super-ping-container';
  373. superPingContainer.innerHTML = `
  374. <h3 id="super-spawned-title">Super Ping</h3>
  375. <div id="super-ping-history"></div>
  376. `;
  377. document.body.appendChild(superPingContainer);
  378.  
  379. // 创建设置容器
  380. let settingsContainer = document.createElement('div');
  381. settingsContainer.id = 'settings-container';
  382. settingsContainer.style.display = 'none';
  383. settingsContainer.innerHTML = `
  384. <h2 id="settings-title">Settings</h2>
  385. <label for="language" id="language-label">Language:</label>
  386. <select id="language">
  387. <option value="en">English</option>
  388. <option value="zh">中文</option>
  389. </select>
  390.  
  391. <label for="hotkey" id="hotkey-label">UI Hotkey (Show/Hide All):</label>
  392. <input type="text" id="hotkey-input" value="Ctrl+Shift+S" readonly>
  393.  
  394. <label for="enable-log" id="enable-log-label">Enable Log UI:</label>
  395. <input type="checkbox" id="enable-log">
  396.  
  397. <label for="enable-server-info" id="enable-server-info-label">Enable Server Info UI:</label>
  398. <input type="checkbox" id="enable-server-info">
  399.  
  400. <button id="save-settings-button">Save Settings</button>
  401. `;
  402. document.body.appendChild(settingsContainer);
  403.  
  404. // 创建按钮容器
  405. const buttonContainer = document.createElement('div');
  406. buttonContainer.id = 'button-container';
  407. document.body.appendChild(buttonContainer);
  408.  
  409. // 创建设置按钮
  410. let settingsButton = document.createElement('button');
  411. settingsButton.id = 'settings-button';
  412. settingsButton.textContent = 'Settings';
  413. buttonContainer.appendChild(settingsButton);
  414.  
  415. // 创建快捷语言切换按钮
  416. let languageSwitchButton = document.createElement('button');
  417. languageSwitchButton.id = 'language-switch-button';
  418. buttonContainer.appendChild(languageSwitchButton);
  419.  
  420. console.log("Settings button:", settingsButton); // 调试:检查按钮元素是否被找到
  421.  
  422. // 创建日志容器
  423. let logContainer = document.createElement('div');
  424. logContainer.id = 'log-container';
  425. logContainer.innerHTML = `
  426. <h3>Log</h3>
  427. <div id="log-output"></div>
  428. `;
  429. document.body.appendChild(logContainer);
  430.  
  431. // 创建服务器信息容器
  432. let serverInfoContainer = document.createElement('div');
  433. serverInfoContainer.id = 'server-info-container';
  434. serverInfoContainer.innerHTML = `
  435. Server ID: <span id="server-id">N/A</span>
  436. <br>
  437. Server: <span id="server-name">N/A</span>
  438. `;
  439. document.body.appendChild(serverInfoContainer);
  440.  
  441. // 获取服务器信息显示元素
  442. const serverIdElement = document.getElementById('server-id');
  443. const serverNameElement = document.getElementById('server-name');
  444.  
  445. // 函数:更新服务器信息显示
  446. function updateServerInfoDisplay() {
  447. serverIdElement.textContent = serverInfo.serverId;
  448. serverNameElement.textContent = serverInfo.serverId; // 假设服务器名称与 ID 相同
  449. }
  450.  
  451. // 获取设置元素
  452. const languageSelect = document.getElementById('language');
  453. let hotkeyInput = document.getElementById('hotkey-input'); // 获取快捷键输入框
  454. const enableLogCheckbox = document.getElementById('enable-log');
  455. const enableServerInfoCheckbox = document.getElementById('enable-server-info');
  456. const saveSettingsButton = document.getElementById('save-settings-button');
  457.  
  458. // 加载设置
  459. let language = GM_getValue('language', 'en');
  460.  
  461. // **自动检测浏览器语言**
  462. const browserLanguage = navigator.language || navigator.userLanguage; // 获取浏览器语言
  463. if (browserLanguage.startsWith('zh')) {
  464. language = 'zh'; // 如果是中文,则设置为中文
  465. } else {
  466. language = 'en'; // 否则设置为英文
  467. }
  468.  
  469. let hotkey = GM_getValue('hotkey', 'Ctrl+Shift+S');
  470. let enableLog = GM_getValue('enableLog', false); // 默认隐藏 Log UI
  471. let enableServerInfo = GM_getValue('enableServerInfo', true);
  472.  
  473. languageSelect.value = language;
  474. hotkeyInput.value = hotkey;
  475. enableLogCheckbox.checked = enableLog;
  476. enableServerInfoCheckbox.checked = enableServerInfo;
  477.  
  478. // 初始化 UI 的显示状态
  479. logContainer.style.display = enableLog ? 'block' : 'none';
  480. serverInfoContainer.style.display = enableServerInfo ? 'block' : 'none';
  481.  
  482. // 保存设置
  483. saveSettingsButton.addEventListener('click', () => {
  484. language = languageSelect.value;
  485. hotkey = hotkeyInput.value;
  486. enableLog = enableLogCheckbox.checked;
  487. enableServerInfo = enableServerInfoCheckbox.checked;
  488.  
  489. GM_setValue('language', language);
  490. GM_setValue('hotkey', hotkey);
  491. GM_setValue('enableLog', enableLog);
  492. GM_setValue('enableServerInfo', enableServerInfo);
  493.  
  494. alert(getTranslation('settingsSaved'));
  495. settingsContainer.style.display = 'none';
  496. updateLanguage();
  497.  
  498. // 应用新的 UI 显示状态
  499. logContainer.style.display = enableLog ? 'block' : 'none';
  500. serverInfoContainer.style.display = enableServerInfo ? 'block' : 'none';
  501. });
  502.  
  503. // 热键处理
  504. document.addEventListener('keydown', (e) => {
  505. const keys = [];
  506. if (e.ctrlKey) keys.push('Ctrl');
  507. if (e.shiftKey) keys.push('Shift');
  508. if (e.altKey) keys.push('Alt');
  509. keys.push(e.key.toUpperCase());
  510. const pressedHotkey = keys.join('+');
  511.  
  512. // 全局 UI 快捷键
  513. if (pressedHotkey === hotkey.toUpperCase()) {
  514. settingsContainer.style.display = settingsContainer.style.display === 'none' ? 'block' : 'none';
  515. superPingContainer.style.display = superPingContainer.style.display === 'none' ? 'block' : 'none';
  516. logContainer.style.display = (enableLog && logContainer.style.display === 'none') ? 'block' : 'none';
  517. serverInfoContainer.style.display = (enableServerInfo && serverInfoContainer.style.display === 'none') ? 'block' : 'none';
  518. }
  519. });
  520.  
  521. // 设置按钮点击事件
  522. settingsButton.addEventListener('click', () => {
  523. console.log("Settings button clicked"); // 调试:检查事件监听器是否被触发
  524. console.log("settingsVisible before:", settingsVisible); // 调试:查看 settingsVisible 的值
  525. settingsVisible = !settingsVisible; // 切换可见性
  526. console.log("settingsVisible after:", settingsVisible); // 调试:查看 settingsVisible 的值
  527. settingsContainer.style.display = settingsVisible ? 'block' : 'none'; // 根据可见性设置显示
  528. console.log("settingsContainer.style.display:", settingsContainer.style.display); // 调试:查看 display 属性
  529. });
  530.  
  531. // 快捷语言切换按钮点击事件
  532. languageSwitchButton.addEventListener('click', () => {
  533. language = (language === 'en') ? 'zh' : 'en';
  534. GM_setValue('language', language);
  535. updateLanguage();
  536. });
  537.  
  538. // 获取 Super Server 和 Super Type 显示元素
  539. const superPingHistoryElement = document.getElementById('super-ping-history');
  540.  
  541. // 获取需要翻译的元素
  542. const superSpawnedTitle = document.getElementById('super-spawned-title');
  543. const settingsTitle = document.getElementById('settings-title');
  544. const languageLabel = document.getElementById('language-label');
  545. const hotkeyLabel = document.getElementById('hotkey-label');
  546. const enableLogLabel = document.getElementById('enable-log-label');
  547. const enableServerInfoLabel = document.getElementById('enable-server-info-label');
  548. const settingsButtonText = document.getElementById('settings-button');
  549.  
  550. // 翻译文本
  551. const translations = {
  552. en: {
  553. superSpawned: 'Super Ping',
  554. settings: 'Settings',
  555. language: 'Language:',
  556. hotkey: 'UI Hotkey (Show/Hide All):',
  557. enableLog: 'Enable Log UI:',
  558. enableServerInfo: 'Enable Server Info UI:',
  559. saveSettings: 'Save Settings',
  560. settingsSaved: 'Settings saved!',
  561. spawnedOn: 'spawned on',
  562. superSpawnedSomewhere: 'A Super has spawned somewhere!',
  563. serverId: 'Server ID:',
  564. server: 'Server:',
  565. chinese: '中文',
  566. fullscreenSuggestion: '⚠️ For the best experience, it is recommended to play in fullscreen.'
  567. },
  568. zh: {
  569. superSpawned: 'Super Ping',
  570. settings: '设置',
  571. language: '语言:',
  572. hotkey: 'UI 快捷键 (显示/隐藏全部):',
  573. enableLog: '启用日志 UI:',
  574. enableServerInfo: '启用服务器信息 UI:',
  575. saveSettings: '保存设置',
  576. settingsSaved: '设置已保存!',
  577. spawnedOn: '生成于',
  578. superSpawnedSomewhere: '某个地方生成了一个 Super!',
  579. serverId: '服务器 ID:',
  580. server: '服务器:',
  581. chinese: 'English',
  582. fullscreenSuggestion: '⚠️ 为了获得最佳体验,建议全屏游玩。'
  583. }
  584. };
  585.  
  586. // 函数:获取翻译文本
  587. function getTranslation(key) {
  588. return translations[language][key] || translations['en'][key] || key;
  589. }
  590.  
  591. // 函数:更新语言
  592. function updateLanguage() {
  593. language = GM_getValue('language', 'en');
  594. superSpawnedTitle.textContent = getTranslation('superSpawned');
  595. settingsTitle.textContent = getTranslation('settings');
  596. languageLabel.textContent = getTranslation('language');
  597. hotkeyLabel.textContent = getTranslation('hotkey');
  598. enableLogLabel.textContent = getTranslation('enableLog');
  599. enableServerInfoLabel.textContent = getTranslation('enableServerInfo');
  600. saveSettingsButton.textContent = getTranslation('saveSettings');
  601. settingsButtonText.textContent = getTranslation('settings');
  602. languageSwitchButton.textContent = getTranslation('chinese');
  603.  
  604. // 翻译 Super Ping 历史记录
  605. const historyEntries = document.querySelectorAll('#super-ping-history p');
  606. historyEntries.forEach(entry => {
  607. // 获取原始消息中的位置和时间信息
  608. const parts = entry.textContent.split(' - ');
  609. const locationAndTime = parts.slice(0, 2).join(' - '); // 位置和时间
  610. const translatedMessage = getTranslation('superSpawnedSomewhere'); // 翻译后的消息
  611.  
  612. // 组合位置、时间和翻译后的消息
  613. entry.textContent = `${locationAndTime} - ${translatedMessage}`;
  614. });
  615.  
  616. // 翻译服务器信息
  617. document.querySelector('#server-info-container').innerHTML = `${getTranslation('serverId')} <span id="server-id">${serverInfo.serverId}</span><br>${getTranslation('server')} <span id="server-name">${serverInfo.serverId}</span>`;
  618.  
  619. // 翻译全屏提示
  620. if (fullscreenSuggestion) { // 检查 fullscreenSuggestion 是否存在
  621. fullscreenSuggestion.textContent = getTranslation('fullscreenSuggestion');
  622. }
  623.  
  624. // Update FPS counter position after language change
  625. updateFPSCounterPosition();
  626. }
  627.  
  628. // 函数:显示 Super Ping
  629. function showSuperPing(superType, location, direction) {
  630. console.log('showSuperPing called', superType, location, direction);
  631.  
  632. try {
  633. const historyEntry = document.createElement('p');
  634. const translatedMessage = getTranslation('superSpawnedSomewhere');
  635. historyEntry.textContent = `${location} - ${new Date().toLocaleTimeString()} - ${translatedMessage}`;
  636. superPingHistoryElement.insertBefore(historyEntry, superPingHistoryElement.firstChild);
  637.  
  638. while (superPingHistoryElement.children.length > 10) {
  639. superPingHistoryElement.removeChild(superPingHistoryElement.lastChild);
  640. }
  641.  
  642. logMessage(`Super spawned: ${superType} at ${location}`);
  643. } catch (error) {
  644. console.error('Error in showSuperPing:', error);
  645. logMessage(`Error showing Super Ping: ${error.message}`);
  646. }
  647. }
  648.  
  649. // 模拟 Super 生成
  650. setInterval(() => {
  651. const superTypes = ['Super Queen Ant', 'Super Beetle', 'Super Spider'];
  652. const randomSuperType = superTypes[Math.floor(Math.random() * superTypes.length)];
  653. const randomLocation = ['US-Desert-1k73-2025/2/19', 'EU-Forest-2j84-2025/2/19', 'AS-Mountain-3l95-2025/2/19'][Math.floor(Math.random() * 3)];
  654. const randomDirection = ['North', 'South', 'East', 'West'][Math.floor(Math.random() * 4)];
  655. showSuperPing(randomSuperType, randomLocation, randomDirection);
  656. }, 15000);
  657.  
  658. // 快捷键录制
  659. let isRecording = false;
  660. //const hotkeyInput = document.getElementById('hotkey-input'); // 获取快捷键输入框
  661. hotkeyInput.addEventListener('click', () => {
  662. startRecordingHotkey(hotkeyInput);
  663. });
  664.  
  665. function startRecordingHotkey(inputElement) {
  666. isRecording = true;
  667. inputElement.value = 'Recording...';
  668. inputElement.classList.add('recording');
  669. }
  670.  
  671. document.addEventListener('keydown', (e) => {
  672. if (isRecording) {
  673. e.preventDefault();
  674.  
  675. const keys = [];
  676. if (e.ctrlKey) keys.push('Ctrl');
  677. if (e.shiftKey) keys.push('Shift');
  678. if (e.altKey) keys.push('Alt');
  679. keys.push(e.key.toUpperCase());
  680. const recordedHotkey = keys.join('+');
  681.  
  682. if (hotkeyInput.classList.contains('recording')) {
  683. hotkeyInput.value = recordedHotkey;
  684. GM_setValue('hotkey', recordedHotkey);
  685. }
  686.  
  687. isRecording = false;
  688. hotkeyInput.classList.remove('recording');
  689. } else {
  690. // 如果不是在录制快捷键,则检查是否按下了隐藏/显示 UI 的快捷键
  691. const keys = [];
  692. if (e.ctrlKey) keys.push('Ctrl');
  693. if (e.shiftKey) keys.push('Shift');
  694. if (e.altKey) keys.push('Alt');
  695. keys.push(e.key.toUpperCase());
  696. const pressedHotkey = keys.join('+');
  697.  
  698. // 全局 UI 快捷键
  699. if (pressedHotkey === hotkey.toUpperCase()) {
  700. settingsContainer.style.display = settingsContainer.style.display === 'none' ? 'block' : 'none';
  701. superPingContainer.style.display = superPingContainer.style.display === 'none' ? 'block' : 'none';
  702. logContainer.style.display = (enableLog && logContainer.style.display === 'none') ? 'block' : 'none';
  703. serverInfoContainer.style.display = (enableServerInfo && serverInfoContainer.style.display === 'none') ? 'block' : 'none';
  704. }
  705. }
  706. });
  707.  
  708. // 日志功能
  709. const logOutput = document.getElementById('log-output');
  710. function logMessage(message) {
  711. const timestamp = new Date().toLocaleTimeString();
  712. logOutput.textContent += `[${timestamp}] ${message}\n`;
  713. logOutput.scrollTop = logOutput.scrollHeight;
  714. }
  715.  
  716. // 初始日志消息
  717. logMessage('Script started.');
  718.  
  719. // --- 服务器信息相关 ---
  720. // Hook WebSocket
  721. const originalWebSocket = window.WebSocket;
  722. window.WebSocket = function(url, protocols) {
  723. window.WebSocket.address = url; // 存储 WebSocket 地址
  724. getServerInfo(); // 获取服务器信息
  725. if (protocols) {
  726. return new originalWebSocket(url, protocols);
  727. } else {
  728. return new originalWebSocket(url);
  729. }
  730. };
  731. window.WebSocket.prototype = originalWebSocket.prototype;
  732.  
  733. // 初始化服务器信息
  734. getServerInfo();
  735.  
  736. // 使用 MutationObserver 监听 Super Ping 历史记录的变化
  737. const observer = new MutationObserver((mutationsList, observer) => {
  738. for (const mutation of mutationsList) {
  739. if (mutation.type === 'childList') {
  740. // 当有节点被添加或删除时,更新语言
  741. updateLanguage();
  742. }
  743. }
  744. });
  745.  
  746. // 开始监听 Super Ping 历史记录容器
  747. const superPingHistoryElementForObserver = document.getElementById('super-ping-history');
  748. observer.observe(superPingHistoryElementForObserver, { childList: true });
  749.  
  750. // 创建全屏提示 UI
  751. const fullscreenSuggestion = document.createElement('div');
  752. console.log("Fullscreen suggestion element created:", fullscreenSuggestion); // Debugging
  753. fullscreenSuggestion.id = 'fullscreen-suggestion';
  754. document.body.appendChild(fullscreenSuggestion);
  755. console.log("Fullscreen suggestion element appended:", fullscreenSuggestion); // Debugging
  756.  
  757. // 20 秒后移除全屏提示
  758. setTimeout(() => {
  759. fullscreenSuggestion.classList.add('fade-out');
  760. setTimeout(() => {
  761. fullscreenSuggestion.remove();
  762. }, 1000); // 1 秒后移除元素,与 CSS 过渡时间一致
  763. }, 20000);
  764.  
  765. // --- FPS Counter ---
  766. let fpsCounter = document.createElement('div');
  767. fpsCounter.id = 'fps-counter';
  768. document.body.appendChild(fpsCounter);
  769.  
  770. let lastFrameTime = performance.now();
  771. let frameCount = 0;
  772. let fps = 0;
  773.  
  774. function updateFPS() {
  775. const now = performance.now();
  776. const delta = now - lastFrameTime;
  777. lastFrameTime = now;
  778. fps = Math.round(1000 / delta);
  779. fpsCounter.textContent = `FPS: ${fps}`;
  780. frameCount++;
  781. requestAnimationFrame(
  782. () => updateFPS());
  783. }
  784.  
  785. // Function to update FPS counter position
  786. function updateFPSCounterPosition() {
  787. const settingsButton = document.getElementById('settings-button');
  788.  
  789. const fpsCounter = document.getElementById('fps-counter');
  790.  
  791. if (settingsButton && fpsCounter) {
  792. // Calculate the left position based on the settings button's position
  793. const settingsButtonRect = settingsButton.getBoundingClientRect();
  794. const fpsCounterWidth = fpsCounter.offsetWidth;
  795. const newLeft = settingsButtonRect.left - fpsCounterWidth - 5; // 5px gap
  796.  
  797. // Set the new left position
  798. fpsCounter.style.left = `${newLeft}px`;
  799. fpsCounter.style.right = 'auto'; // Important: Reset right style
  800. }
  801. }
  802.  
  803. updateFPS(); // Start the FPS counter
  804.  
  805. // --- Initial Language Update ---
  806. updateLanguage();
  807.  
  808. }, 1000);
  809. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址