~starkingdoms/starkingdoms

e9eccd75d7da1cad6bea70c0bc800cfed14d44e4 — core 2 years ago f8a7045
api work
M Cargo.lock => Cargo.lock +1 -0
@@ 3297,6 3297,7 @@ dependencies = [
 "protobuf 3.2.0",
 "protobuf-codegen 3.2.0",
 "protoc-rust",
 "serde",
]

[[package]]

M api/config.toml => api/config.toml +12 -6
@@ 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
]

M protocol/Cargo.toml => protocol/Cargo.toml +1 -0
@@ 7,6 7,7 @@ edition = "2021"

[dependencies]
protobuf = "3"
serde = { version = "1", features = ["derive"] }

[build-dependencies]
protobuf-codegen = "3"

A protocol/src/api.rs => protocol/src/api.rs +6 -0
@@ 0,0 1,6 @@
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
pub struct APISavedPlayerData {

}
\ No newline at end of file

M protocol/src/lib.rs => protocol/src/lib.rs +3 -1
@@ 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 {

M protocol/src/pbuf/message_c2s.proto => protocol/src/pbuf/message_c2s.proto +3 -0
@@ 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 {

A server/src/api.rs => server/src/api.rs +12 -0
@@ 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<APISavedPlayerData, Box<dyn Error>> {
    // TODO
    Ok(APISavedPlayerData {})
}

pub async fn save_player_data_to_api(data: &APISavedPlayerData, token: &str, user_id: &str, internal_token: &str) -> Result<(), Box<dyn Error + Send + Sync>> {
    // TODO
    Ok(())
}
\ No newline at end of file

M server/src/handler.rs => server/src/handler.rs +53 -7
@@ 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<RwLock<EntityHandler>>, data: Arc<RwLock<PhysicsData>>,
                           remote_addr: SocketAddr, rx: Receiver<ClientHandlerMessage>,


@@ 152,12 154,34 @@ pub async fn handle_client(mgr: ClientManager, entities: Arc<RwLock<EntityHandle
                                data_handle.rigid_body_set = rigid_body_set;
                                data_handle.collider_set = collider_set;

                                entities.write().await.entities.insert(get_entity_id(),
                                    Entity::Player(Player {
                                        handle: player_handle,
                                        input: Default::default(),
                                        addr: remote_addr
                                    }));
                                let mut player = Player {
                                    handle: player_handle,
                                    input: Default::default(),
                                    addr: remote_addr,
                                    auth_token: pkt.token.clone(),
                                    auth_user: pkt.user.clone()
                                };

                                let mut e_write_handle = entities.write().await;

                                if let Some(user) = pkt.user {
                                    if let Some(token) = pkt.token {
                                        info!("[{}] * Beamin: beaming in {} as {} with token {}", remote_addr, username, user, token);

                                        let player_data = match load_player_data_from_api(&token, &user, &std::env::var("STK_API_KEY").unwrap()).await {
                                            Ok(d) => 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<RwLock<EntityHandle
                        },
                        MessageC2S::AuthenticateAndBeamOut(p) => {
                            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);
                                }
                            }
                        }
                    }
                }

M server/src/main.rs => server/src/main.rs +6 -0
@@ 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);

M server/src/manager.rs => server/src/manager.rs +12 -0
@@ 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<String>,
    pub auth_user: Option<String>,
}

impl Player {
    pub fn as_api_data(&self) -> APISavedPlayerData {
        APISavedPlayerData {}
    }

    pub fn load_api_data(&mut self, data: &APISavedPlayerData) {
    }
}

#[derive(Default, Clone)]