Compare commits
9 Commits
b3c1e37fa4
...
577726f3bd
Author | SHA1 | Date |
---|---|---|
kozabrada123 | 577726f3bd | |
kozabrada123 | eeb3b4a304 | |
Flori | 85e494dd4a | |
Flori | d3853700c0 | |
bitfl0wer | 59b6907481 | |
bitfl0wer | f7d31fe57b | |
Flori | dcc626ef10 | |
Flori | 7a517b3663 | |
bitfl0wer | fd3aad03e3 |
|
@ -209,7 +209,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chorus"
|
name = "chorus"
|
||||||
version = "0.13.0"
|
version = "0.14.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"base64 0.21.7",
|
"base64 0.21.7",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
[package]
|
[package]
|
||||||
name = "chorus"
|
name = "chorus"
|
||||||
description = "A library for interacting with multiple Spacebar-compatible Instances at once."
|
description = "A library for interacting with multiple Spacebar-compatible Instances at once."
|
||||||
version = "0.13.0"
|
version = "0.14.0"
|
||||||
license = "AGPL-3.0"
|
license = "AGPL-3.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
repository = "https://github.com/polyphony-chat/chorus"
|
repository = "https://github.com/polyphony-chat/chorus"
|
||||||
|
|
|
@ -44,7 +44,7 @@ To get started with Chorus, import it into your project by adding the following
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[dependencies]
|
[dependencies]
|
||||||
chorus = "0.13.0"
|
chorus = "0.14.0"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Establishing a Connection
|
### Establishing a Connection
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
use chorus::instance::Instance;
|
use chorus::instance::Instance;
|
||||||
use chorus::UrlBundle;
|
|
||||||
|
|
||||||
#[tokio::main(flavor = "current_thread")]
|
#[tokio::main(flavor = "current_thread")]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let bundle = UrlBundle::new(
|
let instance = Instance::new("https://example.com/")
|
||||||
"https://example.com/api".to_string(),
|
|
||||||
"wss://example.com/".to_string(),
|
|
||||||
"https://example.com/cdn".to_string(),
|
|
||||||
);
|
|
||||||
let instance = Instance::new(bundle)
|
|
||||||
.await
|
.await
|
||||||
.expect("Failed to connect to the Spacebar server");
|
.expect("Failed to connect to the Spacebar server");
|
||||||
dbg!(instance.instance_info);
|
dbg!(instance.instance_info);
|
||||||
|
|
|
@ -1,15 +1,9 @@
|
||||||
use chorus::instance::Instance;
|
use chorus::instance::Instance;
|
||||||
use chorus::types::LoginSchema;
|
use chorus::types::LoginSchema;
|
||||||
use chorus::UrlBundle;
|
|
||||||
|
|
||||||
#[tokio::main(flavor = "current_thread")]
|
#[tokio::main(flavor = "current_thread")]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let bundle = UrlBundle::new(
|
let mut instance = Instance::new("https://example.com/")
|
||||||
"https://example.com/api".to_string(),
|
|
||||||
"wss://example.com/".to_string(),
|
|
||||||
"https://example.com/cdn".to_string(),
|
|
||||||
);
|
|
||||||
let mut instance = Instance::new(bundle)
|
|
||||||
.await
|
.await
|
||||||
.expect("Failed to connect to the Spacebar server");
|
.expect("Failed to connect to the Spacebar server");
|
||||||
// Assume, you already have an account created on this instance. Registering an account works
|
// Assume, you already have an account created on this instance. Registering an account works
|
||||||
|
|
|
@ -73,7 +73,7 @@ impl PartialEq for LimitsInformation {
|
||||||
|
|
||||||
impl Instance {
|
impl Instance {
|
||||||
/// Creates a new [`Instance`] from the [relevant instance urls](UrlBundle). To create an Instance from one singular url, use [`Instance::from_root_url()`].
|
/// Creates a new [`Instance`] from the [relevant instance urls](UrlBundle). To create an Instance from one singular url, use [`Instance::from_root_url()`].
|
||||||
pub async fn new(urls: UrlBundle) -> ChorusResult<Instance> {
|
async fn from_url_bundle(urls: UrlBundle) -> ChorusResult<Instance> {
|
||||||
let is_limited: Option<LimitsConfiguration> = Instance::is_limited(&urls.api).await?;
|
let is_limited: Option<LimitsConfiguration> = Instance::is_limited(&urls.api).await?;
|
||||||
let limit_information;
|
let limit_information;
|
||||||
|
|
||||||
|
@ -114,9 +114,9 @@ impl Instance {
|
||||||
/// Shorthand for `Instance::new(UrlBundle::from_root_domain(root_domain).await?)`.
|
/// Shorthand for `Instance::new(UrlBundle::from_root_domain(root_domain).await?)`.
|
||||||
///
|
///
|
||||||
/// If `limited` is `true`, then Chorus will track and enforce rate limits for this instance.
|
/// If `limited` is `true`, then Chorus will track and enforce rate limits for this instance.
|
||||||
pub async fn from_root_url(root_url: &str) -> ChorusResult<Instance> {
|
pub async fn new(root_url: &str) -> ChorusResult<Instance> {
|
||||||
let urls = UrlBundle::from_root_url(root_url).await?;
|
let urls = UrlBundle::from_root_url(root_url).await?;
|
||||||
Instance::new(urls).await
|
Instance::from_url_bundle(urls).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn is_limited(api_url: &str) -> ChorusResult<Option<LimitsConfiguration>> {
|
pub async fn is_limited(api_url: &str) -> ChorusResult<Option<LimitsConfiguration>> {
|
||||||
|
|
16
src/lib.rs
16
src/lib.rs
|
@ -140,6 +140,12 @@ pub mod voice;
|
||||||
/// # Notes
|
/// # Notes
|
||||||
/// All the urls can be found on the /api/policies/instance/domains endpoint of a spacebar server
|
/// All the urls can be found on the /api/policies/instance/domains endpoint of a spacebar server
|
||||||
pub struct UrlBundle {
|
pub struct UrlBundle {
|
||||||
|
/// The root url of an Instance. Usually, this would be the url where `.well-known/spacebar` can
|
||||||
|
/// be located under. If the instance you are connecting to for some reason does not have a
|
||||||
|
/// `.well-known` set up (for example, if it is a local/testing instance), you can use the api
|
||||||
|
/// url as a substitute.
|
||||||
|
/// Ex: `https://spacebar.chat`
|
||||||
|
pub root: String,
|
||||||
/// The api's url.
|
/// The api's url.
|
||||||
/// Ex: `https://old.server.spacebar.chat/api`
|
/// Ex: `https://old.server.spacebar.chat/api`
|
||||||
pub api: String,
|
pub api: String,
|
||||||
|
@ -154,8 +160,9 @@ pub struct UrlBundle {
|
||||||
|
|
||||||
impl UrlBundle {
|
impl UrlBundle {
|
||||||
/// Creates a new UrlBundle from the relevant urls.
|
/// Creates a new UrlBundle from the relevant urls.
|
||||||
pub fn new(api: String, wss: String, cdn: String) -> Self {
|
pub fn new(root: String, api: String, wss: String, cdn: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
root: UrlBundle::parse_url(root),
|
||||||
api: UrlBundle::parse_url(api),
|
api: UrlBundle::parse_url(api),
|
||||||
wss: UrlBundle::parse_url(wss),
|
wss: UrlBundle::parse_url(wss),
|
||||||
cdn: UrlBundle::parse_url(cdn),
|
cdn: UrlBundle::parse_url(cdn),
|
||||||
|
@ -240,7 +247,12 @@ impl UrlBundle {
|
||||||
.json::<types::types::domains_configuration::Domains>()
|
.json::<types::types::domains_configuration::Domains>()
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(UrlBundle::new(body.api_endpoint, body.gateway, body.cdn))
|
Ok(UrlBundle::new(
|
||||||
|
url.to_string(),
|
||||||
|
body.api_endpoint,
|
||||||
|
body.gateway,
|
||||||
|
body.cdn,
|
||||||
|
))
|
||||||
} else {
|
} else {
|
||||||
Err(ChorusError::RequestFailed {
|
Err(ChorusError::RequestFailed {
|
||||||
url: url.to_string(),
|
url: url.to_string(),
|
||||||
|
|
|
@ -39,10 +39,9 @@ pub enum VoiceProtocol {
|
||||||
///
|
///
|
||||||
/// See <https://discord-userdoccers.vercel.app/topics/voice-connections#protocol-data-structure>
|
/// See <https://discord-userdoccers.vercel.app/topics/voice-connections#protocol-data-structure>
|
||||||
pub struct SelectProtocolData {
|
pub struct SelectProtocolData {
|
||||||
/// Our external ip
|
/// Our external ip we got from ip discovery
|
||||||
// FIXME: This is a string
|
pub address: String,
|
||||||
pub address: Vec<u8>,
|
/// Our external udp port we got from id discovery
|
||||||
/// Our external udp port
|
|
||||||
pub port: u16,
|
pub port: u16,
|
||||||
/// The mode of encryption to use
|
/// The mode of encryption to use
|
||||||
pub mode: VoiceEncryptionMode,
|
pub mode: VoiceEncryptionMode,
|
||||||
|
|
|
@ -111,6 +111,8 @@ impl Observer<VoiceReady> for VoiceHandler {
|
||||||
|
|
||||||
*self.voice_udp_connection.lock().await = Some(udp_handle.clone());
|
*self.voice_udp_connection.lock().await = Some(udp_handle.clone());
|
||||||
|
|
||||||
|
let string_ip_address = String::from_utf8(ip_discovery.address).expect("Ip discovery gave non string ip");
|
||||||
|
|
||||||
self.voice_gateway_connection
|
self.voice_gateway_connection
|
||||||
.lock()
|
.lock()
|
||||||
.await
|
.await
|
||||||
|
@ -119,7 +121,7 @@ impl Observer<VoiceReady> for VoiceHandler {
|
||||||
.send_select_protocol(SelectProtocol {
|
.send_select_protocol(SelectProtocol {
|
||||||
protocol: VoiceProtocol::Udp,
|
protocol: VoiceProtocol::Udp,
|
||||||
data: SelectProtocolData {
|
data: SelectProtocolData {
|
||||||
address: ip_discovery.address,
|
address: string_ip_address,
|
||||||
port: ip_discovery.port,
|
port: ip_discovery.port,
|
||||||
mode: VoiceEncryptionMode::Xsalsa20Poly1305,
|
mode: VoiceEncryptionMode::Xsalsa20Poly1305,
|
||||||
},
|
},
|
||||||
|
|
|
@ -52,12 +52,7 @@ impl TestBundle {
|
||||||
|
|
||||||
// Set up a test by creating an Instance and a User. Reduces Test boilerplate.
|
// Set up a test by creating an Instance and a User. Reduces Test boilerplate.
|
||||||
pub(crate) async fn setup() -> TestBundle {
|
pub(crate) async fn setup() -> TestBundle {
|
||||||
let urls = UrlBundle::new(
|
let instance = Instance::new("http://localhost:3001/api").await.unwrap();
|
||||||
"http://localhost:3001/api".to_string(),
|
|
||||||
"ws://localhost:3001".to_string(),
|
|
||||||
"http://localhost:3001".to_string(),
|
|
||||||
);
|
|
||||||
let instance = Instance::new(urls.clone()).await.unwrap();
|
|
||||||
// Requires the existance of the below user.
|
// Requires the existance of the below user.
|
||||||
let reg = RegisterSchema {
|
let reg = RegisterSchema {
|
||||||
username: "integrationtestuser".into(),
|
username: "integrationtestuser".into(),
|
||||||
|
@ -114,6 +109,12 @@ pub(crate) async fn setup() -> TestBundle {
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
let urls = UrlBundle::new(
|
||||||
|
"http://localhost:3001/api".to_string(),
|
||||||
|
"http://localhost:3001/api".to_string(),
|
||||||
|
"ws://localhost:3001".to_string(),
|
||||||
|
"http://localhost:3001".to_string(),
|
||||||
|
);
|
||||||
TestBundle {
|
TestBundle {
|
||||||
urls,
|
urls,
|
||||||
user,
|
user,
|
||||||
|
|
Loading…
Reference in New Issue