Disallow indexing (#320)

* Remove indexing

* Introduce replace_with_dosdevices

* Remove all direct indexing
This commit is contained in:
Philip Kristoffersen
2023-01-08 11:58:50 +01:00
committed by GitHub
parent 7b9966b4ff
commit 7dfbc01ed2
12 changed files with 117 additions and 98 deletions
+17 -15
View File
@@ -272,12 +272,9 @@ fn get_namespace_keys<S: AsRef<str>>(steamid: S, db: &mut DB) -> HashSet<String>
fn get_namespaces(db: &mut DB, key_bytes: &[u8]) -> Option<Vec<(i32, String)>> {
match db.get(key_bytes) {
Some(got) => {
let collection_bytes = got.as_slice();
let collectin_str = String::from_utf8_lossy(collection_bytes)[1..].to_string();
let collection = serde_json::from_str(&collectin_str).unwrap_or_default();
Some(collection)
}
Some(got) => String::from_utf8_lossy(got.as_slice())
.get(1..)
.and_then(|s| serde_json::from_str(s).ok()),
_ => None,
}
}
@@ -329,7 +326,7 @@ fn serialize_collection_value<S: AsRef<str>>(name: S, game_ids: &[usize]) -> Str
fn name_to_key<S: AsRef<str>>(name: S) -> String {
let base64 = base64::encode(name.as_ref());
let base64_no_end = if base64.ends_with("==") {
&base64[..base64.len() - 2]
base64.get(..base64.len() - 2).unwrap_or_default()
} else {
&base64
};
@@ -368,15 +365,20 @@ pub fn write_vdf_collection_to_string<S: AsRef<str>>(
let key = "\t\"user-collections\"\t\t";
if let Some(start_index) = input.find_substring(key) {
let start_index_plus_key = start_index + key.len();
if let Some(line_index) = input[start_index_plus_key..].find('\n') {
if let Some(line_index) = input.get(start_index_plus_key..).and_then(|i| i.find('\n')) {
let end_index_in_full = line_index + start_index_plus_key;
let result = format!(
"{}{}{}",
&input[..start_index_plus_key],
encoded_json,
&input[end_index_in_full..]
);
return Some(result);
if let (Some(before), Some(after)) = (
input.get(..start_index_plus_key),
input.get(end_index_in_full..),
) {
let result = format!(
"{}{}{}",
before,
encoded_json,
after
);
return Some(result);
}
}
}
None
+15 -15
View File
@@ -40,8 +40,9 @@ fn get_install_folders(settings: &SteamSettings) -> Vec<PathBuf> {
if let Ok(vdf_file) = std::fs::read_to_string(vdf_path) {
for line in vdf_file.lines() {
if line.contains("\"path\"") {
let path_string = &line[11..line.len() - 1];
result.push(Path::new(&path_string).join("steamapps").to_path_buf());
if let Some(path_string) = line.get(11..line.len() - 1) {
result.push(Path::new(&path_string).join("steamapps").to_path_buf());
}
}
}
}
@@ -63,19 +64,18 @@ fn parse_manifest_file(path: &Path) -> Option<SteamGameInfo> {
fn parse_manifest_string<S: AsRef<str>>(string: S) -> Option<SteamGameInfo> {
let mut lines = string.as_ref().lines();
let app_id_line = lines.find(|l| l.contains("\"appid\""));
let name_line = lines.find(|l| l.contains("\"name\""));
match (app_id_line, name_line) {
(Some(app_id_line), Some(name_line)) => {
let appid = app_id_line[11..app_id_line.len() - 1].to_string().parse();
match appid {
Ok(appid) => Some(SteamGameInfo {
name: name_line[10..name_line.len() - 1].to_string(),
appid,
}),
Err(_) => None,
}
}
let appid: Option<u32> = lines
.find(|l| l.contains("\"appid\""))
.and_then(|line| line.get(11..line.len() - 1))
.and_then(|app_id_str| app_id_str.parse().ok());
let name_line = lines
.find(|l| l.contains("\"name\""))
.and_then(|line| line.get(10..line.len() - 1));
match (appid, name_line) {
(Some(appid), Some(name)) => Some(SteamGameInfo {
name: name.to_string(),
appid,
}),
_ => None,
}
}
+30 -25
View File
@@ -2,7 +2,7 @@ use std::path::Path;
use nom::FindSubstring;
pub fn setup_proton_games<B: AsRef<str>>(games: &[B]) -> eyre::Result<()>{
pub fn setup_proton_games<B: AsRef<str>>(games: &[B]) -> eyre::Result<()> {
if let Ok(home) = std::env::var("HOME") {
let config_file = Path::new(&home).join(".local/share/Steam/config/config.vdf");
if config_file.exists() {
@@ -30,28 +30,32 @@ fn enable_proton_games<S: AsRef<str>, B: AsRef<str>>(vdf_content: S, games: &[B]
};
let proton_replace_string = include_str!("proton_string.txt");
let section_str = &vdf_content[section_info.start..section_info.append_end];
let games_strings_to_add = games
.iter()
.filter(|g| {
let game_section_start = format!("\"{}\"\n", g.as_ref());
!section_str.contains(&game_section_start)
})
.map(|game_id| {
let res = proton_replace_string.to_string();
let res = res.replace("\"X\"", &format!("\"{}\"", game_id.as_ref()));
let res = res.replace('=', &base_indent_string);
res.replace('+', &field_indent_string)
});
let mut new_section = section_str.to_string();
for game_string in games_strings_to_add {
new_section.push_str(&game_string);
}
new_section.push_str(&section_info.end_key);
let section_str = vdf_content.get(section_info.start..section_info.append_end);
if let Some(section_str) = section_str {
let games_strings_to_add = games
.iter()
.filter(|g| {
let game_section_start = format!("\"{}\"\n", g.as_ref());
!section_str.contains(&game_section_start)
})
.map(|game_id| {
let res = proton_replace_string.to_string();
let res = res.replace("\"X\"", &format!("\"{}\"", game_id.as_ref()));
let res = res.replace('=', &base_indent_string);
res.replace('+', &field_indent_string)
});
let mut new_section = section_str.to_string();
for game_string in games_strings_to_add {
new_section.push_str(&game_string);
}
new_section.push_str(&section_info.end_key);
let before_section = &vdf_content[..section_info.start];
let after_section = &vdf_content[section_info.end..];
return format!("{}{}{}", before_section, new_section, after_section);
if let Some(before_section) = vdf_content.get(..section_info.start) {
if let Some(after_section) = vdf_content.get(section_info.end..) {
return format!("{}{}{}", before_section, new_section, after_section);
}
}
}
} else {
//TODO make this an error instead?
println!("Could not find proton section in steam, try to manually set proton on at least one game and then rerun");
@@ -72,14 +76,14 @@ fn find_indexes<S: AsRef<str>>(vdf_content: S) -> Option<SectionInfo> {
let vdf_content = vdf_content.as_ref();
if let Some(compat_index) = vdf_content.find_substring(compat_key) {
let compat_index = compat_index + compat_key.len();
let after_key = vdf_content[compat_index..].to_string();
if let Some(base_indentation) = after_key.find('{') {
let after_key = vdf_content.get(compat_index..);
if let Some(base_indentation) = after_key.and_then(|k| k.find('{')) {
let mut end_key = "\n".to_string();
for _i in 0..base_indentation {
end_key.push('\t');
}
end_key.push('}');
if let Some(end_index) = after_key.as_str().find_substring(&end_key) {
if let Some(end_index) = after_key.and_then(|a| a.find_substring(&end_key)) {
return Some(SectionInfo {
start: compat_index,
end: compat_index + end_index + end_key.len(),
@@ -100,6 +104,7 @@ mod tests {
//Okay to unwrap in tests
#![allow(clippy::unwrap_in_result)]
#![allow(clippy::unwrap_used)]
#![allow(clippy::indexing_slicing)]
use super::*;
#[test]