Merge branch 'imbris/server-arg-for-airshipper' into 'master'

Add `--server` argument to specify the server when launching voxygen.

See merge request veloren/veloren!3591
This commit is contained in:
Imbris 2022-09-04 19:02:43 +00:00
commit 81b8521710
11 changed files with 158 additions and 45 deletions

29
Cargo.lock generated
View File

@ -687,16 +687,16 @@ dependencies = [
[[package]] [[package]]
name = "clap" name = "clap"
version = "3.1.10" version = "3.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3124f3f75ce09e22d1410043e1e24f2ecc44fad3afe4f08408f1f7663d68da2b" checksum = "23b71c3ce99b7611011217b366d923f1d0a7e07a92bb2dbf1e84508c673ca3bd"
dependencies = [ dependencies = [
"atty", "atty",
"bitflags", "bitflags",
"clap_derive", "clap_derive",
"clap_lex", "clap_lex",
"indexmap", "indexmap",
"lazy_static", "once_cell",
"strsim 0.10.0", "strsim 0.10.0",
"termcolor", "termcolor",
"textwrap 0.15.0", "textwrap 0.15.0",
@ -704,9 +704,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_derive" name = "clap_derive"
version = "3.1.7" version = "3.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3aab4734e083b809aaf5794e14e756d1c798d2c69c7f7de7a09a2f5214993c1" checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65"
dependencies = [ dependencies = [
"heck 0.4.0", "heck 0.4.0",
"proc-macro-error", "proc-macro-error",
@ -717,9 +717,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_lex" name = "clap_lex"
version = "0.1.1" version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "189ddd3b5d32a70b35e7686054371742a937b0d99128e76dde6340210e966669" checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
dependencies = [ dependencies = [
"os_str_bytes", "os_str_bytes",
] ]
@ -4016,9 +4016,9 @@ dependencies = [
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.10.0" version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0"
[[package]] [[package]]
name = "oorandom" name = "oorandom"
@ -6501,7 +6501,7 @@ dependencies = [
"async-channel", "async-channel",
"authc", "authc",
"byteorder", "byteorder",
"clap 3.1.10", "clap 3.2.20",
"hashbrown 0.12.0", "hashbrown 0.12.0",
"image", "image",
"num 0.4.0", "num 0.4.0",
@ -6688,7 +6688,7 @@ dependencies = [
"bincode", "bincode",
"bitflags", "bitflags",
"bytes", "bytes",
"clap 3.1.10", "clap 3.2.20",
"criterion", "criterion",
"crossbeam-channel", "crossbeam-channel",
"futures-core", "futures-core",
@ -6811,7 +6811,7 @@ name = "veloren-server-cli"
version = "0.13.0" version = "0.13.0"
dependencies = [ dependencies = [
"ansi-parser", "ansi-parser",
"clap 3.1.10", "clap 3.2.20",
"crossterm 0.23.2", "crossterm 0.23.2",
"lazy_static", "lazy_static",
"mimalloc", "mimalloc",
@ -6840,6 +6840,7 @@ dependencies = [
"bytemuck", "bytemuck",
"chrono", "chrono",
"chumsky", "chumsky",
"clap 3.2.20",
"cmake", "cmake",
"conrod_core", "conrod_core",
"conrod_winit", "conrod_winit",
@ -6962,7 +6963,7 @@ dependencies = [
name = "veloren-voxygen-i18n" name = "veloren-voxygen-i18n"
version = "0.13.0" version = "0.13.0"
dependencies = [ dependencies = [
"clap 3.1.10", "clap 3.2.20",
"deunicode", "deunicode",
"fluent", "fluent",
"fluent-bundle", "fluent-bundle",
@ -6983,7 +6984,7 @@ dependencies = [
"arr_macro", "arr_macro",
"bincode", "bincode",
"bitvec", "bitvec",
"clap 3.1.10", "clap 3.2.20",
"criterion", "criterion",
"csv", "csv",
"deflate", "deflate",

BIN
assets/voxygen/element/ui/generic/buttons/unlock.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/ui/generic/buttons/unlock_hover.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
assets/voxygen/element/ui/generic/buttons/unlock_press.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -91,6 +91,9 @@ gilrs = {version = "0.8.0", features = ["serde-serialize"]}
# Singleplayer # Singleplayer
server = { package = "veloren-server", path = "../server", optional = true, default-features = false, features = ["worldgen"] } server = { package = "veloren-server", path = "../server", optional = true, default-features = false, features = ["worldgen"] }
# CLI
clap = { version = "3.2.20", features = ["derive"] }
# Utility # Utility
assets_manager = {version = "0.8", features = ["ab_glyph"]} assets_manager = {version = "0.8", features = ["ab_glyph"]}
backtrace = "0.3.40" backtrace = "0.3.40"

19
voxygen/src/cli.rs Normal file
View File

@ -0,0 +1,19 @@
//! NOTE: Some of these arguments are used by airshipper, so those needs to be
//! kept fairly stable (probably with some sort of migration period if we need
//! to modify the name or semantics).
//!
//! The arguments used by airshipper are:
//! * `server`
//!
//! Airshipper should only use arguments listed above! Since we will not try to
//! be careful about their stability otherwise.
use clap::Parser;
#[derive(Parser)]
pub struct Args {
/// Value to auto-fill into the server field.
///
/// This allows passing in server selection performed in airshipper.
#[clap(short, long)]
pub server: Option<String>,
}

View File

@ -2,6 +2,8 @@
#![feature(bool_to_option)] #![feature(bool_to_option)]
#![recursion_limit = "2048"] #![recursion_limit = "2048"]
mod cli;
#[cfg(all( #[cfg(all(
target_os = "windows", target_os = "windows",
not(feature = "tracy-memory"), not(feature = "tracy-memory"),
@ -182,6 +184,10 @@ fn main() {
default_hook(panic_info); default_hook(panic_info);
})); }));
// Process CLI arguments
use clap::Parser;
let args = cli::Args::parse();
// Setup tokio runtime // Setup tokio runtime
use common::consts::MIN_RECOMMENDED_TOKIO_THREADS; use common::consts::MIN_RECOMMENDED_TOKIO_THREADS;
use std::sync::{ use std::sync::{
@ -317,5 +323,5 @@ fn main() {
discord, discord,
}; };
run::run(global_state, event_loop); run::run(global_state, event_loop, args.server);
} }

View File

@ -54,9 +54,9 @@ pub struct MainMenuState {
impl MainMenuState { impl MainMenuState {
/// Create a new `MainMenuState`. /// Create a new `MainMenuState`.
pub fn new(global_state: &mut GlobalState) -> Self { pub fn new(global_state: &mut GlobalState, server: Option<String>) -> Self {
Self { Self {
main_menu_ui: MainMenuUi::new(global_state), main_menu_ui: MainMenuUi::new(global_state, server),
init: InitState::None, init: InitState::None,
scene: Scene::new(global_state.window.renderer_mut()), scene: Scene::new(global_state.window.renderer_mut()),
} }

View File

@ -6,7 +6,7 @@ use crate::ui::{
style, style,
widget::{ widget::{
compound_graphic::{CompoundGraphic, Graphic}, compound_graphic::{CompoundGraphic, Graphic},
BackgroundContainer, Image, Padding, AspectRatioContainer, BackgroundContainer, Image, Padding,
}, },
Element, Element,
}, },
@ -55,6 +55,7 @@ impl Screen {
&mut self, &mut self,
fonts: &Fonts, fonts: &Fonts,
imgs: &Imgs, imgs: &Imgs,
server_field_locked: bool,
login_info: &LoginInfo, login_info: &LoginInfo,
error: Option<&str>, error: Option<&str>,
i18n: &Localization, i18n: &Localization,
@ -64,14 +65,19 @@ impl Screen {
button_style: style::button::Style, button_style: style::button::Style,
version: &str, version: &str,
) -> Element<Message> { ) -> Element<Message> {
let buttons = Column::with_children(vec![ let mut buttons = Vec::new();
neat_button( // If the server field is locked, we don't want to show the server selection
// list!
if !server_field_locked {
buttons.push(neat_button(
&mut self.servers_button, &mut self.servers_button,
i18n.get_msg("common-servers"), i18n.get_msg("common-servers"),
FILL_FRAC_ONE, FILL_FRAC_ONE,
button_style, button_style,
Some(Message::ShowServers), Some(Message::ShowServers),
), ))
}
buttons.extend([
// neat_button( // neat_button(
// &mut self.settings_button, // &mut self.settings_button,
// i18n.get_msg("common-settings"), // i18n.get_msg("common-settings"),
@ -100,15 +106,17 @@ impl Screen {
button_style, button_style,
Some(Message::Quit), Some(Message::Quit),
), ),
]) ]);
.width(Length::Fill)
.max_width(100)
.spacing(5);
let buttons = Container::new(buttons) let buttons = Container::new(
.width(Length::Fill) Column::with_children(buttons)
.height(Length::Fill) .width(Length::Fill)
.align_y(Align::End); .max_width(100)
.spacing(5),
)
.width(Length::Fill)
.height(Length::Fill)
.align_y(Align::End);
let intro_text = i18n.get_msg("main-login_process"); let intro_text = i18n.get_msg("main-login_process");
@ -173,8 +181,14 @@ impl Screen {
button_style, button_style,
) )
} else { } else {
self.banner self.banner.view(
.view(fonts, imgs, login_info, i18n, button_style) fonts,
imgs,
server_field_locked,
login_info,
i18n,
button_style,
)
}; };
let central_column = Container::new(central_content) let central_column = Container::new(central_content)
@ -330,6 +344,8 @@ pub struct LoginBanner {
multiplayer_button: button::State, multiplayer_button: button::State,
#[cfg(feature = "singleplayer")] #[cfg(feature = "singleplayer")]
singleplayer_button: button::State, singleplayer_button: button::State,
unlock_server_field_button: button::State,
} }
impl LoginBanner { impl LoginBanner {
@ -342,6 +358,8 @@ impl LoginBanner {
multiplayer_button: Default::default(), multiplayer_button: Default::default(),
#[cfg(feature = "singleplayer")] #[cfg(feature = "singleplayer")]
singleplayer_button: Default::default(), singleplayer_button: Default::default(),
unlock_server_field_button: Default::default(),
} }
} }
@ -349,12 +367,56 @@ impl LoginBanner {
&mut self, &mut self,
fonts: &Fonts, fonts: &Fonts,
imgs: &Imgs, imgs: &Imgs,
server_field_locked: bool,
login_info: &LoginInfo, login_info: &LoginInfo,
i18n: &Localization, i18n: &Localization,
button_style: style::button::Style, button_style: style::button::Style,
) -> Element<Message> { ) -> Element<Message> {
let input_text_size = fonts.cyri.scale(INPUT_TEXT_SIZE); let input_text_size = fonts.cyri.scale(INPUT_TEXT_SIZE);
let server_field: Element<Message> = if server_field_locked {
let unlock_style = style::button::Style::new(imgs.unlock)
.hover_image(imgs.unlock_hover)
.press_image(imgs.unlock_press);
let unlock_button = Button::new(
&mut self.unlock_server_field_button,
Space::new(Length::Fill, Length::Fill),
)
.style(unlock_style)
.width(Length::Fill)
.height(Length::Fill)
.on_press(Message::UnlockServerField);
let container = AspectRatioContainer::new(unlock_button);
let container = match unlock_style.active().0 {
Some((img, _)) => container.ratio_of_image(img),
None => container,
};
Row::with_children(vec![
Text::new(&login_info.server)
.size(input_text_size)
.width(Length::Fill)
.height(Length::Shrink)
.into(),
container.into(),
])
.align_items(Align::Center)
.height(Length::Fill)
.into()
} else {
TextInput::new(
&mut self.server,
&i18n.get_msg("main-server"),
&login_info.server,
Message::Server,
)
.size(input_text_size)
.on_submit(Message::Multiplayer)
.into()
};
let banner_content = Column::with_children(vec![ let banner_content = Column::with_children(vec![
Column::with_children(vec![ Column::with_children(vec![
BackgroundContainer::new( BackgroundContainer::new(
@ -392,16 +454,9 @@ impl LoginBanner {
Image::new(imgs.input_bg) Image::new(imgs.input_bg)
.width(Length::Units(INPUT_WIDTH)) .width(Length::Units(INPUT_WIDTH))
.fix_aspect_ratio(), .fix_aspect_ratio(),
TextInput::new( server_field,
&mut self.server,
&i18n.get_msg("main-server"),
&login_info.server,
Message::Server,
)
.size(input_text_size)
.on_submit(Message::Multiplayer),
) )
.padding(Padding::new().horizontal(7).top(5)) .padding(Padding::new().horizontal(7).vertical(5))
.into(), .into(),
]) ])
.spacing(5) .spacing(5)

View File

@ -53,6 +53,9 @@ image_ids_ice! {
selection: "voxygen.element.ui.generic.frames.selection", selection: "voxygen.element.ui.generic.frames.selection",
selection_hover: "voxygen.element.ui.generic.frames.selection_hover", selection_hover: "voxygen.element.ui.generic.frames.selection_hover",
selection_press: "voxygen.element.ui.generic.frames.selection_press", selection_press: "voxygen.element.ui.generic.frames.selection_press",
unlock: "voxygen.element.ui.generic.buttons.unlock",
unlock_hover: "voxygen.element.ui.generic.buttons.unlock_hover",
unlock_press: "voxygen.element.ui.generic.buttons.unlock_press",
} }
} }
@ -137,6 +140,10 @@ struct Controls {
alpha: String, alpha: String,
credits: Credits, credits: Credits,
// If a server address was provided via cli argument we hide the server list button and replace
// the server field with a plain label (with a button to exit this mode and freely edit the
// field).
server_field_locked: bool,
selected_server_index: Option<usize>, selected_server_index: Option<usize>,
login_info: LoginInfo, login_info: LoginInfo,
@ -157,6 +164,7 @@ enum Message {
#[cfg(feature = "singleplayer")] #[cfg(feature = "singleplayer")]
Singleplayer, Singleplayer,
Multiplayer, Multiplayer,
UnlockServerField,
LanguageChanged(usize), LanguageChanged(usize),
OpenLanguageMenu, OpenLanguageMenu,
Username(String), Username(String),
@ -180,6 +188,7 @@ impl Controls {
bg_img: widget::image::Handle, bg_img: widget::image::Handle,
i18n: LocalizationHandle, i18n: LocalizationHandle,
settings: &Settings, settings: &Settings,
server: Option<String>,
) -> Self { ) -> Self {
let version = common::util::DISPLAY_VERSION_LONG.clone(); let version = common::util::DISPLAY_VERSION_LONG.clone();
let alpha = format!("Veloren {}", common::util::DISPLAY_VERSION.as_str()); let alpha = format!("Veloren {}", common::util::DISPLAY_VERSION.as_str());
@ -198,10 +207,11 @@ impl Controls {
}; };
//}; //};
let server_field_locked = server.is_some();
let login_info = LoginInfo { let login_info = LoginInfo {
username: settings.networking.username.clone(), username: settings.networking.username.clone(),
password: String::new(), password: String::new(),
server: settings.networking.default_server.clone(), server: server.unwrap_or_else(|| settings.networking.default_server.clone()),
}; };
let selected_server_index = settings let selected_server_index = settings
.networking .networking
@ -223,6 +233,7 @@ impl Controls {
alpha, alpha,
credits, credits,
server_field_locked,
selected_server_index, selected_server_index,
login_info, login_info,
@ -291,6 +302,7 @@ impl Controls {
Screen::Login { screen, error } => screen.view( Screen::Login { screen, error } => screen.view(
&self.fonts, &self.fonts,
&self.imgs, &self.imgs,
self.server_field_locked,
&self.login_info, &self.login_info,
error.as_deref(), error.as_deref(),
&self.i18n.read(), &self.i18n.read(),
@ -386,6 +398,7 @@ impl Controls {
server_address: self.login_info.server.clone(), server_address: self.login_info.server.clone(),
}); });
}, },
Message::UnlockServerField => self.server_field_locked = false,
Message::Username(new_value) => self.login_info.username = new_value, Message::Username(new_value) => self.login_info.username = new_value,
Message::LanguageChanged(new_value) => { Message::LanguageChanged(new_value) => {
events.push(Event::ChangeLanguage(language_metadatas.remove(new_value))); events.push(Event::ChangeLanguage(language_metadatas.remove(new_value)));
@ -495,7 +508,12 @@ impl Controls {
screen.banner.password.move_cursor_to_end(); screen.banner.password.move_cursor_to_end();
} else if screen.banner.password.is_focused() { } else if screen.banner.password.is_focused() {
screen.banner.password = text_input::State::new(); screen.banner.password = text_input::State::new();
screen.banner.server = text_input::State::focused(); // Skip focusing server field if it isn't editable!
if self.server_field_locked {
screen.banner.username = text_input::State::focused();
} else {
screen.banner.server = text_input::State::focused();
}
screen.banner.server.move_cursor_to_end(); screen.banner.server.move_cursor_to_end();
} else if screen.banner.server.is_focused() { } else if screen.banner.server.is_focused() {
screen.banner.server = text_input::State::new(); screen.banner.server = text_input::State::new();
@ -517,7 +535,7 @@ pub struct MainMenuUi {
} }
impl MainMenuUi { impl MainMenuUi {
pub fn new(global_state: &mut GlobalState) -> Self { pub fn new(global_state: &mut GlobalState, server: Option<String>) -> Self {
// Load language // Load language
let i18n = &global_state.i18n.read(); let i18n = &global_state.i18n.read();
// TODO: don't add default font twice // TODO: don't add default font twice
@ -541,6 +559,7 @@ impl MainMenuUi {
ui.add_graphic(Graphic::Image(bg_img, None)), ui.add_graphic(Graphic::Image(bg_img, None)),
global_state.i18n, global_state.i18n,
&global_state.settings, &global_state.settings,
server,
); );
Self { ui, controls } Self { ui, controls }

View File

@ -9,9 +9,10 @@ use common_base::{prof_span, span};
use std::{mem, time::Duration}; use std::{mem, time::Duration};
use tracing::debug; use tracing::debug;
pub fn run(mut global_state: GlobalState, event_loop: EventLoop) { pub fn run(mut global_state: GlobalState, event_loop: EventLoop, server: Option<String>) {
// Set up the initial play state. // Set up the initial play state.
let mut states: Vec<Box<dyn PlayState>> = vec![Box::new(MainMenuState::new(&mut global_state))]; let mut states: Vec<Box<dyn PlayState>> =
vec![Box::new(MainMenuState::new(&mut global_state, server))];
states.last_mut().map(|current_state| { states.last_mut().map(|current_state| {
current_state.enter(&mut global_state, Direction::Forwards); current_state.enter(&mut global_state, Direction::Forwards);
let current_state = current_state.name(); let current_state = current_state.name();