|
发表于 2025-4-26 19:33:20
|
查看全部
免费16核60GB内存Windows虚拟机?谷歌的 Firebase Studio(4.26 不会重置/home)
https://firebase.studio/
进去选择 Android Studio,会分配一个豪华配置虚拟机,如楼主所示。
分享下我的经验
把 Android Studio 关闭,换个壁纸,熟悉的背影:Ubuntu 24.04。没错,就是它!
- user$: sudo apt update && sudo apt install cpu-checker && kvm-ok
- INFO: /dev/kvm exists
- KVM acceleration can be used
复制代码
可见,这个虚拟机的CPU有虚拟化功能flag且未被谷歌关闭,而且还有 root 无密码。输入可以执行 root 命令,甚至提权。所以我们就可以运行任意操作系统。比如Windows。
接下来就不说了,qemu+frp+rdp嘛。
注意事项
uptime时间显示24小时10分钟左右吧,用脚本合理设置可以运行1天左右时间
更新一个定时刷新脚本,打开浏览器,自己设置15分钟左右时间刷新一下脚本,可以运行约一天
- // ==UserScript==
- // [url=home.php?mod=space&uid=4014]@name[/url] 持续定时刷新器 (Continuous Timer Refresher)
- // @namespace http://tampermonkey.net/
- // @version 2.0
- // @description 在指定时间间隔后持续自动刷新页面,直到手动停止。状态跨页面保持。
- // @author Gemini
- // @match *://*/*
- // @grant GM_setValue
- // @grant GM_getValue
- // @grant GM_addStyle
- // @run-at document-idle
- // ==/UserScript==
- (function() {
- 'use strict';
- // --- 配置项 ---
- const DEFAULT_INTERVAL_SECONDS = 60; // 默认刷新间隔(秒)
- const STORAGE_KEY_INTERVAL = 'continuousRefresherInterval'; // 存储间隔时间的键名
- const STORAGE_KEY_NEXT_RUN = 'continuousRefresherNextRun'; // 存储下一次运行时间戳的键名
- // --- 状态变量 ---
- let refreshTimerId = null; // 存储刷新定时器的ID
- let countdownTimerId = null; // 存储倒计时更新定时器的ID
- let isRunning = false; // 标记当前页面脚本是否已启动计时器 (瞬时状态)
- let nextRunTimestamp = 0; // 下次运行的目标时间戳
- // --- 创建用户界面 (UI) ---
- const panel = document.createElement('div');
- panel.id = 'continuous-refresher-panel';
- panel.innerHTML = `
- <div class="refresher-title">持续定时刷新器</div>
- <div class="refresher-control">
- <label for="refresh-interval">间隔(秒):</label>
- <input type="number" id="refresh-interval" min="1" value="${GM_getValue(STORAGE_KEY_INTERVAL, DEFAULT_INTERVAL_SECONDS)}">
- </div>
- <div class="refresher-buttons">
- <button id="start-refresh-btn">开始刷新</button>
- <button id="stop-refresh-btn">停止刷新</button>
- </div>
- <div id="refresh-status">已停止</div>
- `;
- document.body.appendChild(panel);
- // --- 获取 UI 元素引用 ---
- const intervalInput = document.getElementById('refresh-interval');
- const startButton = document.getElementById('start-refresh-btn');
- const stopButton = document.getElementById('stop-refresh-btn');
- const statusDisplay = document.getElementById('refresh-status');
- // --- 添加 CSS 样式 ---
- GM_addStyle(`
- #continuous-refresher-panel {
- position: fixed;
- bottom: 15px;
- right: 15px;
- background-color: #f0f0f0;
- border: 1px solid #ccc;
- border-radius: 5px;
- padding: 10px 15px;
- z-index: 9999;
- font-family: Arial, sans-serif;
- font-size: 14px;
- box-shadow: 2px 2px 5px rgba(0,0,0,0.2);
- min-width: 180px;
- color: #333;
- }
- #continuous-refresher-panel .refresher-title {
- font-weight: bold;
- margin-bottom: 8px;
- text-align: center;
- font-size: 15px;
- }
- #continuous-refresher-panel .refresher-control {
- margin-bottom: 8px;
- display: flex;
- align-items: center;
- }
- #continuous-refresher-panel label {
- margin-right: 5px;
- white-space: nowrap;
- }
- #continuous-refresher-panel input[type="number"] {
- width: 60px;
- padding: 3px 5px;
- border: 1px solid #ccc;
- border-radius: 3px;
- }
- #continuous-refresher-panel .refresher-buttons {
- display: flex;
- justify-content: space-around;
- margin-bottom: 8px;
- }
- #continuous-refresher-panel button {
- padding: 5px 10px;
- cursor: pointer;
- border: 1px solid #aaa;
- border-radius: 3px;
- background-color: #e0e0e0;
- }
- #continuous-refresher-panel button:hover:not(:disabled) {
- background-color: #d0d0d0;
- }
- #continuous-refresher-panel button:disabled {
- cursor: not-allowed;
- opacity: 0.6;
- }
- #refresh-status {
- text-align: center;
- font-size: 13px;
- color: #555;
- min-height: 1.2em; /* 防止文字变化时跳动 */
- }
- `);
- // --- 功能函数 ---
- // 更新倒计时显示 (基于时间戳计算)
- function updateCountdown() {
- if (!isRunning || nextRunTimestamp <= 0) {
- // 如果状态不是运行中,或者没有目标时间,确保停止计时
- if (countdownTimerId) clearInterval(countdownTimerId);
- countdownTimerId = null;
- return;
- }
- const now = Date.now();
- const remainingMs = nextRunTimestamp - now;
- const remainingSeconds = Math.max(0, Math.ceil(remainingMs / 1000));
- if (remainingSeconds <= 0) {
- statusDisplay.textContent = '即将刷新...';
- // 实际刷新由 setTimeout 触发,这里只更新显示
- // 到时间后定时器会自动停止或在 performRefresh 中被清除
- if (countdownTimerId) clearInterval(countdownTimerId);
- countdownTimerId = null;
- } else {
- statusDisplay.textContent = `运行中, ${remainingSeconds} 秒后刷新`;
- }
- }
- // 执行页面刷新,并设置下一次刷新
- function performRefresh() {
- console.log('定时刷新器: 执行刷新');
- // 1. 清除当前页面的所有计时器
- if (refreshTimerId) clearTimeout(refreshTimerId);
- if (countdownTimerId) clearInterval(countdownTimerId);
- refreshTimerId = null;
- countdownTimerId = null;
- isRunning = false; // 重置瞬时状态
- // 2. 计算并保存下一次运行的时间戳 (只有在明确需要继续时才保存)
- // (检查一下是否在此期间被用户点了停止)
- const nextRunCheck = GM_getValue(STORAGE_KEY_NEXT_RUN, 0);
- if (nextRunCheck > 0) { // 如果大于0,说明用户没有点停止
- const intervalSeconds = parseInt(GM_getValue(STORAGE_KEY_INTERVAL, DEFAULT_INTERVAL_SECONDS), 10);
- const nextTimestamp = Date.now() + intervalSeconds * 1000; // 基于当前时间计算下一次
- GM_setValue(STORAGE_KEY_NEXT_RUN, nextTimestamp);
- console.log(`定时刷新器: 下次刷新时间戳已设置: ${new Date(nextTimestamp).toLocaleTimeString()}`);
- } else {
- console.log('定时刷新器: 检测到已停止,刷新后不再继续。');
- }
- // 3. 执行刷新
- statusDisplay.textContent = '正在刷新页面...';
- // 使用 небольшое таймаут перед перезагрузкой, чтобы статус успел отобразиться
- setTimeout(() => {
- window.location.reload();
- }, 50);
- }
- // 启动或恢复刷新流程
- function startRefresh(isAutoStart = false) {
- let intervalValue;
- let delayMs;
- if (isAutoStart) {
- // 自动启动(页面加载时)
- intervalValue = parseInt(GM_getValue(STORAGE_KEY_INTERVAL, DEFAULT_INTERVAL_SECONDS), 10);
- nextRunTimestamp = GM_getValue(STORAGE_KEY_NEXT_RUN, 0);
- const now = Date.now();
- if (nextRunTimestamp <= 0) {
- console.log('定时刷新器: 自动启动检查 - 未设置下次运行时间,停止。');
- stopRefresh(true); // 确保状态一致性
- return; // 没有有效的下次运行时间
- }
- delayMs = Math.max(0, nextRunTimestamp - now); // 计算剩余时间
- console.log(`定时刷新器: 自动启动检查 - 计划时间: ${new Date(nextRunTimestamp).toLocaleTimeString()}, 剩余: ${delayMs}ms`);
- if (delayMs < 100) { // 如果时间已过或非常接近,立即刷新
- console.log('定时刷新器: 自动启动检查 - 时间已到,立即刷新。');
- performRefresh();
- return;
- }
- // 如果还有时间,则按剩余时间启动定时器
- } else {
- // 手动启动
- intervalValue = parseInt(intervalInput.value, 10);
- if (isNaN(intervalValue) || intervalValue < 1) {
- alert('请输入有效的刷新间隔(必须是大于等于 1 的整数)。');
- intervalInput.value = GM_getValue(STORAGE_KEY_INTERVAL, DEFAULT_INTERVAL_SECONDS);
- return;
- }
- GM_setValue(STORAGE_KEY_INTERVAL, intervalValue); // 保存新间隔
- delayMs = intervalValue * 1000; // 使用完整间隔
- nextRunTimestamp = Date.now() + delayMs; // 计算并保存首次运行时间
- GM_setValue(STORAGE_KEY_NEXT_RUN, nextRunTimestamp);
- console.log(`定时刷新器: 手动启动 - 间隔: ${intervalValue}s, 下次运行: ${new Date(nextRunTimestamp).toLocaleTimeString()}`);
- }
- // 清除可能存在的旧定时器
- if (refreshTimerId) clearTimeout(refreshTimerId);
- if (countdownTimerId) clearInterval(countdownTimerId);
- isRunning = true; // 设置瞬时运行状态
- // 更新按钮和输入框状态
- startButton.disabled = true;
- stopButton.disabled = false;
- intervalInput.disabled = true;
- // 启动新的定时器
- refreshTimerId = setTimeout(performRefresh, delayMs); // 设置刷新动作
- updateCountdown(); // 立即更新一次显示
- countdownTimerId = setInterval(updateCountdown, 1000); // 每秒更新倒计时
- }
- // 停止刷新流程
- function stopRefresh(isInternalCall = false) { // 添加参数防止重复打印日志
- // 清除定时器
- if (refreshTimerId) {
- clearTimeout(refreshTimerId);
- refreshTimerId = null;
- }
- if (countdownTimerId) {
- clearInterval(countdownTimerId);
- countdownTimerId = null;
- }
- // 清除存储的状态
- GM_setValue(STORAGE_KEY_NEXT_RUN, 0); // 设置为0或无效值表示停止
- isRunning = false;
- nextRunTimestamp = 0;
- // 更新UI状态
- statusDisplay.textContent = '已停止';
- startButton.disabled = false;
- stopButton.disabled = true;
- intervalInput.disabled = false;
- if (!isInternalCall) {
- console.log('定时刷新器: 已手动停止');
- }
- }
- // --- 事件监听器 ---
- startButton.addEventListener('click', () => startRefresh(false)); // 手动启动
- stopButton.addEventListener('click', () => stopRefresh(false)); // 手动停止
- // --- 初始化和自动启动检查 ---
- function initialize() {
- console.log('定时刷新器脚本: 初始化...');
- // 检查是否需要自动启动
- nextRunTimestamp = GM_getValue(STORAGE_KEY_NEXT_RUN, 0);
- if (nextRunTimestamp > 0 && Date.now() < nextRunTimestamp + 1000) { // 加一点容错时间
- // 如果存储了有效的、未来的运行时间,则自动启动
- console.log('定时刷新器: 检测到未完成的刷新任务,尝试自动恢复...');
- startRefresh(true); // 调用自动启动逻辑
- } else {
- // 否则,确保处于停止状态
- console.log('定时刷新器: 无需自动启动,保持停止状态。');
- stopRefresh(true); // 使用内部调用避免打印停止日志
- }
- }
- initialize(); // 页面加载时执行初始化检查
- })();
复制代码
虚拟机session停止了,重新启动或点击Reset按钮,home目录不会重置,根目录会重置,所以要将disk.qcow2保存在home里!
不要按 Ubuntu 的 Poweroff(右上角)的关机按钮,这会导致你的idx一段时间失联
给佬们欣赏欣赏
|
|