Add client/server version checking.
This commit is contained in:
parent
bb1fce886a
commit
64d91c30ff
12
server/build.rs
Normal file
12
server/build.rs
Normal file
@ -0,0 +1,12 @@
|
||||
use std::process::Command;
|
||||
|
||||
fn main()
|
||||
{
|
||||
let output = Command::new("git")
|
||||
.args(&["rev-parse", "HEAD"])
|
||||
.output()
|
||||
.expect("Failed to acquire git HEAD");
|
||||
let git_hash = String::from_utf8(output.stdout).expect("Invalid UTF-8 output from git HEAD");
|
||||
let git_hash = git_hash.trim();
|
||||
println!("cargo:rustc-env=GIT_HASH={}", git_hash);
|
||||
}
|
@ -151,6 +151,12 @@ impl App {
|
||||
let mut socket = conn.stream.write().await;
|
||||
|
||||
match response.data {
|
||||
QRPacketData::RHello(response) => {
|
||||
socket.send(Message::Binary(
|
||||
encode_response(CODE_HELLO, response.encode())
|
||||
)).await.ok();
|
||||
}
|
||||
|
||||
QRPacketData::RRegister(response) => {
|
||||
socket.send(Message::Binary(
|
||||
encode_response(CODE_REGISTER, response.encode())
|
||||
|
@ -1 +1,2 @@
|
||||
pub const VERSION :&str = env!("GIT_HASH");
|
||||
pub const REGISTER_CODE :&str = "mountain";
|
||||
|
@ -77,6 +77,7 @@ async fn service_http(mut request:hyper::Request<hyper::body::Incoming>, args:Ht
|
||||
match request.uri().path() {
|
||||
"/.js" => {
|
||||
output = [
|
||||
format!("let CONFIG_VERSION = \"{}\";", config::VERSION).as_bytes().to_vec(),
|
||||
format!("let CONFIG_LANGUAGE = {};", language_code).as_bytes().to_vec(),
|
||||
output,
|
||||
].concat();
|
||||
|
@ -1,5 +1,6 @@
|
||||
use bus::Bus;
|
||||
use crate::{
|
||||
config,
|
||||
app::{
|
||||
authentication::Authentication,
|
||||
connection::Connection,
|
||||
@ -58,10 +59,13 @@ pub async fn thread_system(mut app:App, bus:Bus<protocol::QRPacket>)
|
||||
packet.from,
|
||||
QRPacket::new(id as u32, QRPacketData::RConn)
|
||||
).ok();
|
||||
|
||||
Some(QRPacket::new(0, QRPacketData::None))
|
||||
}
|
||||
|
||||
QRPacketData::QDisconn => {
|
||||
println!("Disconnect: {}", qr.id);
|
||||
|
||||
// Uninitialize connection
|
||||
if if let Some(conn) = app.connections.get(qr.id as usize).cloned() {
|
||||
|
||||
@ -110,12 +114,17 @@ pub async fn thread_system(mut app:App, bus:Bus<protocol::QRPacket>)
|
||||
true
|
||||
} else { false } {
|
||||
app.connections.remove(qr.id as usize).ok();
|
||||
|
||||
println!("Disconnect: {}", qr.id);
|
||||
}
|
||||
Some(QRPacket::new(0, QRPacketData::None))
|
||||
}
|
||||
|
||||
QRPacketData::QHello => {
|
||||
let response = PacketHelloResponse {
|
||||
version:config::VERSION.to_string(),
|
||||
};
|
||||
Some(QRPacket::new(qr.id, QRPacketData::RHello(response)))
|
||||
}
|
||||
|
||||
QRPacketData::QRegister(request) => {
|
||||
let mut response = PacketRegisterResponse::new();
|
||||
response.status = STATUS_SERVER_ERROR;
|
||||
|
@ -56,6 +56,11 @@ pub async fn handle_ws(ws:WebSocketStream<TokioIo<Upgraded>>, args:HttpServiceAr
|
||||
println!("MESSAGE {:x}", code);
|
||||
|
||||
match code {
|
||||
CODE_HELLO => {
|
||||
args.bus.send(
|
||||
bus_ds, QRPacket::new(conn_id, QRPacketData::QHello)
|
||||
).ok();
|
||||
}
|
||||
|
||||
CODE_REGISTER => match PacketRegister::decode(&data, &mut index) {
|
||||
Ok(packet) => {
|
||||
@ -207,7 +212,10 @@ pub async fn handle_ws(ws:WebSocketStream<TokioIo<Upgraded>>, args:HttpServiceAr
|
||||
true
|
||||
}
|
||||
}
|
||||
Err(_) => false,
|
||||
Err(e) => {
|
||||
println!("WSS error: {}", e.to_string());
|
||||
false
|
||||
},
|
||||
}
|
||||
None => false,
|
||||
} { }
|
||||
|
@ -22,6 +22,8 @@ pub const STATUS_NOT_IMPL :u16 = 0x00FF;
|
||||
** Operation Codes
|
||||
*/
|
||||
|
||||
pub const CODE_HELLO :u16 = 0x0001;
|
||||
|
||||
pub const CODE_REGISTER :u16 = 0x0010;
|
||||
pub const CODE_AUTH :u16 = 0x0011;
|
||||
pub const CODE_AUTH_RESUME :u16 = 0x0012;
|
||||
|
@ -12,6 +12,9 @@ pub enum QRPacketData {
|
||||
|
||||
QDisconn,
|
||||
|
||||
QHello,
|
||||
RHello(PacketHelloResponse),
|
||||
|
||||
QRegister(PacketRegister),
|
||||
RRegister(PacketRegisterResponse),
|
||||
|
||||
|
28
server/src/protocol/packet/hello.rs
Normal file
28
server/src/protocol/packet/hello.rs
Normal file
@ -0,0 +1,28 @@
|
||||
use crate::util::pack::pack_u8;
|
||||
|
||||
use super::Packet;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PacketHelloResponse {
|
||||
pub version:String,
|
||||
}
|
||||
impl PacketHelloResponse {
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self {
|
||||
version:String::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Packet for PacketHelloResponse {
|
||||
type Data = Self;
|
||||
|
||||
fn encode(&self) -> Vec<u8>
|
||||
{
|
||||
let version_bytes = self.version.as_bytes().to_vec();
|
||||
[
|
||||
pack_u8(version_bytes.len() as u8),
|
||||
version_bytes,
|
||||
].concat()
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
mod hello; pub use hello::*;
|
||||
mod connect; pub use connect::*;
|
||||
|
||||
mod register; pub use register::*;
|
||||
|
@ -30,6 +30,8 @@ const Status = {
|
||||
};
|
||||
|
||||
const OpCode = {
|
||||
Hello :0x0001,
|
||||
|
||||
Register :0x0010,
|
||||
Authenticate :0x0011,
|
||||
Resume :0x0012,
|
||||
|
@ -13,11 +13,23 @@ const SCENES = {
|
||||
load() {
|
||||
UI.nav([
|
||||
UI.button(LANG("reconnect"), () => { RECONNECT(); }),
|
||||
UI.button(LANG("practice"), () => { LOAD(SCENES.GamePractice); }),
|
||||
], []);
|
||||
return true;
|
||||
}
|
||||
reconnect() {
|
||||
LOAD_URL();
|
||||
message(code, data) {
|
||||
switch(code) {
|
||||
case OpCode.Hello: {
|
||||
console.log("CLIENT VERSION: '" + CONFIG_VERSION + "'");
|
||||
console.log("SERVER VERSION: '" + data.version + "'");
|
||||
|
||||
if(CONFIG_VERSION == data.version) {
|
||||
RESUME();
|
||||
} else {
|
||||
location.reload();
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -207,36 +219,40 @@ const SCENES = {
|
||||
this.pages = 1;
|
||||
}
|
||||
load() {
|
||||
UI.mainmenu("browse");
|
||||
if(SOCKET !== null) {
|
||||
UI.mainmenu("browse");
|
||||
|
||||
let indicator_page = UI.div([]);
|
||||
indicator_page.setAttribute("id", "indicator-page");
|
||||
let indicator_page = UI.div([]);
|
||||
indicator_page.setAttribute("id", "indicator-page");
|
||||
|
||||
UI.mainnav(
|
||||
[ ],
|
||||
[
|
||||
indicator_page,
|
||||
UI.button("◀", () => {
|
||||
if(SCENE.page < SCENE.pages) { SCENE.page += 1; }
|
||||
SCENE.refresh();
|
||||
}),
|
||||
UI.button("▶", () => {
|
||||
if(SCENE.page > 1) { SCENE.page -= 1; }
|
||||
SCENE.refresh();
|
||||
}),
|
||||
UI.button(LANG("refresh"), () => { SCENE.referesh(); }),
|
||||
],
|
||||
{ auth:true, session:true }
|
||||
);
|
||||
UI.mainnav(
|
||||
[ ],
|
||||
[
|
||||
indicator_page,
|
||||
UI.button("◀", () => {
|
||||
if(SCENE.page < SCENE.pages) { SCENE.page += 1; }
|
||||
SCENE.refresh();
|
||||
}),
|
||||
UI.button("▶", () => {
|
||||
if(SCENE.page > 1) { SCENE.page -= 1; }
|
||||
SCENE.refresh();
|
||||
}),
|
||||
UI.button(LANG("refresh"), () => { SCENE.referesh(); }),
|
||||
],
|
||||
{ auth:true, session:true }
|
||||
);
|
||||
|
||||
let table = document.createElement("table");
|
||||
table.setAttribute("id", "content");
|
||||
table.setAttribute("class", "list session");
|
||||
MAIN.appendChild(table);
|
||||
let table = document.createElement("table");
|
||||
table.setAttribute("id", "content");
|
||||
table.setAttribute("class", "list session");
|
||||
MAIN.appendChild(table);
|
||||
|
||||
SCENE.refresh();
|
||||
SCENE.refresh();
|
||||
|
||||
history.pushState(null, "Dzura", "/");
|
||||
history.pushState(null, "Dzura", "/");
|
||||
} else {
|
||||
LOAD(SCENES.Offline);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
refresh() {
|
||||
@ -1010,7 +1026,6 @@ function LOAD(scene, data=null) {
|
||||
UI.rebuild();
|
||||
SCENE = new scene();
|
||||
if(!SCENE.load(data)) { LOAD(SCENES.Browse); }
|
||||
|
||||
UI.update_status();
|
||||
}
|
||||
|
||||
@ -1023,13 +1038,13 @@ function LOAD_URL() {
|
||||
|
||||
if(parts.length > 1) {
|
||||
switch(parts[1]) {
|
||||
case "continue": LOAD(SCENES.Continue); break;
|
||||
case "live": LOAD(SCENES.Live); break;
|
||||
case "history": LOAD(SCENES.History); break;
|
||||
case "practice": LOAD(SCENES.GamePractice); break;
|
||||
case "guide": LOAD(SCENES.Guide); break;
|
||||
case "about": LOAD(SCENES.About); break;
|
||||
case "challenge": LOAD(SCENES.Challenge); break;
|
||||
case "continue": LOAD(SCENES.Continue); return;
|
||||
case "live": LOAD(SCENES.Live); return;
|
||||
case "history": LOAD(SCENES.History); return;
|
||||
case "practice": LOAD(SCENES.GamePractice); return;
|
||||
case "guide": LOAD(SCENES.Guide); return;
|
||||
case "about": LOAD(SCENES.About); return;
|
||||
case "challenge": LOAD(SCENES.Challenge); return;
|
||||
|
||||
case "game": {
|
||||
if(parts[2]) {
|
||||
@ -1038,14 +1053,10 @@ function LOAD_URL() {
|
||||
token:token,
|
||||
mode:INTERFACE.Mode.Review,
|
||||
});
|
||||
} else {
|
||||
LOAD(SCENES.Browse);
|
||||
return;
|
||||
}
|
||||
} break;
|
||||
|
||||
default: LOAD(SCENES.Browse);
|
||||
}
|
||||
} else {
|
||||
LOAD(SCENES.Browse);
|
||||
}
|
||||
LOAD(SCENES.Browse);
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ function RECONNECT() {
|
||||
SOCKET = new WebSocket("wss://" + location.hostname + ":38612");
|
||||
SOCKET.binaryType = "arraybuffer";
|
||||
SOCKET.addEventListener("error", () => {
|
||||
console.log("Websocket error.");
|
||||
SOCKET = null;
|
||||
if(SCENE.disconnect !== undefined) { SCENE.disconnect(); }
|
||||
});
|
||||
@ -20,11 +21,11 @@ function RECONNECT() {
|
||||
RECONNECT();
|
||||
});
|
||||
|
||||
RESUME();
|
||||
MESSAGE_COMPOSE([
|
||||
PACK.u16(OpCode.Hello),
|
||||
]);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
RESUME();
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,7 +41,7 @@ function RESUME() {
|
||||
secret,
|
||||
]);
|
||||
} else {
|
||||
if(SCENE.reconnect !== undefined) { SCENE.reconnect(); }
|
||||
LOAD_URL();
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,6 +57,18 @@ function MESSAGE(event) {
|
||||
}
|
||||
|
||||
switch(code) {
|
||||
case OpCode.Hello: {
|
||||
console.log("RECV Hello");
|
||||
|
||||
data = {
|
||||
version:"",
|
||||
};
|
||||
|
||||
result = UNPACK.string(bytes, index, UNPACK.u8);
|
||||
index = result.index;
|
||||
data.version = result.data;
|
||||
} break;
|
||||
|
||||
case OpCode.Register: {
|
||||
console.log("RECV Register");
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user