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"]
|
||||
|
||||
use std::time::{Instant, Duration};
|
||||
use log::info;
|
||||
use log::{info, warn};
|
||||
extern crate steven_shared as shared;
|
||||
|
||||
#[macro_use]
|
||||
|
@ -73,6 +73,8 @@ pub struct Game {
|
|||
chunk_builder: chunk_builder::ChunkBuilder,
|
||||
|
||||
connect_reply: Option<mpsc::Receiver<Result<server::Server, protocol::Error>>>,
|
||||
protocol_version: i32,
|
||||
|
||||
dpi_factor: f64,
|
||||
last_mouse_x: f64,
|
||||
last_mouse_y: f64,
|
||||
|
@ -83,6 +85,23 @@ 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_PROTOCOL);
|
||||
protocol::SUPPORTED_PROTOCOL
|
||||
}
|
||||
};
|
||||
|
||||
self.protocol_version = protocol_version;
|
||||
let (tx, rx) = mpsc::channel();
|
||||
self.connect_reply = Some(rx);
|
||||
let address = address.to_owned();
|
||||
|
@ -93,7 +112,7 @@ impl Game {
|
|||
access_token: self.vars.get(auth::AUTH_TOKEN).clone(),
|
||||
};
|
||||
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,
|
||||
chunk_builder: chunk_builder::ChunkBuilder::new(resource_manager, textures),
|
||||
connect_reply: None,
|
||||
protocol_version: protocol::SUPPORTED_PROTOCOL,
|
||||
dpi_factor,
|
||||
last_mouse_x: 0.0,
|
||||
last_mouse_y: 0.0,
|
||||
|
|
|
@ -17,6 +17,7 @@ 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;
|
||||
|
@ -36,6 +37,7 @@ pub struct ServerList {
|
|||
disconnect_reason: Option<Component>,
|
||||
|
||||
needs_reload: Rc<RefCell<bool>>,
|
||||
server_protocol_versions: HashMap<String, i32>,
|
||||
}
|
||||
|
||||
struct UIElements {
|
||||
|
@ -68,6 +70,7 @@ struct Server {
|
|||
}
|
||||
|
||||
struct PingInfo {
|
||||
address: String,
|
||||
motd: format::Component,
|
||||
ping: Duration,
|
||||
exists: bool,
|
||||
|
@ -94,6 +97,7 @@ impl ServerList {
|
|||
elements: None,
|
||||
disconnect_reason,
|
||||
needs_reload: Rc::new(RefCell::new(false)),
|
||||
server_protocol_versions: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -271,6 +275,7 @@ impl ServerList {
|
|||
None
|
||||
};
|
||||
drop(send.send(PingInfo {
|
||||
address,
|
||||
motd: desc,
|
||||
ping: res.1,
|
||||
exists: true,
|
||||
|
@ -286,6 +291,7 @@ 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,
|
||||
|
@ -488,6 +494,11 @@ 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);
|
||||
|
|
|
@ -103,13 +103,13 @@ macro_rules! handle_packet {
|
|||
|
||||
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 host = conn.host.clone();
|
||||
let port = conn.port;
|
||||
conn.write_packet(protocol::packet::handshake::serverbound::Handshake {
|
||||
protocol_version: protocol::VarInt(protocol::SUPPORTED_PROTOCOL),
|
||||
protocol_version: protocol::VarInt(protocol_version),
|
||||
host,
|
||||
port,
|
||||
next: protocol::VarInt(2),
|
||||
|
|
Loading…
Reference in New Issue