Re-ping server on connect to detect protocol version

Previously, the server protocol was detected in the server listing GUI,
and saved for each server in a server_versions.json file. connect_to()
would read this file to get the version to use, an ugly hack/workaround
for threading/intercommunication challenges, and a questionable attempt
at avoiding another round-trip exchange.

Now, the server is re-pinged in connect_to() to get the protocol version
to use. This is a blocking ping so it may somewhat slow down server
connecting, but avoids the race conditions with the server list, and
undesirable intertwining the GUI with the server connection logic.

This hack was present since the original multiprotocol support (#18),
but it was blocking other enhancements, about time to remove it.
This commit is contained in:
ice_iix 2019-05-04 16:38:32 -07:00
parent eca9b8ae00
commit 6322cf8b21
2 changed files with 8 additions and 24 deletions

View File

@ -87,20 +87,15 @@ pub struct Game {
impl Game {
pub fn connect_to(&mut self, address: &str) {
// Read saved server protocol version from ping response TODO: get from memory?
use std::fs;
let file = match fs::File::open("server_versions.json") {
Ok(val) => val,
Err(_) => return,
};
let server_versions_info: serde_json::Value = serde_json::from_reader(file).unwrap();
let protocol_version = {
if let Some(v) = server_versions_info.get(address) {
v.as_i64().unwrap() as i32
} else {
warn!("Server protocol version not known for {} (no ping response?), defaulting to {}", address, protocol::SUPPORTED_PROTOCOLS[0]);
let protocol_version = match protocol::Conn::new(&address, protocol::SUPPORTED_PROTOCOLS[0]).and_then(|conn| conn.do_status()) {
Ok(res) => {
info!("Detected server protocol version {}", res.0.version.protocol);
res.0.version.protocol
},
Err(err) => {
warn!("Error pinging server {} to get protocol version: {:?}, defaulting to {}", address, err, protocol::SUPPORTED_PROTOCOLS[0]);
protocol::SUPPORTED_PROTOCOLS[0]
}
},
};
self.protocol_version = protocol_version;

View File

@ -17,7 +17,6 @@ use std::thread;
use std::sync::mpsc;
use std::rc::Rc;
use std::cell::RefCell;
use std::collections::HashMap;
use crate::ui;
use crate::render;
@ -37,7 +36,6 @@ pub struct ServerList {
disconnect_reason: Option<Component>,
needs_reload: Rc<RefCell<bool>>,
server_protocol_versions: HashMap<String, i32>,
}
struct UIElements {
@ -70,7 +68,6 @@ struct Server {
}
struct PingInfo {
address: String,
motd: format::Component,
ping: Duration,
exists: bool,
@ -97,7 +94,6 @@ impl ServerList {
elements: None,
disconnect_reason,
needs_reload: Rc::new(RefCell::new(false)),
server_protocol_versions: HashMap::new(),
}
}
@ -275,7 +271,6 @@ impl ServerList {
None
};
drop(send.send(PingInfo {
address,
motd: desc,
ping: res.1,
exists: true,
@ -291,7 +286,6 @@ impl ServerList {
let mut msg = TextComponent::new(&e);
msg.modifier.color = Some(format::Color::Red);
let _ = send.send(PingInfo {
address,
motd: Component::Text(msg),
ping: Duration::new(99999, 0),
exists: false,
@ -494,11 +488,6 @@ impl super::Screen for ServerList {
format!("Out of date {}/{}", res.online, res.max)
};
players.text = txt;
// TODO: store in memory instead of disk? but where?
self.server_protocol_versions.insert(res.address, res.protocol_version);
let mut out = fs::File::create("server_versions.json").unwrap();
serde_json::to_writer_pretty(&mut out, &self.server_protocol_versions).unwrap();
}
let mut txt = TextComponent::new(&res.protocol_name);
txt.modifier.color = Some(format::Color::Yellow);