From e9eccd75d7da1cad6bea70c0bc800cfed14d44e4 Mon Sep 17 00:00:00 2001 From: core Date: Wed, 19 Apr 2023 19:21:37 -0400 Subject: [PATCH] api work --- Cargo.lock | 1 + api/config.toml | 18 ++++++--- protocol/Cargo.toml | 1 + protocol/src/api.rs | 6 +++ protocol/src/lib.rs | 4 +- protocol/src/pbuf/message_c2s.proto | 3 ++ server/src/api.rs | 12 ++++++ server/src/handler.rs | 60 +++++++++++++++++++++++++---- server/src/main.rs | 6 +++ server/src/manager.rs | 12 ++++++ 10 files changed, 109 insertions(+), 14 deletions(-) create mode 100644 protocol/src/api.rs create mode 100644 server/src/api.rs diff --git a/Cargo.lock b/Cargo.lock index adc0a457df96acafaf6841329d4b3964bd66f52d..b3364aa5aa8a34aadf6dd126c18b0459703cfc1b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3297,6 +3297,7 @@ dependencies = [ "protobuf 3.2.0", "protobuf-codegen 3.2.0", "protoc-rust", + "serde", ] [[package]] diff --git a/api/config.toml b/api/config.toml index c47f11018c24207732edd0ab11807f44cb54b118..f614f97769d2b22883f44b313177eb51359716c2 100644 --- a/api/config.toml +++ b/api/config.toml @@ -1,15 +1,21 @@ +game = "localhost:5173" +internal_tokens = ["01GY803PVK7YJKXZYWFTK6DS1Y-01GY8040ZQY9SG29DXY4HZ4EPD"] +jwt_signing_secret = "544adbc8144d375d581a1622a4f0cbcf92f006a156ef8b9d4afac6410f51f73c" +base = "localhost:8080" + +[server] +listen = "0.0.0.0:8080" + [realms.discord] authorize_url = "https://api.e3t.cc/auth/discord/authorize.php" -public_key_url = "https://api.e3t.cc/auth/discord/public-key.txt" +public_key = "-----BEGIN PUBLIC KEY-----\nMIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgHBcZsCM6ebFDCp3dFc+3EOzLw8B\n+fR+9Tx6S/lXOTghk49s7yaxza/zVRPxWaMqyjegfRCEepgV++jbWzBib7bhy91M\n+zlRbeZ9rf++N30Nf4R/XAnUAmhAHt8TzDC08DNQNYAFz37+r4EZlY7APHyND4qU\nd8w3qB95v/wMVB6nAgMBAAE=\n-----END PUBLIC KEY-----" issuer = "https://api.e3t.cc" -[tokens] -internal_api_tokens = [ - "01GY803PVK7YJKXZYWFTK6DS1Y-01GY8040ZQY9SG29DXY4HZ4EPD" -] +[database] +url = "postgres://postgres@localhost/starkingdoms" [endpoints] allowed_return_endpoints = [ "127.0.0.1:5173", "starkingdoms.tk" -] \ No newline at end of file +] diff --git a/protocol/Cargo.toml b/protocol/Cargo.toml index 1f220ff6c59130001006e0360f707d03de54d4b3..42c899429df56204f9af951985a85870fb056ae3 100644 --- a/protocol/Cargo.toml +++ b/protocol/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [dependencies] protobuf = "3" +serde = { version = "1", features = ["derive"] } [build-dependencies] protobuf-codegen = "3" diff --git a/protocol/src/api.rs b/protocol/src/api.rs new file mode 100644 index 0000000000000000000000000000000000000000..3614a351e6523278446a7bf5e114424678af0119 --- /dev/null +++ b/protocol/src/api.rs @@ -0,0 +1,6 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize)] +pub struct APISavedPlayerData { + +} \ No newline at end of file diff --git a/protocol/src/lib.rs b/protocol/src/lib.rs index 01ee527e40c13e18200b2d919dbfa8f57f8f3672..f06873473540c38c723e408ad1c6bbebf4846e5e 100644 --- a/protocol/src/lib.rs +++ b/protocol/src/lib.rs @@ -6,7 +6,9 @@ use crate::planet::PlanetType; use crate::starkingdoms_protocol::PacketWrapper; include!(concat!(env!("OUT_DIR"), "/protos/mod.rs")); -pub const PROTOCOL_VERSION: u32 = 1; +pub const PROTOCOL_VERSION: u32 = 2; + +pub mod api; #[derive(Debug)] pub enum MessageC2S { diff --git a/protocol/src/pbuf/message_c2s.proto b/protocol/src/pbuf/message_c2s.proto index 5e5ea243d242c8e8bba3784192dcca5b0854f624..520590ff364ec57eda28e12e98c971571a004525 100644 --- a/protocol/src/pbuf/message_c2s.proto +++ b/protocol/src/pbuf/message_c2s.proto @@ -10,6 +10,9 @@ message MessageC2SHello { uint32 version = 1; // Version of the protocol. Currently always 1 string requested_username = 2; // The username that the client is requesting. protocol.state.State next_state = 3; // The state the connection will go into after the handshake. + + optional string token = 4; + optional string user = 5; } message MessageC2SGoodbye { diff --git a/server/src/api.rs b/server/src/api.rs new file mode 100644 index 0000000000000000000000000000000000000000..133b8be5d1b29c751180bd7db366a8e6cf982391 --- /dev/null +++ b/server/src/api.rs @@ -0,0 +1,12 @@ +use std::error::Error; +use starkingdoms_protocol::api::APISavedPlayerData; + +pub async fn load_player_data_from_api(token: &str, user_id: &str, internal_token: &str) -> Result> { + // TODO + Ok(APISavedPlayerData {}) +} + +pub async fn save_player_data_to_api(data: &APISavedPlayerData, token: &str, user_id: &str, internal_token: &str) -> Result<(), Box> { + // TODO + Ok(()) +} \ No newline at end of file diff --git a/server/src/handler.rs b/server/src/handler.rs index 84664424e737bad7845c2a0843dddcb07ff2ba2a..e88a15c9366c8cdf2310dc7c87dc9170a55b02e8 100644 --- a/server/src/handler.rs +++ b/server/src/handler.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use std::time::{Duration, SystemTime}; use futures::stream::{SplitSink, SplitStream}; use futures::{FutureExt, SinkExt, StreamExt}; -use log::{error, info, debug}; +use log::{error, info, debug, warn}; use nalgebra::{vector, point}; use rapier2d_f64::prelude::{RigidBodyBuilder, RigidBodyType, ColliderBuilder, MassProperties, Collider}; use tungstenite::Message; @@ -18,6 +18,8 @@ use crate::{send, recv, SCALE}; use async_std::{sync::RwLock, channel::Receiver}; use async_std::net::TcpStream; use async_tungstenite::WebSocketStream; +use starkingdoms_protocol::api::APISavedPlayerData; +use crate::api::{load_player_data_from_api, save_player_data_to_api}; pub async fn handle_client(mgr: ClientManager, entities: Arc>, data: Arc>, remote_addr: SocketAddr, rx: Receiver, @@ -152,12 +154,34 @@ pub async fn handle_client(mgr: ClientManager, entities: Arc d, + Err(e) => { + warn!("[{}] * Beamin: ABORTED. API returned error: {}", remote_addr, e); + e_write_handle.entities.insert(get_entity_id(), Entity::Player(player)); + continue; + } + }; + + player.load_api_data(&player_data); + } + } + + e_write_handle.entities.insert(get_entity_id(), Entity::Player(player)); debug!("running"); } }, @@ -224,6 +248,28 @@ pub async fn handle_client(mgr: ClientManager, entities: Arc { info!("[{}] * Beaming out {} as {} with realm token {}", remote_addr, username, p.user_id, p.token); + + let player = entities.read().await.get_player(remote_addr).expect("Player sending messages after disconnect"); + + if Some(p.token) != player.auth_token || Some(p.user_id) != player.auth_user { + warn!("[{}] invalid beamout packet, ignoring", remote_addr); + continue; + } + + match save_player_data_to_api(&player.as_api_data(), &player.auth_token.unwrap(), &player.auth_user.unwrap(), &std::env::var("STK_API_KEY").unwrap()).await { + Ok(_) => { + info!("[{}] * Beamed out successfully", remote_addr); + let msg = MessageS2C::Goodbye(MessageS2CGoodbye { + reason: GoodbyeReason::Done.into(), + special_fields: Default::default(), + }).try_into()?; + send!(client_tx, msg).await?; + break; + } + Err(e) => { + error!("[{}] error beaming out: {}", remote_addr, e); + } + } } } } diff --git a/server/src/main.rs b/server/src/main.rs index c025018803b1cd33924990773b99cb02ef3458c4..9cb71ee0de6203363e3a4a22e250b832fb8851e3 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -27,6 +27,7 @@ pub mod macros; pub mod planet; pub mod orbit; pub mod entity; +pub mod api; const SCALE: f64 = 1.0; @@ -162,6 +163,11 @@ lazy_static! { async fn main() { simple_logger::init_with_level(Level::Debug).expect("Unable to start logging service"); + if std::env::var("STK_API_KEY").is_err() { + error!("Unable to read the API key from STK_API_KEY. Ensure it is set, and has a valid value."); + std::process::exit(1); + } + let addr = SocketAddr::from(([0, 0, 0, 0], 3000)); info!("Listening on {} for HTTP/WebSocket connections", addr); diff --git a/server/src/manager.rs b/server/src/manager.rs index 53467cecfa95e7942d9b7529937eecec350895af..94eff3bb062172f9f2eeb01cddaa99c9506baf49 100644 --- a/server/src/manager.rs +++ b/server/src/manager.rs @@ -5,6 +5,7 @@ use rapier2d_f64::na::Vector2; use rapier2d_f64::prelude::{IntegrationParameters, PhysicsPipeline, IslandManager, BroadPhase, NarrowPhase, ImpulseJointSet, MultibodyJointSet, CCDSolver, RigidBodySet, ColliderSet, RigidBodyHandle}; use async_std::sync::RwLock; use async_std::channel::Sender; +use starkingdoms_protocol::api::APISavedPlayerData; #[derive(Clone)] pub struct ClientManager { @@ -17,6 +18,17 @@ pub struct Player { pub handle: RigidBodyHandle, pub input: PlayerInput, pub addr: SocketAddr, + pub auth_token: Option, + pub auth_user: Option, +} + +impl Player { + pub fn as_api_data(&self) -> APISavedPlayerData { + APISavedPlayerData {} + } + + pub fn load_api_data(&mut self, data: &APISavedPlayerData) { + } } #[derive(Default, Clone)]