Make massive progress towards deployment
156
Cargo.lock
generated
|
@ -1,6 +1,6 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "ab_glyph"
|
||||
|
@ -673,6 +673,27 @@ dependencies = [
|
|||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv"
|
||||
version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acdc4883a9c96732e4733212c01447ebd805833b7275a73ca3ee080fd77afdaf"
|
||||
dependencies = [
|
||||
"csv-core",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv-core"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.20.10"
|
||||
|
@ -715,7 +736,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"hashbrown 0.14.5",
|
||||
"hashbrown",
|
||||
"lock_api",
|
||||
"once_cell",
|
||||
"parking_lot_core",
|
||||
|
@ -1433,7 +1454,7 @@ dependencies = [
|
|||
"futures-sink",
|
||||
"futures-util",
|
||||
"http 0.2.12",
|
||||
"indexmap 2.5.0",
|
||||
"indexmap",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
|
@ -1452,7 +1473,7 @@ dependencies = [
|
|||
"futures-core",
|
||||
"futures-sink",
|
||||
"http 1.1.0",
|
||||
"indexmap 2.5.0",
|
||||
"indexmap",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
|
@ -1471,12 +1492,6 @@ dependencies = [
|
|||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
|
@ -1492,7 +1507,7 @@ version = "0.9.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af"
|
||||
dependencies = [
|
||||
"hashbrown 0.14.5",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1507,12 +1522,6 @@ version = "0.3.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.2.12"
|
||||
|
@ -1693,16 +1702,6 @@ dependencies = [
|
|||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hypertesseract"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/BlueGhostGH/hypertesseract.git?rev=4e05063#4e050634f50a58b9be85018439a0b1a23b59de35"
|
||||
dependencies = [
|
||||
"image 0.25.2",
|
||||
"sys",
|
||||
"thin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.61"
|
||||
|
@ -1832,17 +1831,6 @@ dependencies = [
|
|||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"hashbrown 0.12.3",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.5.0"
|
||||
|
@ -1850,8 +1838,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.14.5",
|
||||
"serde",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2060,15 +2047,6 @@ version = "2.7.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "memmap2"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.3.17"
|
||||
|
@ -2628,25 +2606,25 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "poise"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1819d5a45e3590ef33754abce46432570c54a120798bdbf893112b4211fa09a6"
|
||||
source = "git+https://github.com/serenity-rs/poise?rev=80a3a9c3ca1629725f0fa4ec98372d39cf36f6b6#80a3a9c3ca1629725f0fa4ec98372d39cf36f6b6"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"derivative",
|
||||
"futures-util",
|
||||
"indexmap",
|
||||
"parking_lot",
|
||||
"poise_macros",
|
||||
"regex",
|
||||
"serenity",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"trim-in-place",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "poise_macros"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fa2c123c961e78315cd3deac7663177f12be4460f5440dbf62a7ed37b1effea"
|
||||
source = "git+https://github.com/serenity-rs/poise?rev=80a3a9c3ca1629725f0fa4ec98372d39cf36f6b6#80a3a9c3ca1629725f0fa4ec98372d39cf36f6b6"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
|
@ -3363,9 +3341,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.128"
|
||||
version = "1.0.138"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8"
|
||||
checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
|
@ -3404,41 +3382,11 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_with"
|
||||
version = "3.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"chrono",
|
||||
"hex",
|
||||
"indexmap 1.9.3",
|
||||
"indexmap 2.5.0",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"serde_with_macros",
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_with_macros"
|
||||
version = "3.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serenity"
|
||||
version = "0.12.2"
|
||||
version = "0.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "880a04106592d0a8f5bdacb1d935889bfbccb4a14f7074984d9cd857235d34ac"
|
||||
checksum = "3d72ec4323681bf9a3cabe40fd080abc2435859b502a1b5aa9bf693f125bfa76"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"async-trait",
|
||||
|
@ -3496,16 +3444,16 @@ dependencies = [
|
|||
"anyhow",
|
||||
"axum",
|
||||
"base16ct",
|
||||
"base64 0.22.1",
|
||||
"chrono",
|
||||
"clap",
|
||||
"csv",
|
||||
"discord-rich-presence",
|
||||
"faer",
|
||||
"freetype-rs",
|
||||
"hypertesseract",
|
||||
"image 0.25.2",
|
||||
"imageproc",
|
||||
"include_dir",
|
||||
"memmap2",
|
||||
"num",
|
||||
"paste",
|
||||
"plotters",
|
||||
|
@ -3517,7 +3465,7 @@ dependencies = [
|
|||
"rusqlite",
|
||||
"rusqlite_migration",
|
||||
"serde",
|
||||
"serde_with",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"tempfile",
|
||||
"tokio",
|
||||
|
@ -3656,16 +3604,6 @@ dependencies = [
|
|||
"futures-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sys"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/BlueGhostGH/hypertesseract.git?rev=4e05063#4e050634f50a58b9be85018439a0b1a23b59de35"
|
||||
dependencies = [
|
||||
"openssl-sys",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sysctl"
|
||||
version = "0.5.5"
|
||||
|
@ -3760,14 +3698,6 @@ dependencies = [
|
|||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thin"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/BlueGhostGH/hypertesseract.git?rev=4e05063#4e050634f50a58b9be85018439a0b1a23b59de35"
|
||||
dependencies = [
|
||||
"sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.64"
|
||||
|
@ -3970,7 +3900,7 @@ version = "0.22.21"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b072cee73c449a636ffd6f32bd8de3a9f7119139aff882f44943ce2986dc5cf"
|
||||
dependencies = [
|
||||
"indexmap 2.5.0",
|
||||
"indexmap",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
|
@ -4052,6 +3982,12 @@ dependencies = [
|
|||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "trim-in-place"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "343e926fc669bc8cde4fa3129ab681c63671bae288b1f1081ceee6d9d37904fc"
|
||||
|
||||
[[package]]
|
||||
name = "triomphe"
|
||||
version = "0.1.13"
|
||||
|
@ -4117,7 +4053,7 @@ checksum = "5dece5c06268af6a9ff4541788601e560a4284ffebfb357f713d676f13b964db"
|
|||
dependencies = [
|
||||
"chrono",
|
||||
"dashmap",
|
||||
"hashbrown 0.14.5",
|
||||
"hashbrown",
|
||||
"mini-moka",
|
||||
"parking_lot",
|
||||
"secrecy",
|
||||
|
|
|
@ -30,8 +30,7 @@ freetype-rs = "0.36.0"
|
|||
image = "0.25.2"
|
||||
num = "0.4.3"
|
||||
plotters = { git="https://github.com/starlitcanopy/plotters.git", rev="986cd959362a2dbec8d1b25670fd083b904d7b8c", features=["bitmap_backend"] }
|
||||
poise = "0.6.1"
|
||||
hypertesseract = { features=["image"], git="https://github.com/BlueGhostGH/hypertesseract.git", rev="4e05063" }
|
||||
poise = {git="https://github.com/serenity-rs/poise", rev="80a3a9c3ca1629725f0fa4ec98372d39cf36f6b6"}
|
||||
tokio = {version="1.38.0", features=["rt-multi-thread"]}
|
||||
imageproc = "0.25.0"
|
||||
rusqlite = { version = "0.32.1", features = ["bundled", "chrono"] }
|
||||
|
@ -44,7 +43,6 @@ toml = "0.8.19"
|
|||
tempfile = "3.12.0"
|
||||
clap = { version = "4.5.17", features = ["derive"] }
|
||||
postcard = { version = "1.0.10", features = ["use-std"], default-features = false }
|
||||
serde_with = "3.9.0"
|
||||
anyhow = "1.0.87"
|
||||
sha2 = "0.10.8"
|
||||
base16ct = { version = "0.2.0", features = ["alloc"] }
|
||||
|
@ -53,7 +51,9 @@ paste = "1.0.15"
|
|||
discord-rich-presence = "0.2.4"
|
||||
reqwest = { version = "0.12.7", features = ["json"] }
|
||||
faer = { git = "https://github.com/sarah-ek/faer-rs", rev = "4f3eb7e65c69f7f7df3bdd93aa868d5666db3656", features = ["serde"] }
|
||||
memmap2 = "0.9.5"
|
||||
csv = "1.3.1"
|
||||
serde_json = "1.0.138"
|
||||
base64 = "0.22.1"
|
||||
|
||||
[profile.dev.package.imageproc]
|
||||
opt-level = 3
|
||||
|
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 4 KiB After Width: | Height: | Size: 4 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
Before Width: | Height: | Size: 752 B After Width: | Height: | Size: 752 B |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 5 KiB After Width: | Height: | Size: 5 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
1418
config/notecounts.csv
Normal file
46
flake.lock
|
@ -8,11 +8,11 @@
|
|||
"rust-analyzer-src": "rust-analyzer-src"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1727073227,
|
||||
"narHash": "sha256-1kmkEQmFfGVuPBasqSZrNThqyMDV1SzTalQdRZxtDRs=",
|
||||
"lastModified": 1739169164,
|
||||
"narHash": "sha256-2+/6/2rHsMjlrulkrjZbwthCQiQpeW2pukRFaaUMLy8=",
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"rev": "88cc292eb3c689073c784d6aecc0edbd47e12881",
|
||||
"rev": "d7616af878cd0cb7f940b470440347920395be0c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -41,11 +41,11 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1726937504,
|
||||
"narHash": "sha256-bvGoiQBvponpZh8ClUcmJ6QnsNKw0EMrCQJARK3bI1c=",
|
||||
"lastModified": 1739020877,
|
||||
"narHash": "sha256-mIvECo/NNdJJ/bXjNqIh8yeoSjVLAuDuTUzAo7dzs8Y=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "9357f4f23713673f310988025d9dc261c20e70c6",
|
||||
"rev": "a79cfe0ebd24952b580b1cf08cd906354996d547",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -60,17 +60,17 @@
|
|||
"fenix": "fenix",
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"rust-overlay": "rust-overlay"
|
||||
"shimmeringdarkness": "shimmeringdarkness"
|
||||
}
|
||||
},
|
||||
"rust-analyzer-src": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1726443025,
|
||||
"narHash": "sha256-nCmG4NJpwI0IoIlYlwtDwVA49yuspA2E6OhfCOmiArQ=",
|
||||
"lastModified": 1739099919,
|
||||
"narHash": "sha256-YUdM2yZzQIbakgc2LdVmkgJMYTqeTu3YdWGgFfiZiTg=",
|
||||
"owner": "rust-lang",
|
||||
"repo": "rust-analyzer",
|
||||
"rev": "94b526fc86eaa0e90fb4d54a5ba6313aa1e9b269",
|
||||
"rev": "35181e167efb94d5090df588e6af9f93250421f3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -80,24 +80,20 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"rust-overlay": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"shimmeringdarkness": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1727058553,
|
||||
"narHash": "sha256-tY/UU3Qk5gP/J0uUM4DZ6wo4arNLGAVqLKBotILykfQ=",
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"rev": "edc5b0f896170f07bd39ad59d6186fcc7859bbb2",
|
||||
"type": "github"
|
||||
"lastModified": 1739242531,
|
||||
"narHash": "sha256-OYLvznlkZRjeUdMG1LqifYY0Mo4/SHZInMxmzG1KsqU=",
|
||||
"ref": "refs/heads/main",
|
||||
"rev": "ded8a4858e8815db29bfa5bc1d700bd635b2327c",
|
||||
"revCount": 4,
|
||||
"type": "git",
|
||||
"url": "ssh://forgejo@ssh.git.moonythm.dev/prescientmoon/shimmeringdarkness.git"
|
||||
},
|
||||
"original": {
|
||||
"owner": "oxalica",
|
||||
"repo": "rust-overlay",
|
||||
"type": "github"
|
||||
"type": "git",
|
||||
"url": "ssh://forgejo@ssh.git.moonythm.dev/prescientmoon/shimmeringdarkness.git"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
|
|
44
flake.nix
|
@ -4,8 +4,8 @@
|
|||
flake-utils.url = "github:numtide/flake-utils";
|
||||
fenix.url = "github:nix-community/fenix";
|
||||
fenix.inputs.nixpkgs.follows = "nixpkgs";
|
||||
rust-overlay.url = "github:oxalica/rust-overlay";
|
||||
rust-overlay.inputs.nixpkgs.follows = "nixpkgs";
|
||||
shimmeringdarkness.url = "git+ssh://forgejo@ssh.git.moonythm.dev/prescientmoon/shimmeringdarkness.git";
|
||||
shimmeringdarkness.flake = false;
|
||||
};
|
||||
|
||||
outputs =
|
||||
|
@ -13,15 +13,7 @@
|
|||
inputs.flake-utils.lib.eachSystem (with inputs.flake-utils.lib.system; [ x86_64-linux ]) (
|
||||
system:
|
||||
let
|
||||
# pkgs = inputs.nixpkgs.legacyPackages.${system};
|
||||
pkgs = inputs.nixpkgs.legacyPackages.${system}.extend inputs.fenix.overlays.default;
|
||||
# pkgs = inputs.nixpkgs.legacyPackages.${system}.extend (import inputs.rust-overlay);
|
||||
# pkgs = import inputs.nixpkgs {
|
||||
# inherit system;
|
||||
# overlays = [ (import inputs.rust-overlay) ];
|
||||
# };
|
||||
# toolchain = pkgs.rust-bin.selectLatestNightlyWith (toolchain: toolchain.default);
|
||||
# toolchain = pkgs.rust-bin.stable.latest.default;
|
||||
rust-toolchain = pkgs.fenix.complete.toolchain;
|
||||
spkgs = inputs.self.packages.${system};
|
||||
inherit (pkgs) lib;
|
||||
|
@ -30,6 +22,18 @@
|
|||
packages = {
|
||||
inherit rust-toolchain;
|
||||
|
||||
# {{{ Private config
|
||||
shimmeringdarkness = inputs.shimmeringdarkness.outPath;
|
||||
glass-bundler = pkgs.callPackage ./nix/glass-bundler.nix { };
|
||||
debundled-darkness = pkgs.callPackage ./nix/debundled-darkness.nix {
|
||||
inherit (spkgs) shimmeringdarkness glass-bundler;
|
||||
};
|
||||
|
||||
private-config = pkgs.callPackage ./nix/private-config.nix {
|
||||
inherit (spkgs) shimmeringdarkness debundled-darkness;
|
||||
};
|
||||
# }}}
|
||||
# {{{ Fonts
|
||||
kazesawa = pkgs.callPackage ./nix/kazesawa.nix { };
|
||||
exo = pkgs.callPackage ./nix/exo.nix { };
|
||||
geosans-light = pkgs.callPackage ./nix/geosans-light.nix { };
|
||||
|
@ -38,21 +42,23 @@
|
|||
# Pass custom-packaged fonts
|
||||
inherit (spkgs) exo kazesawa geosans-light;
|
||||
};
|
||||
# }}}
|
||||
|
||||
cc-data = pkgs.callPackage ./nix/cc-data.nix { };
|
||||
default = spkgs.shimmeringmoon;
|
||||
shimmeringmoon = pkgs.callPackage ./nix/shimmeringmoon.nix {
|
||||
inherit (spkgs) shimmering-fonts rust-toolchain;
|
||||
inherit (spkgs)
|
||||
shimmering-fonts
|
||||
rust-toolchain
|
||||
cc-data
|
||||
private-config
|
||||
;
|
||||
};
|
||||
};
|
||||
|
||||
# {{{ Devshell
|
||||
devShell = pkgs.mkShell rec {
|
||||
nativeBuildInputs = with pkgs; [
|
||||
# pkgs.cargo
|
||||
# pkgs.rustc
|
||||
# pkgs.clippy
|
||||
# pkgs.rust-analyzer
|
||||
# pkgs.rustfmt
|
||||
spkgs.rust-toolchain
|
||||
|
||||
pkgs.ruff
|
||||
|
@ -61,15 +67,17 @@
|
|||
];
|
||||
|
||||
buildInputs = with pkgs; [
|
||||
python3
|
||||
freetype
|
||||
fontconfig
|
||||
leptonica
|
||||
tesseract
|
||||
sqlite
|
||||
openssl
|
||||
];
|
||||
|
||||
LD_LIBRARY_PATH = lib.makeLibraryPath buildInputs;
|
||||
SHIMMERING_FONT_DIR = spkgs.shimmering-fonts;
|
||||
SHIMMERING_CC_DIR = spkgs.cc-data;
|
||||
SHIMMERING_PRIVATE_CONFIG_DIR = spkgs.private-config;
|
||||
};
|
||||
# }}}
|
||||
}
|
||||
|
|
|
@ -2,35 +2,8 @@
|
|||
create table IF NOT EXISTS users (
|
||||
id INTEGER NOT NULL PRIMARY KEY,
|
||||
discord_id TEXT UNIQUE NOT NULL,
|
||||
is_pookie BOOL NOT NULL DEFAULT 0
|
||||
private_server_id INTEGER,
|
||||
is_pookie BOOL NOT NULL DEFAULT 0,
|
||||
is_admin BOOL NOT NULL DEFAULT 0
|
||||
);
|
||||
-- }}}
|
||||
-- {{{ plays
|
||||
CREATE TABLE IF NOT EXISTS plays (
|
||||
id INTEGER NOT NULL PRIMARY KEY,
|
||||
chart_id INTEGER NOT NULL,
|
||||
user_id INTEGER NOT NULL,
|
||||
discord_attachment_id TEXT,
|
||||
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
max_recall INTEGER,
|
||||
far_notes INTEGER,
|
||||
|
||||
FOREIGN KEY (chart_id) REFERENCES charts(id),
|
||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
);
|
||||
-- }}}
|
||||
-- {{{ scores
|
||||
CREATE TABLE IF NOT EXISTS scores (
|
||||
id INTEGER NOT NULL PRIMARY KEY,
|
||||
play_id INTEGER NOT NULL,
|
||||
|
||||
score INTEGER NOT NULL,
|
||||
creation_ptt INTEGER,
|
||||
scoring_system TEXT NOT NULL CHECK (scoring_system IN ('standard', 'sdf', 'ex')),
|
||||
|
||||
FOREIGN KEY (play_id) REFERENCES plays(id),
|
||||
UNIQUE(play_id, scoring_system)
|
||||
)
|
||||
-- }}}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
-- {{{ songs
|
||||
CREATE TABLE IF NOT EXISTS songs (
|
||||
id INTEGER NOT NULL PRIMARY KEY,
|
||||
shorthand TEXT NOT NULL UNIQUE,
|
||||
title TEXT NOT NULL,
|
||||
artist TEXT NOT NULL,
|
||||
side TEXT NOT NULL CHECK (side IN ('light', 'conflict', 'silent')),
|
||||
side TEXT NOT NULL CHECK (side IN ('light', 'conflict', 'silent', 'lephon')),
|
||||
bpm TEXT NOT NULL,
|
||||
pack TEXT,
|
||||
|
||||
UNIQUE(title, artist)
|
||||
);
|
||||
|
@ -14,8 +14,8 @@ CREATE TABLE IF NOT EXISTS songs (
|
|||
CREATE TABLE IF NOT EXISTS charts (
|
||||
id INTEGER NOT NULL PRIMARY KEY,
|
||||
song_id INTEGER NOT NULL,
|
||||
title TEXT,
|
||||
note_design TEXT,
|
||||
shorthand TEXT,
|
||||
|
||||
difficulty TEXT NOT NULL CHECK (difficulty IN ('PST','PRS','FTR','ETR','BYD')),
|
||||
level TEXT NOT NULL,
|
||||
|
|
|
@ -5,8 +5,13 @@ CREATE TABLE IF NOT EXISTS metadata (
|
|||
-- The last hash computed for the directory
|
||||
-- containing all the raw jackets. If this
|
||||
-- hash changes, every jacket is reprocessed.
|
||||
raw_jackets_hash TEXT NOT NULL
|
||||
raw_jackets_hash TEXT DEFAULT "" NOT NULL,
|
||||
|
||||
-- If any of these files change, every chart/song is reprocessed
|
||||
songlist_hash TEXT DEFAULT "" NOT NULL,
|
||||
cc_data_hash TEXT DEFAULT "" NOT NULL,
|
||||
notecount_hash TEXT DEFAULT "" NOT NULL
|
||||
) STRICT;
|
||||
|
||||
-- Inserts initial metadata row
|
||||
INSERT INTO metadata VALUES(0, "");
|
||||
INSERT INTO metadata(id) VALUES(0);
|
||||
|
|
7
nix/cc-data.nix
Normal file
|
@ -0,0 +1,7 @@
|
|||
{ pkgs }:
|
||||
pkgs.fetchFromGitHub {
|
||||
owner = "OllyDoge";
|
||||
repo = "ASCPSongConstant";
|
||||
rev = "2f396d13d5a9804ee3a45d46ff2e4a57cca482ad";
|
||||
sha256 = "032nvi5iia0crlafvq8zv8k2pj2kbxjdg4r6j990calhqm8xgljp";
|
||||
}
|
16
nix/debundled-darkness.nix
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
shimmeringdarkness,
|
||||
glass-bundler,
|
||||
runCommand,
|
||||
}:
|
||||
runCommand "debundled-darkness" { } ''
|
||||
mkdir $out
|
||||
|
||||
for file in ${shimmeringdarkness}/bundles/*.cb; do
|
||||
no_ext="''${file%.cb}"
|
||||
meta_file="$no_ext.json"
|
||||
${glass-bundler}/bin/glass-bundler debundle \
|
||||
--input $file -m $meta_file \
|
||||
--output $out/$(basename $no_ext)
|
||||
done
|
||||
''
|
29
nix/glass-bundler.nix
Normal file
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
python3,
|
||||
stdenvNoCC,
|
||||
fetchFromGitHub,
|
||||
}:
|
||||
stdenvNoCC.mkDerivation {
|
||||
pname = "arcaea-bundler";
|
||||
version = "unstable-2024-03-12";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "Lost-MSth";
|
||||
repo = "Arcaea-Bundler";
|
||||
rev = "db1901f31407f623da161a76dde225899ce902de";
|
||||
sha256 = "0fd2yrg8g6iwzy6m1y0ijfz5aqfm5bh8n6dzhiswzpssp4znp6vz";
|
||||
};
|
||||
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
echo "#!${python3}/bin/python" > glass-bundler
|
||||
cat $src/arcaea_bundler/main.py >> glass-bundler
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
install -Dm755 glass-bundler -t $out/bin/
|
||||
runHook postInstall
|
||||
'';
|
||||
}
|
30
nix/private-config.nix
Normal file
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
debundled-darkness,
|
||||
shimmeringdarkness,
|
||||
runCommand,
|
||||
}:
|
||||
let
|
||||
jacketVersion = "6.2.3";
|
||||
songlistVersion = "6.2.3.10";
|
||||
in
|
||||
runCommand "shimmering-private-config" { } ''
|
||||
mkdir $out
|
||||
mkdir $out/jackets
|
||||
|
||||
source=${debundled-darkness}/${jacketVersion}/songs
|
||||
for dir in $source/*; do
|
||||
out_dir=$(basename $dir)
|
||||
out_dir=''${out_dir#dl_}
|
||||
if [ -d $dir ] && [ $out_dir != "pack" ]; then
|
||||
mkdir $out/jackets/$out_dir
|
||||
|
||||
for file in $dir/*_256.jpg; do
|
||||
filename=$(basename $file)
|
||||
cp $file $out/jackets/$out_dir/$filename
|
||||
done
|
||||
fi
|
||||
done
|
||||
|
||||
cp ${debundled-darkness}/${songlistVersion}/songs/songlist $out/songlist.json
|
||||
cp ${shimmeringdarkness}/b30_background.jpg $out
|
||||
''
|
|
@ -6,62 +6,67 @@
|
|||
|
||||
freetype,
|
||||
fontconfig,
|
||||
leptonica,
|
||||
tesseract,
|
||||
openssl,
|
||||
sqlite,
|
||||
shimmering-fonts,
|
||||
makeRustPlatform,
|
||||
|
||||
rust-toolchain,
|
||||
|
||||
shimmering-fonts,
|
||||
cc-data,
|
||||
private-config,
|
||||
}:
|
||||
(makeRustPlatform {
|
||||
cargo = rust-toolchain;
|
||||
rustc = rust-toolchain;
|
||||
}).buildRustPackage
|
||||
rec {
|
||||
pname = "shimmeringmoon";
|
||||
version = "unstable-2024-09-06";
|
||||
src = lib.cleanSource ../.;
|
||||
let
|
||||
src = lib.cleanSource ../.;
|
||||
rustPlatform = makeRustPlatform {
|
||||
cargo = rust-toolchain;
|
||||
rustc = rust-toolchain;
|
||||
};
|
||||
in
|
||||
rustPlatform.buildRustPackage {
|
||||
inherit src;
|
||||
pname = "shimmeringmoon";
|
||||
version = "unstable-2025-02-11";
|
||||
|
||||
nativeBuildInputs = [
|
||||
pkg-config
|
||||
makeWrapper
|
||||
];
|
||||
SHIMMERING_FONTS_DIR = shimmering-fonts;
|
||||
SHIMMERING_CC_DIR = cc-data;
|
||||
SHIMMERING_PRIVATE_CONFIG_DIR = private-config;
|
||||
|
||||
# TODO: is this supposed to be here???
|
||||
# LD_LIBRARY_PATH = lib.makeLibraryPath buildInputs;
|
||||
buildInputs = [
|
||||
freetype
|
||||
fontconfig
|
||||
leptonica
|
||||
tesseract
|
||||
openssl
|
||||
sqlite
|
||||
];
|
||||
nativeBuildInputs = [
|
||||
pkg-config
|
||||
rust-toolchain
|
||||
makeWrapper
|
||||
];
|
||||
|
||||
cargoLock = {
|
||||
lockFile = ../Cargo.lock;
|
||||
outputHashes = {
|
||||
"hypertesseract-0.1.0" = "sha256-G0dos5yvvcfBKznAo1IIzLgXqRDxmyZwB93QQ6hVZSo=";
|
||||
"plotters-0.4.0" = "sha256-9wtd7lig1vQ2RJVaEHdicfPZy2AyuoNav8shPMZ1EuE=";
|
||||
"faer-0.19.4" = "sha256-VXMk2S3caMMs0N0PJa/m/7aPykYgeXVVn7GWPnG63nQ=";
|
||||
};
|
||||
preBuild = ''
|
||||
export SHIMMERING_SOURCE_DIR="$src"
|
||||
'';
|
||||
|
||||
# TODO: is this supposed to be here???
|
||||
# LD_LIBRARY_PATH = lib.makeLibraryPath buildInputs;
|
||||
buildInputs = [
|
||||
freetype
|
||||
fontconfig
|
||||
sqlite
|
||||
openssl
|
||||
src # Idk if putting this here is correct, but it is required at runtime...
|
||||
];
|
||||
|
||||
cargoLock = {
|
||||
lockFile = ../Cargo.lock;
|
||||
outputHashes = {
|
||||
"plotters-0.4.0" = "sha256-9wtd7lig1vQ2RJVaEHdicfPZy2AyuoNav8shPMZ1EuE=";
|
||||
"faer-0.19.4" = "sha256-VXMk2S3caMMs0N0PJa/m/7aPykYgeXVVn7GWPnG63nQ=";
|
||||
"poise-0.6.1" = "sha256-44pPe02JJ97GEpzAXdQmDq/9bb4KS9G7ZFVlBRC6EYs=";
|
||||
};
|
||||
};
|
||||
|
||||
# Disable all tests
|
||||
doCheck = false;
|
||||
# Disable all tests
|
||||
doCheck = false;
|
||||
|
||||
# Tell the binary where to find the fonts
|
||||
postInstall = ''
|
||||
wrapProgram $out/bin/shimmering-discord-bot \
|
||||
--set SHIMMERING_FONTS_DIR ${shimmering-fonts}
|
||||
'';
|
||||
|
||||
meta = {
|
||||
description = "Arcaea score management toolchain";
|
||||
homepage = "https://github.com/prescientmoon/shimmeringmoon";
|
||||
mainProgram = "shimmering-cli";
|
||||
platforms = [ "x86_64-linux" ];
|
||||
};
|
||||
}
|
||||
meta = {
|
||||
description = "Arcaea score management toolchain";
|
||||
homepage = "https://git.moonythm.dev/prescientmoon/shimmeringmoon";
|
||||
mainProgram = "shimmering-cli";
|
||||
platforms = [ "x86_64-linux" ];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
if [ "$#" != 2 ]; then
|
||||
echo "Usage: $0 <from> <to>"
|
||||
if [ "$#" != 1 ]; then
|
||||
echo "Usage: $0 <to>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
from=$1
|
||||
to=$2
|
||||
from=$SHIMMERING_DATA_DIR/db.sqlite
|
||||
to=$1
|
||||
|
||||
echo "Creating destination..."
|
||||
rm -rf "$to"
|
||||
|
|
|
@ -1,123 +0,0 @@
|
|||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -p "pkgs.python3.withPackages (p: with p; [tabulate])"
|
||||
#!nix-shell -i python3
|
||||
import csv
|
||||
import os
|
||||
import sqlite3
|
||||
|
||||
data_dir = os.environ.get("SHIMMERING_DATA_DIR")
|
||||
config_dir = os.environ.get("SHIMMERING_CONFIG_DIR")
|
||||
db_path = data_dir + "/db.sqlite"
|
||||
conn = sqlite3.connect(db_path)
|
||||
|
||||
|
||||
# {{{ Import songs
|
||||
def import_charts_from_csv():
|
||||
chart_count = 0
|
||||
song_count = 0
|
||||
shorthand_count = 0
|
||||
|
||||
with open(config_dir + "/charts.csv", mode="r") as file:
|
||||
for i, row in enumerate(csv.reader(file)):
|
||||
if i == 0 or len(row) == 0:
|
||||
continue
|
||||
|
||||
[
|
||||
title,
|
||||
artist,
|
||||
pack,
|
||||
*charts,
|
||||
side,
|
||||
bpm,
|
||||
version,
|
||||
date,
|
||||
ext_version,
|
||||
ext_date,
|
||||
original,
|
||||
] = map(lambda v: v.strip().replace("\n", " "), row)
|
||||
|
||||
existing_count = conn.execute(
|
||||
"""
|
||||
SELECT count()
|
||||
FROM songs
|
||||
WHERE title=?
|
||||
AND artist=?
|
||||
""",
|
||||
(title, artist),
|
||||
).fetchone()[0]
|
||||
|
||||
if existing_count > 0:
|
||||
continue
|
||||
|
||||
song_count += 1
|
||||
print(f'Importing "{title}" by "{artist}"')
|
||||
|
||||
song_id = conn.execute(
|
||||
"""
|
||||
INSERT INTO songs(title,artist,pack,side,bpm)
|
||||
VALUES (?,?,?,?,?)
|
||||
RETURNING id
|
||||
""",
|
||||
(title, artist, pack, side.lower(), bpm),
|
||||
).fetchone()[0]
|
||||
|
||||
for i in range(4):
|
||||
[note_design, level, cc, note_count] = charts[i * 4 : (i + 1) * 4]
|
||||
if note_design == "N/A":
|
||||
continue
|
||||
chart_count += 1
|
||||
|
||||
[difficulty, level] = level.split(" ")
|
||||
|
||||
conn.execute(
|
||||
"""
|
||||
INSERT INTO charts(song_id, difficulty, level, note_count, chart_constant, note_design)
|
||||
VALUES(?,?,?,?,?, ?)
|
||||
""",
|
||||
(
|
||||
song_id,
|
||||
difficulty,
|
||||
level,
|
||||
int(note_count.replace(",", "").replace(".", "")),
|
||||
int(round(float(cc) * 100)),
|
||||
note_design if len(note_design) else None,
|
||||
),
|
||||
)
|
||||
|
||||
with open(config_dir + "/shorthands.csv", mode="r") as file:
|
||||
for i, row in enumerate(csv.reader(file)):
|
||||
if i == 0 or len(row) == 0:
|
||||
continue
|
||||
|
||||
shorthand_count += 1
|
||||
[name, difficulty, artist, shorthand] = map(lambda v: v.strip(), row)
|
||||
conn.execute(
|
||||
f"""
|
||||
UPDATE charts
|
||||
SET shorthand=?
|
||||
WHERE EXISTS (
|
||||
SELECT 1 FROM songs s
|
||||
WHERE s.id = charts.song_id
|
||||
AND s.title=?
|
||||
{"" if artist=="" else "AND artist=?"}
|
||||
)
|
||||
{"" if difficulty=="" else "AND difficulty=?"}
|
||||
""",
|
||||
[
|
||||
shorthand,
|
||||
name,
|
||||
*([] if artist == "" else [artist]),
|
||||
*([] if difficulty == "" else [difficulty]),
|
||||
],
|
||||
)
|
||||
|
||||
conn.commit()
|
||||
|
||||
print(
|
||||
f"Imported {chart_count} charts, {song_count} songs, and {shorthand_count} shorthands"
|
||||
)
|
||||
|
||||
|
||||
# }}}
|
||||
|
||||
import_charts_from_csv()
|
|
@ -1,25 +0,0 @@
|
|||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -p libsixel
|
||||
#!nix-shell -i bash
|
||||
|
||||
if [ "$#" != 2 ]; then
|
||||
echo "Usage: $0 <name> <url>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
name=$1
|
||||
url=$2
|
||||
|
||||
curr=$(pwd)
|
||||
|
||||
dir_path=$SHIMMERING_ASSET_DIR/songs/raw/$name
|
||||
mkdir -p $dir_path
|
||||
cd $dir_path
|
||||
|
||||
http GET "$url" > temp
|
||||
magick ./temp ./base.jpg
|
||||
magick ./base.jpg -resize 256x256 ./base_256.jpg
|
||||
rm temp
|
||||
img2sixel ./base.jpg
|
||||
|
||||
cd $curr
|
|
@ -1,30 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
dir_path=$SHIMMERING_ASSETS_DIR/songs/raw
|
||||
|
||||
# Find all files in the directory and its subdirectories
|
||||
find "$dir_path" -type f | while read -r file; do
|
||||
# Get the filename without the directory path
|
||||
filename=$(basename "$file")
|
||||
|
||||
# Check if the filename starts with "1080_"
|
||||
if [[ $filename == 1080_* ]]; then
|
||||
# Remove the "1080_" prefix
|
||||
new_filename="${filename#1080_}"
|
||||
|
||||
# Get the directory path without the filename
|
||||
file_dir=$(dirname "$file")
|
||||
|
||||
# Construct the new file path
|
||||
new_file_path="$file_dir/$new_filename"
|
||||
|
||||
# Rename the file
|
||||
mv "$file" "$new_file_path"
|
||||
echo "Renamed: $file -> $new_file_path"
|
||||
fi
|
||||
done
|
||||
|
||||
mv $dir_path/dropdead/3*.jpg $dir_path/overdead 2>/dev/null
|
||||
mv $dir_path/singularity/3*.jpg $dir_path/singularityvvvip 2>/dev/null
|
||||
mv $dir_path/redandblue/3*.jpg $dir_path/redandblueandgreen 2>/dev/null
|
||||
mv $dir_path/ignotus/3*.jpg $dir_path/ignotusafterburn 2>/dev/null
|
||||
rm -rf $dir_path/ifirmxrmx 2>/dev/null
|
|
@ -1,4 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
echo "delete from songs" | sqlite3 $SHIMMERING_DATA_DIR/db.sqlite
|
||||
echo "delete from charts" | sqlite3 $SHIMMERING_DATA_DIR/db.sqlite
|
||||
./scripts/main.py import charts
|
|
@ -1,640 +0,0 @@
|
|||
Song,Artist,Pack,Note Design,Level,CC,Notes,Note Design,Level,CC,Notes,Note Design,Level,CC,Notes,Note Design,Level,CC,Notes,Side,BPM,Version,Date,Version,Date,Original
|
||||
Tutorial,ak+q,,,PST 1,0.0,173,,PRS 4,0.0,158,N/A,,,,N/A,,,,Light,128,1.0.5,17/3/8,N/A,,✓
|
||||
Fairytale,chitose,Arcaea,Toaster,PST 1,1.0,336,Toaster,PRS 3,3.5,511,Toaster,FTR 7,7.0,782,Nitro in Wonderland,BYD 9,9.5,932,Light,189,1.0.5,17/3/8,3.0.0,20/5/27,
|
||||
Sayonara Hatsukoi,REDSHiFT,Arcaea,Nitro,PST 1,1.5,205,Nitro,PRS 4,4.5,305,Toaster,FTR 7,7.0,666,Luxance + Exschwasion,ETR 8,8.5,728,Light,178,1.0.5,17/3/8,5.4.0,24/3/8,
|
||||
Vexaria,ak+q,Arcaea,Nitro,PST 2,2.5,369,Nitro,PRS 5,5.0,534,Nitro,FTR 7,7.0,734,石樂,BYD 9,9.0,785,Light,180,1.0.5,17/3/8,3.0.0,20/5/27,
|
||||
Rise,Combatplayer,Arcaea,Nitro,PST 2,2.5,322,Nitro,PRS 4,4.0,599,Nitro,FTR 7+,7.8,788,N/A,,,,Light,140,1.0.5,17/3/8,N/A,,
|
||||
Babaroque,cYsmix,Arcaea,Toaster,PST 3,3.0,402,Toaster,PRS 6,6.5,645,Toaster,FTR 8,8.5,808,N/A,,,,Light,136,1.0.5,17/3/8,N/A,,
|
||||
Lucifer,chitose,Arcaea,Nitro,PST 3,3.5,424,Nitro,PRS 5,5.5,506,Nitro,FTR 8,8.2,861,N/A,,,,Conflict,165,1.0.5,17/3/8,N/A,,
|
||||
Shades of Light in a Transcendent Realm,ak+q,Arcaea,Nitro,PST 3,3.0,517,Nitro,PRS 6,6.0,789,Nitro,FTR 8,8.3,"1,067",N↑TRO,BYD 9,9.0,"1,042",Light,170,1.0.5,17/3/8,4.3.2,23/3/9,
|
||||
Snow White,Puru,Arcaea,Toaster,PST 2,2.5,486,Toaster,PRS 5,5.0,672,Toaster,FTR 8,8.4,978,N/A,,,,Light,150,1.0.5,17/3/8,N/A,,
|
||||
"GOODTEK
|
||||
(Arcaea Edit)",EBIMAYO,Arcaea,Nitro,PST 4,4.0,449,Nitro,PRS 6,6.5,632,Nitro,FTR 9,9.3,968,GOODTOAST,BYD 9+,9.8,"1,103",Light,190,1.0.5,17/3/8,3.0.0,20/5/27,
|
||||
Lost Civilization,Laur vs. CK,Arcaea,Toaster,PST 4,4.0,462,Toaster,PRS 7,7.0,690,Toaster,FTR 9,9.2,986,"Nitro Affected
|
||||
by Nitro",BYD 9+,9.8,"1,061",Conflict,75-210,1.0.5,17/3/8,3.6.0,21/5/11,
|
||||
I've heard it said,Combatplayer,Eternal Core,Toaster,PST 3,3.5,510,Toaster,PRS 6,6.0,664,Toaster,FTR 8,8.1,864,N/A,,,,Light,160,1.0.8,17/3/9,N/A,,
|
||||
Lumia,sky_delta,Eternal Core,Nitro,PST 2,2.5,469,Nitro,PRS 5,5.5,438,Toaster missing Nitro.,FTR 8,8.4,961,Toaster.,BYD 9,9.5,814,Light,180,1.0.8,17/3/9,3.2.3,20/11/19,✓
|
||||
Relentless,Akira Complex,Eternal Core,Nitro,PST 4,4.5,607,Nitro,PRS 6,6.5,722,Nitro,FTR 8,8.0,"1,015",N/A,,,,Conflict,174,1.0.8,17/3/9,N/A,,
|
||||
cry of viyella,Laur,Eternal Core,Toaster,PST 3,3.5,414,Toaster,PRS 6,6.0,492,Toaster,FTR 8+,8.7,791,N/A,,,,Conflict,75-180,1.0.8,17/3/9,N/A,,
|
||||
memoryfactory.lzh,Frums,Eternal Core,Nitro,PST 2,2.5,308,Nitro,PRS 5,5.5,448,Nitro,FTR 8+,8.9,672,N/A,,,,Light,100,1.0.8,17/3/9,N/A,,✓
|
||||
Essence of Twilight,ak+q,Eternal Core,Nitro,PST 4,4.5,556,Nitro,PRS 7,7.0,767,Nitro,FTR 9,9.1,"1,204",N/A,,,,Conflict,164,1.0.8,17/3/9,N/A,,✓
|
||||
PRAGMATISM,Laur,Eternal Core,東星,PST 4,4.5,476,東星,PRS 8,8.6,855,東星,FTR 10,10.1,942,N/A,,,,Light,174,1.0.8,17/3/9,N/A,,✓
|
||||
Sheriruth,Team Grimoire,Eternal Core,夜浪,PST 5,5.5,611,夜浪,PRS 7+,7.5,832,夜浪,FTR 10,10.1,"1,151",N/A,,,,Conflict,185,1.0.8,17/3/9,N/A,,✓
|
||||
qualia -ideaesthesia-,nitro,Arcaea,-chartaesthesia-,PST 4,4.5,550,-chartaesthesia-,PRS 7,7.0,875,-chartaesthesia-,FTR 9,9.1,"1,022",moonquay -end of chartaesthesia-,BYD 9+,9.7,"1,288",Conflict,144,1.0.8,17/3/9,3.10.0,21/12/9,
|
||||
"Dement
|
||||
~after legend~",Cosmograph,Arcaea,Toaster,PST 3,3.5,548,Toaster,PRS 6,6.0,756,Toaster,FTR 7+,7.8,970,Nitro ~ABYSS~,BYD 9+,9.9,"1,040",Conflict,210,1.0.9,17/3/20,3.1.0,20/8/21,
|
||||
Dandelion,Farhan,Arcaea,Nitro,PST 2,2.5,391,Nitro,PRS 6,6.0,698,Nitro,FTR 8,8.5,921,N/A,,,,Light,169,1.0.9,17/3/20,N/A,,
|
||||
Infinity Heaven,HyuN,Arcaea,Nitro,PST 1,1.5,336,Nitro,PRS 5,5.5,545,Nitro,FTR 7+,7.8,853,Nitr∞,BYD 9,9.6,986,Light,160,1.0.10,17/4/12,3.0.0,20/5/27,
|
||||
Anökumene,Jun Kuroda,Arcaea,Toaster,PST 2,2.5,412,Toaster,PRS 6,6.5,588,Toaster,FTR 9,9.2,851,N/A,,,,Conflict,186,1.0.10,17/4/12,N/A,,
|
||||
Paradise,Sound Souler,Crimson Solace,Nitro,PST 1,1.0,253,Nitro,PRS 4,4.0,349,Nitro,FTR 7+,7.8,729,N/A,,,,Light,126,1.0.11,17/5/11,N/A,,✓
|
||||
Flashback,ARForest,Crimson Solace,Nitro,PST 2,2.0,356,Nitro,PRS 5,5.0,488,Nitro,FTR 8+,8.9,856,N/A,,,,Light,195,1.0.11,17/5/11,N/A,,✓
|
||||
"Flyburg
|
||||
and Endroll","アリスシャッハと
|
||||
魔法の楽団",Crimson Solace,N,PST 3,3.0,413,N,PRS 6,6.0,650,N-Helix,FTR 9,9.0,930,N/A,,,,Light,180,1.0.11,17/5/11,N/A,,✓
|
||||
Party Vinyl,モリモリあつし,Crimson Solace,Party Toaster,PST 4,4.0,337,Party Toaster,PRS 7+,7.8,543,Party Toaster,FTR 9,9.4,800,Party Exschwasion,BYD 10,10.1,946,Light,132,1.0.11,17/5/11,4.1.6,22/12/22,✓
|
||||
Nirv lucE,しーけー,Crimson Solace,東星※紅空,PST 2,2.5,297,東星※紅空,PRS 7,7.0,547,東星※紅空,FTR 10,10.3,980,N/A,,,,Light,260,1.0.11,17/5/11,N/A,,✓
|
||||
Brand new world,U-ske,Arcaea,Nitro 2.0,PST 2,2.0,322,Nitro 2.0,PRS 4,4.0,432,Nitro 2.0,FTR 7+,7.8,787,N/A,,,,Light,160,1.0.11,17/5/11,N/A,,
|
||||
Chronostasis,黒皇帝,Arcaea,Kurorak,PST 3,3.5,619,Kurorak,PRS 7,7.5,812,Kurorak,FTR 8+,8.9,916,N/A,,,,Conflict,196,1.1.0,17/6/2,N/A,,
|
||||
"Kanagawa
|
||||
Cyber Culvert",南ゆに,Arcaea,Nitro,PST 1,1.0,375,Nitro,PRS 5,5.5,707,Nitro,FTR 9,9.0,"1,111",Exschwas↓on,BYD 9+,9.8,"1,121",Light,180,1.1.0,17/6/2,3.10.0,21/12/9,
|
||||
CROSS†SOUL,HyuN feat. Syepias,Memory Archive: Variety,k//eternal,PST 4,4.0,606,k//eternal,PRS 7,7.0,823,k//eternal,FTR 9,9.4,"1,081",N/A,,,,Conflict,200,1.1.0,17/6/2,N/A,,
|
||||
DataErr0r,Cosmograph,Memory Archive: Variety,ToastErr0r,PST 3,3.0,502,ToastErr0r,PRS 7,7.0,785,ToastErr0r,FTR 9,9.5,955,N/A,,,,Conflict,180,1.1.0,17/6/2,N/A,,
|
||||
"Your voice so...
|
||||
feat. Such",PSYQUI,Memory Archive: Variety,Nitro,PST 3,3.5,469,Nitro,PRS 6,6.5,677,Nitro,FTR 9,9.4,"1,013",N/A,,,,Light,176,1.1.0,17/6/2,N/A,,
|
||||
"Moonlight of
|
||||
Sand Castle",旅人E,Dynamix,Kurorak,PST 1,1.5,418,Kurorak,PRS 5,5.0,394,Kurorak,FTR 7+,7.8,645,N/A,,,,Light,160,1.1.2,17/6/23,N/A,,
|
||||
REconstruction,Ryazan,Dynamix,Nitro,PST 2,2.5,347,Nitro,PRS 6,6.0,469,Nitro,FTR 8,8.4,825,N/A,,,,Light,180,1.1.2,17/6/23,N/A,,
|
||||
"Evoltex
|
||||
(poppi'n mix)",Arch vs. n3pu,Dynamix,k//eternal,PST 2,2.0,297,k//eternal,PRS 7,7.0,627,k//eternal,FTR 8+,8.9,775,N/A,,,,Light,205,1.1.2,17/6/23,N/A,,
|
||||
Oracle,TQ☆,Dynamix,Nitro,PST 3,3.0,425,Nitro,PRS 5,5.5,508,Nitro,FTR 9,9.3,963,N/A,,,,Conflict,152,1.1.2,17/6/23,N/A,,
|
||||
αterlβus,Aoi,Dynamix,τoastεr,PST 4,4.0,505,τoastεr,PRS 7,7.5,668,τoastεr,FTR 10,10.2,"1,030",N/A,,,,Conflict,202,1.1.2,17/6/23,N/A,,
|
||||
"Clotho and
|
||||
the stargazer",しーけー,Arcaea,小東星,PST 2,2.0,519,小東星,PRS 5,5.0,745,小東星,FTR 7+,7.8,"1,021",eién,ETR 8+,8.8,"1,031",Light,230,1.1.2,17/6/23,5.4.0,24/3/8,
|
||||
Ignotus,ak+q,Arcaea,Toaster,PST 3,3.5,579,Toaster,PRS 6,6.5,809,Toaster,FTR 9,9.3,"1,225",N/A,,,,Conflict,170,1.1.3,17/7/18,N/A,,✓
|
||||
Impure Bird,MIssionary,Memory Archive: Original,Kurorak,PST 2,2.0,350,Kurorak,PRS 5,5.5,518,Kurorak,FTR 9,9.4,805,N/A,,,,Light,184,1.1.3,17/7/18,N/A,,✓
|
||||
Blossoms,T2Kazuya,Ambivalent Vision,Nitro,PST 1,1.0,275,Nitro,PRS 4,4.0,383,Nitro,FTR 7,7.0,655,N/A,,,,Light,138,1.1.4,17/8/10,N/A,,✓
|
||||
Romance Wars,U-ske (feat. lueur),Ambivalent Vision,Kurorak,PST 1,1.0,423,Kurorak,PRS 4,4.0,378,Kurorak,FTR 7+,7.8,641,N/A,,,,Light,187,1.1.4,17/8/10,N/A,,✓
|
||||
Genesis,Iris,Ambivalent Vision,Haruba,PST 2,2.0,275,Haruba,PRS 5,5.5,399,Haruba,FTR 8,8.2,713,N/A,,,,Conflict,132,1.1.4,17/8/10,N/A,,✓
|
||||
Moonheart,翡乃イスカ,Ambivalent Vision,Toaster,PST 2,2.5,449,Toaster,PRS 5,5.5,566,Toaster,FTR 8,8.4,947,Toaster,BYD 9+,9.7,"1,139",Light,180,1.1.4,17/8/10,3.4.1,21/1/8,✓
|
||||
Lethaeus,Silentroom,Ambivalent Vision,夜浪,PST 3,3.5,480,夜浪,PRS 6,6.5,717,夜浪,FTR 9+,9.7,900,N/A,,,,Conflict,155,1.1.4,17/8/10,N/A,,✓
|
||||
"Harutopia
|
||||
~Utopia of Spring~",A-zu-ra,Arcaea,"トーストピア
|
||||
~Utopia of Toast~",PST 1,1.0,444,"トーストピア
|
||||
~Utopia of Toast~",PRS 4,4.5,706,"トーストピア
|
||||
~Utopia of Toast~",FTR 8,8.5,"1,061",N/A,,,,Light,185,1.1.4,17/8/10,N/A,,
|
||||
Auxesia,ginkiha,Memory Archive: Partner,Nitroだー!!,PST 3,3.5,385,Nitroだー!,PRS 6,6.5,648,Nitroだー!,FTR 9,9.3,"1,000",N/A,,,,Light,183,1.1.4,17/8/10,N/A,,✓
|
||||
"Rabbit In The
|
||||
Black Room",Rabbit House,Arcaea,Toaster,PST 2,2.5,373,Toaster,PRS 5,5.5,467,Toaster,FTR 8,8.4,772,N/A,,,,Conflict,270,1.1.6,17/9/25,N/A,,
|
||||
Modelista,HiTECH NINJA,Memory Archive: Original,NITRO,PST 3,3.5,418,NITRO,PRS 7,7.5,691,NITRO,FTR 10,10.0,"1,010",N/A,,,,Light,165,1.1.6,17/9/25,N/A,,✓
|
||||
Iconoclast,Yamajet,Vicious Labyrinth,Toaster,PST 4,4.0,443,Toaster,PRS 7,7.0,593,Toaster,FTR 9,9.1,795,N/A,,,,Conflict,140,1.5.0,17/11/3,N/A,,✓
|
||||
SOUNDWiTCH,HATE,Vicious Labyrinth,NiTRO,PST 3,3.5,315,NiTRO,PRS 6,6.5,488,NiTRO,FTR 9+,9.9,785,N/A,,,,Conflict,170,1.5.0,17/11/3,N/A,,
|
||||
conflict,siromaru + cranky,Vicious Labyrinth,Toaster,PST 4,4.5,520,Nitro,PRS 7,7.5,731,toaster + nitro,FTR 10,10.2,"1,056",N/A,,,,Conflict,160,1.5.0,17/11/3,N/A,,
|
||||
"trappola
|
||||
bewitching",gmtn.,Vicious Labyrinth,Kurorak,PST 3,3.0,415,Kurorak,PRS 6,6.0,541,k//urorak,FTR 10,10.0,"1,044",NITRO -mesmerize-,BYD 10,10.5,"1,086",Conflict,190,1.5.0,17/11/3,4.3.0,23/3/2,✓
|
||||
Axium Crisis,ak+q,Vicious Labyrinth,The Monolith,PST 5,5.5,685,The Monolith,PRS 8,8.5,"1,065",The Monolith,FTR 10+,10.7,"1,094",N/A,,,,Conflict,170,1.5.0,17/11/3,N/A,,✓
|
||||
Grievous Lady,"Team Grimoire
|
||||
vs. Laur",Vicious Labyrinth,迷路第一層,PST 6,6.5,956,迷路第二層,PRS 9,9.3,"1,194",迷路深層,FTR 11,11.3,"1,450",N/A,,,,Conflict,210,1.5.0,17/11/3,N/A,,✓
|
||||
One Last Drive,REDSHiFT,Arcaea,Toaster,PST 2,2.5,604,Toaster,PRS 5,5.5,564,Toaster,FTR 8,8.2,885,N/A,,,,Light,154-175,1.5.0,17/11/3,N/A,,
|
||||
Dreamin' Attraction!!,翡乃イスカ,Arcaea,Nitro,PST 4,4.5,592,Nitro,PRS 7,7.0,785,Nitro,FTR 9,9.4,"1,129",N/A,,,,Light,205,1.5.0,17/11/3,N/A,,
|
||||
Red and Blue,Silentroom,Arcaea,-chartaesthesia- RED side,PST 4,4.0,464,side BLUE -chartaesthesia-,PRS 7+,7.8,597,-chartaesthesia- LEFT=BLUE RED=RIGHT,FTR 9,9.4,845,N/A,,,,Conflict,150,1.5.0,17/11/3,N/A,,✓
|
||||
Surrender,void,Memory Archive: Music Game,Nitro,PST 3,3.0,550,Nitro,PRS 6,6.5,721,Nitro,FTR 8+,8.8,925,N/A,,,,Light,152,1.5.2,17/11/24,N/A,,
|
||||
Yosakura Fubuki,A.SAKA,Memory Archive: Music Game,k//eternal,PST 4,4.5,416,k//eternal,PRS 7,7.0,582,k//eternal,FTR 9,9.4,931,N/A,,,,Light,172,1.5.2,17/11/24,N/A,,
|
||||
Reinvent,Sound Souler,Arcaea,k//eternal,PST 2,2.5,570,k//eternal,PRS 6,6.5,703,k//eternal + nitro,FTR 8,8.5,852,N/A,,,,Light,174,1.5.3,17/12/21,N/A,,
|
||||
Syro,Mitomoro,Arcaea,Toaster,PST 3,3.5,535,Toaster,PRS 6,6.5,829,Toaster,FTR 9,9.3,"1,150",N/A,,,,Light,178,1.5.3,17/12/21,N/A,,✓
|
||||
Dream goes on,Tiny Minim,Lanota,k//eternal,PST 1,1.5,532,k//eternal,PRS 5,5.0,751,k//eternal,FTR 7+,7.8,719,N/A,,,,Light,174,1.5.5,18/2/1,N/A,,
|
||||
Journey,ARForest,Lanota,Kurorak,PST 3,3.0,551,Kurorak,PRS 6,6.0,778,Kurorak,FTR 9,9.1,997,N/A,,,,Light,200,1.5.5,18/2/1,N/A,,
|
||||
Quon,Feryquitous,Lanota,Nitro,PST 4,4.0,547,Nitro,PRS 6,6.5,718,Nitro,FTR 9,9.6,991,N/A,,,,Light,189,1.5.5,18/2/1,N/A,,✓
|
||||
Specta,Junk,Lanota,Toaster,PST 3,3.5,390,Toaster,PRS 6,6.5,706,Toaster,FTR 9,9.5,"1,096",N/A,,,,Light,179,1.5.5,18/2/1,N/A,,
|
||||
cyanine,jioyi,Lanota,夜浪 - Apocalypse,PST 4,4.0,661,夜浪,PRS 7+,7.8,947,夜浪,FTR 10,10.6,"1,171",N/A,,,,Conflict,182,1.5.5,18/2/1,N/A,,
|
||||
Metallic Punisher,INNOCENT NOIZE,Memory Archive: Partner,Kurorak,PST 3,3.0,500,Kurorak,PRS 7,7.0,846,Black Tea,FTR 10,10.3,"1,238",N/A,,,,Conflict,165,1.5.6,18/2/16,N/A,,✓
|
||||
Blaster,Massive New Krew,Arcaea,k//eternal,PST 4,4.0,571,k//urorak,PRS 7,7.0,635,k//urorak,FTR 9,9.3,"1,002",N/A,,,,Conflict,180,1.5.7,18/3/9,N/A,,✓
|
||||
Silent Rush,Soleily,Binary Enfold,TaroNuke,PST 2,2.5,416,TaroNuke,PRS 5,5.0,674,TaroNuke,FTR 8,8.6,941,N/A,,,,Conflict,158,1.6.0,18/3/23,N/A,,✓
|
||||
next to you,uma feat. 橘花音,Binary Enfold,Nitro,PST 4,4.5,454,Nitro,PRS 7,7.0,583,Nitro,FTR 8+,8.8,824,Toastie,BYD 9,9.6,954,Light,165,1.6.0,18/3/23,3.6.0,21/5/11,✓
|
||||
Strongholds,Yooh,Binary Enfold,TaroNuke,PST 2,2.5,570,TaroNukeΔ,PRS 5,5.0,778,TΔroNuke,FTR 9,9.2,922,N/A,,,,Conflict,105,1.6.0,18/3/23,N/A,,✓
|
||||
Memory Forest,ETIA.,Binary Enfold,Kurorak,PST 3,3.5,639,Kurorak,PRS 6,6.0,726,Kurorak,FTR 9+,9.8,978,N/A,,,,Light,178,1.6.0,18/3/23,N/A,,✓
|
||||
Singularity,ETIA.,Binary Enfold,東星,PST 4,4.5,534,東星,PRS 7+,7.8,678,東星※コラプサー,FTR 10+,10.7,"1,105",N/A,,,,Conflict,175,1.6.0,18/3/23,N/A,,✓
|
||||
Ignotus Afterburn,"Arcaea
|
||||
Sound Team",Arcaea,N/A,,,,N/A,,,,"《WARNING》 TaroNuke vs
|
||||
Arcaea Charting Team",FTR ?,0.0,"1,028",Toaster × 石樂,BYD 9+,9.9,"1,077",Conflict,170,1.6.1,18/4/1,3.12.2,22/3/9,✓
|
||||
carmine:scythe,かゆき,Memory Archive: Partner,週刊Toaster,PST 4,4.0,493,週刊Toaster,PRS 7+,7.8,710,週刊Toaster,FTR 9,9.6,"1,164",N/A,,,,Conflict,165,1.6.2,18/4/29,N/A,,✓
|
||||
γuarδina,Aoi,Memory Archive: Original,τoastεr,PST 4,4.0,507,τoastεr,PRS 8,8.0,678,τoastεr,FTR 10,10.4,"1,120",N/A,,,,Light,202,1.6.2,18/4/29,N/A,,✓
|
||||
Cybernecia Catharsis,Tanchiky,Arcaea,Kero,PST 4,4.0,377,Kero,PRS 7,7.0,655,Kero + Nitro,FTR 9,9.5,946,antymis,BYD 9+,9.8,991,Conflict,184,1.6.4,18/6/1,5.3.0,24/1/25,✓
|
||||
Be There,PSYQUI,Memory Archive: Original,Nitro,PST 4,4.0,592,Nitro,PRS 7,7.5,792,Be Nitro,FTR 9,9.4,982,N/A,,,,Light,164,1.6.4,18/6/1,N/A,,✓
|
||||
inkar-usi,DIA,Arcaea,Kurorak,PST 2,2.0,276,Kurorak,PRS 4,4.0,326,Kurorak,FTR 7+,7.8,463,CERiNG,BYD 9,9.4,857,Light,102,1.6.6,18/6/22,5.3.0,24/1/25,✓
|
||||
"Call My Name
|
||||
feat. Yukacco",Mameyudoufu,Memory Archive: Variety,Kurorak,PST 3,3.5,591,Kurorak,PRS 6,6.0,653,Kuro My Nitro,FTR 8+,8.7,921,N/A,,,,Light,175,1.6.6,18/6/22,N/A,,
|
||||
Maze No.9,"アリスシャッハと
|
||||
魔法の楽団",Luminous Sky ,小東星,PST 3,3.0,494,小東星,PRS 3,3.5,445,小東星,FTR 8+,8.9,775,N/A,,,,Light,159,1.7.0,18/7/16,N/A,,✓
|
||||
Sulfur,ぺのれり,Luminous Sky ,Shirorak,PST 4,4.0,458,Shirorak,PRS 6,6.0,608,Shirorak,FTR 9+,9.7,"1,045",N/A,,,,Light,182,1.7.0,18/7/16,N/A,,✓
|
||||
The Message,Jun Kuroda,Luminous Sky ,Toaster,PST 3,3.0,536,Toaster,PRS 6,6.5,630,Toaster,FTR 9+,9.7,992,N/A,,,,Light,202,1.7.0,18/7/16,N/A,,✓
|
||||
Halcyon,xi,Luminous Sky ,東星※太陽,PST 5,5.5,662,東星※太陽,PRS 8,8.2,943,東星※太陽,FTR 10+,10.7,"1,227",N/A,,,,Light,191,1.7.0,18/7/16,N/A,,
|
||||
Ether Strike,Akira Complex,Luminous Sky ,Zero Sky,PST 5,5.5,659,Zero Sky,PRS 8,8.3,837,Zero Sky,FTR 10,10.3,"1,170",N/A,,,,Light,156,1.7.0,18/7/16,N/A,,✓
|
||||
Fracture Ray,Sakuzyo,Luminous Sky ,Volatile Paradox,PST 6,6.0,983,Absolute Paradox,PRS 9,9.5,"1,343",Paradox Zero,FTR 11,11.3,"1,279",N/A,,,,Light,200,1.7.0,18/7/16,N/A,,✓
|
||||
Suomi,Aire,Arcaea,Toastie,PST 2,2.0,368,Toastie,PRS 5,5.0,550,Toastie,FTR 7+,7.8,818,CERiNG,ETR 8+,8.9,732,Light,125,1.7.0,18/7/16,5.4.0,24/3/8,
|
||||
"Bookmaker
|
||||
(2D Version)",Kobaryo,Arcaea,Kurorak,PST 4,4.5,538,Kurorak,PRS 6,6.5,728,Kurorak,FTR 8,8.3,"1,124",Toastmaker,BYD 10,10.0,"1,287",Conflict,175,1.7.0,18/7/16,3.6.4,21/6/30,
|
||||
Illegal Paradise,"gmtn.
|
||||
(witch's slave)",Arcaea,k//eternal,PST 2,2.0,535,k//eternal,PRS 7,7.0,585,k//eternal + nitro,FTR 9,9.5,"1,061",N/A,,,,Conflict,168,1.7.0,18/7/16,N/A,,
|
||||
Nhelv,Silentroom,Arcaea,"Nitro
|
||||
「Katastrophe」",PST 3,3.0,647,"Nitro
|
||||
「Katastrophe」",PRS 6,6.5,913,"Nitro
|
||||
「Katastrophe」",FTR 9+,9.9,"1,108",N/A,,,,Conflict,174.59,1.7.2,18/8/13,N/A,,
|
||||
dropdead,Frums,Memory Archive: Original,-chartaesthesia- LIMITER:10%,PST 1,1.5,44,-chartaesthesia- LIMITER:100%,PRS 9,9.5,"1,323",-chartaesthesia- LIMITER:25% (OVERDRIVE:+100%),FTR 8+,9.1,823,N/A,,,,Conflict,50,1.7.2,18/8/13,N/A,,✓
|
||||
Fallensquare,Silentroom,Memory Archive: Original,Haruba,PST 3,3.0,316,Haruba,PRS 7,7.5,486,Haruba,FTR 9,9.6,703,N/A,,,,Conflict,99,1.7.2,18/8/13,N/A,,✓
|
||||
LunarOrbit -believe in the Espebranch road-,Apo11o program feat. 大瀬良あい,Arcaea,月刊Toaster,PST 3,3.5,624,月刊Toaster,PRS 6,6.0,757,週刊Toaster,FTR 9,9.6,"1,058",N/A,,,,Conflict,192,1.7.4,18/8/31,N/A,,✓
|
||||
Purgatorium,お月さま交響曲,Arcaea,Kurorak,PST 2,2.5,609,Kurorak,PRS 6,6.0,641,Kurorak,FTR 8,8.4,983,Toaster,BYD 9,9.6,"1,051",Conflict,150,1.7.5,18/9/17,3.1.0,20/8/21,✓
|
||||
Alexandrite,WAiKURO,Memory Archive: Original,東星※空の宝石,PST 4,4.5,507,東星※空の宝石,PRS 7,7.5,699,東星※空の宝石,FTR 10,10.0,"1,040",N/A,,,,Conflict,146,1.7.5,18/9/17,N/A,,✓
|
||||
Hall of Mirrors,Sta,Tone Sphere,Toaster,PST 3,3.0,535,Toaster,PRS 5,5.5,553,Toaster,FTR 8,8.2,898,N/A,,,,Conflict,147,1.8.0,18/10/7,N/A,,
|
||||
Hikari,THB,Tone Sphere,OptoNuke,PST 2,2.5,237,OptoNuke,PRS 6,6.0,450,OptoNuke,FTR 8,8.1,684,N/A,,,,Conflict,130,1.8.0,18/10/7,N/A,,
|
||||
STAGER (ALL STAGE CLEAR),Ras,Tone Sphere,KURORAK,PST 3,3.0,453,KURORAK,PRS 6,6.5,559,KURORAK,FTR 9,9.5,"1,004",N/A,,,,Light,145,1.8.0,18/10/7,N/A,,
|
||||
Linear Accelerator,THE SHAFT,Tone Sphere,THE TOAST,PST 2,2.5,438,THE TOAST,PRS 6,6.5,488,THE TOAST,FTR 9+,9.8,905,N/A,,,,Light,"200-
|
||||
211.9",1.8.0,18/10/7,N/A,,
|
||||
Tiferet,xi + Sta,Tone Sphere,夜浪[Spherical],PST 4,4.5,450,夜浪[Spherical],PRS 7+,7.8,720,夜浪[Spherical],FTR 10,10.4,"1,086",N/A,,,,Conflict,140?,1.8.0,18/10/7,N/A,,
|
||||
Rugie,"Feryquitous
|
||||
feat. Sennzai",Arcaea,k//urorak,PST 3,3.0,566,k//urorak,PRS 6,6.0,754,k//urorak,FTR 9,9.2,975,N/A,,,,Conflict,191,1.8.1,18/11/8,N/A,,
|
||||
Astral tale,Noah,Memory Archive: Original,Nitro,PST 4,4.5,445,Nitro,PRS 7,7.0,642,Nitro,FTR 9,9.6,884,N/A,,,,Conflict,134,1.8.1,18/11/8,N/A,,✓
|
||||
Phantasia,Yunosuke,Memory Archive: Partner,Toaster,PST 4,4.0,544,Toaster,PRS 5,5.5,579,Toaster,FTR 9,9.2,952,N/A,,,,Light,153,1.8.2,18/11/29,N/A,,✓
|
||||
Empire of Winter,Street,Memory Archive: Partner,0°Nitro,PST 3,3.5,484,0°Nitro,PRS 6,6.5,662,0°Nitro,FTR 9,9.0,920,N/A,,,,Light,175,1.8.3,18/12/22,N/A,,✓
|
||||
MERLIN,REDALiCE,Groove Coaster,Got More Taro?,PST 3,3.0,315,Got More Taro?,PRS 5,5.5,428,Got More Taro?,FTR 8+,8.9,712,EXSCHWASiON,BYD 9,9.4,881,Light,180,1.9.0,19/1/9,3.12.4,22/3/23,
|
||||
OMAKENO Stroke,t+pazolite,Groove Coaster,Kurorak,PST 3,3.0,502,Kurorak,PRS 6,6.5,616,Kurorak,FTR 9,9.5,869,NITRO,BYD 10,10.2,931,Conflict,240,1.9.0,19/1/9,3.12.4,22/3/23,
|
||||
"DX Choseinou
|
||||
Full Metal Shojo","IOSYS TRAX
|
||||
(uno with ちよこ)",Groove Coaster,"DX譜面作者フルメ
|
||||
タルNitro",PST 3,3.0,327,"DX譜面作者フルメ
|
||||
タルNitro",PRS 6,6.0,556,"DX譜面作者フルメ
|
||||
タルNitro",FTR 9+,9.8,808,N/A,,,,Light,160,1.9.0,19/1/9,N/A,,
|
||||
Scarlet Lance,MASAKI (ZUNTATA),Groove Coaster,闇運,PST 4,4.0,517,闇運,PRS 7,7.0,644,闇運,FTR 10,10.1,"1,130",N/A,,,,Light,186,1.9.0,19/1/9,N/A,,
|
||||
ouroboros -twin stroke of the end-,Cranky vs. MASAKI,Groove Coaster,Groove 東星,PST 4,4.5,575,Groove 東星,PRS 7,7.5,832,Groove 東星,FTR 10+,10.7,"1,369",N/A,,,,Conflict,188,1.9.0,19/1/9,N/A,,
|
||||
Libertas,Zekk,Memory Archive: Original,Kurorak,PST 3,3.5,476,Kurorak,PRS 5,5.5,514,Kurorak + Nitro,FTR 9,9.2,947,Exschwasion -unbound-,BYD 10,10.5,"1,048",Light,160,1.9.2,19/2/11,5.3.0,24/1/25,✓
|
||||
Solitary Dream,ak+q feat. Sennzai,Eternal Core,,PST 4,4.0,712,,PRS 7,7.0,854,,FTR 8+,8.8,972,N/A,,,,Light,162,1.9.3,19/3/9,N/A,,✓
|
||||
Antithese,Blacklolita,Absolute Reason,chaos//engine,PST 2,2.0,845,chaos//engine,PRS 5,5.0,826,chaos//engine,FTR 8+,8.8,877,石樂,BYD 9,9.5,968,Conflict,172,2.0.0,19/3/21,3.10.0,21/12/9,✓
|
||||
Black Territory,DJ Myosuke,Absolute Reason,NitroNukeδ,PST 3,3.0,627,NitroNukeδ,PRS 7,7.5,785,NitroNukeδ,FTR 9+,9.8,"1,195",N/A,,,,Conflict,200,2.0.0,19/3/21,N/A,,✓
|
||||
Corruption,3R2,Absolute Reason,₸öα$†ε₹,PST 3,3.0,664,₸öα$†ε₹,PRS 6,6.5,847,₸öα$†ε₹,FTR 9+,9.8,"1,293",N/A,,,,Conflict,170,2.0.0,19/3/21,N/A,,✓
|
||||
Vicious Heroism,Kobaryo,Absolute Reason,Nitro vanquish Toaster.,PST 4,4.0,430,Nitro vanquish Toaster.,PRS 7,7.5,756,Nitro vanquish Toaster.,FTR 10,10.0,"1,150",N/A,,,,Conflict,256,2.0.0,19/3/21,N/A,,✓
|
||||
Cyaegha,USAO,Absolute Reason,夜浪、旧支配者,PST 5,5.5,760,夜浪、旧支配者,PRS 8,8.4,984,夜浪、旧支配者,FTR 10+,10.7,"1,368",N/A,,,,Conflict,200,2.0.0,19/3/21,N/A,,✓
|
||||
Grimheart,Puru,Arcaea,Toaster,PST 2,2.5,728,Toaster,PRS 5,5.0,699,Toaster,FTR 8+,8.7,959,N/A,,,,Light,170,2.0.0,19/3/21,N/A,,
|
||||
ReviXy,ikaruga_nex,Arcaea,Revoke Kurorak,PST 3,3.0,538,Revoke Kurorak,PRS 7,7.0,729,Revoke Kurorak,FTR 9,9.0,"1,047",N/A,,,,Conflict,115-185,2.0.0,19/3/21,N/A,,
|
||||
"Red and Blue
|
||||
and Green","fn(Arcaea
|
||||
SoundTeam)",Arcaea,N/A,,,,N/A,,,,《WARNING》 -chartaesthesia- and †chartaesthesia† UNCHAINED,FTR ?,0.0,"1,508","moonquay ""retrograde"" BLUE=LEFT RIGHT=RED",BYD 10,10.0,"1,194",Conflict,160,2.0.2,19/4/1,3.12.2,22/3/9,✓
|
||||
VECTOЯ,WHITEFISTS,Arcaea,Nitro,PST 3,3.0,675,Nitro,PRS 7,7.0,"1,002",Nitro,FTR 9,9.4,"1,299",N/A,,,,Conflict,200,2.0.3,19/5/2,N/A,,
|
||||
SUPERNOVA,BACO,Arcaea,東超新星,PST 3,3.0,664,東超新星,PRS 6,6.0,564,東超新星,FTR 9+,9.7,"1,123",N/A,,,,Conflict,150,2.0.3,19/5/2,N/A,,
|
||||
"Dot to Dot
|
||||
feat. shully",Mameyudoufu,Memory Archive: Variety,•Nitro•,PST 3,3.0,453,•Nitro•,PRS 6,6.0,522,•Nitro•,FTR 8,8.3,739,N/A,,,,Light,174,2.0.3,19/5/2,N/A,,
|
||||
Garakuta Doll Play,t+pazolite,CHUNITHM,Arcaea Charting Team 【Royal Flush】,PST 4,4.5,444,Arcaea Charting Team 【Royal Flush】,PRS 6,6.5,572,Arcaea Charting Teamからの挑戦状,FTR 10,10.4,"1,035",N/A,,,,Conflict,256,2.1.0,19/5/23,N/A,,
|
||||
Ikazuchi,光吉猛修,CHUNITHM,"先史の機械神
|
||||
【夜浪】",PST 3,3.5,656,"先史の機械神
|
||||
【夜浪】",PRS 7,7.5,976,"先史の機械神
|
||||
【夜浪】",FTR 10,10.4,"1,347",N/A,,,,Conflict,200,2.1.0,19/5/23,N/A,,
|
||||
World Vanquisher,void (Mournfinale),CHUNITHM,処刑人 【東星】,PST 2,2.5,529,処刑人 【東星】,PRS 5,5.5,759,処刑人 【東星】,FTR 10+,10.8,"1,452",N/A,,,,Light,170,2.1.0,19/5/23,N/A,,
|
||||
Particle Arts,Virtual Self,Adverse Prelude,小東星,PST 3,3.5,529,小東星,PRS 6,6.0,637,小東星,FTR 8+,8.8,925,N/A,,,,Conflict,162-175,2.2.0,19/7/18,N/A,,
|
||||
Vindication,Laur,Adverse Prelude,Toaster,PST 4,4.0,721,Toaster,PRS 6,6.5,899,Nitro vs Toaster,FTR 9,9.6,"1,075",N/A,,,,Light,174,2.2.0,19/7/18,N/A,,✓
|
||||
Heavensdoor,LeaF,Adverse Prelude,Kurorak,PST 4,4.5,766,Kurorak,PRS 7,7.5,869,Black Tea,FTR 9+,9.9,"1,101",東星※天の門,BYD 10+,10.8,"1,534",Conflict,240,2.2.0,19/7/18,3.10.0,21/12/9,✓
|
||||
Ringed Genesis,Edelritter,Adverse Prelude,夜浪 vs Nitro,PST 5,5.5,672,夜浪 vs Nitro,PRS 8,8.4,860,夜浪 vs Nitro,FTR 10+,10.8,"1,146",N/A,,,,Light,160,2.2.0,19/7/18,N/A,,✓
|
||||
Dreadnought,"Mastermind
|
||||
(xi + nora2r)",Memory Archive: Variety,Astronomer (Toaster + 東星),PST 4,4.0,715,Astronomer (Toaster + 東星),PRS 7,7.0,897,Astronomer (Toaster + 東星),FTR 9+,9.7,"1,099",N/A,,,,Conflict,96-384,2.2.0,19/7/18,N/A,,
|
||||
Chelsea,7mai,Sunset Radiance,TaroNuke,PST 3,3.0,388,TaroNuke,PRS 6,6.0,503,TaroNuke,FTR 8+,8.9,650,N/A,,,,Light,174,2.3.0,19/8/22,N/A,,✓
|
||||
AI[UE]OON,MYUKKE.,Sunset Radiance,N[I]TRO,PST 3,3.5,436,N[I]TRO,PRS 6,6.5,623,N[I]TRO,FTR 9,9.4,989,N/A,,,,Light,145,2.3.0,19/8/22,N/A,,✓
|
||||
A Wandering Melody of Love,からとP⍺ոchii少年 feat. はるの,Sunset Radiance,恋のToaster,PST 3,3.5,422,恋のToaster,PRS 7,7.5,670,恋のToaster,FTR 9,9.6,931,N/A,,,,Light,165,2.3.0,19/8/22,N/A,,✓
|
||||
Tie me down gently,"溝口ゆうま
|
||||
feat. 大瀬良あい",Sunset Radiance,Kurorak,PST 3,3.0,581,Kurorak,PRS 5,5.5,535,Kurorak,FTR 8,8.3,724,N/A,,,,Conflict,191,2.3.0,19/8/22,N/A,,✓
|
||||
Valhalla:0,Juggernaut.,Sunset Radiance,夜浪,PST 4,4.5,624,夜浪,PRS 7,7.5,893,夜浪,FTR 10,10.4,"1,173",N/A,,,,Conflict,200,2.3.0,19/8/22,N/A,,✓
|
||||
Mirzam,Aoi vs. siqlo,Memory Archive: Original,"東星※
|
||||
おおいぬ座β星",PST 4,4.0,662,"東星※
|
||||
おおいぬ座β星",PRS 7,7.5,885,"東星※
|
||||
おおいぬ座β星",FTR 10,10.0,"1,303",N/A,,,,Conflict,201,2.3.2,19/9/7,N/A,,✓
|
||||
GLORY : ROAD,"uma vs.
|
||||
モリモリあつし",Crimson Solace,東星※紅空,PST 4,4.5,868,東星※紅空,PRS 7,7.0,999,東星※紅空,FTR 10,10.6,"1,479",N/A,,,,Light,250,2.4.0,19/10/8,N/A,,✓
|
||||
Diode,Kolaa,Arcaea,Kurorak,PST 2,2.5,452,Kurorak,PRS 5,5.5,472,Kurorak,FTR 8,8.1,709,N/A,,,,Light,132,2.4.0,19/10/8,N/A,,✓
|
||||
FREEF4LL,YUKIYANAGI,Arcaea,N↓TRO,PST 4,4.0,589,N↓TRO,PRS 7,7.0,782,N↓TRO,FTR 8,8.6,"1,023",TO4STER,BYD 9+,9.8,"1,336",Conflict,170,2.4.0,19/10/8,4.1.4,22/11/10,✓
|
||||
Monochrome Princess,polysha,Arcaea,N↕︎tro,PST 4,4.5,621,N↕︎tro,PRS 7+,7.8,756,N↕︎tro,FTR 9+,9.7,974,N/A,,,,Conflict,160,2.4.3,19/10/26,N/A,,✓
|
||||
Heavenly caress,Noah,Memory Archive: Original,Toaster,PST 3,3.5,855,Toaster,PRS 7,7.5,909,Toaster,FTR 9+,9.8,"1,560",N/A,,,,Light,241,2.4.3,19/10/26,N/A,,✓
|
||||
Senkyou,MYTK,Arcaea,k//eternal,PST 3,3.0,627,k//eternal,PRS 5,5.5,722,k//eternal,FTR 8+,8.7,964,N/A,,,,Light,90,2.4.5,19/11/18,N/A,,✓
|
||||
Filament,Puru,Memory Archive: Original,Toaster,PST 4,4.5,582,Toaster,PRS 7+,7.8,780,Toaster,FTR 9+,9.7,991,N/A,,,,Light,170,2.4.5,19/11/18,N/A,,✓
|
||||
Avant Raze,"Sampling
|
||||
Masters MEGA",Memory Archive: Partner,Avant Toast,PST 3,3.5,580,Avant Toast,PRS 6,6.5,727,Avant Toast,FTR 9,9.6,"1,125",N/A,,,,Conflict,200,2.4.7,19/12/9,N/A,,✓
|
||||
BATTLE NO.1,"TANO*C
|
||||
Sound Team",Memory Archive: Variety,Arcaea Team,PST 3,3.5,476,Arcaea Team,PRS 6,6.5,677,Arcaea Team,FTR 9+,9.7,"1,042",N/A,,,,Conflict,200,2.4.9,20/1/15,N/A,,
|
||||
La'qryma of the Wasteland,DJ Noriken,Memory Archive: Original,Toaster,PST 3,3.5,447,Toaster,PRS 6,6.5,651,Toaster,FTR 9,9.1,956,"Nitro
|
||||
「The Forsaken」",BYD 9+,9.9,"1,161",Conflict,168,2.5.0,20/1/22,3.6.4,21/6/30,✓
|
||||
Einherjar Joker,DJ Genki vs. Gram,Memory Archive: Original,Requiem TaroNuke,PST 4,4.0,582,Requiem TaroNuke,PRS 7,7.0,767,Requiem TaroNuke,FTR 9+,9.8,"1,159",~REQUIEM~ 夜浪,BYD 10+,10.9,"1,857",Conflict,222,2.5.0,20/1/22,5.3.0,24/1/25,✓
|
||||
IZANA,"t+pazolite
|
||||
vs. P*Light",Memory Archive: Original,NITRO,PST 5,5.0,609,NITRO,PRS 8,8.3,836,NITRO,FTR 10,10.3,976,N/A,,,,Light,222,2.5.0,20/1/22,N/A,,✓
|
||||
SAIKYO STRONGER,"REDALiCE
|
||||
vs. USAO",Memory Archive: Partner,"最強FUMEN
|
||||
(夜浪 ft. 東星)",PST 5,5.5,654,"最強FUMEN
|
||||
(夜浪 ft. 東星)",PRS 9,9.4,"1,067","最強FUMEN
|
||||
(夜浪 ft. 東星)",FTR 11,11.0,"1,384",N/A,,,,Conflict,205,2.5.0,20/1/22,N/A,,✓
|
||||
world.execute(me);,Mili,Arcaea,toaster.chart(this);,PST 3,3.5,452,toaster.chart(this);,PRS 5,5.0,582,toaster.chart(this);,FTR 8,8.0,851,N/A,,,,Light,130,2.5.2,20/2/21,N/A,,
|
||||
BLRINK,Sta,Adverse Prelude,過去の縁,PST 3,3.5,400,現在の縁,PRS 7+,7.8,683,未来の縁,FTR 9+,9.7,"1,015",N/A,,,,Conflict,115,2.5.3,20/3/9,N/A,,✓
|
||||
"corps-sans-
|
||||
organes",cybermiso,Ambivalent Vision,夜浪 「月食」,PST 4,4.5,438,夜浪 「月食」,PRS 7+,7.8,615,夜浪 「月食」,FTR 10,10.6,"1,077",N/A,,,,Conflict,105,2.6.0,20/3/25,N/A,,✓
|
||||
Oblivia,Saiph,Arcaea,Toaster,PST 3,3.5,574,Toaster,PRS 5,5.0,517,Toaster,FTR 8,8.3,956,"Nitro
|
||||
「The Forgotten」",BYD 9+,9.7,"1,021",Light,180,2.6.0,20/3/25,5.3.0,24/1/25,✓
|
||||
amygdata,nitro,Memory Archive: Original,Nitro,PST 4,4.0,504,Nitro,PRS 7,7.5,711,Nitro,FTR 9+,9.7,"1,199",N/A,,,,Conflict,154,2.6.0,20/3/25,N/A,,✓
|
||||
Singularity VVVIP,Arcaea Sound Team against ETIA.,Binary Enfold,N/A,,,,N/A,,,,"《WARNING》
|
||||
Arcaea Charting Team
|
||||
【Electrify】 vs TaroNuke",FTR ?,0.0,770,Exschwasion against. 絶滅,BYD 10,10.4,"1,114",Conflict,175,2.6.1,20/4/1,3.12.2,22/3/9,✓
|
||||
Equilibrium,Maozon,Black Fate,Kurorak,PST 3,3.5,587,Kurorak,PRS 6,6.5,724,Kurorak,FTR 9,9.4,951,N/A,,,,Light,180,3.0.0,20/5/27,N/A,,✓
|
||||
Antagonism,Yooh vs. siromaru,Black Fate,Toaster,PST 4,4.5,431,Toaster,PRS 7+,7.8,738,Toaster,FTR 9+,9.9,"1,142",N/A,,,,Conflict,160,3.0.0,20/5/27,N/A,,✓
|
||||
Lost Desire,"Powerless
|
||||
feat. Sennzai",Black Fate,Darkest Dream,PST 4,4.0,684,Darkest Dream,PRS 7+,7.8,871,Darkest Dream,FTR 9+,9.8,"1,154",N/A,,,,Conflict,170,3.0.0,20/5/27,N/A,,✓
|
||||
#1f1e33,かめりあ(EDP),Black Fate,夜浪,PST 5,5.5,765,夜浪,PRS 9,9.2,"1,144","夜浪 VS 東星 ""Convergence""",FTR 10+,10.9,"1,576",N/A,,,,Conflict,181,3.0.0,20/5/27,N/A,,✓
|
||||
Dantalion,Team Grimoire,Black Fate,夜浪,PST 5,5.0,731,東星,PRS 8,8.2,843,"夜浪 X 東星
|
||||
""The Lost""",FTR 10+,10.9,"1,476",N/A,,,,Conflict,186,3.0.0,20/5/27,N/A,,✓
|
||||
Tempestissimo,t+pazolite,Black Fate,Prelude - Overture,PST 7,7.0,919,Convergence - Intermezzo,PRS 9,9.5,"1,034",Onslaught - Crescendo,FTR 10+,10.7,"1,254","Finale -
|
||||
The Tempest",BYD 11,11.5,"1,540",Conflict,231,3.0.0,20/5/27,3.0.0,20/5/27,✓
|
||||
Arcahv,Feryquitous,Black Fate,∅,PST 4,4.5,818,∅,PRS 7+,7.8,884,∅,FTR 9+,9.9,"1,065",N/A,,,,Light,191,3.0.0,20/5/27,N/A,,✓
|
||||
1F√,WHITEFISTS,Extend Archive 1: Visions,Nitro,PST 2,2.5,411,Nitro,PRS 6,6.5,539,Nitro,FTR 8,8.2,758,N/A,,,,Light,130,3.0.0,20/5/27,N/A,,
|
||||
"Gekka
|
||||
(Short Version)",Nhato,Extend Archive 1: Visions,Nitro,PST 4,4.0,559,Nitro,PRS 6,6.5,628,Nitro,FTR 8,8.6,817,N/A,,,,Light,132,3.0.0,20/5/27,N/A,,
|
||||
Give Me a Nightmare,"アリスシャッハと
|
||||
魔法の楽団",Extend Archive 1: Visions,CERiNG,PST 3,3.5,676,CERiNG,PRS 5,5.5,817,CERiNG,FTR 8+,8.9,948,N/A,,,,Conflict,95-190,3.0.0,20/5/27,N/A,,✓
|
||||
Vivid Theory,ak+q,Extend Archive 1: Visions,TaroNuke,PST 2,2.0,447,TaroNuke,PRS 5,5.0,658,TaroNuke,FTR 8+,8.8,885,N/A,,,,Light,178,3.0.0,20/5/27,N/A,,✓
|
||||
Black Lotus,wa.,Extend Archive 1: Visions,Exschwasion,PST 3,3.0,653,Exschwasion,PRS 6,6.5,687,Exschwasion,FTR 9+,9.7,965,N/A,,,,Conflict,200,3.0.0,20/5/27,N/A,,
|
||||
Altale,Sakuzyo,Memory Archive: Variety,Kurorak,PST 2,2.5,357,Kurorak,PRS 5,5.5,424,Kurorak,FTR 9+,9.7,690,N/A,,,,Light,83-90,3.0.0,20/5/27,N/A,,
|
||||
"Faint Light
|
||||
(Arcaea Edit)",Taishi,Extend Archive 1: Visions,Nitro,PST 3,3.0,587,Nitro,PRS 6,6.0,711,Nitro,FTR 9,9.1,809,N/A,,,,Light,133,3.0.3,20/7/8,N/A,,
|
||||
"Feels So Right
|
||||
feat. Renko",Mysteka,Memory Archive: Variety,Toaster,PST 3,3.5,594,Toaster,PRS 6,6.5,636,Toaster,FTR 9,9.3,947,N/A,,,,Light,180,3.0.3,20/7/8,N/A,,
|
||||
Scarlet Cage,Daisuke Kurosawa,Memory Archive: Partner,赤Nitro,PST 4,4.0,570,赤Nitro,PRS 7,7.5,711,赤Nitro,FTR 9+,9.8,"1,195",N/A,,,,Conflict,166,3.0.3,20/7/8,N/A,,✓
|
||||
Teriqma,owl*tree,Memory Archive: Music Game,Nitro,PST 3,3.0,345,Nitro,PRS 6,6.5,579,Nitro,FTR 9,9.4,873,én 200716,BYD 9+,9.7,954,Conflict,128,3.0.5,20/7/16,4.4.0,23/3/23,
|
||||
MAHOROBA,Zekk,Memory Archive: Partner,Nitro,PST 3,3.0,422,Nitro,PRS 6,6.5,632,TaroNuke + Nitro,FTR 9,9.5,828,N/A,,,,Light,195,3.0.6,20/8/7,N/A,,✓
|
||||
BADTEK,EBIMAYO,Memory Archive: Original,Toaster,PST 4,4.0,532,Toaster,PRS 7,7.0,595,"BADTOAST
|
||||
feat. Kurorak",FTR 9+,9.7,916,N/A,,,,Conflict,190,3.1.0,20/8/21,N/A,,✓
|
||||
Malicious Mischance,s-don,Memory Archive: Partner,×NITRO×,PST 4,4.0,510,×NITRO×,PRS 7+,7.8,706,×NITRO×,FTR 10,10.2,"1,126",N/A,,,,Conflict,155,3.1.2,20/9/3,N/A,,✓
|
||||
Got hive of Ra,E.G.G.,Groove Coaster,Groove Nitro,PST 3,3.0,322,Groove Nitro,PRS 6,6.5,509,Groove Nitro,FTR 9+,9.8,794,N/A,,,,Light,268,3.2.0,20/9/16,N/A,,
|
||||
BUCHiGiRE Berserker,"REDALiCE
|
||||
vs. MASAKI",Memory Archive: Music Game,夜浪,PST 5,5.0,850,夜浪,PRS 8,8.6,"1,046","東星 vs 夜浪
|
||||
《BERSERK》",FTR 10+,10.9,"1,412",N/A,,,,Conflict,200,3.2.0,20/9/16,N/A,,
|
||||
CROSS†OVER,HyuN feat. LyuU,Extend Archive 1: Visions,Exschwasion,PST 4,4.0,653,Exschwasion,PRS 6,6.5,810,Exschwasion,FTR 9,9.4,"1,094",N/A,,,,Conflict,200,3.2.1,20/10/7,N/A,,
|
||||
Galaxy Friends,Kobaryo,Memory Archive: Variety,Nitrome X,PST 3,3.5,474,Nitrome X,PRS 6,6.0,572,Nitrome X,FTR 9+,9.8,"1,013",N/A,,,,Conflict,300,3.2.1,20/10/7,N/A,,
|
||||
Lapis,SHIKI,Extend Archive 1: Visions,CERiNG,PST 2,2.0,391,CERiNG,PRS 6,6.0,520,CERiNG,FTR 9,9.4,920,N/A,,,,Light,146,3.2.2,20/10/30,N/A,,
|
||||
Xeraphinite,BlackY,Memory Archive: Original,東星※空の宝石,PST 3,3.0,383,東星※空の宝石,PRS 7,7.5,643,東星※空の宝石,FTR 9+,9.8,"1,048",N/A,,,,Light,146,3.2.2,20/10/30,N/A,,✓
|
||||
Xanatos,Tatsh,Memory Archive: Original,XERiNG,PST 4,4.0,735,eXschwasion,PRS 7,7.5,938,XERiNG × eXschwasion × NitromeX,FTR 10,10.0,"1,232",N/A,,,,Conflict,170,3.2.3,20/11/19,N/A,,✓
|
||||
Eccentric Tale,Yamajet,Ephemeral Page,Nitro,PST 2,2.0,313,Nitro,PRS 5,5.5,483,Nitro,FTR 8,8.4,732,N/A,,,,Conflict,132,3.3.0,20/12/3,N/A,,✓
|
||||
Alice à la mode,Masanori Akita,Ephemeral Page,Toaster,PST 2,2.5,436,Toaster,PRS 6,6.5,618,Toaster,FTR 9,9.2,872,N/A,,,,Light,80-134,3.3.0,20/12/3,N/A,,✓
|
||||
Alice's Suitcase,Endorfin.,Ephemeral Page,Kurorak,PST 3,3.5,644,Kurorak,PRS 6,6.0,660,Kurorak,FTR 9,9.1,999,N/A,,,,Light,190,3.3.0,20/12/3,N/A,,✓
|
||||
Jump,Rasmus Faber,Ephemeral Page,Nitroだー!,PST 4,4.0,531,Nitroだー!,PRS 6,6.0,622,Nitroだー!,FTR 9,9.0,841,N/A,,,,Light,133,3.3.0,20/12/3,N/A,,✓
|
||||
Felis,M2U,Ephemeral Page,東星,PST 4,4.0,463,東星,PRS 7,7.5,624,東星,FTR 10,10.4,"1,153",N/A,,,,Light,155,3.3.0,20/12/3,N/A,,✓
|
||||
Purple Verse,Hommarju,Extend Archive 1: Visions,Exschwasion,PST 4,4.0,558,Exschwasion,PRS 7,7.5,664,Exschwasion,FTR 9,9.6,"1,023",/ERROR/ 絶滅,BYD 10,10.6,"1,202",Conflict,170,3.3.0,20/12/3,5.3.0,24/1/25,✓
|
||||
Beside You,江口孝宏,The Journey Onwards,CERiNG,PST 2,2.5,526,CERiNG,PRS 6,6.0,634,CERiNG,FTR 8+,8.7,703,N/A,,,,Light,181,3.3.1,20/12/9,N/A,,✓
|
||||
Heart Jackin',Yu_Asahina,The Journey Onwards,TaroNuke + Nitro,PST 3,3.0,506,TaroNuke + Nitro,PRS 5,5.5,543,TaroNuke + Nitro,FTR 9+,9.7,"1,112",N/A,,,,Light,160,3.3.1,20/12/9,N/A,,✓
|
||||
To: Alice Liddell,モリモリあつし,The Journey Onwards,"Yours Sincerely,
|
||||
夜浪",PST 4,4.0,535,"Yours Sincerely,
|
||||
夜浪",PRS 7,7.5,674,"Yours Sincerely,
|
||||
夜浪",FTR 10,10.3,998,N/A,,,,Conflict,222,3.3.1,20/12/9,N/A,,✓
|
||||
Lazy Addiction,sky_delta,O.N.G.E.K.I.,Nitro without Toaster.,PST 2,2.5,462,Nitro without Toaster.,PRS 6,6.0,647,Nitro without Toaster.,FTR 9,9.6,"1,031",N/A,,,,Light,185,3.4.0,20/12/17,N/A,,
|
||||
Dazzle hop,"Sampling
|
||||
Masters MEGA",O.N.G.E.K.I.,Kuro rak,PST 3,3.5,561,Kuro rak,PRS 6,6.5,571,Kuro rak,FTR 9+,9.7,"1,022",N/A,,,,Conflict,220,3.4.0,20/12/17,N/A,,
|
||||
Viyella's Tears,Laur,O.N.G.E.K.I.,東星の涙,PST 4,4.0,716,東星の涙,PRS 7+,7.8,942,東星の涙,FTR 10,10.3,"1,403",N/A,,,,Conflict,218,3.4.0,20/12/17,N/A,,
|
||||
ω4,"穴山大輔 vs.
|
||||
光吉猛修 vs. Kai",O.N.G.E.K.I.,τ0,PST 3,3.5,816,τ0,PRS 7+,7.8,943,τ0,FTR 10+,10.8,"1,393",N/A,,,,Light,71-192,3.4.0,20/12/17,N/A,,
|
||||
April showers,cubesato,maimai,Nitro-100号,PST 2,2.0,363,Nitro-100号,PRS 5,5.5,544,Nitro-100号,FTR 8,8.6,697,N/A,,,,Light,79,3.4.1,21/1/8,N/A,,
|
||||
7thSense,削除,maimai,石樂,PST 3,3.0,360,石樂,PRS 7+,7.8,739,石樂,FTR 9+,9.9,925,N/A,,,,Conflict,150,3.4.1,21/1/8,N/A,,
|
||||
Oshama Scramble!,t+pazolite,maimai,Nitro!+9牛乳,PST 3,3.5,508,Nitro!+99牛乳,PRS 6,6.5,568,Nitro!+999牛乳,FTR 10,10.0,"1,073",N/A,,,,Light,190,3.4.1,21/1/8,N/A,,
|
||||
AMAZING MIGHTYYYY!!!!,WAiKURO,maimai,AMAZING TOASTYYYY!!!!,PST 4,4.5,624,AMAZING TOASTYYYY!!!!,PRS 7+,7.8,776,AMAZING TOASTYYYY!!!!,FTR 10+,10.7,"1,249",N/A,,,,Conflict,185,3.4.1,21/1/8,N/A,,
|
||||
Climax,USAO,CHUNITHM 2,"Nitro
|
||||
-EXTRA ROUND-",PST 4,4.5,773,"Nitro
|
||||
-EXTRA ROUND-",PRS 7+,7.8,988,"Nitro
|
||||
-EXTRA ROUND-",FTR 10,10.4,"1,367",N/A,,,,Conflict,190,3.5.0,21/1/21,N/A,,
|
||||
Last Celebration,Laur vs. CK,CHUNITHM 2,Nitro affected by 'CHUNITHM',PST 3,3.5,969,Nitro affected by 'CHUNITHM',PRS 6,6.5,994,Nitro affected by 'CHUNITHM',FTR 10,10.5,"1,475",N/A,,,,Conflict,238,3.5.0,21/1/21,N/A,,
|
||||
"Misdeed
|
||||
-la bonté de Dieu et l'origine du mal-","光吉猛修
|
||||
vs. 穴山大輔",CHUNITHM 2,"神の啓示
|
||||
「人類の限界」",PST 5,5.5,814,"神の啓示
|
||||
「人類の希望」",PRS 8,8.5,"1,070","神の啓示
|
||||
「人類の未来」",FTR 10+,10.9,"1,522",N/A,,,,Light,190,3.5.0,21/1/21,N/A,,
|
||||
AttraqtiA,かめりあ,Memory Archive: Original,Toaster affected by 'CHUNITHM',PST 4,4.0,732,Toaster affected by 'CHUNITHM',PRS 8,8.3,"1,002",Toaster affected by 'CHUNITHM',FTR 10,10.6,"1,433",N/A,,,,Light,202,3.5.0,21/1/21,N/A,,✓
|
||||
Glow,SPACELECTRO,Extend Archive 1: Visions,Exschwasion,PST 4,4.0,504,Exschwasion,PRS 7,7.5,666,Exschwasion,FTR 9,9.3,916,N/A,,,,Conflict,165,3.5.0,21/1/21,N/A,,✓
|
||||
enchanted love,linear ring,Extend Archive 1: Visions,Toaster,PST 2,2.0,436,Toaster,PRS 4,4.5,617,Toaster,FTR 8,8.6,759,N/A,,,,Light,95,3.5.1,21/2/11,N/A,,
|
||||
Bamboo,立秋 feat. ちょこ,Extend Archive 1: Visions,竹の子,PST 3,3.0,499,竹の子,PRS 6,6.5,631,竹の子,FTR 10,10.0,"1,050",N/A,,,,Light,5-315,3.5.1,21/2/11,N/A,,
|
||||
"GIMME
|
||||
DA BLOOD",C-Show,Memory Archive: Partner,夜浪,PST 3,3.5,582,夜浪,PRS 7,7.5,737,夜浪,FTR 10,10.4,"1,093",N/A,,,,Conflict,87-110,3.5.2,21/3/9,N/A,,✓
|
||||
overdead.,fn,Memory Archive: Original,N/A,,,,N/A,,,,《WARNING》 -chartaesthesia- LIMITER:underflow_error% (OVERDRIVE:+overflow_error%),FTR ?,0.0,"1,228",絶滅 over 夜浪.,BYD 10,10.5,"1,503",Conflict,500,3.5.3,21/4/1,3.12.2,22/3/9,✓
|
||||
Life is PIANO,Junk,Extend Archive 1: Visions,Nitro,PST 3,3.5,398,Nitro,PRS 6,6.0,437,Nitro,FTR 9,9.1,674,N/A,,,,Light,133,3.5.4,21/4/9,N/A,,
|
||||
Can I Friend You on Bassbook? Lol,"かめりあ
|
||||
feat. ななひら",Memory Archive: Variety,トースト食べる?笑,PST 3,3.0,415,トースト食べる?笑,PRS 6,6.5,548,トースト食べる?笑,FTR 9,9.3,861,N/A,,,,Light,128,3.5.4,21/4/9,N/A,,
|
||||
Paper Witch,Yu-dachi,Esoteric Order,CERiNG,PST 2,2.0,348,CERiNG,PRS 5,5.0,487,CERiNG,FTR 8+,8.7,793,N/A,,,,Light,130,3.6.0,21/5/11,N/A,,✓
|
||||
Crystal Gravity,"Tanchiky
|
||||
vs. siromaru",Esoteric Order,Exschwasion,PST 3,3.5,571,Exschwasion,PRS 6,6.5,653,Exschwasion,FTR 9,9.4,872,N/A,,,,Conflict,178,3.6.0,21/5/11,N/A,,✓
|
||||
Far Away Light,"technoplanet feat.
|
||||
はるの & 黒沢ダイスケ",Esoteric Order,Toaster,PST 4,4.5,656,Toaster,PRS 7+,7.8,769,Toaster,FTR 9+,9.8,"1,322",N/A,,,,Light,180-216,3.6.0,21/5/11,N/A,,✓
|
||||
Löschen,"BlackY feat.
|
||||
Risa Yuzuki",Esoteric Order,絶滅,PST 3,3.5,642,絶滅,PRS 7,7.0,850,絶滅,FTR 10,10.2,"1,235",N/A,,,,Conflict,181,3.6.0,21/5/11,N/A,,✓
|
||||
Aegleseeker,"Silentroom
|
||||
vs. Frums",Esoteric Order,<RECORD START> 0:,PST 5,5.5,973,"<OBSRV> boundary(?°a,?°A)",PRS 9,9.1,"1,235",L₆: The Void,FTR 11,11.1,"1,568",N/A,,,,Light,234,3.6.0,21/5/11,N/A,,✓
|
||||
Coastal Highway,Glitch Droids,Pale Tapestry,Exschwasion,PST 3,3.0,355,Exschwasion,PRS 6,6.0,479,Exschwasion,FTR 9,9.0,732,N/A,,,,Light,110,3.6.0,21/5/11,N/A,,✓
|
||||
ΟΔΥΣΣΕΙΑ,Sober Bear,Pale Tapestry,ΤΟΑΣΤΕΡ,PST 4,4.0,717,ΤΟΑΣΤΕΡ,PRS 7+,7.8,909,ΤΟΑΣΤΕΡ,FTR 9,9.5,"1,092",N/A,,,,Conflict,174,3.6.0,21/5/11,N/A,,✓
|
||||
Overwhelm,xi,Pale Tapestry,夜浪,PST 5,5.0,854,夜浪,PRS 8,8.5,"1,038",夜浪,FTR 10,10.6,"1,251",N/A,,,,Light,200,3.6.0,21/5/11,N/A,,✓
|
||||
Vandalism,Ashrount,Extend Archive 1: Visions,Kurorak,PST 3,3.5,668,Kurorak,PRS 7,7.0,685,Kurorak,FTR 9+,9.7,"1,087",N/A,,,,Conflict,194,3.6.0,21/5/11,N/A,,✓
|
||||
Turbocharger,A/I,Extend Archive 1: Visions,Toaster,PST 2,2.5,419,Toaster,PRS 6,6.0,659,Toaster,FTR 9,9.0,979,N/A,,,,Light,128-170,3.6.2,21/6/10,N/A,,✓
|
||||
THE ULTIMACY,"aran vs.
|
||||
Massive New Krew",Memory Archive: Original,東星 vs Toaster,PST 3,3.0,749,東星 vs Toaster,PRS 7,7.0,919,東星 vs Toaster,FTR 9+,9.8,"1,304",N/A,,,,Conflict,200,3.6.4,21/6/30,N/A,,✓
|
||||
REKKA RESONANCE,"REDALiCE
|
||||
vs. Kobaryo",Memory Archive: Partner,夜浪 vs Nitro,PST 5,5.0,860,夜浪 vs Nitro,PRS 8+,8.9,"1,051",夜浪 vs Nitro,FTR 10+,10.7,"1,212",N/A,,,,Light,240,3.6.4,21/6/30,N/A,,✓
|
||||
Seclusion,Laur feat. Sennzai,Esoteric Order,Exschwasion,PST 4,4.0,544,Exschwasion,PRS 7,7.5,762,N•Ex•T,FTR 10,10.6,"1,132",N/A,,,,Conflict,175,3.7.0,21/7/21,N/A,,✓
|
||||
"Small Cloud
|
||||
Sugar Candy","テヅカ × Aoi
|
||||
feat. 桃雛なの",Light of Salvation,én,PST 3,3.0,548,én,PRS 6,6.5,727,én,FTR 9,9.1,919,N/A,,,,Light,220,3.7.0,21/7/21,N/A,,✓
|
||||
AlterAle,"Arik Kau Delay
|
||||
(アラ & かゆき & でり)",Light of Salvation,CERiNG,PST 3,3.0,728,CERiNG,PRS 6,6.0,881,CERiNG,FTR 9+,9.7,"1,277",N/A,,,,Light,220-245,3.7.0,21/7/21,N/A,,✓
|
||||
"Divine Light
|
||||
of Myriad",yoho,Light of Salvation,東星※神授,PST 4,4.5,798,東星※神授,PRS 7+,7.8,835,東星※神授,FTR 10+,10.8,"1,021",N/A,,,,Light,172,3.7.0,21/7/21,N/A,,✓
|
||||
False Embellishment,影虎。 & ikaruga_nex,Extend Archive 1: Visions,Exschwasion,PST 3,3.5,576,Exschwasion,PRS 6,6.5,684,Exschwasion,FTR 9,9.3,969,N/A,,,,Conflict,155,3.7.0,21/7/21,N/A,,✓
|
||||
HIVEMIND,かたぎり,Extend Archive 1: Visions,NITRO -unconnected-,PST 4,4.0,995,NITRO -unconnected-,PRS 8,8.6,988,NITRO -unconnected-,FTR 10,10.0,"1,252",N/A,,,,Conflict,252,3.7.0,21/7/21,N/A,,✓
|
||||
Quon,DJ Noriken,WACCA,CERiNG,PST 2,2.5,425,CERiNG,PRS 6,6.0,496,CERiNG,FTR 8+,8.7,749,"XIII: The
|
||||
Journey/Nitro",BYD 10,10.2,"1,044",Conflict,170,3.8.0,21/8/10,3.8.0,21/8/10,
|
||||
"Let you DIVE!
|
||||
(nitro rmx)",nitro (lowiro),WACCA,Nitro,PST 3,3.0,608,Nitro,PRS 6,6.5,819,Nitro,FTR 9,9.4,"1,049",N/A,,,,Light,185,3.8.0,21/8/10,N/A,,✓
|
||||
with U,t+pazolite & Massive New Krew feat. リリィ (CV: 青木志貴),WACCA,én,PST 2,2.5,448,én,PRS 6,6.5,649,én,FTR 9,9.4,932,N/A,,,,Light,155,3.8.0,21/8/10,N/A,,
|
||||
Mazy Metroplex,aran,WACCA,Exschwasion,PST 3,3.0,453,Exschwasion,PRS 7+,7.8,704,Exschwasion,FTR 9+,9.7,952,N/A,,,,Light,155,3.8.0,21/8/10,N/A,,
|
||||
GENOCIDER,DJ Myosuke,WACCA,Toaster,PST 4,4.5,832,Toaster,PRS 8+,8.9,"1,025",Toaster,FTR 10+,10.7,"1,483",N/A,,,,Conflict,250-390,3.8.0,21/8/10,N/A,,
|
||||
"Sheriruth
|
||||
(Laur Remix)",Laur,Memory Archive: Original,Nitro,PST 4,4.0,671,Nitro,PRS 7,7.8,795,東星※恣意,FTR 10,10.6,"1,134",N/A,,,,Conflict,200,3.8.0,21/8/10,N/A,,✓
|
||||
blue comet,ああああ,Extend Archive 1: Visions,Toaster,PST 3,3.5,494,Toaster,PRS 5,5.0,645,Toaster,FTR 8,8.2,776,N/A,,,,Light,100-172,3.8.2,21/8/24,N/A,,✓
|
||||
Evening in Scarlet,Freezer feat. 妃莓,Memory Archive: Partner,Nitroだー!,PST 4,4.0,530,Nitroだー!,PRS 7,7.0,638,Nitroだー!,FTR 9,9.5,922,N/A,,,,Conflict,170,3.8.2,21/8/24,N/A,,✓
|
||||
"ENERGY
|
||||
SYNERGY MATRIX",Tanchiky,Extend Archive 1: Visions,POWER NITRO,PST 3,3.5,471,POWER NITRO,PRS 7,7.0,608,POWER NITRO,FTR 9,9.6,922,N/A,,,,Conflict,160,3.8.4,21/9/8,N/A,,
|
||||
G e n g a o z o,-45,Extend Archive 1: Visions,_ P A S T,PST 4,4.0,580,_ P R E S E N T,PRS 8,8.1,870,_ F U T U R E,FTR 10,10.2,"1,353",N/A,,,,Conflict,153,3.8.6,21/9/28,N/A,,
|
||||
lastendconductor,zts,Memory Archive: Pop/Recommended,Nitro,PST 3,3.5,726,Nitro,PRS 7,7.5,901,Nitro,FTR 9,9.4,"1,209",Toaster,BYD 10,10.1,"1,339",Conflict,139,3.8.6,21/9/28,3.8.6,21/9/28,
|
||||
goldenslaughterer,zts,Memory Archive: Pop/Recommended,Exschwasion,PST 4,4.0,864,Exschwasion,PRS 6,6.5,880,Exschwasion,FTR 9+,9.7,"1,326",N/A,,,,Conflict,133,3.8.6,21/9/28,N/A,,
|
||||
Redolent Shape,Sanaas,Memory Archive: Original,絶滅,PST 4,4.5,570,絶滅,PRS 7,7.5,717,絶滅,FTR 10,10.2,"1,088",N/A,,,,Conflict,150,3.8.8,21/10/21,N/A,,✓
|
||||
Cosmica,Nhato,Shared Time,Nitro,PST 2,2.5,428,Nitro,PRS 5,5.0,566,Nitro missing Toaster.,FTR 8+,8.8,773,N/A,,,,Conflict,110,3.9.0,21/11/11,N/A,,✓
|
||||
Ascent,TANUKI,Shared Time,CER↑NG,PST 3,3.0,455,CER↑NG,PRS 6,6.0,626,"Exschwas↑on
|
||||
with CER↑NG",FTR 9+,9.8,"1,023",N/A,,,,Light,145,3.9.0,21/11/11,N/A,,✓
|
||||
"Live Fast
|
||||
Die Young",anubasu-anubasu,Shared Time,Nitro,PST 4,4.5,565,Nitro,PRS 8,8.1,837,Nitro with Toaster.,FTR 10,10.6,"1,292",N/A,,,,Light,153,3.9.0,21/11/11,N/A,,✓
|
||||
Summer Fireworks of Love,"karatoP⍺ոchii
|
||||
feat. はるの",Memory Archive: Original,夏のNitro,PST 3,3.0,478,夏のNitro,PRS 6,6.5,641,夏のNitro,FTR 9+,9.9,"1,088",N/A,,,,Light,160,3.9.0,21/11/11,N/A,,✓
|
||||
PRAGMATISM -RESURRECTION-,Laur,Eternal Core,N/A,,,,N/A,,,,N/A,,,,THE LAST DREAM,BYD 11,11.0,"1,502",Light,174,N/A,,3.10.0,21/12/9,✓
|
||||
First Snow,黒魔,Divided Heart,Nitro,PST 2,2.5,366,Nitro,PRS 4,4.5,442,Nitro,FTR 7+,7.8,578,N/A,,,,Light,88,3.10.0,21/12/9,N/A,,✓
|
||||
Blocked Library,影虎。,Divided Heart,Exschwasion,PST 3,3.5,449,Exschwasion,PRS 6,6.5,622,Exschwasion,FTR 9,9.3,850,N/A,,,,Conflict,148,3.10.0,21/12/9,N/A,,✓
|
||||
Blue Rose,Cosmograph,Divided Heart,CERiNG,PST 2,2.0,595,CERiNG,PRS 6,6.0,669,CERiNG,FTR 9,9.1,955,N/A,,,,Light,250-295,3.10.0,21/12/9,N/A,,✓
|
||||
nέo κósmo,ak+q × Street,Divided Heart,Nitro × Toaster,PST 4,4.0,603,Nitro × Toaster,PRS 7+,7.8,791,Nitro × Toaster,FTR 9+,9.7,979,N/A,,,,Conflict,190,3.10.0,21/12/9,N/A,,✓
|
||||
Lightning Screw,HiTECH NINJA,Divided Heart,東星,PST 4,4.5,611,東星,PRS 7+,7.8,811,東星,FTR 10,10.5,"1,192",N/A,,,,Light,190,3.10.0,21/12/9,N/A,,✓
|
||||
Lights of Muse,Ayatsugu_Otowa,Muse Dash,antymis,PST 2,2.5,333,antymis,PRS 6,6.0,438,antymis,FTR 8+,8.9,580,N/A,,,,Light,180,3.11.0,21/12/24,N/A,,
|
||||
Final Step!,Lime,Muse Dash,CERiNG,PST 3,3.5,625,CERiNG,PRS 6,6.5,684,CERiNG,FTR 9,9.4,"1,056",N/A,,,,Conflict,180,3.11.0,21/12/24,N/A,,
|
||||
Haze of Autumn,"karatoP⍺ոchii
|
||||
feat. はるの",Muse Dash,秋のén,PST 3,3.5,533,秋のén,PRS 7,7.0,733,秋のén,FTR 9+,9.8,"1,077",N/A,,,,Light,180,3.11.0,21/12/24,N/A,,✓
|
||||
Medusa,HiTECH NINJA,Muse Dash,Toaster,PST 4,4.5,550,Toaster,PRS 7,7.0,645,Toaster,FTR 10,10.2,931,N/A,,,,Conflict,165,3.11.0,21/12/24,N/A,,
|
||||
init(),kamome sano,Memory Archive: Partner,Toaster,PST 4,4.0,713,Toaster,PRS 7,7.5,957,Toaster,FTR 9+,9.8,"1,204",N/A,,,,Conflict,180,3.11.2,22/1/20,N/A,,✓
|
||||
"Ävril
|
||||
-Flicka i krans-",Rigël Theatre,Arcaea,Aster -Får i Vaaris-,PST 3,3.0,459,Aster -Får i Vaaris-,PRS 6,6.0,607,Aster -Får i Vaaris-,FTR 8,8.3,851,N/A,,,,Light,130,3.12.0,22/2/17,N/A,,
|
||||
NULCTRL,Silentroom,Arcaea,moonquay [CON],PST 3,3.0,407,moonquay [AUX],PRS 7,7.5,410,moonquay [NUL],FTR 9,9.5,715,N/A,,,,Conflict,100,3.12.0,22/2/17,N/A,,
|
||||
Sakura Fubuki,Street,Arcaea,én,PST 3,3.5,526,én,PRS 6,6.5,571,én,FTR 9,9.3,837,N/A,,,,Light,175,3.12.0,22/2/17,N/A,,
|
||||
INTERNET OVERDOSE,"Aiobahn
|
||||
feat. KOTOKO",Memory Archive: Pop/Recommended,Nitro Ch.,PST 3,3.0,430,Nitro Ch.,PRS 6,6.5,578,Nitro Ch.,FTR 8,8.4,657,N/A,,,,Light,163,3.12.0,22/2/17,N/A,,
|
||||
Macrocosmic Modulation,JAKAZiD,Memory Archive: Original,Exschwas↕on,PST 4,4.0,608,Exschwas↕on,PRS 7+,7.8,794,Exschwas↕︎on,FTR 9+,9.8,"1,117",N/A,,,,Light,170,3.12.0,22/2/17,N/A,,✓
|
||||
Kissing Lucifer,ETIA.,Memory Archive: Original,NITRO,PST 4,4.5,639,NITRO,PRS 7+,7.8,770,NITRO,FTR 10,10.4,"1,183",N/A,,,,Conflict,170,3.12.0,22/2/17,N/A,,✓
|
||||
NEO WINGS,"SOUND HOLIC
|
||||
feat. Nana Takahashi",Memory Archive: Partner,Toaster,PST 4,4.0,591,Toaster,PRS 7,7.5,840,Toaster,FTR 10,10.2,"1,328",N/A,,,,Conflict,168,3.12.0,22/2/17,N/A,,✓
|
||||
DDD,はがね,Arcaea,én,PST 2,2.5,363,én,PRS 6,6.5,484,én,FTR 8,8.5,653,N/A,,,,Light,138,3.12.4,22/3/23,N/A,,
|
||||
Head BONK ache,"saaa feat.
|
||||
MC iwata Bros.",Memory Archive: Variety,Nitro,PST 4,4.0,570,Nitro,PRS 7,7.0,725,Nitro,FTR 9,9.4,"1,061",N/A,,,,Conflict,132-165,3.12.4,22/3/23,N/A,,
|
||||
Aurgelmir,"溝口ゆうま
|
||||
feat. 大瀬良あい",Memory Archive: Music Game,夜浪,PST 4,4.5,540,夜浪,PRS 8,8.5,765,夜浪,FTR 10,10.5,"1,100",N/A,,,,Conflict,122-230,3.12.4,22/3/23,N/A,,
|
||||
Mistempered Malignance,"s-don vs.
|
||||
nitro (lowiro)",Memory Archive: Partner,N/A,,,,N/A,,,,"《WARNING》
|
||||
Arcaea Charting Team
|
||||
「Maledictive Misanthrope」",FTR ?,0.0,944,N/A,,,,Conflict,155,3.12.6,22/4/1,N/A,,✓
|
||||
Prism,bermei.inazawa feat. Chata,Lanota 2,CERiNG,PST 2,2.0,476,CERiNG,PRS 5,5.0,544,CERiNG,FTR 8,8.0,785,N/A,,,,Light,107-109,3.12.8,22/4/28,N/A,,
|
||||
Protoflicker,Silentroom,Lanota 2,antymis <prototype>,PST 3,3.0,510,antymis <prototype>,PRS 7,7.0,633,antymis <prototype>,FTR 9+,9.8,"1,042",N/A,,,,Conflict,140,3.12.8,22/4/28,N/A,,
|
||||
Stasis,Maozon,Lanota 2,東星,PST 4,4.5,848,東星,PRS 7,7.0,935,東星,FTR 10+,10.7,"1,521",N/A,,,,Light,180,3.12.8,22/4/28,N/A,,
|
||||
"Dancin' on a
|
||||
Cat's Paw",Ino(chronoize),Arcaea,antymis,PST 3,3.0,417,antymis,PRS 6,6.0,593,antymis,FTR 9,9.2,891,N/A,,,,Light,148,3.12.8,22/4/28,N/A,,
|
||||
"PICO-Pico-
|
||||
Translation!","t+pazolite, ななひら, Cranky, Pico*",Memory Archive: Variety,Translated by én,PST 2,2.0,543,Translated by én,PRS 6,6.0,723,Translated by én,FTR 9,9.3,"1,049",N/A,,,,Conflict,185,3.12.8,22/4/28,N/A,,
|
||||
san skia,ユアミトス,Arcaea,CERiNG,PST 3,3.5,670,CERiNG,PRS 6,6.0,783,CERiNG,FTR 8,8.3,"1,046",N/A,,,,Light,170,3.12.10,22/5/25,N/A,,✓
|
||||
µ,Frums,Memory Archive: Original,N↕TRO v1.0.5,PST 3,3.5,825,N↕TRO v1.0.5,PRS 7,7.5,986,N↕TRO v1.0.5,FTR 9+,9.7,"1,256",N/A,,,,Light,140-190,3.12.10,22/5/25,N/A,,✓
|
||||
Defection,"TeddyLoid
|
||||
feat. DELTA",Final Verdict,"Monolith
|
||||
Incarnate",PST 3,3.5,588,"Monolith
|
||||
Incarnate",PRS 6,6.5,800,"Monolith
|
||||
Incarnate",FTR 9+,9.8,"1,141",N/A,,,,Light,160,4.0.0,22/7/7,N/A,,✓
|
||||
"Infinite Strife,","BlackYooh
|
||||
vs. siromaru",Final Verdict,Inner Labyrinth,PST 4,4.0,888,Inner Labyrinth,PRS 7,7.5,"1,081",Inner Labyrinth,FTR 9+,9.9,"1,511",Inner Labyrinth,BYD 10+,10.9,"1,633",Conflict,198,4.0.0,22/7/7,4.0.0,22/7/7,✓
|
||||
World Ender,"sasakure.UK
|
||||
× TJ.hangneil",Final Verdict,Imaginary Sky,PST 4,4.0,616,Imaginary Sky,PRS 7+,7.8,850,Imaginary Sky,FTR 9+,9.9,"1,225",Imaginary Sky,BYD 11,11.2,"1,661",Light,190-280,4.0.0,22/7/7,4.0.0,22/7/7,✓
|
||||
Pentiment,Nothing But Requiem with Museo,Final Verdict,Paradox Blight,PST 7,7.0,911,Paradox Blight,PRS 8+,8.7,"1,055",Paradox Blight,FTR 10,10.3,"1,345",Paradox Blight,BYD 11,11.4,"1,741",Conflict,200-222,4.0.0,22/7/7,4.0.0,22/7/7,✓
|
||||
Arcana Eden,Team Grimoire vs. Sakuzyo vs. Laur,Final Verdict,Eye of the Storm,PST 5,5.5,"1,097",Eye of the Storm,PRS 8+,8.7,"1,310",Eye of the Storm,FTR 10,10.5,"1,792",Eye of the Storm,BYD 11,11.4,"2,134",Conflict,211,4.0.0,22/7/7,4.0.0,22/7/7,✓
|
||||
Testify,void (Mournfinale) feat. 星熊南巫,Final Verdict,Eternal¦PAST,PST 7+,7.8,"1,001",Adverse¦PRESENT,PRS 9,9.4,"1,225",Black¦FUTURE,FTR 10+,10.8,"1,766",Silent¦END,BYD 12,12.0,"2,221",Silent,178,4.0.0,22/7/7,4.0.0,22/7/7,✓
|
||||
"Altair
|
||||
(feat. *spiLa*)","kamome sano
|
||||
& you",Arcaea,antymis,PST 2,2.5,670,antymis,PRS 6,6.0,828,antymis,FTR 8,8.5,830,N/A,,,,Light,170,4.0.0,22/7/7,N/A,,
|
||||
Redraw the Colorless World,MisomyL,Arcaea,antymis ~無色~,PST 4,4.0,568,antymis ~彩色~,PRS 6,6.5,680,antymis ~虹色~,FTR 9,9.2,886,N/A,,,,Light,155,4.0.0,22/7/7,N/A,,
|
||||
Trap Crow,Puru,Arcaea,CERiNG + Nitro,PST 4,4.5,876,CERiNG + Nitro,PRS 7+,7.8,898,CERiNG + Nitro,FTR 9+,9.9,"1,074",N/A,,,,Conflict,80,4.0.0,22/7/7,N/A,,✓
|
||||
PUPA,モリモリあつし,Memory Archive: Variety,én -胡蝶の夢-,PST 4,4.0,374,én -胡蝶の夢-,PRS 7+,7.8,684,én -胡蝶の夢-,FTR 10,10.4,"1,099",N/A,,,,Conflict,202,4.0.0,22/7/7,N/A,,
|
||||
Loveless Dress,かねこちはる,Silent Answer,Final Prayer,PST 3,3.5,537,Final Prayer,PRS 6,6.5,630,Final Prayer,FTR 9,9.6,850,N/A,,,,Silent,99,4.0.255,22/7/13,N/A,,✓
|
||||
Last,onoken,Silent Answer,Arcaea,PST 4,4.0,680,Arcaea,PRS 7,7.0,781,Arcaea,FTR 9,9.0,831,N/A,,,,Silent,175,4.0.255,22/7/13,N/A,,✓
|
||||
Last | Moment,onoken,Silent Answer,N/A,,,,N/A,,,,N/A,,,,Arcaea,BYD 9,9.6,888,Silent,175,N/A,,4.0.255,22/7/13,✓
|
||||
Last | Eternity,onoken,Silent Answer,N/A,,,,N/A,,,,N/A,,,,Arcaea,BYD 9+,9.7,790,Silent,175,N/A,,4.0.255,22/7/13,✓
|
||||
Callima Karma,"t+pazolite
|
||||
vs. Feryquitous",Silent Answer,Forlorn Dream,PST 3,3.5,"1,024",Forlorn Dream,PRS 7,7.5,989,Forlorn Dream,FTR 9+,9.8,"1,222",N/A,,,,Silent,95,4.0.255,22/7/13,N/A,,✓
|
||||
Heart,"削除
|
||||
(Violin: Katali)",O.N.G.E.K.I. 2,"écologie
|
||||
(from SEGA)",PST 1,1.0,428,"écologie
|
||||
(from SEGA)",PRS 5,5.0,575,"écologie
|
||||
(from SEGA)",FTR 9,9.3,872,N/A,,,,Light,80,4.1.0,22/10/4,N/A,,
|
||||
Ai Drew,Feryquitous,O.N.G.E.K.I. 2,"moonquay
|
||||
【新入生】",PST 3,3.5,694,moonquay v.EXPERT,PRS 6,6.5,732,moonquay v.MASTER,FTR 9+,9.8,"1,066",N/A,,,,Conflict,175,4.1.0,22/10/4,N/A,,
|
||||
FLUFFY FLASH,Kobaryo,O.N.G.E.K.I. 2,Toaster,PST 3,3.5,787,Toaster,PRS 6,6.5,946,Toaster,FTR 9+,9.8,"1,329",N/A,,,,Light,252,4.1.0,22/10/4,N/A,,
|
||||
"Good bye, Merry-Go-Round.",Yooh,O.N.G.E.K.I. 2,絶滅,PST 4,4.5,679,絶滅,PRS 7,7.5,696,絶滅,FTR 10,10.5,"1,084",N/A,,,,Conflict,185,4.1.0,22/10/4,N/A,,
|
||||
LAMIA,BlackY,O.N.G.E.K.I. 2,夜浪,PST 5,5.0,826,"夜浪 「ノブレス・
|
||||
オブリージュ」",PRS 8,8.5,885,"[漆黒の執行者]
|
||||
夜浪",FTR 10+,10.9,"1,385",N/A,,,,Conflict,199,4.1.0,22/10/4,N/A,,
|
||||
cocoro*cosmetic,KOTONOHOUSE,Memory Archive: Original,Nitro,PST 3,3.0,525,Nitro,PRS 7,7.0,687,Nitro,FTR 9,9.2,"1,025",N/A,,,,Light,144,4.1.4,22/11/10,N/A,,✓
|
||||
Free Myself,lapix feat. mami,Memory Archive: Partner,Exschwasion,PST 4,4.5,662,Exschwasion,PRS 7,7.5,785,Exschwasion -unbound-,FTR 10,10.0,"1,132",N/A,,,,Light,153,4.1.4,22/11/10,N/A,,✓
|
||||
Dialnote,七草くりむ,Arcaea,Nitroです。,PST 3,3.0,393,Nitroです。,PRS 6,6.0,548,Nitroです。,FTR 8+,8.8,684,N/A,,,,Light,130,4.1.6,22/12/22,N/A,,
|
||||
Capella,ARForest,Memory Archive: Partner,0°Nitro,PST 4,4.5,884,0°Nitro,PRS 7+,7.8,904,0°Nitro,FTR 10,10.2,"1,159",N/A,,,,Light,210,4.1.6,22/12/22,N/A,,✓
|
||||
"Tsuki ni Murakumo, Hana ni Kaze",幽閉サテライト,Extend Archive 2: Chronicles,"Lovely Visitor
|
||||
「Toaster」",PST 3,3.0,468,"Lovely Visitor
|
||||
「Toaster」",PRS 6,6.0,610,"Lovely Visitor
|
||||
「Toaster」",FTR 8+,8.7,740,N/A,,,,Conflict,160,4.2.0,23/1/26,N/A,,
|
||||
MANTIS (Arcaea Ultra-Bloodrush VIP),"Akira Complex
|
||||
feat. kiraku",Extend Archive 2: Chronicles,ANTyMIS,PST 3,3.0,575,ANTyMIS,PRS 7,7.0,760,ANTyMIS,FTR 9,9.3,"1,014",N/A,,,,Conflict,135,4.2.0,23/1/26,N/A,,
|
||||
Astra walkthrough,paraoka,Extend Archive 2: Chronicles,Aster,PST 4,4.5,769,Aster,PRS 7+,7.8,886,Aster join Toaster.,FTR 9+,9.9,"1,191",N/A,,,,Conflict,225,4.2.0,23/1/26,N/A,,
|
||||
World Fragments III(radio edit),xi,Extend Archive 2: Chronicles,én,PST 3,3.5,777,én,PRS 7,7.0,999,"én supported
|
||||
by Nitro",FTR 9+,9.8,"1,387",N/A,,,,Light,200,4.2.0,23/1/26,N/A,,
|
||||
Chronicle,Lime,Extend Archive 2: Chronicles,夜浪 -Annales Historiae-,PST 5,5.0,928,夜浪 -Annales Historiae-,PRS 8+,8.9,"1,077",夜浪 -Annales Historiae-,FTR 10,10.4,"1,264",N/A,,,,Light,221,4.2.0,23/1/26,N/A,,✓
|
||||
NULL APOPHENIA,N²,Memory Archive: Partner,夜浪,PST 4,4.5,990,夜浪,PRS 8+,8.8,"1,098","東星 vs 夜浪
|
||||
《APOPHÄNIE》",FTR 10,10.6,"1,299",N/A,,,,Conflict,177,4.2.0,23/1/26,N/A,,✓
|
||||
CYCLES,"Masayoshi
|
||||
Minoshima feat.
|
||||
綾倉盟",maimai 2,Nitro,PST 2,2.0,389,N-Helix,PRS 5,5.0,430,N-Helix,FTR 8+,8.8,695,N/A,,,,Light,135,4.3.0,23/3/2,N/A,,
|
||||
MAXRAGE,EBIMAYO,maimai 2,EXSCHWASION,PST 3,3.5,696,EXSCHWASION,PRS 6,6.5,760,EXSCHWASION,FTR 9+,9.9,"1,184",N/A,,,,Conflict,222,4.3.0,23/3/2,N/A,,
|
||||
[X],Blacklolita,maimai 2,東星,PST 4,4.5,594,東星,PRS 7+,7.8,782,東星,FTR 10,10.4,"1,190",N/A,,,,Conflict,162-180,4.3.0,23/3/2,N/A,,
|
||||
TEmPTaTiON,かねこちはる,maimai 2,EXtINcTiON,PST 5,5.0,627,EXtINcTiON,PRS 8,8.2,768,EXtINcTiON,FTR 10+,10.9,"1,099",N/A,,,,Light,160,4.3.0,23/3/2,N/A,,
|
||||
"Let's Rock
|
||||
(Arcaea mix)","ikaruga_nex
|
||||
vs. FALCHiON",Extend Archive 2: Chronicles,Luxance,PST 3,3.0,541,Luxance,PRS 7,7.0,963,Luxance,FTR 9+,9.7,"1,177",N/A,,,,Conflict,210,4.3.0,23/3/2,N/A,,
|
||||
Crimson Throne,Dimier√Lisb,Memory Archive: Partner,Toaster,PST 4,4.0,727,Toaster,PRS 8,8.0,"1,079",Toaster,FTR 10,10.4,"1,313",N/A,,,,Conflict,210,4.3.0,23/3/2,N/A,,✓
|
||||
"Hiiro Gekka,
|
||||
Kyoushou no Zetsu (nayuta 2017 ver.)","nayuta × 黒鳥
|
||||
(EastNewSound)",Memory Archive: Pop/Recommended,絶滅 Exschwasion 絶滅 Exschwasion,PST 3,3.5,719,絶滅 Exschwasion 絶滅 Exschwasion,PRS 6,6.5,709,絶滅 Exschwasion 絶滅 Exschwasion,FTR 10,10.3,"1,126",N/A,,,,Conflict,150,4.3.0,23/3/2,N/A,,
|
||||
Manic Jeer,ルゼ,Memory Archive: Original,NITR<O>,PST 4,4.0,698,NITR<O>,PRS 7+,7.8,875,NITR<O>,FTR 10,10.6,"1,286",N/A,,,,Conflict,195,4.3.0,23/3/2,N/A,,✓
|
||||
PRIMITIVE LIGHTS,TAG,Memory Archive: Original,東星※原始の灯,PST 5,5.5,785,東星※原始の灯,PRS 8+,8.8,"1,073",東星※原始の灯,FTR 10+,10.7,"1,524",N/A,,,,Light,205,4.3.2,23/3/9,N/A,,✓
|
||||
Cosmo Pop Funclub,ナユタン星人,CHUNITHM 3,Nitro NEW!!,PST 2,2.5,352,Nitro NEW!!,PRS 6,6.0,591,Nitro NEW!!,FTR 8+,8.8,809,N/A,,,,Light,129,4.4.0,23/3/23,N/A,,
|
||||
IMPACT,"USAO feat.
|
||||
光吉猛修",CHUNITHM 3,ÉCOLOGIE IMPACT,PST 3,3.5,723,ÉN IMPACT,PRS 7+,7.8,913,én feat. écologie,FTR 9,9.6,"1,231",Toaster NEW!!,BYD 10,10.4,"1,392",Light,210,4.4.0,23/3/23,4.4.0,23/3/23,
|
||||
Genesis,Morrigan feat. Lily,CHUNITHM 3,Exschwasion,PST 4,4.0,587,Exschwasion,PRS 7,7.0,838,Exschwasion,FTR 9+,9.9,867,N/A,,,,Conflict,150,4.4.0,23/3/23,N/A,,
|
||||
Trrricksters!!,"s-don vs.
|
||||
翡乃イスカ",CHUNITHM 3,絶滅,PST 4,4.5,561,絶滅,PRS 7,7.5,784,絶滅,FTR 10,10.1,"1,183",N/A,,,,Conflict,155,4.4.0,23/3/23,N/A,,
|
||||
Spider's Thread,"きくお ×
|
||||
cosMo@暴走P
|
||||
feat. 影縫英",CHUNITHM 3,夜浪 <->,PST 4,4.5,794,夜浪 <->,PRS 7+,7.8,764,夜浪 <->,FTR 10+,10.8,"1,203",N/A,,,,Conflict,180,4.4.0,23/3/23,N/A,,
|
||||
0xe0e1ccull,f→n,Black Fate,N/A,,,,N/A,,,,"《WARNING》
|
||||
Arcaea Charting Team vs -chromaesthesia-",FTR ?,0.0,"1,530",N/A,,,,Conflict,198-216,4.4.2,23/4/1,N/A,,✓
|
||||
GIMMICK,Ms.Sill,Extend Archive 2: Chronicles,Nitro,PST 2,2.5,421,Nitro,PRS 6,6.5,598,antymis + Nitro,FTR 9,9.5,733,N/A,,,,Conflict,143,4.4.4,23/4/27,N/A,,
|
||||
"Lost Emotion
|
||||
feat. nomico",Masayoshi Minoshima(ALR),Extend Archive 2: Chronicles,"ポーカーフェイスの
|
||||
Toaster",PST 3,3.5,602,"ポーカーフェイスの
|
||||
Toaster",PRS 7,7.0,780,"ポーカーフェイスの
|
||||
Toaster",FTR 9,9.3,"1,123",N/A,,,,Light,172,4.4.4,23/4/27,N/A,,
|
||||
"New York
|
||||
Back Raise",saaa + kei_iwata + stuv + わかどり,Memory Archive: Variety,"Exschwasion
|
||||
「CHECK」",PST 4,4.5,762,"Exschwasion
|
||||
「RAISE」",PRS 7,7.0,803,"Exschwasion
|
||||
「ALL IN」",FTR 9+,9.9,"1,091",N/A,,,,Conflict,160,4.4.4,23/4/27,N/A,,
|
||||
"The Survivor
|
||||
(Game Edit)",Taishi,Memory Archive: Variety,Nitro,PST 3,3.5,817,Nitro,PRS 6,6.5,750,Nitro,FTR 9+,9.9,"1,100",N/A,,,,Conflict,132,4.4.4,23/4/27,N/A,,
|
||||
Lawless Point,La prière,Extend Archive 2: Chronicles,Luxance,PST 3,3.0,476,Luxance,PRS 6,6.0,630,Luxance,FTR 9,9.0,838,N/A,,,,Conflict,148,4.4.6,23/5/25,N/A,,
|
||||
Hybris (The one who shattered),"qfeileadh
|
||||
feat. のあ",Extend Archive 2: Chronicles,Exschwasion,PST 4,4.5,757,Exschwasion,PRS 7+,7.8,973,Exschwasion,FTR 9+,9.8,"1,196",N/A,,,,Conflict,158,4.4.6,23/5/25,N/A,,
|
||||
Galactic Love,La prière,Memory Archive: Pop/Recommended,én,PST 3,3.0,513,én,PRS 6,6.5,694,én,FTR 9,9.0,813,N/A,,,,Light,145,4.4.6,23/5/25,N/A,,
|
||||
Lost in the Abyss,FELT,Memory Archive: Pop/Recommended,Nitro,PST 3,3.5,907,Nitro,PRS 6,6.5,908,Nitro,FTR 9+,9.7,"1,179",N/A,,,,Conflict,183,4.4.6,23/5/25,N/A,,
|
||||
To the Milky Way,黒魔,Memory Archive: Partner,Nitroだー!,PST 5,5.0,928,Nitroだー!,PRS 8+,8.9,"1,154",Nitroだー!,FTR 10,10.5,"1,392",N/A,,,,Light,186,4.4.6,23/5/25,N/A,,✓
|
||||
Bullet Waiting for Me (James Landino remix),Nikki Simmons,Cytus II,CERiNG,PST 2,2.5,325,CERiNG,PRS 4,4.5,390,CERiNG,FTR 8,8.1,701,N/A,,,,Light,107,4.5.0,23/6/28,N/A,,
|
||||
Used to be,KIVΛ,Cytus II,Luxance,PST 4,4.0,537,Luxance,PRS 6,6.5,675,Luxance + Nitro,FTR 9,9.2,799,N/A,,,,Light,140,4.5.0,23/6/28,N/A,,
|
||||
Devillic Sphere,3R2,Cytus II,₸öα$†ε₹,PST 4,4.0,490,₸öα$†ε₹,PRS 7+,7.8,692,₸öα$†ε₹,FTR 9+,9.9,"1,129",N/A,,,,Conflict,160,4.5.0,23/6/28,N/A,,
|
||||
Lucid Traveler,"Akira Complex
|
||||
vs. 3R2",Cytus II,Toaster vs ₸öα$†ε₹,PST 4,4.5,634,Toaster vs ₸öα$†ε₹,PRS 8+,8.9,"1,006",Toaster vs ₸öα$†ε₹,FTR 10,10.4,"1,341",N/A,,,,Conflict,170-200,4.5.0,23/6/28,N/A,,✓
|
||||
CHAOS,Æsir,Cytus II,絶滅,PST 5,5.5,646,絶滅,PRS 7,7.5,848,絶滅,FTR 10+,10.9,"1,369",N/A,,,,Conflict,150,4.5.0,23/6/28,N/A,,
|
||||
INTERNET YAMERO,"Aiobahn
|
||||
feat. KOTOKO",Memory Archive: Pop/Recommended,該当チャンネルが停止されたため、 この譜面は再生できません。,PST 4,4.5,677,該当チャンネルが停止されたため、 この譜面は再生できません。,PRS 7+,7.8,987,該当チャンネルが停止されたため、 この譜面は再生できません。,FTR 9+,9.9,"1,222",N/A,,,,Conflict,185,4.5.0,23/6/28,N/A,,
|
||||
syūten,"Apo11o ""COLLAPSAR"" program feat.
|
||||
大瀬良あい",Cytus II 2,antymīs,PST 2,2.0,395,antymīs,PRS 5,5.0,446,antymīs,FTR 8,8.5,592,N/A,,,,Light,76-96,4.6.0,23/7/19,N/A,,
|
||||
DRG,onoken,Cytus II 2,_NITRO,PST 3,3.5,380,_HARD,PRS 7,7.0,624,_CHAOS,FTR 9,9.5,872,N/A,,,,Light,155,4.6.0,23/7/19,N/A,,
|
||||
99 Glooms,Sta,Cytus II 2,終点,PST 4,4.0,637,終点,PRS 7+,7.8,774,終点,FTR 10,10.3,"1,294",N/A,,,,Conflict,185,4.6.0,23/7/19,N/A,,
|
||||
͟͝͞Ⅱ́̕,Cytus,Cytus II 2," Corrupted data Recovery progress
|
||||
......100%",PST 5,5.0,690,"Main_Log_
|
||||
702_10_25",PRS 8+,8.9,816,"Cam_Library_
|
||||
702_12_29",FTR 10+,10.8,"1,051",N/A,,,,Conflict,130-150,4.6.0,23/7/19,N/A,,
|
||||
Magnolia,"M2U
|
||||
Vocal by Guriri",Cytus II 2,Lacrimosa,PST 4,4.5,625,Lacrimosa,PRS 7+,7.8,726,Lacrimosa,FTR 10,10.2,895,N/A,,,,Light,160,4.6.0,23/7/19,N/A,,
|
||||
Ultimate taste,ぱらどっと,Extend Archive 2: Chronicles,"Arcaea
|
||||
Charting Team",PST 3,3.5,828,"Arcaea
|
||||
Charting Team",PRS 6,6.5,"1,008",Arcaea Charting Team 【Full Flavor】,FTR 9+,9.7,"1,405",N/A,,,,Light,200,4.6.0,23/7/19,N/A,,
|
||||
WAIT FOR DAWN,"U-ske feat.
|
||||
棗いつき",Lasting Eden,én,PST 2,2.5,596,én,PRS 7+,7.8,636,én,FTR 8+,8.7,861,N/A,,,,Light,188,4.7.0,23/8/18,N/A,,✓
|
||||
Raven's Pride,"みーに feat.
|
||||
はらもりよしな",Lasting Eden,Exschwasion,PST 3,3.0,697,Exschwasion,PRS 7,7.0,797,Exschwasion,FTR 9,9.4,"1,030",N/A,,,,Conflict,165,4.7.0,23/8/18,N/A,,✓
|
||||
Rise of the World,cosMo@暴走P,Lasting Eden,N⇑TRO,PST 4,4.5,722,N⇑TRO,PRS 8,8.1,843,N⇑TRO,FTR 10,10.4,"1,176",N/A,,,,Light,182-212,4.7.0,23/8/18,N/A,,✓
|
||||
UNKNOWN LEVELS,Yuta Imai,Lasting Eden,Toaster,PST 4,4.0,591,Toaster,PRS 8,8.1,771,⇓ 東星 vs Toaster ⇓,FTR 10,10.6,"1,149",N/A,,,,Conflict,110-165,4.7.0,23/8/18,N/A,,✓
|
||||
Abstruse Dilemma,"Ashrount vs.
|
||||
打打だいず",Lasting Eden,Remnant ⇐ Guilt,PST 5,5.5,983,Remnant ⇒ Doubt,PRS 8+,8.9,"1,127","Remnant ⇑
|
||||
⇓ Volition",FTR 11,11.1,"1,467",N/A,,,,Light,216,4.7.0,23/8/18,N/A,,✓
|
||||
RGB,MEMODEMO × AQUASINE,Extend Archive 2: Chronicles,NO₂,PST 4,4.0,652,NO₂,PRS 7+,7.8,803,NO₂,FTR 9+,9.7,"1,131",N/A,,,,Light,163,4.7.0,23/8/18,N/A,,✓
|
||||
"SACRIFICE
|
||||
feat. ayame",Masayoshi Minoshima(ALR),Memory Archive: Pop/Recommended,Luxance,PST 3,3.5,548,Luxance,PRS 7,7.5,779,Luxance,FTR 9+,9.7,958,N/A,,,,Conflict,180,4.7.0,23/8/18,N/A,,
|
||||
Kanjou no Matenrou ~Arr.Demetori,Demetori,Extend Archive 2: Chronicles,Exschwasion,PST 3,3.5,736,Exschwasion,PRS 6,6.5,929,N•Ex•T,FTR 9+,9.8,"1,294",N/A,,,,Conflict,178,4.7.2,23/9/14,N/A,,
|
||||
"To the
|
||||
Furthest Dream","ii/night
|
||||
feat. 綺良雪",Memory Archive: Original,,PST 4,4.5,836,,PRS 8,8.5,994,,FTR 9+,9.8,"1,102",N/A,,,,Silent,183,4.7.2,23/9/14,N/A,,✓
|
||||
Primeval Texture,くるぶっこちゃん,Severed Eden,CERiNG,PST 3,3.0,387,CERiNG,PRS 7,7.5,525,CERiNG,FTR 9,9.0,810,N/A,,,,Light,120,5.0.0,23/9/27,N/A,,✓
|
||||
Technicolour,Maozon,Severed Eden,KLMNOP,PST 3,3.5,644,KLMNOP,PRS 7,7.0,812,KLMNOP,FTR 9+,9.8,"1,140",N/A,,,,Light,175,5.0.0,23/9/27,N/A,,✓
|
||||
Ego Eimi,"BlackY feat.
|
||||
Risa Yuzuki",Severed Eden,東星,PST 5,5.5,801,東星,PRS 8,8.6,937,東星,FTR 10,10.5,"1,223",N/A,,,,Conflict,178,5.0.0,23/9/27,N/A,,✓
|
||||
Logos,"polysha
|
||||
feat. 高城みよ",Severed Eden,絶滅,PST 4,4.0,697,絶滅,PRS 7+,7.8,798,絶滅,FTR 10,10.1,"1,040",N/A,,,,Conflict,189,5.0.0,23/9/27,N/A,,✓
|
||||
Arghena,"Feryquitous
|
||||
vs. Laur",Severed Eden,"第一識 ""Reality""",PST 7,7.5,883,"第二識 ""Causality""",PRS 9,9.4,"1,082","第三識 ""Pluriversality""",FTR 11,11.3,"1,444",N/A,,,,Conflict,185,5.0.0,23/9/27,N/A,,✓
|
||||
Remind the Souls (Short Version),Nhato,Arcaea,Nitro,PST 3,3.5,561,Nitro,PRS 7,7.0,756,Nitro,FTR 9,9.5,945,N/A,,,,Light,130,5.0.0,23/9/27,N/A,,
|
||||
Dynitikós,Prower,Extend Archive 2: Chronicles,Exschwasión,PST 4,4.0,683,Exschwasión,PRS 7,7.5,894,Exschwasión,FTR 9,9.5,986,N/A,,,,Conflict,180,5.0.0,23/9/27,N/A,,✓
|
||||
Amekagura,荒谷サトル,Extend Archive 2: Chronicles,antymis,PST 4,4.0,741,antymis,PRS 7,7.5,851,antymis,FTR 9+,9.9,"1,076",N/A,,,,Light,105,5.0.0,23/9/27,N/A,,✓
|
||||
B.B.K.K.B.K.K.,nora2r,Memory Archive: Variety,E.E.X.X.E.X.X.,PST 4,4.5,669,E.E.X.X.E.X.X.,PRS 7,7.0,708,E.E.X.X.E.X.X.,FTR 9+,9.7,976,N/A,,,,Conflict,170,5.0.0,23/9/27,N/A,,
|
||||
Transient Space,"sleepless,
|
||||
Gardens, aspect",Shifting Veil,CERiNG -liminal-,PST 2,2.5,419,CERiNG -liminal-,PRS 7,7.0,607,CERiNG -liminal-,FTR 9,9.5,805,N/A,,,,Conflict,115-132,5.1.0,23/10/26,N/A,,✓
|
||||
Nameless Passion,天束 feat. Sennzai,Shifting Veil,Luxance,PST 3,3.0,681,Luxance,PRS 7,7.0,890,Luxance,FTR 9+,9.9,"1,223",N/A,,,,Conflict,200,5.1.0,23/10/26,N/A,,✓
|
||||
TeraVolt,Katali,Shifting Veil,夜浪,PST 5,5.0,675,夜浪,PRS 8+,8.9,804,超東星 × 雷夜浪,FTR 10+,10.9,"1,008",N/A,,,,Conflict,154,5.1.0,23/10/26,N/A,,✓
|
||||
FANTA5Y,Moon Jelly & YUKIYANAGI,Extend Archive 2: Chronicles,TOA5TIE,PST 3,3.0,536,TOA5TIE,PRS 7,7.0,715,TOA5TIE,FTR 9,9.4,965,N/A,,,,Light,170,5.1.0,23/10/26,N/A,,✓
|
||||
Stratoliner,C-Show,WACCA 2,Exschwasion,PST 3,3.5,535,Exschwasion,PRS 6,6.5,702,Exschwasion,FTR 9,9.6,877,N/A,,,,Conflict,175,5.2.0,23/11/30,N/A,,
|
||||
Ouvertüre,"USAO & DJ Genki
|
||||
feat. ルーン
|
||||
(CV: 河瀬茉希)",WACCA 2,るくあんす,PST 2,2.5,583,るくあんす,PRS 7,7.5,786,るくあんす,FTR 9+,9.8,913,N/A,,,,Conflict,200,5.2.0,23/11/30,N/A,,
|
||||
eden,"""漆黒"" の堕天使
|
||||
《Gram》 †Versus† ""聖刻""
|
||||
の熾天使 《Gram》",WACCA 2,反水,PST 4,4.5,826,反水,PRS 8,8.2,"1,194",反水,FTR 10,10.5,"1,365",N/A,,,,Conflict,246,5.2.0,23/11/30,N/A,,
|
||||
XTREME,USAO,WACCA 2,絶滅,PST 4,4.5,752,絶滅,PRS 7+,7.8,831,絶滅,FTR 10,10.5,"1,258",N/A,,,,Conflict,205,5.2.0,23/11/30,N/A,,
|
||||
Meta-Mysteria,DJ Noriken,WACCA 2,夜浪,PST 5,5.0,844,夜浪,PRS 7+,7.8,905,VII: THE CHARIOT/夜浪,FTR 10+,10.8,"1,309",N/A,,,,Light,205,5.2.0,23/11/30,N/A,,
|
||||
Alone & Lorn,"Ponchi♪
|
||||
feat. はぁち",Extend Archive 2: Chronicles,én,PST 3,3.0,643,én,PRS 6,6.5,742,én & KLMNOP,FTR 9,9.6,970,N/A,,,,Light,100,5.2.0,23/11/30,N/A,,✓
|
||||
Wish Upon a Snow,打打だいず,Memory Archive: Original,0°絶滅,PST 4,4.5,"1,031",0°絶滅,PRS 7,7.5,"1,095",0°絶滅,FTR 10,10.5,"1,309",N/A,,,,Light,218,5.2.0,23/11/30,N/A,,✓
|
||||
felys final remix,onoken,Extend Archive 2: Chronicles,Dec18,PST 3,3.0,626,Dec18,PRS 6,6.5,771,Dec18,FTR 9,9.5,"1,130",N/A,,,,Conflict,180,5.2.2,23/12/21,N/A,,
|
||||
"On And On!!
|
||||
feat. Jenga",ETIA.,Extend Archive 2: Chronicles,én and én!!,PST 3,3.0,370,én and én!!,PRS 7,7.0,616,én and én!!,FTR 9,9.5,836,N/A,,,,Light,170,5.2.2,23/12/21,N/A,,
|
||||
LIVHT MY WΔY,かめりあ feat. STΔRLIVHT,Memory Archive: Music Game,"k//eternal + nitro ""ephemeral past""",PST 4,4.5,673,"k//eternal + nitro ""recursive present""",PRS 7,7.5,738,"k//eternal + nitro ""convergent future""",FTR 9+,9.8,954,N/A,,,,Conflict,190,5.2.2,23/12/21,N/A,,
|
||||
Kanbu de Tomatte Sugu Tokeru,ARM + 夕野ヨシミ (IOSYS) feat. miko,Memory Archive: Pop/Recommended,C7H11NO配合!!!!!!,PST 4,4.0,584,C7H11NO配合!!!!!!,PRS 7,7.5,714,C7H11NO配合!!!!!!,FTR 10,10.0,"1,108",N/A,,,,Light,200,5.2.2,23/12/21,N/A,,
|
||||
Hotarubi no Yuki,Endorfin.,Sunset Radiance,0°Nitro,PST 3,3.5,589,0°Nitro,PRS 7,7.0,733,0°Nitro,FTR 9+,9.7,991,N/A,,,,Light,159,5.2.6,24/1/12,N/A,,✓
|
||||
Vicious [ANTi] Heroism,Kobaryo,Absolute Reason,N/A,,,,N/A,,,,N/A,,,,"[FUTiLE]
|
||||
Defiance",BYD 11,11.1,"1,772",Conflict,271,N/A,,5.3.0,24/1/25,✓
|
||||
The Formula,Junk,Arcaea,Dec18,PST 3,3.0,427,Dec18,PRS 6,6.0,587,Dec18,FTR 9,9.3,957,N/A,,,,Light,144,5.3.0,24/1/25,N/A,,
|
||||
Luna Rossa,r0y,Memory Archive: Music Game,Luxance,PST 3,3.0,443,Luxance,PRS 6,6.0,578,Luxance,FTR 9+,9.7,920,N/A,,,,Conflict,174,5.3.0,24/1/25,N/A,,
|
||||
Jingle,DJ Noriken,Arcaea,Exschwasion,PST 2,2.5,530,Exschwasion,PRS 5,5.5,741,Exschwasion,FTR 7+,7.8,848,KLMNOP,ETR 9,9.5,"1,047",Light,170,5.4.0,24/3/8,5.4.0,24/3/8,
|
||||
Aleph-0,LeaF,Extend Archive 2: Chronicles,ə₀,PST 5,5.5,388,ə₀,PRS 8+,8.8,579,ə₀,FTR 10,10.5,919,N/A,,,,Conflict,35-400,5.4.0,24/3/8,N/A,,
|
||||
Innocence,"Powerless
|
||||
feat. Sennzai",Memory Archive: Original,First Dawn,PST 3,3.0,734,First Dawn,PRS 6,6.5,811,First Dawn,FTR 8,8.5,"1,023",First Dawn,ETR 9+,9.7,"1,157",Light,190,5.4.0,24/3/8,5.4.0,24/3/8,✓
|
||||
IONOSTREAM,Tatsh,Memory Archive: Music Game,Nitro,PST 3,3.5,845,Nitro,PRS 6,6.0,890,Dec18 + Nitro,FTR 8+,8.7,818,Dec18 + Nitro,ETR 9+,9.7,871,Conflict,220-254,5.4.0,24/3/8,5.4.0,24/3/8,
|
||||
"Masquerade
|
||||
Legion","Srav3R &
|
||||
DJ Noriken",Memory Archive: Original,"Nitro
|
||||
「The Veiled」",PST 3,3.5,510,"Nitro
|
||||
「The Veiled」",PRS 6,6.5,698,"Nitro
|
||||
「The Veiled」",FTR 10,10.0,"1,064",N/A,,,,Conflict,175,5.4.0,24/3/8,N/A,,✓
|
||||
Qovat,owl*tree,Memory Archive: Original,ex*tree,PST 4,4.5,519,ex*tree,PRS 8,8.2,765,ny*tree,FTR 10,10.6,"1,299",N/A,,,,Conflict,122,5.4.0,24/3/8,N/A,,✓
|
||||
KYOREN ROMANCE,"REDALiCE vs.
|
||||
DJ Myosuke feat.
|
||||
DELUTAYA",Memory Archive: Partner,Dec18 + Nitro,PST 4,4.0,821,Dec18 + Nitro,PRS 7+,7.8,982,Dec18 + Nitro,FTR 10+,10.7,"1,519",N/A,,,,Conflict,205,5.4.0,24/3/8,N/A,,✓
|
||||
HELLOHELL,暁Records,World Extend 3: Illusions,én,PST 2,2.5,466,én,PRS 5,5.0,445,én,FTR 7,7.5,673,eién,ETR 9,9.4,770,Conflict,155,5.5.0,24/3/25,5.5.0,24/3/25,
|
||||
MORNINGLOOM,saaa,World Extend 3: Illusions,Exschwasion • 8:00,PST 3,3.0,710,Exschwasion • 8:21,PRS 6,6.5,829,Exschwasion • 8:45,FTR 8+,8.8,940,Exschwasion • 8:46,ETR 9+,9.8,"1,035",Light,102,5.5.0,24/3/25,5.5.0,24/3/25,
|
||||
〇、,Kolaa & 熊子,World Extend 3: Illusions,CERiNG、,PST 2,2.5,368,CERiNG、,PRS 6,6.5,519,CERiNG、,FTR 9,9.5,708,N/A,,,,Light,145,5.5.0,24/3/25,N/A,,
|
||||
Awaken In Ruins,Supa7onyz,World Extend 3: Illusions,antymis,PST 3,3.5,412,antymis,PRS 7,7.5,570,antymis,FTR 9+,9.9,754,N/A,,,,Conflict,125,5.5.0,24/3/25,N/A,,
|
||||
Lethal Voltage,siqlo,World Extend 3: Illusions,moonquay [EMP],PST 4,4.5,724,moonquay [FLASH],PRS 7+,7.8,922,moonquay [SHOCK],FTR 10,10.4,"1,497",N/A,,,,Conflict,190,5.5.0,24/3/25,N/A,,✓
|
||||
MIRINAE,TAK × Zekk,Memory Archive: Original,N↑TRO,PST 4,4.5,646,N↑TRO,PRS 8,8.3,881,N↑TRO,FTR 10,10.5,"1,277",N/A,,,,Light,180,5.5.0,24/3/25,N/A,,✓
|
||||
HIVEMIND INTERLINKED,かたぎり,Extend Archive 1: Visions,N/A,,,,N/A,,,,"《WARNING》
|
||||
Arcaea Cognition Team -assimilated-",FTR ?,0.0,"1,445",N/A,,,,Conflict,252,5.5.6,24/4/1,N/A,,✓
|
||||
ultradiaxon-N3,nitro (lowiro),Memory Archive: Partner,Nitro,PST 4,4.5,605,Nitro,PRS 8,8.5,896,Nitro,FTR 10,10.5,"1,228",N/A,,,,Conflict,150,5.5.6,24/4/1,N/A,,✓
|
||||
Leave All Behind,rider,World Extend 3: Illusions,Luxance,PST 2,2.0,380,Luxance,PRS 5,5.5,488,Luxance,FTR 9,9.2,828,N/A,,,,Conflict,150,5.6.0,24/4/26,N/A,,
|
||||
Distorted Fate,Sakuzyo,Memory Archive: Music Game,Toaster,PST 4,4.5,756,Toaster,PRS 7+,7.8,890,Toaster,FTR 9,9.6,"1,172","TOASTER
|
||||
DATA PATCHER",ETR 10+,10.9,"1,402",Conflict,150,5.6.0,24/4/26,5.6.0,24/4/26,
|
||||
Floating World,baker feat. botan,Memory Archive: Partner,én,PST 3,3.0,753,én,PRS 7,7.0,793,én,FTR 9,9.3,"1,047",N/A,,,,Light,174,5.6.0,24/4/26,N/A,,✓
|
||||
Désive,MisomyL,Memory Archive: Partner,Yearning Call,PST 5,5.0,"1,007",Yearning Call,PRS 8,8.0,"1,051",Yearning Call,FTR 9+,9.9,"1,273",Yearning Call,ETR 10+,10.8,"1,340",Light,180-230,5.6.0,24/4/26,5.6.0,24/4/26,✓
|
||||
Chromafill,ていぬ,Memory Archive: Partner,"exschwasion
|
||||
-彩色-",PST 4,4.0,757,"exschwasion
|
||||
-彩色-",PRS 7,7.0,890,"exschwasion
|
||||
-彩色-",FTR 10,10.0,"1,130",N/A,,,,Light,179,5.6.0,24/4/26,N/A,,✓
|
||||
Hidden Rainbows of Epicurus,"SYNC.ART'S
|
||||
feat. Misato",Arcaea,Dec18,PST 2,2.5,595,Dec18,PRS 5,5.5,644,Dec18,FTR 7,7.5,783,Dec18,ETR 8+,8.8,884,Light,155,5.7.0,24/5/30,5.7.0,24/5/30,
|
||||
Old School Salvage,DJ SHARPNEL,World Extend 3: Illusions,antymis,PST 4,4.0,705,antymis,PRS 7+,7.8,950,antymis + Nitro,FTR 9+,9.8,"1,316",N/A,,,,Conflict,205,5.7.0,24/5/30,N/A,,✓
|
||||
Twilight Concerto,Scarlette,Memory Archive: Music Game,Exschwasion,PST 4,4.5,584,Exschwasion,PRS 7+,7.8,634,Exschwasion,FTR 9,9.5,803,Exschwasion,ETR 10,10.4,962,Conflict,194,5.7.0,24/5/30,5.7.0,24/5/30,
|
||||
Beautiful Dreamer,M-Project,Memory Archive: Original,CERiNG,PST 4,4.0,611,CERiNG,PRS 7+,7.8,773,CERiNG,FTR 9+,9.9,"1,139",N/A,,,,Light,188,5.7.0,24/5/30,N/A,,✓
|
||||
Back to Basics,m1dy,Memory Archive: Original,夜浪 THE FUMEn ANARCHIST,PST 5,5.0,717,夜浪 THE FUMEn ANARCHIST,PRS 8+,8.7,"1,115",夜浪 THE FUMEn ANARCHIST,FTR 10,10.5,"1,544",N/A,,,,Conflict,420,5.7.0,24/5/30,N/A,,✓
|
||||
"Sign of ""10.5km""",渡部恭久,Groove Coaster 2,Dec18,PST 3,3.0,490,Dec18,PRS 6,6.5,564,Dec18,FTR 9,9.2,735,N/A,,,,Light,160,5.8.0,24/6/27,N/A,,
|
||||
10pt8ion,Lite Show Magic,Groove Coaster 2,Nitro,PST 4,4.0,475,Nitro,PRS 7+,7.8,704,Nite Schwa Power,FTR 9+,9.7,906,Nite Schwa Power,ETR 10,10.4,"1,087",Conflict,128-185,5.8.0,24/6/27,5.8.0,24/6/27,
|
||||
Black MInD,COSIO,Groove Coaster 2,聖輪,PST 5,5.0,601,聖輪,PRS 8,8.0,754,聖輪,FTR 10+,10.8,"1,274",N/A,,,,Conflict,192,5.8.0,24/6/27,N/A,,
|
||||
STARGATE EXTREME,KARUT,Memory Archive: Music Game,én,PST 4,4.0,337,én,PRS 6,6.0,430,én,FTR 9,9.3,724,eién,ETR 10,10.0,915,Conflict,150,5.8.0,24/6/27,5.8.0,24/6/27,
|
||||
HYPER VISION,VOLTA,Memory Archive: Partner,NITRO,PST 4,4.5,639,NITRO,PRS 7,7.5,839,NITRO,FTR 9+,9.8,"1,040",N/A,,,,Conflict,155,5.8.0,24/6/27,N/A,,✓
|
||||
Hypnotize,rejection,Absolute Nihil,én,PST 3,3.5,518,én,PRS 6,7.0,761,én,FTR 8+,8.9,993,"én × nitro
|
||||
「The Radical」",ETR 9+,9.9,"1,164",Conflict,160,5.9.0,24/7/30,5.9.0,24/7/30,✓
|
||||
In Vain,ryhki,Absolute Nihil,CERiNG,PST 3,3.5,562,CERiNG,PRS 6,6.5,677,CERiNG,FTR 9,9.5,"1,111",N/A,,,,Conflict,165,5.9.0,24/7/30,N/A,,✓
|
||||
Ashen 6oundary,YUKIYANAGI,Absolute Nihil,[NITRO],PST 4,4.5,702,[NITRO],PRS 7+,7.8,813,[NITRO],FTR 9+,9.9,"1,183",N/A,,,,Conflict,172,5.9.0,24/7/30,N/A,,✓
|
||||
Judgement,Tatsunoshin,Absolute Nihil,絶滅 » collapse,PST 5,5.5,844,絶滅 » collapse,PRS 8,8.6,"1,055",絶滅 » collapse,FTR 10,10.4,"1,432",N/A,,,,Conflict,200,5.9.0,24/7/30,N/A,,✓
|
||||
ALTER EGO,"Yuta Imai
|
||||
vs. Qlarabelle",Absolute Nihil,"Article V
|
||||
《Observation》",PST 6,6.5,865,"Article VI
|
||||
《Hypothesis》",PRS 9,9.2,"1,213","Article VII
|
||||
《Analysis》",FTR 10,10.5,"1,466","Article 0x8
|
||||
《Enmity》",ETR 11,11.2,"1,644",Conflict,195,5.9.0,24/7/30,5.9.0,24/7/30,✓
|
||||
Distortion Human,DJ Myosuke & KAJI,World Extend 3: Illusions,"ディストーション・
|
||||
ルクアンス",PST 3,3.0,544,"ディストーション・
|
||||
ルクアンス",PRS 6,6.5,841,"ディストーション・
|
||||
ルクアンス",FTR 9+,9.8,"1,317",N/A,,,,Conflict,200,5.9.0,24/7/30,N/A,,
|
||||
shrink,"Shohei Tsuchiya
|
||||
(ZUNTATA)",Memory Archive: Music Game,Dec18,PST 3,3.5,451,Dec18,PRS 7,7.0,660,Dec18,FTR 9+,9.8,929,N/A,,,,Light,180,5.9.0,24/7/30,N/A,,
|
||||
Dual Doom Deathmatch,Kobaryo vs. HyuN,Rotaeno,NITRO,PST 3,3.5,838,NITRO,PRS 6,6.5,830,NITRO,FTR 8+,8.9,"1,094",NITRO,ETR 10,10.3,"1,292",Conflict,222,5.10.0,24/8/29,5.10.0,24/8/29,
|
||||
Waltz for Lorelei,Sobrem & 庭師,Rotaeno,antymis,PST 2,2.5,664,antymis,PRS 5,5.5,814,antymis,FTR 8+,8.8,916,antymis,ETR 9+,9.8,999,Light,220,5.10.0,24/8/29,5.10.0,24/8/29,
|
||||
Inverted World,ARForest,Rotaeno,↑én↓,PST 3,3.0,525,↑én↓,PRS 7,7.0,646,↑én↓,FTR 9,9.5,940,聖輪↓↑夜浪,ETR 10+,10.7,"1,065",Light,180,5.10.0,24/8/29,5.10.0,24/8/29,
|
||||
MVURBD,ETIA.,Rotaeno,絶滅,PST 4,4.5,999,絶滅,PRS 7+,7.8,"1,031",絶滅,FTR 10,10.6,"1,497",N/A,,,,Conflict,175,5.10.0,24/8/29,N/A,,
|
||||
Vulcānus,"Team Grimoire
|
||||
vs. Aoi",Rotaeno,Volution,PST 5,5.5,968,Volution CCCLX,PRS 8,8.4,"1,234",Volution IV,FTR 10+,10.9,"1,542",N/A,,,,Light,212,5.10.0,24/8/29,N/A,,✓
|
||||
epitaxy,Camellia,World Extend 3: Illusions,Dec18,PST 3,3.0,826,Dec18,PRS 6,6.0,939,Dec18,FTR 8,8.6,"1,177",Dec18,ETR 9,9.6,"1,410",Light,183,5.10.0,24/8/29,5.10.0,24/8/29,
|
||||
"Rain of Conflict in a Radiant Abyss",ak+q,Memory Archive: Partner,"Nitro ""v20170309""",PST 5,5.0,831,"Nitro ""v20170309""",PRS 7+,7.8,934,"Nitro ""v20170309""",FTR 9,9.5,"1,174","Nitro meets Toaster ""v20170309""",ETR 10,10.5,"1,247",Conflict,195,5.10.2,24/9/12,5.10.2,24/9/12,✓
|
||||
Saint or Sinner,crayvxn,Adverse Prelude,小終点,PST 3,3.0,447,小終点,PRS 6,6.0,563,小終点,FTR 8+,8.8,906,N/A,,,,Conflict,164,5.10.4,24/9/26,N/A,,✓
|
||||
FURETE-MITAI,みきとP,World Extend 3: Illusions,nora::neko,PST 2,2.5,447,nora::neko,PRS 6,6.0,523,nora::neko,FTR 8,8.4,763,nora::neko,ETR 9,9.4,841,Light,155,5.10.4,24/9/26,5.10.4,24/9/26,
|
||||
Hailstone,Kazki Misora,World Extend 3: Illusions,raycast,PST 3,3.5,534,raycast,PRS 7,7.0,651,raycast,FTR 9+,9.7,"1,002",N/A,,,,Light,180,5.10.4,24/9/26,N/A,,
|
||||
Gensou no Satellite,豚乙女,Memory Archive: Pop/Recommended,Luxance,PST 2,2.5,721,Luxance,PRS 6,6.5,783,Luxance,FTR 8+,8.7,992,Luxance,ETR 10,10.1,"1,139",Conflict,230,5.10.4,24/9/26,5.10.4,24/9/26,
|
||||
Prayer,"qfeileadh & レゾナンスもえこ",World Extend 3: Illusions,nora::neko,PST 2,2.5,419,nora::neko,PRS 5,5.5,479,nora::neko,FTR 8,8.2,591,nora::neko,ETR 9,9.1,714,Light,132,5.10.6,24/10/24,5.10.6,24/10/24,
|
||||
Crimson Quartz,DiGiTAL WiNG with 空音,Memory Archive: Pop/Recommended,raycast,PST 3,3.0,569,raycast,PRS 6,6.0,615,raycast,FTR 8+,8.8,861,raycast,ETR 9+,9.8,"1,200",Conflict,145,5.10.6,24/10/24,5.10.6,24/10/24,
|
||||
Dies irae,お月さま交響曲,Memory Archive: Original,M理論,PST 4,4.5,632,M理論,PRS 7,7.5,802,M理論,FTR 9,9.5,"1,052",M理論,ETR 10,10.6,"1,263",Conflict,172,5.10.6,24/10/24,5.10.6,24/10/24,✓
|
||||
Third Sun,Ash Astral,Memory Archive: Music Game,NEO NITRO,PST 3,3.5,532,NEO NITRO,PRS 7,7.0,702,NEO NITRO,FTR 9,9.4,811,NEO NITRO,ETR 10,10.0,"1,043",Conflict,75-225,5.10.6,24/10/24,5.10.6,24/10/24,
|
||||
Spirit of the Dauntless,KO3 & Relect,Memory Archive: Original,絶滅,PST 4,4.5,693,絶滅,PRS 7+,7.8,957,絶滅,FTR 10,10.5,"1,207",N/A,,,,Conflict,180,5.10.6,24/10/24,N/A,,✓
|
|
|
@ -1,64 +0,0 @@
|
|||
Name,Difficulty,Artist,Shorthand
|
||||
Kanjou no Matenrou ~Arr.Demetori,,,matenrou
|
||||
nέo κósmo,,,neo kosmo
|
||||
Genesis,,Morrigan feat. Lily,genesischunithm
|
||||
The Survivor (Game Edit),,,thesurvivor
|
||||
Haze of Autumn,,,akinokagerou
|
||||
Bamboo,,,take
|
||||
10pt8ion,,,tempationgc
|
||||
HIVEMIND INTERLINKED,,,hivemindrmx
|
||||
Kanbu de Tomatte Sugu Tokeru,,,overdrive
|
||||
1F√,,,onefr
|
||||
[X],,,infinity
|
||||
0xe0e1ccull,,,ifirmx
|
||||
Last,,,last
|
||||
Last | Moment,,,last
|
||||
Last | Eternity,,,lasteternity
|
||||
Lost Emotion feat. nomico,,,lostemotion
|
||||
µ,,,mu
|
||||
I've heard it said,,,hearditsaid
|
||||
Quon,,DJ Noriken,quonwacca
|
||||
B.B.K.K.B.K.K.,,,bbkkbkk
|
||||
World Fragments III(radio edit),,,worldfragments
|
||||
#1f1e33,,,ifi
|
||||
On And On!! feat. Jenga,,,onandon
|
||||
Misdeed -la bonté de Dieu et l'origine du mal-,,,gou
|
||||
Hidden Rainbows of Epicurus,,,epicurus
|
||||
G e n g a o z o,,,gengaozo
|
||||
A Wandering Melody of Love,,,melodyoflove
|
||||
Let's Rock (Arcaea mix),,,letsrock
|
||||
LunarOrbit -believe in the Espebranch road-,,,espebranch
|
||||
Can I Friend You on Bassbook? Lol,,,bassline
|
||||
Sheriruth (Laur Remix),,,sheriruthrm
|
||||
ω4,,,omegafour
|
||||
〇、,,,ichirin
|
||||
Let you DIVE! (nitro rmx),,,letyoudivermx
|
||||
99 Glooms,,,nnglooms
|
||||
͟͝͞Ⅱ́̕,,,ii
|
||||
Redraw the Colorless World,,,mukinshitsu
|
||||
Ävril -Flicka i krans-,,,avril
|
||||
7thSense,,,seventhsense
|
||||
LIVHT MY WΔY,,,lightmyway
|
||||
False Embellishment,,,kyogenkigo
|
||||
Illegal Paradise,,,darakunosono
|
||||
cry of viyella,,,viyella
|
||||
"Good bye, Merry-Go-Round.",,,goodbyemerry
|
||||
ΟΔΥΣΣΕΙΑ,,,odysseia
|
||||
Mistempered Malignance,,,mismal
|
||||
Twilight Concerto,,,tasogare
|
||||
Heart,,,kokoro
|
||||
Dancin' on a Cat's Paw,,,nekonote
|
||||
Bookmaker (2D Version),,,bookmaker
|
||||
Dement ~after legend~,,,dement
|
||||
Einherjar Joker,,,einherjar
|
||||
GOODTEK (Arcaea Edit),,,goodtek
|
||||
Kanagawa Cyber Culvert,,,kanagawa
|
||||
La'qryma of the Wasteland,,,laqryma
|
||||
PRAGMATISM,,,pragmatism
|
||||
PRAGMATISM -RESURRECTION-,,,pragmatism
|
||||
qualia -ideaesthesia-,,,qualia
|
||||
Shades of Light in a Transcendent Realm,,,shadesoflight
|
||||
trappola bewitching,,,trappola
|
||||
Vicious Heroism,,,viciousheroism
|
||||
Vicious [ANTi] Heroism,,,viciousheroism
|
||||
eden,,,edenwacca
|
|
|
@ -4,6 +4,7 @@ use std::path::PathBuf;
|
|||
use anyhow::anyhow;
|
||||
use image::RgbaImage;
|
||||
|
||||
use crate::commands::DataSource;
|
||||
use crate::context::{ErrorKind, TagError, TaggedError, UserContext};
|
||||
use crate::user::User;
|
||||
|
||||
|
@ -121,7 +122,16 @@ impl GoalStats {
|
|||
user: &User,
|
||||
scoring_system: ScoringSystem,
|
||||
) -> Result<Self, TaggedError> {
|
||||
let plays = get_best_plays(ctx, user.id, scoring_system, 0, usize::MAX, None)?;
|
||||
let plays = get_best_plays(
|
||||
ctx,
|
||||
user,
|
||||
DataSource::Local,
|
||||
scoring_system,
|
||||
0,
|
||||
usize::MAX,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
let conn = ctx.db.get()?;
|
||||
|
||||
// {{{ PM count
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
use std::str::FromStr;
|
||||
// {{{ Imports
|
||||
use std::{fmt::Display, num::NonZeroU16};
|
||||
|
||||
use anyhow::anyhow;
|
||||
use anyhow::{anyhow, bail};
|
||||
use image::{ImageBuffer, Rgb};
|
||||
use rusqlite::types::{FromSql, FromSqlError, FromSqlResult, ValueRef};
|
||||
use rusqlite::ToSql;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::bitmap::Color;
|
||||
|
@ -36,6 +38,19 @@ impl Difficulty {
|
|||
}
|
||||
}
|
||||
|
||||
impl FromStr for Difficulty {
|
||||
type Err = anyhow::Error;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
for (i, level) in Self::DIFFICULTY_SHORTHANDS.iter().enumerate() {
|
||||
if *level == s {
|
||||
return Ok(Self::DIFFICULTIES[i]);
|
||||
}
|
||||
}
|
||||
|
||||
bail!("Invalid level '{s}'");
|
||||
}
|
||||
}
|
||||
|
||||
impl FromSql for Difficulty {
|
||||
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
||||
let str: String = rusqlite::types::FromSql::column_result(value)?;
|
||||
|
@ -52,6 +67,12 @@ impl FromSql for Difficulty {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToSql for Difficulty {
|
||||
fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>> {
|
||||
Self::DIFFICULTY_SHORTHANDS[*self as usize].to_sql()
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Difficulty {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", Self::DIFFICULTY_SHORTHANDS[self.to_index()])
|
||||
|
@ -85,11 +106,12 @@ pub enum Level {
|
|||
Ten,
|
||||
TenP,
|
||||
Eleven,
|
||||
ElevenP,
|
||||
Twelve,
|
||||
}
|
||||
|
||||
impl Level {
|
||||
pub const LEVELS: [Self; 17] = [
|
||||
pub const LEVELS: [Self; 18] = [
|
||||
Self::Unknown,
|
||||
Self::One,
|
||||
Self::Two,
|
||||
|
@ -106,11 +128,13 @@ impl Level {
|
|||
Self::Ten,
|
||||
Self::TenP,
|
||||
Self::Eleven,
|
||||
Self::ElevenP,
|
||||
Self::Twelve,
|
||||
];
|
||||
|
||||
pub const LEVEL_STRINGS: [&'static str; 17] = [
|
||||
"?", "1", "2", "3", "4", "5", "6", "7", "7+", "8", "8+", "9", "9+", "10", "10+", "11", "12",
|
||||
pub const LEVEL_STRINGS: [&'static str; 18] = [
|
||||
"?", "1", "2", "3", "4", "5", "6", "7", "7+", "8", "8+", "9", "9+", "10", "10+", "11",
|
||||
"11+", "12",
|
||||
];
|
||||
|
||||
#[inline]
|
||||
|
@ -119,6 +143,19 @@ impl Level {
|
|||
}
|
||||
}
|
||||
|
||||
impl FromStr for Level {
|
||||
type Err = anyhow::Error;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
for (i, level) in Self::LEVEL_STRINGS.iter().enumerate() {
|
||||
if *level == s {
|
||||
return Ok(Self::LEVELS[i]);
|
||||
}
|
||||
}
|
||||
|
||||
bail!("Invalid level '{s}'");
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Level {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", Self::LEVEL_STRINGS[self.to_index()])
|
||||
|
@ -140,6 +177,12 @@ impl FromSql for Level {
|
|||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSql for Level {
|
||||
fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>> {
|
||||
Self::LEVEL_STRINGS[*self as usize].to_sql()
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
// {{{ Side
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
||||
|
@ -147,11 +190,12 @@ pub enum Side {
|
|||
Light,
|
||||
Conflict,
|
||||
Silent,
|
||||
Lephon,
|
||||
}
|
||||
|
||||
impl Side {
|
||||
pub const SIDES: [Self; 3] = [Self::Light, Self::Conflict, Self::Silent];
|
||||
pub const SIDE_STRINGS: [&'static str; 3] = ["light", "conflict", "silent"];
|
||||
pub const SIDES: [Self; 4] = [Self::Light, Self::Conflict, Self::Silent, Self::Lephon];
|
||||
pub const SIDE_STRINGS: [&'static str; 4] = ["light", "conflict", "silent", "lephon"];
|
||||
|
||||
#[inline]
|
||||
pub fn to_index(self) -> usize {
|
||||
|
@ -174,11 +218,18 @@ impl FromSql for Side {
|
|||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToSql for Side {
|
||||
fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>> {
|
||||
Self::SIDE_STRINGS[*self as usize].to_sql()
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
// {{{ Song
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Song {
|
||||
pub id: u32,
|
||||
pub shorthand: String,
|
||||
pub title: String,
|
||||
pub lowercase_title: String,
|
||||
|
||||
|
@ -186,7 +237,6 @@ pub struct Song {
|
|||
pub artist: String,
|
||||
|
||||
pub bpm: String,
|
||||
pub pack: Option<String>,
|
||||
pub side: Side,
|
||||
}
|
||||
|
||||
|
@ -219,7 +269,8 @@ pub struct Jacket {
|
|||
pub struct Chart {
|
||||
pub id: u32,
|
||||
pub song_id: u32,
|
||||
pub shorthand: Option<String>,
|
||||
pub title: Option<String>, // Name override for charts like PRAGMATISM
|
||||
pub lowercase_title: Option<String>,
|
||||
pub note_design: Option<String>,
|
||||
|
||||
pub difficulty: Difficulty,
|
||||
|
@ -363,9 +414,9 @@ impl SongCache {
|
|||
Ok(Song {
|
||||
id: row.get("id")?,
|
||||
lowercase_title: row.get::<_, String>("title")?.to_lowercase(),
|
||||
shorthand: row.get("shorthand")?,
|
||||
title: row.get("title")?,
|
||||
artist: row.get("artist")?,
|
||||
pack: row.get("pack")?,
|
||||
bpm: row.get("bpm")?,
|
||||
side: row.get("side")?,
|
||||
})
|
||||
|
@ -388,7 +439,10 @@ impl SongCache {
|
|||
Ok(Chart {
|
||||
id: row.get("id")?,
|
||||
song_id: row.get("song_id")?,
|
||||
shorthand: row.get("shorthand")?,
|
||||
title: row.get("title")?,
|
||||
lowercase_title: row
|
||||
.get::<_, Option<String>>("title")?
|
||||
.map(|t| t.to_lowercase()),
|
||||
difficulty: row.get("difficulty")?,
|
||||
level: row.get("level")?,
|
||||
chart_constant: row.get("chart_constant")?,
|
||||
|
|
282
src/arcaea/import_charts.rs
Normal file
|
@ -0,0 +1,282 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use anyhow::{anyhow, Context};
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::{
|
||||
arcaea::{chart::Side, rating::rating_as_fixed},
|
||||
context::paths::ShimmeringPaths,
|
||||
};
|
||||
|
||||
use super::{
|
||||
chart::{Difficulty, Level},
|
||||
rating::{rating_from_fixed, Rating},
|
||||
};
|
||||
|
||||
// {{{ Notecount
|
||||
struct NotecountEntry {
|
||||
difficulty: Difficulty,
|
||||
level: Level,
|
||||
name: String,
|
||||
notecount: u32,
|
||||
}
|
||||
|
||||
fn get_notecount_records(paths: &ShimmeringPaths) -> anyhow::Result<Vec<NotecountEntry>> {
|
||||
let mut entries = Vec::new();
|
||||
let mut reader = csv::Reader::from_reader(std::io::BufReader::new(std::fs::File::open(
|
||||
paths.notecount_path(),
|
||||
)?));
|
||||
|
||||
for result in reader.records() {
|
||||
let record = result?;
|
||||
|
||||
let notecount = record
|
||||
.get(0)
|
||||
.ok_or_else(|| anyhow!("Missing notecount in csv entry"))?
|
||||
.parse()?;
|
||||
|
||||
let raw_difficulty = record
|
||||
.get(1)
|
||||
.ok_or_else(|| anyhow!("Missing level/difficulty in csv entry"))?;
|
||||
|
||||
let name = record
|
||||
.get(2)
|
||||
.ok_or_else(|| anyhow!("Missing name in csv entry"))?;
|
||||
|
||||
let (raw_difficulty, raw_level) = raw_difficulty
|
||||
.split_once(" ")
|
||||
.ok_or_else(|| anyhow!("Invalid level/difficulty string in csv entry"))?;
|
||||
|
||||
entries.push(NotecountEntry {
|
||||
notecount,
|
||||
name: name.to_owned(),
|
||||
level: raw_level.parse()?,
|
||||
difficulty: raw_difficulty.parse()?,
|
||||
});
|
||||
}
|
||||
|
||||
Ok(entries)
|
||||
}
|
||||
// }}}
|
||||
// {{{ PTT entries
|
||||
#[derive(Clone, Copy, Deserialize)]
|
||||
struct PTTEntry {
|
||||
#[serde(rename = "0")]
|
||||
pst: Option<f32>,
|
||||
#[serde(rename = "1")]
|
||||
prs: Option<f32>,
|
||||
#[serde(rename = "2")]
|
||||
ftr: Option<f32>,
|
||||
#[serde(rename = "3")]
|
||||
byd: Option<f32>,
|
||||
#[serde(rename = "4")]
|
||||
etr: Option<f32>,
|
||||
}
|
||||
|
||||
impl PTTEntry {
|
||||
fn get_rating(&self, difficulty: Difficulty) -> Option<Rating> {
|
||||
let float = match difficulty {
|
||||
Difficulty::PST => self.pst,
|
||||
Difficulty::PRS => self.prs,
|
||||
Difficulty::FTR => self.ftr,
|
||||
Difficulty::BYD => self.byd,
|
||||
Difficulty::ETR => self.etr,
|
||||
};
|
||||
|
||||
float.map(|f| rating_from_fixed((f * 100.0).round() as i32))
|
||||
}
|
||||
}
|
||||
|
||||
fn get_ptt_entries(paths: &ShimmeringPaths) -> anyhow::Result<HashMap<String, PTTEntry>> {
|
||||
let result = serde_json::from_reader(std::io::BufReader::new(std::fs::File::open(
|
||||
paths.cc_data_path(),
|
||||
)?))?;
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
// }}}
|
||||
// {{{ Songlist types
|
||||
#[derive(Deserialize)]
|
||||
struct LocalizedName {
|
||||
en: String,
|
||||
og: Option<String>,
|
||||
}
|
||||
|
||||
impl LocalizedName {
|
||||
fn get(&self) -> &str {
|
||||
self.og.as_ref().unwrap_or(&self.en)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct Chart {
|
||||
rating: u8,
|
||||
#[serde(default, rename = "ratingPlus")]
|
||||
rating_plus: bool,
|
||||
#[serde(rename = "ratingClass")]
|
||||
difficulty: u8,
|
||||
|
||||
#[serde(rename = "chartDesigner")]
|
||||
chart_designer: String,
|
||||
|
||||
#[allow(unused)]
|
||||
#[serde(rename = "jacketDesigner")]
|
||||
jacket_designer: String,
|
||||
|
||||
#[serde(rename = "title_localized")]
|
||||
title: Option<LocalizedName>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct Song {
|
||||
#[serde(rename = "idx")]
|
||||
id: u32,
|
||||
#[serde(rename = "id")]
|
||||
shorthand: String,
|
||||
#[serde(rename = "title_localized")]
|
||||
title: LocalizedName,
|
||||
|
||||
artist: String,
|
||||
bpm: String,
|
||||
side: u32,
|
||||
difficulties: Vec<Chart>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct DeletedSong {
|
||||
#[allow(unused)]
|
||||
deleted: bool,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(untagged)]
|
||||
enum SonglistEntry {
|
||||
Song(Song),
|
||||
|
||||
#[allow(unused)]
|
||||
Deleted(DeletedSong),
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct Songlist {
|
||||
songs: Vec<SonglistEntry>,
|
||||
}
|
||||
// }}}
|
||||
// {{{ Process songlist file
|
||||
pub fn import_songlist(
|
||||
paths: &ShimmeringPaths,
|
||||
conn: &mut rusqlite::Connection,
|
||||
) -> anyhow::Result<()> {
|
||||
let notecount_records =
|
||||
get_notecount_records(paths).context("Failed to read notecount records")?;
|
||||
let ptt_entries = get_ptt_entries(paths).context("Failed to read ptt entries")?;
|
||||
|
||||
let transaction = conn.transaction()?;
|
||||
transaction.execute("DELETE FROM charts", ())?;
|
||||
transaction.execute("DELETE FROM songs", ())?;
|
||||
|
||||
let songlist: Songlist = serde_json::from_reader(std::io::BufReader::new(
|
||||
std::fs::File::open(paths.songlist_path())?,
|
||||
))?;
|
||||
|
||||
let mut song_count = 0;
|
||||
let mut chart_count = 0;
|
||||
|
||||
for song in songlist.songs {
|
||||
let song = match song {
|
||||
SonglistEntry::Song(song) => song,
|
||||
SonglistEntry::Deleted(_) => continue,
|
||||
};
|
||||
|
||||
song_count += 1;
|
||||
transaction.execute(
|
||||
"
|
||||
INSERT INTO songs(id,title,shorthand,artist,side,bpm)
|
||||
VALUES (?,?,?,?,?,?)
|
||||
",
|
||||
(
|
||||
song.id,
|
||||
song.title.get(),
|
||||
&song.shorthand,
|
||||
&song.artist,
|
||||
Side::SIDES[song.side as usize],
|
||||
song.bpm,
|
||||
),
|
||||
)?;
|
||||
|
||||
for chart in song.difficulties {
|
||||
if chart.rating == 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
chart_count += 1;
|
||||
|
||||
let difficulty = crate::private_server::decode_difficulty(chart.difficulty)
|
||||
.ok_or_else(|| anyhow!("Invalid difficulty"))?;
|
||||
|
||||
let level = format!(
|
||||
"{}{}",
|
||||
chart.rating,
|
||||
if chart.rating_plus { "+" } else { "" }
|
||||
)
|
||||
.parse()
|
||||
.context("Failed to parse level")?;
|
||||
|
||||
let name = chart.title.as_ref().unwrap_or(&song.title).get();
|
||||
let notecount = notecount_records
|
||||
.iter()
|
||||
.find_map(|record| {
|
||||
let names_match = record.name == name
|
||||
|| record.name == format!("{name} ({})", &song.artist)
|
||||
|| record.name == song.shorthand;
|
||||
|
||||
if names_match && record.level == level && record.difficulty == difficulty {
|
||||
Some(record.notecount)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.ok_or_else(|| {
|
||||
anyhow!(
|
||||
"Cannot find note count for song '{}' [{}]",
|
||||
name,
|
||||
difficulty
|
||||
)
|
||||
})?;
|
||||
|
||||
let cc = ptt_entries
|
||||
.get(&song.shorthand)
|
||||
.ok_or_else(|| anyhow!("Cannot find PTT data for song '{}'", song.shorthand))?
|
||||
.get_rating(difficulty)
|
||||
.ok_or_else(|| {
|
||||
anyhow!("Cannot find PTT data for song '{}' [{}]", name, difficulty)
|
||||
})?;
|
||||
|
||||
transaction.execute(
|
||||
"
|
||||
INSERT INTO charts(
|
||||
song_id, title, difficulty,
|
||||
level, note_count, chart_constant,
|
||||
note_design
|
||||
) VALUES(?,?,?,?,?,?,?)
|
||||
",
|
||||
(
|
||||
song.id,
|
||||
chart.title.as_ref().map(|t| t.get()),
|
||||
difficulty,
|
||||
level,
|
||||
notecount,
|
||||
rating_as_fixed(cc),
|
||||
chart.chart_designer,
|
||||
),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
transaction.commit()?;
|
||||
|
||||
println!("✅ Succesfully imported {chart_count} charts, {song_count} songs");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
// }}}
|
|
@ -1,5 +1,6 @@
|
|||
pub mod achievement;
|
||||
pub mod chart;
|
||||
pub mod import_charts;
|
||||
pub mod jacket;
|
||||
pub mod play;
|
||||
pub mod rating;
|
||||
|
|
|
@ -16,6 +16,7 @@ use serde::Deserialize;
|
|||
use serde::Serialize;
|
||||
|
||||
use crate::arcaea::chart::{Chart, Song};
|
||||
use crate::commands::DataSource;
|
||||
use crate::context::ErrorKind;
|
||||
use crate::context::TagError;
|
||||
use crate::context::TaggedError;
|
||||
|
@ -67,7 +68,12 @@ impl CreatePlay {
|
|||
}
|
||||
|
||||
// {{{ Save
|
||||
pub fn save(self, ctx: &UserContext, user: &User, chart: &Chart) -> Result<Play, TaggedError> {
|
||||
pub async fn save(
|
||||
self,
|
||||
ctx: &UserContext,
|
||||
user: &User,
|
||||
chart: &Chart,
|
||||
) -> Result<Play, TaggedError> {
|
||||
let conn = ctx.db.get()?;
|
||||
let attachment_id = self.discord_attachment_id.map(|i| i.get() as i64);
|
||||
|
||||
|
@ -110,7 +116,7 @@ impl CreatePlay {
|
|||
|
||||
for system in ScoringSystem::SCORING_SYSTEMS {
|
||||
let i = system.to_index();
|
||||
let creation_ptt = try_compute_ptt(ctx, user.id, system, None)?;
|
||||
let creation_ptt = try_compute_ptt(ctx, user, DataSource::Local, system, None).await?;
|
||||
|
||||
conn.prepare_cached(
|
||||
"
|
||||
|
@ -382,8 +388,11 @@ impl Play {
|
|||
"-".to_string()
|
||||
},
|
||||
true,
|
||||
)
|
||||
.field("ID", format!("{}", self.id), true);
|
||||
);
|
||||
|
||||
if self.id != 0 {
|
||||
embed = embed.field("ID", format!("{}", self.id), true);
|
||||
}
|
||||
|
||||
if icon_attachement.is_some() {
|
||||
embed = embed.thumbnail(format!("attachment://{}", &attachement_name));
|
||||
|
@ -410,19 +419,22 @@ impl Play {
|
|||
// {{{ General functions
|
||||
pub type PlayCollection<'a> = Vec<(Play, &'a Song, &'a Chart)>;
|
||||
|
||||
pub fn get_best_plays(
|
||||
ctx: &UserContext,
|
||||
user_id: u32,
|
||||
pub async fn get_best_plays<'a>(
|
||||
ctx: &'a UserContext,
|
||||
user: &User,
|
||||
source: DataSource,
|
||||
scoring_system: ScoringSystem,
|
||||
min_amount: usize,
|
||||
max_amount: usize,
|
||||
before: Option<NaiveDateTime>,
|
||||
) -> Result<PlayCollection<'_>, TaggedError> {
|
||||
let conn = ctx.db.get()?;
|
||||
) -> Result<PlayCollection<'a>, TaggedError> {
|
||||
// {{{ DB data fetching
|
||||
let mut plays = conn
|
||||
.prepare_cached(
|
||||
"
|
||||
let conn = ctx.db.get()?;
|
||||
let mut plays = match source {
|
||||
DataSource::Local => {
|
||||
// {{{ Fetch plays from db
|
||||
conn.prepare_cached(
|
||||
"
|
||||
SELECT
|
||||
p.id, p.chart_id, p.user_id, p.created_at,
|
||||
p.max_recall, p.far_notes, s.score,
|
||||
|
@ -437,20 +449,35 @@ pub fn get_best_plays(
|
|||
AND p.created_at<=?
|
||||
GROUP BY p.chart_id
|
||||
",
|
||||
)?
|
||||
.query_and_then(
|
||||
(
|
||||
ScoringSystem::SCORING_SYSTEM_DB_STRINGS[scoring_system.to_index()],
|
||||
user_id,
|
||||
before.unwrap_or_else(|| Utc::now().naive_utc()),
|
||||
),
|
||||
|row| {
|
||||
let (song, chart) = ctx.song_cache.lookup_chart(row.get("chart_id")?)?;
|
||||
let play = Play::from_sql(chart, row)?;
|
||||
Ok((play, song, chart))
|
||||
},
|
||||
)?
|
||||
.collect::<Result<Vec<_>, Error>>()?;
|
||||
)?
|
||||
.query_and_then(
|
||||
(
|
||||
ScoringSystem::SCORING_SYSTEM_DB_STRINGS[scoring_system.to_index()],
|
||||
user.id,
|
||||
before.unwrap_or_else(|| Utc::now().naive_utc()),
|
||||
),
|
||||
|row| {
|
||||
let (song, chart) = ctx.song_cache.lookup_chart(row.get("chart_id")?)?;
|
||||
let play = Play::from_sql(chart, row)?;
|
||||
Ok((play, song, chart))
|
||||
},
|
||||
)?
|
||||
.collect::<Result<Vec<_>, Error>>()?
|
||||
// }}}
|
||||
}
|
||||
DataSource::Server => {
|
||||
// {{{ Fetch data remotely
|
||||
crate::private_server::best(ctx, user, crate::private_server::BestOptions::default())
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|play| {
|
||||
let (song, chart) = ctx.song_cache.lookup_chart(play.chart_id)?;
|
||||
Ok((play, song, chart))
|
||||
})
|
||||
.collect::<Result<Vec<_>, Error>>()?
|
||||
// }}}
|
||||
}
|
||||
};
|
||||
// }}}
|
||||
|
||||
if plays.len() < min_amount {
|
||||
|
@ -474,13 +501,14 @@ pub fn get_best_plays(
|
|||
/// This is similar to directly calling [get_best_plays] and then passing the
|
||||
/// result into [compute_b30_ptt], except any user errors (i.e.: not enough
|
||||
/// plays available) get turned into [None] values.
|
||||
pub fn try_compute_ptt(
|
||||
pub async fn try_compute_ptt(
|
||||
ctx: &UserContext,
|
||||
user_id: u32,
|
||||
user: &User,
|
||||
source: DataSource,
|
||||
system: ScoringSystem,
|
||||
before: Option<NaiveDateTime>,
|
||||
) -> Result<Option<i32>, Error> {
|
||||
match get_best_plays(ctx, user_id, system, 30, 30, before) {
|
||||
match get_best_plays(ctx, user, source, system, 30, 30, before).await {
|
||||
Err(err) => match err.kind {
|
||||
ErrorKind::User => Ok(None),
|
||||
ErrorKind::Internal => Err(err.error),
|
||||
|
@ -526,7 +554,17 @@ pub async fn generate_missing_scores(ctx: &UserContext) -> Result<(), Error> {
|
|||
let play = play?;
|
||||
for system in ScoringSystem::SCORING_SYSTEMS {
|
||||
let i = system.to_index();
|
||||
let creation_ptt = try_compute_ptt(ctx, play.user_id, system, Some(play.created_at))?;
|
||||
let creation_ptt = try_compute_ptt(
|
||||
ctx,
|
||||
&User {
|
||||
id: play.user_id,
|
||||
..Default::default()
|
||||
},
|
||||
DataSource::Local,
|
||||
system,
|
||||
Some(play.created_at),
|
||||
)
|
||||
.await?;
|
||||
|
||||
let raw_score = play.scores.0[i].0;
|
||||
|
||||
|
|
|
@ -11,8 +11,9 @@ use super::rating::{rating_as_float, rating_from_fixed, Rating};
|
|||
// }}}
|
||||
|
||||
// {{{ Scoring system
|
||||
#[derive(Debug, Clone, Copy, poise::ChoiceParameter)]
|
||||
#[derive(Debug, Clone, Copy, Default, poise::ChoiceParameter)]
|
||||
pub enum ScoringSystem {
|
||||
#[default]
|
||||
Standard,
|
||||
|
||||
/// Forgives up to 9 missed shinies, then uses EX scoring.
|
||||
|
@ -36,12 +37,6 @@ impl ScoringSystem {
|
|||
self as usize
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ScoringSystem {
|
||||
fn default() -> Self {
|
||||
Self::Standard
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
// {{{ Grade
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
|
|
|
@ -44,15 +44,20 @@ pub static UNI_FONT: RefCell<Font> = get_font!("unifont.otf");
|
|||
// }}}
|
||||
// {{{ Asset art helpers
|
||||
macro_rules! get_asset {
|
||||
($name: ident, $path:expr) => {
|
||||
get_asset!($name, $path, "SHIMMERING_ASSET_DIR", |d: DynamicImage| d);
|
||||
($name: ident, $file:expr) => {
|
||||
get_asset!(
|
||||
$name,
|
||||
$file,
|
||||
concat!(env!("SHIMMERING_SOURCE_DIR"), "/assets"),
|
||||
|d: DynamicImage| d
|
||||
);
|
||||
};
|
||||
($name: ident, $path:expr, $env_var: literal, $f:expr) => {
|
||||
($name: ident, $file:expr, $dir: expr, $f:expr) => {
|
||||
pub static $name: LazyLock<RgbaImage> = LazyLock::new(move || {
|
||||
static IMAGE_BYTES: &[u8] = include_bytes!(concat!(env!($env_var), "/", $path));
|
||||
static IMAGE_BYTES: &[u8] = include_bytes!(concat!($dir, "/", $file));
|
||||
|
||||
let image = image::load_from_memory(&IMAGE_BYTES)
|
||||
.unwrap_or_else(|_| panic!("Could no read asset `{}`", $path));
|
||||
.unwrap_or_else(|_| panic!("Could no read asset `{}`", $file));
|
||||
|
||||
let f = $f;
|
||||
f(image).into_rgba8()
|
||||
|
@ -71,7 +76,7 @@ get_asset!(PTT_EMBLEM, "ptt_emblem.png");
|
|||
get_asset!(
|
||||
B30_BACKGROUND,
|
||||
"b30_background.jpg",
|
||||
"SHIMMERING_PRIVATE_CONFIG_DIR",
|
||||
env!("SHIMMERING_PRIVATE_CONFIG_DIR"),
|
||||
|image: DynamicImage| image.blur(7.0)
|
||||
);
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ async fn on_error(error: poise::FrameworkError<'_, UserContext, Error>) {
|
|||
// }}}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
// {{{ Poise options
|
||||
let options = poise::FrameworkOptions {
|
||||
commands: vec![
|
||||
|
@ -22,6 +22,7 @@ async fn main() {
|
|||
commands::stats::stats(),
|
||||
commands::chart::chart(),
|
||||
commands::calc::calc(),
|
||||
commands::user::user(),
|
||||
],
|
||||
prefix_options: poise::PrefixFrameworkOptions {
|
||||
stripped_dynamic_prefix: Some(|_ctx, message, _user_ctx| {
|
||||
|
@ -56,20 +57,18 @@ async fn main() {
|
|||
Box::pin(async move {
|
||||
println!("🔒 Logged in as {}", _ready.user.name);
|
||||
poise::builtins::register_globally(ctx, &framework.options().commands).await?;
|
||||
let ctx = UserContext::new()?;
|
||||
|
||||
if var("SHIMMERING_REGEN_SCORES").unwrap_or_default() == "1" {
|
||||
timed!("generate_missing_scores", {
|
||||
generate_missing_scores(&ctx).await?;
|
||||
});
|
||||
}
|
||||
|
||||
Ok(ctx)
|
||||
Ok(UserContext::new().unwrap())
|
||||
})
|
||||
})
|
||||
.options(options)
|
||||
.build();
|
||||
|
||||
if var("SHIMMERING_REGEN_SCORES").unwrap_or_default() == "1" {
|
||||
timed!("generate_missing_scores", {
|
||||
generate_missing_scores(framework.user_data().await).await?;
|
||||
});
|
||||
}
|
||||
|
||||
let token =
|
||||
var("SHIMMERING_DISCORD_TOKEN").expect("Missing `SHIMMERING_DISCORD_TOKEN` env var");
|
||||
let intents =
|
||||
|
@ -79,6 +78,8 @@ async fn main() {
|
|||
.framework(framework)
|
||||
.await;
|
||||
|
||||
client.unwrap().start().await.unwrap()
|
||||
client.unwrap().start().await?;
|
||||
// }}}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ use crate::user::User;
|
|||
use crate::arcaea::score::{Score, ScoringSystem};
|
||||
|
||||
use super::discord::MessageContext;
|
||||
use super::DataSource;
|
||||
// }}}
|
||||
|
||||
// {{{ Top command
|
||||
|
@ -28,6 +29,8 @@ pub async fn calc(_ctx: PoiseContext<'_>) -> Result<(), Error> {
|
|||
// {{{ Implementation
|
||||
async fn expected_impl(
|
||||
ctx: &mut impl MessageContext,
|
||||
source: DataSource,
|
||||
system: ScoringSystem,
|
||||
ptt: Option<Rational32>,
|
||||
name: &str,
|
||||
) -> Result<Score, TaggedError> {
|
||||
|
@ -39,7 +42,7 @@ async fn expected_impl(
|
|||
let user = User::from_context(ctx)?;
|
||||
compute_b30_ptt(
|
||||
ScoringSystem::Standard,
|
||||
&get_best_plays(ctx.data(), user.id, ScoringSystem::Standard, 30, 30, None)?,
|
||||
&get_best_plays(ctx.data(), &user, source, system, 30, 30, None).await?,
|
||||
)
|
||||
};
|
||||
|
||||
|
@ -85,9 +88,15 @@ mod expected_tests {
|
|||
for i in 0..1_000 {
|
||||
let score = Score(i * 10_000);
|
||||
let rating = score.play_rating(1140);
|
||||
let res = expected_impl(&mut ctx, Some(rating), "Pentiment [BYD]")
|
||||
.await
|
||||
.map_err(|e| e.error)?;
|
||||
let res = expected_impl(
|
||||
&mut ctx,
|
||||
DataSource::Local,
|
||||
ScoringSystem::Standard,
|
||||
Some(rating),
|
||||
"Pentiment [BYD]",
|
||||
)
|
||||
.await
|
||||
.map_err(|e| e.error)?;
|
||||
assert_eq!(
|
||||
score, res,
|
||||
"Wrong expected score for starting score {score} and rating {rating}"
|
||||
|
@ -101,6 +110,8 @@ mod expected_tests {
|
|||
async fn basic_usage(ctx: &mut MockContext) -> Result<(), TaggedError> {
|
||||
expected_impl(
|
||||
ctx,
|
||||
DataSource::Local,
|
||||
ScoringSystem::Standard,
|
||||
Some(Rational32::from_f32(12.27).unwrap()),
|
||||
"Vicious anti heorism",
|
||||
)
|
||||
|
@ -115,12 +126,21 @@ mod expected_tests {
|
|||
#[poise::command(prefix_command, slash_command, user_cooldown = 1)]
|
||||
async fn expected(
|
||||
mut ctx: PoiseContext<'_>,
|
||||
source: Option<DataSource>,
|
||||
system: Option<ScoringSystem>,
|
||||
#[description = "The potential to compute the expected score for"] ptt: Option<f32>,
|
||||
#[rest]
|
||||
#[description = "Name of chart (difficulty at the end)"]
|
||||
name: String,
|
||||
) -> Result<(), Error> {
|
||||
let res = expected_impl(&mut ctx, ptt.and_then(Rational32::from_f32), &name).await;
|
||||
let res = expected_impl(
|
||||
&mut ctx,
|
||||
source.unwrap_or_default(),
|
||||
system.unwrap_or_default(),
|
||||
ptt.and_then(Rational32::from_f32),
|
||||
&name,
|
||||
)
|
||||
.await;
|
||||
ctx.handle_error(res).await?;
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -21,6 +21,7 @@ use poise::CreateReply;
|
|||
use crate::arcaea::score::{Score, ScoringSystem};
|
||||
|
||||
use super::discord::{CreateReplyExtra, MessageContext};
|
||||
use super::DataSource;
|
||||
// }}}
|
||||
|
||||
// {{{ Top command
|
||||
|
@ -75,13 +76,9 @@ async fn info_impl(ctx: &mut impl MessageContext, name: &str) -> Result<(), Tagg
|
|||
.field("Side", Side::SIDE_STRINGS[song.side.to_index()], true)
|
||||
.field("Artist", &song.title, true);
|
||||
|
||||
if let Some(note_design) = &chart.note_design {
|
||||
embed = embed.field("Note design", note_design, true);
|
||||
}
|
||||
|
||||
if let Some(pack) = &song.pack {
|
||||
embed = embed.field("Pack", pack, true);
|
||||
}
|
||||
// if let Some(note_design) = &chart.note_design {
|
||||
// embed = embed.field("Note design", note_design, true);
|
||||
// }
|
||||
|
||||
if icon_attachement.is_some() {
|
||||
embed = embed.thumbnail(format!("attachment://{}", &attachement_name));
|
||||
|
@ -150,16 +147,22 @@ async fn info(
|
|||
// }}}
|
||||
// {{{ Best score
|
||||
// {{{ Implementation
|
||||
async fn best_impl<C: MessageContext>(ctx: &mut C, name: &str) -> Result<Play, TaggedError> {
|
||||
async fn best_impl<C: MessageContext>(
|
||||
ctx: &mut C,
|
||||
name: &str,
|
||||
source: DataSource,
|
||||
) -> Result<Play, TaggedError> {
|
||||
let user = User::from_context(ctx)?;
|
||||
|
||||
let (song, chart) = guess_song_and_chart(ctx.data(), name)?;
|
||||
let play = ctx
|
||||
.data()
|
||||
.db
|
||||
.get()?
|
||||
.prepare_cached(
|
||||
"
|
||||
let play = match source {
|
||||
DataSource::Local => {
|
||||
// {{{ Query local db
|
||||
ctx.data()
|
||||
.db
|
||||
.get()?
|
||||
.prepare_cached(
|
||||
"
|
||||
SELECT
|
||||
p.id, p.chart_id, p.user_id, p.created_at,
|
||||
p.max_recall, p.far_notes, s.score
|
||||
|
@ -171,16 +174,43 @@ async fn best_impl<C: MessageContext>(ctx: &mut C, name: &str) -> Result<Play, T
|
|||
ORDER BY s.score DESC
|
||||
LIMIT 1
|
||||
",
|
||||
)?
|
||||
.query_row((user.id, chart.id), |row| Play::from_sql(chart, row))
|
||||
.map_err(|_| {
|
||||
anyhow!(
|
||||
"Could not find any scores for {} [{:?}]",
|
||||
song.title,
|
||||
chart.difficulty
|
||||
)?
|
||||
.query_row((user.id, chart.id), |row| Play::from_sql(chart, row))
|
||||
.map_err(|_| {
|
||||
anyhow!(
|
||||
"Could not find any scores for {} [{:?}]",
|
||||
song.title,
|
||||
chart.difficulty
|
||||
)
|
||||
.tag(ErrorKind::User)
|
||||
})?
|
||||
// }}}
|
||||
}
|
||||
DataSource::Server => {
|
||||
// {{{ Query from private server
|
||||
crate::private_server::best(
|
||||
ctx.data(),
|
||||
&user,
|
||||
crate::private_server::BestOptions {
|
||||
limit: Some(1),
|
||||
offset: None,
|
||||
query: Some(crate::private_server::BestScoreQuery {
|
||||
song_id: Some(&song.shorthand),
|
||||
difficulty: Some(crate::private_server::encode_difficulty(
|
||||
chart.difficulty,
|
||||
)),
|
||||
}),
|
||||
},
|
||||
)
|
||||
.tag(ErrorKind::User)
|
||||
})?;
|
||||
.await?
|
||||
.into_iter()
|
||||
.next()
|
||||
.ok_or_else(|| {
|
||||
anyhow!("The server found no plays for the given song").tag(ErrorKind::User)
|
||||
})?
|
||||
// }}}
|
||||
}
|
||||
};
|
||||
|
||||
let (embed, attachment) = play.to_embed(
|
||||
ctx.data(),
|
||||
|
@ -218,7 +248,7 @@ mod best_tests {
|
|||
#[tokio::test]
|
||||
async fn no_scores() -> Result<(), Error> {
|
||||
with_test_ctx!("commands/chart/best/no_scores", |ctx| async move {
|
||||
best_impl(ctx, "Pentiment").await?;
|
||||
best_impl(ctx, "Pentiment", DataSource::Local).await?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
@ -236,7 +266,7 @@ mod best_tests {
|
|||
)
|
||||
.await?;
|
||||
|
||||
let play = best_impl(ctx, "Fracture ray").await?;
|
||||
let play = best_impl(ctx, "Fracture ray", DataSource::Local).await?;
|
||||
assert_eq!(play.score(ScoringSystem::Standard).0, 9_805_651);
|
||||
assert_eq!(plays[0], play);
|
||||
|
||||
|
@ -250,11 +280,16 @@ mod best_tests {
|
|||
#[poise::command(prefix_command, slash_command, user_cooldown = 1)]
|
||||
async fn best(
|
||||
mut ctx: PoiseContext<'_>,
|
||||
|
||||
#[description = "Whether to use local data or data from some private server"] source: Option<
|
||||
DataSource,
|
||||
>,
|
||||
|
||||
#[rest]
|
||||
#[description = "Name of chart (difficulty at the end)"]
|
||||
name: String,
|
||||
) -> Result<(), Error> {
|
||||
let res = best_impl(&mut ctx, &name).await;
|
||||
let res = best_impl(&mut ctx, &name, source.unwrap_or(DataSource::Local)).await;
|
||||
ctx.handle_error(res).await?;
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -70,7 +70,7 @@ pub trait MessageContext {
|
|||
}
|
||||
// }}}
|
||||
// {{{ Poise implementation
|
||||
impl<'a> MessageContext for poise::Context<'a, UserContext, Error> {
|
||||
impl MessageContext for poise::Context<'_, UserContext, Error> {
|
||||
type Attachment = poise::serenity_prelude::Attachment;
|
||||
|
||||
fn data(&self) -> &UserContext {
|
||||
|
|
|
@ -5,8 +5,16 @@ pub mod chart;
|
|||
pub mod discord;
|
||||
pub mod score;
|
||||
pub mod stats;
|
||||
pub mod user;
|
||||
pub mod utils;
|
||||
|
||||
#[derive(Clone, Copy, Default, poise::ChoiceParameter)]
|
||||
pub enum DataSource {
|
||||
#[default]
|
||||
Local,
|
||||
Server,
|
||||
}
|
||||
|
||||
// {{{ Help
|
||||
/// Show this help menu
|
||||
#[poise::command(prefix_command, slash_command, subcommands("scoring", "scoringz"))]
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::arcaea::score::Score;
|
|||
use crate::context::{Error, ErrorKind, PoiseContext, TagError, TaggedError};
|
||||
use crate::recognition::recognize::{ImageAnalyzer, ScoreKind};
|
||||
use crate::user::User;
|
||||
use crate::{get_user_error, timed, try_block};
|
||||
use crate::{async_try_block, get_user_error, timed};
|
||||
use anyhow::anyhow;
|
||||
use image::DynamicImage;
|
||||
use poise::{serenity_prelude as serenity, CreateReply};
|
||||
|
@ -48,7 +48,7 @@ pub async fn magic_impl<C: MessageContext>(
|
|||
let mut grayscale_image = DynamicImage::ImageLuma8(image.to_luma8());
|
||||
// }}}
|
||||
|
||||
let result: Result<(), TaggedError> = try_block!({
|
||||
let result: Result<(), TaggedError> = async_try_block!({
|
||||
// {{{ Detection
|
||||
|
||||
let kind = timed!("read_score_kind", {
|
||||
|
@ -99,7 +99,8 @@ pub async fn magic_impl<C: MessageContext>(
|
|||
.with_attachment(C::attachment_id(attachment))
|
||||
.with_fars(maybe_fars)
|
||||
.with_max_recall(max_recall)
|
||||
.save(ctx.data(), &user, chart)?;
|
||||
.save(ctx.data(), &user, chart)
|
||||
.await?;
|
||||
// }}}
|
||||
// }}}
|
||||
// {{{ Deliver embed
|
||||
|
|
|
@ -23,6 +23,7 @@ use crate::logs::debug_image_log;
|
|||
use crate::user::User;
|
||||
|
||||
use super::discord::MessageContext;
|
||||
use super::DataSource;
|
||||
// }}}
|
||||
|
||||
// {{{ Stats
|
||||
|
@ -41,6 +42,7 @@ pub async fn stats(_ctx: PoiseContext<'_>) -> Result<(), Error> {
|
|||
async fn best_plays<C: MessageContext>(
|
||||
ctx: &mut C,
|
||||
user: &User,
|
||||
source: DataSource,
|
||||
scoring_system: ScoringSystem,
|
||||
grid_size: (u32, u32),
|
||||
require_full: bool,
|
||||
|
@ -48,7 +50,8 @@ async fn best_plays<C: MessageContext>(
|
|||
let user_ctx = ctx.data();
|
||||
let plays = get_best_plays(
|
||||
user_ctx,
|
||||
user.id,
|
||||
user,
|
||||
source,
|
||||
scoring_system,
|
||||
if require_full {
|
||||
grid_size.0 * grid_size.1
|
||||
|
@ -57,7 +60,8 @@ async fn best_plays<C: MessageContext>(
|
|||
} as usize,
|
||||
(grid_size.0 * grid_size.1) as usize,
|
||||
None,
|
||||
)?;
|
||||
)
|
||||
.await?;
|
||||
|
||||
// {{{ Layout
|
||||
let mut layout = LayoutManager::default();
|
||||
|
@ -419,10 +423,19 @@ async fn best_plays<C: MessageContext>(
|
|||
// {{{ Implementation
|
||||
pub async fn b30_impl<C: MessageContext>(
|
||||
ctx: &mut C,
|
||||
source: Option<DataSource>,
|
||||
scoring_system: Option<ScoringSystem>,
|
||||
) -> Result<(), TaggedError> {
|
||||
let user = User::from_context(ctx)?;
|
||||
best_plays(ctx, &user, scoring_system.unwrap_or_default(), (5, 6), true).await?;
|
||||
best_plays(
|
||||
ctx,
|
||||
&user,
|
||||
source.unwrap_or_default(),
|
||||
scoring_system.unwrap_or_default(),
|
||||
(5, 6),
|
||||
true,
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
// }}}
|
||||
|
@ -431,9 +444,10 @@ pub async fn b30_impl<C: MessageContext>(
|
|||
#[poise::command(prefix_command, slash_command, user_cooldown = 30)]
|
||||
pub async fn b30(
|
||||
mut ctx: PoiseContext<'_>,
|
||||
source: Option<DataSource>,
|
||||
scoring_system: Option<ScoringSystem>,
|
||||
) -> Result<(), Error> {
|
||||
let res = b30_impl(&mut ctx, scoring_system).await;
|
||||
let res = b30_impl(&mut ctx, source, scoring_system).await;
|
||||
ctx.handle_error(res).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -443,6 +457,7 @@ pub async fn b30(
|
|||
// {{{ Implementation
|
||||
async fn bany_impl<C: MessageContext>(
|
||||
ctx: &mut C,
|
||||
source: Option<DataSource>,
|
||||
scoring_system: Option<ScoringSystem>,
|
||||
width: u32,
|
||||
height: u32,
|
||||
|
@ -452,6 +467,7 @@ async fn bany_impl<C: MessageContext>(
|
|||
best_plays(
|
||||
ctx,
|
||||
&user,
|
||||
source.unwrap_or_default(),
|
||||
scoring_system.unwrap_or_default(),
|
||||
(width, height),
|
||||
false,
|
||||
|
@ -465,11 +481,12 @@ async fn bany_impl<C: MessageContext>(
|
|||
#[poise::command(prefix_command, slash_command, hide_in_help, global_cooldown = 5)]
|
||||
pub async fn bany(
|
||||
mut ctx: PoiseContext<'_>,
|
||||
source: Option<DataSource>,
|
||||
scoring_system: Option<ScoringSystem>,
|
||||
width: u32,
|
||||
height: u32,
|
||||
) -> Result<(), Error> {
|
||||
let res = bany_impl(&mut ctx, scoring_system, width, height).await;
|
||||
let res = bany_impl(&mut ctx, source, scoring_system, width, height).await;
|
||||
ctx.handle_error(res).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
221
src/commands/user.rs
Normal file
|
@ -0,0 +1,221 @@
|
|||
use anyhow::anyhow;
|
||||
|
||||
use crate::{
|
||||
context::{Error, ErrorKind, PoiseContext, TagError, TaggedError},
|
||||
user::User,
|
||||
};
|
||||
|
||||
use super::discord::MessageContext;
|
||||
|
||||
// {{{ Toplevel
|
||||
/// User management
|
||||
#[poise::command(
|
||||
prefix_command,
|
||||
slash_command,
|
||||
subcommands("register", "pookify", "bind", "unbind", "friend"),
|
||||
subcommand_required
|
||||
)]
|
||||
pub async fn user(_ctx: PoiseContext<'_>) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
// }}}
|
||||
// {{{ Register
|
||||
async fn register_impl<C: MessageContext>(
|
||||
ctx: &mut C,
|
||||
target_user: poise::serenity_prelude::User,
|
||||
) -> Result<(), TaggedError> {
|
||||
let user = User::from_context(ctx)?;
|
||||
user.assert_is_pookie()?;
|
||||
|
||||
match User::by_discord_id(ctx.data(), target_user.id) {
|
||||
Ok(_) => {
|
||||
ctx.reply("An account for this user already exists!")
|
||||
.await?;
|
||||
}
|
||||
Err(error) if error.kind == ErrorKind::Internal => return Err(error),
|
||||
Err(_) => {
|
||||
let rows_changed = ctx
|
||||
.data()
|
||||
.db
|
||||
.get()?
|
||||
.prepare_cached("INSERT INTO users(discord_id) VALUES (?)")?
|
||||
.execute([&target_user.id.to_string()])?;
|
||||
|
||||
assert!(rows_changed > 0);
|
||||
ctx.reply("Succesfully created user account!").await?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Create an account for another discord user
|
||||
#[poise::command(
|
||||
prefix_command,
|
||||
slash_command,
|
||||
context_menu_command = "Register user",
|
||||
install_context = "Guild",
|
||||
interaction_context = "Guild|BotDm|PrivateChannel"
|
||||
)]
|
||||
async fn register(
|
||||
mut ctx: PoiseContext<'_>,
|
||||
user: poise::serenity_prelude::User,
|
||||
) -> Result<(), Error> {
|
||||
let res = register_impl(&mut ctx, user).await;
|
||||
ctx.handle_error(res).await?;
|
||||
Ok(())
|
||||
}
|
||||
// }}}
|
||||
// {{{ Pookify
|
||||
async fn pookify_impl<C: MessageContext>(
|
||||
ctx: &mut C,
|
||||
target_user: poise::serenity_prelude::User,
|
||||
) -> Result<(), TaggedError> {
|
||||
let user = User::from_context(ctx)?;
|
||||
user.assert_is_admin()?;
|
||||
|
||||
let user = User::by_discord_id(ctx.data(), target_user.id)?;
|
||||
if user.is_pookie || user.is_admin {
|
||||
ctx.reply("This user is already a pookie of mine!").await?;
|
||||
} else {
|
||||
ctx.data()
|
||||
.db
|
||||
.get()?
|
||||
.prepare_cached("UPDATE users SET is_pookie=1 WHERE id=?")?
|
||||
.execute([user.id])?;
|
||||
|
||||
ctx.reply("Succesfully added user to my pookie list!")
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Add the given user to my pookie list
|
||||
#[poise::command(
|
||||
prefix_command,
|
||||
slash_command,
|
||||
context_menu_command = "Pookify user",
|
||||
install_context = "Guild",
|
||||
interaction_context = "Guild|BotDm|PrivateChannel"
|
||||
)]
|
||||
pub async fn pookify(
|
||||
mut ctx: PoiseContext<'_>,
|
||||
user: poise::serenity_prelude::User,
|
||||
) -> Result<(), Error> {
|
||||
let res = pookify_impl(&mut ctx, user).await;
|
||||
ctx.handle_error(res).await?;
|
||||
Ok(())
|
||||
}
|
||||
// }}}
|
||||
// {{{ Bind
|
||||
async fn bind_impl<C: MessageContext>(ctx: &mut C, username: String) -> Result<(), TaggedError> {
|
||||
let user = User::from_context(ctx)?;
|
||||
|
||||
let result = crate::private_server::users(
|
||||
ctx.data(),
|
||||
crate::private_server::UsersQueryOptions {
|
||||
query: Some(crate::private_server::UsersQuery {
|
||||
name: Some(&username),
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)
|
||||
.await?
|
||||
.into_iter()
|
||||
.next()
|
||||
.unwrap();
|
||||
|
||||
ctx.data()
|
||||
.db
|
||||
.get()?
|
||||
.prepare_cached("UPDATE users SET private_server_id=? WHERE id=?")?
|
||||
.execute((result.user_id, user.id))?;
|
||||
|
||||
ctx.reply("Succesfully bound account!").await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Bind your account to an account on the associated private server
|
||||
#[poise::command(prefix_command, slash_command)]
|
||||
async fn bind(mut ctx: PoiseContext<'_>, username: String) -> Result<(), Error> {
|
||||
let res = bind_impl(&mut ctx, username).await;
|
||||
ctx.handle_error(res).await?;
|
||||
Ok(())
|
||||
}
|
||||
// }}}
|
||||
// {{{ Friend code
|
||||
async fn friend_code_impl<C: MessageContext>(
|
||||
ctx: &mut C,
|
||||
target_user: poise::serenity_prelude::User,
|
||||
) -> Result<(), TaggedError> {
|
||||
let user = User::from_context(ctx)?;
|
||||
|
||||
let target = User::by_discord_id(ctx.data(), target_user.id)?;
|
||||
|
||||
let user_id = target
|
||||
.private_server_id
|
||||
.ok_or_else(|| anyhow!("This person hasn't bound their discord account to any account on the associated private server...").tag(ErrorKind::User))?;
|
||||
|
||||
let result = crate::private_server::users(
|
||||
ctx.data(),
|
||||
crate::private_server::UsersQueryOptions {
|
||||
query: Some(crate::private_server::UsersQuery {
|
||||
user_id: Some(user_id),
|
||||
..Default::default()
|
||||
}),
|
||||
},
|
||||
)
|
||||
.await?
|
||||
.into_iter()
|
||||
.next()
|
||||
.unwrap();
|
||||
|
||||
ctx.reply(&format!(
|
||||
"You can add `{}` as a friend using the code `{}`",
|
||||
&result.name, &result.user_code
|
||||
))
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Lookup the friend code of the given user
|
||||
#[poise::command(prefix_command, slash_command)]
|
||||
async fn friend(
|
||||
mut ctx: PoiseContext<'_>,
|
||||
user: poise::serenity_prelude::User,
|
||||
) -> Result<(), Error> {
|
||||
let res = friend_code_impl(&mut ctx, user).await;
|
||||
ctx.handle_error(res).await?;
|
||||
Ok(())
|
||||
}
|
||||
// }}}
|
||||
// {{{ Unbind
|
||||
async fn unbind_impl<C: MessageContext>(ctx: &mut C) -> Result<(), TaggedError> {
|
||||
let user = User::from_context(ctx)?;
|
||||
|
||||
if user.private_server_id.is_some() {
|
||||
ctx.data()
|
||||
.db
|
||||
.get()?
|
||||
.prepare_cached("UPDATE users SET private_server_id=NULL WHERE id=?")?
|
||||
.execute([user.id])?;
|
||||
|
||||
ctx.reply("Succesfully unbound account.").await?;
|
||||
} else {
|
||||
ctx.reply("There's no account to unbind 🤔").await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Unbind your account from an account on the associated private server
|
||||
#[poise::command(prefix_command, slash_command)]
|
||||
async fn unbind(mut ctx: PoiseContext<'_>) -> Result<(), Error> {
|
||||
let res = unbind_impl(&mut ctx).await;
|
||||
ctx.handle_error(res).await?;
|
||||
Ok(())
|
||||
}
|
||||
// }}}
|
|
@ -6,6 +6,7 @@ use r2d2_sqlite::SqliteConnectionManager;
|
|||
use rusqlite_migration::Migrations;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
use crate::arcaea::import_charts::import_songlist;
|
||||
use crate::context::hash::hash_files;
|
||||
use crate::context::paths::ShimmeringPaths;
|
||||
use crate::context::process_jackets::process_jackets;
|
||||
|
@ -17,6 +18,7 @@ pub fn connect_db(paths: &ShimmeringPaths) -> anyhow::Result<SqlitePool> {
|
|||
let db_path = paths.db_path();
|
||||
let mut conn = rusqlite::Connection::open(&db_path)
|
||||
.with_context(|| "Could not connect to sqlite database")?;
|
||||
conn.pragma_update(None, "journal_mode", "WAL")?;
|
||||
|
||||
// {{{ Run migrations
|
||||
static MIGRATIONS_DIR: Dir = include_dir!("$CARGO_MANIFEST_DIR/migrations");
|
||||
|
@ -31,20 +33,47 @@ pub fn connect_db(paths: &ShimmeringPaths) -> anyhow::Result<SqlitePool> {
|
|||
// }}}
|
||||
// {{{ Check if we need to reprocess jackets
|
||||
let current_raw_jackets_hash = hash_files(&paths.raw_jackets_path())?;
|
||||
let current_songlist_hash = hash_files(&paths.songlist_path())?;
|
||||
let current_cc_data_hash = hash_files(&paths.cc_data_path())?;
|
||||
let current_notecount_hash = hash_files(&paths.notecount_path())?;
|
||||
|
||||
// All this nonsense is so we can query without allocating
|
||||
// space for the output string 💀
|
||||
let mut statement = conn.prepare("SELECT raw_jackets_hash FROM metadata")?;
|
||||
let mut rows = statement.query(())?;
|
||||
let prev_raw_jackets_hash = rows
|
||||
.next()?
|
||||
.ok_or_else(|| anyhow!("No metadata row found"))?
|
||||
.get_ref("raw_jackets_hash")?
|
||||
.as_str()?;
|
||||
let (prev_raw_jackets_hash, prev_songlist_hash, prev_cc_data_hash, prev_notecount_hash) = conn
|
||||
.query_row("SELECT * FROM metadata", (), |row| {
|
||||
Ok((
|
||||
row.get_ref("raw_jackets_hash")?.as_str()?.to_owned(),
|
||||
row.get_ref("songlist_hash")?.as_str()?.to_owned(),
|
||||
row.get_ref("cc_data_hash")?.as_str()?.to_owned(),
|
||||
row.get_ref("notecount_hash")?.as_str()?.to_owned(),
|
||||
))
|
||||
})
|
||||
.with_context(|| anyhow!("No metadata row found"))?;
|
||||
|
||||
let mut should_reprocess_jackets = true;
|
||||
|
||||
if current_raw_jackets_hash != prev_raw_jackets_hash {
|
||||
if current_songlist_hash != prev_songlist_hash
|
||||
|| current_cc_data_hash != prev_cc_data_hash
|
||||
|| current_notecount_hash != prev_notecount_hash
|
||||
{
|
||||
println!("😞 Chart data hash mismatch. Re-importing everything");
|
||||
|
||||
// {{ Import songlist & update hashes
|
||||
import_songlist(paths, &mut conn).context("Failed to import songlist file")?;
|
||||
|
||||
conn.execute(
|
||||
"
|
||||
UPDATE metadata
|
||||
SET songlist_hash=?,
|
||||
cc_data_hash=?,
|
||||
notecount_hash=?
|
||||
",
|
||||
(
|
||||
current_songlist_hash,
|
||||
current_cc_data_hash,
|
||||
current_notecount_hash,
|
||||
),
|
||||
)?;
|
||||
// }}}
|
||||
} else if current_raw_jackets_hash != prev_raw_jackets_hash {
|
||||
println!("😞 Jacket hashes do not match. Re-running the processing pipeline");
|
||||
} else if !paths.recognition_matrix_path().exists() {
|
||||
println!("😞 Jacket recognition matrix not found.");
|
||||
|
|
|
@ -20,7 +20,7 @@ pub type Error = anyhow::Error;
|
|||
pub type PoiseContext<'a> = poise::Context<'a, UserContext, Error>;
|
||||
// }}}
|
||||
// {{{ Error handling
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ErrorKind {
|
||||
User,
|
||||
Internal,
|
||||
|
@ -81,6 +81,8 @@ pub struct UserContext {
|
|||
// TODO: do we really need both after I've fixed the bug in the ocr code?
|
||||
pub kazesawa_measurements: CharMeasurements,
|
||||
pub kazesawa_bold_measurements: CharMeasurements,
|
||||
|
||||
pub http_client: reqwest::Client,
|
||||
}
|
||||
|
||||
impl UserContext {
|
||||
|
@ -119,6 +121,7 @@ impl UserContext {
|
|||
exo_measurements,
|
||||
kazesawa_measurements,
|
||||
kazesawa_bold_measurements,
|
||||
http_client: reqwest::Client::builder().build()?,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -6,15 +6,18 @@ use anyhow::Context;
|
|||
use std::{path::Path, path::PathBuf, str::FromStr};
|
||||
|
||||
/// Wrapper around [std::env::var] which adds [anyhow] context around errors.
|
||||
#[inline]
|
||||
pub fn get_var(name: &str) -> anyhow::Result<String> {
|
||||
std::env::var(name).with_context(|| format!("Missing ${name} environment variable"))
|
||||
}
|
||||
|
||||
/// Reads an environment variable containing a directory path,
|
||||
/// creating the directory if it doesn't exist.
|
||||
pub fn get_env_dir_path(name: &str) -> anyhow::Result<PathBuf> {
|
||||
let var = get_var(name)?;
|
||||
pub fn get_env_dir_path(name: &str, default_to: Option<&str>) -> anyhow::Result<PathBuf> {
|
||||
let var = get_var(name);
|
||||
let var = match default_to {
|
||||
None => var?,
|
||||
Some(other) => var.or(get_var(other))?,
|
||||
};
|
||||
|
||||
let path = PathBuf::from_str(&var).with_context(|| format!("${name} is not a valid path"))?;
|
||||
|
||||
|
@ -36,6 +39,9 @@ pub struct ShimmeringPaths {
|
|||
|
||||
/// This directory contains logs and other debugging info.
|
||||
log_dir: PathBuf,
|
||||
|
||||
/// This location the source-code resides at
|
||||
source_dir: PathBuf,
|
||||
}
|
||||
|
||||
impl ShimmeringPaths {
|
||||
|
@ -43,43 +49,58 @@ impl ShimmeringPaths {
|
|||
/// creating every involved directory in the process.
|
||||
pub fn new() -> anyhow::Result<Self> {
|
||||
let res = Self {
|
||||
data_dir: get_env_dir_path("SHIMMERING_DATA_DIR")?,
|
||||
private_config_dir: get_env_dir_path("SHIMMERING_PRIVATE_CONFIG_DIR")?,
|
||||
log_dir: get_env_dir_path("SHIMMERING_LOG_DIR")?,
|
||||
data_dir: get_env_dir_path("SHIMMERING_DATA_DIR", Some("STATE_DIRECTORY"))?,
|
||||
log_dir: get_env_dir_path("SHIMMERING_LOG_DIR", Some("LOGS_DIRECTORY"))?,
|
||||
private_config_dir: get_env_dir_path("SHIMMERING_PRIVATE_CONFIG_DIR", None)?,
|
||||
source_dir: PathBuf::from_str(env!("SHIMMERING_SOURCE_DIR")).unwrap(),
|
||||
};
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn data_dir(&self) -> &PathBuf {
|
||||
&self.data_dir
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn log_dir(&self) -> &PathBuf {
|
||||
&self.log_dir
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn db_path(&self) -> PathBuf {
|
||||
self.data_dir.join("db.sqlite")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn jackets_path(&self) -> PathBuf {
|
||||
self.data_dir.join("jackets")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn recognition_matrix_path(&self) -> PathBuf {
|
||||
self.data_dir.join("recognition_matrix")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn raw_jackets_path(&self) -> PathBuf {
|
||||
self.private_config_dir.join("jackets")
|
||||
}
|
||||
|
||||
pub fn songlist_path(&self) -> PathBuf {
|
||||
self.private_config_dir.join("songlist.json")
|
||||
}
|
||||
|
||||
pub fn scripts_dir(&self) -> PathBuf {
|
||||
self.source_dir.join("scripts")
|
||||
}
|
||||
|
||||
pub fn config_dir(&self) -> PathBuf {
|
||||
self.source_dir.join("config")
|
||||
}
|
||||
|
||||
pub fn notecount_path(&self) -> PathBuf {
|
||||
self.config_dir().join("notecounts.csv")
|
||||
}
|
||||
|
||||
pub fn cc_data_path(&self) -> PathBuf {
|
||||
PathBuf::from_str(concat!(env!("SHIMMERING_CC_DIR"), "/ptt.json")).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensures an empty directory exists at a given path,
|
||||
|
|
|
@ -13,7 +13,6 @@ use crate::arcaea::jacket::{
|
|||
JACKET_RECOGNITITION_DIMENSIONS,
|
||||
};
|
||||
use crate::context::paths::create_empty_directory;
|
||||
use crate::recognition::fuzzy_song_name::guess_chart_name;
|
||||
|
||||
use super::paths::ShimmeringPaths;
|
||||
// }}}
|
||||
|
@ -68,17 +67,25 @@ pub fn process_jackets(paths: &ShimmeringPaths, conn: &rusqlite::Connection) ->
|
|||
let entries = fs::read_dir(dir.path())
|
||||
.with_context(|| "Couldn't read song directory")?
|
||||
.map(|f| f.unwrap())
|
||||
.filter(|f| !f.file_name().to_str().unwrap().ends_with("_256.jpg"))
|
||||
.filter(|f| f.file_name().to_str().unwrap().ends_with(".jpg"))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
for file in &entries {
|
||||
let raw_name = file.file_name();
|
||||
let name = raw_name
|
||||
let mut name = raw_name
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.strip_suffix(".jpg")
|
||||
.ok_or_else(|| anyhow!("No '.jpg' suffix to remove from filename {raw_name:?}"))?;
|
||||
|
||||
if name.starts_with("1080_") {
|
||||
name = name.strip_prefix("1080_").unwrap();
|
||||
}
|
||||
|
||||
if name.ends_with("_256") {
|
||||
name = name.strip_suffix("_256").unwrap();
|
||||
}
|
||||
|
||||
let difficulty = match name {
|
||||
"0" => Some(Difficulty::PST),
|
||||
"1" => Some(Difficulty::PRS),
|
||||
|
@ -91,8 +98,20 @@ pub fn process_jackets(paths: &ShimmeringPaths, conn: &rusqlite::Connection) ->
|
|||
_ => bail!("Unknown jacket suffix {}", name),
|
||||
};
|
||||
|
||||
let (song, _) = guess_chart_name(dir_name, &song_cache, difficulty, true)
|
||||
.with_context(|| format!("Could not recognise chart name from '{dir_name}'"))?;
|
||||
let song = song_cache.songs.iter().find_map(|cached_song| {
|
||||
let song = &cached_song.as_ref()?.song;
|
||||
if song.shorthand == dir_name {
|
||||
Some(song)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
let song = if let Some(song) = song {
|
||||
song
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
writeln!(debug_name_mapping, "{dir_name} -> {}", song.title)?;
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#![allow(async_fn_in_trait)]
|
||||
#![allow(clippy::needless_range_loop)]
|
||||
#![allow(clippy::redundant_closure)]
|
||||
#![allow(clippy::redundant_closure_call)]
|
||||
// This sometimes triggers for rationals, where it doesn't make sense
|
||||
#![allow(clippy::int_plus_one)]
|
||||
|
||||
|
@ -11,6 +12,7 @@ pub mod commands;
|
|||
pub mod context;
|
||||
mod levenshtein;
|
||||
pub mod logs;
|
||||
pub mod private_server;
|
||||
pub mod recognition;
|
||||
pub mod time;
|
||||
pub mod transform;
|
||||
|
|
|
@ -21,7 +21,7 @@ fn should_save_debug_images() -> bool {
|
|||
|
||||
#[inline]
|
||||
fn get_log_dir() -> PathBuf {
|
||||
get_env_dir_path("SHIMMERING_LOG_DIR").unwrap()
|
||||
get_env_dir_path("SHIMMERING_LOG_DIR", "LOGS_DIRECTORY").unwrap()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
246
src/private_server/mod.rs
Normal file
|
@ -0,0 +1,246 @@
|
|||
use anyhow::{anyhow, Context};
|
||||
use base64::{prelude::BASE64_URL_SAFE_NO_PAD, Engine};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
arcaea::{
|
||||
chart::Difficulty,
|
||||
play::{Play, ScoreCollection},
|
||||
score::Score,
|
||||
},
|
||||
context::{ErrorKind, TagError, TaggedError, UserContext},
|
||||
user::User,
|
||||
};
|
||||
|
||||
// {{{ Generic response types
|
||||
#[derive(Deserialize)]
|
||||
#[serde(untagged)]
|
||||
enum MaybeData<T> {
|
||||
SomeData(T),
|
||||
NoData {},
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct PrivateServerResult<T> {
|
||||
code: i32,
|
||||
msg: String,
|
||||
data: MaybeData<T>,
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ User query types
|
||||
#[derive(Serialize, Default)]
|
||||
pub struct UsersQuery<'a> {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub name: Option<&'a str>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub user_id: Option<u32>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Default)]
|
||||
pub struct UsersQueryOptions<'a> {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub query: Option<UsersQuery<'a>>,
|
||||
}
|
||||
// }}}
|
||||
// {{{ User response types
|
||||
#[derive(Deserialize)]
|
||||
pub struct RawUser {
|
||||
pub user_id: u32,
|
||||
pub user_code: String,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ Best score query types
|
||||
#[derive(Serialize)]
|
||||
pub struct BestScoreQuery<'a> {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub song_id: Option<&'a str>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub difficulty: Option<u8>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Default)]
|
||||
pub struct BestOptions<'a> {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub query: Option<BestScoreQuery<'a>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub limit: Option<u32>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub offset: Option<u32>,
|
||||
}
|
||||
// }}}
|
||||
// {{{ Best score response types
|
||||
#[allow(dead_code)]
|
||||
#[derive(Deserialize)]
|
||||
struct RawBestScore {
|
||||
best_clear_type: u8,
|
||||
clear_type: u8,
|
||||
difficulty: u8,
|
||||
health: i8,
|
||||
modifier: u8, // wtf is this?
|
||||
|
||||
miss_count: u16,
|
||||
near_count: u16,
|
||||
perfect_count: u16,
|
||||
shiny_perfect_count: u16,
|
||||
|
||||
rating: f32,
|
||||
score: u32,
|
||||
song_id: String,
|
||||
time_played: i64,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct RawBestScores {
|
||||
data: Vec<RawBestScore>,
|
||||
|
||||
#[allow(unused)]
|
||||
user_id: u32,
|
||||
}
|
||||
// }}}
|
||||
// {{{ Helpers
|
||||
pub fn api_url() -> Result<String, TaggedError> {
|
||||
std::env::var("SHIMMERING_PRIVATE_SERVER_URL").map_err(|_| {
|
||||
anyhow!("This instance of `shimmeringmoon` is not connected to a private server.")
|
||||
.tag(ErrorKind::User)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn encode_difficulty(difficulty: Difficulty) -> u8 {
|
||||
match difficulty {
|
||||
Difficulty::PST => 0,
|
||||
Difficulty::PRS => 1,
|
||||
Difficulty::FTR => 2,
|
||||
Difficulty::BYD => 3,
|
||||
Difficulty::ETR => 4,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn decode_difficulty(difficulty: u8) -> Option<Difficulty> {
|
||||
match difficulty {
|
||||
0 => Some(Difficulty::PST),
|
||||
1 => Some(Difficulty::PRS),
|
||||
2 => Some(Difficulty::FTR),
|
||||
3 => Some(Difficulty::BYD),
|
||||
4 => Some(Difficulty::ETR),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
// }}}
|
||||
// {{{ Perform best score request
|
||||
pub async fn best(
|
||||
ctx: &UserContext,
|
||||
user: &User,
|
||||
options: BestOptions<'_>,
|
||||
) -> Result<Vec<Play>, TaggedError> {
|
||||
let url = api_url()?;
|
||||
let token = std::env::var("SHIMMERING_PRIVATE_SERVER_TOKEN")
|
||||
.map_err(|_| anyhow!("No api token found"))?;
|
||||
|
||||
let private_user_id = user.private_server_id.ok_or_else(|| {
|
||||
anyhow!("This account is not bound to any private server account").tag(ErrorKind::User)
|
||||
})?;
|
||||
|
||||
let mut query_param = BASE64_URL_SAFE_NO_PAD.encode(serde_json::to_string(&options)?);
|
||||
query_param.push_str("=="); // Maximum padding, as otherwise python screams at me
|
||||
|
||||
let decoded = ctx
|
||||
.http_client
|
||||
.get(format!("{url}/api/v1/users/{}/best", private_user_id))
|
||||
.query(&[("query", query_param)])
|
||||
.header("Token", token)
|
||||
.send()
|
||||
.await
|
||||
.context("Failed to send request")?
|
||||
.error_for_status()
|
||||
.context("Request has non-ok status")?
|
||||
.json::<PrivateServerResult<RawBestScores>>()
|
||||
.await
|
||||
.context("Failed to decode response")?;
|
||||
|
||||
let decoded = if let (true, MaybeData::SomeData(inner)) = (decoded.code == 0, decoded.data) {
|
||||
inner
|
||||
} else {
|
||||
return Err(
|
||||
anyhow!("The server return an error: \"{}\"", decoded.msg).tag(ErrorKind::Internal)
|
||||
);
|
||||
};
|
||||
|
||||
let plays = decoded
|
||||
.data
|
||||
.iter()
|
||||
.filter(|raw_play| raw_play.health >= 0 && raw_play.rating > 0.0)
|
||||
.map(|raw_play| -> Result<Play, TaggedError> {
|
||||
let chart = ctx
|
||||
.song_cache
|
||||
.charts()
|
||||
.find(|chart| {
|
||||
let Some(cached_song) = ctx.song_cache.lookup_song(chart.song_id).ok() else {
|
||||
return false;
|
||||
};
|
||||
|
||||
cached_song.song.shorthand == raw_play.song_id
|
||||
&& raw_play.difficulty == encode_difficulty(chart.difficulty)
|
||||
})
|
||||
.ok_or_else(|| {
|
||||
anyhow!("The server returned an unknown song: {}", raw_play.song_id)
|
||||
.tag(ErrorKind::User)
|
||||
})?;
|
||||
|
||||
Ok(Play {
|
||||
id: 0, // External
|
||||
created_at: chrono::DateTime::from_timestamp(raw_play.time_played, 0)
|
||||
.unwrap()
|
||||
.naive_utc(),
|
||||
scores: ScoreCollection::from_standard_score(Score(raw_play.score), chart),
|
||||
chart_id: chart.id,
|
||||
user_id: user.id,
|
||||
far_notes: Some(raw_play.near_count as u32),
|
||||
max_recall: None,
|
||||
})
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
Ok(plays)
|
||||
}
|
||||
// }}}
|
||||
// {{{ Find usesr
|
||||
pub async fn users(
|
||||
ctx: &UserContext,
|
||||
options: UsersQueryOptions<'_>,
|
||||
) -> Result<Vec<RawUser>, TaggedError> {
|
||||
let url = api_url()?;
|
||||
let token = std::env::var("SHIMMERING_PRIVATE_SERVER_TOKEN")
|
||||
.map_err(|_| anyhow!("No api token found"))?;
|
||||
|
||||
let mut query_param = BASE64_URL_SAFE_NO_PAD.encode(serde_json::to_string(&options)?);
|
||||
query_param.push_str("=="); // Maximum padding, as otherwise python screams at me
|
||||
|
||||
let decoded = ctx
|
||||
.http_client
|
||||
.get(format!("{url}/api/v1/users"))
|
||||
.query(&[("query", query_param)])
|
||||
.header("Token", token)
|
||||
.send()
|
||||
.await
|
||||
.context("Failed to send request")?
|
||||
.error_for_status()
|
||||
.context("Request has non-ok status")?
|
||||
.json::<PrivateServerResult<Vec<RawUser>>>()
|
||||
.await
|
||||
.context("Failed to decode response")?;
|
||||
|
||||
let decoded = if let (true, MaybeData::SomeData(inner)) = (decoded.code == 0, decoded.data) {
|
||||
inner
|
||||
} else {
|
||||
return Err(
|
||||
anyhow!("The server return an error: \"{}\"", decoded.msg).tag(ErrorKind::Internal)
|
||||
);
|
||||
};
|
||||
|
||||
Ok(decoded)
|
||||
}
|
||||
// }}}
|
|
@ -97,7 +97,11 @@ pub fn guess_chart_name<'a>(
|
|||
return None;
|
||||
}
|
||||
|
||||
let song_title = &song.lowercase_title;
|
||||
let mut song_title = &song.lowercase_title;
|
||||
if let Some(chart_title) = &chart.lowercase_title {
|
||||
song_title = chart_title;
|
||||
}
|
||||
|
||||
distance_vec.clear();
|
||||
|
||||
// Apply raw distance
|
||||
|
@ -118,15 +122,10 @@ pub fn guess_chart_name<'a>(
|
|||
}
|
||||
|
||||
// Shorthand-based matching
|
||||
if let Some(shorthand) = &chart.shorthand {
|
||||
if unsafe_heuristics {
|
||||
let short_distance =
|
||||
edit_distance_with(text, shorthand, &mut levenshtein_vec);
|
||||
|
||||
if short_distance <= shorthand.len() / 3 {
|
||||
distance_vec.push(short_distance * 10 + 1);
|
||||
}
|
||||
}
|
||||
let short_distance =
|
||||
edit_distance_with(text, &song.shorthand, &mut levenshtein_vec);
|
||||
if short_distance <= song.shorthand.len() / 3 {
|
||||
distance_vec.push(short_distance * 10 + 1);
|
||||
}
|
||||
|
||||
distance_vec
|
||||
|
|
|
@ -201,7 +201,7 @@ impl ComponentsWithBounds {
|
|||
|
||||
// {{{ Remove components that are too large
|
||||
for bound in &mut bounds {
|
||||
if bound.map_or(false, |b| {
|
||||
if bound.is_some_and(|b| {
|
||||
(b.x_max - b.x_min) as f32 >= max_sizes.0 * image.width() as f32
|
||||
|| (b.y_max - b.y_min) as f32 >= max_sizes.1 * image.height() as f32
|
||||
}) {
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
use std::fmt::Display;
|
||||
|
||||
use anyhow::{anyhow, bail};
|
||||
use hypertesseract::{PageSegMode, Tesseract};
|
||||
use image::imageops::FilterType;
|
||||
use image::{DynamicImage, GenericImageView};
|
||||
use num::integer::Roots;
|
||||
|
@ -17,7 +16,6 @@ use crate::commands::discord::MessageContext;
|
|||
use crate::context::{Error, UserContext};
|
||||
use crate::levenshtein::edit_distance;
|
||||
use crate::logs::debug_image_log;
|
||||
use crate::recognition::fuzzy_song_name::guess_chart_name;
|
||||
use crate::recognition::ui::{
|
||||
ScoreScreenRect, SongSelectRect, UIMeasurementRect, UIMeasurementRect::*,
|
||||
};
|
||||
|
@ -162,7 +160,7 @@ impl ImageAnalyzer {
|
|||
);
|
||||
|
||||
// Discard scores if it's impossible
|
||||
let valid_analysis = note_count.map_or(true, |note_count| {
|
||||
let valid_analysis = note_count.is_none_or(|note_count| {
|
||||
let (zeta, shinies, score_units) = result.analyse(note_count);
|
||||
8_000_000 <= zeta.0
|
||||
&& zeta.0 <= 10_000_000
|
||||
|
@ -256,35 +254,6 @@ impl ImageAnalyzer {
|
|||
Ok(result)
|
||||
}
|
||||
// }}}
|
||||
// {{{ Read song
|
||||
pub fn read_song<'a>(
|
||||
&mut self,
|
||||
ctx: &'a UserContext,
|
||||
image: &DynamicImage,
|
||||
difficulty: Difficulty,
|
||||
) -> Result<(&'a Song, &'a Chart), Error> {
|
||||
let (text, conf) = Tesseract::builder()
|
||||
.language(hypertesseract::Language::English)
|
||||
.page_seg_mode(PageSegMode::SingleLine)
|
||||
.whitelist_str("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,.()- ")?
|
||||
.build()?
|
||||
.recognize_text_cloned_with_conf(
|
||||
&self
|
||||
.interp_crop(ctx, image, ScoreScreen(ScoreScreenRect::Title))?
|
||||
.into_rgba8(),
|
||||
)?;
|
||||
|
||||
if conf < 20 && conf != 0 {
|
||||
bail!(
|
||||
"Title text is not readable (confidence = {}, text = {}).",
|
||||
conf,
|
||||
text.trim()
|
||||
);
|
||||
}
|
||||
|
||||
guess_chart_name(&text, &ctx.song_cache, Some(difficulty), false)
|
||||
}
|
||||
// }}}
|
||||
// {{{ Read jacket
|
||||
pub fn read_jacket<'a>(
|
||||
&mut self,
|
||||
|
|
|
@ -100,7 +100,8 @@ impl UIMeasurements {
|
|||
let mut measurements = Vec::new();
|
||||
let mut measurement = UIMeasurement::default();
|
||||
|
||||
const CONTENTS: &str = include_str!(concat!(env!("SHIMMERING_CONFIG_DIR"), "/ui.txt"));
|
||||
const CONTENTS: &str =
|
||||
include_str!(concat!(env!("SHIMMERING_SOURCE_DIR"), "/config/ui.txt"));
|
||||
|
||||
// {{{ Parse measurement file
|
||||
for (i, line) in CONTENTS.split('\n').enumerate() {
|
||||
|
|
40
src/user.rs
|
@ -4,11 +4,13 @@ use rusqlite::Row;
|
|||
use crate::commands::discord::MessageContext;
|
||||
use crate::context::{ErrorKind, TagError, TaggedError, UserContext};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct User {
|
||||
pub id: u32,
|
||||
pub private_server_id: Option<u32>,
|
||||
pub discord_id: String,
|
||||
pub is_pookie: bool,
|
||||
pub is_admin: bool,
|
||||
}
|
||||
|
||||
impl User {
|
||||
|
@ -16,8 +18,10 @@ impl User {
|
|||
fn from_row(row: &Row<'_>) -> Result<Self, rusqlite::Error> {
|
||||
Ok(Self {
|
||||
id: row.get("id")?,
|
||||
private_server_id: row.get("private_server_id")?,
|
||||
discord_id: row.get("discord_id")?,
|
||||
is_pookie: row.get("is_pookie")?,
|
||||
is_admin: row.get("is_admin")?,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -39,8 +43,10 @@ impl User {
|
|||
|
||||
Ok(Self {
|
||||
discord_id,
|
||||
private_server_id: None,
|
||||
id: user_id,
|
||||
is_pookie: false,
|
||||
is_admin: false,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -54,7 +60,7 @@ impl User {
|
|||
.query_map([id], Self::from_row)?
|
||||
.next()
|
||||
.ok_or_else(|| {
|
||||
anyhow!("You are not an user in my database, sowwy ^~^").tag(ErrorKind::User)
|
||||
anyhow!("You are not an user in my database, sowwy ^~^. Please ask someone on my pookie list to let you in.").tag(ErrorKind::User)
|
||||
})??;
|
||||
|
||||
Ok(user)
|
||||
|
@ -74,9 +80,26 @@ impl User {
|
|||
Ok(user)
|
||||
}
|
||||
|
||||
pub fn by_discord_id(
|
||||
ctx: &UserContext,
|
||||
id: poise::serenity_prelude::UserId,
|
||||
) -> Result<Self, TaggedError> {
|
||||
let user = ctx
|
||||
.db
|
||||
.get()?
|
||||
.prepare_cached("SELECT * FROM users WHERE discord_id = ?")?
|
||||
.query_map([id.to_string()], Self::from_row)?
|
||||
.next()
|
||||
.ok_or_else(|| {
|
||||
anyhow!("This person is not in my database, sowwy ^~^").tag(ErrorKind::User)
|
||||
})??;
|
||||
|
||||
Ok(user)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn assert_is_pookie(&self) -> Result<(), TaggedError> {
|
||||
if !self.is_pookie {
|
||||
if !self.is_pookie && !self.is_admin {
|
||||
return Err(
|
||||
anyhow!("This feature is reserved for my pookies. Sowwy :3").tag(ErrorKind::User)
|
||||
);
|
||||
|
@ -84,4 +107,15 @@ impl User {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn assert_is_admin(&self) -> Result<(), TaggedError> {
|
||||
if !self.is_admin {
|
||||
return Err(
|
||||
anyhow!("This feature is reserved for admins. Sowwy :3").tag(ErrorKind::User)
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,3 +18,12 @@ macro_rules! try_block {
|
|||
}))()
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! async_try_block {
|
||||
{ $($token:tt)* } => {
|
||||
(async || $crate::wrap_ok!({
|
||||
$($token)*
|
||||
}))().await
|
||||
}
|
||||
}
|
||||
|
|