Get the protocol version to send from the ping packet (#20)
The first step of https://github.com/iceiix/steven/issues/18 Enhance protocol support, instead of hardcoding a fixed version, the client now matches whatever the server sent. * Get the protocol version to send from the ping packet * Save/load server protocol versions to disk, server_versions.json * Fallback to default SUPPORTED_PROTOCOL if no ping response
This commit is contained in:
parent
c099a68168
commit
d80eca3940
24
src/main.rs
24
src/main.rs
|
@ -15,7 +15,7 @@
|
||||||
#![recursion_limit="300"]
|
#![recursion_limit="300"]
|
||||||
|
|
||||||
use std::time::{Instant, Duration};
|
use std::time::{Instant, Duration};
|
||||||
use log::info;
|
use log::{info, warn};
|
||||||
extern crate steven_shared as shared;
|
extern crate steven_shared as shared;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -73,6 +73,8 @@ pub struct Game {
|
||||||
chunk_builder: chunk_builder::ChunkBuilder,
|
chunk_builder: chunk_builder::ChunkBuilder,
|
||||||
|
|
||||||
connect_reply: Option<mpsc::Receiver<Result<server::Server, protocol::Error>>>,
|
connect_reply: Option<mpsc::Receiver<Result<server::Server, protocol::Error>>>,
|
||||||
|
protocol_version: i32,
|
||||||
|
|
||||||
dpi_factor: f64,
|
dpi_factor: f64,
|
||||||
last_mouse_x: f64,
|
last_mouse_x: f64,
|
||||||
last_mouse_y: f64,
|
last_mouse_y: f64,
|
||||||
|
@ -83,6 +85,23 @@ pub struct Game {
|
||||||
|
|
||||||
impl Game {
|
impl Game {
|
||||||
pub fn connect_to(&mut self, address: &str) {
|
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_PROTOCOL);
|
||||||
|
protocol::SUPPORTED_PROTOCOL
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
self.protocol_version = protocol_version;
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
self.connect_reply = Some(rx);
|
self.connect_reply = Some(rx);
|
||||||
let address = address.to_owned();
|
let address = address.to_owned();
|
||||||
|
@ -93,7 +112,7 @@ impl Game {
|
||||||
access_token: self.vars.get(auth::AUTH_TOKEN).clone(),
|
access_token: self.vars.get(auth::AUTH_TOKEN).clone(),
|
||||||
};
|
};
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
tx.send(server::Server::connect(resources, profile, &address)).unwrap();
|
tx.send(server::Server::connect(resources, profile, &address, protocol_version)).unwrap();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,6 +230,7 @@ fn main() {
|
||||||
should_close: false,
|
should_close: false,
|
||||||
chunk_builder: chunk_builder::ChunkBuilder::new(resource_manager, textures),
|
chunk_builder: chunk_builder::ChunkBuilder::new(resource_manager, textures),
|
||||||
connect_reply: None,
|
connect_reply: None,
|
||||||
|
protocol_version: protocol::SUPPORTED_PROTOCOL,
|
||||||
dpi_factor,
|
dpi_factor,
|
||||||
last_mouse_x: 0.0,
|
last_mouse_x: 0.0,
|
||||||
last_mouse_y: 0.0,
|
last_mouse_y: 0.0,
|
||||||
|
|
|
@ -17,6 +17,7 @@ use std::thread;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::ui;
|
use crate::ui;
|
||||||
use crate::render;
|
use crate::render;
|
||||||
|
@ -36,6 +37,7 @@ pub struct ServerList {
|
||||||
disconnect_reason: Option<Component>,
|
disconnect_reason: Option<Component>,
|
||||||
|
|
||||||
needs_reload: Rc<RefCell<bool>>,
|
needs_reload: Rc<RefCell<bool>>,
|
||||||
|
server_protocol_versions: HashMap<String, i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UIElements {
|
struct UIElements {
|
||||||
|
@ -68,6 +70,7 @@ struct Server {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PingInfo {
|
struct PingInfo {
|
||||||
|
address: String,
|
||||||
motd: format::Component,
|
motd: format::Component,
|
||||||
ping: Duration,
|
ping: Duration,
|
||||||
exists: bool,
|
exists: bool,
|
||||||
|
@ -94,6 +97,7 @@ impl ServerList {
|
||||||
elements: None,
|
elements: None,
|
||||||
disconnect_reason,
|
disconnect_reason,
|
||||||
needs_reload: Rc::new(RefCell::new(false)),
|
needs_reload: Rc::new(RefCell::new(false)),
|
||||||
|
server_protocol_versions: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,6 +275,7 @@ impl ServerList {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
drop(send.send(PingInfo {
|
drop(send.send(PingInfo {
|
||||||
|
address,
|
||||||
motd: desc,
|
motd: desc,
|
||||||
ping: res.1,
|
ping: res.1,
|
||||||
exists: true,
|
exists: true,
|
||||||
|
@ -286,6 +291,7 @@ impl ServerList {
|
||||||
let mut msg = TextComponent::new(&e);
|
let mut msg = TextComponent::new(&e);
|
||||||
msg.modifier.color = Some(format::Color::Red);
|
msg.modifier.color = Some(format::Color::Red);
|
||||||
let _ = send.send(PingInfo {
|
let _ = send.send(PingInfo {
|
||||||
|
address,
|
||||||
motd: Component::Text(msg),
|
motd: Component::Text(msg),
|
||||||
ping: Duration::new(99999, 0),
|
ping: Duration::new(99999, 0),
|
||||||
exists: false,
|
exists: false,
|
||||||
|
@ -488,6 +494,11 @@ impl super::Screen for ServerList {
|
||||||
format!("Out of date {}/{}", res.online, res.max)
|
format!("Out of date {}/{}", res.online, res.max)
|
||||||
};
|
};
|
||||||
players.text = txt;
|
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);
|
let mut txt = TextComponent::new(&res.protocol_name);
|
||||||
txt.modifier.color = Some(format::Color::Yellow);
|
txt.modifier.color = Some(format::Color::Yellow);
|
||||||
|
|
|
@ -103,13 +103,13 @@ macro_rules! handle_packet {
|
||||||
|
|
||||||
impl Server {
|
impl Server {
|
||||||
|
|
||||||
pub fn connect(resources: Arc<RwLock<resources::Manager>>, profile: mojang::Profile, address: &str) -> Result<Server, protocol::Error> {
|
pub fn connect(resources: Arc<RwLock<resources::Manager>>, profile: mojang::Profile, address: &str, protocol_version: i32) -> Result<Server, protocol::Error> {
|
||||||
let mut conn = protocol::Conn::new(address)?;
|
let mut conn = protocol::Conn::new(address)?;
|
||||||
|
|
||||||
let host = conn.host.clone();
|
let host = conn.host.clone();
|
||||||
let port = conn.port;
|
let port = conn.port;
|
||||||
conn.write_packet(protocol::packet::handshake::serverbound::Handshake {
|
conn.write_packet(protocol::packet::handshake::serverbound::Handshake {
|
||||||
protocol_version: protocol::VarInt(protocol::SUPPORTED_PROTOCOL),
|
protocol_version: protocol::VarInt(protocol_version),
|
||||||
host,
|
host,
|
||||||
port,
|
port,
|
||||||
next: protocol::VarInt(2),
|
next: protocol::VarInt(2),
|
||||||
|
|
Loading…
Reference in New Issue