ai/at
1
0

Compare commits

..

4 Commits

Author SHA1 Message Date
1df58322dc update scpt 2024-12-27 16:25:16 +09:00
78e01d4568 add scpt 2024-12-27 16:25:16 +09:00
e7471b20e4 add game 2024-11-12 15:58:21 +09:00
4fa3212bdd up 2024-11-12 15:58:21 +09:00
74 changed files with 227 additions and 1794 deletions

View File

@ -1,38 +0,0 @@
name: Generate Record JSON
on:
workflow_dispatch: # 手動トリガー
push:
paths:
- scpt/generate_record.py # スクリプトに変更があったとき
schedule:
- cron: '0 3 * * *' # 毎日03:00 UTCに自動生成任意
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install Dependencies
run: |
pip install -r requirements.txt || true # 必要なら
- name: Run Record Generator Script
run: |
python scpt/generate_record.py
- name: Commit and Push Generated JSON
run: |
git config --global user.name "GitHub Actions Bot"
git config --global user.email "actions@github.com"
git add record.json
git commit -m "🧬 Auto-generate record.json" || echo "No changes to commit"
git push origin main

1
.gitignore vendored
View File

@ -1 +0,0 @@
repos

View File

@ -1,16 +1,11 @@
# at
# atproto
https://github.com/bluesky-social/atproto
|word|name|example|
|---|---|---|
|at|uri|at://ai.syu.is|
|@|user|@ai.syu.is|
|[at]proto|repo|`git@github.com:bluesky-social/atproto`|
|[at]mosphere|system|pds, bsky(appview), ozone, bgs, plc|
|[a]uthenticated [t]ransfer|protocol|[did](https://www.w3.org/TR/did-core/)|
- https://atproto.com/ja/guides/glossary
- @
- [at]mosphere
- at://proto
- at protocol
## account
@ -20,10 +15,6 @@ https://github.com/bluesky-social/atproto
- https://plc.syu.is/did:plc:6qyecktefllvenje24fcxnie
- https://plc.directory/did:plc:ytvoptig4ddshmwdsjmhtcym
[@yui.syui.ai](https://bsky.app/profile/did:plc:4hqjfn7m6n5hno3doamuhgef)
- https://pds.syu.is/at://did:plc:4hqjfn7m6n5hno3doamuhgef
```sh
$ curl -sL syu.is/xrpc/_health
{"version":"0.4.65"}
@ -65,7 +56,7 @@ currently, bsky and bsync require patches to function properly. additionally, so
|name|service|patch|
|---|---|---|
|pds|https://github.com/bluesky-social/atproto/blob/main/services/pds/Dockerfile||
|bsky|https://github.com/bluesky-social/atproto/blob/main/services/bsky/Dockerfile|[itaru2622/bluesky-atproto-bsky](https://github.com/itaru2622/bluesky-selfhost-env/blob/master/patching/105-atproto-services-for-docker.diff)|
|bsky|https://github.com/bluesky-social/atproto/blob/main/services/bsky/Dockerfile|[itaru2622/bluesky-atproto-bsky](https://hub.docker.com/r/itaru2622/bluesky-atproto-bsky)|
|bsync|https://github.com/bluesky-social/atproto/blob/main/services/bsync/Dockerfile||
|ozone|https://github.com/bluesky-social/atproto/blob/main/services/ozone/Dockerfile||
|plc|https://github.com/did-method-plc/did-method-plc/tree/main/packages/server||

30
build.sh Executable file
View File

@ -0,0 +1,30 @@
#!/bin/zsh
d=${0:a:h}
cd $d/repos
t="
https://github.com/bluesky-social/atproto
https://github.com/did-method-plc/did-method-plc
https://github.com/bluesky-social/feed-generator
https://github.com/bluesky-social/social-app
https://github.com/bluesky-social/cookbook
https://github.com/itaru2622/bluesky-selfhost-env
"
t=`echo $t|grep -v '^$'`
n=`echo $t|wc -l`
for ((i=1;i<=$n;i++))
do
tt=`echo $t|awk "NR==$i"`
dd=$d/repos/$tt:t
if [ -d $dd ];then
echo ok
cd $dd
git pull
cd $d/repos
else
git clone $tt
fi
done

View File

@ -24,6 +24,18 @@ services:
timeout: 5s
retries: 5
pds-fix-permission:
image: alpine:latest
volumes:
- ./data/pds/:/data/
command: chown 1000.1000 /data
bsky-fix-permission:
image: alpine:latest
volumes:
- ./data/bsky/:/data/
command: chown 1000.1000 /data
plc:
ports:
- 2582:3000
@ -40,6 +52,8 @@ services:
pds:
ports:
- 2583:3000
#image: itaru2622/bluesky-atproto-pds
#image: ghcr.io/bluesky-social/pds:latest
build:
context: ./repos/atproto/
dockerfile: services/pds/Dockerfile
@ -51,6 +65,8 @@ services:
depends_on:
database:
condition: service_healthy
pds-fix-permission:
condition: service_completed_successfully
bgs:
ports:
@ -67,9 +83,45 @@ services:
database:
condition: service_healthy
ozone:
ports:
- 2585:3000
build:
context: ./repos/atproto/
dockerfile: services/ozone/Dockerfile
restart: always
command: node --enable-source-maps api.js
volumes:
- ./data/ozone/:/data/
- ./repos/ozone.js:/app/services/ozone/api.js:ro
env_file:
- ./envs/ozone
healthcheck:
test: "wget -q --spider http://localhost:3000/xrpc/_health"
interval: 5s
retries: 20
depends_on:
database:
condition: service_healthy
ozone-daemon:
build:
context: ./repos/atproto/
dockerfile: services/ozone/Dockerfile
restart: always
command: node --enable-source-maps daemon.js
env_file:
- ./envs/ozone
depends_on:
ozone:
condition: service_healthy
database:
condition: service_healthy
social-app:
ports:
- 8100:8100
#image: itaru2622/bluesky-social-app
build:
context: ./repos/social-app/
dockerfile: Dockerfile
@ -81,68 +133,34 @@ services:
bsky:
ports:
- 2584:2584
build:
context: ./repos/atproto/
dockerfile: services/bsky/Dockerfile
image: itaru2622/bluesky-atproto-bsky
#build:
# context: ./repos/atproto/
# dockerfile: services/bsky/Dockerfile
restart: always
env_file:
- ./envs/bsky
user: root
volumes:
- ./data/bsky/:/data/
# - ./repos/bsky.js:/app/services/bsky/api.js:ro
command: node --enable-source-maps api.js
depends_on:
database:
condition: service_healthy
redis:
condition: service_healthy
bsky-fix-permission:
condition: service_completed_successfully
jetstream:
build:
context: ./repos/jetstream/
dockerfile: Dockerfile
feed:
ports:
- 6008:6008
volumes:
- ./data/jetstream:/data
restart: always
env_file:
- ./envs/jetstream
ozone-web:
- 2586:2586
build:
context: ./repos/ozone/
ports:
- 2586:3000
context: ./repos/feed-generator/
restart: always
volumes:
- ./data/ozone/:/data/
env_file:
- ./envs/ozone
depends_on:
database:
condition: service_healthy
- ./envs/feed
volumes:
- ./data/feed/:/data/
ozone:
build:
context: ./repos/atproto/
dockerfile: services/ozone/Dockerfile
ports:
- 2585:3000
restart: always
command: node --enable-source-maps api.js
volumes:
- ./data/ozone/:/data/
env_file:
- ./envs/ozone
ozone-daemon:
build:
context: ./repos/atproto/
dockerfile: services/ozone/Dockerfile
restart: always
command: node --enable-source-maps daemon.js
volumes:
- ./data/ozone/:/data/
env_file:
- ./envs/ozone

View File

@ -1,5 +0,0 @@
JETSTREAM_WS_URL=wss://bgs.${host}/xrpc/com.atproto.sync.subscribeRepos
JETSTREAM_DATA_DIR=/data
JETSTREAM_LISTEN_ADDR=:6008
JETSTREAM_METRICS_LISTEN_ADDR=:6009
JETSTREAM_LIVENESS_TTL=96h

View File

@ -19,9 +19,3 @@ OZONE_DB_MIGRATE=1
OZONE_ADMIN_PASSWORD
OZONE_SIGNING_KEY_HEX
OZONE_BLOB_DIVERT_ADMIN_PASSWORD
OZONE_VERIFIER_URL
OZONE_VERIFIER_DID
OZONE_VERIFIER_PASSWORD
OZONE_VERIFIER_ISSUERS_TO_INDEX
OZONE_VERIFIER_JETSTREAM_URL

View File

@ -1,201 +0,0 @@
#!/bin/zsh
# ./install.zsh $HOST
repos_v='{}'
function at-repos-env() {
host=$1
if [ -z "$1" ];then
host=syu.is
fi
did=did:plc:6qyecktefllvenje24fcxnie
icon=https://git.syui.ai/ai/at/raw/branch/main/icons/Logotype.tsx
repos=(
https://github.com/did-method-plc/did-method-plc
https://github.com/bluesky-social/indigo
https://github.com/bluesky-social/atproto
https://github.com/bluesky-social/social-app
https://github.com/bluesky-social/feed-generator
https://github.com/bluesky-social/ozone
https://github.com/bluesky-social/jetstream
)
d=${0:a:h}
dh=${0:a:h:h}
name=${host%%.*}
domain=${host##*.}
}
function at-repos-json() {
f=~/.config/atproto/token.json
j="{ \"did\": \"did:plc:6qyecktefllvenje24fcxnie\", \"didDoc\": { \"service\": [ { \"serviceEndpoint\": \"https://syu.is\" } ] }, \"handle\": \"ai.syu.is\", \"accessJwt\": \"xxx\" }"
if [ ! -f "$f" ];then
mkdir -p ~/.config/atproto
echo $j >> $f
fi
echo $f
}
function at-repos-token() {
at-repos-json
if [ -z "$host" ] && [ -f $f ];then
host=`cat $f|jq -r ".didDoc.service.[].serviceEndpoint"`
handle=`cat $f|jq -r ".handle"`
did=`cat $f|jq -r ".did"`
token=`cat $f|jq -r ".token"`
host=${host##*/}
fi
name=${host%%.*}
domain=${host##*.}
}
function at-repos-clone() {
if [ ! -d $d/repos ];then
mkdir -p $d/repos
fi
cd $d/repos
for ((i=1; i<=${#repos}; i++)); do
repo=${repos[$i]}
echo $repo
if [ ! -d $d/repos/${repo##*/} ];then
git clone $repo
fi
done
if [ ! -f $d/repos/feed-generator/Dockerfile ] && [ -f $d/docker/feed/Dockerfile ];then
cp -rf $d/docker/feed/Dockerfile $d/repos/feed-generator/
fi
}
function at-repos-pull() {
cd $d/repos
for ((i=1; i<=${#repos}; i++)); do
repo=${repos[$i]}
echo $repo
if [ -d $d/repos/${repo##*/} ];then
cd $d/repos/${repo##*/}
if ! git pull;then
rm -rf $d/repos/${repo##*/}
at-repos-clone
fi
fi
rv=$(echo "$repos_v" | jq -r ".[\"${repo##*/}\"]")
if [ "$rv" != "null" ];then
cd $d/repos/${repo##*/}
git reset --hard $rv
cd ..
fi
done
cd $d
}
function at-repos-social-app-icon() {
curl -sL https://raw.githubusercontent.com/bluesky-social/social-app/main/src/view/icons/Logotype.tsx -o $d/repos/social-app/src/view/icons/Logotype.tsx
if [ -d $d/icons ];then
mkdir -p $d/icons
fi
cp -rf $d/repos/social-app/src/view/icons/Logotype.tsx $d/icons/
}
function at-repos-social-app-icon-origin() {
curl -sL $icon -o $d/icons/Logotype.tsx
}
function at-repos-social-app-write() {
did_admin=did:plc:6qyecktefllvenje24fcxnie
dt=$d/repos/social-app/src
cd $dt
grep -R syu.is .|cut -d : -f 1|sort -u|xargs sed -i "s/syu.is/${host}/g"
grep -R web.syu.is .|cut -d : -f 1|sort -u|xargs sed -i "s/web.syu.is/web.${host}/g"
f=$dt/lib/constants.ts
sed -i "s/public.api.web/bsky/g" $f
f=$dt/view/icons/Logotype.tsx
o=$d/icons/Logotype.tsx
cp -rf $o $f
f=$dt/view/com/util/UserAvatar.tsx
curl -sL https://raw.githubusercontent.com/bluesky-social/social-app/refs/heads/main/src/view/com/util/UserAvatar.tsx -o $f
sed -i "s#/img/avatar/plain/#https://cdn.web.syu.is/img/avatar/plain/#g" $f
sed -i "s#/img/avatar_thumbnail/plain/#https://bsky.${host}/img/avatar/plain/#g" $f
sed -i "s#source={{uri: avatar}}#source={{ uri: hackModifyThumbnailPath(avatar, 1 > 0), }}#g" $f
curl -sL https://raw.githubusercontent.com/bluesky-social/social-app/refs/heads/main/src/lib/strings/url-helpers.ts -o $dt/lib/strings/url-helpers.ts
sed -i "s#https://go.web.syu.is/redirect?u=\${encodeURIComponent(url)}#\${url}#g" $dt/lib/strings/url-helpers.ts
grep -R $did_admin .|cut -d : -f 1|sort -u|xargs sed -i "s/${did_admin}/${did}/g"
}
function at-repos-bsky-patch() {
f=$d/repos/atproto/services/bsky/api.js
curl -sL https://raw.githubusercontent.com/bluesky-social/atproto/refs/heads/main/services/bsky/api.js -o $f
d_=$d/repos/atproto
p_=$d/patching/105-atproto-services-for-docker.diff
cd ${d_}
if [ ! -f ${p_} ];then
# https://github.com/itaru2622/bluesky-selfhost-env/blob/master/patching/105-atproto-services-for-docker.diff
echo download patch: https://github.com/itaru2622/bluesky-selfhost-env/blob/master/patching/105-atproto-services-for-docker.diff
curl -sL https://raw.githubusercontent.com/itaru2622/bluesky-selfhost-env/refs/heads/master/patching/105-atproto-services-for-docker.diff -o ${p_}
else
echo local patch
fi
echo "applying patch: under ${f} for ${p_}"
pushd ${d_}
patch -p1 < ${p_}
popd
}
function at-repos-social-app-patch() {
f=$d/repos/social-app/Dockerfile
p_=$d/patching/social-app-dockerfile.diff
d_=$d/repos/social-app
cd ${d_}
curl -sLO https://raw.githubusercontent.com/bluesky-social/social-app/refs/heads/main/Dockerfile
echo "applying patch: under ${f} for ${p_}"
pushd ${d_}
patch -p1 < ${p_}
popd
}
function at-repos-ozone-patch() {
#DOMAIN=syu.is
cd $d/repos
d_=$d/repos/ozone
rm -rf ${d_}
p_=$d/patching/120-ozone-runtimeEnvVars.diff
git clone https://github.com/bluesky-social/ozone
cd ${d_}
pushd ${d_}
echo "applying patch: under ${d_} for ${p_}"
patch -p1 < ${p_}
popd
p_=$d/patching/122-ozone-enable-daemon.diff
echo "applying patch: under ${d_} for ${p_}"
pushd ${d_}
patch -p1 < ${p_}
popd
#cp -rf $d/repos/atproto/service/ozone/* $d/ozone/service/
}
function at-repos-docker() {
cd $d
docker compose build && docker compose up -d
}
at-repos-env
at-repos-clone
at-repos-pull
at-repos-social-app-icon
at-repos-social-app-icon-origin
at-repos-social-app-write
at-repos-bsky-patch
at-repos-social-app-patch
at-repos-ozone-patch
at-repos-docker
#echo "[y]docker compose build && up"
#read key
#case $key in
# [yY])
# at-repos-docker
# ;;
#esac

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 544 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 933 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 688 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 516 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 324 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 462 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 361 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 683 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 805 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 402 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 476 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 713 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 330 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 680 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

View File

@ -1,38 +0,0 @@
# card
カードの仕様を決定します。
基本的に`3:4``1620x2160`で生成していましたが、`4:5``1080x1350`で生成することにしました。これはwindows動画編集が4:5にしか対応していないからです。`.mov`から動画編集で`.mp4`に変換し、それを`.webp`にします。
comfyuiの動画生成はカードの大きさではなかなか思うような動画が作れませんでした。やはり`1920x1080(1080p)`からの生成が最適でした。
- [16:9] 1920x1080 (1080p)
- [16:9] 1280×720 (720p)
- [16:9] 854x480 (480p)
- [4:3] 2160x1620
- [4:3] 1440x1080
- [4:3] 1024×768
- [4:3] 640×480
- [4:5] 2025x1620
- [4:5] 1536x2048
- [4:5] 1080x1350
```bash
$ magick convert -resize 480x -quality 100 4.png 4.webp
$ magick convert -quality 100 1.png 1.webp
$ magick convert -size 1620x2160 xc:white 1080p.png
$ magick convert -resize 1080x -quality 100 1.png 1.webp
```
```sh
$ ffmpeg -i 4.mp4 -vf "fps=15,setpts=PTS/4" -c:v libwebp -loop 1 -quality 100 4.webp
```
## list
<img src="https://git.syui.ai/ai/ai/raw/branch/main/card/1.webp" width="200px">
<img src="https://git.syui.ai/ai/ai/raw/branch/main/card/2.webp" width="200px">
<img src="https://git.syui.ai/ai/ai/raw/branch/main/card/3.webp" width="200px">
<img src="https://git.syui.ai/ai/ai/raw/branch/main/card/4.webp" width="200px">

View File

@ -1,153 +0,0 @@
{
"lexicon": 1,
"id": "ai.syui.system",
"revision": 1,
"description": "Syui's system definitions for game logic and metaphysics",
"defs": {
"main": {
"type": "record",
"record": {
"key": "self",
"recordType": "document",
"schema": {
"type": "object",
"required": ["card", "system"],
"properties": {
"card": {
"type": "array",
"items": { "$ref": "#card" }
},
"system": {
"type": "array",
"items": { "$ref": "#system" }
},
"weapon": {
"type": "array",
"items": { "$ref": "#weapon" }
},
"ability": {
"type": "array",
"items": { "$ref": "#ability" }
},
"character": {
"type": "array",
"items": { "$ref": "#character" }
}
}
}
}
},
"card": {
"type": "object",
"required": ["id", "img", "name", "lang"],
"properties": {
"id": { "type": "integer" },
"img": { "type": "string" },
"name": { "type": "string" },
"lang": {
"type": "object",
"properties": {
"ja": {
"type": "object",
"properties": {
"name": { "type": "string" },
"text": { "type": "string" }
}
}
}
}
}
},
"system": {
"type": "object",
"required": ["id", "enum", "name", "lang"],
"properties": {
"id": { "type": "integer" },
"enum": {
"type": "array",
"items": { "type": "string" }
},
"name": { "type": "string" },
"alias": {
"type": "array",
"items": { "type": "string" }
},
"lang": {
"type": "object",
"properties": {
"ja": { "type": "string" }
}
},
"description": { "type": "string" }
}
},
"weapon": {
"type": "object",
"required": ["id", "img", "name", "lang"],
"properties": {
"id": { "type": "integer" },
"img": { "type": "string" },
"name": { "type": "string" },
"lang": {
"type": "object",
"properties": {
"ja": {
"type": "object",
"properties": {
"name": { "type": "string" },
"text": { "type": "string" }
}
}
}
}
}
},
"ability": {
"type": "object",
"required": ["id", "name", "color"],
"properties": {
"id": { "type": "integer" },
"name": { "type": "string" },
"lang": {
"type": "object",
"properties": {
"ja": { "type": "string" }
}
},
"color": { "type": "string" },
"group": {
"type": "array",
"items": { "type": "string" }
},
"duration": { "type": "integer" },
"multiplier": {
"type": "object",
"additionalProperties": { "type": "number" }
}
}
},
"character": {
"type": "object",
"required": ["id", "name", "lang"],
"properties": {
"id": { "type": "integer" },
"img": { "type": "string" },
"name": { "type": "string" },
"lang": {
"type": "object",
"properties": {
"ja": {
"type": "object",
"properties": {
"name": { "type": "string" },
"text": { "type": "string" },
"description": { "type": "string" }
}
}
}
},
"text": { "type": "string" }
}
}
}
}

View File

@ -1,56 +0,0 @@
{
"lexicon": 1,
"id": "ai.syui.card",
"defs": {
"main": {
"type": "record",
"description": "Record containing a cards box.",
"key": "tid",
"record": {
"type": "object",
"required": ["verify", "createdAt"],
"properties": {
"id":{
"type": "integer",
"minimum": 0,
"maximum": 14,
"default": 0
},
"cp":{
"type": "integer",
"minimum": 1,
"maximum": 5000,
"default": 1
},
"rank":{
"type": "integer",
"minimum": 0,
"maximum": 7,
"default": 0
},
"rare": {
"type": "string",
"enum": ["normal", "super", "ultra", "yui", "ai"],
"default": "normal"
},
"author": {
"type": "string",
"format": "uri",
"description": "https://verify...",
"default": "https://yui.syui.ai"
},
"verify": {
"type": "string",
"format": "at-uri",
"description": "at://verify..."
},
"createdAt": {
"type": "string",
"format": "datetime",
"description": "Client-declared timestamp when this post was originally created."
}
}
}
}
}
}

View File

@ -1,72 +0,0 @@
{
"lexicon": 1,
"id": "ai.syui.card.verify",
"defs": {
"main": {
"type": "record",
"description": "Record containing a card verify.",
"key": "tid",
"record": {
"type": "object",
"required": [
"handle",
"did",
"createdAt"
],
"properties": {
"id": {
"type": "integer",
"minimum": 0,
"maximum": 14,
"default": 0
},
"cp": {
"type": "integer",
"minimum": 1,
"maximum": 10000,
"default": 1
},
"rank": {
"type": "integer",
"minimum": 0,
"maximum": 7,
"default": 0
},
"rare": {
"type": "string",
"enum": [
"normal",
"super",
"ultra",
"yui",
"ai"
],
"default": "normal"
},
"handle": {
"type": "string",
"maxLength": 32,
"maxGraphemes": 32
},
"did": {
"type": "string"
},
"embed": {
"type": "union",
"refs": [
"app.bsky.embed.images",
"app.bsky.embed.external",
"app.bsky.embed.record",
"app.bsky.embed.recordWithMedia"
]
},
"createdAt": {
"type": "string",
"format": "datetime",
"description": "Client-declared timestamp when this post was originally created."
}
}
}
}
}
}

View File

@ -1,27 +0,0 @@
{
"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."
}
}
}
}
}
}

View File

@ -1,80 +0,0 @@
{
"lexicon": 1,
"id": "ai.syui.game.character",
"defs": {
"main": {
"type": "record",
"key": "string",
"description": "record containing a game character.",
"input": {
"encoding": "application/json",
"record": {
"type": "object",
"required": [
"createdAt"
],
"charactor": {
"type": "object",
"enum": [
"ai",
"manny",
"quinn",
"chinese",
"phoenix",
"kirin",
"leviathan",
"wyvern",
"cerberus",
"dragon",
"kitsune",
"pegasus"
],
"properties": {
"type": "object",
"properties": {
"season": {
"type": "integer",
"minimum": 0,
"maximum": 3,
"default": 1
},
"group": {
"type": "string",
"default": "fantasy",
"enum": [
"origin",
"fantasy",
"animal"
]
},
"gender": {
"type": "string",
"enum": [
"none",
"male",
"famale"
]
},
"fullname": {
"type": "string"
},
"nickname": {
"type": "string"
}
}
}
},
"createdAt": {
"type": "string",
"format": "datetime",
"description": "Client-declared timestamp when this post was originally created."
},
"updatedAt": {
"type": "string",
"format": "datetime"
}
}
}
}
}
}

View File

@ -1,101 +0,0 @@
{
"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","cerberus","chinesedragon","dragon","kirin","kitsune","leviathan","pegasus","phoenix"],
"properties": {
"type": "object",
"properties": {
"group":{
"type": "string"
},
"season":{
"type": "integer"
},
"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"
}
}
}
}
}
}
}

View File

@ -1,30 +0,0 @@
{
"lexicon": 1,
"id": "ai.syui.o.comment",
"defs": {
"main": {
"type": "record",
"description": "Record containing a Frontpage comment.",
"key": "tid",
"record": {
"type": "object",
"required": ["content", "createdAt", "post"],
"properties": {
"content": {
"type": "string",
"maxLength": 100000,
"maxGraphemes": 10000,
"description": "The content of the comment."
},
"createdAt": {
"type": "string",
"format": "datetime",
"description": "Client-declared timestamp when this comment was originally created."
},
"parent": { "type": "ref", "ref": "com.atproto.repo.strongRef" },
"post": { "type": "ref", "ref": "com.atproto.repo.strongRef" }
}
}
}
}
}

View File

@ -1,33 +0,0 @@
{
"lexicon": 1,
"id": "ai.syui.o.post",
"defs": {
"main": {
"type": "record",
"description": "Record containing a Frontpage post.",
"key": "tid",
"record": {
"type": "object",
"required": ["title", "url", "createdAt"],
"properties": {
"title": {
"type": "string",
"maxLength": 3000,
"maxGraphemes": 300,
"description": "The title of the post."
},
"url": {
"type": "string",
"format": "uri",
"description": "The URL of the post."
},
"createdAt": {
"type": "string",
"format": "datetime",
"description": "Client-declared timestamp when this post was originally created."
}
}
}
}
}
}

View File

@ -1,23 +0,0 @@
{
"lexicon": 1,
"id": "ai.syui.o.vote",
"defs": {
"main": {
"type": "record",
"description": "Record containing a Frontpage vote.",
"key": "tid",
"record": {
"type": "object",
"required": ["subject", "createdAt"],
"properties": {
"subject": { "type": "ref", "ref": "com.atproto.repo.strongRef" },
"createdAt": {
"type": "string",
"format": "datetime",
"description": "Client-declared timestamp when this vote was originally created."
}
}
}
}
}
}

View File

@ -1,85 +0,0 @@
diff --git a/services/bsky/api.js b/services/bsky/api.js
index 56c769b9d..5d14c0057 100644
--- a/services/bsky/api.js
+++ b/services/bsky/api.js
@@ -44,19 +44,62 @@ const assert = require('node:assert')
const cluster = require('node:cluster')
const path = require('node:path')
-const { BskyAppView, ServerConfig } = require('@atproto/bsky')
+const bsky = require('@atproto/bsky') // import all bsky features
const { Secp256k1Keypair } = require('@atproto/crypto')
const main = async () => {
const env = getEnv()
- const config = ServerConfig.readEnv()
+ const config = bsky.ServerConfig.readEnv()
assert(env.serviceSigningKey, 'must set BSKY_SERVICE_SIGNING_KEY')
const signingKey = await Secp256k1Keypair.import(env.serviceSigningKey)
- const bsky = BskyAppView.create({ config, signingKey })
- await bsky.start()
+
+// starts: involve logics in packages/dev-env/src/bsky.ts >>>>>>>>>>>>>
+// Separate migration db in case migration changes some connection state that we need in the tests, e.g. "alter database ... set ..."
+ const migrationDb = new bsky.Database({
+ url: env.dbPostgresUrl,
+ schema: env.dbPostgresSchema,
+ })
+ if (env.migration) {
+ await migrationDb.migrateToOrThrow(env.migration)
+ } else {
+ await migrationDb.migrateToLatestOrThrow()
+ }
+ await migrationDb.close()
+
+ const db = new bsky.Database({
+ url: env.dbPostgresUrl,
+ schema: env.dbPostgresSchema,
+ poolSize: 10,
+ })
+
+ const dataplane = await bsky.DataPlaneServer.create(
+ db,
+ env.dataplanePort,
+ config.didPlcUrl
+ )
+
+ const bsync = await bsky.MockBsync.create(db, env.bsyncPort)
+
+// ends: involve logics in packages/dev-env/src/bsky.ts <<<<<<<<<<<<<
+
+ const server = bsky.BskyAppView.create({ config, signingKey })
+// starts: involve logics in packages/dev-env/src/bsky.ts >>>>>>>>>>>>>
+ const sub = new bsky.RepoSubscription({
+ service: env.repoProvider,
+ db,
+ idResolver: dataplane.idResolver,
+ background: new bsky.BackgroundQueue(db),
+ })
+// ends: involve logics in packages/dev-env/src/bsky.ts <<<<<<<<<<<<<
+ await server.start()
+ sub.start() // involve logics in packages/dev-env/src/bsky.ts
// Graceful shutdown (see also https://aws.amazon.com/blogs/containers/graceful-shutdowns-with-ecs/)
const shutdown = async () => {
- await bsky.destroy()
+ await server.destroy()
+ await bsync.destroy()
+ await dataplane.destroy()
+ await sub.destroy()
+ await db.close()
}
process.on('SIGTERM', shutdown)
process.on('disconnect', shutdown) // when clustering
@@ -64,6 +107,12 @@ const main = async () => {
const getEnv = () => ({
serviceSigningKey: process.env.BSKY_SERVICE_SIGNING_KEY || undefined,
+ dbPostgresUrl: process.env.BSKY_DB_POSTGRES_URL || undefined,
+ dbPostgresSchema: process.env.BSKY_DB_POSTGRES_SCHEMA || undefined,
+ dataplanePort : maybeParseInt(process.env.BSKY_DATAPLANE_PORT) || undefined,
+ bsyncPort : maybeParseInt(process.env.BSKY_BSYNC_PORT) || undefined,
+ migration: process.env.ENABLE_MIGRATIONS === 'true' || undefined,
+ repoProvider: process.env.BSKY_REPO_PROVIDER || undefined
})
const maybeParseInt = (str) => {

View File

@ -1,119 +0,0 @@
diff --git a/app/layout.tsx b/app/layout.tsx
index bfc3470..9350629 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -5,6 +5,7 @@ import 'yet-another-react-lightbox/styles.css'
import 'yet-another-react-lightbox/plugins/thumbnails.css'
import 'yet-another-react-lightbox/plugins/captions.css'
import { ToastContainer } from 'react-toastify'
+import { PublicEnvScript } from 'next-runtime-env';
import { Shell } from '@/shell/Shell'
import { CommandPaletteRoot } from '@/shell/CommandPalette/Root'
@@ -36,6 +37,7 @@ export default function RootLayout({
isDarkModeEnabled() ? 'dark' : ''
}`}
>
+ <head>
<title>Ozone</title>
<link
rel="icon"
@@ -43,6 +45,8 @@ export default function RootLayout({
sizes="any"
/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
+ <PublicEnvScript />
+ </head>
<body className="h-full overflow-hidden">
<ToastContainer
position="bottom-right"
diff --git a/environment.d.ts b/environment.d.ts
index 7a47cc2..33ab29f 100644
--- a/environment.d.ts
+++ b/environment.d.ts
@@ -9,6 +9,8 @@ declare global {
NEXT_PUBLIC_OZONE_SERVICE_DID?: string // e.g. did:plc:xxx#atproto_labeler
NEXT_PUBLIC_OZONE_PUBLIC_URL?: string // e.g. https://ozone.example.com (falls back to window.location.origin)
NEXT_PUBLIC_SOCIAL_APP_URL?: string // e.g. https://bsky.app
+ NEXT_PUBLIC_SOCIAL_APP_DOMAIN?: string // e.g. bsky.app
+ NEXT_PUBLIC_HANDLE_RESOLVER_URL?: string // e.g. https://api.bsky.app
}
}
}
diff --git a/lib/constants.ts b/lib/constants.ts
index fe7c0e8..c286ac6 100644
--- a/lib/constants.ts
+++ b/lib/constants.ts
@@ -1,29 +1,32 @@
+import { env } from 'next-runtime-env';
+
export const OAUTH_SCOPE = 'atproto transition:generic'
export const OZONE_SERVICE_DID =
- process.env.NEXT_PUBLIC_OZONE_SERVICE_DID || undefined
+ env('NEXT_PUBLIC_OZONE_SERVICE_DID') || undefined
export const OZONE_PUBLIC_URL =
- process.env.NEXT_PUBLIC_OZONE_PUBLIC_URL || undefined
+ env('NEXT_PUBLIC_OZONE_PUBLIC_URL') || undefined
export const PLC_DIRECTORY_URL =
- process.env.NEXT_PUBLIC_PLC_DIRECTORY_URL ||
+ env('NEXT_PUBLIC_PLC_DIRECTORY_URL') ||
(process.env.NODE_ENV === 'development'
? 'http://localhost:2582'
: 'https://plc.directory')
-export const QUEUE_CONFIG = process.env.NEXT_PUBLIC_QUEUE_CONFIG || '{}'
+export const QUEUE_CONFIG = env('NEXT_PUBLIC_QUEUE_CONFIG') || '{}'
-export const QUEUE_SEED = process.env.NEXT_PUBLIC_QUEUE_SEED || ''
+export const QUEUE_SEED = env('NEXT_PUBLIC_QUEUE_SEED') || ''
+export const SOCIAL_APP_DOMAIN = env('NEXT_PUBLIC_SOCIAL_APP_DOMAIN') || 'bsky.app'
export const SOCIAL_APP_URL =
- process.env.NEXT_PUBLIC_SOCIAL_APP_URL ||
+ env('NEXT_PUBLIC_SOCIAL_APP_URL') ||
(process.env.NODE_ENV === 'development'
? 'http://localhost:2584'
- : 'https://bsky.app')
+ : `https://${SOCIAL_APP_DOMAIN}`)
export const HANDLE_RESOLVER_URL =
- process.env.NEXT_PUBLIC_HANDLE_RESOLVER_URL ||
+ env('NEXT_PUBLIC_HANDLE_RESOLVER_URL') ||
(process.env.NODE_ENV === 'development'
? 'http://localhost:2584'
: 'https://api.bsky.app')
diff --git a/lib/util.ts b/lib/util.ts
index 0aa4460..ecec7d1 100644
--- a/lib/util.ts
+++ b/lib/util.ts
@@ -1,5 +1,5 @@
import { CollectionId } from '@/reports/helpers/subject'
-import { SOCIAL_APP_URL } from './constants'
+import { SOCIAL_APP_URL, SOCIAL_APP_DOMAIN } from './constants'
import { AtUri } from '@atproto/api'
export function classNames(...classes: (string | undefined)[]) {
@@ -57,7 +57,7 @@ export function takesKeyboardEvt(el?: EventTarget | null) {
)
}
-const blueSkyUrlMatcher = new RegExp('(https?://)?.*bsky.app')
+const blueSkyUrlMatcher = new RegExp('(https?://)?.*'+ `${SOCIAL_APP_DOMAIN}`)
export const isBlueSkyAppUrl = (url: string) => blueSkyUrlMatcher.test(url)
diff --git a/package.json b/package.json
index 8919841..750dce9 100644
--- a/package.json
+++ b/package.json
@@ -37,6 +37,7 @@
"kbar": "^0.1.0-beta.45",
"lande": "^1.0.10",
"next": "15.2.4",
+ "next-runtime-env": "^3.2.1",
"react": "19.1.0",
"react-dom": "19.1.0",
"react-dropzone": "^14.3.5",

