Skip to content

Commit

Permalink
matchmaking servers conflicts resolve
Browse files Browse the repository at this point in the history
  • Loading branch information
ymo-4 committed Jul 25, 2024
2 parents 275db01 + 260e66d commit 7848fab
Show file tree
Hide file tree
Showing 89 changed files with 68,470 additions and 41,915 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
strategy:
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
toolchain: [stable, nightly]
toolchain: [stable, nightly, "1.71.1"]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
Expand Down
60 changes: 60 additions & 0 deletions .github/workflows/rebuild-bindings.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Rebuild bindings

on: workflow_dispatch

env:
CARGO_TERM_COLOR: always

jobs:
build:
strategy:
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v2

- uses: actions-rs/toolchain@v1
id: toolchain
with:
toolchain: stable
profile: minimal
components: rustfmt, clippy
override: true

- name: Install alsa and udev
run: sudo apt-get update; sudo apt-get install --no-install-recommends libasound2-dev libudev-dev
if: runner.os == 'linux'

- name: Setup cache
uses: actions/cache@v2
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-test-rustc-${{ steps.toolchain.outputs.rustc_hash }}-${{ hashFiles('**/Cargo.lock') }}

- run: cargo build --features "rebuild-bindings"
working-directory: steamworks-sys
env:
STEAM_SDK_LOCATION: ./lib/steam

- uses: actions/upload-artifact@v4
with:
name: artifact-linux-bindings
path: steamworks-sys/src/linux_bindings.rs
if: matrix.os == 'ubuntu-latest'

- uses: actions/upload-artifact@v4
with:
name: artifact-macos-bindings
path: steamworks-sys/src/macos_bindings.rs
if: matrix.os == 'macos-latest'

- uses: actions/upload-artifact@v4
with:
name: artifact-windows-bindings
path: steamworks-sys/src/windows_bindings.rs
if: matrix.os == 'windows-latest'
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ Cargo.lock

