Add custom game args to settings (#905)
This commit is contained in:
parent
e7ddd85960
commit
d073e10a3b
13 changed files with 171 additions and 56 deletions
5
.changeset/custom_game_arguments.md
Normal file
5
.changeset/custom_game_arguments.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
default: minor
|
||||
---
|
||||
|
||||
# Game settings have a Game Arguments field for passing extra arguments to Minecraft, globally or per cluster
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n\t\tSELECT name, java_path, resolution, force_fullscreen, mem_max, launch_args, launch_env,\n\t\t hook_pre, hook_wrapper, hook_post, os_extra, browser_update_mode\n\t\tFROM setting_profiles\n\t\tORDER BY name ASC\n\t\t",
|
||||
"query": "\n\t\tSELECT name, java_path, resolution, force_fullscreen, mem_max, launch_args, game_args, launch_env,\n\t\t hook_pre, hook_wrapper, hook_post, os_extra, browser_update_mode\n\t\tFROM setting_profiles\n\t\tORDER BY name ASC\n\t\t",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
|
|
@ -70,9 +70,20 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"name": "launch_env",
|
||||
"name": "game_args",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text",
|
||||
"origin": {
|
||||
"Table": {
|
||||
"table": "setting_profiles",
|
||||
"name": "game_args"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "launch_env",
|
||||
"ordinal": 7,
|
||||
"type_info": "Text",
|
||||
"origin": {
|
||||
"Table": {
|
||||
"table": "setting_profiles",
|
||||
|
|
@ -82,7 +93,7 @@
|
|||
},
|
||||
{
|
||||
"name": "hook_pre",
|
||||
"ordinal": 7,
|
||||
"ordinal": 8,
|
||||
"type_info": "Text",
|
||||
"origin": {
|
||||
"Table": {
|
||||
|
|
@ -93,7 +104,7 @@
|
|||
},
|
||||
{
|
||||
"name": "hook_wrapper",
|
||||
"ordinal": 8,
|
||||
"ordinal": 9,
|
||||
"type_info": "Text",
|
||||
"origin": {
|
||||
"Table": {
|
||||
|
|
@ -104,7 +115,7 @@
|
|||
},
|
||||
{
|
||||
"name": "hook_post",
|
||||
"ordinal": 9,
|
||||
"ordinal": 10,
|
||||
"type_info": "Text",
|
||||
"origin": {
|
||||
"Table": {
|
||||
|
|
@ -115,7 +126,7 @@
|
|||
},
|
||||
{
|
||||
"name": "os_extra",
|
||||
"ordinal": 10,
|
||||
"ordinal": 11,
|
||||
"type_info": "Text",
|
||||
"origin": {
|
||||
"Table": {
|
||||
|
|
@ -126,7 +137,7 @@
|
|||
},
|
||||
{
|
||||
"name": "browser_update_mode",
|
||||
"ordinal": 11,
|
||||
"ordinal": 12,
|
||||
"type_info": "Text",
|
||||
"origin": {
|
||||
"Table": {
|
||||
|
|
@ -151,8 +162,9 @@
|
|||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "f68b9ade92feb989828ca81582c5960bf2968c4b75705e1a0e6800e97c3f4628"
|
||||
"hash": "01b2ef24541af92505a3c2bc14037a61470a393dffa06da8bebfba98138709d0"
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n\t\tINSERT INTO setting_profiles (\n\t\t\tname, java_path, resolution, force_fullscreen, mem_max, launch_args, launch_env,\n\t\t\thook_pre, hook_wrapper, hook_post, os_extra, browser_update_mode\n\t\t)\n\t\tVALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n\t\tON CONFLICT(name) DO UPDATE SET\n\t\t\tjava_path = excluded.java_path,\n\t\t\tresolution = excluded.resolution,\n\t\t\tforce_fullscreen = excluded.force_fullscreen,\n\t\t\tmem_max = excluded.mem_max,\n\t\t\tlaunch_args = excluded.launch_args,\n\t\t\tlaunch_env = excluded.launch_env,\n\t\t\thook_pre = excluded.hook_pre,\n\t\t\thook_wrapper = excluded.hook_wrapper,\n\t\t\thook_post = excluded.hook_post,\n\t\t\tos_extra = excluded.os_extra,\n\t\t\tbrowser_update_mode = excluded.browser_update_mode\n\t\tRETURNING name, java_path, resolution, force_fullscreen, mem_max, launch_args, launch_env,\n hook_pre, hook_wrapper, hook_post, os_extra, browser_update_mode\n\t\t",
|
||||
"query": "\n\t\tINSERT INTO setting_profiles (\n\t\t\tname, java_path, resolution, force_fullscreen, mem_max, launch_args, game_args, launch_env,\n\t\t\thook_pre, hook_wrapper, hook_post, os_extra, browser_update_mode\n\t\t)\n\t\tVALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n\t\tON CONFLICT(name) DO UPDATE SET\n\t\t\tjava_path = excluded.java_path,\n\t\t\tresolution = excluded.resolution,\n\t\t\tforce_fullscreen = excluded.force_fullscreen,\n\t\t\tmem_max = excluded.mem_max,\n\t\t\tlaunch_args = excluded.launch_args,\n\t\t\tgame_args = excluded.game_args,\n\t\t\tlaunch_env = excluded.launch_env,\n\t\t\thook_pre = excluded.hook_pre,\n\t\t\thook_wrapper = excluded.hook_wrapper,\n\t\t\thook_post = excluded.hook_post,\n\t\t\tos_extra = excluded.os_extra,\n\t\t\tbrowser_update_mode = excluded.browser_update_mode\n\t\tRETURNING name, java_path, resolution, force_fullscreen, mem_max, launch_args, game_args, launch_env,\n hook_pre, hook_wrapper, hook_post, os_extra, browser_update_mode\n\t\t",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
|
|
@ -70,9 +70,20 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"name": "launch_env",
|
||||
"name": "game_args",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text",
|
||||
"origin": {
|
||||
"Table": {
|
||||
"table": "setting_profiles",
|
||||
"name": "game_args"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "launch_env",
|
||||
"ordinal": 7,
|
||||
"type_info": "Text",
|
||||
"origin": {
|
||||
"Table": {
|
||||
"table": "setting_profiles",
|
||||
|
|
@ -82,7 +93,7 @@
|
|||
},
|
||||
{
|
||||
"name": "hook_pre",
|
||||
"ordinal": 7,
|
||||
"ordinal": 8,
|
||||
"type_info": "Text",
|
||||
"origin": {
|
||||
"Table": {
|
||||
|
|
@ -93,7 +104,7 @@
|
|||
},
|
||||
{
|
||||
"name": "hook_wrapper",
|
||||
"ordinal": 8,
|
||||
"ordinal": 9,
|
||||
"type_info": "Text",
|
||||
"origin": {
|
||||
"Table": {
|
||||
|
|
@ -104,7 +115,7 @@
|
|||
},
|
||||
{
|
||||
"name": "hook_post",
|
||||
"ordinal": 9,
|
||||
"ordinal": 10,
|
||||
"type_info": "Text",
|
||||
"origin": {
|
||||
"Table": {
|
||||
|
|
@ -115,7 +126,7 @@
|
|||
},
|
||||
{
|
||||
"name": "os_extra",
|
||||
"ordinal": 10,
|
||||
"ordinal": 11,
|
||||
"type_info": "Text",
|
||||
"origin": {
|
||||
"Table": {
|
||||
|
|
@ -126,7 +137,7 @@
|
|||
},
|
||||
{
|
||||
"name": "browser_update_mode",
|
||||
"ordinal": 11,
|
||||
"ordinal": 12,
|
||||
"type_info": "Text",
|
||||
"origin": {
|
||||
"Table": {
|
||||
|
|
@ -137,7 +148,7 @@
|
|||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 12
|
||||
"Right": 13
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
|
|
@ -151,8 +162,9 @@
|
|||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "c939cef4b51d506d5b73b4c2e0330ba45423c0116c911b9da16576290ed9f3c2"
|
||||
"hash": "598a34a0eb0f4d497cfd9bd77696310d1088e8baec677e07843a21ce6978652e"
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n\t\tSELECT name, java_path, resolution, force_fullscreen, mem_max, launch_args, launch_env,\n\t\t hook_pre, hook_wrapper, hook_post, os_extra, browser_update_mode\n\t\tFROM setting_profiles\n\t\tWHERE name = ?\n\t\t",
|
||||
"query": "\n\t\tSELECT name, java_path, resolution, force_fullscreen, mem_max, launch_args, game_args, launch_env,\n\t\t hook_pre, hook_wrapper, hook_post, os_extra, browser_update_mode\n\t\tFROM setting_profiles\n\t\tWHERE name = ?\n\t\t",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
|
|
@ -70,9 +70,20 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"name": "launch_env",
|
||||
"name": "game_args",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text",
|
||||
"origin": {
|
||||
"Table": {
|
||||
"table": "setting_profiles",
|
||||
"name": "game_args"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "launch_env",
|
||||
"ordinal": 7,
|
||||
"type_info": "Text",
|
||||
"origin": {
|
||||
"Table": {
|
||||
"table": "setting_profiles",
|
||||
|
|
@ -82,7 +93,7 @@
|
|||
},
|
||||
{
|
||||
"name": "hook_pre",
|
||||
"ordinal": 7,
|
||||
"ordinal": 8,
|
||||
"type_info": "Text",
|
||||
"origin": {
|
||||
"Table": {
|
||||
|
|
@ -93,7 +104,7 @@
|
|||
},
|
||||
{
|
||||
"name": "hook_wrapper",
|
||||
"ordinal": 8,
|
||||
"ordinal": 9,
|
||||
"type_info": "Text",
|
||||
"origin": {
|
||||
"Table": {
|
||||
|
|
@ -104,7 +115,7 @@
|
|||
},
|
||||
{
|
||||
"name": "hook_post",
|
||||
"ordinal": 9,
|
||||
"ordinal": 10,
|
||||
"type_info": "Text",
|
||||
"origin": {
|
||||
"Table": {
|
||||
|
|
@ -115,7 +126,7 @@
|
|||
},
|
||||
{
|
||||
"name": "os_extra",
|
||||
"ordinal": 10,
|
||||
"ordinal": 11,
|
||||
"type_info": "Text",
|
||||
"origin": {
|
||||
"Table": {
|
||||
|
|
@ -126,7 +137,7 @@
|
|||
},
|
||||
{
|
||||
"name": "browser_update_mode",
|
||||
"ordinal": 11,
|
||||
"ordinal": 12,
|
||||
"type_info": "Text",
|
||||
"origin": {
|
||||
"Table": {
|
||||
|
|
@ -151,8 +162,9 @@
|
|||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "98500a40f7e1ca7df79dd0ca90eaaa4f0b079ccbd757e5db1a8229ea58d2e700"
|
||||
"hash": "86e3ba70da419464c0be3b3971f613c5a112558472cf2dcdeffa5907e3785318"
|
||||
}
|
||||
|
|
@ -175,6 +175,7 @@ impl Component for ClusterSettings {
|
|||
.into_element(),
|
||||
)
|
||||
.child(text_row(cluster_id, TextField::JvmArgs, &profile, &global))
|
||||
.child(text_row(cluster_id, TextField::GameArgs, &profile, &global))
|
||||
.child(section_header("PROCESS"))
|
||||
.child(text_row(cluster_id, TextField::Pre, &profile, &global))
|
||||
.child(text_row(cluster_id, TextField::Wrapper, &profile, &global))
|
||||
|
|
@ -629,6 +630,7 @@ impl Component for ResolutionRow {
|
|||
#[derive(Clone, Copy, PartialEq)]
|
||||
enum TextField {
|
||||
JvmArgs,
|
||||
GameArgs,
|
||||
Pre,
|
||||
Wrapper,
|
||||
Post,
|
||||
|
|
@ -643,6 +645,12 @@ impl TextField {
|
|||
"Extra arguments passed to Java. Separate them with spaces; quote values containing spaces.",
|
||||
"-XX:+UseG1GC",
|
||||
),
|
||||
Self::GameArgs => (
|
||||
IconType::Play,
|
||||
"Game Arguments",
|
||||
"Extra arguments passed to Minecraft. Separate them with spaces; quote values containing spaces.",
|
||||
"--tracy --tracyNoImages",
|
||||
),
|
||||
Self::Pre => (
|
||||
IconType::FilePlus02,
|
||||
"Pre-Launch Command",
|
||||
|
|
@ -667,6 +675,7 @@ impl TextField {
|
|||
fn value(self, profile: &GameSettingsProfile) -> Option<String> {
|
||||
match self {
|
||||
Self::JvmArgs => profile.launch_args.clone(),
|
||||
Self::GameArgs => profile.game_args.clone(),
|
||||
Self::Pre => profile.hook_pre.clone(),
|
||||
Self::Wrapper => profile.hook_wrapper.clone(),
|
||||
Self::Post => profile.hook_post.clone(),
|
||||
|
|
@ -677,6 +686,7 @@ impl TextField {
|
|||
let mut u = ProfileUpdate::default();
|
||||
match self {
|
||||
Self::JvmArgs => u.launch_args = value,
|
||||
Self::GameArgs => u.game_args = value,
|
||||
Self::Pre => u.hook_pre = value,
|
||||
Self::Wrapper => u.hook_wrapper = value,
|
||||
Self::Post => u.hook_post = value,
|
||||
|
|
|
|||
|
|
@ -48,6 +48,10 @@ impl Component for SettingsMinecraft {
|
|||
let v = profile.launch_args.clone().unwrap_or_default();
|
||||
move || v
|
||||
});
|
||||
let game_args = use_state({
|
||||
let v = profile.game_args.clone().unwrap_or_default();
|
||||
move || v
|
||||
});
|
||||
let pre_launch_command = use_state({
|
||||
let v = profile.hook_pre.clone().unwrap_or_default();
|
||||
move || v
|
||||
|
|
@ -79,6 +83,7 @@ impl Component for SettingsMinecraft {
|
|||
&height.read(),
|
||||
&memory.read(),
|
||||
&jvm_args.read(),
|
||||
&game_args.read(),
|
||||
&pre_launch_command.read(),
|
||||
&wrapper_command.read(),
|
||||
&post_exit_command.read(),
|
||||
|
|
@ -154,6 +159,19 @@ impl Component for SettingsMinecraft {
|
|||
defaults.launch_args.clone().unwrap_or_default(),
|
||||
),
|
||||
))
|
||||
.child(settings_row(
|
||||
IconType::Play,
|
||||
"Game Arguments",
|
||||
"Extra arguments passed to Minecraft. Separate them with spaces; quote values containing spaces.",
|
||||
resettable(
|
||||
TextInput::new(game_args)
|
||||
.placeholder("--tracy --tracyNoImages")
|
||||
.expandable(true)
|
||||
.width(Size::px(220.)),
|
||||
game_args,
|
||||
defaults.game_args.clone().unwrap_or_default(),
|
||||
),
|
||||
))
|
||||
.child(section_header("CONTENT"))
|
||||
.child(settings_row(
|
||||
IconType::RefreshCw01,
|
||||
|
|
@ -263,6 +281,7 @@ fn build_update(
|
|||
height: &str,
|
||||
memory: &str,
|
||||
jvm_args: &str,
|
||||
game_args: &str,
|
||||
pre: &str,
|
||||
wrapper: &str,
|
||||
post: &str,
|
||||
|
|
@ -286,6 +305,7 @@ fn build_update(
|
|||
resolution,
|
||||
mem_max,
|
||||
launch_args: command_patch(jvm_args),
|
||||
game_args: command_patch(game_args),
|
||||
hook_pre: command_patch(pre),
|
||||
hook_wrapper: command_patch(wrapper),
|
||||
hook_post: command_patch(post),
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ pub struct GameSettingsProfile {
|
|||
pub force_fullscreen: Option<bool>,
|
||||
pub mem_max: Option<u32>,
|
||||
pub launch_args: Option<String>,
|
||||
pub game_args: Option<String>,
|
||||
pub launch_env: Option<String>,
|
||||
pub hook_pre: Option<String>,
|
||||
pub hook_wrapper: Option<String>,
|
||||
|
|
@ -57,6 +58,7 @@ impl GameSettingsProfile {
|
|||
force_fullscreen: Some(false),
|
||||
mem_max: Some(oneclient_common::default_mem_max()),
|
||||
launch_args: None,
|
||||
game_args: None,
|
||||
launch_env: None,
|
||||
hook_pre: None,
|
||||
hook_wrapper: None,
|
||||
|
|
@ -90,6 +92,9 @@ impl GameSettingsProfile {
|
|||
if self.launch_args.is_none() {
|
||||
self.launch_args = global.launch_args.clone();
|
||||
}
|
||||
if self.game_args.is_none() {
|
||||
self.game_args = global.game_args.clone();
|
||||
}
|
||||
if self.launch_env.is_none() {
|
||||
self.launch_env = global.launch_env.clone();
|
||||
}
|
||||
|
|
@ -121,6 +126,7 @@ impl GameSettingsProfile {
|
|||
force_fullscreen: row.force_fullscreen.map(|v| v != 0),
|
||||
mem_max: row.mem_max.map(|v| v as u32),
|
||||
launch_args: row.launch_args,
|
||||
game_args: row.game_args,
|
||||
launch_env: row.launch_env,
|
||||
hook_pre: row.hook_pre,
|
||||
hook_wrapper: row.hook_wrapper,
|
||||
|
|
@ -149,6 +155,7 @@ impl GameSettingsProfile {
|
|||
force_fullscreen: self.force_fullscreen.map(i64::from),
|
||||
mem_max: self.mem_max.map(i64::from),
|
||||
launch_args: self.launch_args.clone(),
|
||||
game_args: self.game_args.clone(),
|
||||
launch_env: self.launch_env.clone(),
|
||||
hook_pre: self.hook_pre.clone(),
|
||||
hook_wrapper: self.hook_wrapper.clone(),
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ pub struct ProfileUpdate {
|
|||
pub force_fullscreen: Patch<bool>,
|
||||
pub mem_max: Patch<u32>,
|
||||
pub launch_args: Patch<String>,
|
||||
pub game_args: Patch<String>,
|
||||
pub launch_env: Patch<String>,
|
||||
pub hook_pre: Patch<String>,
|
||||
pub hook_wrapper: Patch<String>,
|
||||
|
|
@ -132,6 +133,8 @@ impl ProfileUpdate {
|
|||
self.mem_max.apply_to_option(&mut profile.mem_max);
|
||||
self.launch_args
|
||||
.apply_to_command_option(&mut profile.launch_args);
|
||||
self.game_args
|
||||
.apply_to_command_option(&mut profile.game_args);
|
||||
self.launch_env
|
||||
.apply_to_command_option(&mut profile.launch_env);
|
||||
self.hook_pre.apply_to_command_option(&mut profile.hook_pre);
|
||||
|
|
|
|||
|
|
@ -360,7 +360,11 @@ async fn start(
|
|||
profile.resolution.unwrap_or_default(),
|
||||
&java.os_arch,
|
||||
)?;
|
||||
arguments::append_profile_game_arguments(&mut mc_args, profile.force_fullscreen, None);
|
||||
arguments::append_profile_game_arguments(
|
||||
&mut mc_args,
|
||||
profile.force_fullscreen,
|
||||
profile.game_args.as_deref(),
|
||||
);
|
||||
|
||||
if let Some(reason) = run_hook(profile.hook_pre.as_deref(), &cwd).await {
|
||||
events
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
-- Extra arguments appended to the Minecraft command line, after the version's
|
||||
-- own game arguments. NULL inherits the global profile like `launch_args`.
|
||||
ALTER TABLE `setting_profiles` ADD COLUMN `game_args` TEXT;
|
||||
|
|
@ -14,7 +14,7 @@ pub async fn list_all(pool: &SqlitePool) -> DbResult<Vec<SettingProfileRow>> {
|
|||
let rows = sqlx::query_as!(
|
||||
SettingProfileRow,
|
||||
r#"
|
||||
SELECT name, java_path, resolution, force_fullscreen, mem_max, launch_args, launch_env,
|
||||
SELECT name, java_path, resolution, force_fullscreen, mem_max, launch_args, game_args, launch_env,
|
||||
hook_pre, hook_wrapper, hook_post, os_extra, browser_update_mode
|
||||
FROM setting_profiles
|
||||
ORDER BY name ASC
|
||||
|
|
@ -30,7 +30,7 @@ pub async fn get_by_name(pool: &SqlitePool, name: &str) -> DbResult<Option<Setti
|
|||
let row = sqlx::query_as!(
|
||||
SettingProfileRow,
|
||||
r#"
|
||||
SELECT name, java_path, resolution, force_fullscreen, mem_max, launch_args, launch_env,
|
||||
SELECT name, java_path, resolution, force_fullscreen, mem_max, launch_args, game_args, launch_env,
|
||||
hook_pre, hook_wrapper, hook_post, os_extra, browser_update_mode
|
||||
FROM setting_profiles
|
||||
WHERE name = ?
|
||||
|
|
@ -58,23 +58,24 @@ pub async fn upsert(
|
|||
SettingProfileRow,
|
||||
r#"
|
||||
INSERT INTO setting_profiles (
|
||||
name, java_path, resolution, force_fullscreen, mem_max, launch_args, launch_env,
|
||||
name, java_path, resolution, force_fullscreen, mem_max, launch_args, game_args, launch_env,
|
||||
hook_pre, hook_wrapper, hook_post, os_extra, browser_update_mode
|
||||
)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT(name) DO UPDATE SET
|
||||
java_path = excluded.java_path,
|
||||
resolution = excluded.resolution,
|
||||
force_fullscreen = excluded.force_fullscreen,
|
||||
mem_max = excluded.mem_max,
|
||||
launch_args = excluded.launch_args,
|
||||
game_args = excluded.game_args,
|
||||
launch_env = excluded.launch_env,
|
||||
hook_pre = excluded.hook_pre,
|
||||
hook_wrapper = excluded.hook_wrapper,
|
||||
hook_post = excluded.hook_post,
|
||||
os_extra = excluded.os_extra,
|
||||
browser_update_mode = excluded.browser_update_mode
|
||||
RETURNING name, java_path, resolution, force_fullscreen, mem_max, launch_args, launch_env,
|
||||
RETURNING name, java_path, resolution, force_fullscreen, mem_max, launch_args, game_args, launch_env,
|
||||
hook_pre, hook_wrapper, hook_post, os_extra, browser_update_mode
|
||||
"#,
|
||||
&row.name,
|
||||
|
|
@ -83,6 +84,7 @@ pub async fn upsert(
|
|||
row.force_fullscreen,
|
||||
row.mem_max,
|
||||
&row.launch_args,
|
||||
&row.game_args,
|
||||
&row.launch_env,
|
||||
&row.hook_pre,
|
||||
&row.hook_wrapper,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ pub struct SettingProfileRow {
|
|||
pub force_fullscreen: Option<i64>,
|
||||
pub mem_max: Option<i64>,
|
||||
pub launch_args: Option<String>,
|
||||
pub game_args: Option<String>,
|
||||
pub launch_env: Option<String>,
|
||||
pub hook_pre: Option<String>,
|
||||
pub hook_wrapper: Option<String>,
|
||||
|
|
|
|||
|
|
@ -232,31 +232,27 @@ pub fn minecraft_arguments(
|
|||
}
|
||||
|
||||
fn drop_repeated_arguments(args: &mut Vec<String>) {
|
||||
let mut seen: HashSet<(String, Option<String>)> = HashSet::new();
|
||||
let mut kept: Vec<String> = Vec::with_capacity(args.len());
|
||||
let mut index = 0;
|
||||
let mut seen = HashSet::new();
|
||||
retain_arguments(args, |option, value| {
|
||||
seen.insert((option.to_owned(), value.map(str::to_owned)))
|
||||
});
|
||||
}
|
||||
|
||||
while index < args.len() {
|
||||
let token = &args[index];
|
||||
fn retain_arguments(args: &mut Vec<String>, mut keep: impl FnMut(&str, Option<&str>) -> bool) {
|
||||
let mut kept = Vec::with_capacity(args.len());
|
||||
let mut tokens = std::mem::take(args).into_iter().peekable();
|
||||
|
||||
while let Some(token) = tokens.next() {
|
||||
if !token.starts_with("--") {
|
||||
kept.push(token.clone());
|
||||
index += 1;
|
||||
kept.push(token);
|
||||
continue;
|
||||
}
|
||||
|
||||
let value = args
|
||||
.get(index + 1)
|
||||
.filter(|next| !next.starts_with("--"))
|
||||
.cloned();
|
||||
|
||||
if seen.insert((token.clone(), value.clone())) {
|
||||
kept.push(token.clone());
|
||||
if let Some(value) = &value {
|
||||
kept.push(value.clone());
|
||||
}
|
||||
let value = tokens.next_if(|next| !next.starts_with("--"));
|
||||
if keep(&token, value.as_deref()) {
|
||||
kept.push(token);
|
||||
kept.extend(value);
|
||||
}
|
||||
|
||||
index += if value.is_some() { 2 } else { 1 };
|
||||
}
|
||||
|
||||
*args = kept;
|
||||
|
|
@ -265,15 +261,17 @@ fn drop_repeated_arguments(args: &mut Vec<String>) {
|
|||
pub fn append_profile_game_arguments(
|
||||
args: &mut Vec<String>,
|
||||
force_fullscreen: Option<bool>,
|
||||
launch_args: Option<&str>,
|
||||
game_args: Option<&str>,
|
||||
) {
|
||||
if force_fullscreen.unwrap_or(false) {
|
||||
args.push("--fullscreen".to_string());
|
||||
}
|
||||
|
||||
if let Some(extra) = launch_args.map(str::trim).filter(|s| !s.is_empty()) {
|
||||
args.push(extra.to_string());
|
||||
}
|
||||
let extra = game_args.map(split_custom_args).unwrap_or_default();
|
||||
retain_arguments(args, |option, _| {
|
||||
option == "--tweakClass" || !extra.iter().any(|arg| arg == option)
|
||||
});
|
||||
args.extend(extra);
|
||||
}
|
||||
|
||||
pub fn processor_arguments<T: AsRef<str>, S: std::hash::BuildHasher>(
|
||||
|
|
@ -599,8 +597,8 @@ where
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{
|
||||
HashMap, Library, Path, SidedDataEntry, ZGC_MIN_HEAP_MB, classpaths,
|
||||
drop_repeated_arguments, get_library, is_collector_flag, java_arguments,
|
||||
HashMap, Library, Path, SidedDataEntry, ZGC_MIN_HEAP_MB, append_profile_game_arguments,
|
||||
classpaths, drop_repeated_arguments, get_library, is_collector_flag, java_arguments,
|
||||
minecraft_arguments, performance_flags, processor_arguments, split_custom_args,
|
||||
};
|
||||
use oneclient_common::Resolution;
|
||||
|
|
@ -627,6 +625,32 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn game_arguments_are_split_after_fullscreen() {
|
||||
let mut args = ["--username", "Steve", "--width", "854", "--height", "480"]
|
||||
.map(String::from)
|
||||
.to_vec();
|
||||
append_profile_game_arguments(
|
||||
&mut args,
|
||||
Some(true),
|
||||
Some("--tracy --tracyNoImages --width 1920 --fullscreen"),
|
||||
);
|
||||
assert_eq!(
|
||||
args,
|
||||
vec![
|
||||
"--username",
|
||||
"Steve",
|
||||
"--height",
|
||||
"480",
|
||||
"--tracy",
|
||||
"--tracyNoImages",
|
||||
"--width",
|
||||
"1920",
|
||||
"--fullscreen"
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_empty_quoted_value_survives() {
|
||||
assert_eq!(split_custom_args(r#"-Dempty="""#), vec!["-Dempty="]);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue