您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
需要特定地图才能提示,按1键可以提示plonkit中的知识,比如:plonkit新手向等等,或者带有tips关键词的题库才能使用
当前为
// ==UserScript== // @name 图寻tips // @namespace https://tuxun.fun/ // @version 2.3 // @description 需要特定地图才能提示,按1键可以提示plonkit中的知识,比如:plonkit新手向等等,或者带有tips关键词的题库才能使用 // @supportURL https://sleazyfork.org/en/scripts/480332-图寻tips // @author yukejun // @match https://tuxun.fun/* // @grant GM_xmlhttpRequest // @connect knowledgetips.fun // @connect nominatim.openstreetmap.org // @license MIT // ==/UserScript== (function() { 'use strict'; const modalHTML = ` <div id="customModal" style=" cursor: move; /* 设置鼠标为可移动状态 */ display: none; /* 初始设置为不显示,更改为block显示模态窗口 */ position: fixed; /* 固定位置 */ z-index: 1000; /* 设置堆叠顺序 */ top: 10vh; /* 距离顶部10%的视口高度 */ left: 10vw; /* 距离左侧10%的视口宽度 */ background-color: #eee; /* 背景颜色 */ padding: 5px; /* 内边距 */ border-radius: 10px; /* 边框圆角 */ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* 盒子阴影 */ width: 80vw; /* 宽度(这里可能是个错误,180vw可能过大) */ max-width: 350px; /* 最大宽度 */ transform: translate(0, 0); /* 移动转换(之前的负值已移除) */ text-align: left; /* 文本对齐方式 */ opacity: 0; /* 初始设置为透明,更改为1显示 */ visibility: hidden; /* 初始设置为隐藏,更改为visible显示 */ "> <div id="customModalHeader" style="cursor: move; padding: 10px; background-color: #eee;"> <h2 style="cursor: move; user-select: none; margin-top: 0; margin-bottom: 20px; font-size: 1.5em; color: #333;">小技巧</h2> <!-- 图片模态窗口 --> <div id="imageModal" style="display:none;"> <button id="toggleButton">地图</button> </div> <button id="pinModal" style="position: absolute; top: 3px; right: 30px; cursor: pointer;">📌</button> <div id="modalContent" style="user-select: text;">无提示</div> <!-- 新增文本输入框 --> <input type="text" id="customInputBox" placeholder="在此输入内容..." style=" width: 90%; /* 输入框宽度 */ padding: 5px; /* 内边距 */ margin: 10px 5%; /* 外边距,水平居中 */ border: 1px solid #ccc; /* 边框 */ border-radius: 5px; /* 边框圆角 */ "> <!-- 设置按钮 --> <div id="settingsPanel" style="display: none; padding: 10px; background-color: #f9f9f9; border-bottom: 1px solid #ccc;"> <label for="countdownTime">设置倒计时(秒):</label> <input type="number" id="countdownTime" value="15" min="1" style="margin-right: 10px;"> <button id="saveSettings">保存设置</button> </div> <!-- 新增按钮 --> <div style="text-align: center; margin-top: 10px;"> <button id="addButton" style="padding: 5px 15px; border: none; border-radius: 5px; cursor: pointer;">新增</button> </div> <span id="modalClose" style=" position: absolute; top: -4px; right: 8px; cursor: pointer; font-size: 1.5em; color: #333; ">×</span> </div> `; document.body.insertAdjacentHTML('beforeend', modalHTML); function updateModalPosition(x, y) { const modal = document.getElementById('customModal'); modal.style.left = `${x}px`; modal.style.top = `${y}px`; localStorage.setItem('modalPosition', JSON.stringify({ x, y })); } function restoreModalPosition() { const modal = document.getElementById('customModal'); const position = JSON.parse(localStorage.getItem('modalPosition')); if (position) { modal.style.left = `${position.x}px`; modal.style.top = `${position.y}px`; } } function createTagElement(text, index) { const tagContainer = document.createElement('div'); tagContainer.classList.add('tag-container'); const label = document.createElement('span'); label.textContent = index !== undefined ? `${index + 1}. ` : ''; label.classList.add('tag-label'); const paragraph = document.createElement('p'); paragraph.textContent = text; paragraph.contentEditable = "true"; paragraph.id = index !== undefined ? `tag-${index}` : undefined; const placeholder = document.createElement('div'); placeholder.style.display = 'none'; const saveButton = document.createElement('button'); saveButton.textContent = '保存'; saveButton.classList.add('save-button'); saveButton.onclick = index !== undefined ? () => saveTag(paragraph, index) : () => saveTag(paragraph); saveButton.style.display = 'none'; applyButtonStyles(saveButton); paragraph.ondblclick = function() { makeEditable(paragraph, saveButton, placeholder); }; tagContainer.appendChild(label); tagContainer.appendChild(paragraph); tagContainer.appendChild(placeholder); tagContainer.appendChild(saveButton); return tagContainer; } function makeEditable(paragraph, saveButton, placeholder) { paragraph.contentEditable = "true"; paragraph.focus(); saveButton.style.display = 'inline-block'; placeholder.style.display = 'block'; } function applyButtonStyles(button) { button.style.minWidth = '50px'; button.style.minHeight = '25px'; button.style.overflow = 'hidden'; button.style.backgroundColor = '#4CAF50'; button.style.color = 'white'; button.style.border = 'none'; button.style.borderRadius = '5px'; button.style.padding = '5px 5px'; button.style.cursor = 'text'; button.onmouseover = function() { button.style.backgroundColor = '#45a049'; }; button.onmouseout = function() { button.style.backgroundColor = '#4CAF50'; }; } function addCustomStyles() { const style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = ` .tag-container { display: flex; align-items: flex-start; margin-bottom: 10px; } .tag-label { margin-right: 8px; font-weight: bold; } .tag-container p { margin: 0; flex-grow: 1; margin-right: 8px; } .save-button { display: none; align-self: center; flex-shrink: 0; } @media (max-width: 600px) { .save-button { min-width: 40px; min-height: 20px; } } `; document.head.appendChild(style); } function preventKeyPropagation() { const modal = document.getElementById('customModal'); modal.addEventListener('keydown', function(event) { event.stopPropagation(); }); } window.addEventListener('load', function() { addCustomStyles(); preventKeyPropagation(); localStorage.removeItem('imageUrls'); localStorage.removeItem('imageUrl'); document.getElementById('addButton').style.display = 'none'; document.getElementById('customInputBox').style.display = 'none'; }); let countdownInterval; let shouldDisplayServerText = true; function showModal(serverText) { const modal = document.getElementById('customModal'); const modalContent = document.getElementById('modalContent'); modalContent.innerHTML = '倒计时: 15秒'; const storedAddress = localStorage.getItem('address') || localStorage.getItem('state') || '地址信息未找到'; const storedModalPosition = JSON.parse(localStorage.getItem('modalPosition')); if (storedModalPosition) { modal.style.left = storedModalPosition.x + 'px'; modal.style.top = storedModalPosition.y + 'px'; } modalContent.innerHTML = `<p>倒计时: 15秒</p><p>地址信息: ${storedAddress}</p>`; if (countdownInterval) { clearInterval(countdownInterval); } let countdown = 3; countdownInterval = setInterval(function() { countdown--; modalContent.innerHTML = `<p>倒计时: ${countdown}秒</p>`; if (countdown <= 0) { clearInterval(countdownInterval); modalContent.innerHTML = `<p>省份:${storedAddress}</p>`; const tags = serverText.split('; '); tags.forEach((tag, index) => { const tagElement = createTagElement(tag, index); modalContent.appendChild(tagElement); }); } }, 1000); modalContent.innerHTML = '倒计时: 15秒'; if (modal.style.display !== 'none') { modal.style.display = 'block'; modal.style.opacity = '1'; modal.style.visibility = 'visible'; } } function closeModal() { const modal = document.getElementById('customModal'); modal.style.opacity = '0'; modal.style.visibility = 'hidden'; setTimeout(() => modal.style.display = 'none', 100); } function saveTag(paragraph, index) { const editedText = paragraph.textContent.trim(); paragraph.contentEditable = "false"; let tags = []; tags = localStorage.getItem('tagsText') ? localStorage.getItem('tagsText').split('; ') : []; if (index !== undefined) { if (editedText === '') { tags.splice(index, 1); const tagContainer = paragraph.parentElement; if (tagContainer) { tagContainer.remove(); } } else { tags[index] = editedText; } } else { if (editedText !== '') { tags.push(editedText); } } tags = tags.filter(tag => tag && tag.trim()); const updatedTagsText = tags.join('; '); localStorage.setItem('tagsText', updatedTagsText); const storedCoordinates = JSON.parse(localStorage.getItem('coordinates')); const dataToSend = { mapsId: localStorage.getItem('mapsId'), coordinates: storedCoordinates, tagsText: updatedTagsText }; const saveButton = paragraph.parentElement.querySelector('.save-button'); if (saveButton) { saveButton.style.display = 'none'; } GM_xmlhttpRequest({ method: "POST", url: 'http://knowledgetips.fun:3000/save-data', data: JSON.stringify(dataToSend), headers: { "Content-Type": "application/json" }, onload: function(response) { } }); } //更新标签 function updateTagNumbers() { const tags = document.querySelectorAll('.tag-container'); tags.forEach((tag, index) => { const label = tag.querySelector('.tag-label'); if (label) { label.textContent = `${index + 1}. `; } }); } function addNewTag() { const inputBox = document.getElementById('customInputBox'); const newText = inputBox.value.trim(); if (newText) { const newTagElement = createTagElement(newText); const modalContent = document.getElementById('modalContent'); modalContent.appendChild(newTagElement); saveTag(newTagElement.querySelector('p')); inputBox.value = ''; updateTagNumbers(); } } const addButton = document.getElementById('addButton'); if (addButton) { } else { } addButton.addEventListener('click', addNewTag); let isPinned = false; function loadPinState() { const savedState = localStorage.getItem('isPinned'); if (savedState !== null) { isPinned = savedState === 'true'; } updatePinButton(); } function updatePinButton() { const pinButton = document.getElementById('pinModal'); pinButton.textContent = isPinned ? '📍' : '📌'; } function togglePin() { isPinned = !isPinned; localStorage.setItem('isPinned', isPinned); updatePinButton(); } document.getElementById('pinModal').addEventListener('click', function(event) { togglePin(); event.stopPropagation(); }); window.addEventListener('load', loadPinState); //以上是置顶函数变量 let isDragging = false; let dragStartX, dragStartY; let originalX, originalY; document.getElementById('customModalHeader').addEventListener('mousedown', function(e) { if (e.target !== this && e.target !== document.querySelector('#customModalHeader h2')) { return; } isDragging = true; dragStartX = e.clientX; dragStartY = e.clientY; const modal = document.getElementById('customModal'); originalX = parseInt(window.getComputedStyle(modal).left, 10); originalY = parseInt(window.getComputedStyle(modal).top, 10); e.preventDefault(); }); document.addEventListener('mousemove', function(e) { if (!isDragging) return; let newX = originalX + e.clientX - dragStartX; let newY = originalY + e.clientY - dragStartY; updateModalPosition(newX, newY); }); document.addEventListener('mouseup', function(e) { if (isDragging) { isDragging = false; let newX = originalX + e.clientX - dragStartX; let newY = originalY + e.clientY - dragStartY; updateModalPosition(newX, newY); } }); document.addEventListener('click', function(event) { const modal = document.getElementById('customModal'); if (!isPinned && !modal.contains(event.target)) { closeModal(); } }); document.getElementById('modalClose').addEventListener('click', closeModal); function toggleModal() { const modal = document.getElementById('customModal'); if (modal.style.opacity === '1' || modal.style.visibility === 'visible') { modal.style.opacity = '0'; modal.style.visibility = 'hidden'; modal.style.display = 'none'; } else { modal.style.opacity = '1'; modal.style.visibility = 'visible'; modal.style.display = 'block'; } } document.addEventListener("keydown", function(evt) { const targetTagName = (evt.target || evt.srcElement).tagName; if (evt.key === '1' && targetTagName !== 'INPUT' && targetTagName !== 'TEXTAREA') { toggleModal(); } }); const mapsIdMatch = window.location.href.match(/maps-start\?mapsId=(\d+)/); const mapsId = mapsIdMatch ? mapsIdMatch[1] : localStorage.getItem('mapsId') || '未找到ID'; if (mapsIdMatch) { localStorage.setItem('mapsId', mapsId); } const mapsIdPattern = /mapsId=(\d+)/; const addressPattern = /\[\["(.*?)","zh"\]\]|\[\[.*?,\["(.*?)","zh"\]\]\]/; const coordinatePattern = /\[\[null,null,(-?\d+\.\d+),(-?\d+\.\d+)\],\[\d+\.\d+\],\[\d+\.\d+,\d+\.\d+,\d+\.\d+\]\]|\[\s*null,\s*null,\s*(-?\d+\.\d+),\s*(-?\d+\.\d+)\s*\]/; var realSend = XMLHttpRequest.prototype.send; XMLHttpRequest.prototype.send = function(value) { let currentUrl = this._url; this.addEventListener("loadstart", function() { currentUrl = this._url; }); this.addEventListener("load", function() { let previousMapsId = localStorage.getItem('previousMapsId'); let currentMapsId = localStorage.getItem('mapsId'); if (!currentUrl.includes('mapsId=')) { const responseText = this.responseText; const mapsIdMatches = mapsIdPattern.exec(responseText); if (mapsIdMatches) { const newMapsId = mapsIdMatches[1]; if (newMapsId !== currentMapsId) { localStorage.setItem('previousMapsId', currentMapsId); localStorage.setItem('mapsId', newMapsId); } } } if (this._url.includes('https://tuxun.fun/api/v0/tuxun/party/changeMaps')) { const newMapsIdMatch = this._url.match(mapsIdPattern); if (newMapsIdMatch) { const newMapsId = newMapsIdMatch[1]; if (newMapsId !== currentMapsId) { localStorage.setItem('previousMapsId', currentMapsId); localStorage.setItem('mapsId', newMapsId); } } } currentMapsId = localStorage.getItem('mapsId'); previousMapsId = localStorage.getItem('previousMapsId'); if (currentMapsId !== previousMapsId) { // } else { // } if (currentUrl.includes('https://tuxun.fun/api/v0/tuxun/mapProxy/getGooglePanoInfoPost')) { // const responseText = this.responseText; let addressMatches; let isAddressFound = false; let loopCount = 0; let dummyVar = Math.random(); function confuseFunction(data) { return data.split('').reverse().join(''); } while ((addressMatches = addressPattern.exec(responseText)) !== null && loopCount < 3) { loopCount++; isAddressFound = true; const address = addressMatches[1] || addressMatches[2]; const encryptedAddress = confuseFunction(address); const storedAddress = localStorage.getItem('address'); if (address !== storedAddress) { localStorage.setItem('address', address); } else { } break; } if (!isAddressFound) { localStorage.removeItem('address'); } if (coordinatePattern.test(responseText)) { // let latitude, longitude; const matches = coordinatePattern.exec(responseText); if (matches) { // function confuse() { var seed = Math.random(); return seed.toString(36).substring(2, 15); } var unused = confuse(); var coordinateData = {lat: undefined, lon: undefined}; if (matches[1] !== undefined && matches[2] !== undefined) { latitude = matches[1]; longitude = matches[2]; } else if (matches[3] !== undefined && matches[4] !== undefined) { latitude = matches[3]; longitude = matches[4]; } (function(){ var fakeLat = Math.random() * 100; var fakeLon = Math.random() * 100; // })(); if (latitude !== undefined && longitude !== undefined) { const storedCoordinatesString = localStorage.getItem('coordinates'); let storedCoordinates = null; if (storedCoordinatesString) { storedCoordinates = JSON.parse(storedCoordinatesString); }else { } const tolerance = 0.008; if (!storedCoordinates || !isCoordinateCloseEnough(storedCoordinates, latitude, longitude, tolerance)) { localStorage.removeItem('tagsText'); const coordinates = { latitude, longitude }; localStorage.setItem('coordinates', JSON.stringify(coordinates)); function getAddress(lat, lon) { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "GET", url: `https://nominatim.openstreetmap.org/reverse?lat=${lat}&lon=${lon}&format=json`, onload: function(response) { // if (response.status === 200) { // resolve(JSON.parse(response.responseText)); } else { // reject(`Failed to fetch address. Status: ${response.status}`); } }, onerror: function(error) { reject("Error occurred while fetching address"); } }); }); } getAddress(latitude, longitude) .then(addressData => { if (addressData && addressData.address && addressData.address.country) { const fullCountryString = addressData.address.country; // const country = fullCountryString.split('/')[0].trim(); localStorage.setItem('country', country); const storedCountry = localStorage.getItem('country'); if (storedCountry && storedCountry !== country) { } localStorage.setItem('country', country); } else { } if (addressData && addressData.address && addressData.address.state) { localStorage.setItem('state', addressData.address.state); const fullStateString = addressData.address.state; const state = fullStateString.split('/')[0].trim(); } else { } const country = localStorage.getItem('country'); const dataToSend = JSON.stringify({ mapsId, coordinates: `${latitude},${longitude}`,country }); GM_xmlhttpRequest({ method: "POST", url: 'http://knowledgetips.fun:3000/receive-data', data: JSON.stringify({ mapsId, coordinates: `${latitude},${longitude}`,country }), headers: { "Content-Type": "application/json" }, onload: function(response) { const jsonResponse = JSON.parse(response.responseText); if (jsonResponse.match && jsonResponse.tags) { const tagsText = jsonResponse.tags.join('; '); if (jsonResponse.images && jsonResponse.images.length > 0) { let isImageZoomed = false; let zoomedImg; function updateImage(url) { if (!zoomedImg) { zoomedImg = document.createElement('img'); zoomedImg.id = 'myImage'; document.body.appendChild(zoomedImg); zoomedImg.addEventListener('dblclick', function() { zoomedImg.style.display = "none"; isImageZoomed = false; }); } if (zoomedImg.src !== url) { zoomedImg.src = url; } zoomedImg.style.position = 'fixed'; zoomedImg.style.top = '50%'; zoomedImg.style.left = '50%'; zoomedImg.style.transform = 'translate(-50%, -50%)'; zoomedImg.style.width = "auto"; zoomedImg.style.height = "80vh"; zoomedImg.style.objectFit = "contain"; zoomedImg.style.zIndex = 1000; } function toggleImageZoom() { let newImageUrl = jsonResponse.images[0]; updateImage(newImageUrl); if (!isImageZoomed) { zoomedImg.style.display = "block"; isImageZoomed = true; } else { zoomedImg.style.display = "none"; isImageZoomed = false; } } document.addEventListener('keydown', function(event) { if (event.keyCode === 50) { toggleImageZoom(); event.preventDefault(); } }); } localStorage.setItem('tagsText', tagsText); // localStorage.setItem('coordinates', JSON.stringify(coordinates)); const modal = document.getElementById('customModal'); if (modal.style.display !== 'none') { const modalContent = document.getElementById('modalContent'); modalContent.textContent = tagsText; } showModal(tagsText); }else{ modalContent.innerHTML = '无提示'; } }, }); }) .catch(error => { }); } else { } function isCoordinateCloseEnough(storedCoordinates, latitude, longitude, tolerance) { const latDifference = Math.abs(storedCoordinates.latitude - latitude); const lonDifference = Math.abs(storedCoordinates.longitude - longitude); return latDifference <= tolerance && lonDifference <= tolerance; } }else { } } else { } if (latitude !== undefined && longitude !== undefined) { } }else { modalContent.innerHTML = ''; } } }, false); realSend.call(this, value); }; XMLHttpRequest.prototype.realOpen = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function(method, url, async, user, pass) { this._url = url; this.realOpen(method, url, async, user, pass); }; if (XMLHttpRequest.prototype.send === XMLHttpRequest.prototype.realSend) { } else { } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址