From edeafdb9f07eb77afeca4e0f216b91876714ee24 Mon Sep 17 00:00:00 2001 From: syui Date: Sat, 9 Nov 2024 11:31:01 +0900 Subject: [PATCH] add game --- .config/ai/scpt | 2 +- README.md | 27 ++++- at/lexicons/ai/syui/game.json | 27 +++++ at/lexicons/ai/syui/game/user.json | 97 +++++++++++++++++ src/data.rs | 2 + src/game.rs | 5 + src/{ => game}/post_card.rs | 0 src/{ => game}/post_card_verify.rs | 0 src/game/post_game.rs | 39 +++++++ src/game/post_game_login.rs | 41 +++++++ src/game/post_game_user.rs | 56 ++++++++++ src/main.rs | 169 ++++++++++++++++++++++++++++- 12 files changed, 461 insertions(+), 4 deletions(-) create mode 100644 at/lexicons/ai/syui/game.json create mode 100644 at/lexicons/ai/syui/game/user.json create mode 100644 src/game.rs rename src/{ => game}/post_card.rs (100%) rename src/{ => game}/post_card_verify.rs (100%) create mode 100644 src/game/post_game.rs create mode 100644 src/game/post_game_login.rs create mode 100644 src/game/post_game_user.rs diff --git a/.config/ai/scpt b/.config/ai/scpt index 03a64c3..1123a82 160000 --- a/.config/ai/scpt +++ b/.config/ai/scpt @@ -1 +1 @@ -Subproject commit 03a64c3652bd60cc8cfab09bd70368a1c7dab9d8 +Subproject commit 1123a82bbcd10eaf6d4fd5d9c70484af6fa06a16 diff --git a/README.md b/README.md index 577f0a6..f8d1be5 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,7 @@ $ docker compose build $ docker compose up -d ``` -## pds +## pds:card - https://atproto.com/ja/guides/lexicon - https://at.syu.is/at/did:plc:uqzpqmrjnptsxezjx4xuh2mn/ai.syui.card/3lagpwihqxi2v @@ -116,4 +116,29 @@ $ docker compose up -d ```sh # oauth(button) [yui]ai.syui.card.verify -> [user]ai.syui.card + +[yui] +$ ./target/debug/ai card-verify -i 0 -p 0 -r 0 -h syui.ai -d did:plc:uqzpqmrjnptsxezjx4xuh2mn +{"uri":"at://did:plc:4hqjfn7m6n5hno3doamuhgef/ai.syui.card.verify/3lagpvhppmd2q"} + +[user] +$ ./target/debug/ai card -i 0 -p 0 -r 0 -v at://did:plc:4hqjfn7m6n5hno3doamuhgef/ai.syui.card.verify/3lagpvhppmd2q ``` + +## pds:game + +- https://atproto.com/ja/specs/record-key +- https://at.syu.is/at/did:plc:uqzpqmrjnptsxezjx4xuh2mn/ai.syui.game/self + +```sh +# oauth(play) +[yui]ai.syui.game.user -> [user]ai.syui.game + +[account] +# https://at.syu.is/at/did:plc:4hqjfn7m6n5hno3doamuhgef/ai.syui.game.user/syui + ## [rkey] + 1. echo $handle|cut -d . -f 1 + 2. $handle + 3. tid +``` + diff --git a/at/lexicons/ai/syui/game.json b/at/lexicons/ai/syui/game.json new file mode 100644 index 0000000..cfdeb13 --- /dev/null +++ b/at/lexicons/ai/syui/game.json @@ -0,0 +1,27 @@ +{ + "lexicon": 1, + "id": "ai.syui.game", + "defs": { + "main": { + "type": "record", + "description": "Record containing a game.", + "key": "literal:self", + "record": { + "type": "object", + "required": ["account", "createdAt"], + "properties": { + "account": { + "type": "string", + "format": "at-uri", + "description": "at://verify..." + }, + "createdAt": { + "type": "string", + "format": "datetime", + "description": "Client-declared timestamp when this post was originally created." + } + } + } + } + } +} diff --git a/at/lexicons/ai/syui/game/user.json b/at/lexicons/ai/syui/game/user.json new file mode 100644 index 0000000..883de96 --- /dev/null +++ b/at/lexicons/ai/syui/game/user.json @@ -0,0 +1,97 @@ +{ + "lexicon": 1, + "id": "ai.syui.game.user", + "defs": { + "main": { + "type": "record", + "key": "tid", + "description": "Record containing a game user.", + "input": { + "encoding": "application/json", + "record": { + "type": "object", + "required": ["did", "createdAt"], + "properties": { + "aiten":{ + "type": "integer", + "default": 0 + }, + "did": { + "type": "string" + }, + "login": { + "type": "bool" + }, + "limit": { + "type": "bool" + }, + "charactor": { + "type": "object", + "enum": ["ai", "test"], + "properties": { + "ai":{ + "type": "object", + "properties": { + "lv":{ + "type": "integer", + "minimum": 1, + "maximum": 7, + "default": 1 + }, + "exp":{ + "type": "integer" + }, + "rank":{ + "type": "integer", + "minimum": 0, + "maximum": 7, + "default": 0 + }, + "mode":{ + "type": "integer", + "minimum": 0, + "maximum": 7, + "default": 0 + }, + "hp":{ + "type": "integer", + "maximum": 255, + "default": 0 + }, + "attach":{ + "type": "integer", + "minimum": 1, + "maximum": 255, + "default": 1 + }, + "critical":{ + "type": "integer", + "minimum": 0, + "maximum": 255, + "default": 0 + }, + "critical_d":{ + "type": "integer", + "minimum": 0, + "maximum": 255, + "default": 0 + } + } + } + } + }, + "createdAt": { + "type": "string", + "format": "datetime", + "description": "Client-declared timestamp when this post was originally created." + }, + "updatedAt": { + "type": "string", + "format": "datetime" + } + } + } + } + } + } +} diff --git a/src/data.rs b/src/data.rs index c4a8505..2d19147 100644 --- a/src/data.rs +++ b/src/data.rs @@ -107,6 +107,7 @@ pub struct BaseUrl { pub record_list: String, pub record_create: String, pub record_delete: String, + pub record_put: String, pub session_create: String, pub session_refresh: String, pub session_get: String, @@ -142,6 +143,7 @@ pub fn url(s: &str) -> String { let baseurl = BaseUrl { profile_get: "com.atproto.identity.resolveHandle".to_string(), thread_get: "app.bsky.feed.getPostThread".to_string(), + record_put: "com.atproto.repo.putRecord".to_string(), record_create: "com.atproto.repo.createRecord".to_string(), record_delete: "com.atproto.repo.deleteRecord".to_string(), describe: "com.atproto.repo.describeRepo".to_string(), diff --git a/src/game.rs b/src/game.rs new file mode 100644 index 0000000..297cddc --- /dev/null +++ b/src/game.rs @@ -0,0 +1,5 @@ +pub mod post_card; +pub mod post_card_verify; +pub mod post_game; +pub mod post_game_user; +pub mod post_game_login; diff --git a/src/post_card.rs b/src/game/post_card.rs similarity index 100% rename from src/post_card.rs rename to src/game/post_card.rs diff --git a/src/post_card_verify.rs b/src/game/post_card_verify.rs similarity index 100% rename from src/post_card_verify.rs rename to src/game/post_card_verify.rs diff --git a/src/game/post_game.rs b/src/game/post_game.rs new file mode 100644 index 0000000..332a023 --- /dev/null +++ b/src/game/post_game.rs @@ -0,0 +1,39 @@ +extern crate reqwest; +use crate::data_toml; +use crate::data_refresh; +use crate::url; +use iso8601_timestamp::Timestamp; +use serde_json::json; + +pub async fn post_request(col: String, account: String) -> String { + let token = data_refresh(&"access"); + let did = data_toml(&"did"); + let handle = data_toml(&"handle"); + let url = url(&"record_put"); + let d = Timestamp::now_utc(); + let d = d.to_string(); + let post = Some(json!({ + "repo": handle.to_string(), + "did": did.to_string(), + "collection": col.to_string(), + "rkey": "self".to_string(), + "record": { + "account": account.to_string(), + "createdAt": d.to_string(), + }, + })); + + let client = reqwest::Client::new(); + let res = client + .post(url) + .json(&post) + .header("Authorization", "Bearer ".to_owned() + &token) + .send() + .await + .unwrap() + .text() + .await + .unwrap(); + + return res; +} diff --git a/src/game/post_game_login.rs b/src/game/post_game_login.rs new file mode 100644 index 0000000..65acc43 --- /dev/null +++ b/src/game/post_game_login.rs @@ -0,0 +1,41 @@ +extern crate reqwest; +use crate::data_toml; +use crate::data_refresh; +use crate::url; +use iso8601_timestamp::Timestamp; +use serde_json::json; + +pub async fn post_request(col: String, username: String, login: bool) -> String { + let token = data_refresh(&"access"); + let did = data_toml(&"did"); + let handle = data_toml(&"handle"); + let url = url(&"record_create"); + let d = Timestamp::now_utc(); + let d = d.to_string(); + + let post = Some(json!({ + "repo": handle.to_string(), + "did": did.to_string(), + "collection": col.to_string(), + "rkey": "self".to_string(), + "record": { + "login": login, + "username": username.to_string(), + "createdAt": d.to_string(), + }, + })); + + let client = reqwest::Client::new(); + let res = client + .post(url) + .json(&post) + .header("Authorization", "Bearer ".to_owned() + &token) + .send() + .await + .unwrap() + .text() + .await + .unwrap(); + + return res; +} diff --git a/src/game/post_game_user.rs b/src/game/post_game_user.rs new file mode 100644 index 0000000..083909d --- /dev/null +++ b/src/game/post_game_user.rs @@ -0,0 +1,56 @@ +extern crate reqwest; +use crate::data_toml; +use crate::data_refresh; +use crate::url; +use iso8601_timestamp::Timestamp; +use serde_json::json; + +pub async fn post_request(col: String, user_name: String, user_did: String, user_handle: String, aiten: i32, limit: i32, chara: String, lv: i32, exp: i32, hp: i32, rank: i32, mode: i32, attach: i32, critical: i32, critical_d: i32) -> String { + //let col = "ai.syui.game.user".to_string(); + let token = data_refresh(&"access"); + let did = data_toml(&"did"); + let handle = data_toml(&"handle"); + let url = url(&"record_put"); + let d = Timestamp::now_utc(); + let d = d.to_string(); + let post = Some(json!({ + "repo": handle.to_string(), + "did": did.to_string(), + "collection": col.to_string(), + "rkey": user_name.to_string(), + "record": { + "did": user_did.to_string(), + "handle": user_handle.to_string(), + "aiten": aiten, + "limit": limit, + "character": { + chara.to_string(): { + "lv": lv, + "exp": exp, + "hp": hp, + "rank": rank, + "mode": mode, + "attach": attach, + "critical": critical, + "critical_d": critical_d, + } + }, + "createdAt": d.to_string(), + "updatedAt": d.to_string(), + }, + })); + + let client = reqwest::Client::new(); + let res = client + .post(url) + .json(&post) + .header("Authorization", "Bearer ".to_owned() + &token) + .send() + .await + .unwrap() + .text() + .await + .unwrap(); + + return res; +} diff --git a/src/main.rs b/src/main.rs index fead43f..176863b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,6 +12,11 @@ use crate::data::url; use crate::data::w_cfg; use crate::data::w_refresh; use crate::feed_watch::c_feed_watch; +use crate::game::post_card; +use crate::game::post_card_verify; +use crate::game::post_game; +use crate::game::post_game_user; +use crate::game::post_game_login; use data::ProfileIdentityResolve; @@ -30,8 +35,7 @@ pub mod notify_read; pub mod openai; pub mod post; pub mod post_link; -pub mod post_card; -pub mod post_card_verify; +pub mod game; pub mod profile; pub mod refresh; pub mod reply; @@ -223,6 +227,93 @@ fn main() { .alias("did"), ) ) + .command( + Command::new("game") + .description("-a ") + .action(game) + .flag( + Flag::new("col", FlagType::String) + .alias("c"), + ) + .flag( + Flag::new("account", FlagType::String) + .alias("a"), + ) + ) + .command( + Command::new("game-login") + .description("-l -u -c ") + .action(game_login) + .flag( + Flag::new("col", FlagType::String) + .alias("c"), + ) + .flag( + Flag::new("login", FlagType::Bool) + .alias("l"), + ) + .flag( + Flag::new("username", FlagType::String) + .alias("u"), + ) + ) + .command( + Command::new("game-user") + .description("-u -h -d -ten 0 -l 20240101 -chara -lv 0 -exp 0 -hp 0 -rank 0 -mode 0 -attach 0 -critical 0 -critical_d 0") + .action(game_user) + .flag( + Flag::new("username", FlagType::String) + .alias("u"), + ) + .flag( + Flag::new("col", FlagType::String) + .alias("c"), + ) + .flag( + Flag::new("did", FlagType::String) + .alias("d"), + ) + .flag( + Flag::new("handle", FlagType::String) + .alias("h"), + ) + .flag( + Flag::new("character", FlagType::String) + .alias("chara"), + ) + .flag( + Flag::new("aiten", FlagType::Int) + .alias("ten"), + ) + .flag( + Flag::new("limit", FlagType::Int) + .alias("l"), + ) + .flag( + Flag::new("lv", FlagType::Int) + ) + .flag( + Flag::new("hp", FlagType::Int) + ) + .flag( + Flag::new("attach", FlagType::Int) + ) + .flag( + Flag::new("exp", FlagType::Int) + ) + .flag( + Flag::new("critical", FlagType::Int) + ) + .flag( + Flag::new("critical_d", FlagType::Int) + ) + .flag( + Flag::new("rank", FlagType::Int) + ) + .flag( + Flag::new("mode", FlagType::Int) + ) + ) .command( Command::new("like") .description("like -u ") @@ -578,6 +669,8 @@ async fn c_card_verify(c: &Context) -> Result<(), Box> { let rare = c.string_flag("rare").unwrap_or_else(|_| "normal".to_string()); let user_handle = c.string_flag("handle").unwrap_or_else(|_| "syui.ai".to_string()); let user_did = c.string_flag("did").unwrap_or_else(|_| "did:plc:uqzpqmrjnptsxezjx4xuh2mn".to_string()); + + //match id === 1 let img = "xxx"; let str = post_card_verify::post_request(col, img, id, cp, rank, rare, user_handle, user_did); println!("{}", str.await); Ok(()) @@ -594,6 +687,78 @@ fn card_verify(c: &Context) { }); } +async fn c_game(c: &Context) -> Result<(), Box> { + let account = c.string_flag("account").unwrap_or_else(|_| "at://did:plc:4hqjfn7m6n5hno3doamuhgef/ai.syui.game.user/syui".to_string()); + let col = c.string_flag("col").unwrap_or_else(|_| "ai.syui.game".to_string()); + let str = post_game::post_request(col, account); + println!("{}", str.await); + Ok(()) +} + +fn game(c: &Context) { + refresh(c); + tokio::runtime::Runtime::new() + .unwrap() + .block_on(async { + if let Err(e) = c_game(c).await { + eprintln!("Error: {}", e); + } + }); +} + +async fn c_game_user(c: &Context) -> Result<(), Box> { + let col = c.string_flag("col").unwrap_or_else(|_| "ai.syui.game.user".to_string()); + let user_name = c.string_flag("username").unwrap_or_else(|_| "syui".to_string()); + let user_handle = c.string_flag("handle").unwrap_or_else(|_| "syui.ai".to_string()); + let user_did = c.string_flag("did").unwrap_or_else(|_| "did:plc:uqzpqmrjnptsxezjx4xuh2mn".to_string()); + let chara = c.string_flag("character").unwrap_or_else(|_| "ai".to_string()); + let limit = c.int_flag("limit")?.try_into()?; + let aiten = c.int_flag("aiten")?.try_into()?; + let lv = c.int_flag("lv")?.try_into()?; + let exp = c.int_flag("exp")?.try_into()?; + let hp = c.int_flag("hp")?.try_into()?; + let rank = c.int_flag("rank")?.try_into()?; + let mode = c.int_flag("mode")?.try_into()?; + let attach = c.int_flag("attach")?.try_into()?; + let critical = c.int_flag("critical")?.try_into()?; + let critical_d = c.int_flag("critical_d")?.try_into()?; + let str = post_game_user::post_request(col, user_name, user_did, user_handle, aiten, limit, chara, lv, exp, hp, rank, mode, attach, critical, critical_d); + println!("{}", str.await); + Ok(()) +} + +fn game_user(c: &Context) { + refresh(c); + tokio::runtime::Runtime::new() + .unwrap() + .block_on(async { + if let Err(e) = c_game_user(c).await { + eprintln!("Error: {}", e); + } + }); +} + +async fn c_game_login(c: &Context) -> Result<(), Box> { + let col = c.string_flag("col").unwrap_or_else(|_| "ai.syui.game.login".to_string()); + let user_name = c.string_flag("username").unwrap_or_else(|_| "syui".to_string()); + let login = c.bool_flag("login"); + let str = post_game_login::post_request(col, user_name, login); + println!("{}", str.await); + Ok(()) +} + +fn game_login(c: &Context) { + refresh(c); + tokio::runtime::Runtime::new() + .unwrap() + .block_on(async { + if let Err(e) = c_game_login(c).await { + eprintln!("Error: {}", e); + } + }); +} + + fn repost(c: &Context) { refresh(c); let m = c.args[0].to_string();