From 105c9796bd5eacc5dcef33e9709407abdc3968e2 Mon Sep 17 00:00:00 2001 From: Kirito Date: Tue, 25 May 2021 13:07:44 +0900 Subject: [PATCH] saucer fulfill support --- jubeat@asphyxia/README.md | 7 +- jubeat@asphyxia/data/fulfill_courses.json | 1624 +++++++++++++++++ jubeat@asphyxia/handlers/common.ts | 32 +- jubeat@asphyxia/handlers/profile.ts | 125 +- jubeat@asphyxia/index.ts | 53 +- jubeat@asphyxia/models/course.ts | 9 + jubeat@asphyxia/models/profile.ts | 44 + .../templates/gameInfos/fulfill.ts | 28 + jubeat@asphyxia/templates/profiles/fulfill.ts | 117 ++ 9 files changed, 1997 insertions(+), 42 deletions(-) create mode 100644 jubeat@asphyxia/data/fulfill_courses.json create mode 100644 jubeat@asphyxia/models/course.ts create mode 100644 jubeat@asphyxia/templates/gameInfos/fulfill.ts create mode 100644 jubeat@asphyxia/templates/profiles/fulfill.ts diff --git a/jubeat@asphyxia/README.md b/jubeat@asphyxia/README.md index 72a87a4..418a4a3 100644 --- a/jubeat@asphyxia/README.md +++ b/jubeat@asphyxia/README.md @@ -1,6 +1,6 @@ # Jubeat -Plugin Version: **v1.4.1** +Plugin Version: **v1.5.0** ### Supported Versions @@ -11,11 +11,16 @@ Plugin Version: **v1.4.1** - copious - copious APPEND - saucer +- saucer fulfill ### Changelogs *** +#### 1.5.0 + +- saucer fulfill support + #### 1.4.1 - saucer support diff --git a/jubeat@asphyxia/data/fulfill_courses.json b/jubeat@asphyxia/data/fulfill_courses.json new file mode 100644 index 0000000..49a810b --- /dev/null +++ b/jubeat@asphyxia/data/fulfill_courses.json @@ -0,0 +1,1624 @@ +{ + "courses": [ + { + "course_id": 1, + "course_name": "溢れ出した記憶、特別なあなたにありがとう。", + "course_level": 1, + "norma": { + "norma_id": [ + 1, + 2, + 0 + ], + "bronze": [ + 850000, + 0, + 0 + ], + "silver": [ + 900000, + 1, + 0 + ], + "gold": [ + 950000, + 2, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 50000241, + "seq_id": 2 + }, + { + "index": 1, + "music_id": 10000052, + "seq_id": 2 + }, + { + "index": 2, + "music_id": 30000042, + "seq_id": 2 + }, + { + "index": 3, + "music_id": 50000085, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 50000144, + "seq_id": 2 + } + ] + }, + { + "course_id": 2, + "course_name": "コースモードが怖い?ばっかお前TAGがついてるだろ", + "course_level": 1, + "norma": { + "norma_id": [ + 1, + 2, + 0 + ], + "bronze": [ + 800000, + 0, + 0 + ], + "silver": [ + 850000, + 1, + 0 + ], + "gold": [ + 900000, + 2, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 50000121, + "seq_id": 1 + }, + { + "index": 1, + "music_id": 30000122, + "seq_id": 1 + }, + { + "index": 2, + "music_id": 40000159, + "seq_id": 1 + }, + { + "index": 3, + "music_id": 50000089, + "seq_id": 1 + }, + { + "index": 4, + "music_id": 40000051, + "seq_id": 2 + } + ] + }, + { + "course_id": 3, + "course_name": "満月の鐘踊り響くは虚空から成る恋の歌", + "course_level": 2, + "norma": { + "norma_id": [ + 1, + 2, + 0 + ], + "bronze": [ + 850000, + 1, + 0 + ], + "silver": [ + 900000, + 2, + 0 + ], + "gold": [ + 950000, + 3, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 40000121, + "seq_id": 2 + }, + { + "index": 1, + "music_id": 50000188, + "seq_id": 2 + }, + { + "index": 2, + "music_id": 30000047, + "seq_id": 2 + }, + { + "index": 3, + "music_id": 50000237, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 50000176, + "seq_id": 2 + } + ] + }, + { + "course_id": 4, + "course_name": "スミスゼミナール 夏の陣開講記念 基本編", + "course_level": 2, + "norma": { + "norma_id": [ + 3, + 2, + 0 + ], + "bronze": [ + 85, + 1, + 0 + ], + "silver": [ + 90, + 2, + 0 + ], + "gold": [ + 95, + 3, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 50000267, + "seq_id": 1 + }, + { + "index": 1, + "music_id": 50000233, + "seq_id": 1 + }, + { + "index": 2, + "music_id": 50000228, + "seq_id": 1 + }, + { + "index": 3, + "music_id": 50000268, + "seq_id": 1 + }, + { + "index": 4, + "music_id": 50000291, + "seq_id": 1 + } + ] + }, + { + "course_id": 5, + "course_name": "HARDモードじゃないから、絶対、大丈夫だよっ!", + "course_level": 2, + "norma": { + "norma_id": [ + 1, + 2, + 0 + ], + "bronze": [ + 850000, + 0, + 0 + ], + "silver": [ + 900000, + 1, + 0 + ], + "gold": [ + 950000, + 3, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 50000144, + "seq_id": 2 + }, + { + "index": 1, + "music_id": 50000188, + "seq_id": 2 + }, + { + "index": 2, + "music_id": 50000070, + "seq_id": 2 + }, + { + "index": 3, + "music_id": 50000151, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 50000152, + "seq_id": 2 + } + ] + }, + { + "course_id": 6, + "course_name": "星明かりの下、愛という名の日替わりランチを君と", + "course_level": 3, + "norma": { + "norma_id": [ + 3, + 0, + 0 + ], + "bronze": [ + 70, + 0, + 0 + ], + "silver": [ + 80, + 0, + 0 + ], + "gold": [ + 90, + 0, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 50000196, + "seq_id": 1 + }, + { + "index": 1, + "music_id": 50000151, + "seq_id": 2 + }, + { + "index": 2, + "music_id": 50000060, + "seq_id": 1 + }, + { + "index": 3, + "music_id": 40000048, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 10000051, + "seq_id": 2 + } + ] + }, + { + "course_id": 7, + "course_name": "輝く北極星と幸せなヒーロー", + "course_level": 4, + "norma": { + "norma_id": [ + 1, + 2, + 0 + ], + "bronze": [ + 900000, + 1, + 0 + ], + "silver": [ + 950000, + 2, + 0 + ], + "gold": [ + 980000, + 3, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 50000079, + "seq_id": 2 + }, + { + "index": 1, + "music_id": 20000044, + "seq_id": 2 + }, + { + "index": 2, + "music_id": 50000109, + "seq_id": 2 + }, + { + "index": 3, + "music_id": 10000043, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 10000042, + "seq_id": 2 + } + ] + }, + { + "course_id": 8, + "course_name": "花-鳥-藻-夏", + "course_level": 4, + "norma": { + "norma_id": [ + 3, + 0, + 0 + ], + "bronze": [ + 70, + 0, + 0 + ], + "silver": [ + 80, + 0, + 0 + ], + "gold": [ + 90, + 0, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 10000068, + "seq_id": 2 + }, + { + "index": 1, + "music_id": 40000154, + "seq_id": 2 + }, + { + "index": 2, + "music_id": 50000123, + "seq_id": 1 + }, + { + "index": 3, + "music_id": 40000051, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 30000045, + "seq_id": 2 + } + ] + }, + { + "course_id": 9, + "course_name": "TAG生誕祭2014 俺の記録を抜いてみろ!", + "course_level": 4, + "norma": { + "norma_id": [ + 1, + 2, + 0 + ], + "bronze": [ + 900000, + 0, + 0 + ], + "silver": [ + 950000, + 0, + 0 + ], + "gold": [ + 967252, + 1, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 30000122, + "seq_id": 2 + }, + { + "index": 1, + "music_id": 50000086, + "seq_id": 2 + }, + { + "index": 2, + "music_id": 50000121, + "seq_id": 2 + }, + { + "index": 3, + "music_id": 50000196, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 40000051, + "seq_id": 2 + } + ] + }, + { + "course_id": 10, + "course_name": "さよなら、亡くした恋と蝶の舞うヒストリア", + "course_level": 5, + "norma": { + "norma_id": [ + 3, + 0, + 0 + ], + "bronze": [ + 80, + 0, + 0 + ], + "silver": [ + 85, + 0, + 0 + ], + "gold": [ + 90, + 0, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 20000041, + "seq_id": 2 + }, + { + "index": 1, + "music_id": 30000044, + "seq_id": 2 + }, + { + "index": 2, + "music_id": 50000037, + "seq_id": 2 + }, + { + "index": 3, + "music_id": 20000124, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 50000033, + "seq_id": 2 + } + ] + }, + { + "course_id": 11, + "course_name": "きらきらほしふるまぼろしなぎさちゃん", + "course_level": 5, + "norma": { + "norma_id": [ + 4, + 1, + 0 + ], + "bronze": [ + 0, + 700000, + 0 + ], + "silver": [ + 0, + 800000, + 0 + ], + "gold": [ + 0, + 900000, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 30000050, + "seq_id": 2 + }, + { + "index": 1, + "music_id": 30000049, + "seq_id": 2 + }, + { + "index": 2, + "music_id": 50000235, + "seq_id": 2 + }, + { + "index": 3, + "music_id": 50000157, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 50000038, + "seq_id": 2 + } + ] + }, + { + "course_id": 12, + "course_name": "The Memorial Third: 僕みたいに演奏してね", + "course_level": 5, + "norma": { + "norma_id": [ + 3, + 0, + 0 + ], + "bronze": [ + 75, + 0, + 0 + ], + "silver": [ + 80, + 0, + 0 + ], + "gold": [ + 85, + 0, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 10000037, + "seq_id": 2 + }, + { + "index": 1, + "music_id": 20000048, + "seq_id": 1 + }, + { + "index": 2, + "music_id": 50000253, + "seq_id": 1 + }, + { + "index": 3, + "music_id": 20000121, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 50000133, + "seq_id": 2 + } + ] + }, + { + "course_id": 13, + "course_name": "Enjoy! 4thKAC ~Memories of saucer~", + "course_level": 5, + "norma": { + "norma_id": [ + 1, + 2, + 0 + ], + "bronze": [ + 900000, + 1, + 0 + ], + "silver": [ + 950000, + 2, + 0 + ], + "gold": [ + 980000, + 4, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 50000206, + "seq_id": 1 + }, + { + "index": 1, + "music_id": 50000023, + "seq_id": 1 + }, + { + "index": 2, + "music_id": 50000078, + "seq_id": 1 + }, + { + "index": 3, + "music_id": 50000203, + "seq_id": 1 + }, + { + "index": 4, + "music_id": 50000323, + "seq_id": 1 + } + ] + }, + { + "course_id": 14, + "course_name": "風に吹かれるキケンなシロクマダンス", + "course_level": 6, + "norma": { + "norma_id": [ + 1, + 2, + 0 + ], + "bronze": [ + 900000, + 1, + 0 + ], + "silver": [ + 950000, + 2, + 0 + ], + "gold": [ + 980000, + 3, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 50000059, + "seq_id": 2 + }, + { + "index": 1, + "music_id": 50000197, + "seq_id": 2 + }, + { + "index": 2, + "music_id": 30000037, + "seq_id": 2 + }, + { + "index": 3, + "music_id": 50000182, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 20000038, + "seq_id": 2 + } + ] + }, + { + "course_id": 15, + "course_name": "君主は視線で友との愛を語るめう", + "course_level": 6, + "norma": { + "norma_id": [ + 3, + 0, + 0 + ], + "bronze": [ + 85, + 0, + 0 + ], + "silver": [ + 90, + 0, + 0 + ], + "gold": [ + 95, + 0, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 40000052, + "seq_id": 2 + }, + { + "index": 1, + "music_id": 50000152, + "seq_id": 2 + }, + { + "index": 2, + "music_id": 50000090, + "seq_id": 2 + }, + { + "index": 3, + "music_id": 20000040, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 50000184, + "seq_id": 2 + } + ] + }, + { + "course_id": 16, + "course_name": "スミスゼミナール 夏の陣開講記念 応用編", + "course_level": 6, + "norma": { + "norma_id": [ + 4, + 1, + 0 + ], + "bronze": [ + 0, + 750000, + 0 + ], + "silver": [ + 0, + 850000, + 0 + ], + "gold": [ + 0, + 900000, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 50000233, + "seq_id": 2 + }, + { + "index": 1, + "music_id": 50000267, + "seq_id": 2 + }, + { + "index": 2, + "music_id": 50000268, + "seq_id": 2 + }, + { + "index": 3, + "music_id": 50000228, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 50000291, + "seq_id": 2 + } + ] + }, + { + "course_id": 17, + "course_name": "天から降り注ぐ星はまるで甘いキャンディ", + "course_level": 7, + "norma": { + "norma_id": [ + 3, + 0, + 0 + ], + "bronze": [ + 85, + 0, + 0 + ], + "silver": [ + 90, + 0, + 0 + ], + "gold": [ + 95, + 0, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 20000044, + "seq_id": 2 + }, + { + "index": 1, + "music_id": 30000050, + "seq_id": 2 + }, + { + "index": 2, + "music_id": 50000080, + "seq_id": 2 + }, + { + "index": 3, + "music_id": 40000126, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 10000067, + "seq_id": 2 + } + ] + }, + { + "course_id": 18, + "course_name": "てんとう虫が囁いている「Wow Wow…」", + "course_level": 7, + "norma": { + "norma_id": [ + 3, + 0, + 0 + ], + "bronze": [ + 85, + 0, + 0 + ], + "silver": [ + 90, + 0, + 0 + ], + "gold": [ + 95, + 0, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 50000132, + "seq_id": 2 + }, + { + "index": 1, + "music_id": 40000128, + "seq_id": 2 + }, + { + "index": 2, + "music_id": 10000036, + "seq_id": 2 + }, + { + "index": 3, + "music_id": 50000119, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 50000030, + "seq_id": 2 + } + ] + }, + { + "course_id": 19, + "course_name": "HARDモードでも大丈夫だよ!絶対、大丈夫だよっ!", + "course_level": 7, + "norma": { + "norma_id": [ + 4, + 1, + 0 + ], + "bronze": [ + 0, + 850000, + 0 + ], + "silver": [ + 0, + 900000, + 0 + ], + "gold": [ + 0, + 950000, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 50000144, + "seq_id": 2 + }, + { + "index": 1, + "music_id": 50000070, + "seq_id": 2 + }, + { + "index": 2, + "music_id": 50000188, + "seq_id": 2 + }, + { + "index": 3, + "music_id": 50000151, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 50000152, + "seq_id": 2 + } + ] + }, + { + "course_id": 20, + "course_name": "こんなHARDモード、滅べばいい…", + "course_level": 7, + "norma": { + "norma_id": [ + 4, + 1, + 0 + ], + "bronze": [ + 0, + 850000, + 0 + ], + "silver": [ + 0, + 900000, + 0 + ], + "gold": [ + 0, + 950000, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 50000294, + "seq_id": 2 + }, + { + "index": 1, + "music_id": 50000295, + "seq_id": 2 + }, + { + "index": 2, + "music_id": 50000234, + "seq_id": 2 + }, + { + "index": 3, + "music_id": 50000245, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 50000282, + "seq_id": 2 + } + ] + }, + { + "course_id": 21, + "course_name": "Challenge! 4thKAC ~Memories of saucer~", + "course_level": 7, + "norma": { + "norma_id": [ + 1, + 0, + 0 + ], + "bronze": [ + 900000, + 0, + 0 + ], + "silver": [ + 950000, + 0, + 0 + ], + "gold": [ + 980000, + 0, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 50000206, + "seq_id": 2 + }, + { + "index": 1, + "music_id": 50000023, + "seq_id": 2 + }, + { + "index": 2, + "music_id": 50000078, + "seq_id": 2 + }, + { + "index": 3, + "music_id": 50000203, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 50000323, + "seq_id": 2 + } + ] + }, + { + "course_id": 22, + "course_name": "サヨナラ・キングコング ~恋のつぼみは愛の虹へ~", + "course_level": 8, + "norma": { + "norma_id": [ + 4, + 1, + 0 + ], + "bronze": [ + 0, + 900000, + 0 + ], + "silver": [ + 0, + 950000, + 0 + ], + "gold": [ + 0, + 980000, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 50000148, + "seq_id": 2 + }, + { + "index": 1, + "music_id": 50000101, + "seq_id": 2 + }, + { + "index": 2, + "music_id": 10000064, + "seq_id": 2 + }, + { + "index": 3, + "music_id": 50000171, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 50000070, + "seq_id": 2 + } + ] + }, + { + "course_id": 23, + "course_name": "風に舞う白鳥の翼と花弁、さながら万華鏡のよう", + "course_level": 8, + "norma": { + "norma_id": [ + 3, + 0, + 0 + ], + "bronze": [ + 90, + 0, + 0 + ], + "silver": [ + 95, + 0, + 0 + ], + "gold": [ + 98, + 0, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 30000036, + "seq_id": 2 + }, + { + "index": 1, + "music_id": 50000122, + "seq_id": 2 + }, + { + "index": 2, + "music_id": 10000062, + "seq_id": 2 + }, + { + "index": 3, + "music_id": 50000199, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 40000153, + "seq_id": 2 + } + ] + }, + { + "course_id": 24, + "course_name": "The 小さなおぼろガチョウ♪", + "course_level": 8, + "norma": { + "norma_id": [ + 1, + 2, + 0 + ], + "bronze": [ + 970000, + 2, + 0 + ], + "silver": [ + 980000, + 3, + 0 + ], + "gold": [ + 990000, + 4, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 50000049, + "seq_id": 2 + }, + { + "index": 1, + "music_id": 50000071, + "seq_id": 2 + }, + { + "index": 2, + "music_id": 10000041, + "seq_id": 2 + }, + { + "index": 3, + "music_id": 50000031, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 40000129, + "seq_id": 2 + } + ] + }, + { + "course_id": 25, + "course_name": "TAG生誕祭2014 俺の記録を抜いてみろ!~HARD編~", + "course_level": 8, + "norma": { + "norma_id": [ + 4, + 1, + 0 + ], + "bronze": [ + 0, + 800000, + 0 + ], + "silver": [ + 0, + 900000, + 0 + ], + "gold": [ + 0, + 931463, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 50000089, + "seq_id": 2 + }, + { + "index": 1, + "music_id": 50000083, + "seq_id": 2 + }, + { + "index": 2, + "music_id": 50000210, + "seq_id": 2 + }, + { + "index": 3, + "music_id": 50000030, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 40000159, + "seq_id": 2 + } + ] + }, + { + "course_id": 26, + "course_name": "凍る世界で見る鳳凰の火の花", + "course_level": 9, + "norma": { + "norma_id": [ + 4, + 1, + 0 + ], + "bronze": [ + 0, + 920000, + 0 + ], + "silver": [ + 0, + 950000, + 0 + ], + "gold": [ + 0, + 980000, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 30000043, + "seq_id": 2 + }, + { + "index": 1, + "music_id": 10000039, + "seq_id": 2 + }, + { + "index": 2, + "music_id": 20000048, + "seq_id": 2 + }, + { + "index": 3, + "music_id": 50000096, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 20000038, + "seq_id": 2 + } + ] + }, + { + "course_id": 27, + "course_name": "真実の桜が乱れしとき、キルト纏いし君は修羅となる", + "course_level": 9, + "norma": { + "norma_id": [ + 4, + 3, + 0 + ], + "bronze": [ + 0, + 80, + 0 + ], + "silver": [ + 0, + 85, + 0 + ], + "gold": [ + 0, + 90, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 50000113, + "seq_id": 2 + }, + { + "index": 1, + "music_id": 50000184, + "seq_id": 2 + }, + { + "index": 2, + "music_id": 50000177, + "seq_id": 2 + }, + { + "index": 3, + "music_id": 30000124, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 50000078, + "seq_id": 2 + } + ] + }, + { + "course_id": 28, + "course_name": "THE FINAL01 ~雷光に月、乙女に花散る祝福を~", + "course_level": 10, + "norma": { + "norma_id": [ + 4, + 1, + 0 + ], + "bronze": [ + 0, + 920000, + 0 + ], + "silver": [ + 0, + 950000, + 0 + ], + "gold": [ + 0, + 980000, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 10000038, + "seq_id": 2 + }, + { + "index": 1, + "music_id": 20000051, + "seq_id": 2 + }, + { + "index": 2, + "music_id": 30000048, + "seq_id": 2 + }, + { + "index": 3, + "music_id": 40000060, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 50000023, + "seq_id": 2 + } + ] + }, + { + "course_id": 29, + "course_name": "The Memorial Third: assimilated all into Nature", + "course_level": 10, + "norma": { + "norma_id": [ + 4, + 1, + 0 + ], + "bronze": [ + 0, + 920000, + 0 + ], + "silver": [ + 0, + 950000, + 0 + ], + "gold": [ + 0, + 980000, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 50000135, + "seq_id": 2 + }, + { + "index": 1, + "music_id": 50000029, + "seq_id": 2 + }, + { + "index": 2, + "music_id": 40000047, + "seq_id": 2 + }, + { + "index": 3, + "music_id": 40000046, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 50000253, + "seq_id": 2 + } + ] + }, + { + "course_id": 30, + "course_name": "4thKAC ~Memories of saucer~", + "course_level": 10, + "norma": { + "norma_id": [ + 4, + 1, + 0 + ], + "bronze": [ + 0, + 920000, + 0 + ], + "silver": [ + 0, + 950000, + 0 + ], + "gold": [ + 0, + 980000, + 0 + ] + }, + "music_list": [ + { + "index": 0, + "music_id": 50000206, + "seq_id": 2 + }, + { + "index": 1, + "music_id": 50000023, + "seq_id": 2 + }, + { + "index": 2, + "music_id": 50000078, + "seq_id": 2 + }, + { + "index": 3, + "music_id": 50000203, + "seq_id": 2 + }, + { + "index": 4, + "music_id": 50000323, + "seq_id": 2 + } + ] + } + ] +} diff --git a/jubeat@asphyxia/handlers/common.ts b/jubeat@asphyxia/handlers/common.ts index bd791cb..c3a1a1d 100644 --- a/jubeat@asphyxia/handlers/common.ts +++ b/jubeat@asphyxia/handlers/common.ts @@ -1,35 +1,39 @@ -import {getVersion, VersionRange} from '../utils'; +import {getVersion, VersionRange} from "../utils"; export const gameInfo: EPR = (info, data, send) => { - const locId = $(data).content('shop.locationid'); + const locId = $(data).content("shop.locationid"); const version = getVersion(info); if (version === 0) return send.deny(); return send.object({ data: { - ...info.module === 'shopinfo' && { - cabid: K.ITEM('u32', _.random(1, 10)), - locationid: K.ITEM('str', locId), - ...VersionRange(version, 3, 6) && { is_send: K.ITEM('u8', 1) }, + ...info.module === "shopinfo" && { + cabid: K.ITEM("u32", _.random(1, 10)), + locationid: K.ITEM("str", locId), + ...VersionRange(version, 3, 6) && { is_send: K.ITEM("u8", 1) }, + tax_phase: K.ITEM("u8", 0), + facility: { + exist: K.ITEM("u32", 1) + } }, ...VersionRange(version, 5, 6) && { - white_music_list: K.ARRAY('s32', Array(32).fill(-1)) + white_music_list: K.ARRAY("s32", Array(32).fill(-1)) } } }); }; export const demodata = { - getNews: (_, __, send) => send.object({ data: { officialnews: K.ATTR({ count: '0' }) } }), + getNews: (_, __, send) => send.object({ data: { officialnews: K.ATTR({ count: "0" }) } }), getData: (_, data, send) => { - const newsId = $(data).number('officialnews.newsid'); + const newsId = $(data).number("officialnews.newsid"); return send.object({ data: { officialnews: { data: { - newsid: K.ITEM('s16', newsId), - image: K.ITEM('u8', 0, { size: '0' }) + newsid: K.ITEM("s16", newsId), + image: K.ITEM("u8", 0, { size: "0" }) } } } @@ -38,10 +42,10 @@ export const demodata = { getHitchart: (_, __, send) => send.object({ data: { hitchart: { - update: K.ITEM('str', ''), + update: K.ITEM("str", ""), - hitchart_lic: K.ATTR({ count: '0' }), - hitchart_org: K.ATTR({ count: '0' }), + hitchart_lic: K.ATTR({ count: "0" }), + hitchart_org: K.ATTR({ count: "0" }), } } }), diff --git a/jubeat@asphyxia/handlers/profile.ts b/jubeat@asphyxia/handlers/profile.ts index bcdac0e..6ea0bd7 100644 --- a/jubeat@asphyxia/handlers/profile.ts +++ b/jubeat@asphyxia/handlers/profile.ts @@ -1,6 +1,7 @@ import {getVersion, getVersionName, VersionRange} from "../utils"; import Profile from "../models/profile"; import {Score} from "../models/score"; +import {CourseResult} from "../models/course"; export const profile: EPR = async (info, data, send) => { let refId = $(data).str("data.player.pass.refid"); @@ -32,17 +33,20 @@ export const profile: EPR = async (info, data, send) => { return send.object({ data: { - ...VersionRange(version, 5, 5) && require("../templates/gameInfos/saucer.ts")(profile), + ...version === 5 && require("../templates/gameInfos/saucer.ts")(profile), + ...version === 6 && require("../templates/gameInfos/fulfill.ts")(profile), player: { name: K.ITEM("str", profile.name), jid: K.ITEM("s32", profile.jubeatId), refid: K.ITEM("str", profile.__refid), session_id: K.ITEM("s32", 1), + event_flag: K.ITEM("u64", BigInt(0)), ...version === 3 && require("../templates/profiles/knit.ts")(profile), ...version === 4 && require("../templates/profiles/copious.ts")(profile), ...version === 5 && require("../templates/profiles/saucer.ts")(profile), + ...version === 6 && require("../templates/profiles/fulfill.ts")(profile), } } }); @@ -236,6 +240,62 @@ export const saveProfile: EPR = async (info, { data }, send) => { profile.saucer.bistro.carry_over = $(data).number("player.bistro.carry_over"); } + if (version === 6) { + if (!profile.fulfill) profile.fulfill = {}; + profile.fulfill.jubility = $(data).number("player.info.jubility"); + profile.fulfill.jubilityYday = $(data).number("player.info.jubility_yday"); + profile.fulfill.tuneCount = $(data).number("player.info.tune_cnt"); + profile.fulfill.saveCount = $(data).number("player.info.save_cnt"); + profile.fulfill.savedCount = $(data).number("player.info.saved_cnt"); + profile.fulfill.fcCount = $(data).number("player.info.fc_cnt"); + profile.fulfill.exCount = $(data).number("player.info.exc_cnt"); + profile.fulfill.clearCount = $(data).number("player.info.clear_cnt"); + profile.fulfill.matchCount = $(data).number("player.info.match_cnt"); + profile.fulfill.expertOption = $(data).number("player.info.expert_option"); + profile.fulfill.matching = $(data).number("player.info.matching"); + profile.fulfill.hazard = $(data).number("player.info.hazard"); + profile.fulfill.hard = $(data).number("player.info.hard"); + profile.fulfill.extraPoint = $(data).number("player.info.extra_point"); + profile.fulfill.isExtraPlayed = $(data).bool("player.info.is_extra_played"); + profile.fulfill.totalBestScore = $(data).number("player.info.total_best_score"); + profile.fulfill.clearMaxLevel = $(data).number("player.info.clear_max_level"); + profile.fulfill.fcMaxLevel = $(data).number("player.info.fc_max_level"); + profile.fulfill.exMaxLevel = $(data).number("player.info.exc_max_level"); + + profile.fulfill.marker = lastMarker; + profile.fulfill.theme = lastTheme; + profile.fulfill.title = lastTitle; + profile.fulfill.parts = lastParts; + profile.fulfill.sort = lastSort; + profile.fulfill.category = lastCategory; + + profile.fulfill.secretList = $(data).numbers("player.item.secret_list"); + profile.fulfill.themeList = $(data).number("player.item.theme_list"); + profile.fulfill.markerList = $(data).numbers("player.item.marker_list"); + profile.fulfill.titleList = $(data).numbers("player.item.title_list"); + profile.fulfill.partsList = $(data).numbers("player.item.parts_list"); + profile.fulfill.secretListNew = $(data).numbers("player.item.secret_new"); + profile.fulfill.themeListNew = $(data).number("player.item.theme_new"); + profile.fulfill.markerListNew = $(data).numbers("player.item.marker_new"); + profile.fulfill.titleListNew = $(data).numbers("player.item.title_new"); + + const courseNode = $(data).element("course"); + if (courseNode) { + profile.fulfill.lastCourseId = courseNode.number("course_id"); + + await DB.Upsert(refId, { + collection: "course_results", + courseId: courseNode.number("course_id"), + version: 6 + }, { + $set: { + rating: courseNode.number("rating"), + scores: courseNode.elements("music").map(m => m.number("score")) + } + }); + } + } + try { await DB.Update(refId, { collection: "profile" }, profile); @@ -340,6 +400,69 @@ const updateScore = async (refId: string, data: any): Promise => { } }; +export const getCourse: EPR = async (info, data, send) => { + const version = getVersion(info); + if (version === 0) return send.deny(); + + const jubeatId = $(data).number("data.player.jid"); + if (!jubeatId) return send.deny(); + + const profile = await DB.FindOne(null, { collection: "profile", jubeatId }); + if (!profile) return send.deny(); + + if (version === 6) { + const results = await DB.Find(profile.__refid, { collection: "course_results", version: 6 }); + + const { courses } = require("../data/fulfill_courses.json"); + + const validCourseIds: number[] = courses.map(course => course.course_id); + + return send.object({ + data: { + course_list: { + course: courses.map(course => ({ + id: K.ITEM("s32", course.course_id), + name: K.ITEM("str", course.course_name), + level: K.ITEM("u8", course.course_level), + + norma: { + norma_id: K.ARRAY("s32", course.norma.norma_id), + bronze_value: K.ARRAY("s32", course.norma.bronze), + silver_value: K.ARRAY("s32", course.norma.silver), + gold_value: K.ARRAY("s32", course.norma.gold) + }, + + music_list: { + music: course.music_list.map(music => (K.ATTR({ index: music.index }, { + music_id: K.ITEM("s32", music.music_id), + seq: K.ITEM("u8", music.seq_id) + }))) + } + })) + }, + + player_list: { + player: { + jid: K.ITEM("s32", jubeatId), + + result_list: { + result: results.filter(e => validCourseIds.find(valid => valid === e.courseId)).map(result => ({ + id: K.ITEM("s32", result.courseId), + rating: K.ITEM("u8", result.rating), + score: K.ARRAY("s32", result.scores) + })) + } + } + }, + + last_course_id: K.ITEM("s32", profile.fulfill?.lastCourseId || 0) + } + }); + } + + return send.deny(); +}; + export const meeting: EPR = (info, data, send) => { return send.object({ data: { diff --git a/jubeat@asphyxia/index.ts b/jubeat@asphyxia/index.ts index 1a1fb95..4c9f434 100644 --- a/jubeat@asphyxia/index.ts +++ b/jubeat@asphyxia/index.ts @@ -1,36 +1,37 @@ -import {demodata, gameInfo} from './handlers/common'; -import {check, entry, refresh, report} from './handlers/matching'; -import {getCollabo, loadScore, meeting, profile, saveProfile} from './handlers/profile'; +import {demodata, gameInfo} from "./handlers/common"; +import {check, entry, refresh, report} from "./handlers/matching"; +import {getCollabo, getCourse, loadScore, meeting, profile, saveProfile} from "./handlers/profile"; export function register() { if (CORE_VERSION_MAJOR <= 1 && CORE_VERSION_MINOR < 31) { - console.error('The current version of Asphyxia Core is not supported. Requires version \'1.31\' or later.'); + console.error("The current version of Asphyxia Core is not supported. Requires version '1.31' or later."); return; } - R.GameCode('J44'); - R.GameCode('K44'); - R.GameCode('L44'); + R.GameCode("J44"); + R.GameCode("K44"); + R.GameCode("L44"); - R.Route('gametop.regist', profile); - R.Route('gametop.get_info', gameInfo); - R.Route('gametop.get_pdata', profile); - R.Route('gametop.get_mdata', loadScore); - R.Route('gametop.get_meeting', meeting); - R.Route('gametop.get_collabo', getCollabo); + R.Route("gametop.regist", profile); + R.Route("gametop.get_info", gameInfo); + R.Route("gametop.get_pdata", profile); + R.Route("gametop.get_mdata", loadScore); + R.Route("gametop.get_course", getCourse); + R.Route("gametop.get_meeting", meeting); + R.Route("gametop.get_collabo", getCollabo); - R.Route('gameend.regist', saveProfile); - R.Route('gameend.log', true); - R.Route('gameend.set_collabo', true); + R.Route("gameend.regist", saveProfile); + R.Route("gameend.log", true); + R.Route("gameend.set_collabo", true); - R.Route('shopinfo.regist', gameInfo); - R.Route('demodata.get_news', demodata.getNews); - R.Route('demodata.get_data', demodata.getData); - R.Route('demodata.get_hitchart', demodata.getHitchart); - R.Route('lobby.check', check); - R.Route('lobby.entry', entry); - R.Route('lobby.refresh', refresh); - R.Route('lobby.report', report); + R.Route("shopinfo.regist", gameInfo); + R.Route("demodata.get_news", demodata.getNews); + R.Route("demodata.get_data", demodata.getData); + R.Route("demodata.get_hitchart", demodata.getHitchart); + R.Route("lobby.check", check); + R.Route("lobby.entry", entry); + R.Route("lobby.refresh", refresh); + R.Route("lobby.report", report); - R.Route('netlog.send', true); - R.Route('logger.report', true); + R.Route("netlog.send", true); + R.Route("logger.report", true); } diff --git a/jubeat@asphyxia/models/course.ts b/jubeat@asphyxia/models/course.ts new file mode 100644 index 0000000..8f07c59 --- /dev/null +++ b/jubeat@asphyxia/models/course.ts @@ -0,0 +1,9 @@ +export interface CourseResult { + collection: "course_results"; + + version: number; + + courseId: number; + rating: number; + scores: number[]; +} diff --git a/jubeat@asphyxia/models/profile.ts b/jubeat@asphyxia/models/profile.ts index 7fec747..c2f4e88 100644 --- a/jubeat@asphyxia/models/profile.ts +++ b/jubeat@asphyxia/models/profile.ts @@ -120,4 +120,48 @@ export default interface Profile { carry_over?: number; } }; + + fulfill?: { + jubility?: number; + jubilityYday?: number; + tuneCount?: number; + clearCount?: number; + saveCount?: number; + savedCount?: number; + fcCount?: number; + exCount?: number; + matchCount?: number; + extraPoint?: number; + isExtraPlayed?: boolean; + totalBestScore?: number; + clearMaxLevel?: number; + fcMaxLevel?: number; + exMaxLevel?: number; + + marker?: number; + theme?: number; + title?: number; + parts?: number; + sort?: number; + category?: number; + expertOption?: number; + matching?: number; + hazard?: number; + hard?: number; + + secretList?: number[]; + themeList?: number; + markerList?: number[]; + titleList?: number[]; + partsList?: number[]; + + secretListNew?: number[]; + themeListNew?: number; + markerListNew?: number[]; + titleListNew?: number[]; + + lastCourseId?: number; + + + }; } diff --git a/jubeat@asphyxia/templates/gameInfos/fulfill.ts b/jubeat@asphyxia/templates/gameInfos/fulfill.ts new file mode 100644 index 0000000..3c706a7 --- /dev/null +++ b/jubeat@asphyxia/templates/gameInfos/fulfill.ts @@ -0,0 +1,28 @@ +module.exports = () => ({ + termver: K.ITEM("u8", 0), + season_etime: K.ITEM("u32", 0), + white_music_list: K.ARRAY("s32", Array(32).fill(-1)), + open_music_list: K.ARRAY("s32", Array(32).fill(0)), + + collabo_info: { + collabo: [ + K.ATTR({ type: "1" }, { state: K.ITEM("u8", 0) }), + K.ATTR({ type: "2" }, { state: K.ITEM("u8", 0) }), + K.ATTR({ type: "3" }, { state: K.ITEM("u8", 0) }), + K.ATTR({ type: "4" }, { state: K.ITEM("u8", 0) }), + K.ATTR({ type: "5" }, { state: K.ITEM("u8", 0) }), + K.ATTR({ type: "8" }, { state: K.ITEM("u8", 0) }) + ], + + policy_break: { + is_report_end: K.ITEM("bool", true) + } + }, + + lab: { + is_open: K.ITEM("bool", false) + }, + + share_music: K.ATTR({ count: "0" }), + bonus_music: K.ATTR({ count: "0" }) +}); diff --git a/jubeat@asphyxia/templates/profiles/fulfill.ts b/jubeat@asphyxia/templates/profiles/fulfill.ts new file mode 100644 index 0000000..5148786 --- /dev/null +++ b/jubeat@asphyxia/templates/profiles/fulfill.ts @@ -0,0 +1,117 @@ +import Profile from "../../models/profile"; + +module.exports = (data: Profile) => ({ + info: { + jubility: K.ITEM("s16", data.fulfill?.jubility || 0), + jubility_yday: K.ITEM("s16", data.fulfill?.jubilityYday || 0), + tune_cnt: K.ITEM("s32", data.fulfill?.tuneCount || 31), + save_cnt: K.ITEM("s32", data.fulfill?.saveCount || 0), + saved_cnt: K.ITEM("s32", data.fulfill?.savedCount || 0), + fc_cnt: K.ITEM("s32", data.fulfill?.fcCount || 0), + ex_cnt: K.ITEM("s32", data.fulfill?.exCount || 0), + clear_cnt: K.ITEM("s32", data.fulfill?.clearCount || 0), + pf_cnt: K.ITEM("s32", 0), + match_cnt: K.ITEM("s32", data.fulfill?.matchCount || 0), + beat_cnt: K.ITEM("s32", 0), + mynews_cnt: K.ITEM("s32", 0), + mtg_entry_cnt: K.ITEM("s32", 0), + mtg_hold_cnt: K.ITEM("s32", 0), + mtg_result: K.ITEM("u8", 0), + extra_point: K.ITEM("s32", data.fulfill?.extraPoint || 0), + is_extra_played: K.ITEM("bool", data.fulfill?.isExtraPlayed || false) + }, + + last: { + play_time: K.ITEM("s64", BigInt(0)), + shopname: K.ITEM("str", data.lastShopname), + areaname: K.ITEM("str", data.lastAreaname), + title: K.ITEM("s16", data.fulfill?.title || 0), + parts: K.ITEM("s16", data.fulfill?.parts || 0), + theme: K.ITEM("s8", data.fulfill?.theme || 0), + marker: K.ITEM("s8", data.fulfill?.marker || 0), + rank_sort: K.ITEM("s8", data.rankSort || 1), + combo_disp: K.ITEM("s8", data.comboDisp || 1), + music_id: K.ITEM("s32", data.musicId || 0), + seq_id: K.ITEM("s8", data.seqId || 0), + sort: K.ITEM("s8", data.fulfill?.sort || 0), + category: K.ITEM("s8", data.fulfill?.category || 0), + expert_option: K.ITEM("s8", data.fulfill?.category || 0), + matching: K.ITEM("s8", data.fulfill?.category || 1), + hazard: K.ITEM("s8", data.fulfill?.category || 0), + hard: K.ITEM("s8", data.fulfill?.category || 0) + }, + + item: { + secret_list: K.ARRAY("s32", Array(32).fill(-1)), + theme_list: K.ITEM("s16", -1), + marker_list: K.ARRAY("s32", Array(2).fill(-1)), + title_list: K.ARRAY("s32", Array(96).fill(-1)), + parts_list: K.ARRAY("s32", Array(96).fill(-1)), + + new: { + secret_list: K.ARRAY("s32", Array(32).fill(0)), + theme_list: K.ITEM("s16", 0), + marker_list: K.ARRAY("s32", Array(2).fill(0)), + title_list: K.ARRAY("s32", Array(96).fill(0)) + } + }, + + history: K.ATTR({ count: "0" }), + + challenge: { + today: { + music_id: K.ITEM("s32", 0), + state: K.ITEM("u8", 0) + } + }, + + news: { + checked: K.ITEM("s16", 0) + }, + + macchiato: { + pack_id: K.ITEM("s32", 0), + bean_num: K.ITEM("u16", 0), + daily_milk_num: K.ITEM("s32", 1200), + is_received_daily_milk: K.ITEM("bool", true), + today_tune_cnt: K.ITEM("s32", 0), + daily_milk_bonus: K.ARRAY("s32", [100, 100, 1000, 200, 200, 200, 200, 200, 1000]), + daily_play_burst: K.ITEM("s32", 300), + + sub_menu_is_completed: K.ITEM("bool", true), + compensation_milk: K.ITEM("s32", 0), + + macchiato_music_list: K.ATTR({ count: "0" }, { + music: [] + }), + + sub_pack_id: K.ITEM("s32", 0), + + sub_macchiato_music_list: K.ATTR({ count: "0" }, { + music: [] + }), + + season_music_list: K.ATTR({ count: "0" }), + + match_cnt: K.ITEM("s32", 0), + + achievement_list: K.ATTR({ count: "0" }, { + achievement: [] + }), + + cow_list: K.ATTR({ count: "0" }), + }, + + rivallist: K.ATTR({ count: "0" }), + + only_now_music: K.ATTR({ count: "0" }), + lab_edit_seq: K.ATTR({ count: "0" }), + kac_music: K.ATTR({ count: "0" }), + + memorial: { + latest_event_id: K.ITEM("u8", 1), + player_event_id: K.ITEM("u8", 1), + flag: K.ITEM("u32", 0), + params: K.ARRAY("u32", Array(15).fill(0)) + } +});