Spaces:
Sleeping
Sleeping
Upload 5 files
Browse files
app.py
CHANGED
|
@@ -143,14 +143,28 @@ HTML_CONTENT = '''<!DOCTYPE html>
|
|
| 143 |
<div class="output" id="commandOutput">等待命令...</div>
|
| 144 |
</div>
|
| 145 |
<div class="tab-content" id="tab-screenshot" style="display:none;">
|
| 146 |
-
<div class="
|
| 147 |
-
<
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 152 |
</div>
|
| 153 |
-
<div class="screenshot-view" id="screenshotView" style="margin-top:15px;"></div>
|
| 154 |
</div>
|
| 155 |
<div class="tab-content" id="tab-control" style="display:none;">
|
| 156 |
<p style="color:#888;margin-bottom:15px;">远程控制</p>
|
|
@@ -253,7 +267,10 @@ HTML_CONTENT = '''<!DOCTYPE html>
|
|
| 253 |
|
| 254 |
async function requestScreenshot() {
|
| 255 |
if (!selectedClient) return;
|
| 256 |
-
document.getElementById('screenshotView')
|
|
|
|
|
|
|
|
|
|
| 257 |
await fetch('/api/command', {
|
| 258 |
method: 'POST', headers: {'Content-Type': 'application/json'},
|
| 259 |
body: JSON.stringify({client_id: selectedClient.id, type: 'screenshot', payload: ''})
|
|
@@ -261,27 +278,45 @@ HTML_CONTENT = '''<!DOCTYPE html>
|
|
| 261 |
setTimeout(loadScreenshot, 2000);
|
| 262 |
}
|
| 263 |
|
|
|
|
|
|
|
| 264 |
async function loadScreenshot() {
|
| 265 |
if (!selectedClient) return;
|
| 266 |
const t = Date.now();
|
| 267 |
-
const
|
| 268 |
-
document.getElementById('screenshotView').innerHTML = img;
|
| 269 |
|
| 270 |
-
|
| 271 |
-
|
| 272 |
-
|
| 273 |
-
|
| 274 |
-
|
| 275 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 276 |
}
|
| 277 |
|
| 278 |
-
async function sendMouseClickAt(x, y) {
|
| 279 |
if (!selectedClient) return;
|
| 280 |
await fetch('/api/command', {
|
| 281 |
method: 'POST', headers: {'Content-Type': 'application/json'},
|
| 282 |
-
body: JSON.stringify({client_id: selectedClient.id, type: 'mouse_click', payload: JSON.stringify({button:
|
| 283 |
});
|
| 284 |
-
document.getElementById('commandOutput').textContent = `鼠标点击: (${x}, ${y})`;
|
| 285 |
}
|
| 286 |
|
| 287 |
function startAutoScreenshot() {
|
|
|
|
| 143 |
<div class="output" id="commandOutput">等待命令...</div>
|
| 144 |
</div>
|
| 145 |
<div class="tab-content" id="tab-screenshot" style="display:none;">
|
| 146 |
+
<div class="screenshot-settings" style="background:#0a0a15;padding:10px;border-radius:5px;margin-bottom:10px;">
|
| 147 |
+
<div class="command-input" style="margin-bottom:10px;">
|
| 148 |
+
<button class="btn" onclick="requestScreenshot()">获取截图</button>
|
| 149 |
+
<input type="number" id="screenInterval" value="3" min="1" max="60" style="width:50px;padding:8px;border-radius:5px;border:1px solid #0f3460;background:#1a1a2e;color:#eee;">
|
| 150 |
+
<span style="color:#888;">秒间隔</span>
|
| 151 |
+
<button class="btn btn-success" id="btnAutoScreen" onclick="toggleAutoScreenshot()">自动连续</button>
|
| 152 |
+
<button class="btn btn-danger" id="btnStopScreen" onclick="stopAutoScreenshot()" style="display:none;">停止</button>
|
| 153 |
+
</div>
|
| 154 |
+
<div class="command-input">
|
| 155 |
+
<label style="color:#888;margin-right:10px;">
|
| 156 |
+
<input type="checkbox" id="clickAutoRefresh" checked> 点击后自动刷新
|
| 157 |
+
</label>
|
| 158 |
+
<span style="color:#888;margin:0 10px;">点击类型:</span>
|
| 159 |
+
<label style="color:#00d9ff;margin-right:10px;">
|
| 160 |
+
<input type="radio" name="clickButton" value="left" checked> 左键
|
| 161 |
+
</label>
|
| 162 |
+
<label style="color:#00d9ff;">
|
| 163 |
+
<input type="radio" name="clickButton" value="right"> 右键
|
| 164 |
+
</label>
|
| 165 |
+
</div>
|
| 166 |
</div>
|
| 167 |
+
<div class="screenshot-view" id="screenshotView" style="margin-top:15px;min-height:300px;background:#000;display:flex;align-items:center;justify-content:center;"></div>
|
| 168 |
</div>
|
| 169 |
<div class="tab-content" id="tab-control" style="display:none;">
|
| 170 |
<p style="color:#888;margin-bottom:15px;">远程控制</p>
|
|
|
|
| 267 |
|
| 268 |
async function requestScreenshot() {
|
| 269 |
if (!selectedClient) return;
|
| 270 |
+
const container = document.getElementById('screenshotView');
|
| 271 |
+
if (!screenshotImgElement) {
|
| 272 |
+
container.innerHTML = '<p style="color:#888;">获取中...</p>';
|
| 273 |
+
}
|
| 274 |
await fetch('/api/command', {
|
| 275 |
method: 'POST', headers: {'Content-Type': 'application/json'},
|
| 276 |
body: JSON.stringify({client_id: selectedClient.id, type: 'screenshot', payload: ''})
|
|
|
|
| 278 |
setTimeout(loadScreenshot, 2000);
|
| 279 |
}
|
| 280 |
|
| 281 |
+
let screenshotImgElement = null;
|
| 282 |
+
|
| 283 |
async function loadScreenshot() {
|
| 284 |
if (!selectedClient) return;
|
| 285 |
const t = Date.now();
|
| 286 |
+
const container = document.getElementById('screenshotView');
|
|
|
|
| 287 |
|
| 288 |
+
// 保持容器大小,只更新图片
|
| 289 |
+
if (screenshotImgElement) {
|
| 290 |
+
screenshotImgElement.src = `/api/screenshots/${selectedClient.id}?t=${t}`;
|
| 291 |
+
} else {
|
| 292 |
+
container.innerHTML = `<img id="screenshotImg" style="max-width:100%;max-height:500px;cursor:crosshair;">`;
|
| 293 |
+
screenshotImgElement = document.getElementById('screenshotImg');
|
| 294 |
+
screenshotImgElement.src = `/api/screenshots/${selectedClient.id}?t=${t}`;
|
| 295 |
+
|
| 296 |
+
screenshotImgElement.onclick = function(e) {
|
| 297 |
+
const rect = this.getBoundingClientRect();
|
| 298 |
+
const x = Math.round((e.clientX - rect.left) * (this.naturalWidth / rect.width));
|
| 299 |
+
const y = Math.round((e.clientY - rect.top) * (this.naturalHeight / rect.height));
|
| 300 |
+
|
| 301 |
+
// 获取选中的点击类型
|
| 302 |
+
const clickButton = document.querySelector('input[name="clickButton"]:checked').value;
|
| 303 |
+
sendMouseClickAt(x, y, clickButton);
|
| 304 |
+
|
| 305 |
+
// 点击后自动刷新
|
| 306 |
+
if (document.getElementById('clickAutoRefresh').checked) {
|
| 307 |
+
setTimeout(loadScreenshot, 500);
|
| 308 |
+
}
|
| 309 |
+
};
|
| 310 |
+
}
|
| 311 |
}
|
| 312 |
|
| 313 |
+
async function sendMouseClickAt(x, y, button) {
|
| 314 |
if (!selectedClient) return;
|
| 315 |
await fetch('/api/command', {
|
| 316 |
method: 'POST', headers: {'Content-Type': 'application/json'},
|
| 317 |
+
body: JSON.stringify({client_id: selectedClient.id, type: 'mouse_click', payload: JSON.stringify({button: button, x: x, y: y})})
|
| 318 |
});
|
| 319 |
+
document.getElementById('commandOutput').textContent = `鼠标${button}键点击: (${x}, ${y})`;
|
| 320 |
}
|
| 321 |
|
| 322 |
function startAutoScreenshot() {
|