Skip to content

Commit

Permalink
refactor protobuf definitions and add head overlay attribute (#16)
Browse files Browse the repository at this point in the history
This refactors the protobuf definition to its more-final version and adds documentation as well as a new overlay attribute for the request of heads that controls whether the second layer will be merged onto the texture.

Implements #7
  • Loading branch information
scrayos authored Jan 31, 2024
1 parent 164d190 commit a915498
Show file tree
Hide file tree
Showing 9 changed files with 194 additions and 136 deletions.
23 changes: 0 additions & 23 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -92,28 +92,5 @@ ij_markdown_max_lines_around_block_elements = 1
ij_markdown_min_lines_around_header = 1
ij_markdown_max_lines_around_header = 1

[*.rs]
max_line_length = 100
ij_continuation_indent_size = 4
ij_rust_align_multiline_chained_methods = false
ij_rust_align_multiline_parameters = true
ij_rust_align_multiline_parameters_in_calls = true
ij_rust_align_ret_type = true
ij_rust_align_type_params = false
ij_rust_align_where_bounds = true
ij_rust_align_where_clause = false
ij_rust_allow_one_line_match = false
ij_rust_block_comment_at_first_column = false
ij_rust_indent_where_clause = true
ij_rust_keep_blank_lines_in_code = 2
ij_rust_keep_blank_lines_in_declarations = 2
ij_rust_keep_indents_on_empty_lines = false
ij_rust_keep_line_breaks = true
ij_rust_line_comment_add_space = true
ij_rust_line_comment_at_first_column = false
ij_rust_min_number_of_blanks_between_items = 1
ij_rust_preserve_punctuation = false
ij_rust_spaces_around_assoc_type_binding = false

[{*.toml,Cargo.lock,Cargo.toml.orig,Gopkg.lock,Pipfile,poetry.lock}]
ij_toml_keep_indents_on_empty_lines = false
2 changes: 1 addition & 1 deletion build.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
fn main() -> Result<(), Box<dyn std::error::Error>> {
tonic_build::compile_protos("proto/service.proto")?;
tonic_build::compile_protos("proto/profile.proto")?;
println!("Build proto successfully");
Ok(())
}
101 changes: 101 additions & 0 deletions proto/profile.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
syntax = "proto3";

package scrayosnet.xenos;

// Profile is the service responsible for profile information lookup. It also contains information about the player skin
// and other properties of the profile.
service Profile {
// Get the Minecraft UUIDs for specific usernames.
rpc GetUuids(UuidRequest) returns (UuidResponse);

// Get the Minecraft Profile for a specific UUID.
rpc GetProfile(ProfileRequest) returns (ProfileResponse);

// Get the Minecraft Skin for a specific UUID.
rpc GetSkin(SkinRequest) returns (SkinResponse);

// Get the Minecraft Head for a specific UUID.
rpc GetHead(HeadRequest) returns (HeadResponse);
}

// UuidRequest is a request of the Minecraft UUIDs of specific, case-insensitive usernames.
message UuidRequest {
// The individual, case-insensitive usernames whose UUIDs should be queried.
repeated string usernames = 1;
}

// UuidResult is an individual result of the Minecraft UUID resolution.
message UuidResult {
// The unix timestamp (in seconds) at which the returned data was last updated.
uint64 timestamp = 1;
// The username with correct capitalization.
string username = 2;
// The UUID in hyphenated form.
string uuid = 3;
}

// UuidResponse is a response with the Minecraft UUIDs of the requested usernames.
message UuidResponse {
// The individual results of the requested usernames.
repeated UuidResult resolved = 1;
}

// ProfileRequest is a request of the Minecraft Profile of a specific UUID.
message ProfileRequest {
// The UUID in simple or hyphenated form whose Minecraft Profile should be queried.
string uuid = 1;
}

// ProfileProperty is a single property of a Minecraft Profile, that is possibly signed.
message ProfileProperty {
// The unique name of the property within the Minecraft Profile.
string name = 1;
// The value of the property that contains the real information.
string value = 2;
// The optional Yggdrasil signature to verify the authenticity and integrity.
optional string signature = 3;
}

// ProfileResponse is a response with the Minecraft Profile of the requested UUID.
message ProfileResponse {
// The unix timestamp (in seconds) at which the returned data was last updated.
uint64 timestamp = 1;
// The UUID of the Minecraft Profile in hyphenated form.
string uuid = 2;
// The username with correct capitalization.
string name = 3;
// The individual properties of attached information for this profile.
repeated ProfileProperty properties = 4;
// The moderative actions/sanctions that have been imposed on this Minecraft Profile.
repeated string profile_actions = 5;
}

// SkinRequest is a request of the Skin texture of a specific UUID.
message SkinRequest {
// The UUID in simple or hyphenated form whose Minecraft Skin should be queried.
string uuid = 1;
}

// SkinResponse is a response with the Skin texture of the requested UUID.
message SkinResponse {
// The unix timestamp (in seconds) at which the returned data was last updated.
uint64 timestamp = 1;
// The binary data of the 64x64 PNG image of the player's Skin.
bytes data = 2;
}

// HeadRequest is a request of the Head texture of a specific UUID.
message HeadRequest {
// The UUID in simple or hyphenated form whose Minecraft Head should be queried.
string uuid = 1;
// Whether the overlay layer should be added to the texture.
bool overlay = 2;
}

// HeadResponse is a response with the Head texture of the requested UUID.
message HeadResponse {
// The unix timestamp (in seconds) at which the returned data was last updated.
uint64 timestamp = 1;
// The binary data of the 8x8 PNG image of the player's Head.
bytes data = 2;
}
60 changes: 0 additions & 60 deletions proto/service.proto

This file was deleted.

33 changes: 24 additions & 9 deletions src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,16 @@ pub trait XenosCache: Send + Sync {
async fn set_profile_by_uuid(&mut self, entry: ProfileEntry) -> Result<(), XenosError>;
async fn get_skin_by_uuid(&mut self, uuid: &Uuid) -> Result<Option<SkinEntry>, XenosError>;
async fn set_skin_by_uuid(&mut self, entry: SkinEntry) -> Result<(), XenosError>;
async fn get_head_by_uuid(&mut self, uuid: &Uuid) -> Result<Option<HeadEntry>, XenosError>;
async fn set_head_by_uuid(&mut self, entry: HeadEntry) -> Result<(), XenosError>;
async fn get_head_by_uuid(
&mut self,
uuid: &Uuid,
overlay: &bool,
) -> Result<Option<HeadEntry>, XenosError>;
async fn set_head_by_uuid(
&mut self,
entry: HeadEntry,
overlay: &bool,
) -> Result<(), XenosError>;
}

pub struct RedisCache {
Expand Down Expand Up @@ -228,20 +236,27 @@ impl XenosCache for RedisCache {
Ok(())
}

async fn get_head_by_uuid(&mut self, uuid: &Uuid) -> Result<Option<HeadEntry>, XenosError> {
async fn get_head_by_uuid(
&mut self,
uuid: &Uuid,
overlay: &bool,
) -> Result<Option<HeadEntry>, XenosError> {
let uuid = uuid.simple().to_string();
let entry = self
.redis_manager
.get(build_key("head", uuid.simple().to_string().as_str()))
.get(build_key("head", &format!("{uuid}.{overlay}")))
.await?;
Ok(entry)
}

async fn set_head_by_uuid(&mut self, entry: HeadEntry) -> Result<(), XenosError> {
async fn set_head_by_uuid(
&mut self,
entry: HeadEntry,
overlay: &bool,
) -> Result<(), XenosError> {
let uuid = entry.uuid.simple().to_string();
self.redis_manager
.set(
build_key("head", entry.uuid.simple().to_string().as_str()),
entry,
)
.set(build_key("head", &format!("{uuid}.{overlay}")), entry)
.await?;
Ok(())
}
Expand Down
8 changes: 4 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use tonic::transport::Server;
use tonic_health::server::health_reporter;
use xenos::cache::RedisCache;
use xenos::mojang::Mojang;
use xenos::service::pb::xenos_server::XenosServer;
use xenos::service::pb::profile_server::ProfileServer;
use xenos::service::XenosService;

#[tokio::main]
Expand All @@ -23,19 +23,19 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {

// build grpc service
let service = XenosService { cache, mojang };
let svc = XenosServer::new(service);
let profile_service = ProfileServer::new(service);

// build grpc health reporter
let (mut health_reporter, health_service) = health_reporter();
health_reporter
.set_serving::<XenosServer<XenosService>>()
.set_serving::<ProfileServer<XenosService>>()
.await;

let addr = addr_str.parse().expect("listen address invalid format");
println!("Xenos listening on {}", addr);
Server::builder()
.add_service(health_service)
.add_service(svc)
.add_service(profile_service)
.serve(addr)
.await?;
Ok(())
Expand Down
Loading

0 comments on commit a915498

Please sign in to comment.