@@ 33,8 33,12 @@ use bevy_rapier2d::prelude::*;
use bevy_tungstenite_stk::{StkTungsteniteServerConfig, StkTungsteniteServerPlugin, WsEvent};
use component::Input;
use component::*;
+use hmac::{Hmac, Mac};
+use jwt::VerifyWithKey;
use packet::*;
use rand::Rng;
+use serde::{Deserialize, Serialize};
+use sha2::Sha256;
use starkingdoms_common::SaveModule;
use starkingdoms_common::{pack_savefile, unpack_savefile, SaveData};
use std::f32::consts::PI;
@@ 100,6 104,16 @@ impl PluginGroup for StkPluginGroup {
}
}
+#[derive(Serialize, Deserialize, Debug, Clone)]
+pub struct UserToken {
+ pub id: i64,
+ pub username: String,
+ pub permission_level: i32,
+ pub expires: std::time::SystemTime,
+}
+
+pub const REQUIRED_PERM_LEVEL: i32 = 10;
+
fn main() {
// read the key in
let key = std::fs::read_to_string("/etc/starkingdoms/app_key").unwrap();
@@ 293,8 307,46 @@ fn on_message(
Packet::ClientLogin {
username,
save,
- jwt: _,
+ jwt,
} => {
+ // auth
+ // plz no remove
+ if let Some(token) = jwt {
+ let key: Hmac<Sha256> = Hmac::new_from_slice(&app_keys.app_key).unwrap();
+ let claims: UserToken = match token.verify_with_key(&key) {
+ Ok(c) => c,
+ Err(e) => {
+ event_queue.push(WsEvent::Send {
+ to: *from,
+ message: Packet::Message { message_type: MessageType::Error, actor: "SERVER".to_string(), content: format!("Token is invalid or verification failed: {e}. Please log in again, or contact StarKingdoms staff if the problem persists.") }.into(),
+ });
+ event_queue.push(WsEvent::Close { addr: *from });
+ continue;
+ }
+ };
+
+ if claims.permission_level < REQUIRED_PERM_LEVEL {
+ event_queue.push(WsEvent::Send {
+ to: *from,
+ message: Packet::Message { message_type: MessageType::Error, actor: "SERVER".to_string(), content: format!("Permission level {} is too low, {REQUIRED_PERM_LEVEL} is required. If your permissions were just changed, you need to log out and log back in for the change to take effect. If you believe this is a mistake, contact StarKingdoms staff.", claims.permission_level) }.into(),
+ });
+ event_queue.push(WsEvent::Close { addr: *from });
+ continue;
+ }
+
+ event_queue.push(WsEvent::Send {
+ to: *from,
+ message: Packet::Message { message_type: MessageType::Server, actor: "StarKingdoms Team".to_string(), content: "Thank you for participating in the StarKingdoms private alpha! Your feedback is essential to improving the game, so please give us any feedback you have in the Discord! <3".to_string() }.into(),
+ });
+ } else if REQUIRED_PERM_LEVEL != 0 {
+ event_queue.push(WsEvent::Send {
+ to: *from,
+ message: Packet::Message { message_type: MessageType::Error, actor: "SERVER".to_string(), content: "Authentication is required to join this server at the moment. Log in and try again, or try again later.".to_string() }.into(),
+ });
+ event_queue.push(WsEvent::Close { addr: *from });
+ continue;
+ }
+
let angle: f32 = {
let mut rng = rand::thread_rng();
rng.gen::<f32>() * std::f32::consts::PI * 2.
@@ 472,12 524,33 @@ fn on_message(
let packet = Packet::Message {
message_type: packet::MessageType::Server,
actor: "SERVER".to_string(),
+ content: format!(
+ "starkingdoms-server v{} says hello",
+ env!("CARGO_PKG_VERSION")
+ ),
+ };
+ event_queue.push(WsEvent::Send {
+ to: *from,
+ message: packet.into(),
+ });
+ let packet = Packet::Message {
+ message_type: packet::MessageType::Server,
+ actor: "SERVER".to_string(),
content: "Welcome to StarKingdoms.IO! Have fun!".to_string(),
};
event_queue.push(WsEvent::Send {
to: *from,
message: packet.into(),
});
+ let packet = Packet::Message {
+ message_type: packet::MessageType::Server,
+ actor: "SERVER".to_string(),
+ content: "Found a bug? Have a feature request? Please bring this and all other feedback to the game's official Discord server! Join here: https://discord.gg/3u7Yw8DWtQ".to_string(),
+ };
+ event_queue.push(WsEvent::Send {
+ to: *from,
+ message: packet.into(),
+ });
}
Packet::SendMessage { target, content } => {
// find our player
@@ 56,6 56,8 @@ export function startRender() {
global.rendering!.app.stage.addChild(global.rendering!.starfield_near.sprite);
app.ticker.add(() => {
+ if (player() === undefined) { return; }
+
global.rendering!.app.stage.x =
-player()?.transform.x! + window.innerWidth / 2;
global.rendering!.app.stage.y =
@@ 68,17 70,17 @@ export function startRender() {
global.rendering!.starfield.sprite.width = window.innerWidth + 384;
global.rendering!.starfield.off_x =
- ((global.parts_map.get(global.me?.part_id!)!.transform.x * 3) / 4) % 384;
+ ((player()?.transform.x! * 3) / 4) % 384;
global.rendering!.starfield.off_y =
- ((global.parts_map.get(global.me?.part_id!)!.transform.y * 3) / 4) % 384;
+ ((player()?.transform.y! * 3) / 4) % 384;
global.rendering!.starfield.sprite.x =
- Math.floor(global.parts_map.get(global.me?.part_id!)!.transform.x / 384) *
+ Math.floor(player()?.transform.x! / 384) *
384 -
global.rendering!.starfield.sprite.width / 2 +
192;
global.rendering!.starfield.sprite.y =
- Math.floor(global.parts_map.get(global.me?.part_id!)!.transform.y / 384) *
+ Math.floor(player()?.transform.y! / 384) *
384 -
global.rendering!.starfield.sprite.height / 2 +
192;
@@ 93,17 95,17 @@ export function startRender() {
global.rendering!.starfield_near.sprite.width = window.innerWidth + 768;
global.rendering!.starfield_near.off_x =
- (global.parts_map.get(global.me?.part_id!)!.transform.x / 2) % 768;
+ (player()?.transform.x! / 2) % 768;
global.rendering!.starfield_near.off_y =
- (global.parts_map.get(global.me?.part_id!)!.transform.y / 2) % 768;
+ (player()?.transform.y! / 2) % 768;
global.rendering!.starfield_near.sprite.x =
- Math.floor(global.parts_map.get(global.me?.part_id!)!.transform.x / 768) *
+ Math.floor(player()?.transform.x! / 768) *
768 -
global.rendering!.starfield_near.sprite.width / 2 +
384;
global.rendering!.starfield_near.sprite.y =
- Math.floor(global.parts_map.get(global.me?.part_id!)!.transform.y / 768) *
+ Math.floor(player()?.transform.y! / 768) *
768 -
global.rendering!.starfield_near.sprite.height / 2 +
384;