阿珏のBlog の国際化への道

最近、個人ブログに「大改修」を施しました。 単一言語バージョンから多言語サイト(簡体字中国語、繁体字中国語、英語、日本語)にアップグレードし、 その全プロセスを自動化しました。💪 主な内容は以下の通りです。 メインサイトの記事を自動同期 コンテンツを自動AI翻訳 多言語サイトの自動構築とデプロイ なぜ Hugo を選んだのか? それは、その自信に満ちたスローガンがあったからです。 “The world’s fastest framework for building websites.” —— この一言で、これに決めました 😆。 しかし、私は「一つのテーマで多言語を切り替える」という伝統的な方法ではなく、 各言語に独立したテーマを持たせることにしました。 これにより、各言語バージョンが独自のデザインとレイアウトスタイルを保持し、 真に「文化的なローカライゼーション」を実現できます。 設計目標と制約 🎯 言語: 簡体字中国語、繁体字中国語、英語、日本語をサポートし、将来的に拡張可能。 テーマ: 各言語に最適な Hugo テーマを使用し、無理に再利用しない。 コンテンツ同期: 全言語で一つのコンテンツリポジトリを共有し、必要に応じて翻訳。 デプロイ戦略: 各言語を独立して構築・公開し、異なるブランチやドメインにデプロイ可能。 カスタムページ: 「友だちリンク」、「書斎」、「アーカイブ」などのページは、多言語で一貫した体験を維持する。 多言語設定戦略 🧩 各言語用に個別の設定ファイルを用意しました。 config/<lang>.toml で、主に以下の役割を担います。 テーマの指定(例: theme = "PaperMod")。 その言語固有の title / description / keywords の定義。 異なるテーマのナビゲーション構造に合わせるためのメニュー設定 [[params.menu]] の上書き。 全体的な視覚的一貫性を保証するためのカスタムスタイルの注入。 この構造は非常に明確で、将来的にさらに多くの言語バージョンを拡張するのにも便利です。 GitHub Actions 自動デプロイマトリックス ⚙️ CI/CD 部分は完全に GitHub Actions に任せています。 .github/workflows/hugo.yml では、マトリックスビルドを使用し、 各言語を独立して構築・公開しています。 ...

2025年11月2日 · 1 分 · MoeJue

# ポータブルモニターを自作する方法

ポータブルディスプレイを自作する方法 はじめに 家には古いノートパソコンが1台あります。バッテリーはもうダメですが、他の部品はまだ正常に動作します。しかし、技術の進化は非常に速く、このノートパソコンはウェブサイトを閲覧する以外に、ほとんど使い道がありません。捨てるのはもったいないし、売っても大した値段にはなりません。そこで、これをポータブルディスプレイに改造することにしました。そうすれば、ノートパソコンやデスクトップPCに接続して、ゲームをしたり動画を見たりと、もう一働きさせることができます。ちなみに、ハードディスクはすでにポータブルハードディスクに改造済みです。 材料の準備 廃棄するディスプレイ LEDスクリーン駆動ボード スクリーンケーブル キーパッド インバーターボード 電源 (12V 5A) 主な材料はこれだけです。通販サイトですぐに購入でき、価格も高くありません。電源は父のネックマッサージャーから直接取り外したもので、また一つ節約できました。 改造プロセス ノートパソコンのディスプレイを分解し、スクリーンを取り出します。 もしお使いのスクリーンに対応する駆動ボードがわからない場合は、スクリーンの裏にある型番などの情報を写真に撮って販売店に送れば、それに合った駆動ボードを推薦してくれます。もちろん、電子回路に詳しい方なら、自分で回路図を設計して駆動ボードを自作することもできます。 配線し、ホットボンドで固定します。 ps: ホットボンドは貧乏人の3Dプリンターですね。 電源を入れてテストします。 私は手間を省くため、販売店に予め対応するファームウェアを書き込んでもらいました。 信号を入力します。 キーパッドの機能調整をテストします。 段ボールでケースを作ります。 どうやら私には廃材の段ボールでケースを作る才能がそこそこあるようです。見た目が悪すぎるのが心配で、壁紙シールを貼ってみました。家に3Dプリンターがある方は、直接ケースを設計してプリントすれば、もっと見栄えが良くなるでしょう。 完成品: 前面はホットボンドで接着したせいで、ちょっと見るに堪えない状態になってしまいました。

2025年4月13日 · 1 分 · MoeJue

オープンソースでシンプルかつスタイリッシュな、酷狗のサードパーティ製クライアント V1.0.0 Beta

MoeKoe Music オープンソースでシンプル、見た目も美しいKuGouのサードパーティクライアント 🌎 GitHubリポジトリ | 📦️ インストーラーをダウンロード | 💬 ブログを訪問 はじめに 10年ほど前、ウェブ版QQを使っていた頃からKuGou Musicを使い始めました(もう10年来のファンです)。なので、この数年で集めた曲はすべてそこにあります。その後、NetEase Cloud MusicやQQ Musicも試してみましたが、KuGouのプレイリストをインポートしようとしても、結果は芳しくありませんでした。私が聴くのは主に日本のアニメのOPで、多くの曲が見つかりませんでした。 結局、KuGouに戻ってきました。しかし、Mac版のKuGouは時々再生できないことがありました。インターフェースはシンプルですが、それはそれで良い点です。ネットユーザーの勧めで、今はKuGouのコンセプト版で音楽を聴いています。これは市場で数少ない、VIP曲を無料で聴ける音楽プレイヤーで、強くお勧めします。 私の自己紹介ページで、特に日本のアニメのOPを聴くのが大好きだと書きました。それをどう証明するか?(以前のウェブ版プレイリストも長年放置されていました)そうだ、自分で音楽プレイヤーを開発しよう、と。 ✨ 特徴 ✅ Vue.js ファミリーを使用して開発 🔴 KuGouアカウントでのログイン(QRコード/携帯電話/アカウントでのログイン) 📃 歌詞表示をサポート 📻 毎日のおすすめ曲 🚫🤝 ソーシャル機能一切なし 🔗 公式サーバーに直接接続、サードパーティAPIは一切使用しません ✔️ 毎日VIPを自動で受け取り、ログインするだけでVIPに 🎨 テーマカラーの切り替え 👋 起動時の挨拶メッセージ ⚙️ マルチプラットフォーム対応 🛠 さらに多くの機能を開発中 Todo List [ ] 📺 MV再生をサポート [ ] 🌚 Light/Dark Modeの自動切り替え [ ] 👆 Touch Barをサポート [ ] 🖥️ PWAをサポート、Chrome/Edgeのアドレスバー右側の ➕ をクリックしてPCにインストール可能 [ ] 🟥 Last.fm Scrobbleをサポート [ ] 🎧 Mprisをサポート [ ] ⌨️ カスタムショートカットキーとグローバルショートカットキー [ ] 🤟 多言語対応 [ ] 📻 デスクトップ歌詞 [ ] ⚙️ システムアーキテクチャの最適化 [ ] 🎶 曲、プレイリスト/お気に入り、削除 📦️ インストール 本プロジェクトの Releases ページにアクセスしてインストーラーをダウンロードしてください。 ...

