osu!を魔改造してMisskeyクライアントをつくる

2022/12/23に公開

はじめに💭

けもんちゅはこんなことをかんがえていました…🦊

ブラウザはデバイスの性能をうまく使い切れずに重くなることがあります
ゲームはデバイスの性能をうまく使ってぬるぬる動きます
→ゲームエンジンでMisskeyクライアントをつくればマルチプラットフォームでぬるぬるなクライアントを作れるのでは…?

つくりました

https://github.com/sim1222/osukey
現在開発中ですが、

  • ログイン
  • TLの表示
  • ノート

まではできるようになりました。

これはなに…?

osuベースのMisskeyクライアント

です

素材選定

osu!というPCにの音楽ゲームの次期大型アップデートの新クライアントとして、osu!lazerがあります
これはC# と.NET Coreでできていて、マルチプラットフォーム対応なのでこれを改造することにしました💪💪

巨大な壁

開発中巨大ソフトウェアあるあるなのですが、ドキュメントが一切ないのでソースコードを読むしかosu-frameworkの使い方を知る方法がありません。
また、元の開発速度がとても早いため1ヶ月放置していると200ファイルぐらいの変更が降りてきたりしてとても大変でした

使い方(記事作成時点)

WindowsとAndroidの方はGitHubのReleaseにバイナリがおいてあります。
Linuxとmacはreadmeに従ってビルドすると動くはずです

メインメニューのMisskey→MisskeyLoginからmisskey.ioのアカウントでログインしてください(2段階認証は非対応)
MisskeyPostやTimelineが現在使用可能です

つくってておもしろかったこと

osu-frameworkがとてもWebのような書き方でUIが作成できておもしろかったです

例としてノート作成画面のコードを載せておきます

PostForm.cs
[BackgroundDependencyLoader(permitNulls: true)]
private void load()
{
    Direction = FillDirection.Vertical;
    Spacing = new Vector2(0, 5);
    AutoSizeAxes = Axes.Y;
    RelativeSizeAxes = Axes.X;
    ErrorTextFlowContainer errorText;
    Children = new Drawable[]
    {
        cwBox = new OsuTextBox
        {
            PlaceholderText = "CW",
            RelativeSizeAxes = Axes.X,
            TabbableContentContainer = this,
        },
        textBox = new OsuTextBox
        {
            PlaceholderText = "お気持ち表明してください",
            RelativeSizeAxes = Axes.X,
            TabbableContentContainer = this,
        },
        errorText = new ErrorTextFlowContainer
        {
            RelativeSizeAxes = Axes.X,
            AutoSizeAxes = Axes.Y,
        },
        new Container
        {
            RelativeSizeAxes = Axes.X,
            AutoSizeAxes = Axes.Y,
            Children = new Drawable[]
            {
                shakeSignIn = new ShakeContainer
                {
                    RelativeSizeAxes = Axes.X,
                    AutoSizeAxes = Axes.Y,
                    Child = new SettingsButton
                    {
                        Text = "ノート",
                        Action = () => post()
                    },
                }
            }
        },
        new SettingsButton
        {
            Text = "test",
            Action = () =>
            {
                onScreenDisplay?.Display(new ResToast("送信しています", ""));
            }
        },
        new FillFlowContainer<IconButton>
        {
            Spacing = new Vector2(20),
            Size = new Vector2(500, 200),
            Children = new[]
            {
                new IconButton
                {
                    Icon = FontAwesome.Solid.Image,
                    Size = new Vector2(30),
                    Action = () => this.ShowPopover()
                },
                new IconButton
                {
                    Icon = FontAwesome.Solid.PollH,
                    Size = new Vector2(30),
                    Action = () => toggleCw = !toggleCw
                },
                new IconButton
                {
                    Icon = FontAwesome.Solid.EyeSlash,
                    Size = new Vector2(30),
                    Action = () => toggleCw = !toggleCw
                },
                new IconButton
                {
                    Icon = FontAwesome.Solid.At,
                    Size = new Vector2(30),
                    Action = () => toggleCw = !toggleCw
                },
                new IconButton
                {
                    Icon = FontAwesome.Solid.Hashtag,
                    Size = new Vector2(30),
                    Action = () => toggleCw = !toggleCw
                },
                new IconButton
                {
                    Icon = FontAwesome.Solid.LaughSquint,
                    Size = new Vector2(30),
                    Action = () => cwBox.Show()
                },
            }
        }
    };
    textBox.OnCommit += (_, _) => post();
    cwBox.Hide();
    if (api.LastLoginError?.Message is string error)
        errorText.AddErrors(new[] { error });
}

今後の開発目標

  • ほぼすべての機能を実装する
  • ぬるぬるを維持できるように最適化する
  • ついでにosu!frameworkのドキュメントを書く💪

さいごに

いっしょに開発する人を募集しています💕

時間がたりな~~~い

Discussion