Compare commits

...

6 Commits

Author SHA1 Message Date
fd3863c0d4
The Rewrite: Rustification
All checks were successful
Rust / build (push) Successful in 2m26s
2025-03-14 14:24:29 -04:00
8740c41a63
update readme idk if this will work
All checks were successful
Rust / build (push) Successful in 1m28s
2024-08-29 15:45:19 -04:00
f057283998
Let's try building for windows using the action
All checks were successful
Rust / build (push) Successful in 1m17s
2024-08-29 15:03:27 -04:00
52359bfeeb
dynamic fps cap! (dewb)
All checks were successful
Rust / build (push) Successful in 1m55s
2024-08-29 17:55:40 -04:00
8c19ed0208
Rename folder .github -> .gitea + rewrite
All checks were successful
Rust / build (push) Successful in 1m40s
2024-08-26 13:52:34 -04:00
dd2d5a58b1
small tweak + formatting 2024-08-26 08:48:53 -04:00
6 changed files with 268 additions and 63 deletions

32
.gitea/workflows/rust.yml Normal file
View File

@ -0,0 +1,32 @@
name: Rust
on:
push:
branches: ["master"]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install rust
uses: dtolnay/rust-toolchain@stable
with:
targets: "x86_64-pc-windows-gnu"
- name: Install cross compilation tools
run: sudo apt-get update && sudo apt-get install mingw-w64 -y
- name: Setup Cache
uses: Swatinem/rust-cache@v2
- name: Build release
run: cargo build --verbose --locked --release --target x86_64-pc-windows-gnu
- name: Archive build
uses: actions/upload-artifact@v3
with:
name: alt_enter_fix
path: target/x86_64-pc-windows-gnu/release/alt_enter_fix.exe

View File

@ -1,22 +0,0 @@
name: Rust
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
env:
CARGO_TERM_COLOR: always
jobs:
build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: Build
run: cargo build --verbose
- name: Run tests
run: cargo test --verbose

90
Cargo.lock generated
View File

@ -1,7 +1,95 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
version = 4
[[package]]
name = "alt_enter_fix"
version = "0.1.0"
dependencies = [
"serde_json",
]
[[package]]
name = "itoa"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "proc-macro2"
version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
name = "ryu"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "serde"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.140"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
]
[[package]]
name = "syn"
version = "2.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"

View File

@ -5,4 +5,8 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc"
[dependencies]
serde_json = "1.0.140"

View File