2024年11月3日 · 2 分 · MoeJue

転生:ECサイトを構築する - 萌音ECサイトV1.0リリース

萌音シリーズのN+1番目のプロジェクトが来ましたね。これも実は数年間放置していたプロジェクトで、今回ようやく完成させることができました。 まずはプロジェクトアドレス: https://MoeKoe.cn なぜ私はプロジェクトを作り続けているのか? この質問はとても面白いですね。なぜ様々なプロジェクトを、しかもお金にならないものばかり作り続けているのか。私の以前のプロジェクトに触れたことのある方はご存知でしょうが、私はどんなプロジェクトも「自分が使う」という原則に基づいて制作しています。もちろん今回も例外ではありません。ずっと、どこかのプラットフォームで、持っているけれど使わず、捨てるには惜しい小物たちを売りたいと思っていました。同時に、面白くて楽しい製品を皆さんと共有したいとも思っています(将来的には私のIP製品も加わるかもしれません)。「最高の出来事や物を、最高のあなたと共有したい」という思いもありますし、「他人が持っているなら私も持つべきだ」という原則に基づいて、私も持たなければなりません。 もし私がただ小物を売りたいだけなら、なぜ直接淘宝や闲鱼のようなプラットフォームを使わないのでしょうか。一歩譲って、これらのプラットフォームを使わないとしても、既存のECシステムを自分で構築することもできます。今や市場には成熟していて使いやすいシステムが山ほどあります。なぜわざわざ自分で開発する必要があるのでしょうか? 一言で言えば、好きだからです。これは私の趣味で、創造することが好きで、面白いものやことをするのが好きなんです。私はただ生きているだけの凡人ではなく、すごくて面白い人間になりたい。もっと多くの面白い魂と出会いたい。「すごい」という私の定義は、技術がどれほど優れているか、お金をどれほど稼ぐかということではありません。挫折や困難に直面したときでも、笑顔で立ち向かい、楽観的であり続け、初心を忘れない人。そのような人を、私は「すごい人」と呼びたいのです。 新しいプロジェクトを発表する記事なのに、またしても口語体のブログになってしまいました、ハハハ。 プロジェクト紹介 最近何をしているか?ピンクで可愛らしいもの、つまり二次元少女萌え系スタイルの魔法少女ECサイトを作っています。 魔法少女のファンタジー世界へようこそ!二次元の無限の可能性を探る冒険の旅を始めましょう!これは二次元愛好家のために特別に作られたオンラインECサイトです。ここでは、最も輝く魔法のアイテム、最もキュートな変身コスチューム、そして豊富で多様な二次元関連商品を見つけることができます。可愛い萌えグッズに夢中な方も、クールなコレクターズアイテムがお好きな方も、二次元へのすべての愛と期待をここで満たすことができます! URLをクリックすると、目が覚めるような(ピンクの)感覚を覚えるでしょう。そうです、これこそ私が求めていたスタイルです。ピンクで可愛らしく、乙女心満載で、カワイイ感じ。これこそが私の個性を際立たせるのです。 技術スタック Vue.js3 Vite Pinia Axios Node.js Express Mysql Nginx フロントエンドとバックエンドの分離 MySQLスレッドプール Vue.jsのフルスタックは本当に素晴らしいですね。ネイティブで書く手間が省けます。現在、国際化プラグイン(i18n)はこのバージョンにはまだ搭載されていません。市販のUIライブラリがこのプロジェクトの私の位置付けや個性に直接合致しないため、既存のUIライブラリは使用せず、すべて自分で手書きしました。 紹介: 仮想通貨USDTに対応(ウォレットアドレスを入力するだけで、自動で着金を監視。外部プログラム不要。監視システムは新規注文があると自動起動し、30分間新規注文がないと自動休眠し、リソース消費を削減) Alipay対面決済に対応、即時着金、自動コールバック ユーザー登録、ログイン、ログアウト、パスワード変更、アバター変更、商品レビューに対応 商品管理、商品カテゴリ管理に対応 注文管理、注文決済、注文発送、物流追跡に対応 商品注文データ分析に対応 全サイトレスポンシブデザイン フロントエンドとバックエンドの分離 MySQLスレッドプール システムの基本情報設定 最初のバージョンでは、基本的な機能と必要な機能のみを追加しました。新機能は設計段階で既に考慮されており、データベースとコードには予約がされています(そのため、あるボタンをクリックしても反応がない場合でも心配しないでください。その背後にはまだコードがないだけです)。これらは将来のバージョンで追加される予定です。現在、ECサイトでは物理的な商品の発送形式で販売していますが、将来的には仮想商品の販売も追加し、基本的に萌音発券の機能をすべて統合する予定です。 このプロジェクトの命名は「shop」ではなく「mall」としました。そのため、将来的には単なる店舗ではなく、ショッピングモールになる可能性があります。 将来: マルチテナントモード。ユーザーが直接ECサイトへの出店を申請し、萌音ECサイトを利用して自身の製品を販売できるようにする 商品の多カテゴリ分類。製品のより詳細な仕様分類 より多くの決済方法。現在、作者は他の決済権限を持っていないため、2つのみ連携済み 仮想商品に対応。発券機能を統合する形となる 商品ポスター宣伝画像生成 メールシステム。あってもなくても良い通知機能に過ぎない 右下の多機能メニュー。下部の笑顔のキャラクターがスマートナビゲーションシステムになる 商品インターフェースのデータ表示を追加。データが一目でわかるように 多言語対応(i18n)。国際化の流れに乗り、世界へ SMSシステム。メールシステムと全く同じ Redisキャッシュ。本来はこのバージョンで追加する予定だったが、データの制御は現状でも問題ない ダークモード。これもトレンドに追随 ソースコードの入手方法? 阿珏酱に233RMB以上を寄付することでソースコードを入手できます。 以前に阿珏酱を支援してくださった方々(以前の支援総額が233に満たない場合は差額を補填する形で、233を超えている場合は1元を寄付して契約を再締結するだけで直接入手できます) こちらをクリックして某コミュニティ公式交流グループで阿珏酱を支援してください。個人のQQリンクを貼れないため、グループリンクを貼りました。グループに参加してグループ管理者に@メンションしてください。 なぜ商用版を設けないのか? なぜ商用版ではなく、寄付版なのか、その違いは何でしょうか?商用版となると、ライセンスシステムが必要になり、同時にソースコードが提供されない可能性もあり、技術サポートも必要で、さらに多くの完璧な機能が求められるでしょう。商用版のお金はプロジェクト自体に支払われるもので、作者とは利害関係、つまり商業契約のモデルであり、作者はそれ(人)に対して責任を負う必要があります。(私はこの感覚が特に好きではありません。これが私が稼げない理由かもしれませんね) 一方、寄付版は、作者本人への寄付であり、個人の意思、友人同士の約束のような契約モデルであり、作者はプロジェクト自体にのみ責任を負います。 もちろん、私が言葉遊びをしている、言葉の隙間を突いていると感じるかもしれません。だから、これは完全に寄付行為なのです。今回の寄付の敷居には少し商業的な雰囲気があるかもしれませんが、それは私と妻たちが生活のために稼がなければならないからです。 ヒント 寄付版ではVueフロントエンドのソースコード+コンパイル後の静的ファイル+Node.jsバックエンドのソースファイルを提供します。 すべての寄付版で入手できるのはソースファイルであり、暗号化や難読化はされていません。漏洩しないようお願いするとともに、ご自身の権利を守るためでもあります。 ソースコードの変更にはある程度の基本的なプログラミング知識が必要です。もしできない場合は、変更しないでください。 宝塔パネルのデプロイサービスを1回提供します。 ウェブサイトのインターフェースは少女萌え系スタイルに傾倒しており、一般的な製品には適さない可能性がありますのでご注意ください。 コードは複製可能であるため、契約締結後は撤回できません。何卒ご了承ください。 今回もこれまでと同様に、寄付版の形式でソースコードを入手できるようにしました。なぜ今回またソースコードの入手を開放したのでしょうか?以前の萌音コミュニティの影響が多少あるでしょう。萌音コミュニティは私が2ヶ月以上かけて丹念に書き上げたもので、ソースコードの寄付による入手は受け付けず、純粋に自分で運営していました。寄付を申し出た人たちは皆断りましたが、最終的には一度だけ寄付を受け取りました。結局、萌音コミュニティに申し訳ない気持ちになりました。自分の手で潰してしまい、もっと多くの人にその存在を知ってもらえなかったからです。では、なぜ直接オープンソースにしないのかというと、そうするとかえってこのプロジェクトに申し訳ないと感じるからです。誰もが簡単に手に入れられるものだと思われ、その価値が失われてしまうでしょう。直接オープンソースにはしませんが、プロジェクト関連のアーキテクチャや設計思想、一部のコードを公開し、皆さんの参考にしてもらい、学習の妨げにはならないようにします。 ...