View File

@ -1,82 +0,0 @@
diff --git a/service/index.js b/service/index.js
index 943c281..7721cd9 100644
--- a/service/index.js
+++ b/service/index.js
@@ -1,5 +1,7 @@
const next = require('next')
-const {
+const ozone = require('@atproto/ozone')
+/*
+{
readEnv,
httpLogger,
envToCfg,
@@ -7,6 +9,7 @@ const {
OzoneService,
Database,
} = require('@atproto/ozone')
+*/
const pkg = require('@atproto/ozone/package.json')
async function main() {
@@ -16,37 +19,48 @@ async function main() {
const frontendHandler = frontend.getRequestHandler()
await frontend.prepare()
// backend
- const env = readEnv()
+ const env = ozone.readEnv()
env.version ??= pkg.version
- const config = envToCfg(env)
- const secrets = envToSecrets(env)
+ const config = ozone.envToCfg(env)
+ const secrets = ozone.envToSecrets(env)
const migrate = process.env.OZONE_DB_MIGRATE === '1'
if (migrate) {
- const db = new Database({
+ const db = new ozone.Database({
url: config.db.postgresUrl,
schema: config.db.postgresSchema,
})
await db.migrateToLatestOrThrow()
await db.close()
}
- const ozone = await OzoneService.create(config, secrets)
+ const server = await ozone.OzoneService.create(config, secrets)
// setup handlers
- ozone.app.get('/.well-known/ozone-metadata.json', (_req, res) => {
+ server.app.get('/.well-known/ozone-metadata.json', (_req, res) => {
return res.json({
- did: ozone.ctx.cfg.service.did,
- url: ozone.ctx.cfg.service.publicUrl,
- publicKey: ozone.ctx.signingKey.did(),
+ did: server.ctx.cfg.service.did,
+ url: server.ctx.cfg.service.publicUrl,
+ publicKey: server.ctx.signingKey.did(),
})
})
// Note: We must use `use()` here. This should be the last middleware.
- ozone.app.use((req, res) => {
+ server.app.use((req, res) => {
void frontendHandler(req, res, undefined)
})
// run
- const httpServer = await ozone.start()
+ const httpServer = await server.start()
+ // starts: involve ops from atproto/packages/dev-env/src/ozone.ts >>>
+ ozone.httpLogger.info('starts ozone daemon')
+ const daemon = await ozone.OzoneDaemon.create(config, secrets)
+ await daemon.start()
+ //if (process.env.OZONE_ENABLE_EVENT_REVERSER != 'true') // atproto/services/ozone/daemon.js doesn't stop eventReverser
+ //{
+ // ozone.httpLogger.info('disable ozone daemon eventReverser')
+ // await daemon.ctx.eventReverser.destroy()
+ //}
+ // ends: involve ops from atproto/packages/dev-env/src/ozone.ts <<<
+
/** @type {import('net').AddressInfo} */
const addr = httpServer.address()
- httpLogger.info(`Ozone is running at http://localhost:${addr.port}`)
+ ozone.httpLogger.info(`Ozone is running at http://localhost:${addr.port}`)
}
main().catch(console.error)

View File

@ -1,10 +0,0 @@
--- a/Dockerfile
+++ b/Dockerfile
@@ -37,6 +37,7 @@ RUN \. "$NVM_DIR/nvm.sh" && \
echo "EXPO_PUBLIC_BUNDLE_IDENTIFIER=$EXPO_PUBLIC_BUNDLE_IDENTIFIER" >> .env && \
echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env && \
npm install --global yarn && \
+ yarn config set network-timeout 600000 && \
yarn && \
yarn intl:build && \
EXPO_PUBLIC_BUNDLE_IDENTIFIER=$EXPO_PUBLIC_BUNDLE_IDENTIFIER EXPO_PUBLIC_BUNDLE_DATE=$() yarn build-web

1
repos/atproto Submodule

Submodule repos/atproto added at 8f2b80a0dc

Submodule repos/bluesky-selfhost-env added at 3e384e3b58

1
repos/cookbook Submodule

Submodule repos/cookbook added at 03739f5268

1
repos/did-method-plc Submodule

Submodule repos/did-method-plc added at 13da315787

1
repos/feed-generator Submodule

Submodule repos/feed-generator added at 9a887dd8f2

1
repos/social-app Submodule

Submodule repos/social-app added at f6649e22a7

View File

@ -1,4 +1,4 @@
FROM node:21
FROM node:20
RUN npm install -g pnpm
WORKDIR /app

View File

@ -3,4 +3,4 @@ services:
build:
context: .
ports:
- 3001:13213
- 3000:13213

View File

@ -1,47 +1,15 @@
import { defineConfig } from "vite";
import solidPlugin from "vite-plugin-solid";
import UnoCSS from "unocss/vite";
import metadata from "./public/client-metadata.json";
const SERVER_HOST = "0.0.0.0";
const SERVER_PORT = 13213;
export default defineConfig({
plugins: [
UnoCSS(),
solidPlugin(),
// Injects OAuth-related variables
{
name: "oauth",
config(_conf, { command }) {
if (command === "build") {
process.env.VITE_OAUTH_CLIENT_ID = metadata.client_id;
process.env.VITE_OAUTH_REDIRECT_URL = metadata.redirect_uris[0];
} else {
const redirectUri = ((): string => {
const url = new URL(metadata.redirect_uris[0]);
return `http://${SERVER_HOST}:${SERVER_PORT}${url.pathname}`;
})();
const clientId =
`http://localhost` +
`?redirect_uri=${encodeURIComponent(redirectUri)}` +
`&scope=${encodeURIComponent(metadata.scope)}`;
process.env.VITE_DEV_SERVER_PORT = "" + SERVER_PORT;
process.env.VITE_OAUTH_CLIENT_ID = clientId;
process.env.VITE_OAUTH_REDIRECT_URL = redirectUri;
}
process.env.VITE_CLIENT_URI = metadata.client_uri;
process.env.VITE_OAUTH_SCOPE = metadata.scope;
},
},
],
plugins: [UnoCSS(), solidPlugin()],
server: {
host: SERVER_HOST,
port: SERVER_PORT,
allowedHosts: ['pds.syu.is'],
},
build: {
target: "esnext",

View File

@ -4,14 +4,11 @@ d=${0:a:h}
source $d/src/tag.zsh
source $d/src/func.zsh
source $d/src/ue.zsh
source $d/src/ai/syui/game/character.zsh
source $d/src/is/syu/main.zsh
at-env
case $1 in
version|v)
at-version $2
at-version
;;
uri|u)
at-uri $2
@ -41,34 +38,16 @@ case $1 in
at-profile
;;
download-character-icon)
source $d/ai/syui/game/character.zsh
download_character_icon
;;
create-game-character)
source $d/ai/syui/game/character.zsh
create_game_character
;;
create-game-user)
create_game_user $2
;;
create-system)
create_system
;;
get-game-user)
get_game_user $2
;;
delete-game-user)
delete_game_user $2 $3
;;
verify-icon)
verify-icon
;;
self-col)
self-col $2
;;
ue-system)
ue-system
;;
ue-user)
ue-user $2
ai-create-user)
source $d/ai/syui/game/character.zsh
ai_create_user
;;
*)
echo "${help[@]}"

