Skip to content

Commit

Permalink
Cleanup, bot rebalancing WIP.
Browse files Browse the repository at this point in the history
  • Loading branch information
finnbear committed Aug 20, 2023
1 parent 326652c commit 391bac1
Show file tree
Hide file tree
Showing 19 changed files with 431 additions and 290 deletions.
12 changes: 5 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,11 @@ rustup target add wasm32-unknown-unknown
3. `trunk build --release` in `/client`
4. `cargo run --release` in `/server`

## HTTPS

If you build the server in `--release` mode, it will force HTTPS using a self-signed certificate.

Optionally, specify `--certificate-path` and `--private-key-path` to use a trusted CA certificate (e.g. acquired via [Let's Encrypt](https://letsencrypt.org/)). The server will periodically check for and load renewed certificates.

## Official Server(s)

To avoid potential visibility-cheating, you are prohibited from using the open-source
client to play on official Kiomet server(s).
client to play on official Kiomet server(s).

## Trademark

Kiomet is a trademark of Softbear, Inc.
Binary file added assets/branding/app.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ sprite_sheet = { path = "../engine/sprite_sheet" }
strum = { version = "0.24.1" }
stylist = { version = "0.12.1", default-features = false }
yew = "0.20"
yew_frontend = { path = "../engine/yew_frontend" }
yew_frontend = { path = "../engine/yew_frontend", features = ["audio"] }
yew_icons = { version = "0.7", features = [
"BootstrapExclamationTriangleFill",
"FontAwesomeSolidLocationCrosshairs",
Expand Down
2 changes: 1 addition & 1 deletion common/src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use serde::{Deserialize, Serialize};

pub use diff::Diff;

#[derive(Clone, Encode, Decode)]
#[derive(Clone, Debug, Encode, Decode)]
pub enum Command {
Alliance {
with: PlayerId,
Expand Down
5 changes: 4 additions & 1 deletion engine/core_protocol/src/plasma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,10 @@ pub enum PlasmaRequestV1 {
#[cfg_attr(feature = "server", rtype(result = "()"))]
pub enum PlasmaUpdate {
/// Version 1 protocol.
V1(Box<[PlasmaUpdateV1]>),
V1(
#[serde(deserialize_with = "crate::serde_util::box_slice_skip_invalid")]
Box<[PlasmaUpdateV1]>,
),
}

#[derive(Clone, Debug, Serialize, Deserialize)]
Expand Down
41 changes: 41 additions & 0 deletions engine/core_protocol/src/serde_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use serde::de::Visitor;
use serde::{de, Deserialize, Deserializer};
use std::fmt;
use std::marker::PhantomData;

pub fn is_default<T: Default + PartialEq>(x: &T) -> bool {
x == &T::default()
Expand Down Expand Up @@ -168,3 +169,43 @@ impl<'de> Visitor<'de> for StrVisitor {
Ok(String::from(value))
}
}

pub fn box_slice_skip_invalid<'de, T: Deserialize<'de>, D>(
deserializer: D,
) -> Result<Box<[T]>, D::Error>
where
D: Deserializer<'de>,
{
#[derive(serde::Deserialize)]
#[serde(untagged, bound(deserialize = "T: Deserialize<'de>"))]
enum Item<T> {
Valid(T),
Skip(serde::de::IgnoredAny),
}

struct SeqVisitor<T>(PhantomData<T>);

impl<'de, T: Deserialize<'de>> serde::de::Visitor<'de> for SeqVisitor<T> {
type Value = Box<[T]>;

fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter.write_str("a sequence")
}

fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'de>,
{
let mut values = Vec::with_capacity(seq.size_hint().unwrap_or_default().min(32));
while let Some(value) = seq.next_element()? {
if let Item::<T>::Valid(value) = value {
values.push(value);
}
}
Ok(values.into_boxed_slice())
}
}

let visitor = SeqVisitor::<T>(PhantomData);
deserializer.deserialize_seq(visitor)
}
2 changes: 1 addition & 1 deletion engine/game_server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "game_server"
workspace = ".."
version = "0.1.0"
edition = "2018"
edition = "2021"
authors = ["Softbear, Inc."]
license = "AGPL-3.0-or-later"

Expand Down
7 changes: 4 additions & 3 deletions engine/game_server/src/bot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ impl<G: GameArenaService> BotData<G> {
Self {
bot: G::Bot::default(),
player_tuple: Arc::new(player_tuple),
action_buffer: BotAction::None,
action_buffer: BotAction::default(),
}
}
}
Expand Down Expand Up @@ -72,7 +72,8 @@ impl<G: GameArenaService> BotRepo<G> {
update,
bot_data.player_tuple.player.borrow().player_id,
players,
)
);
//println!("{:?}", bot_data.action_buffer);
});
}