*.iml
steamworks-sys/lib/steam/*
!steamworks-sys/lib/steam/redistributable_bin/
!steamworks-sys/lib/steam/redistributable_bin/
!steamworks-sys/lib/steam/public/
9 changes: 6 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "steamworks"
version = "0.9.0"
version = "0.11.0"
authors = ["Thinkofname"]
description = "Provides rust friendly bindings to the steamworks sdk"
license = "MIT / Apache-2.0"
Expand All @@ -9,10 +9,12 @@ documentation = "https://docs.rs/steamworks"
keywords = ["steam", "gamedev"]
categories = ["games"]
edition = "2021"
rust-version = "1.71.1"

[features]
default = []
raw-bindings = []
image = ["dep:image"]

[workspace]
members = [
Expand All @@ -22,12 +24,13 @@ members = [
]

[dependencies]
steamworks-sys = {path = "./steamworks-sys", version = "0.9.0"}
steamworks-sys = { path = "./steamworks-sys", version = "0.11.0" }
thiserror = "1.0"
bitflags = "1.2"
lazy_static = "1.4"
serde = { version = "1.0", features = ["derive"], optional = true }
paste = "1.0.11"
image = { version = "0.25.1", optional = true, default-features = false }

[dev-dependencies]
serial_test = "0.6"
serial_test = "1"
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ Add the following to your `Cargo.toml`:

```toml
[dependencies]
steamworks = "0.9.0"
steamworks = "0.11.0"
```

| Crate | SDK | MSRV |
|-------|-------|--------|
| git | 1.54 | 1.56.1 |
| 0.9.0 | 1.53a | 1.56.1 |
| Crate | SDK | MSRV |
|--------|-------|--------|
| git | 1.60 | 1.71.1 |
| 0.11.0 | 1.58a | 1.71.1 |
| 0.10.0 | 1.54 | 1.56.1 |
| 0.9.0 | 1.53a | 1.56.1 |

## Example
You can find more examples in [examples](examples).
Expand Down
146 changes: 146 additions & 0 deletions examples/achievements/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# 🏆 Achievements Example
*By [Jackson0ne](https://github.com/Jackson0ne)*

This example outlines how to use the following achievement functions from the Steamworks API within `steamworks-rs`:

`get_achievement_achieved_percent()`
-

> *⚠ This function **requires** a successful callback to be received from `request_global_achievement_percentages(...)` before it will return any data!*
Returns the percentage of users who have unlocked the specified achievement.

To use, you'll first need to call `client.user_stats().request_global_achievement_percentages(...)`, and obtain the result from within the returned callback.

#### Example:

```rust
use steamworks::{Client,AppId};

fn main() {
let (client,single) = Client::init_app(AppId(4000)).unwrap();
let name = "GMA_BALLEATER";

client.user_stats().request_global_achievement_percentages(move|result| {
if !result.is_err() {
let user_stats = client.user_stats();
let achievement = user_stats.achievement(name);

let ach_percent = achievement.get_achievement_achieved_percent().unwrap();
} else {
eprintln!("Error fetching achievement percentage for {}",name);
}
});

for _ in 0..50 {
single.run_callbacks();
std::thread::sleep(std::time::Duration::from_millis(100));
}
}
```

`get_achievement_display_attribute("name" | "desc" | "hidden")`
-

Returns a string for the result of the specified attribute type. Accepted values are:

- `"name"`: The friendly (*non-API*) name of the achievement
- `"desc"`: The achievement description
- `"hidden"`: Whether the achievement is hidden (`"1"`) or not (`"0"`).

> *As the returned value is always a string, the `"hidden"` value will need to be parsed for comparison!*
#### Example:

```rust
use steamworks::{Client,AppId};

fn main() {
let (client,single) = Client::init_app(AppId(4000)).unwrap();
let name = "GMA_BALLEATER";

let user_stats = client.user_stats();
let achievement = user_stats.achievement(name);

let ach_name = achievement.get_achievement_display_attribute("name").unwrap();
let ach_desc = achievement.get_achievement_display_attribute("desc").unwrap();
let ach_hidden = achievement.get_achievement_display_attribute("hidden").unwrap().parse::<u32>().unwrap();

println!(
"Name: {:?}\nDesc: {:?}\nHidden?: {:?}",
ach_name,
ach_desc,
ach_hidden != 0
);
}
```

`get_achievement_icon()`
-

Returns a `Vec<u8>` buffer containing the image data for the specified achievement.


- The icon is always returned as `64px` x `64px`.
- The version of the icon that is downloaded - i.e. locked (*grey*) vs unlocked (*colour*) - is dependent on whether the achievement has been unlocked or not at the time the function is called.

> *As far as I can tell, there's no parameter to request a specific version!*
To convert the buffer into an image, you can use an external crate to convert the `Vec<u8>` (`Uint8Array`) into a file (such as `.jpg`) and save it to disk - there's plenty of [Rust crates](https://crates.io/crates/image) or [NPM libraries](https://www.npmjs.com/package/jpeg-js) that can do this.

#### Example:

```rust
use steamworks::{Client,AppId};

fn main() {
let (client,single) = Client::init_app(AppId(4000)).unwrap();
let name = "GMA_BALLEATER";

let user_stats = client.user_stats();
let achievement = user_stats.achievement(name);

let _ach_icon_handle = achievement.get_achievement_icon().expect("Failed getting achievement icon RGBA buffer");
}
```

`get_num_achievements()`
-

Returns the number of achievements for the current AppId.

> *Returns `0` if the current AppId has no achievements.*
#### Example:

```rust
use steamworks::{Client,AppId};

fn main() {
let (client,single) = Client::init_app(AppId(4000)).unwrap();

let num = client.user_stats().get_num_achievements().expect("Failed to get number of achievements");

println!("{}",num);
}
```

`get_achievement_names()`
-

Returns a `Vec<String>` containing the API names of all achievements for the current AppId.

> *The returned string value will be empty if the specified index is invalid.*
#### Example:

```rust
use steamworks::{Client,AppId};

fn main() {
let (client,single) = Client::init_app(AppId(4000)).unwrap();
let name = "GMA_BALLEATER";

let names = client.user_stats().get_achievement_names().expect("Failed to get achievement names");
}
```
60 changes: 31 additions & 29 deletions examples/workshop/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,32 @@ use steamworks::{Client, ClientManager, PublishedFileId, UGC};
fn create_item(ugc: &UGC<ClientManager>) {
// creating a new workshop item
// make sure you change the appid to the specified game
ugc.create_item(480, steamworks::FileType::Community, |create_result| {
// handle the result
match create_result {
Ok((published_id, needs_to_agree_to_terms)) => {
// if the user needs to agree to the terms of use, they will need to do that before you can upload any files
// in any case, make sure you save the published_id somewhere, like a manifest file.
// it is needed for all further calls
if needs_to_agree_to_terms {
println!(
"You need to agree to the terms of use before you can upload any files"
);
} else {
println!("Published item with id {}", published_id);
ugc.create_item(
steamworks::AppId(480),
steamworks::FileType::Community,
|create_result| {
// handle the result
match create_result {
Ok((published_id, needs_to_agree_to_terms)) => {
// if the user needs to agree to the terms of use, they will need to do that before you can upload any files
// in any case, make sure you save the published_id somewhere, like a manifest file.
// it is needed for all further calls
if needs_to_agree_to_terms {
println!(
"You need to agree to the terms of use before you can upload any files"
);
} else {
println!("Published item with id {:?}", published_id);
}
}
Err(e) => {
// an error occurred, usually because the app is not authorized to create items
// or the user is banned from the community
println!("Error creating workshop item: {:?}", e);
}
}
Err(e) => {
// an error occurred, usually because the app is not authorized to create items
// or the user is banned from the community
println!("Error creating workshop item: {:?}", e);
}
}
});
},
);
}

fn upload_item_content(ugc: &UGC<ClientManager>, published_id: PublishedFileId) {
Expand All @@ -46,13 +50,13 @@ fn upload_item_content(ugc: &UGC<ClientManager>, published_id: PublishedFileId)
// notes:
// - once an upload is started, it cannot be cancelled!
// - content_path is the path to a folder which houses the content you wish to upload
let upload_handle = ugc
.start_item_update(480, published_id)
.content_path("/absolute/path/to/content")
let _upload_handle = ugc
.start_item_update(steamworks::AppId(480), published_id)
.content_path(Path::new("/absolute/path/to/content"))
.preview_path(Path::new("/absolute/path/to/preview.png"))
.title("Item title")
.description("Item description")
.tags([])
.tags(Vec::<String>::new(), false)
.visibility(steamworks::PublishedFileVisibility::Public)
.submit(Some("My changenotes"), |upload_result| {
// handle the result
Expand All @@ -68,7 +72,7 @@ fn upload_item_content(ugc: &UGC<ClientManager>, published_id: PublishedFileId)
// this is the definite indicator that an item was uploaded successfully
// the watch handle is NOT an accurate indicator whether the upload is done
// the progress on the other hand IS accurate and can simply be used to monitor the upload
println!("Uploaded item with id {}", published_id);
println!("Uploaded item with id {:?}", published_id);
}
}
Err(e) => {
Expand All @@ -82,11 +86,11 @@ fn upload_item_content(ugc: &UGC<ClientManager>, published_id: PublishedFileId)

fn delete_item(ugc: &UGC<ClientManager>, published_id: PublishedFileId) {
// deleting an item
ugc.delete_item(published_id, |delete_result| {
ugc.delete_item(published_id, move |delete_result| {
match delete_result {
Ok(()) => {
// item has been deleted
println!("Deleted item with id {}", published_id);
println!("Deleted item with id {:?}", published_id);
}
Err(e) => {
// the item could not be deleted
Expand Down Expand Up @@ -139,6 +143,4 @@ fn main() {
callback_thread
.join()
.expect("Failed to join callback thread");

Ok(())
}
Loading

0 comments on commit 7848fab

Please sign in to comment.