View File

@ -1,10 +0,0 @@
import json
record = {
"$type": "app.bsky.feed.post",
"text": "テスト投稿 from script",
"createdAt": "2025-05-26T12:00:00Z"
}
with open("record.json", "w", encoding="utf-8") as f:
json.dump(record, f, ensure_ascii=False, indent=2)

View File

@ -1,3 +1,33 @@
character=(
ai
manny
quinn
chinese
kirin
leviathan
phoenix
wyvern
cerberus
dragon
kitsune
pegasus
)
img=(
bafkreie34pjuc6coenzcdwrgrh4fbacq7bkhsz263g5vpbsqxwaz37kkwy
bafkreie34pjuc6coenzcdwrgrh4fbacq7bkhsz263g5vpbsqxwaz37kkwy
bafkreie34pjuc6coenzcdwrgrh4fbacq7bkhsz263g5vpbsqxwaz37kkwy
bafkreidlealfybajqzwv5eoz4jshnsijc2vnktlhpw4ph47krwj6aigqby
bafkreiegpqedlrfa4ljhssdnkrr5hyd5huy2xhh2zszj5wq2wuuzejggmq
bafkreig6vszkx3c4dcortjwfsz6sa6zwqgj7zpxj4lxfrrkwql4xhiu5ou
bafkreich7fsumke2yvumvixkruonzrcevk3f6g2cntzfwdn4n2c2vox5dm
bafkreiacjvagsekhiiljz3j237b6klrt6pkptxljt7kltprgg5276gv25q
bafkreihpni4lp55jysalcntulzal5rbhidtbseanlucpyucagzxmv6xj24
bafkreia3huw2gdenqatoobx3hcft74chced46bw4znfgepo5aenegobkri
bafkreidy74aieb6ie646xhosginox5zbnbnrtd76cnt4pbn73hrxgfnple
bafkreifnbfj27fr6nv7qeqqmwdibf7qrw4lauvzoknw5hexbifmwqt6kmq
)
function download_character_icon(){
t=(
@ -159,85 +189,35 @@ json="{
}
function get_game_user() {
rkey=$did.$pds
pds=bsky.social
if [ "$1" = "syui" ] || [ "$1" = "ai" ];then
rkey=$1
fi
req=com.atproto.repo.getRecord
url="https://$pds/xrpc/$req?rkey=$rkey&repo=$did_yui&collection=ai.syui.game"
curl -sL $url|jq .
}
function ai_create_user() {
delete_game_user() {
rkey=$2
if [ -z "$1" ];then
col=ai.syui.game
else
col=$1
fi
req=com.atproto.repo.DeleteRecord
url=https://$pds/xrpc/$req
repo=$did
#repo=did:plc:6qyecktefllvenje24fcxnie
json="{\"collection\":\"$col\", \"rkey\":\"$rkey\", \"repo\":\"$repo\"}"
echo $json
curl -sL -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $token" -d $json $url
}
function create_game_user() {
col=ai.syui.game
rkey=$1
handle_yui=$handle
did_yui=$did
pds=`cat $f|jq -r ".didDoc.service.[].serviceEndpoint"|cut -d / -f 3`
if [ "$pds" != "syu.is" ];then
pds=bsky.social
fi
version=4
col=ai.syui.game.user
rkey=ai
did=$did_yui
handle=$handle_yui
#rkey=syui
#img=https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:4hqjfn7m6n5hno3doamuhgef/bafkreie34pjuc6coenzcdwrgrh4fbacq7bkhsz263g5vpbsqxwaz37kkwy@jpeg
req=com.atproto.repo.putRecord
url=https://$pds/xrpc/$req
url=https://$host/xrpc/$req
cname=dragon
cid=bafkreia3huw2gdenqatoobx3hcft74chced46bw4znfgepo5aenegobkri
for ((i=1; i<=${#character}; i++)); do
if [ "$rkey" = "ai" ];then
cname=$rkey
cid=bafkreie34pjuc6coenzcdwrgrh4fbacq7bkhsz263g5vpbsqxwaz37kkwy
gender=none
fi
if [ "$rkey" = "syui" ];then
cname=chinese
did=$did_syui
handle=syui.ai
cid=bafkreidlealfybajqzwv5eoz4jshnsijc2vnktlhpw4ph47krwj6aigqby
gender=male
fi
if [ "$rkey" = "self" ];then
cname=manny
unset did handle gender
pds=bsky.social
plc=plc.directory
fi
cname=${character[$i]}
cid=${img[$i]}
imguri=https://cdn.bsky.app/img/feed_thumbnail/plain/$did_yui/${cid}@jpeg
echo $imguri
echo $i $character $cname
season=1
group=test
lv=1
hp=1
hp=100
exp=0
rare=0
rank=0
mode=0
attack=0
attack_post=0
critical=0
critical_d=0
card=0
weapon=0
coin=0
count=0
case $cname in
ai)
@ -253,10 +233,16 @@ function create_game_user() {
;;
esac
json="\"$cname\": { \"group\": \"$group\", \"season\": $season, \"lv\": $lv, \"exp\": $exp, \"hp\": $hp, \"mode\": $mode, \"attack\": $attack, \"critical\": $critical, \"critical_d\": $critical_d, \"card\": $card, \"coin\": $coin, \"weapon\": $weapon, \"count\": $count, \"rare\": $rare}"
#json="\"$cname\": { \"group\": \"$group\", \"season\": $season, \"img\": \"$imguri\", \"lv\": $lv, \"exp\": $exp, \"hp\": $hp, \"rank\": $rank, \"mode\": $mode, \"attack\": $attack, \"attack_post\": $attack_post, \"critical\": $critical, \"critical_d\": $critical_d }"
jc="\"$cname\": { \"group\": \"$group\", \"season\": $season, \"img\": \"$imguri\", \"lv\": $lv, \"exp\": $exp, \"hp\": $hp, \"rank\": $rank, \"mode\": $mode, \"attack\": $attack, \"attack_post\": $attack_post, \"critical\": $critical, \"critical_d\": $critical_d }"
v1_json="
if [ $#character -ne $i ];then
jc=${jc},
fi
json=${json}${jc}
done
json="
{
\"repo\": \"$handle_yui\",
\"did\": \"$did_yui\",
@ -268,7 +254,7 @@ function create_game_user() {
\"login\": false,
\"handle\": \"$handle\",
\"aiten\": 10,
\"gender\": \"$gender\",
\"gender\": \"famale\",
\"character\": {
$json
},
@ -277,11 +263,19 @@ function create_game_user() {
}
}"
json_item="
\"coin\": [{\"id\": 0, \"cp\": 0, \"rare\": 0, \"count\": 0}],
\"card\": [{\"id\": 0, \"cp\": 0, \"rare\": 0, \"count\": 0}],
\"weapon\": [{\"id\": 0, \"cp\": 0, \"rare\": 0, \"count\": 0}]
"
if echo $json|jq . ;then
echo $token_yui
echo y
read y
if [ "y" = "$y" ];then
curl -sL -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $token_yui" -d $json $url
fi
fi
col=ai.syui.game
rkey=self
at_uri=at://$did_yui/ai.syui.game.user/ai
json="
{
@ -290,25 +284,9 @@ json_item="
\"collection\": \"$col\",
\"rkey\": \"$rkey\",
\"record\": {
\"version\": $version,
\"did\": \"$did\",
\"handle\": \"$handle\",
\"plc\": \"$plc\",
\"pds\": \"$pds\",
\"player\": {
\"limit\": false,
\"login\": false,
\"ten\": 0,
\"gender\": \"$gender\"
},
\"character\": {
$json
},
\"item\": {
$json_item
},
\"createdAt\": \"${created}\",
\"updatedAt\": \"${created}\"
\"account\": \"$at_uri\",
\"username\": \"ai\",
\"createdAt\": \"$created\"
}
}"
@ -316,62 +294,9 @@ if echo $json|jq . ;then
echo y
read y
if [ "y" = "$y" ];then
t=`curl -sL -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $token" -d $json $url`
echo $t|jq .
#f=~/ai/ue/json/v${version}_${rkey}.json
#if [ -f $f ];then
# get_game_user $rkey >! $f
#fi
curl -sL -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $token_yui" -d $json $url
fi
fi
}
function create_system() {
col=ai.syui.system
rkey=self
did=$did
handle=$handle
pds=`cat $f|jq -r ".didDoc.service.[].serviceEndpoint"|cut -d / -f 3`
if [ "$pds" != "syu.is" ];then
pds=bsky.social
fi
version=1
#rkey=syui
#img=https://cdn.bsky.app/img/feed_thumbnail/plain/did:plc:4hqjfn7m6n5hno3doamuhgef/bafkreie34pjuc6coenzcdwrgrh4fbacq7bkhsz263g5vpbsqxwaz37kkwy@jpeg
req=com.atproto.repo.putRecord
url=https://$pds/xrpc/$req
#cid=bafkreia3huw2gdenqatoobx3hcft74chced46bw4znfgepo5aenegobkri
#imguri=https://cdn.bsky.app/img/feed_thumbnail/plain/$did_yui/${cid}@jpeg
imgurl=https://git.syui.ai/ai/ai/raw/branch/main/img/item/card
json_card=" \"id\": $id, \"name\": \"$name\", \"img\": \"${imgurl}/${id}.webp\""
json_card=`curl -sL https://git.syui.ai/ai/ai/raw/branch/main/json/card.json|jq ".[]"`
json_weapon=`curl -sL https://git.syui.ai/ai/ai/raw/branch/main/json/weapon.json|jq ".[]"`
json_system=`curl -sL https://git.syui.ai/ai/ai/raw/branch/main/json/system.json|jq ".[]"`
json_character=`curl -sL https://git.syui.ai/ai/ai/raw/branch/main/json/character.json|jq ".[]"`
json_ability=`curl -sL https://git.syui.ai/ai/ai/raw/branch/main/json/ability.json|jq ".[]"`
json="
{
\"repo\": \"$handle\",
\"did\": \"$did\",
\"collection\": \"$col\",
\"rkey\": \"$rkey\",
\"record\": {
\"card\": ${json_card},
\"weapon\": ${json_weapon},
\"system\": ${json_system},
\"character\": ${json_character},
\"ability\": ${json_ability},
\"createdAt\": \"${created}\",
\"updatedAt\": \"${created}\"
}
}"
if echo $json|jq . ;then
echo y
read y
if [ "y" = "$y" ];then
t=`curl -sL -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $token" -d $json $url`
echo $t|jq .
fi
fi
}

View File

@ -1,76 +1,33 @@
function at-env() {
pds=bsky.social
plc=plc.directory
host=https://bsky.social
host=bsky.social
handle_syui=syui.ai
handle_yui=yui.syui.ai
did_yui=did:plc:4hqjfn7m6n5hno3doamuhgef
did_syui=did:plc:uqzpqmrjnptsxezjx4xuh2mn
handle=$handle_yui
did=$did_yui
created=2025-04-21T00:00:00.323Z
created=2020-01-01T00:00:00+09:00
at_uri=at://$did_yui/ai.syui.game.user/syui
docs_uri=https://docs.bsky.app/docs/api
at_uri=at://$handle/ai.syui.game/ai
did=`echo $at_uri|cut -d / -f 3`
collection=`echo $at_uri|cut -d / -f 4`
rkey=`echo $at_uri|cut -d / -f 5`
d=${0:a:h}
f=~/.config/ai/token.json
f=~/.config/.at-zsh.json
if [ -f $f ];then
host=`cat $f|jq -r ".didDoc.service.[].serviceEndpoint"|cut -d / -f 3`
token=`cat $f|jq -r .accessJwt`
did=`cat $f|jq -r .did`
handle=`cat $f|jq -r .handle`
actor=$did
fi
if [ "$host" = "syu.is" ];then
plc=plc.syu.is
pds=$host
fi
}
function at-unset() {
unset t password token refresh
}
function at-version-env() {
case $1 in
bsky)
tag=$1
list=( public.api.bsky.app bsky.syu.is )
;;
ozone)
tag=$1
list=( ozone.bsky.social ozone.syu.is )
;;
*)
tag=pds
list=( bsky.social syu.is socl.is )
;;
esac
title="atproto $tag version"
latest=https://raw.githubusercontent.com/bluesky-social/atproto/refs/heads/main/packages/$tag/package.json
latest=`curl -sL $latest |jq -r .version`
# bgs=( bsky.network bgs.syu.is )
# plc=( plc.directory plc.syu.is )
}
function at-version-json() {
echo "[{\"title\":\"$title\",\"latest\":\"$latest\"},["
e=${list[@]: -1}
for i in $list; do
t=`curl -sL ${i}/xrpc/_health |jq -r .version`
echo "{\"$i\":\"$t\"}"
if [ "$e" != "$i" ];then
echo ,
fi
done
echo "]]"
}
function at-version() {
at-version-env
at-version-json|jq .
curl -sL ${host}/xrpc/_health |jq .
}
function at-uri() {
@ -141,7 +98,7 @@ function at-refresh() {
echo $f
token=`cat $f|jq -r .refreshJwt`
req=/xrpc/com.atproto.server.refreshSession
url=${host}${req}
url=https://${host}${req}
t=`curl -sL -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $token" $url`
if echo $t |jq .;then
echo $t >! $f
@ -152,13 +109,13 @@ function at-cid() {
did=`at-did $1|jq -r .did`
cid=$2
req=/xrpc/com.atproto.sync.getBlob
url="${host}${req}?did=${did}&cid=${cid}"
url="https://${host}${req}?did=${did}&cid=${cid}"
curl -sL $url
}
function at-session() {
req=/xrpc/com.atproto.server.getSession
url=${host}${req}
url=https://${host}${req}
t=`curl -sL -X GET -H "Content-Type: application/json" -H "Authorization: Bearer $token" $url`
if ! echo $t |jq .;then
echo refresh
@ -174,35 +131,6 @@ function at-profile() {
t=`at-session`
fi
req=/xrpc/app.bsky.actor.getProfile
url="${host}${req}?actor=$did"
url="https://${host}${req}?actor=$did"
curl -sL -X GET -H "Content-Type: application/json" -H "Authorization: Bearer $token" $url|jq .
}
function verify-icon() {
syuisadmin_handle=ai.syu.is
syuisadmin_did=did:plc:6qyecktefllvenje24fcxnie
#rkey=
col=app.bsky.graph.verification
handle=syui.syu.is
subject=did:plc:vzsvtbtbnwn22xjqhcu3vd6y
displayName=syui
req=/xrpc/com.atproto.repo.createRecord
url=${host}${req}
json="
{
\"repo\": \"$syuisadmin_handle\",
\"did\": \"$syuisadmin_did\",
\"collection\": \"$col\",
\"record\": {
\"subject\": \"$subject\",
\"handle\": \"$handle\",
\"displayName\": \"$displayName\",
\"createdAt\": \"${created}\"
}
}"
if echo $json|jq . ;then
t=`curl -sL -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $token" -d $json $url`
echo $t
fi
}

View File

@ -1,18 +0,0 @@
#!/bin/zsh
function self-col(){
if [ -n "$1" ];then
t=`curl -sL "$pds/xrpc/com.atproto.repo.listRecords?repo=$handle&collection=$1"`
echo $t|jq .
exit
fi
col=(
ai.syui.game
ai.syui.system
)
e=${col[@]: -1}
for i in $col; do
t=`curl -sL "$pds/xrpc/com.atproto.repo.listRecords?repo=$handle&collection=$i"`
echo $t|jq .
done
}

View File

@ -37,34 +37,3 @@ github=(
https://github.com/did-method-plc/did-method-plc
)
tag=( at bsky bsync pds bgs plc ozone feed jetstream social-app oauth )
#pds_list=(bsky.social syu.is boobee.blue socl.is )
character=(
ai
manny
quinn
chinese
kirin
leviathan
phoenix
wyvern
cerberus
dragon
kitsune
pegasus
)
character_img=(
bafkreie34pjuc6coenzcdwrgrh4fbacq7bkhsz263g5vpbsqxwaz37kkwy
bafkreie34pjuc6coenzcdwrgrh4fbacq7bkhsz263g5vpbsqxwaz37kkwy
bafkreie34pjuc6coenzcdwrgrh4fbacq7bkhsz263g5vpbsqxwaz37kkwy
bafkreidlealfybajqzwv5eoz4jshnsijc2vnktlhpw4ph47krwj6aigqby
bafkreiegpqedlrfa4ljhssdnkrr5hyd5huy2xhh2zszj5wq2wuuzejggmq
bafkreig6vszkx3c4dcortjwfsz6sa6zwqgj7zpxj4lxfrrkwql4xhiu5ou
bafkreich7fsumke2yvumvixkruonzrcevk3f6g2cntzfwdn4n2c2vox5dm
bafkreiacjvagsekhiiljz3j237b6klrt6pkptxljt7kltprgg5276gv25q
bafkreihpni4lp55jysalcntulzal5rbhidtbseanlucpyucagzxmv6xj24
bafkreia3huw2gdenqatoobx3hcft74chced46bw4znfgepo5aenegobkri
bafkreidy74aieb6ie646xhosginox5zbnbnrtd76cnt4pbn73hrxgfnple
bafkreifnbfj27fr6nv7qeqqmwdibf7qrw4lauvzoknw5hexbifmwqt6kmq
)

View File

@ -1,193 +0,0 @@
case $OSTYPE in
darwin*)
day=`gdate --iso-8601=seconds`
;;
*)
day=`date --iso-8601=seconds`
;;
esac
function get_game_user() {
rkey=$did.$pds
pds=bsky.social
if [ "$1" = "syui" ] || [ "$1" = "ai" ];then
rkey=$1
fi
req=com.atproto.repo.getRecord
url="https://$pds/xrpc/$req?rkey=$rkey&repo=$did_yui&collection=ai.syui.game"
curl -sL $url|jq .
}
function delete_game_user() {
rkey=$2
if [ -z "$1" ];then
col=ai.syui.game
else
col=$1
fi
req=com.atproto.repo.DeleteRecord
url=https://$pds/xrpc/$req
repo=$did
#repo=did:plc:6qyecktefllvenje24fcxnie
json="{\"collection\":\"$col\", \"rkey\":\"$rkey\", \"repo\":\"$repo\"}"
echo $json
curl -sL -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $token" -d $json $url
}
function ue-user() {
col=ai.syui.game
rkey=$1
handle_yui=$handle
did_yui=$did
pds=`cat $f|jq -r ".didDoc.service.[].serviceEndpoint"|cut -d / -f 3`
if [ "$pds" != "syu.is" ];then
pds=bsky.social
fi
version=4
#rkey=syui
req=com.atproto.repo.putRecord
url=https://$pds/xrpc/$req
cname=dragon
if [ "$rkey" = "ai" ];then
cname=$rkey
gender=none
fi
if [ "$rkey" = "syui" ];then
cname=chinese
did=$did_syui
handle=syui.ai
gender=male
fi
if [ "$rkey" = "self" ];then
cname=manny
unset did handle gender
pds=bsky.social
plc=plc.directory
fi
season=1
group=test
lv=1
hp=1
exp=0
rare=0
mode=0
attack=0
attack_post=0
critical=0
critical_d=0
card=0
weapon=0
coin=0
count=0
case $cname in
ai)
group=origin
season=0
mode=2
;;
manny|quinn)
group=test
;;
*)
group=fantasy
;;
esac
json_item="
\"coin\": [{\"id\": 0, \"cp\": 0, \"rare\": 0, \"count\": 0}],
\"card\": [{\"id\": 0, \"cp\": 0, \"rare\": 0, \"count\": 0}],
\"weapon\": [{\"id\": 0, \"cp\": 0, \"rare\": 0, \"count\": 0}]
"
json="
{
\"repo\": \"$handle_yui\",
\"did\": \"$did_yui\",
\"collection\": \"$col\",
\"rkey\": \"$rkey\",
\"record\": {
\"version\": $version,
\"did\": \"$did\",
\"handle\": \"$handle\",
\"plc\": \"$plc\",
\"pds\": \"$pds\",
\"player\": {
\"limit\": false,
\"login\": false,
\"ten\": 0,
\"gender\": \"$gender\"
},
\"character\": {
$json
},
\"item\": {
$json_item
},
\"createdAt\": \"${created}\",
\"updatedAt\": \"${created}\"
}
}"
if echo $json|jq . ;then
echo y
read y
if [ "y" = "$y" ];then
t=`curl -sL -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $token" -d $json $url`
echo $t|jq .
#f=~/ai/ue/json/v${version}_${rkey}.json
#if [ -f $f ];then
# get_game_user $rkey >! $f
#fi
fi
fi
}
function ue-system() {
col=ai.syui.system
rkey=self
did=$did
handle=$handle
pds=`cat $f|jq -r ".didDoc.service.[].serviceEndpoint"|cut -d / -f 3`
if [ "$pds" != "syu.is" ];then
pds=bsky.social
fi
version=1
#rkey=syui
req=com.atproto.repo.putRecord
url=https://$pds/xrpc/$req
imgurl=https://git.syui.ai/ai/ai/raw/branch/main/img/item/card
json_card=" \"id\": $id, \"name\": \"$name\", \"img\": \"${imgurl}/${id}.webp\""
json_card=`curl -sL https://git.syui.ai/ai/ai/raw/branch/main/json/card.json|jq ".[]"`
json_weapon=`curl -sL https://git.syui.ai/ai/ai/raw/branch/main/json/weapon.json|jq ".[]"`
json_system=`curl -sL https://git.syui.ai/ai/ai/raw/branch/main/json/system.json|jq ".[]"`
json_character=`curl -sL https://git.syui.ai/ai/ai/raw/branch/main/json/character.json|jq ".[]"`
json_ability=`curl -sL https://git.syui.ai/ai/ai/raw/branch/main/json/ability.json|jq ".[]"`
json="
{
\"repo\": \"$handle\",
\"did\": \"$did\",
\"collection\": \"$col\",
\"rkey\": \"$rkey\",
\"record\": {
\"card\": ${json_card},
\"weapon\": ${json_weapon},
\"system\": ${json_system},
\"character\": ${json_character},
\"ability\": ${json_ability},
\"createdAt\": \"${created}\",
\"updatedAt\": \"${created}\"
}
}"
if echo $json|jq . ;then
echo y
read y
if [ "y" = "$y" ];then
t=`curl -sL -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $token" -d $json $url`
echo $t|jq .
fi
fi
}