@ -1,5 +1,5 @@
# alt_enter_fix
[![Rust](https://github.com/dowoge/alt_enter_fix/actions/workflows/rust.yml/badge.svg)](https://github.com/dowoge/alt_enter_fix/actions/workflows/rust.yml)
[![Rust](https://git.tommyy.dev/tommy/alt_enter_fix/actions/workflows/rust.yml/badge.svg)](https://git.tommyy.dev/tommy/alt_enter_fix/actions/workflows/rust.yml)
fire program

View File

@ -1,47 +1,150 @@
use std::{io, fs, env, path::Path};
use io::Read;
fn main() {
let mut rblxpath = String::new();
if let Some(lad) = env::var("LOCALAPPDATA").ok() {
let temprbx_lad = format!("{}\\Roblox",lad);
if Path::new(&temprbx_lad).is_dir() {
rblxpath = temprbx_lad;
}
} else if let Some(pfx86) = env::var("ProgramFiles(x86)").ok() {
let temprbx_pfx86 = format!("{}\\Roblox",pfx86);
if Path::new(&temprbx_pfx86).is_dir() {
rblxpath = temprbx_pfx86;
}
}
if rblxpath != "" {
println!("Found path: {}",rblxpath);
} else {
use serde_json::{json, Value};
use std::{env, fs, io::{self, stdin, Read, Write}, path::{Path, PathBuf}};
const UNLIMITED_FPS_CAP_NUM: i32 = i32::max_value();
fn main() -> io::Result<()> {
let roblox_path = find_roblox_path().ok_or_else(|| {
println!("Roblox not found (Die)");
return;
io::Error::new(io::ErrorKind::NotFound, "Roblox installation not found")
})?;
println!("Found path: {}", roblox_path.display());
println!("What FPS would you like to cap the fps to? (0 for no cap at all)");
io::stdout().flush()?;
let fps = read_fps_input()?;
let desired_fps = if fps == 0 { UNLIMITED_FPS_CAP_NUM } else { fps };
println!("FPS cap will be set to {desired_fps}");
let required_settings = json!({
// Restore original 'alt-enter' behaviour
"FFlagHandleAltEnterFullscreenManually": "False",
// Disable Roblox's built-in 240 fps hard-coded cap and replace with custom cap
"DFIntTaskSchedulerTargetFps": desired_fps,
"FFlagGameBasicSettingsFramerateCap5": "False",
"FFlagTaskSchedulerLimitTargetFpsTo2402": "False",
// Ensure Direct3D11 is the rendering API for optimal performance
"FFlagDebugGraphicsDisableDirect3D11": "False",
"FFlagDebugGraphicsPreferD3D11": "True",
// Disable telemetry related FFlags
"FFlagDebugDisableTelemetryEphemeralCounter": "True",
"FFlagDebugDisableTelemetryEphemeralStat": "True",
"FFlagDebugDisableTelemetryEventIngest": "True",
"FFlagDebugDisableTelemetryPoint": "True",
"FFlagDebugDisableTelemetryV2Counter": "True",
"FFlagDebugDisableTelemetryV2Event": "True",
"FFlagDebugDisableTelemetryV2Stat": "True"
});
update_client_settings(&roblox_path, required_settings)?;
println!("Press enter to exit");
let _ = io::stdin().read(&mut [0u8])?;
Ok(())
}
fn find_roblox_path() -> Option<PathBuf> {
if let Some(local_app_data) = env::var("LOCALAPPDATA").ok() {
let path = PathBuf::from(local_app_data).join("Roblox");
if path.is_dir() {
return Some(path);
}
}
let versions = format!("{}\\Versions\\",rblxpath);
for folder in fs::read_dir(versions).unwrap() {
let cur_folder = folder.unwrap().path().display().to_string();
if cur_folder.to_lowercase().contains("version") {
let executable = format!("{}\\RobloxPlayerBeta.exe",cur_folder);
if Path::new(&executable).is_file() {
let cs_folder = format!("{}\\ClientSettings",cur_folder);
if !Path::new(&cs_folder).is_dir() {
fs::create_dir(&cs_folder).ok();
println!("Created ClientSettings folder in {}",cur_folder);
// This is here because Roblox installs into Program Files (x86) if you run the installer as administrator (??? lol)
if let Some(program_files) = env::var("ProgramFiles(x86)").ok() {
let path = PathBuf::from(program_files).join("Roblox");
if path.is_dir() {
return Some(path);
}
}
None
}
fn read_fps_input() -> io::Result<i32> {
let mut input = String::new();
stdin().read_line(&mut input)?;
let input = input.trim();
input.parse::<i32>().map_err(|_| {
io::Error::new(io::ErrorKind::InvalidInput, "Invalid FPS value")
})
}
fn update_client_settings(roblox_path: &Path, required_settings: Value) -> io::Result<()> {
let versions_path = roblox_path.join("Versions");
for entry in fs::read_dir(versions_path)? {
let entry = entry?;
let path = entry.path();
let path_str = path.to_string_lossy().to_lowercase();
if path_str.contains("version") {
let executable = path.join("RobloxPlayerBeta.exe");
if executable.is_file() {
let client_settings_dir = path.join("ClientSettings");
if !client_settings_dir.exists() {
fs::create_dir(&client_settings_dir)?;
println!("Created ClientSettings folder in {}", path.display());
} else {
println!("ClientSettings folder already exists in {}",cur_folder);
}
let cas_json = format!("{}\\ClientAppSettings.json",cs_folder);
if !Path::new(&cas_json).is_file() {
fs::write(cas_json, "{\"FFlagHandleAltEnterFullscreenManually\":\"False\",\"DFIntTaskSchedulerTargetFps\":5588562,\"FFlagEnableInGameMenuChromeABTest3\":\"False\",\"FFlagGameBasicSettingsFramerateCap5\":\"False\",\"FFlagTaskSchedulerLimitTargetFpsTo2402\":\"False\"}").ok();
println!("Wrote ClientAppSettings.json to {}",cur_folder)
} else {
println!("ClientAppSettings.json already exists in {}",cur_folder)
println!("ClientSettings folder already exists in {}", path.display());
}
let settings_file = client_settings_dir.join("ClientAppSettings.json");
update_settings_file(&settings_file, &required_settings)?;
println!("Updated ClientAppSettings.json in {}", path.display());
}
}
}
println!("Press enter to exit");
let _ = io::stdin().read(&mut [0u8]).unwrap();
Ok(())
}
fn update_settings_file(file_path: &Path, required_settings: &Value) -> io::Result<()> {
// Funky code to edit or create the ClientAppSettings.json file (shoutout claude for the help with the object stuff (json sucks))
let mut settings = if file_path.exists() {
match fs::read_to_string(file_path) {
Ok(content) if !content.trim().is_empty() => {
match serde_json::from_str::<Value>(&content) {
Ok(existing) => existing,
Err(e) => {
println!("Warning: Could not parse existing settings ({}), creating new file", e);
json!({})
}
}
},
_ => json!({})
}
} else {
json!({})
};
if let Some(required_obj) = required_settings.as_object() {
if !settings.is_object() {
settings = json!({});
}
if let Some(settings_obj) = settings.as_object_mut() {
for (key, value) in required_obj {
println!("Adding {}: {}", key, value);
settings_obj.insert(key.clone(), value.clone());
}
}
}
let formatted = serde_json::to_string_pretty(&settings)?;
fs::write(file_path, formatted)?;
Ok(())
}