Skip to content

Commit d007045

Browse files
committed
add pixel checker
1 parent 4c7c072 commit d007045

File tree

2 files changed

+146
-3
lines changed

2 files changed

+146
-3
lines changed

src/content_ui.js

Lines changed: 145 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,151 @@
11
// content_ui.js (完整替换文件)
22
// 功能:浮动面板、稳定拖拽、最小化为可拖拽图标、智能检测并填充 Blue/Skirk 输入后跳转
33
(() => {
4-
if (window.__WPLACE_VERSATILE_TOOL_INJECTED) return;
5-
window.__WPLACE_VERSATILE_TOOL_INJECTED = true;
4+
if (window.__WPLACE_VERSATILE_TOOL_INJECTED) return;
5+
window.__WPLACE_VERSATILE_TOOL_INJECTED = true;
6+
7+
(function promptOpenInjectCheckOnce() {
8+
const KEY = 'wplace_prompted_inject_check_v1';
9+
const CHECK_URL = 'https://github.com/lin-alg/Wplace_Versatile_Tool/raw/refs/heads/main/inject_check_pixels.user.js';
10+
11+
function markPrompted() {
12+
try {
13+
if (window.chrome && chrome.storage && chrome.storage.local) {
14+
chrome.storage.local.set({ [KEY]: true }, () => {});
15+
} else {
16+
localStorage.setItem(KEY, '1');
17+
}
18+
} catch (e) {
19+
try { localStorage.setItem(KEY, '1'); } catch (_) {}
20+
}
21+
}
22+
23+
function alreadyPrompted(cb) {
24+
try {
25+
if (window.chrome && chrome.storage && chrome.storage.local) {
26+
chrome.storage.local.get([KEY], (res) => {
27+
try { cb(!!(res && res[KEY])); } catch (e) { cb(false); }
28+
});
29+
return;
30+
}
31+
} catch (e) {}
32+
try {
33+
const v = localStorage.getItem(KEY);
34+
cb(!!v);
35+
} catch (e) { cb(false); }
36+
}
37+
38+
function createModal(message, onConfirm, onCancel) {
39+
try {
40+
// 若已有 modal,直接返回
41+
if (document.getElementById('__wplace_inject_prompt')) return;
42+
const wrap = document.createElement('div');
43+
wrap.id = '__wplace_inject_prompt';
44+
Object.assign(wrap.style, {
45+
position: 'fixed',
46+
left: '0',
47+
top: '0',
48+
width: '100vw',
49+
height: '100vh',
50+
zIndex: 2147483647,
51+
display: 'flex',
52+
alignItems: 'center',
53+
justifyContent: 'center',
54+
background: 'rgba(0,0,0,0.36)',
55+
fontFamily: 'sans-serif'
56+
});
57+
58+
const box = document.createElement('div');
59+
Object.assign(box.style, {
60+
width: '420px',
61+
maxWidth: '92vw',
62+
background: '#0b0b0b',
63+
color: '#e8e8e8',
64+
padding: '14px',
65+
borderRadius: '10px',
66+
boxShadow: '0 8px 30px rgba(0,0,0,0.6)',
67+
display: 'flex',
68+
flexDirection: 'column',
69+
gap: '12px'
70+
});
71+
72+
const title = document.createElement('div');
73+
title.textContent = 'Wplace 检查脚本';
74+
Object.assign(title.style, { fontWeight: 600, fontSize: '15px' });
75+
76+
const msg = document.createElement('div');
77+
msg.textContent = message;
78+
Object.assign(msg.style, { fontSize: '13px', opacity: 0.95, lineHeight: '1.4' });
79+
80+
const actions = document.createElement('div');
81+
Object.assign(actions.style, { display: 'flex', justifyContent: 'flex-end', gap: '8px' });
82+
83+
const btnCancel = document.createElement('button');
84+
btnCancel.textContent = '取消';
85+
Object.assign(btnCancel.style, { padding: '6px 10px', borderRadius: '6px', background: 'transparent', color: '#cfcfcf', border: '1px solid rgba(255,255,255,0.06)', cursor: 'pointer' });
86+
87+
const btnOk = document.createElement('button');
88+
btnOk.textContent = '打开';
89+
Object.assign(btnOk.style, { padding: '6px 12px', borderRadius: '6px', background: '#0a84ff', color: '#fff', border: 'none', cursor: 'pointer' });
90+
91+
actions.appendChild(btnCancel);
92+
actions.appendChild(btnOk);
93+
94+
box.appendChild(title);
95+
box.appendChild(msg);
96+
box.appendChild(actions);
97+
wrap.appendChild(box);
98+
(document.body || document.documentElement).appendChild(wrap);
99+
100+
function cleanup() {
101+
try { wrap.remove(); } catch (e) {}
102+
}
103+
104+
btnCancel.addEventListener('click', () => {
105+
try { cleanup(); } catch (e) {}
106+
try { onCancel && onCancel(); } catch (e) {}
107+
}, { once: true });
108+
109+
btnOk.addEventListener('click', () => {
110+
try { cleanup(); } catch (e) {}
111+
try { onConfirm && onConfirm(); } catch (e) {}
112+
}, { once: true });
113+
114+
// close on outside click
115+
wrap.addEventListener('click', (ev) => {
116+
if (ev.target === wrap) {
117+
try { cleanup(); } catch (e) {}
118+
try { onCancel && onCancel(); } catch (e) {}
119+
}
120+
});
121+
} catch (e) {
122+
try { onCancel && onCancel(); } catch (err) {}
123+
}
124+
}
125+
126+
try {
127+
alreadyPrompted((did) => {
128+
if (did) return;
129+
// 延迟一点时间以免影响页面首屏渲染
130+
setTimeout(() => {
131+
createModal(
132+
'此插件外带的篡改猴脚本可帮助检查绘画时画错的像素,是否安装?(需使用Skirk Marble)',
133+
() => {
134+
try {
135+
// 标记已提示并打开链接
136+
markPrompted();
137+
const w = window.open(CHECK_URL, '_blank');
138+
try { if (w) w.focus(); } catch (e) {}
139+
} catch (e) {}
140+
},
141+
() => {
142+
try { markPrompted(); } catch (e) {}
143+
}
144+
);
145+
}, 800);
146+
});
147+
} catch (e) {}
148+
})();
6149

7150
const i18n = {
8151
en: {

src/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"manifest_version": 3,
33
"name": "Wplace_Versatile_Tool",
4-
"version": "3.1",
4+
"version": "3.2",
55
"description": "A versatile Wplace tool",
66
"permissions": [
77
"scripting",

0 commit comments

Comments
 (0)