2024年10月2日 · 1 分 · MoeJue

ESP8266-NodeMCU開発ボードを使って、私のQQアバターを表示してみる。

ええ、自分でESP8266開発ボードのファームウェアを書くと言っていた私が戻ってきました。20年前に約束した通り、今日、その願いを叶えに戻ってきました。ESP8266串口WiFi模块 - WiFi杀手 今日はOLEDディスプレイも接続します。今回購入したのは4ピンのOLED(128*64)で、カラー表示には対応していません。 NodeMCU開発ボード NodeMCUはオープンソースのIoTハードウェア開発ボードです。WIFI機能をサポートし、Arduino開発ボードと非常に似た使用方法であるため、近年、世界中のメイカーたちからますます人気を集めています。NodeMCUのサイズはArduino Nanoに似ています。Arduinoチームによって開発されたものではありませんが、Arduino IDEを使用して開発することも可能です。 あらゆるものがインターネットに接続されるIoTの基盤として、まずIoT制御ボードのコストが高すぎてはいけません。高価なIoT制御コンポーネントは、プロジェクトのコスト管理に不利であり、多くのメイカー愛好家が学習し使用する上でも不利です。この点において、NodeMCUはRaspberry PiやArduinoファミリーのIoTプラットフォームなどよりも優位性があります。 注意深い方はすでにお気づきかもしれませんが、私の開発ボードはESP8266-NodeMCUと呼ばれています。しかし、他のウェブサイトや資料では、ESP8266と表記されたり、NodeMCUと表記されたりすることがあります。では、ESP8266とNodeMCUの間にはどのような関係があるのでしょうか? ESP8266はチップ(鉄製のケースに収められた四角いもの)であり、NodeMCUはESP8266チップを核とした開発ボードです。下の図に示す通りです。 小さなチップのピンをコンピューターに接続し、プログラムをアップロードするなどの操作を行うのは非常に困難であるため、ESP8266チップを中心とした様々な開発ボードが誕生しました。NodeMCUもこれらの開発ボードの一つです。 NodeMCU開発ボード上の2列のピンヘッダーは、ESP8266チップのピンに接続されています。開発ボード上の2列のピンヘッダーがあれば、デュポン線を使ってチップのピンを実験回路に簡単に接続できます。NodeMCU開発ボードにはUSBポートと電圧変換回路も搭載されています。これらは私たちに大きな利便性を提供します。USBデータケーブル1本で、ESP8266への給電とプログラムのアップロードを簡単に実現できます。もちろん、NodeMCU開発ボードの回路機能はこれだけではありませんが、これ以上は深掘りしません。 ドライバーのインストール 以前にも開発ボードのドライバーインストールについては説明しましたが、十分詳細ではありませんでした。 現在市販されているESP8266ドライバーには様々な種類があり、同じNodeMCU開発ボードであってもドライバーが異なる場合があります。現在主流なのはCH340とCP210Xのドライバーです。 ドライバーのダウンロードは、チップメーカーの公式サイトから直接行ってください。 CP210X:https://cn.silabs.com/developers/usb-to-uart-bridge-vcp-drivers CH340C:https://www.wch.cn/downloads/CH341SER_EXE.html ご自身のプラットフォームに適したドライバーインストーラーをダウンロードしてください。ご自身のシリアルチップのモデルがドライバーのサポート範囲内にあるか、よく確認する必要があります。 自分の開発ボードに必要なドライバーを確認する方法 直接見る。下の図の縦長の黒い長方形がUSB-シリアル変換チップです。その上にチップのモデル名が記載されています。 購入した販売店に尋ねる。 ディスプレイのはんだ付け はんだ付けを間違えないでください。間違えるとチップが焼損します。OLEDの配線: GND - GND VCC - VCC SCL - GPIO5(D1) SDA - GPIO4(D2) はんだごて加熱中 以下がはんだ付け完了したものです。配線に注意してください。この順番であるとは限りません。名称を確認してください。 Arduino IDEのインストール Arduino IDEをダウンロード https://www.arduino.cc/en/software インストール。インストールまで私が教える必要がありますか? 設定。「ツール」-「ボード」-「ボードマネージャー」をクリックし、設定でボードアドレスを記述します:http://arduino.esp8266.com/stable/package_esp8266com_index.json その後、対応するサポートライブラリファイルが自動的にダウンロードされます。この間、ネットワークの安定性を確保する必要があります。 開発ボードを選択: NodeMCU1.0(ESP-12EModule) ポートを選択: コンピューターのデバイスマネージャーで開発ボードのCOMポートを見つけます。 Arduinoコード 時々、私が長々と説明するよりも、直接コードを見せる方が手っ取り早いと感じます。あなたもきっと、私の無駄話を聞くよりも直接コードを見たいと思っているでしょう。私も可能な限りコードにコメントを付けました(Arduinoコードの記述はC/C++言語の規範に従ってください)。 以下の例では、WiFi接続にはライブラリを使用しています。初回接続時には、ESP8266が発信するWiFiに携帯電話で接続し、ネットワーク設定を行う必要があります。画面への書き出しにはライブラリを使用しており、中国語の直接書き出しをサポートしています。 これは、WiFi接続と画面への画像表示の簡単な例です。 #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include <ESP8266WiFi.h> #include <NTPClient.h> #include <WiFiManager.h> #include <U8g2lib.h> #define SDA 4 // SDA引脚,默认gpio4(D2) #define SCL 5 // SCL引脚,默认gpio5(D1) Adafruit_SSD1306 oled(128, 64, &Wire,-1); //OLED 屏幕实例化 WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP,"pool.ntp.org", 8*3600, 60000); U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /*clock=*/SCL, /*data=*/SDA, /*reset=*/U8X8_PIN_NONE); // 选择显示屏幕 // 只执行一次 void setup() { u8g2.begin(); // 初始化 u8g2.enableUTF8Print(); // UTF8允许 u8g2.setFont(u8g2_font_wqy12_t_gb2312b); //字体大小 u8g2_font_wqy15_t_gb2312b // 初始化屏幕 OLED_Init(); OLED_Showchin(1,13,"正在连接WiFi....",0); WiFiManager wifiManager; wifiManager.autoConnect("ESP8266"); OLED_Showchin(1,27,"WiFi连接成功!",0); OLED_Showchin(1,41,"名称: " + WiFi.SSID(),0); OLED_Showchin(1,55,"IP: " + WiFi.localIP().toString(),1); // 获取时间 timeClient.begin(); u8g2.setFont(u8g2_font_wqy15_t_gb2312b); //字体大小 u8g2_font_wqy15_t_gb2312b OLED_Showchin(1,13,"宁小建",0); OLED_Showchin(1,27,"hhhhhhhhhhhh",0); OLED_Showchin(1,55,"大傻逼哈哈哈",1); timeClient.update(); OLED_Showchin(1,20,"当前北京时间: ",0); OLED_Showchin(1,41,timeClient.getFormattedTime(),1); delay(1000); OLED_img(); } // 重复执行程序 void loop() { // 更新时间 // timeClient.update(); // OLED_Showchin(1,27,"当前北京时间: ",0); // OLED_Showchin(1,41,timeClient.getFormattedTime(),0); } // 打印输出到屏幕(支持中文) void OLED_Showchin(uint8_t x, uint8_t y, String string, uint8_t boot) { u8g2.setCursor(x, y); //设置显示坐标 u8g2.print(string); // 指定缓存区需要打印的字符串 u8g2.sendBuffer(); // 将定位信息发送到缓冲区 if(boot == 1){ delay(1000); u8g2.clearBuffer(); // 清除缓存,其实初始化里有清除,循环时一定要加上 } } // 屏幕初始化 void OLED_Init() { oled.begin(SSD1306_SWITCHCAPVCC, 0x3C); //"SSD1306_SWITCHCAPVCC"表示显示器为OLED ,"0x3C"为OLED屏幕默认通信地址 oled.setTextColor(WHITE);//开像素点发光 oled.clearDisplay();//清屏 } // 输出屏幕 void OLED_ShowString(uint8_t x, uint8_t y, uint8_t font_size, String string) { oled.setTextSize(font_size); //设置字体尺寸 (>=1) oled.setCursor(x, y); //设置显示坐标 oled.println(string); //显示内容 oled.display(); //开启显示 } // 绘画 void OLED_img() { // 图片数据 const unsigned char gImage_1[518] = { 0X00,0X01,0X40,0X00,0X40,0X00, 0X00,0X40,0X00,0X00,0X00,0X3E,0XF0,0X00,0X00,0X80,0X00,0X00,0X00,0X1F,0XE0,0X00, 0X00,0X00,0X00,0X00,0X00,0X06,0XB0,0X00,0X01,0X00,0X00,0X00,0X00,0X03,0XF8,0X00, 0X00,0X00,0X00,0X00,0X00,0X03,0XFC,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0XDC,0X00, 0X04,0X00,0X00,0X00,0X00,0X01,0XC0,0X00,0X0E,0X00,0X00,0X00,0X00,0X00,0X80,0X00, 0X06,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X01,0X00,0X00,0X00,0X10,0X00,0X00,0X00, 0X08,0X00,0X00,0X00,0X0E,0X00,0X00,0X00,0X08,0X00,0X00,0X00,0X8F,0X00,0X00,0X00, 0X00,0X00,0X02,0X02,0X47,0X00,0X00,0X00,0X00,0X00,0X01,0X10,0X63,0X80,0X00,0X00, 0X00,0X00,0X01,0XC9,0X73,0XC0,0X00,0X00,0X00,0X00,0X00,0XE4,0X79,0XE0,0X00,0X00, 0X00,0X02,0X00,0XFA,0XF9,0XE0,0X00,0X00,0X10,0X02,0X00,0X7D,0X8C,0XF0,0X00,0X00, 0X10,0X03,0X01,0X7E,0X90,0XF1,0X80,0X00,0X10,0X01,0X20,0XFD,0X1C,0X7B,0XE0,0X00, 0X00,0X01,0XA0,0X7D,0X03,0X7B,0X20,0X00,0X10,0X01,0XD8,0XFF,0X8B,0X7E,0X30,0X00, 0X00,0X01,0XFC,0X7F,0X83,0XB6,0X10,0X00,0X00,0X00,0XF7,0XFF,0XC7,0XBE,0X10,0X00, 0X00,0X01,0X8F,0XFF,0XE3,0XF6,0X10,0X00,0X01,0X01,0X4F,0XFF,0XFF,0XFF,0X10,0X00, 0X00,0X01,0XCF,0XFF,0XFF,0XDF,0X10,0X00,0X00,0X01,0XC3,0XFF,0XFF,0XDF,0X70,0X00, 0X01,0X03,0XE3,0XFF,0XFF,0XDF,0XE0,0X00,0X04,0X01,0XE7,0XFF,0XFF,0XDF,0XE4,0X00, 0X07,0X00,0XFB,0XFF,0XFF,0XDF,0XC0,0X00,0X07,0X00,0XFB,0XFF,0XFF,0XFE,0X00,0X00, 0X13,0X00,0X7F,0XFF,0XFF,0XFC,0X00,0X00,0X01,0X20,0X3F,0XFF,0XFF,0XFC,0X00,0X00, 0X00,0X00,0X3F,0XFF,0XFF,0XF8,0X00,0X0B,0X00,0X00,0X1F,0XFE,0X0F,0XF8,0X00,0X1F, 0X00,0X00,0X1F,0XF8,0X6F,0XF0,0X00,0XFF,0X00,0X00,0X1F,0XE1,0XFF,0XF0,0X05,0XFF, 0X00,0X00,0X0F,0XF3,0XFF,0XE0,0X03,0XFF,0X00,0X40,0X0F,0XF7,0XFF,0XC0,0X07,0XFF, 0X00,0X00,0X07,0XFF,0XFF,0X80,0X07,0XFF,0X08,0X00,0X07,0XFF,0XFF,0X00,0X0F,0XFF, 0X00,0X00,0X23,0XFF,0XFE,0X00,0X0F,0XFF,0X00,0X08,0X60,0XFF,0XFE,0X00,0X0F,0XFF, 0X00,0X40,0X20,0X3F,0XFE,0X00,0X1F,0XFF,0X00,0X00,0X10,0X0B,0XFF,0X80,0X1F,0XFF, 0X00,0X00,0X40,0X00,0X3F,0X00,0X1F,0XFF,0X00,0X00,0X10,0X00,0X3F,0X00,0X1F,0XFF, 0X20,0X00,0X02,0X00,0X3F,0X00,0X3F,0XFF,0X00,0X00,0X00,0X00,0X7F,0X80,0X3F,0XFF, 0X00,0X00,0X00,0X10,0X7F,0X80,0X7F,0XFF,0X00,0X00,0X00,0X80,0X7F,0X80,0X7F,0XFF, 0X10,0X00,0X00,0X00,0X7F,0X80,0XFF,0XFF,0X30,0X00,0X00,0X00,0X7F,0X80,0XFF,0XFF, 0X10,0X10,0X00,0X00,0X7F,0XC1,0XFF,0XFF,0X00,0X00,0X00,0X00,0X7F,0XF3,0XFF,0XFF, 0X00,0X00,0X01,0X00,0X3F,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X04,0X3F,0XFF,0XFF,0XFF, 0X00,0X00,0X00,0X00,0X3F,0XFF,0XFF,0XFF,0X00,0X00,0X10,0X80,0X1F,0XFF,0XFF,0XFF, 0X01,0X00,0X00,0X05,0X1F,0XFF,0XFF,0XFB,0X00,0X00,0X00,0X00,0X1F,0XF7,0XFF,0XFC, 0X00,0X00,0X00,0X00,0X1F,0XFB,0XFF,0XFF,0X00,0X00,0X40,0X00,0X19,0XFF,0XFF,0XFF, }; oled.clearDisplay(); oled.drawBitmap(3, 1, gImage_1, 64, 64, WHITE); oled.display(); } ...

