M README.md => README.md +0 -9
@@ 5,15 5,6 @@ A multiplayer deck building game.
## **Current major issues**
-### **Session cookie refreshing**
-Currently, the cookie is refreshed on every single action which requires\
-session auth.\
-Okay, that seems pretty normal.\
-So, we just save the new one to the `global.user_to_session_map` hashmap,\
-and just send an event to the client with the new one, so they can update\
-it in the clients presistent storage, right? This can happen automatically\
-in the background.
-
### **Quite a few unwraps in use**
All should be handled, with sane error responses.
M client/src/plugins/networking/systems/events/receive/mod.rs => client/src/plugins/networking/systems/events/receive/mod.rs +6 -2
@@ 8,8 8,8 @@
use bevy::prelude::*;
use laurelin_shared::server::{
- channels::{AfterAuthChannel, DataRequestChannel},
- messages::{AfterAuth, DataRequestResponse, DataRequestType},
+ channels::{AfterAuthChannel, CookieRefreshChannel, DataRequestChannel},
+ messages::{AfterAuth, CookieRefresh, DataRequestResponse, DataRequestType},
};
use naia_bevy_client::{
events::{ClientTickEvent, ConnectEvent, DisconnectEvent, MessageEvents, RejectEvent},
@@ 77,6 77,10 @@ pub fn message_events(
commands.insert_resource(NextState(Some(MenuState::Menu)));
}
+ for cr_message in events.read::<CookieRefreshChannel, CookieRefresh>() {
+ cfg_user.cookie = cr_message.cookie;
+ }
+
for response in events.read::<DataRequestChannel, DataRequestResponse>() {
match DataRequestType::from_u8(&response.r#type) {
DataRequestType::GameCreate => {
M server/src/systems/event/message/mod.rs => server/src/systems/event/message/mod.rs +40 -10
@@ 6,14 6,17 @@
* See LICENSE for licensing information.
*/
-use bevy_ecs::{event::EventReader, system::Res};
+use bevy_ecs::{
+ event::EventReader,
+ system::{Res, ResMut},
+};
use laurelin_shared::{
api::game::{
all_forming, create, my_games, ResponseAllForming, ResponseCreateGame, ResponseMyGames,
},
server::{
- channels::DataRequestChannel,
- messages::{DataRequest, DataRequestResponse, DataRequestType},
+ channels::{CookieRefreshChannel, DataRequestChannel},
+ messages::{CookieRefresh, DataRequest, DataRequestResponse, DataRequestType},
},
};
use naia_bevy_server::{events::MessageEvents, Server};
@@ 24,7 27,7 @@ pub(crate) fn message_events(
mut ev: EventReader<MessageEvents>,
mut server: Server,
config: Res<Config>,
- global: Res<Global>,
+ mut global: ResMut<Global>,
) {
for events in ev.iter() {
for (user_key, request) in events.read::<DataRequestChannel, DataRequest>() {
@@ 32,8 35,8 @@ pub(crate) fn message_events(
DataRequestType::GameCreate => {
// TODO: handle
let cookie = global.user_to_session_map.get(&user_key).unwrap();
- let response = create(&config.api_address, &cookie);
- let json = match response {
+ let wrapped = create(&config.api_address, &cookie);
+ let json = match wrapped.response {
ResponseCreateGame::Error(err) => serde_json::to_string(&err).unwrap(), // TODO: handle
ResponseCreateGame::Valid(result) => {
serde_json::to_string(&result).unwrap() // TODO: handle
@@ 43,12 46,21 @@ pub(crate) fn message_events(
&user_key,
&DataRequestResponse::new(request.r#type, &json),
);
+
+ // update cookie
+ global
+ .user_to_session_map
+ .insert(user_key, wrapped.cookie.clone());
+ server.send_message::<CookieRefreshChannel, CookieRefresh>(
+ &user_key,
+ &CookieRefresh::new(&wrapped.cookie),
+ );
}
DataRequestType::GameAllForming => {
// TODO: handle
let cookie = global.user_to_session_map.get(&user_key).unwrap();
- let response = all_forming(&config.api_address, &cookie);
- let json = match response {
+ let wrapped = all_forming(&config.api_address, &cookie);
+ let json = match wrapped.response {
ResponseAllForming::Error(err) => serde_json::to_string(&err).unwrap(), // TODO: handle
ResponseAllForming::Valid(result) => {
serde_json::to_string(&result).unwrap() // TODO: handle
@@ 58,12 70,21 @@ pub(crate) fn message_events(
&user_key,
&DataRequestResponse::new(request.r#type, &json),
);
+
+ // update cookie
+ global
+ .user_to_session_map
+ .insert(user_key, wrapped.cookie.clone());
+ server.send_message::<CookieRefreshChannel, CookieRefresh>(
+ &user_key,
+ &CookieRefresh::new(&wrapped.cookie),
+ );
}
DataRequestType::GameMyGames => {
// TODO: handle
let cookie = global.user_to_session_map.get(&user_key).unwrap();
- let response = my_games(&config.api_address, &cookie);
- let json = match response {
+ let wrapped = my_games(&config.api_address, &cookie);
+ let json = match wrapped.response {
ResponseMyGames::Error(err) => serde_json::to_string(&err).unwrap(), // TODO: handle
ResponseMyGames::Valid(result) => {
serde_json::to_string(&result).unwrap() // TODO: handle
@@ 73,6 94,15 @@ pub(crate) fn message_events(
&user_key,
&DataRequestResponse::new(request.r#type, &json),
);
+
+ // update cookie
+ global
+ .user_to_session_map
+ .insert(user_key, wrapped.cookie.clone());
+ server.send_message::<CookieRefreshChannel, CookieRefresh>(
+ &user_key,
+ &CookieRefresh::new(&wrapped.cookie),
+ );
}
}
}
M shared/src/api/game/all_forming.rs => shared/src/api/game/all_forming.rs +12 -3
@@ 9,7 9,7 @@
use reqwest::{self, header::COOKIE};
use serde::{Deserialize, Serialize};
-use crate::{error::api::APIError, types::game::Game};
+use crate::{api::macros::extract_cookie, error::api::APIError, types::game::Game};
pub type ResultAllForming = Vec<Game>;
@@ 20,7 20,13 @@ pub enum ResponseAllForming {
Valid(ResultAllForming),
}
-pub fn all_forming(api_address: &String, cookie: &String) -> ResponseAllForming {
+#[derive(Deserialize)]
+pub struct ResponseAllFormingWrapper {
+ pub response: ResponseAllForming,
+ pub cookie: String,
+}
+
+pub fn all_forming(api_address: &String, cookie: &String) -> ResponseAllFormingWrapper {
let client = reqwest::blocking::Client::new();
let resp = client
@@ 29,5 35,8 @@ pub fn all_forming(api_address: &String, cookie: &String) -> ResponseAllForming
.send()
.unwrap();
- resp.json().unwrap()
+ ResponseAllFormingWrapper {
+ cookie: extract_cookie!(resp),
+ response: resp.json().unwrap(),
+ }
}
M shared/src/api/game/create.rs => shared/src/api/game/create.rs +12 -3
@@ 9,7 9,7 @@
use reqwest::{self, header::COOKIE};
use serde::{Deserialize, Serialize};
-use crate::{error::api::APIError, types::game::Game};
+use crate::{api::macros::extract_cookie, error::api::APIError, types::game::Game};
#[derive(Serialize, Deserialize)]
#[serde(untagged)]
@@ 18,7 18,13 @@ pub enum ResponseCreateGame {
Valid(Game),
}
-pub fn create(api_address: &String, cookie: &String) -> ResponseCreateGame {
+#[derive(Deserialize)]
+pub struct ResponseCreateGameWrapper {
+ pub response: ResponseCreateGame,
+ pub cookie: String,
+}
+
+pub fn create(api_address: &String, cookie: &String) -> ResponseCreateGameWrapper {
let client = reqwest::blocking::Client::new();
let resp = client
@@ 27,5 33,8 @@ pub fn create(api_address: &String, cookie: &String) -> ResponseCreateGame {
.send()
.unwrap();
- resp.json().unwrap()
+ ResponseCreateGameWrapper {
+ cookie: extract_cookie!(resp),
+ response: resp.json().unwrap(),
+ }
}
M shared/src/api/game/mygames.rs => shared/src/api/game/mygames.rs +12 -3
@@ 9,7 9,7 @@
use reqwest::{self, header::COOKIE};
use serde::{Deserialize, Serialize};
-use crate::{error::api::APIError, types::game::Game};
+use crate::{api::macros::extract_cookie, error::api::APIError, types::game::Game};
pub type ResultMyGames = Vec<Game>;
@@ 20,7 20,13 @@ pub enum ResponseMyGames {
Valid(ResultMyGames),
}
-pub fn my_games(api_address: &String, cookie: &String) -> ResponseMyGames {
+#[derive(Deserialize)]
+pub struct ResponseMyGamesWrapper {
+ pub response: ResponseMyGames,
+ pub cookie: String,
+}
+
+pub fn my_games(api_address: &String, cookie: &String) -> ResponseMyGamesWrapper {
let client = reqwest::blocking::Client::new();
let resp = client
@@ 29,5 35,8 @@ pub fn my_games(api_address: &String, cookie: &String) -> ResponseMyGames {
.send()
.unwrap();
- resp.json().unwrap()
+ ResponseMyGamesWrapper {
+ cookie: extract_cookie!(resp),
+ response: resp.json().unwrap(),
+ }
}
M shared/src/server/channels.rs => shared/src/server/channels.rs +7 -0
@@ 14,6 14,9 @@ use naia_bevy_shared::{
pub struct AfterAuthChannel;
#[derive(Channel)]
+pub struct CookieRefreshChannel;
+
+#[derive(Channel)]
pub struct DataRequestChannel;
pub struct ChannelsPlugin;
@@ 25,6 28,10 @@ impl ProtocolPlugin for ChannelsPlugin {
ChannelDirection::ServerToClient,
ChannelMode::UnorderedReliable(ReliableSettings::default()),
)
+ .add_channel::<CookieRefreshChannel>(
+ ChannelDirection::ServerToClient,
+ ChannelMode::UnorderedReliable(ReliableSettings::default()),
+ )
.add_channel::<DataRequestChannel>(
ChannelDirection::Bidirectional,
ChannelMode::OrderedReliable(ReliableSettings::default()),
A shared/src/server/messages/cookierefresh.rs => shared/src/server/messages/cookierefresh.rs +22 -0
@@ 0,0 1,22 @@
+/*
+ * This file is part of laurelin/shared
+ * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
+ *
+ * Licensed under GPL-3.0-only.
+ * See LICENSE for licensing information.
+ */
+
+use naia_bevy_shared::Message;
+
+#[derive(Message)]
+pub struct CookieRefresh {
+ pub cookie: String,
+}
+
+impl CookieRefresh {
+ pub fn new(cookie: &str) -> Self {
+ Self {
+ cookie: cookie.to_string(),
+ }
+ }
+}
M shared/src/server/messages/mod.rs => shared/src/server/messages/mod.rs +4 -0
@@ 11,6 11,9 @@ use naia_bevy_shared::{Protocol, ProtocolPlugin};
mod auth;
pub use auth::{AfterAuth, Auth};
+mod cookierefresh;
+pub use cookierefresh::CookieRefresh;
+
mod datarequest;
pub use datarequest::{DataRequest, DataRequestResponse, DataRequestType};
@@ 21,6 24,7 @@ impl ProtocolPlugin for MessagesPlugin {
protocol
.add_message::<Auth>()
.add_message::<AfterAuth>()
+ .add_message::<CookieRefresh>()
.add_message::<datarequest::DataRequest>()
.add_message::<datarequest::DataRequestResponse>();
}