Skip to content

Commit

Permalink
Add support for custom GDPSes
Browse files Browse the repository at this point in the history
dash-rs now supports overwriting the endpoint to which requests are made
by updating the GD_SERVER_ENDPOINT_BASE_URL global static at the
beginning of program execution. Should thi static not explicitly be set
it will default to the boomlings servers.

Co-Authored-By:  stadust <[email protected]>
Signed-off-by: stadust <[email protected]>
  • Loading branch information
LG125YT and stadust committed Jan 13, 2025
1 parent 69dea86 commit ee5919e
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 24 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@

The project is a collaboration with [mgostIH](https://github.com/mgostIH), on whose idea the initial library design is based on and who continues to provide incredibly helpful insights into optimization, Geometry Dash and Rust.

## Using With a Custom GDPS
If you are planning to use this library to interact with a GDPS, you can use:

```rust
use dash_rs::request::GD_SERVER_ENDPOINT_BASE_URL;

GD_SERVER_ENDPOINT_BASE_URL.get_or_init(|| "https://your-custom-gdps-url.com".to_string());
```

Insert this anywhere before the first call to any `dash-rs` function.

## Goals

The goals for dash-rs are, in order:
Expand Down
6 changes: 3 additions & 3 deletions src/request/comment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use crate::{
model::level::Level,
request::{BaseRequest, GD_22, REQUEST_BASE_URL},
request::{BaseRequest, GD_22, endpoint_base_url},
};
use serde::Serialize;

Expand Down Expand Up @@ -84,7 +84,7 @@ impl<'a> LevelCommentsRequest<'a> {
const_setter!(page: u32);

pub fn to_url(&self) -> String {
format!("{}{}", REQUEST_BASE_URL, LEVEL_COMMENTS_ENDPOINT)
format!("{}{}", endpoint_base_url(), LEVEL_COMMENTS_ENDPOINT)
}

pub const fn new(level: u64) -> Self {
Expand Down Expand Up @@ -164,7 +164,7 @@ impl<'a> ProfileCommentsRequest<'a> {
const_setter!(account_id: u64);

pub fn to_url(&self) -> String {
format!("{}{}", REQUEST_BASE_URL, PROFILE_COMMENT_ENDPOINT)
format!("{}{}", endpoint_base_url(), PROFILE_COMMENT_ENDPOINT)
}

pub const fn new(account: u64) -> Self {
Expand Down
6 changes: 3 additions & 3 deletions src/request/level.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
level::{DemonRating, LevelLength, LevelRating},
song::MainSong,
},
request::{BaseRequest, GD_22, REQUEST_BASE_URL},
request::{BaseRequest, GD_22, endpoint_base_url},
};
use serde::{Deserialize, Serialize, Serializer};

Expand Down Expand Up @@ -85,7 +85,7 @@ impl<'a> LevelRequest<'a> {
}

pub fn to_url(&self) -> String {
format!("{}{}", REQUEST_BASE_URL, DOWNLOAD_LEVEL_ENDPOINT)
format!("{}{}", endpoint_base_url(), DOWNLOAD_LEVEL_ENDPOINT)
}
}

Expand Down Expand Up @@ -536,7 +536,7 @@ impl<'a> LevelsRequest<'a> {
const_setter!(request_type: LevelRequestType);

pub fn to_url(&self) -> String {
format!("{}{}", REQUEST_BASE_URL, SEARCH_LEVEL_ENDPOINT)
format!("{}{}", endpoint_base_url(), SEARCH_LEVEL_ENDPOINT)
}

pub fn with_base(base: BaseRequest<'a>) -> Self {
Expand Down
41 changes: 26 additions & 15 deletions src/request/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
//! Module containing all structs modelling requests to the boomlings APIs.
//! Module containing all structs modelling requests to the Boomlings APIs.
//!
//! These directly implement (de)serialization into RobTop's data format, unlike models where
//! RobTop's eccentricities are hidden. This is since directly re-using these structs outside of
//! making/proxying requests for the boomlings servers seems rather useless to me, as they already
//! contain a lot of boomlings-specific fields.
//! making/proxying requests for the Boomlings servers seems rather useless to me, as they already
//! contain a lot of Boomlings-specific fields.
//! This can also be edited for a specific GDPS, e.g 1.9 GDPS. (hi absowute :3)
use std::sync::OnceLock;

use crate::{model::GameVersion, serde::RequestSerializer};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -44,7 +47,13 @@ pub mod comment;
pub mod level;
pub mod user;

pub const REQUEST_BASE_URL: &str = "https://www.boomlings.com/database/";
pub static GD_SERVER_ENDPOINT_BASE_URL: OnceLock<&'static str> = OnceLock::new();

pub fn endpoint_base_url() -> &'static str {
GD_SERVER_ENDPOINT_BASE_URL.get_or_init(|| BOOMLINGS_ENDPOINTS_BASE)
}

pub const BOOMLINGS_ENDPOINTS_BASE: &str = "https://www.boomlings.com/database/";

/// A `BaseRequest` instance that has all its fields set to the
/// same values a Geometry Dash 2.1 client would use
Expand All @@ -65,41 +74,41 @@ pub const GD_22: BaseRequest = BaseRequest::new(
/// Base data included in every request made
///
/// The fields in this struct are only relevant when making a request to the
/// `boomlings` servers. When using GDCF with a custom Geometry Dash API, they
/// `Boomlings` servers. When using GDCF with a custom Geometry Dash API, they
/// can safely be ignored.
#[derive(Debug, Clone, Hash, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct BaseRequest<'a> {
/// The version of the game client we're pretending to be
///
/// ## GD Internals:
/// This field is called `gameVersion` in the boomlings API and needs to be
/// converted to a string response
/// This field is called `gameVersion` in the Boomlings API and needs to
/// be converted to a string response.
/// The value of this field doesn't matter, and the request will succeed
/// regardless of what it's been set to
/// regardless of what it's been set to.
#[serde(rename = "gameVersion")]
pub game_version: GameVersion,

/// Internal version of the game client we're pretending to be
///
/// ## GD Internals:
/// This field is called `binaryVersion` in the boomlings API and needs to
/// be converted to a string
/// This field is called `binaryVersion` in the Boomlings API and needs to
/// be converted to a string.
///
/// The value of this field doesn't matter, and the request will succeed
/// regardless of what it's been set to
/// regardless of what it's been set to.
#[serde(rename = "binaryVersion")]
pub binary_version: GameVersion,

/// The current secret String the server uses to identify valid clients.
/// The current secret string the server uses to identify valid clients.
///
/// ## GD Internals:
/// Settings this field to an incorrect value will cause the request to fail
/// Setting this field to an incorrect value will cause the request to fail.
pub secret: &'a str,
}

impl BaseRequest<'_> {
/// Constructs a new `BaseRequest` with the given values.
pub const fn new(game_version: GameVersion, binary_version: GameVersion, secret: &'static str) -> BaseRequest<'_> {
/// This constructs a new BaseRequest. It also uses the given values. :3
pub const fn new(game_version: GameVersion, binary_version: GameVersion, secret: &'static str) -> BaseRequest<'static> {
BaseRequest {
game_version,
binary_version,
Expand All @@ -122,3 +131,5 @@ pub(crate) fn to_string<S: Serialize>(request: S) -> String {

String::from_utf8(output).unwrap()
}


6 changes: 3 additions & 3 deletions src/request/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use crate::{
model::creator::Creator,
request::{BaseRequest, GD_22, REQUEST_BASE_URL},
request::{BaseRequest, GD_22, endpoint_base_url},
};
use serde::Serialize;

Expand Down Expand Up @@ -35,7 +35,7 @@ impl UserRequest<'_> {
}

pub fn to_url(&self) -> String {
format!("{}{}", REQUEST_BASE_URL, GET_USER_ENDPOINT)
format!("{}{}", endpoint_base_url(), GET_USER_ENDPOINT)
}
}

Expand Down Expand Up @@ -98,7 +98,7 @@ impl<'a> UserSearchRequest<'a> {
}

pub fn to_url(&self) -> String {
format!("{}{}", REQUEST_BASE_URL, SEARCH_USER_ENDPOINT)
format!("{}{}", endpoint_base_url(), SEARCH_USER_ENDPOINT)
}
}

Expand Down

0 comments on commit ee5919e

Please sign in to comment.