Skip to content

Commit

Permalink
[Feat] Detect runtime (#53)
Browse files Browse the repository at this point in the history
* detect runtime

* fix artifact publishing

* wrap some parts into try catches

* fix progress boundaries

* Update README.md
  • Loading branch information
Danil0v3s authored Dec 31, 2024
1 parent 47fddeb commit b6346e6
Show file tree
Hide file tree
Showing 24 changed files with 310 additions and 91 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: cleanmeter
path: target\server\build\compose\binaries\main\app
path: target\desktop\build\compose\binaries\main\app

dependency-submission:

Expand Down
50 changes: 27 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,33 @@
# <img align="left" src="images/Logo.png" height=50> Clean Meter

> Did you like my work? Consider supporting me so I can keep putting hours in.
> - [ko-fi](https://ko-fi.com/danil0v3s)
> - [PayPal](https://www.paypal.com/donate/?hosted_button_id=W2GU6AHGQUND8)
> [!IMPORTANT]
> We are preparing our first major release 1.0.0. It's already available in [beta1](https://github.com/Danil0v3s/CleanMeter/releases/tag/1.0.0.beta-1) and it makes our app completely standalone, without the need of HWiNFO or MSI Afterburner anymore. Try it out and let us know!
<a href="https://payloadcms.com"><img width="100%" src="https://github.com/user-attachments/assets/403720a9-8016-4fdc-b0a8-719bc25d63ee" alt="Payload headless CMS Admin panel built with React" /></a>
<br />
<br />


<p align="left">
<a href="https://github.com/Danil0v3s/CleanMeter/actions"><img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/Danil0v3s/CleanMeter/build.yml?style=flat-square"></a>
&nbsp;
<a href="https://discord.gg/phqwe89cvE"><img alt="Discord" src="https://img.shields.io/discord/1297574228698337405?label=Discord&color=7289da&style=flat-square" /></a>
&nbsp;
<a href="https://github.com/Danil0v3s/CleanMeter/graphs/contributors"><img alt="npm" src="https://img.shields.io/github/contributors-anon/Danil0v3s/CleanMeter?color=yellow&style=flat-square"/></a>
&nbsp;
<a href="https://github.com/Danil0v3s/CleanMeter/releases/latest"><img alt="GitHub Release" src="https://img.shields.io/github/v/release/Danil0v3s/CleanMeter"></a>
</p>
<hr/>
<h4>
<a target="_blank" href="https://ko-fi.com/danil0v3s" rel="dofollow"><strong>Donate via ko-fi</strong></a>&nbsp;·&nbsp;<a target="_blank" href="https://www.paypal.com/donate/?hosted_button_id=W2GU6AHGQUND8" rel="dofollow"><strong>Donate via PayPal</strong></a>&nbsp;·&nbsp;<a target="_blank" href="https://www.instagram.com/mars.designs" rel="dofollow"><strong>Follow our Designer</strong></a>
</h4>
<hr/>

> [!IMPORTANT]
> We released 0.0.4 which DROPPED the need of MSI Afterburner and rely entirely on HWInfo alone. We heard some of you dislike Afterburner so we opted to go the least friction route.
> 🎉 <strong>We've released 1.0!</strong> Star this repo or keep an eye on it to follow along.
## What is this?
CleanMeter is the first gamer oriented clean statistics tracker, no fuss no muss, dead simple setup and good looking visuals.

A small desktop companion app to display sleek graphs overlays from HWInfo. Designs were made by [/u/Violetmars](https://www.reddit.com/user/Violetmars/)

<img align="right" src="https://github.com/user-attachments/assets/5e797f42-bebc-4d8f-82c8-837fc4b58a07">
<img align="center" src="https://github.com/user-attachments/assets/6c7bd91a-7e9a-4c38-a450-d6e2ce26bcd4">

## Getting started
1. If you have HWiNFO installed already, make sure that `Enable Shared Memory Support` is **enabled** at the settings.
![image](images/qa_clean_meter.png)
> [!IMPORTANT]
> If you chose to have HWiNFO installed, _**you**_ will have to manage the `Shared Memory Support` limitation of 12 hours. Every 12 hours of uptime you will need to re-enable the setting. It seems the timer resets if you shutdown your computer before 12h uptime.
2. If you didn't have HWiNFO installed, there's no need to do any additional setup. (We manage a portable version of it ourselves)
3. Download the latest release, run it
### Benefits over traditional performance trackers
- This looks good
- No fluorescent numbers with Arial 12
- Doesn't mess with your power profile or fan setup

## Current Limitations
### Current Limitations
- Doesn't work with exclusive fullscreen
- Given our mission is to look _good_ and _clean_ at the same time, we might hold on to release new features because we need time to think how to accommodate our UI. We can't just enable every possible sensor, sorry.
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package app.cleanmeter.target.desktop.data
package app.cleanmeter.core.os

import app.cleanmeter.target.desktop.model.OverlaySettings
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import java.util.prefs.Preferences

const val OVERLAY_SETTINGS_PREFERENCE_KEY = "OVERLAY_SETTINGS_PREFERENCE_KEY"
Expand All @@ -26,18 +23,4 @@ object PreferencesRepository {
fun setPreference(key: String, value: String) = prefs.put(key, value)
fun setPreferenceBoolean(key: String, value: Boolean) = prefs.putBoolean(key, value)
fun clear() = prefs.clear()
}

fun PreferencesRepository.loadOverlaySettings(): OverlaySettings {
val json = getPreferenceString(OVERLAY_SETTINGS_PREFERENCE_KEY)
val settings = if (json != null) {
try {
Json.decodeFromString<OverlaySettings>(json)
} catch (e: Exception) {
OverlaySettings()
}
} else {
OverlaySettings()
}
return settings
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,53 @@ import app.cleanmeter.core.os.util.isDev
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.IOException
import java.nio.file.Path
import java.util.*

object HardwareMonitorProcessManager {
private var process: Process? = null

fun checkRuntime() {
ProcessBuilder().apply {
command("dotnet --list-runtimes")
}.start()
suspend fun checkRuntime(): Boolean {
return try {
val process = ProcessBuilder().apply {
command("cmd.exe", "/c", "dotnet", "--list-runtimes")
}.start()

val scannerIn = Scanner(process.inputStream)
val scannerErr = Scanner(process.errorStream)

val stdOutput = emptyList<String>().toMutableList()
val errOutput = emptyList<String>().toMutableList()

CoroutineScope(Dispatchers.IO).launch {
try {
while (scannerIn.hasNextLine()) {
stdOutput.add(scannerIn.nextLine())
}
} catch (e: Exception) {
return@launch
}

}
CoroutineScope(Dispatchers.IO).launch {
try {
while (scannerErr.hasNextLine()) {
errOutput.add(scannerIn.nextLine())
}
} catch (e: Exception) {
return@launch
}
}

return withContext(Dispatchers.IO) {
val exitCode = process.waitFor()
exitCode == 0 && errOutput.isEmpty()
}
} catch (ex: Exception) {
return false
}
}

fun start() {
Expand All @@ -32,12 +69,12 @@ object HardwareMonitorProcessManager {
val scannerErr = Scanner(process!!.errorStream)

CoroutineScope(Dispatchers.IO).launch {
while(scannerIn.hasNextLine()) {
while (scannerIn.hasNextLine()) {
System.out.println(scannerIn.nextLine())
}
}
CoroutineScope(Dispatchers.IO).launch {
while(scannerErr.hasNextLine()) {
while (scannerErr.hasNextLine()) {
System.err.println(scannerErr.nextLine())
}
}
Expand All @@ -57,7 +94,8 @@ object HardwareMonitorProcessManager {
val command = listOf(
"cmd.exe",
"/c",
"sc create svcleanmeter displayname= \"CleanMeter Service\" binPath= $file start= auto group= LocalServiceNoNetworkFirewall")
"sc create svcleanmeter displayname= \"CleanMeter Service\" binPath= $file start= auto group= LocalServiceNoNetworkFirewall"
)
ProcessBuilder().apply {
command(command)
}.start()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package app.cleanmeter.core.os.hardwaremonitor

import app.cleanmeter.core.os.PREFERENCE_PERMISSION_CONSENT
import app.cleanmeter.core.os.PreferencesRepository
import app.cleanmeter.core.os.util.getByteBuffer
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
Expand Down Expand Up @@ -55,7 +57,9 @@ object SocketClient {
val packetFlow: Flow<Packet> = packetChannel.receiveAsFlow()

init {
connect()
if (PreferencesRepository.getPreferenceBoolean(PREFERENCE_PERMISSION_CONSENT, false)) {
connect()
}
}

private fun connect() = CoroutineScope(Dispatchers.IO).launch {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,14 @@ class WindowsService {
fun tryElevateProcess(isAutostart: Boolean) {
if (isAutostart) return
if (!isDev() && !WindowsService.isProcessElevated()) {
val currentDir = Path.of("").toAbsolutePath().toString()
Shell32Impl.INSTANCE.ShellExecuteW(null, "runas", "$currentDir\\cleanmeter.exe", "", "", 10)
exitProcess(0)
elevateProcess()
}
}

fun elevateProcess() {
val currentDir = Path.of("").toAbsolutePath().toString()
Shell32Impl.INSTANCE.ShellExecuteW(null, "runas", "$currentDir\\cleanmeter.exe", "", "", 10)
exitProcess(0)
}
}
}
Binary file removed images/Logo.png
Binary file not shown.
1 change: 0 additions & 1 deletion images/compose-logo.svg

This file was deleted.

Binary file removed images/qa_clean_meter.png
Binary file not shown.
Binary file removed images/qa_clean_meter2.png
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import app.cleanmeter.core.common.reporting.ApplicationParams
import app.cleanmeter.core.os.ProcessManager
import app.cleanmeter.core.os.util.isDev
import app.cleanmeter.core.os.win32.WindowsService
import app.cleanmeter.target.desktop.data.PREFERENCE_PERMISSION_CONSENT
import app.cleanmeter.target.desktop.data.PreferencesRepository
import app.cleanmeter.core.os.PREFERENCE_PERMISSION_CONSENT
import app.cleanmeter.core.os.PreferencesRepository

fun main(vararg args: String) = singleInstance(args) {
if (PreferencesRepository.getPreferenceBoolean(PREFERENCE_PERMISSION_CONSENT, false)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package app.cleanmeter.target.desktop.data

import app.cleanmeter.core.os.OVERLAY_SETTINGS_PREFERENCE_KEY
import app.cleanmeter.core.os.PreferencesRepository
import app.cleanmeter.target.desktop.model.OverlaySettings
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package app.cleanmeter.target.desktop.data

import app.cleanmeter.core.os.OVERLAY_SETTINGS_PREFERENCE_KEY
import app.cleanmeter.core.os.PreferencesRepository
import app.cleanmeter.target.desktop.model.OverlaySettings
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json

fun PreferencesRepository.loadOverlaySettings(): OverlaySettings {
val json = getPreferenceString(OVERLAY_SETTINGS_PREFERENCE_KEY)
val settings = if (json != null) {
try {
Json.decodeFromString<OverlaySettings>(json)
} catch (e: Exception) {
OverlaySettings()
}
} else {
OverlaySettings()
}
return settings
}
Loading

0 comments on commit b6346e6

Please sign in to comment.