Expand All @@ -83,7 +84,7 @@ impl<G: GameArenaService> BotRepo<G> {
BotAction::Some(command) => {
let _ = service.player_command(command, &bot_data.player_tuple, players);
}
BotAction::None => {}
BotAction::None(_) => {}
BotAction::Quit => {
// Recycle.
service.player_left(&bot_data.player_tuple, players);
Expand Down
6 changes: 4 additions & 2 deletions engine/game_server/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ impl<G: GameArenaService> ClientRepo<G> {
let player_tuple = match players.get(player_id) {
Some(player_tuple) => player_tuple,
None => {
debug_assert!(false, "client gone in register");
debug_assert!(false, "client {player_id:?} gone in register");
return;
}
};
Expand Down Expand Up @@ -972,6 +972,7 @@ impl<G: GameArenaService> Handler<ObserverMessage<Request<G::GameRequest>, Updat
_ctx: &mut Self::Context,
) {
let Some(context_service) = self.arenas.get_mut(msg.realm_name) else {
error!("missing realm {:?}", msg.realm_name);
match msg.body {
ObserverMessageBody::Register { observer, .. } => {
let _ = observer.send(ObserverUpdate::Close);
Expand All @@ -995,7 +996,7 @@ impl<G: GameArenaService> Handler<ObserverMessage<Request<G::GameRequest>, Updat
#[cfg(feature = "teams")]
&mut context_service.context.teams,
&context_service.context.chat,
&self.leaderboard,
&context_service.context.leaderboard,
&context_service.context.liveboard,
&mut self.metrics,
&self.system,
Expand Down Expand Up @@ -1103,6 +1104,7 @@ impl<G: GameArenaService> Handler<Authenticate> for Infrastructure<G> {

let realm_name = msg.realm_name;
let Some(context_service) = self.arenas.get_mut(realm_name) else {
log::warn!("no arena {realm_name:?}");
return Err("no such arena");
};
let arena_token = context_service.context.token;
Expand Down
4 changes: 3 additions & 1 deletion engine/game_server/src/context.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// SPDX-FileCopyrightText: 2021 Softbear, Inc.
// SPDX-License-Identifier: AGPL-3.0-or-later

use crate::bot::BotRepo;
use crate::chat::ChatRepo;
use crate::game_service::GameArenaService;
use crate::liveboard::LiveboardRepo;
use crate::player::PlayerRepo;
#[cfg(feature = "teams")]
use crate::team::TeamRepo;
use crate::{bot::BotRepo, leaderboard::LeaderboardRepo};
use core_protocol::ArenaToken;
use rand::{thread_rng, Rng};

Expand All @@ -20,6 +20,7 @@ pub struct Context<G: GameArenaService> {
#[cfg(feature = "teams")]
pub teams: TeamRepo<G>,
pub(crate) liveboard: LiveboardRepo<G>,
pub(crate) leaderboard: LeaderboardRepo<G>,
}

impl<G: GameArenaService> Context<G> {
Expand All @@ -32,6 +33,7 @@ impl<G: GameArenaService> Context<G> {
teams: TeamRepo::default(),
chat: ChatRepo::new(chat_log),
liveboard: LiveboardRepo::default(),
leaderboard: LeaderboardRepo::default(),
}
}
}
10 changes: 6 additions & 4 deletions engine/game_server/src/context_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use crate::client::ClientRepo;
use crate::context::Context;
use crate::game_service::GameArenaService;
use crate::invitation::InvitationRepo;
use crate::leaderboard::LeaderboardRepo;
use crate::metric::MetricRepo;
use crate::plasma::PlasmaClient;
use core_protocol::dto::ServerDto;
Expand Down Expand Up @@ -39,7 +38,6 @@ impl<G: GameArenaService> ContextService<G> {
pub(crate) fn update(
&mut self,
clients: &mut ClientRepo<G>,
leaderboard: &mut LeaderboardRepo<G>,
invitations: &mut InvitationRepo<G>,
metrics: &mut MetricRepo<G>,
server_delta: &Option<(Arc<[ServerDto]>, Arc<[ServerNumber]>)>,
Expand Down Expand Up @@ -78,18 +76,22 @@ impl<G: GameArenaService> ContextService<G> {
#[cfg(feature = "teams")]
&mut self.context.teams,
&mut self.context.liveboard,
leaderboard,
&self.context.leaderboard,
server_delta,
);
self.context
.bots
.update(&self.service, &self.context.players);

leaderboard.process(&self.context.liveboard, &self.context.players);
self.context
.leaderboard
.process(&self.context.liveboard, &self.context.players);

// Post-update game logic.
self.service.post_update(&mut self.context);

self.context.leaderboard.clear_deltas();

// Bot commands/joining/leaving, postponed because no commands should be issued between
// `GameService::tick` and `GameService::post_update`.
self.context
Expand Down
Loading

0 comments on commit 391bac1

Please sign in to comment.