2024年6月16日 · 4 分 · MoeJue

真の現実逃避

ずっとVR機器が欲しいという願いがあったのですが、今日ついに叶いました。 @本群吉祥物 のおすすめで、OculusブランドのVR一体型ヘッドセットを購入しました。 カードを開設して節約カードを入手 -> クーポンを取得 -> チャージ -> 注文 -> 一気に完了(心が痛む) Oculusブランドが中国市場に参入していないなどの理由で、ギガビットルーターもセットで購入しました。 届いたのは大きな箱が2つでした 1つはVR本体が入っていて、販売店からUSB充電バッテリーが追加でプレゼントされていました。SMARTOOOLSというスペインブランドで、なかなか良さそうです もう1つの箱には、ギガビットルーターと数百元もするUSB3.0リンクケーブルが入っていました。 ピーナッツの殻のような形をしたルーターです。 読めない説明書がたくさん、しかも外付けファン付き(#泣き笑い)。このルーターブランドも海外製なので、3ピンのプラグはヨーロッパ規格で、国内の3穴コンセントには変換アダプターが必要です。 外箱 - 裏面、下には人気ゲームのおすすめがいくつか載っています。 正面、シンプルでクールです。 パッケージの中の箱には、Oculusのロゴが印刷されています。 蓋を開けると、わぁ! Oculus Quest 6DoF VR、現在市場で最も強力なVR一体型ヘッドセットです。 公式にはコントローラー用の電池が1組、デバイスの基本的な操作説明書、そして分厚くて詳細すぎて読めない説明書が付属しています。 ポーズを決めて撮影、本体+左右コントローラー。 さて、電源を入れて使い始め、ずっと楽しみにしていたBeat Saber、VRChatなどをダウンロードして……現実逃避の旅を始めます……。 後日談: 普段、開封レビューはしません。なぜなら、専門的なレビューには専門的な学術知識が必要で、すごい専門用語を使いこなす必要もあるからです。しかし、私にはそれができませんし、私の記事を読んだ人を、真面目な顔をしてデタラメを言うことで誤解させたくもありません。私はただ、言いたいことを言っているだけです。 VRChatで皆さんをお待ちしています。後で時間があれば、私が遊んでいる動画をBilibiliにもアップロードします。 もしOculus Questについてさらに詳しく知りたい方がいれば、専門的なレビュー動画をおすすめします。 Oculus Quest VRは私たちを「ソードアート・オンライン」「レディ・プレイヤー1」からどれだけ近づけるのか? https://www.youtube.com/watch?v=2z-QyogFp9o (もし開けるなら)

2020年9月18日 · 1 分 · MoeJue

Android APK インストール パッケージの AndroidManifest.xml ファイルを表示します。

原因 先週、私は Android システムのファクトリープッシュ機能に取り組んでいました。一部のモデルは工場出荷時にオフラインにプッシュできないため、apk を解凍し、パッケージ化パラメータに問題があるかどうかを確認します。 序文 Android 開発では、自分のアプリケーションから他のアプリケーションのインターフェイスにジャンプする必要がある場合がありますが、他のアプリケーションのパッケージ名とクラス名が分からないと、これを行うのは困難です。最も簡単な方法は、アプリケーションの apk ファイルをダウンロードし、拡張子を zip または rar に変更して、ファイルを解凍することです。解凍したファイルの中に AndroidManifest.xml ファイルがあるのですが、開いてみると文字化けしていて恥ずかしいです。どうすればいいですか? AXMLPrinter2.jar は、一般的に使用される APK 逆コンパイル ツールです。これは主に、パッケージ名、バージョン番号、アイコン、その他の情報を含む apk ファイルを逆コンパイルするために使用されます。 AXMLPrinter2 を使用して androidmanifest.xml を逆コンパイルし、プレーン テキストで表示できます。 使用方法 ダウンロードツール AXMLPrinter2.jar ツールのアドレス: https://code.google.com/archive/p/android4me/downloads 表示する AndroidManfist.xml ファイルをツールと同じフォルダーにコピーします。 現在のフォルダーで DOS ウィンドウを開きます。 以下のコマンドを実行します。 java -jar AXMLPrinter2.jar AndroidManifest.xml » AndroidManifest.txt このコマンドを実行すると、フォルダー内にデコードされたファイルである AndroidManifest.txt ファイルが生成されます。 もちろん、実行後にエラーが発生するものもあります。「java」は内部コマンドでも外部コマンドでも、操作可能なプログラムやバッチ ファイルでもありません。 これは、Java 環境がインストールされていないか、環境変数が設定されていないことが原因で発生します。 JDK をインストールします まず、JDK のインストールプロセスを確認してみましょう 1\。 JDKをダウンロードしてインストールします JDK1.6、1.7、または 1.8 をダウンロードすることを選択できます。使いたいものをダウンロードしてください。 JDK をダウンロードするための公式 Web サイト https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html インストールは非常に簡単で、次のステップは簡単です。ここでは詳細には触れません。 2\。 JDK環境変数を構成する (1) コンピュータの「マイ コンピュータ」を右クリックし、Win10 では「このコンピュータ」を選択し、「プロパティ」を選択し、システムの詳細設定を選択し、新しいインターフェースで「環境変数」を選択します。「システム変数」を編集するだけです。 (2) 「新規」をクリックして「JAVA_HOME」という名前の変数を追加します。変数の値は「C:\Program Files\Java\jdk1.8.0_60」です。この値は、インストールした JDK パスです。インストールした場所にそのアドレスを使用するだけです。 「CLASSPATH」という名前の新しい変数を作成します。変数値は「.;%JAVA_HOME%/lib/dt.jar;%JAVA_HOME%/lib/tools.jar」です。必ず保存してください。 「.;」を見逃さないように注意してください。値にすべての記号を含める必要があります。 ...

2020年4月19日 · 1 分 · MoeJue

支付宝対面決済連携

当面付(対面支払い)は、その名の通り対面での支払いを指し、店舗がオフラインの消費シーンで迅速な集金を可能にするものです。当面付製品は、バーコード支払いとQRコード決済の2種類の支払い方法をサポートしています。 ここで連携するのはQRコード決済です。 QRコード決済とは、ユーザーがAlipayウォレットの「スキャン」機能を開き、店舗がレジのシーンで提示するQRコードをスキャンして支払いを行うモードを指します。このモードは、オフラインの実店舗での支払い、対面支払いなどのシナリオに適しています。ビジネスフローは以下の図の通りです。 当面付の契約は非常に簡単で、個人事業主/個人商店の契約が許可されています。そのため、この方法はオンラインのQRコード決済にも大量に利用されていますが、Alipayの関連規約に違反するため、一定のリスクがあります。技術交流として、この問題は一旦置いておきましょう。 技術連携としては、当面付製品を契約していなくても開発を進めることができます。 支払い機能は取引と資金に直接関わるため、開発者が支払い機能をデバッグしやすいように、オープンプラットフォームはサンドボックス環境(サンドボックス環境アカウントとサンドボックス版Alipayウォレットを含む)を用意しています。これにより、開発者はサンドボックス環境でデバッグできます。サンドボックスへの接続方法とサンドボックス環境への接続をクリックして詳細を確認してください。 そのため、私の開発ではサンドボックス環境を使用しています。何しろ中にはたくさんのお金があるので、自由に使えますからね。 まず、対応する開発言語のSDKをダウンロードします。ダウンロード:https://docs.open.alipay.com/194/105201/ QRコード決済ドキュメント:https://docs.open.alipay.com/194/106078/ キーの設定 取引当事者(加盟店とAlipay)の身元とデータセキュリティを確保するため、開発者はインターフェースを呼び出す前に、双方のキーを設定し、取引データの双方検証を行う必要があります。 Alipayオープンプラットフォーム開発アシスタントをダウンロードしてキーを生成してください。 キー生成後、開発者はオープンプラットフォーム開発者センターでキー設定を行う必要があります。設定完了後、Alipay公開鍵を取得できます。 設計と連携 私の設計ではポーリング(後述)を使用する必要がないため、追加していません。 以下は私の業務における関連コードです。 public function pay(){ if (request()->isPost()) { // (必填) 商户网站订单系统中唯一订单号,64个字符以内,只能包含字母、数字、下划线, // 需保证商户系统端不能重复,建议通过数据库sequence生成, $uid = Session::get('sq.uid'); $outTradeNo = order\_num() . $uid; // (必填) 订单标题,粗略描述用户的支付目的。如“xxx品牌xxx门店当面付扫码消费” $subject = '聚合平台用户积分充值'; // (必填) 订单总金额,单位为元,不能超过1亿元 // 如果同时传入了【打折金额】,【不可打折金额】,【订单总金额】三者,则必须满足如下条件:【订单总金额】=【打折金额】+【不可打折金额】 $totalAmount = input('post.pay\_money/f'); if($totalAmount < 1){ return \['status' => 1, 'msg' => '最低充值金额1元'\]; } if($totalAmount > 9999999){ return \['status' => 1, 'msg' => '充值最大金额不能超过9999999元'\]; } // (不推荐使用) 订单可打折金额,可以配合商家平台配置折扣活动,如果订单部分商品参与打折,可以将部分商品总价填写至此字段,默认全部商品可打折 // 如果该值未传入,但传入了【订单总金额】,【不可打折金额】 则该值默认为【订单总金额】- 【不可打折金额】 //String discountableAmount = "1.00"; // // (可选) 订单不可打折金额,可以配合商家平台配置折扣活动,如果酒水不参与打折,则将对应金额填写至此字段 // 如果该值未传入,但传入了【订单总金额】,【打折金额】,则该值默认为【订单总金额】-【打折金额】 // $undiscountableAmount = "0.01"; // 卖家支付宝账号ID,用于支持一个签约账号下支持打款到不同的收款账号,(打款到sellerId对应的支付宝账号) // 如果该字段为空,则默认为与支付宝签约的商户的PID,也就是appid对应的PID //$sellerId = ""; // 订单描述,可以对交易或商品进行一个详细地描述,比如填写"购买商品2件共15.00元" $body = "聚合平台用户积分充值" . $totalAmount . '元'; //商户操作员编号,添加此参数可以为商户操作员做销售统计 // $operatorId = ""; // (可选) 商户门店编号,通过门店号和商家后台可以配置精准到门店的折扣信息,详询支付宝技术支持 // $storeId = ""; // 支付宝的店铺编号 // $alipayStoreId= ""; // 业务扩展参数,目前可添加由支付宝分配的系统商编号(通过setSysServiceProviderId方法),系统商开发使用,详情请咨询支付宝技术支持 // $providerId = ""; //系统商pid,作为系统商返佣数据提取的依据 // $extendParams = new ExtendParams(); // $extendParams->setSysServiceProviderId($providerId); // $extendParamsArr = $extendParams->getExtendParams(); // 支付超时,线下扫码交易定义为5分钟 $timeExpress = "5m"; // 商品明细列表,需填写购买商品详细信息, // $goodsDetailList = array(); // // 创建一个商品信息,参数含义分别为商品id(使用国标)、名称、单价(单位为分)、数量,如果需要添加商品类别,详见GoodsDetail // $goods1 = new GoodsDetail(); // $goods1->setGoodsId("apple-01"); // $goods1->setGoodsName("iphone"); // $goods1->setPrice(3000); // $goods1->setQuantity(1); // //得到商品1明细数组 // $goods1Arr = $goods1->getGoodsDetail(); // // 继续创建并添加第一条商品信息,用户购买的产品为“xx牙刷”,单价为5.05元,购买了两件 // $goods2 = new GoodsDetail(); // $goods2->setGoodsId("apple-02"); // $goods2->setGoodsName("ipad"); // $goods2->setPrice(1000); // $goods2->setQuantity(1); // //得到商品1明细数组 // $goods2Arr = $goods2->getGoodsDetail(); // $goodsDetailList = array($goods1Arr,$goods2Arr); //第三方应用授权令牌,商户授权系统商开发模式下使用 $appAuthToken = "";//根据真实值填写 // 创建请求builder,设置请求参数 $qrPayRequestBuilder = new AlipayTradePrecreateContentBuilder(); $qrPayRequestBuilder->setOutTradeNo($outTradeNo); $qrPayRequestBuilder->setTotalAmount($totalAmount); $qrPayRequestBuilder->setTimeExpress($timeExpress); $qrPayRequestBuilder->setSubject($subject); $qrPayRequestBuilder->setBody($body); // $qrPayRequestBuilder->setUndiscountableAmount($undiscountableAmount); // $qrPayRequestBuilder->setExtendParams($extendParamsArr); // $qrPayRequestBuilder->setGoodsDetailList($goodsDetailList); // $qrPayRequestBuilder->setStoreId($storeId); // $qrPayRequestBuilder->setOperatorId($operatorId); // $qrPayRequestBuilder->setAlipayStoreId($alipayStoreId); $qrPayRequestBuilder->setAppAuthToken($appAuthToken); // 调用qrPay方法获取当面付应答 require ROOT\_PATH.'extend/f2fpay/config/config.php'; $qrPay = new AlipayTradeService($config); $qrPayResult = $qrPay->qrPay($qrPayRequestBuilder); // 根据状态值进行业务处理 switch ($qrPayResult->getTradeStatus()){ case "SUCCESS": $response = $qrPayResult->getResponse(); Db::name('order') ->insert(\[ 'uid' => $uid, 'pay\_id' => $outTradeNo, 'money' => $totalAmount, 'creat\_time' => time(), 'subject' => $subject \]); return \['status' => 0, 'msg' => '支付宝创建订单二维码成功!!!"','data' => \[ 'qr\_code' => $response->qr\_code, 'outTradeNo' => $outTradeNo \]\]; // $qrcode = $qrPay->create\_erweima($response->qr\_code); // echo $qrcode; // print\_r($response); break; case "FAILED": return \['status' => 1, 'msg' => '支付宝创建订单二维码失败!!!"'\]; // if(!empty($qrPayResult->getResponse())){ // print\_r($qrPayResult->getResponse()); // } break; case "UNKNOWN": return \['status' => 1, 'msg' => '系统异常,状态未知!!!"'\]; // echo "系统异常,状态未知!!!"."<br>--------------------------<br>"; // if(!empty($qrPayResult->getResponse())){ // print\_r($qrPayResult->getResponse()); // } break; default: return \['status' => 1, 'msg' => '不支持的返回状态,创建订单二维码返回异常!!!'\]; break; } return ; } } 以上が当面付の事前注文コードです。 このSDKについては、どうしても文句を言いたいです。誰が書いたデモなのか、PHPの例にlotusphpフレームワークを導入していて、大量の不要なものが含まれており、私たち開発者が受け入れられるかどうかを全く考慮していません。 私も少し時間をかけてSDKを簡素化し、必要な部分だけを取り出して自分のフレームワークに組み込み、namespaceとオートロードを追加しました。 QRコード決済には独自の機能があります—-非同期通知です。 これはオンライン決済で最も必要とされる機能でもあります。 レジが事前注文リクエストAPIを呼び出してQRコードを生成しユーザーに表示した後、ユーザーが携帯電話でQRコードをスキャンして支払いを行うと、Alipayは当該注文の変更情報を、加盟店が事前注文リクエストを呼び出した際に渡した非同期通知アドレス notify_url に沿って、POSTリクエストの形式で支払い結果をパラメータとして加盟店システムに通知します。 この非同期通知アドレスは、アプリケーション側で設定する必要があることを覚えておいてください。 ...

2020年4月4日 · 3 分 · MoeJue

ESP8266 シリアル WiFi モジュール - WiFi キラー

私はしばらく前に ESP8266 を購入し、それで遊ぶつもりでした。実際には数カ月間停滞し、その後2020年まで延期された。 ESP8266 は、幅広い実用的なアプリケーションを備えた WiFi モノのインターネット モジュールです。簡単に言えば、その機能は次のとおりです。Wi-Fi からデータを受信し、シリアル ポート経由で出力します。シリアルポートからデータを受信し、Wi-Fi経由でデータを出力します。 このものの技術は成熟しており、コストが低いため、価格はわずか数十元です。 開封 ここで買ったのは有機EL液晶画面付きパッケージ(将来のお楽しみに備えて) 最も古典的なのは WiFi キラーです。それでは、まずお楽しみとして WiFi キラーのファームウェアをフラッシュしてみましょう。 ファームウェア: https://github.com/samdenty/Wi-PWN?wi-pwn=7.0 原理は、認証解除メッセージを送信して、ルーター自体を切断する必要があるとクライアントに認識させ、Wi-Fi から切断することです。偽造ルーターは認証解除メッセージをクライアントに送信し、クライアントが Wi-Fi から積極的に切断されるようにします。また、カスタム ホットスポット フォージェリ (偽の Wi-Fi 信号をバッチで生成する) もサポートしています。 パソコンとの接続には、データ通信が可能なデータケーブルを使用してください。デスクトップ コンピュータを背面ポートに接続してみます。 接続後、Windows システム コンピュータは、下の図に示すように、ドライバを自動的にインストールします。この COM を覚えておいてください。 また、ch341ser ドライバーと、USB 用の WINDOWS ドライバー インストール パッケージをシリアル ポート CH341/CH340 にインストールする必要があります。プロンプトに従ってインストールするだけです。これは別途ダウンロードする必要があります ファームウェアの書き込み ここで使用するのは、NodeMcu FIRMWARE PROGRAMMER 書き込みツールです。 ここの COM ポートとして、前に見たものを選択します。または、デバイス マネージャーで ESP8266 開発ボードがどのポートに接続されているかを確認してください。 config でファームウェア アドレスを選択し、その他はデフォルトで変更しないままにします。 詳細 - ボーレート ボーレートは、開発ボードの裏面に書かれている内容によって異なります。 写真の通り、丸で囲った部分が 設定後、フラッシュ (F) キーをクリックして書き込みを開始します。このプロセスには時間がかかる場合がありますので、そのままお待ちください。 書き込みが完了したら、一度抜き差ししてください。書き込みが成功すると、wi-pwn という名前のパブリック WiFi が表示されます。 リンク後、ブラウザーでこの背景 http://192.168.4.1/ が開き、ガイダンスに従ってください。 ここで WiFi をバッチで偽造する方法を説明しましょう。 「Beacom」をクリックして作業を開始します。 動作ステータス、実行中、青色のインジケータライトが点滅して点灯したまま なぜ長い間携帯電話でいくつかしか検索できないのかわかりません。 他にもたくさんの機能があるので、一つずつ試していくつもりはありません。 要約: 要約するものは何もありません。私も初めてのプレイです。プレイの全プロセスを記録し、私の経験を共有します。 今回は他人が書いたファームウェアを使用しました。次回は私が自分で書く番です。

2020年2月3日 · 1 分 · MoeJue

美しすぎるAlibaba Cloud画像ホスティングツール

一度サボると気持ちいい、ずっとサボればずっと気持ちいい。うっかりまた一ヶ月も更新をサボってしまい、元旦にさえ顔を出すこともなく、お恥ずかしい限りです。 その埋め合わせとして、今日の週末にAlibaba画像アップローダーを一つ公開します。 以前のプログラムは多くの方からインストールが難しいと言われましたが、今回のAlibaba画像アップローダーは非常にシンプルです。サーバーにアップロードしてアクセスするだけで利用でき、設定は一切不要。本当にこれだけです。(決して手抜きで何も書いていないわけではありません) インターフェースをご覧ください。とても美しいでしょう? 非常にシンプルなため、今のところデモサイトはありません。もし設置が完了した方がいらっしゃれば、下部のコメント欄にご自身のアップローダーのURLを投稿して、他の方々の参考にしていただけると幸いです。 プロジェクトページ ここ数日で新しいロゴに変更しました。これもまた綺麗でしょう?(会社のPhotoshopの達人にお願いして作ってもらいました) 幻想領域画像アップローダーも認証コードを導入しました。皆さん、不適切な画像をアップロードしないようにお願いしますね。 最後に 遅くなってしまいましたが、それでも言わせてください。皆様の新しい一年が、楽しく幸せなものでありますように!

2020年1月12日 · 1 分 · MoeJue