Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **API** Move generated client APIs to sdks/
- Lower long poll timeout from 60s -> 40s
- **Bolt** Moved additional project roots to Bolt.toml
- **types** Support multiple project roots for reusing Protobuf types

### Security

Expand Down
83 changes: 48 additions & 35 deletions lib/types/build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,38 +18,44 @@ pub fn compile_with_base<F>(base_builder: F) -> io::Result<()>
where
F: Fn() -> io::Result<schemac::CompileOpts>,
{
let project_root = seek_project_root()?;
let project_roots = seek_project_roots()?;
let main_project_root = &project_roots[0];
let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());

// Add rereun statement
let mut input_paths = Vec::new();

// Add common proto from root of project
//
// This will be symlinked if there are multiple roots
println!(
"cargo:rerun-if-changed={}",
project_root.join("proto").display()
main_project_root.join("proto").display()
);

let mut paths = if project_root.join("proto").is_dir() {
find_all_proto(&project_root.join("proto"))?
} else {
Vec::new()
if main_project_root.join("proto").is_dir() {
let paths = find_all_proto(&main_project_root.join("proto"))?;
input_paths.extend(paths);
};

// Find all proto files
for entry in fs::read_dir(project_root.join("svc").join("pkg"))? {
let entry = entry?;
let proto_path = entry.path().join("types");
// Add protos from all services
for project_root in &project_roots {
for entry in fs::read_dir(project_root.join("svc").join("pkg"))? {
let entry = entry?;
let proto_path = entry.path().join("types");

if proto_path.is_dir() {
println!("cargo:rerun-if-changed={}", proto_path.display());
if proto_path.is_dir() {
println!("cargo:rerun-if-changed={}", proto_path.display());

paths.append(&mut find_all_proto(&proto_path)?);
let paths = find_all_proto(&proto_path)?;
input_paths.extend(paths);
}
}
}

let paths = paths.iter().map(std::ops::Deref::deref).collect::<Vec<_>>();

// Compile
let input_paths = input_paths.iter().map(|x| x.as_path()).collect::<Vec<_>>();
compile_proto_input(
base_builder()?,
paths.as_slice(),
input_paths.as_slice(),
&out_dir.join("schema.rs"),
)?;

Expand Down Expand Up @@ -78,21 +84,19 @@ pub fn compile_proto_input(
Ok(())
}

fn update_compile_opts(base: schemac::CompileOpts) -> io::Result<schemac::CompileOpts> {
let project_root = seek_project_root()?;
fn update_compile_opts(mut base: schemac::CompileOpts) -> io::Result<schemac::CompileOpts> {
let project_roots = seek_project_roots()?;

Ok(base
.root(&project_root)
base = base
.root(&project_roots[0])
.plugin(Box::new(plugins::CommonPlugin::default()))
// .plugin(Box::new(plugins::BackendServicePlugin {
// project_root: project_root.clone(),
// }))
.plugin(Box::new(plugins::BackendMessagePlugin {
project_root: project_root.clone(),
})))
.plugin(Box::new(plugins::BackendMessagePlugin::default()));

Ok(base)
}

fn seek_project_root() -> io::Result<PathBuf> {
fn seek_project_roots() -> io::Result<Vec<PathBuf>> {
// Find project root
let mut project_root = std::env::current_dir()?;
loop {
if project_root.join("Bolt.toml").exists() {
Expand All @@ -104,7 +108,18 @@ fn seek_project_root() -> io::Result<PathBuf> {
panic!("could not find project root");
}
}
Ok(project_root)

// Read project roots
let bolt_toml = fs::read_to_string(project_root.join("Bolt.toml"))?;
let project_config = bolt_config::project::decode(&bolt_toml)
.map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?;

let mut roots = vec![project_root.clone()];
for (_, additional_root) in project_config.additional_roots.iter() {
roots.push(project_root.join(&additional_root.path));
}

Ok(roots)
}

fn find_all_proto(path: &Path) -> io::Result<Vec<PathBuf>> {
Expand All @@ -131,7 +146,7 @@ fn find_all_proto(path: &Path) -> io::Result<Vec<PathBuf>> {
}

mod plugins {
use std::{io, path::PathBuf};
use std::io;

use indoc::{formatdoc, indoc};
use regex::Regex;
Expand Down Expand Up @@ -199,10 +214,8 @@ mod plugins {
}
}

#[derive(Debug)]
pub struct BackendMessagePlugin {
pub project_root: PathBuf,
}
#[derive(Debug, Default)]
pub struct BackendMessagePlugin;

impl schemac::CompilePlugin for BackendMessagePlugin {
fn module_pass(
Expand Down
2 changes: 2 additions & 0 deletions lib/util/env/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ license = "Apache-2.0"

[dependencies]
lazy_static = "1.4"
serde = { version = "1.0.193", features = ["derive"] }
serde_json = "1.0.109"
17 changes: 12 additions & 5 deletions lib/util/env/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
use serde::Deserialize;
use std::collections::HashMap;

/// Reads a secret from the env.
///
/// This is marked as async so we have the flexibility to pull the secret from remote datasources.
Expand Down Expand Up @@ -72,10 +75,9 @@ lazy_static::lazy_static! {
static ref ORIGIN_HUB: Option<String> = std::env::var("RIVET_ORIGIN_HUB").ok();
static ref DNS_PROVIDER: Option<String> = std::env::var("RIVET_DNS_PROVIDER").ok();
static ref CHIRP_SERVICE_NAME: Option<String> = std::env::var("CHIRP_SERVICE_NAME").ok();
static ref IS_BILLING_ENABLED: bool = std::env::var("IS_BILLING_ENABLED")
static ref BILLING: Option<RivetBilling> = std::env::var("RIVET_BILLING")
.ok()
.map(|s| s == "1")
.unwrap_or_default();
.map(|x| serde_json::from_str(&x).expect("failed to parse billing"));
}

pub fn region() -> &'static str {
Expand Down Expand Up @@ -169,8 +171,13 @@ pub fn chirp_service_name() -> &'static str {
}
}

pub fn is_billing_enabled() -> bool {
*IS_BILLING_ENABLED
#[derive(Deserialize)]
pub struct RivetBilling {
pub region_price_ids: HashMap<String, String>,
}

pub fn billing() -> Option<&'static RivetBilling> {
BILLING.as_ref()
}

/// The current stripe API token.
Expand Down
15 changes: 15 additions & 0 deletions proto/backend/faker.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
syntax = "proto3";

package rivet.backend.faker;

import "proto/common.proto";
import "google/protobuf/empty.proto";

enum Image {
FAIL_IMMEDIATELY = 0;
HANG_INDEFINITELY = 1;
MM_LOBBY_AUTO_READY = 2;
MM_LOBBY_ECHO = 3;
MM_PLAYER_CONNECT = 4;
}

18 changes: 18 additions & 0 deletions proto/backend/job.proto
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,24 @@ message ProxiedPort {
SslDomainMode ssl_domain_mode = 5;
}

// Used to create a propxied port
//
// See ProxiedPort.
message ProxiedPortConfig {
reserved 1;

/// Label of the Nomad port to connect to.
optional string target_nomad_port_label = 6;

// Port to listen on on the load balancer. If not provided, a port will be
// automatically chosen from the port allocator.
optional uint32 ingress_port = 2;

repeated string ingress_hostnames = 3;
ProxyProtocol proxy_protocol = 4;
SslDomainMode ssl_domain_mode = 5;
}

// Protocol that this proxied port uses.
enum ProxyProtocol {
HTTP = 0;
Expand Down
30 changes: 30 additions & 0 deletions proto/backend/matchmaker/lobby_find.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
syntax = "proto3";

package rivet.backend.matchmaker.lobby_find;

enum ErrorCode {
UNKNOWN = 0;

STALE_MESSAGE = 1;

TOO_MANY_PLAYERS_FROM_SOURCE = 101;

LOBBY_STOPPED = 201;
LOBBY_CLOSED = 202;
LOBBY_NOT_FOUND = 203;
NO_AVAILABLE_LOBBIES = 204;
LOBBY_FULL = 205;
LOBBY_COUNT_OVER_MAX = 206;
REGION_NOT_ENABLED = 207;
LOBBY_STOPPED_PREMATURELY = 208;

DEV_TEAM_INVALID_STATUS = 301;

FIND_DISABLED = 401;
JOIN_DISABLED = 402;
VERIFICATION_FAILED = 403;
VERIFICATION_REQUEST_FAILED = 404;
IDENTITY_REQUIRED = 405;
REGISTRATION_REQUIRED = 406;
}

50 changes: 8 additions & 42 deletions svc/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions svc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,6 @@ members = [
"pkg/region/ops/resolve",
"pkg/team-dev/ops/game-list",
"pkg/team-dev/ops/get",
"pkg/team-dev/ops/halt",
"pkg/team-dev/standalone/halt-collect",
"pkg/team-dev/worker",
"pkg/team-invite/ops/get",
"pkg/team-invite/worker",
Expand Down
2 changes: 1 addition & 1 deletion svc/api/identity/tests/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ impl Ctx {

let build_res = op!([ctx] faker_build {
game_id: game_res.game_id,
image: faker::build::Image::MmLobbyAutoReady as i32,
image: backend::faker::Image::MmLobbyAutoReady as i32,
})
.await
.unwrap();
Expand Down
2 changes: 1 addition & 1 deletion svc/api/kv/tests/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ impl Ctx {

let build_res = op!([ctx] faker_build {
game_id: game_res.game_id,
image: faker::build::Image::MmLobbyAutoReady as i32,
image: backend::faker::Image::MmLobbyAutoReady as i32,
})
.await
.unwrap();
Expand Down
4 changes: 2 additions & 2 deletions svc/api/matchmaker/src/route/lobbies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1029,11 +1029,11 @@ async fn find_inner(
})
.await?;
let lobby_id = match find_res
.map_err(|msg| mm::msg::lobby_find_fail::ErrorCode::from_i32(msg.error_code))
.map_err(|msg| backend::matchmaker::lobby_find::ErrorCode::from_i32(msg.error_code))
{
Ok(res) => unwrap_ref!(res.lobby_id).as_uuid(),
Err(Some(code)) => {
use mm::msg::lobby_find_fail::ErrorCode::*;
use backend::matchmaker::lobby_find::ErrorCode::*;

match code {
Unknown => bail!("unknown find error code"),
Expand Down
Loading