连接探测只看通不通:绿红两色 60 格,去掉延迟抖动丢包,前台固定每秒探测

- ProbeGrid 只分绿(通)、红(超时或不可达)、灰(尚无数据),不再用橙色表示延迟偏高
- 探测历史固定 60 次:弹窗 20 列 3 行,主窗口 30 列 2 行;去掉格子下面的延迟、抖动、丢包与 NetworkController 里对应的统计
- 网络详情打开时固定每秒探测一次(NetworkController.foregroundProbeSeconds),移除 AppSettings.probeSeconds、设置里的“探测间隔”与同步文档字段;后台低频探测仍每 10 秒
- 译文、README、官网与隐私页、更新日志同步
This commit is contained in:
gentpan committed 2026-09-16 18:32:38 +05:00
1 parent d68fbce42a
commit 9e4f92e366
16 files changed
+35 -93

No files matched your search

+1
View File
@@ -10,6 +10,7 @@
#### 样式
- 主窗口在 macOS 26 上改用液态玻璃:侧边栏是一块浮在窗口里的玻璃面板,红绿灯按钮落在面板里,选中项垫一块淡蓝色圆角底并随切换滑动;顶栏右侧“在菜单栏显示”一组收进玻璃胶囊。主按钮是蓝色玻璃胶囊、次要按钮与图标按钮是透明玻璃,风扇模式等快捷切换是玻璃胶囊,开关换成系统开关(拖动时滑块变成玻璃)。设置分组与数据卡片保持实色,与系统设置一致。macOS 14、15 上保持原来的样式。
- 连接探测只用来看网络通不通:格子通了是绿色、不通是红色(不再用橙色表示延迟偏高),固定 60 格,弹窗排成 3 行、主窗口排成 2 行;去掉格子下面的延迟、抖动、丢包三项。打开网络详情时固定每秒探测一次,「设置 · 网络」里的“探测间隔”选项随之去掉,后台低频探测仍是每 10 秒。
- 分段切换改为苹果标准样式:灰色圆角底槽,各段等宽铺满,选中的一段是实心蓝色、白字,切换时蓝块滑过去;网络详情的 IPv4 / IPv6 切换同样是灰底蓝选中。
#### 新增
@@ -89,7 +89,7 @@ npm 缓存 npm Cache
{} {} 英寸 {} {}-inch
{} · {} 个 {} · {}
{} · {} 核 {} · {} cores
{} · 每 {} 秒 {} · every {}s
{} · 每秒一次 {} · every second
{} · 约 {} {} · about {}
{} · 负载 {}/{} {} · load {}/{}
{} 个 {}
@@ -123,8 +123,8 @@ npm 缓存 npm Cache
{}后充满 Full in {}
{}电量低 {} battery low
{}({}) {} ({})
{},{} 秒,后台{} {}, {}s, background {}
{},{},健康 {} {}, {}, health {}
{},后台{} {}, background {}
{}:{} {}: {}
~/.npm/_cacache,安装依赖时自动重新下载 ~/.npm/_cacache; downloaded again when installing dependencies
~/Library/Caches 中各应用的缓存,删除后会按需重建 App caches in ~/Library/Caches; rebuilt as needed
@@ -157,7 +157,6 @@ npm 缓存 npm Cache
不限 No limit
不限时 Indefinitely
与 30 秒前持平 Same as 30s ago
丢包 Loss
严重 Critical
中等负载 Moderate load
中等风险 Medium risk
@@ -470,7 +469,6 @@ npm 缓存 npm Cache
应用缓存 App Caches
应用退出或断开连接时,自动恢复风扇与睡眠设置 Restores fan and sleep settings when the app quits or disconnects
废纸篓 Trash
延迟 Latency
开 On
开关防休眠 Toggle Keep Awake
开发构建不支持在线升级 Development builds can't update online
@@ -523,7 +521,6 @@ npm 缓存 npm Cache
打开 OpenStats 主窗口 Open the OpenStats Window
打开 SMC 失败 ({}) Failed to open SMC ({})
打开登录项设置 Open Login Items Settings
打开网络详情时使用 Used while network details are open
打开网络详情时向 Cloudflare(1.1.1.1)或 ipify 查询一次公网地址,10 分钟内不重复请求;归属地、ASN、网络类型与纯净度由这台 Mac 直接向 cleanip.io 查询,只发送公网地址 When network details open, asks Cloudflare (1.1.1.1) or ipify for your public address, at most once every 10 minutes; location, ASN, network type and cleanliness are looked up by this Mac directly at cleanip.io, sending only the public address
打开进程页 Show Processes
打开通知设置 Open Notification Settings
@@ -532,7 +529,6 @@ npm 缓存 npm Cache
扫描中 Scanning
扫描中… Scanning…
扫描于 Scanned
抖动 Jitter
折线历史 Line History
折线是最近 30 次采样(约 1 分钟)的走势 The line shows the last 30 samples (about a minute)
拷贝 Copy
@@ -550,7 +546,6 @@ npm 缓存 npm Cache
掌托 Palm rest
排队程度 Run Queue
探测目标 Probe Target
探测间隔 Probe Interval
接口 Interface
接通电源 Plugged in
推出 Eject
@@ -762,7 +757,6 @@ npm 缓存 npm Cache
现在 Now
现在没有本地快照 No local snapshots right now
用 Apple 智能解释 Explain with Apple Intelligence
用 ping 测量延迟与丢包,在网络详情里以格子显示 Measures latency and loss with ping, shown as a grid in network details
用户 User
用户 {} User {}
用户资源库 User Library
@@ -867,6 +861,7 @@ npm 缓存 npm Cache
网络已恢复 Network Restored
网络断开 Network Down
网络类型 Network type
网络详情打开时每秒 ping 一次,通了是绿格、不通是红格,显示最近 60 次 Pings once a second while network details are open: green when reachable, red when not, showing the last 60
网络运营方 Network operator
网络连接中断超过 20 秒,恢复后再提示一次 Network has been down for over 20 seconds; notifies again when it's back
网络连接已中断超过 20 秒。可以打开网络详情查看接口与路由器状态。 The network has been down for over 20 seconds. Open network details to check the interface and router.
@@ -206,11 +206,10 @@ public final class AppController: NSObject, NSApplicationDelegate {
}
}
/// 探测目标、间隔变化时清空历史重新探测;关闭公网 IP 查询时清除已显示的结果
/// 探测目标变化时清空历史重新探测;关闭公网 IP 查询时清除已显示的结果
private func observeProbeSettings() {
withObservationTracking {
_ = model.settings.probeTarget
_ = model.settings.probeSeconds
_ = model.settings.publicIPLookup
} onChange: { [weak self] in
Task { @MainActor in
@@ -464,13 +464,12 @@ struct MirroredRateChart: View {
}
}
/// 连接探测格子:按时间从左到右、从上到下排列,最新的一格在末尾。
/// 绿色正常,橙色延迟偏高,红色超时,灰色尚无数据
/// 连接探测格子:一格一次探测,从左上到右下按时间排,最新的在最后一格。
/// 只表示通不通:通了是绿色,超时或不可达是红色,还没探测到的是灰色
struct ProbeGrid: View {
let samples: [ProbeSample]
var columns = 20
var rows = 3
var slowThreshold: Double = 200
var body: some View {
let capacity = columns * rows
@@ -487,8 +486,8 @@ struct ProbeGrid: View {
let color: Color
if index < offset {
color = DS.Palette.track
} else if let latency = recent[index - offset].latency {
color = latency >= slowThreshold ? DS.Palette.warning : DS.Palette.success
} else if recent[index - offset].latency != nil {
color = DS.Palette.success
} else {
color = DS.Palette.error
}
@@ -100,17 +100,13 @@ private struct ProbeSection: View {
SectionCard(title: PopoverSection.networkProbe.title, trailing: {
if settings.probeEnabled {
Text(verbatim: tr("\(network.probeAddress ?? "—") · 每 \(settings.probeSeconds) 秒"))
Text(verbatim: tr("\(network.probeAddress ?? "—") · 每秒一次"))
}
}) {
if settings.probeEnabled {
ProbeGrid(samples: network.probes.elements, columns: isDetailPage ? 40 : 20, rows: 3)
HStack(spacing: DS.Space.s3) {
stat(tr("延迟"), network.latency.map(milliseconds) ?? "—")
stat(tr("抖动"), network.jitter.map(milliseconds) ?? "—")
stat(tr("丢包"), network.lossRate.map { Format.percent($0) } ?? "—",
tone: (network.lossRate ?? 0) > 0.05 ? .error : .neutral)
}
// 只用来看网络通不通:60 格是最近 60 次探测,主窗口里更宽,排成两行
let columns = isDetailPage ? 30 : 20
ProbeGrid(samples: network.probes.elements, columns: columns, rows: NetworkController.probeCapacity / columns)
} else {
HStack {
Text(tr("定时 ping 一个地址,记录网络是否通畅")).dsFont(.xs).foregroundStyle(DS.Palette.textSecondary)
@@ -121,21 +117,6 @@ private struct ProbeSection: View {
}
}
}
private func milliseconds(_ value: Double) -> String {
value < 10 ? "\(value.formatted(.number.precision(.fractionLength(1)))) ms" : "\(Int(value.rounded())) ms"
}
private func stat(_ label: String, _ value: String, tone: Tone = .neutral) -> some View {
VStack(alignment: .leading, spacing: 0) {
Text(label).dsFont(.xs).foregroundStyle(DS.Palette.textTertiary)
Text(verbatim: value)
.dsFont(.sm, weight: .semibold)
.monospacedDigit()
.foregroundStyle(tone == .neutral ? DS.Palette.textPrimary : tone.color)
}
.frame(maxWidth: .infinity, alignment: .leading)
}
}
// MARK: - 接口
@@ -552,18 +552,10 @@ struct NetworkSettings: View {
SettingsGroup(caption: tr("连接探测")) {
GroupRow(showsDivider: false) {
SettingRow(title: tr("定时探测网络"), subtitle: tr("用 ping 测量延迟与丢包,在网络详情里以格子显示")) {
SettingRow(title: tr("定时探测网络"), subtitle: tr("网络详情打开时每秒 ping 一次,通了是绿格、不通是红格,显示最近 60 次")) {
DSToggle(isOn: $settings.probeEnabled, label: tr("定时探测网络"))
}
}
GroupRow {
SettingRow(title: tr("探测间隔"), subtitle: tr("打开网络详情时使用")) {
SegmentedControl(selection: $settings.probeSeconds,
options: AppSettings.probeOptions.map { ($0, tr("\($0) 秒")) })
.frame(width: DS.Size.sidebarWidth)
}
}
.disabled(!settings.probeEnabled)
GroupRow {
SettingRow(title: tr("探测目标"), subtitle: tr("国内网络建议选阿里云或腾讯;选路由器只检测本地连接")) {
Picker(tr("探测目标"), selection: $settings.probeTarget) {
@@ -14,7 +14,6 @@ enum SnapshotRenderer {
let defaults = UserDefaults(suiteName: "OpenStats.snapshot") ?? .standard
let settings = AppSettings(defaults: defaults)
settings.menuBarItems = [.cpu, .gpu, .memory, .network, .disk, .temperature, .battery]
settings.probeSeconds = 1
// 历史页用示例数据:最近 24 小时每分钟一条,中间留一段“睡眠”空档
let historyURL = FileManager.default.temporaryDirectory.appendingPathComponent("openstats-snapshot-history.sqlite")
try? FileManager.default.removeItem(at: historyURL)
@@ -435,9 +435,6 @@ public final class AppSettings {
public var probeInBackground: Bool {
didSet { defaults.set(probeInBackground, forKey: Keys.probeInBackground) }
}
public var probeSeconds: Int {
didSet { defaults.set(probeSeconds, forKey: Keys.probeSeconds) }
}
public var probeTarget: ProbeTarget {
didSet { defaults.set(probeTarget.rawValue, forKey: Keys.probeTarget) }
}
@@ -491,7 +488,6 @@ public final class AppSettings {
}
public static let refreshOptions = [1, 2, 3, 5]
public static let probeOptions = [1, 2, 5]
public static let batteryFloorOptions = [10, 20, 30, 40]
public static let fanSafetyOptions = [85, 90, 95, 100]
public static let alertTemperatureOptions = [85, 90, 95, 100]
@@ -526,8 +522,6 @@ public final class AppSettings {
.map { Set($0.compactMap(PopoverSection.init(rawValue:))) } ?? PopoverSection.hiddenByDefault
probeEnabled = defaults.object(forKey: Keys.probeEnabled) as? Bool ?? true
probeInBackground = defaults.object(forKey: Keys.probeInBackground) as? Bool ?? true
probeSeconds = Self.probeOptions.contains(defaults.integer(forKey: Keys.probeSeconds))
? defaults.integer(forKey: Keys.probeSeconds) : 2
probeTarget = defaults.string(forKey: Keys.probeTarget).flatMap(ProbeTarget.init(rawValue:)) ?? .cloudflare
publicIPLookup = defaults.object(forKey: Keys.publicIPLookup) as? Bool ?? true
autoCheckUpdates = defaults.object(forKey: Keys.autoCheckUpdates) as? Bool ?? true
@@ -589,7 +583,6 @@ public final class AppSettings {
static let menuBarLayout = "menuBarLayout"
static let hiddenPopoverSections = "hiddenPopoverSections"
static let probeEnabled = "probeEnabled"
static let probeSeconds = "probeSeconds"
static let probeInBackground = "probeInBackground"
static let probeTarget = "probeTarget"
static let publicIPLookup = "publicIPLookup"
@@ -110,7 +110,7 @@ final class DiagnosticsExporter {
row(tr("菜单栏风格"), settings.menuBarStyle.rawValue)
row(tr("刷新间隔"), tr("\(settings.refreshSeconds) 秒"))
row(tr("外观"), settings.appearance.rawValue)
row(tr("连接探测"), settings.probeEnabled ? tr("\(settings.probeTarget.rawValue),\(settings.probeSeconds) 秒,后台\(settings.probeInBackground ? tr("开启") : tr("关闭"))") : tr("关闭"))
row(tr("连接探测"), settings.probeEnabled ? tr("\(settings.probeTarget.rawValue),后台\(settings.probeInBackground ? tr("开启") : tr("关闭"))") : tr("关闭"))
row(tr("公网 IP 查询"), settings.publicIPLookup ? tr("开启") : tr("关闭"))
row(tr("风扇安全温度"), "\(settings.fanSafetyTemperature)°C")
row(tr("合盖电量下限"), "\(settings.lidModeBatteryFloor)%")
@@ -12,8 +12,8 @@ public struct ProbeSample: Sendable, Equatable {
@MainActor
@Observable
public final class NetworkController {
/// 主窗口显示 120 次,弹窗显示最近 60 次
public static let probeCapacity = 120
/// 探测格子显示最近 60 次;前台每秒一次,也就是最近 60 秒
public static let probeCapacity = 60
public private(set) var details: NetworkDetails?
/// 公网 IP 信息按地址族各存一份:两份都含 IPv4 与 IPv6 地址,归属地、纯净度等是各自那个地址的
@@ -50,7 +50,8 @@ public final class NetworkController {
/// 正在运行的探测是否为前台频率;前后台切换时重启循环,不必等完后台的长间隔
@ObservationIgnored private var probingForeground: Bool?
/// 详情关闭、只在菜单栏显示网速时的低频探测间隔
/// 网络详情打开时每秒探测一次;详情关闭、只在菜单栏显示网速时低频探测
static let foregroundProbeSeconds = 1
static let backgroundProbeSeconds = 10
/// 上次查到的公网 IP 信息:点开弹窗时先显示它,只有超过 7 天或公网 IP 变了才重新查归属地
@@ -113,24 +114,7 @@ public final class NetworkController {
rate.totalUploaded >= baseline.upload ? rate.totalUploaded - baseline.upload : 0)
}
// MARK: 统计
/// 最近一次成功探测的延迟
var latency: Double? { probes.elements.last?.latency }
/// 抖动:相邻两次成功探测的延迟差的平均值
var jitter: Double? {
let values = probes.elements.suffix(20).compactMap(\.latency)
guard values.count > 2 else { return nil }
let differences = zip(values.dropFirst(), values).map { abs($0 - $1) }
return differences.reduce(0, +) / Double(differences.count)
}
var lossRate: Double? {
let recent = probes.elements
guard !recent.isEmpty else { return nil }
return Double(recent.filter { $0.latency == nil }.count) / Double(recent.count)
}
// MARK: 探测目标
var probeAddress: String? {
settings.probeTarget.address(router: details?.physical?.router)
@@ -316,7 +300,7 @@ public final class NetworkController {
let clock = ContinuousClock()
while !Task.isCancelled {
guard let self else { return }
let interval = Double(foreground ? self.settings.probeSeconds : Self.backgroundProbeSeconds)
let interval = Double(foreground ? Self.foregroundProbeSeconds : Self.backgroundProbeSeconds)
if self.details == nil { await self.refreshDetails() }
let started = clock.now
guard let address = self.probeAddress else {
@@ -21,7 +21,6 @@ public struct SettingsDocument: Codable, Equatable, Sendable {
public var hiddenPopoverSections: [String]?
public var probeEnabled: Bool?
public var probeInBackground: Bool?
public var probeSeconds: Int?
public var probeTarget: String?
public var publicIPLookup: Bool?
public var enabledAlerts: [String]?
@@ -55,7 +54,6 @@ extension AppSettings {
doc.hiddenPopoverSections = hiddenPopoverSections.map(\.rawValue).sorted()
doc.probeEnabled = probeEnabled
doc.probeInBackground = probeInBackground
doc.probeSeconds = probeSeconds
doc.probeTarget = probeTarget.rawValue
doc.publicIPLookup = publicIPLookup
doc.enabledAlerts = enabledAlerts.map(\.rawValue).sorted()
@@ -99,7 +97,6 @@ extension AppSettings {
assign(\.hiddenPopoverSections, doc.hiddenPopoverSections.map { Set($0.compactMap(PopoverSection.init(rawValue:))) })
assign(\.probeEnabled, doc.probeEnabled)
assign(\.probeInBackground, doc.probeInBackground)
assign(\.probeSeconds, option(doc.probeSeconds, in: Self.probeOptions))
assign(\.probeTarget, doc.probeTarget.flatMap(ProbeTarget.init(rawValue:)))
assign(\.publicIPLookup, doc.publicIPLookup)
assign(\.enabledAlerts, doc.enabledAlerts.map { Set($0.compactMap(AlertKind.init(rawValue:))) })
+5 -4
View File
@@ -59,14 +59,15 @@ system language by default; switch it in Settings → General → Language.
<!-- changelog:start -->
<!-- Generated from CHANGELOG.md by Scripts/sync_changelog.py. Do not edit by hand. -->
Latest release **0.3.2** (2026-09-16) · **3** changes in development · [full changelog](CHANGELOG.md) (kept in Chinese)
Latest release **0.3.2** (2026-09-16) · **4** changes in development · [full changelog](CHANGELOG.md) (kept in Chinese)
<details open>
<summary><b>2026-09-16</b> · Unreleased · 2 style · 1 added</summary>
<summary><b>2026-09-16</b> · Unreleased · 3 style · 1 added</summary>
**Style**
- 主窗口在 macOS 26 上改用液态玻璃:侧边栏是一块浮在窗口里的玻璃面板,红绿灯按钮落在面板里,选中项垫一块淡蓝色圆角底并随切换滑动;顶栏右侧“在菜单栏显示”一组收进玻璃胶囊。主按钮是蓝色玻璃胶囊、次要按钮与图标按钮是透明玻璃,风扇模式等快捷切换是玻璃胶囊,开关换成系统开关(拖动时滑块变成玻璃)。设置分组与数据卡片保持实色,与系统设置一致。macOS 14、15 上保持原来的样式。
- 连接探测只用来看网络通不通:格子通了是绿色、不通是红色(不再用橙色表示延迟偏高),固定 60 格,弹窗排成 3 行、主窗口排成 2 行;去掉格子下面的延迟、抖动、丢包三项。打开网络详情时固定每秒探测一次,「设置 · 网络」里的“探测间隔”选项随之去掉,后台低频探测仍是每 10 秒。
- 分段切换改为苹果标准样式:灰色圆角底槽,各段等宽铺满,选中的一段是实心蓝色、白字,切换时蓝块滑过去;网络详情的 IPv4 / IPv6 切换同样是灰底蓝选中。
**Added**
@@ -138,7 +139,7 @@ Choose which sections each popover shows in Settings. `Esc` closes it.
queueing (load average per core, rising or falling); usage summed by app.
- **Memory.** What is still available with a pressure timeline; a waterline bar; memory saved by compression and
live swap I/O; usage summed by app.
- **Network.** Traffic history; a connection-probe grid (latency, jitter, loss); interface,
- **Network.** Traffic history; a connection-probe grid (green when reachable, red when not, last 60 pings); interface,
Wi-Fi signal, VPN / proxy; local and public IPv4 / IPv6 with a flag, region and ASN; an IP cleanliness score with an F to A+
grade and risk flags (VPN, proxy, Tor, data center, abuse); DNS flush
and one-click switching to Cloudflare, Google, Tencent, Alibaba Cloud or manual servers;
@@ -244,7 +245,7 @@ check in Settings → About:
come from `cleanip.io`, queried directly from each Mac with nothing but the public address and never
through our servers; a result is kept for a week unless the address changes or you refresh.
- **Connection probe**: an ICMP ping to the target you pick (Cloudflare, Google, Alibaba Cloud,
Tencent or your router) every 1, 2 or 5 seconds, only while the network item is in the menu bar
Tencent or your router) once a second while network details are open (every 10 seconds in the background), only while the network item is in the menu bar
or network details are open.
- **Update check**: at launch and once a day, the app reads a version manifest from getopenstats.com — the
manifest only. When a new version is out it asks; nothing installs without your click.
+5 -4
View File
@@ -55,14 +55,15 @@ CPU 不分性能核与能效核,部分功耗与频率读数可能不显示。
<!-- changelog:start -->
<!-- 由 Scripts/sync_changelog.py 从 CHANGELOG.md 生成,请勿手改。 -->
最新版本 **0.3.2**(2026-09-16) · 开发中 **3** 项改动尚未发布 · [完整更新日志](CHANGELOG.md)
最新版本 **0.3.2**(2026-09-16) · 开发中 **4** 项改动尚未发布 · [完整更新日志](CHANGELOG.md)
<details open>
<summary><b>2026-09-16</b> · 未发布 · 样式 2 · 新增 1</summary>
<summary><b>2026-09-16</b> · 未发布 · 样式 3 · 新增 1</summary>
**样式**
- 主窗口在 macOS 26 上改用液态玻璃:侧边栏是一块浮在窗口里的玻璃面板,红绿灯按钮落在面板里,选中项垫一块淡蓝色圆角底并随切换滑动;顶栏右侧“在菜单栏显示”一组收进玻璃胶囊。主按钮是蓝色玻璃胶囊、次要按钮与图标按钮是透明玻璃,风扇模式等快捷切换是玻璃胶囊,开关换成系统开关(拖动时滑块变成玻璃)。设置分组与数据卡片保持实色,与系统设置一致。macOS 14、15 上保持原来的样式。
- 连接探测只用来看网络通不通:格子通了是绿色、不通是红色(不再用橙色表示延迟偏高),固定 60 格,弹窗排成 3 行、主窗口排成 2 行;去掉格子下面的延迟、抖动、丢包三项。打开网络详情时固定每秒探测一次,「设置 · 网络」里的“探测间隔”选项随之去掉,后台低频探测仍是每 10 秒。
- 分段切换改为苹果标准样式:灰色圆角底槽,各段等宽铺满,选中的一段是实心蓝色、白字,切换时蓝块滑过去;网络详情的 IPv4 / IPv6 切换同样是灰底蓝选中。
**新增**
@@ -129,7 +130,7 @@ CPU 不分性能核与能效核,部分功耗与频率读数可能不显示。
**详情弹窗**——每个指标一个菜单栏图标,点击弹出该项的窄详情,显示哪些区块可在设置里勾选;按 `Esc` 关闭。
- **CPU**:占用与状态、与 30 秒前的变化、CPU 温度与余量、1 / 3 / 5 分钟走势;核心热力图与此刻各核心占用;核心分工与频率;排队程度(每核平均负载与趋势);按应用汇总。
- **内存**:还可用多少与压力走势;内存水位条;压缩省下的内存与交换区读写;按应用汇总。
- **网络**:流量历史;连接探测格子(延迟、抖动、丢包);接口、Wi-Fi 信号、VPN / 代理;本地与公网 IPv4 / IPv6,
- **网络**:流量历史;连接探测格子(通了是绿格、不通是红格,最近 60 次);接口、Wi-Fi 信号、VPN / 代理;本地与公网 IPv4 / IPv6,
归属地国旗、ASN;IP 纯净度评分与 F 到 A+ 等级、风险标记(VPN、代理、Tor、机房、滥用记录);DNS 一键刷新,一键切换 Cloudflare、Google、腾讯、阿里云或手动填写;各进程流量。
- **磁盘**:启动磁盘容量分段条(已用、可清除、可用);读写速度与 60 秒走势;SSD 健康;读写最多的应用。
- **GPU**、**温度与风扇**:使用历史、各组温度、风扇转速与快捷模式。
@@ -211,7 +212,7 @@ CPU 不分性能核与能效核,部分功耗与频率读数可能不显示。
会联网的功能都可以关闭。前两项在“设置 → 网络”中,检查更新在“设置 · 关于”中:
- **公网 IP**:打开网络详情时向 Cloudflare `1.1.1.1`(回退 ipify)请求一次公网地址,10 分钟内不重复请求。归属地、ASN、网络类型与纯净度评分由这台 Mac 直接向 `cleanip.io` 查询,只发送公网地址、不经过我们的服务器;地址没变、不满 7 天就沿用上次结果,点刷新才重查。
- **连接探测**:每 1、2 或 5 秒向你选择的目标(Cloudflare、Google、阿里云、腾讯或路由器)发送一次 ICMP ping,只在菜单栏显示网络项或打开网络详情时运行。
- **连接探测**:打开网络详情时每秒(后台每 10 秒)向你选择的目标(Cloudflare、Google、阿里云、腾讯或路由器)发送一次 ICMP ping,只在菜单栏显示网络项或打开网络详情时运行。
- **检查更新**:启动时与之后每天向 getopenstats.com 读取一次版本清单,只下载清单本身;发现新版本时提示,由你决定是否安装。
账号是可选的,只在登录后同步偏好设置,不含任何监控数据。
+1 -1
View File
@@ -13,7 +13,7 @@ settings:
SWIFT_VERSION: "6.0"
MARKETING_VERSION: "0.3.2"
# 构建号四位数字,每次 make build 加一;营销版本只在发布时用 Scripts/version.sh patch / minor 修改
CURRENT_PROJECT_VERSION: "0067"
CURRENT_PROJECT_VERSION: "0068"
MACOSX_DEPLOYMENT_TARGET: "14.0"
# 本地开发使用 ad-hoc 签名;发布时改为 Developer ID(见 docs/PLAN.md)
CODE_SIGN_STYLE: Manual
+2 -2
View File
@@ -248,7 +248,7 @@
<h2>网络,一眼看到底</h2>
<ul class="check-list">
<li>上下镜像的流量历史,上传绿、下载蓝</li>
<li>连接探测格子:每 1 / 2 / 5 秒 ping 一次,延迟、抖动、丢包一目了然</li>
<li>连接探测格子:每秒 ping 一次,通了是绿格、不通是红格,最近 60 次一眼看清</li>
<li>本地与公网 IPv4 / IPv6、路由器、Wi‑Fi 信号,点一下就拷贝</li>
<li>归属地显示国旗、城市、ASN 与网络运营方,原生 / 广播、住宅 / 机房直接标出</li>
<li>IP 纯净度:CleanIP.io 评分与 F 到 A+ 等级色带,列出 VPN、代理、Tor、机房、滥用记录等风险标记</li>
@@ -326,7 +326,7 @@
<li><b>统计上报</b><span>没有</span></li>
<li><b>公网 IP</b><span>打开网络详情时向 Cloudflare 查询一次公网地址,10 分钟内不重复,可关闭</span></li>
<li><b>归属地</b><span>归属地、ASN、网络类型与纯净度评分来自 cleanip.io,这台 Mac 直接向它查自己的公网 IP,只发送这个地址</span></li>
<li><b>连接探测</b><span>按设定间隔 ping 你选择的目标,只在显示网络项时运行,可关闭</span></li>
<li><b>连接探测</b><span>打开网络详情时每秒 ping 一次你选择的目标(后台每 10 秒),只在显示网络项时运行,可关闭</span></li>
<li><b>偏好设置</b><span>保存在本机;登录后同步的那一份不含任何监控数据</span></li>
</ul>
</div>
+1 -1
View File
@@ -35,7 +35,7 @@
<ul class="fact-list">
<li><b>公网 IP</b><span>打开网络详情时向 Cloudflare 查询一次公网地址,10 分钟内不重复,可在设置中关闭</span></li>
<li><b>归属地</b><span>归属地、ASN、网络类型与纯净度评分由 cleanip.io 提供:这台 Mac 直接向它查询自己的公网 IP,只发送这个地址、不带其他信息,不经过 OpenStats 的服务器</span></li>
<li><b>连接探测</b><span>按设定间隔 ping 你选择的目标,只在显示网络项时运行,可关闭</span></li>
<li><b>连接探测</b><span>打开网络详情时每秒 ping 一次你选择的目标(后台每 10 秒),只在显示网络项时运行,可关闭</span></li>
<li><b>检查更新</b><span>启动时与每天一次读取 getopenstats.com 上的版本清单,请求不带任何标识</span></li>
</ul>