絞り込み

最新の投稿

プログラミング Polygon
プログラミング

Minecraftでプレイヤーの参加をツイートするbotの作り方

こんにちはさしぐめです。初投稿の今回はマインクラフトとTypeScriptを使ったbotについて書こうと思います。 Twitterアプリを申請する Developer PortalでTwitterアプリの申請をしましょう。この時、botとして使いたいアカウントで申請するのがベストです。 間違えてメインアカで申請しちゃった場合は、OAuth1.0aを使ってサブアカのトークンを発行しましょう。(手順は割愛) また、アプリの権限はRead & Write にします(DM権限は使いません)。 APIを用意する Webhookの受け皿にはCloud Functions for Firebase (実質GCP)を使います。 Herokuでもいいんですが、個人的に ログが見やすいサーバーレスかつ応答が早いFirestore等と連携できる外出先で確認できるアプリがある という理由で選びました。 https://firebase.google.com/pricing/ なお、従量制プランを選択する必要があり、処理時間と回数が膨大になると請求される可能性もありますのでご注意ください。 ステップ1: 認証情報を用意 Firebaseプロジェクトを用意して、開発環境を用意します。ここの手順は日々変わるので割愛します。 また、Cloud Functions for Firebaseでは.env ではなくCLIで一つづつ環境変数を設定していきます。 後述するWebhookプラグインはリクエストのヘッダーをカスタマイズできません。仕方なくbodyでパスフレーズを送って認証します。 まずはオレオレパスフレーズを作ります。OAuthでもなんでもないただのパスワードなので、個人用途以外で使わないでください。$ cd functions/ # 32桁のオレオレパスフレーズを生成 $ openssl rand -base64 32 # configに登録 $ firebase functions:config:set minecraft.auth="(オレオレパスフレーズ)" もっといい生成方法があったら教えてください>< アプリの申請が通ると以下のキーが手に入ります。これらを全部コンフィグに登録します。コンシューマキーコンシューマシークレットユーザのトークンユーザのシークレット $ firebase functions:config:set twitter.key="(コンシューマキー)" $ firebase functions:config:set twitter.secret="(コンシューマシークレット)" $ firebase functions:config:set minecraft.auth=(ユーザのトークン)" $ firebase functions:config:set minecraft.auth="(ユーザのシークレット)" # エミュレータ用ファイルを生成 $ firebase functions:config:get > .runtimeconfig.json {   "twitter": {     "user_secret": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",     "user_token": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",     "key": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",     "secret": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"   }, "minecraft": {     "auth": "(オレオレパスフレーズ)"   } }.runtimeconfig.json がこんな感じになります。これがローカルでテストする時の環境変数代わりになります。 functions/models/AdminConfig.d.tsexport interface AdminConfig {   twitter: {     key: string;     secret: string;     user_token: string;     user_secret: string;   };   minecraft: {     auth: string;   }; }TypeScriptの場合、こんな感じで型を作っておくと自動補完が楽です。 ステップ3: APIのエンドポイントを用意 さあいよいよAPIを作ります。 $ npm i twitter-api-clienttwitter-api-client というライブラリを使います。 FirebaseなのでFirebaseが用意しているfunctions.https.onRequest を使いますが、別にexpressでもいいです。 functions/src/twitter/post.tsimport * as functions from 'firebase-functions'; import { AdminConfig } from '../models/adminConfig'; const config = functions.config() as AdminConfig; import { TwitterClient } from 'twitter-api-client'; const client = new TwitterClient({ apiKey: config.twitter.key, apiSecret: config.twitter.secret, accessToken: config.twitter.user_token, accessTokenSecret: config.twitter.user_secret, }); const post = functions.region('asia-northeast1').https.onRequest(async (request, response) => { if (request.method !== 'POST') { response.status(405).json({ message: `POSTメソッドを使ってください`, }); return; } const body: { // マイクラサーバーのplugins/SimpleWebhooks/config.ymlで内容は定義してある tweet?: string; // コンフィグで定義 auth?: string; // テスト用 test?: boolean; } = request.body;   functions.logger.debug(`Received body: ${JSON.stringify(body)}`); if (Object.keys(body).length == 0) { response.status(400).json({ message: `bodyはJSONオブジェクトにしてください`, }); return; } if (body.auth !== config.minecraft.auth) { response.status(401).json({ message: `認証できませんでした`, }); return; } let tweet = body.tweet; if (!tweet) { response.status(422).json({ message: `ツイート本文を指定してください`, }); return; } // testがtrueならツイートはしない if (body.test) { response.status(200).json({ message: `テスト成功`,       ...body,     }); return; } // 以下、Twitter APIと通信する try { await client.tweets .statusesUpdate({ status: tweet, }) .then(async (apiResponse) => { // https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-update         // レスポンスにcreated_atがあればツイート成功 if (apiResponse.created_at) { response.status(200).json({ message: `ツイート成功`, ...apiResponse }); functions.logger.info(`Successfully tweeted: ${tweet}`); } else { response.status(500).json( apiResponse ?? { message: `Twitter APIからの応答がありませんでした`, } ); } }) .catch((e) => { response.status(500).json({ message: `Twitter API呼び出し中のエラー: ${JSON.stringify(e)}`, }); }); return; } catch (e) { response.status(500).json({ message: `その他のエラー: ${JSON.stringify(e)}`, }); } return; }); export default post; ステップ3: フォルダにまとめる expressならこんなことしなくて良いですが、Firebaseの書き方だとこうやってエンドポイントを整理します。 functions/src/index.tsconst twitter = require('./twitter'); exports.twitter = twitter; functions/src/twitter/index.tsexport { default as post } from './post'; こうすることで、エンドポイントが /twitter-post になります。 ステップ4: テストとデプロイ $ npm run serve Firebaseのエミュレータが立ち上がり、 http://localhost:5001/(プロジェクト名)/asia-northeast1/twitter-post でテスト可能になります。 curl --location --request POST 'http://localhost:5001/(プロジェクト名)/asia-northeast1/twitter-post' \ --header 'Content-Type: application/json' \ --data-raw '{     "tweet": "テストツイート",     "auth": "(オレオレパスフレーズ)",     "test": true }' こんな感じのリクエストを送ればテストできます。 $ npm run deploy デプロイすると https://asia-northeast1-(プロジェクト名).cloudfunctions.net/twitter-post にAPIが公開されます。 マイクラサーバー側の設定 あとはマイクラサーバーからWebhookを送るだけです。 Webhookプラグインを入れる https://github.com/Akenland/SimpleWebhooks SimpleWebhooks プラグインを使います。PaperMCの1.16.5で動作を確認しました。 プラグインの設定 $ vi plugins/SimpleWebhooks/config.yml config.yml webhooks:   join:     twitter-join:       url: https://asia-northeast1-(プロジェクト名).cloudfunctions.net/twitter-post       json:         tweet: "{PLAYER_DISPLAYNAME}が{SERVER_MOTD}に参加しました!"         auth: "(オレオレパスフレーズ)" こんな感じで、URLと送信するJSONを設定してください。YAMLマジで苦手。 豆知識: Cyberduckなら、サーバー上のファイルをローカルのように編集できます。宗教的こだわりがない場合は例えばVSCodeで開いて編集しましょう。 動作確認 YAMLを保存したら、マイクラサーバー側でwebhookをリロードします。 > webhooks reload サーバー再起動の必要はなく、このコマンドを実行するだけです。 プレイヤーが参加すると、Firebaseの管理画面にログが出るはずです。 .sasigumeが自由にサバイバル!に参加しました!#mc_asobinon 参加方法はこちら→ https://t.co/N1cU2977TQ— アソビノン - 誰でも編集できる攻略サイト (@asobinon) July 23, 2021 うちのサーバーではこんな感じでツイートしています。 --- 以上、マイクラサーバーと連携するbotの作り方でした。

> 内容を見る

ガジェット/ハードウェア Polygon
ガジェット/ハードウェア

非サポートハードウェアにWindows 11を無理やり入れるお話

非サポートハードウェアにWindows 11を無理やり入れるお話どうも,しげです.6月25日にWindows 11が発表になりましたね.Windows 11ではAndroidアプリのサポートやUIの大幅刷新など大きな変化がありましたが,動作要件も大きく変化しました.古いハードウェアを徹底的に排除する成約が動作要件に盛り込まれ,ごく一部の例外を除いてWindows Insider Previewに入っていてもインストールができなくなってしまいました.厳しい動作要件Windows Insider Previewに入っても,動作要件外のデバイスにはWindows 10のPreviewが提供されるだけで,Windows 11が提供されることはありません.プロセッササポートが,第7世代Intel Core以降か第1世代AMD Ryzen以降というきつい制約があるせいで,「このPCではWindows 11を実行できません」というエラーが表示されます. ここでWindows 11の動作要件について見てみましょう. プロセッサの動作要件は,Windows 10のときから大きく変化していない気がします.Windows 11は64bit版のみの提供となったため,メモリ要件が4GBに増加しています.記憶装置の要件も32GBから64GBに増加しました.そしてここからが問題の動作要件です.システムファームウェアがUEFIを必須とするようになりました.Legacy BIOSで動作する古いPCはおさらばです.一般に第1世代Intel Core以前のマシンは対応していない気がします.そしてさらにTPM.TPM2.0は第4世代Intel Core以降に搭載されるようになりました.第2・3世代はTPM1.2で対応していませんし,Windows 7がTPM2.0をサポートしていなかったのもあり,第6世代Intel CoreまではTPM1.2が搭載されている可能性があります.メーカー側が変更するツールを提供していればバージョンを変更できる可能性があります.でも,そうでないデバイスは例え第4世代Intel Core以降であろうと動作要件外となります.第7世代Intel Core以降はWindows 7・8.1用のデバイスドライバーが提供されていないため,これらのOSの動作を考える必要がありません.よってTPM2.0以降が標準で搭載されているため,動作要件内に含まれる可能性が高いです.Surface Pro 2はTPM1.2でWindows 11には対応していませんでした(泣).Surface Pro 3はTPM2.0なのになんで...どちらも第4世代Intel Core搭載のデバイスじゃん!納得行かねぇ!!非サポートハードウェアにはインストールできない?とは言え,せっかくのデバイスが使えないのは残念としか言いようがありません.何とかインストールする方法はないのでしょうか? ...ありました.ここでは,その方法を紹介していきます.自己責任で試してみてください. 今回の検証環境は次のとおりです.1コアのIntel Celeron,1GBのメモリを搭載していたLenovo SL500 2746RP4を魔改造したデバイスです.ご覧の通り,Windows 11のほとんどの動作要件を満たしていません(笑). Windows 11のインストールに必要なもの8GB以上のUSBメモリ(中身が消えてもいいもの)Windows 7以降搭載の使用可能なPC1台(インストールしたいPCとは別のPC,できるだけ高性能なもの)インターネット環境Google ChromeなどのWebブラウザ7-ZipRufusUUP dumpWindows ISO DownloaderWindows 10 21H1 64bit版ISO(古いバージョンでも行けるかもしれませんが,念の為最新版)Windows 11 ISOちょっと待って,Windows 11のインストールメディアって公開されてないんじゃないの?と思われた方もいると思います.その通りです.Windows 11は2021/7/10現在,Windows Insider PreviewのWindows Update経由でしか配信されておらず,ISOイメージも公開されていません. ここではUUP dumpの力を借りて,サーバから必要なファイルをダウンロードして自分でISOをビルドします.ビルドはPCの性能にもよりますが,30分程度はかかります.UUP dumpを用いてWindows 11のISOの作成まずはUUP dumpのホームページにアクセスします. 1.Latest Dev Channel Buildのx64版をクリックします. 2.Cumulative Update for Windows 11をクリックします. 3.LanguageをJapaneseに変更してNextをクリックします. 4.必要に応じてエディションを加えてNextをクリックします. Include updates(Windows converter only)のチェックを外し,Create download packageをクリックします. 5.ダウンロードしたzipファイルを展開し,uup_download_windowsを実行します.自動でダウンロードとビルドが始まり,しばらく待っていればISOが生成されます.Windows ISO Downloaderを用いたWindows 10 21H1のISOのダウンロード次にWindows ISO Downloaderのダウンロードページにアクセスします. 1.Download:Windows-ISO-Downloader.exeをクリックしてダウンロードします. 2.ダウンロードしたファイルを開いて,Windows ISO Downloaderを起動します. 3.Windows 10のラジオボタンをクリックします. 4.Windows 10 Version 21H1のHome/Proエディションを選択し,確認ボタンを押します. 5.日本語を選択し,確認ボタンを押します. 6.右側に「64ビット版のリンクをコピー」のボタンが表示されるので,リンクをコピーし,WebブラウザのURLバーに貼り付けてISOをダウンロードします(Webブラウザでやったほうがダウンロードが速いです).Rufusを用いたWindows 10のインストールメディアの作成次にRufusでISOファイルをUSBメモリに焼いていきます.Rufus Portableを用いれば,PCにインストールしなくても使用できます. 1.一番上のデバイスのところから,インストールメディアを作成するUSBデバイスを選びます. 2.Windows 10 21H1のISOを選択します. 3.パーティション構成をMBR/GPTから適切に選びます.Legacy BIOSの場合はMBR,UEFIの場合はGPTとなります.間違うとインストールメディアが起動しません.今回の場合はLegacy BIOSなのでMBRを選びます. 4.スタートを押して書き込みを始めます.7-Zipを用いたWindows 11のISOの展開次に7-Zipで,先程ダウンロードしたWindows 11のISOを展開します.7-zip 19.00の64ビット版exeをインストールします. 1.右クリックメニューから7-zip > "ファイル名"に展開を選ぶ 2.展開されたフォルダのsourcesフォルダを開きます. 3.install.wimを作成済みのUSBインストールメディアのsourcesフォルダにコピーして上書きします. これで,Windows 10のインストールメディアだけど,実際にはWindows 11がインストールされるインストールメディアの完成です.install.wimファイルは,Windowsのインストールイメージで,実際にインストールされるWindowsの実体です.これを置き換えることで異なるバージョンのWindowsをインストールするわけです. 動作要件を満たすかどうかはinstall.wimではなく他のファイルでチェックされているので,それがないWindows 10のインストールメディアをベースに使用します.ここまでお疲れさまでした.後は通常通りインストールするだけ自作PCを組んだり,Windowsをクリーンインストールしたりしたことがある人には説明するまでもないでしょう.ちなみに,Windows 10をインストールしたことがあるデバイスであれば,プロダクトキーがありません > 適切なエディションを選択することでライセンス認証が通ります.Windows 10をクリーンインストールする場合と同じ感じですね.インストールの仕方は先人の記事がたくさんあるので,ここでは説明しません.強いて言うならセットアップが終わるまでインターネットには接続しないようにしましょう(Microsoftアカウントを強制されます).制限された設定で続行すれば大丈夫です. Windows 11,結構良さそうWindows 10アンチな筆者ですが,Windows 11は良さそうに感じています.Windows 7の正統後継OSになれるんじゃないでしょうか?年末のリリースに向けてMicrosoftには頑張って欲しいと思います.それでは.

> 内容を見る

ガジェット/ハードウェア Polygon
ガジェット/ハードウェア

呪われた(自分で呪った)フォルダを解呪した話

こんにちは。鮭です。 皆さんはWindowsでこれまで使えていたファイルやフォルダにアクセスできなくなってブチギレたことはありますか? 私はあります。別にブチギレてはいませんが、先日以下のようなやりとりがありました。 呪いについて先輩:Dドライブに置いたOneDriveのフォルダを(管理者を含む)別のユーザーから見れへんようにしたいんやけど、どうしたらいい? 私:多分プロパティ>セキュリティ>詳細設定から自分のユーザーにフルコントロール権限を付与して、Administratorsを全て拒否にすればいいんじゃないですかね? 先輩:すごいそれっぽいみたいな感じでやったんですが、まさかのその先輩からもアクセス不可能になってしまいました(タイトルにもある「呪い」)。 何がいけなかったのでしょうか? まあどう考えてもAdministratorsの権限を拒否してるからですね(とは言え、単に指定しない状態にしただけではAdministratorsならば権限を取得することが可能) なので、先輩の言ったようなことはWindowsのファイルシステムのみではおそらく実現できません。 まず呪いを解く 例のフォルダは70GBもあります。いくらDドライブが3TBあるからといって、解呪しないで放置するわけには行かないサイズ感なので、なんとかします。 さて、まずは状況を把握しましょう。 件のフォルダがどのようにして呪われたかというと、他人が所有権を持っているフォルダについて、自分のユーザーにフルコントロール権限を与え、UsersやAdministratorsから権限を剥がすとこうなってこうなってこうなります ウィザードにあるように、所有者を変更すればアクセスできるのですが、サブディレクトリにも拒否権限が引き継がれており、数百~数千個のファイルを手で相手するのは無理があります。 ACL関連のコマンドを利用 所有権とアクセス権が失われてしまった状態から復旧するのに役に立つコマンドがあります。 それが、 takeownとicaclsです。 百聞は一見に如かずといいますし、実際に使ってみましょう。 PS D:\> takeown /f "cursed-folder" /r /a 成功: ファイル (またはフォルダー): "D:\cursed-folder" は現在 Administrators グループによって所有されています。 成功: ファイル (またはフォルダー): "D:\cursed-folder\child" は現在 Administrators グループによって所有されています。 成功: ファイル (またはフォルダー): "D:\cursed-folder\child\grandchild" は現在 Administrators グループによって所有されています。 成功: ファイル (またはフォルダー): "D:\cursed-folder\child\grandchild\新しいテキスト ドキュメント.txt" は現在 Administrators グループ によって所有されています。 PS D:\> icacls "cursed-folder" /reset /t 処理ファイル: cursed-folder 処理ファイル: cursed-folder\child 処理ファイル: cursed-folder\child\grandchild 処理ファイル: cursed-folder\child\grandchild\新しいテキスト ドキュメント.txt 4 個のファイルが正常に処理されました。0 個のファイルを処理できませんでした 解説します。 takeownコマンドはファイルの所有権を特定のユーザーに与えるためのコマンドです。 /fオプションでファイルを指定し、/rオプションで再帰的に処理、 /aオプションで管理者(Administratorsグループ)に所有権を与えます。 これによって管理者がアクセス権を変更できるようになります。 icaclsコマンドはファイルのアクセス権を指定するためのコマンドです。 第一引数でファイルを指定し、/resetオプションでアクセス権をリセット(デフォルトの継承値にする)、/tオプションで再帰的に処理しています。 これによってアクセス権が元の状態に戻ります。 良かったね、これで元通りだよ。 当初の目的は 当初の目的は、「管理者を含む自分以外のユーザーからアクセスできないようにする」ことでした。 この手順はアクセス権をもとに戻すだけであって、目的は達成できていません。 ではどうすればいいかというと、EFS(Encrypted File System)を利用します。 ……部室のPC、Windows 10 Homeやから使えへんわ!! ちなみにEFS(上図の「内容を暗号化してデータをセキュリティで保護する」)を使えば、ユーザーに紐付けされた秘密鍵を利用して復号するので、目的が達成できます。自宅のPCで試してみたところ、うまく管理者でもアクセスできないようになりました(特殊な方法を使えばどうか分かりませんが)。やはりWindowsはProを買えということだな ~終~ ちなみにOneDriveにはPersonal Vaultという機能がありますが、無料では3つまでしかファイルを追加できず、組織アカウントでは利用できません。 本当に終われ

> 内容を見る

プログラミング Polygon
プログラミング

Ktorを知る ~Pipeline編~

こんにちは、オキリョウと申します! 前回、Ktorの特徴について解説させていただきました。(https://oucrc.net/articles/ia_sv-bbmz) そこで今回はKtorで重要な概念であるPipelineについて解説していきたいと思います。 PipelineとはPipelineとは、Ktorにおいて処理を順序良く処理していくためのものです。 ライフサイクルを定義するためのもの、みたいな感じに考えていただけてたらと思います。 前回、Ktorには以下の特徴があるといいました。拡張性が高く、柔軟非同期処理に強いこれらはPipelineを導入することで実現しています。 Ktor内では、継承可能なクラスとして定義されており、そこらじゅうで使われています。Ktor内のクラスの継承元をたどっていくと一枚嚙んでいた・・・ということも珍しくありません。 それではより詳しく見ていきましょう。 Pipelineを図で表すと以下のようになります。 この画像の場合、オレンジ色の向きへと処理が流れていきます。 つまりフェーズ(Phase)1->フェーズ2->フェーズ3->フェーズ4の順番に処理が流れていくということです。 各フェーズ同士は依存していません。しかし、共有する必要のある値ももちろん存在します。 それらはPipelineが所有しているPipelineContextに保存しておき、そこから値を取り出す仕組みになっています。 また、フェーズは好きなところに付け足すことも可能です。 このように、左から右へと、それぞれ独立したフェーズを処理していく流れがPipelineです。 Pipelineの使用例では、Pipelineがどのように使われているのか見てみましょう。 例えば、サーバーサイドアプリケーションの中でも必須である、「リクエストを受けとってリスポンスを返す」という部分はPipelineで実装されています。(ApplicationCallPipelineという名前のクラスです) このオレンジ色の矢印がApplicationCallPipelineです。 こんな感じに差し込まれています。 リクエストを受けとって、そこから各フェーズを実行してリスポンスを作成、返すという感じです。 ではより具体的に見ていきましょう。 このような感じになっています。 左から順番にSetup -> Monitoring -> Features -> Call -> Fallbackの順番に処理が流れています。これら青い部分がフェーズですね。 これらのフェーズの役割は以下の通りです Setup: callやattributesを用意する Monitoring: callを追跡するための部分で、ログやコードの評価を行う、エラーハンドリングなどに使われる Feature: 大体のFeatureが入るところ Call: callを完全に作りきるために利用するところ Fallback: ハンドリングされていないcallを何らかの形で処理する部分 補足call:ApplicationCallの事。リスポンスであったりattributesであったりを管理している attributes:DIコンテナ(多分、詳しく知りたい人は公式をチェック) Feature:Ktorの追加機能の事。後述 それぞれのフェーズを順に通していく中で徐々にリスポンスを作成しています。 この流れがPipelineです。 ちなみにRouting等もPipelineを使用しています。 ではPipelineについてある程度説明したところで拡張性が高く、柔軟非同期処理に強いを実現している方法について説明していきたいと思います。 拡張性が高く柔軟Pipelineはそれぞれのフェーズを定められた順に実行していくことは先ほどまで書いた通りです。 また、これらのフェーズは互いに依存しておらず、好きなところに差し込むことができるということも説明したと思います。 必要なフェーズを差し込んだり、要らないフェーズを抜くことができるということは、必要な処理だけを記述することができるということです。 それに加えて、実はフェーズの間に処理を入れることも可能です。(intercept) 先ほどちらっと登場したFeatureというのは、このような処理を練りこんだライブラリといえます。 そのようにすることで、本来複雑になるはずのライブラリの作成、導入が非常にシンプルにできるわけです。 せっかくですので、リスポンスのヘッダーに現在時刻を付ける、というFeatureを定義、導入したコードを掲載します。 まずは現在時刻を付けるFeatureの定義からpackage com.example import io.ktor.application.* import io.ktor.response.* import io.ktor.util.* import io.ktor.util.pipeline.* import java.time.LocalDateTime class SendTimeHeader(configuration: Configuration) { private val name = configuration.headerName //設定 //この場合、ヘッダーのkeyの部分を設定できるようにする class Configuration{ var headerName: String = "Send-Time" } //差し込まれる処理 private fun intercept(context: PipelineContext<Unit, ApplicationCall>){ //設定された値と、現在時刻をheaderにセット context.call.response.header(name, LocalDateTime.now()) } //アプリケーション実行時に行われる処理 companion object Feature : ApplicationFeature<ApplicationCallPipeline, Configuration, SendTimeHeader>{ //Attributeを設定 override val key: AttributeKey<SendTimeHeader> = AttributeKey("SendTimeHeader") //install時の処理 override fun install(pipeline: ApplicationCallPipeline, configure: Configuration.() -> Unit): SendTimeHeader { val configuration = Configuration().apply(configure) //インスタンスの作成 val feature = SendTimeHeader(configuration) //ApplicationCallPipelineのCallというフェーズに以下の処理を入れる pipeline.intercept(ApplicationCallPipeline.Call){ //先ほど定義した、interceptの処理 feature.intercept(this) } return feature } } } こんな感じです。 非常に見づらくなってしまい申し訳ないですが、雰囲気は理解できたかと思います。 実装の流れはそのうち別の記事で説明すると思います。 ちなみに今回の場合は、ApplicationCallPipeline↓ のCallのところにこちらの処理が入ります。 それでは利用するときのコードも掲載します package com.example import io.ktor.application.* import io.ktor.response.* import io.ktor.routing.* import io.ktor.util.* import io.ktor.util.pipeline.* import kotlinx.coroutines.launch fun main(args: Array<String>) = io.ktor.server.netty.EngineMain.main(args) fun Application.main(){ //先ほどのFeatureの導入 install(SendTimeHeader){ headerName = "Time" } routing { //ホームルートにアクセスしたときに「Hello World」を返す get("/"){ call.respondText("Hello World") } } } これだけですね。 installのところでFeatureを指定(必要ならば設定も行う)するだけで、すべてのルートにて、現在時刻が追加で刻まれたヘッダーが返却されます。 一見複雑に見えるかもしれませんが、普段は利用するだけ、つまり下側だけですので非常にシンプルです。 上側の方も、やっていることはそこまで複雑ではなく、他のフレームワークで同じことをすることを考えたらはるかに簡単だと思います。 他にも認証機能やログを取る機能もこんな感じで簡単に導入できます。 このように、簡単にいろいろなライブラリを導入したり、作成したりすることができます。 ですので、自分が好きなライブラリで固めることも可能ですし、かなり規模の大きいアプリケーションを作成することも全然可能です。 これもPipelineだからできることです。 非同期処理に強い前回、KtorではCoroutineというものを使い倒しており、そのために非同期処理に強いという話を書きました。 Pipelineもこの流れを強く受けています。というのも、PipelineContextはCoroutine Scopeを継承しており、Coroutine Scopeとして扱うことができるためです。 例えばrouting { //ホームルートにアクセスしたときに「Hello World」を返す get("/"){ launch{ TODO("Coroutineを起動") } } } という感じで、さらっとCoroutine builderを呼び出すことができます。 get()関数は引数としてPipelineContextを取るからですね。 このように、わざわざCoroutine Scopeを定義する必要もないため、気軽に非同期処理を書くことができます。 また、非同期処理が強い理由としてProceed関数およびProceedWith関数の存在もあります。 ややこしい説明になりますが、この関数を実行したインターセプター(フェーズの間に入れる処理群の事)の処理は後回しにされます。 なんの役に立つのかと思うかもしれませんが、意外と使えます。 例えばかなり重たい処理があったとします。その時はPipelineと違うCoroutineを立ち上げて、その後Proceed関数を実行します。 本来だとCoroutineを立ち上げた場合は、そのCoroutineの処理が終わるまで待機しないといけないため、Coroutineの処理が長ければ長いほどレスポンスが遅くなります。 しかし、後回しにすることで、かなり重たい処理とほかの処理を並列に実行することができます。 重たい処理の完了を待つことなく別の処理を進めることができるため、早く処理を終わらすことができるというわけです。 このようにPipelineを用いることで、非同期処理を簡単に、しかし効果的に書き上げることができるのです。 他にもPipelineではCoroutineを生かして処理の効率化を図っていますが、ここでは省略しています。 まとめいかがだったでしょうか?ちょっと説明が難しくなってしまい、申し訳ございません。 ただ、このフレームワークはかなり面白いので、実際に組んでみる価値は大いにあります。 また、公式がより分かりやすく説明してくれています(英語ですが) ぜひそちらの方にも目を通してみてください! あと、ここまでの説明は公式の解説と、コードを読んでみた結果から書いています。 何かしら間違っていたら申し訳ございません。

> 内容を見る

プログラミング Polygon
プログラミング

音 割 れ ひ じ き (前編)

※想像以上にサムネが怖かったので苦情があればすぐに変えます.なんなら自主的に変えます.なので苦情があれば遠慮せずに言ってください.文句は一切言いません. 突然ですが,皆さんは音を割りたいと思ったことはありますか? ありますね?(圧力) しかしながら,最近,音割れブームは衰退してきており,音割れ動画の投稿数は日に日に減少の一途をたどっています. そこで,音割れ動画愛好家である私が音割れ動画の復興を図るため,この場を借りて,音割れ動画の作り方を伝授しようと思います. まず名乗れよメガネ とお思いになった人もいるかもしれないので,改めて自己紹介をしておきます. どうも,新2回生のひじきです. 最近,換気扇を回しても風呂が完全に乾かなくなってきて非常に困っております. よろしくお願いします. というわけで前置きはさておき,早速音を割っていこうと思います. と思ったのですが,まずは形からということでビジュアル面の方から作っていきたいと思います.(?????????) そして今回は,音割れブームの火付け役であり,私の知る全音割れ動画の中でも最も好きな動画である「音割れポッター」をオマージュしながら音を割っていきます. というわけでまずはこちらの画像をご覧ください. 何度見ても笑ってしまう.(諸般の事情によりモザイクをかけております) そしてここから ①魔法の杖 ②ポッターの外見の作成 ➂光る眼鏡 ④ポーズ の4つを主に寄せて再現しようと思います. 1.杖の再現 そういうことでまずは魔法の杖を再現しよう,というわけで近くのダイソーに向かい,こちらの4点を購入してきました. 1つ目は光を出すための懐中電灯と電池.令和では魔法は電池を用いて使用することができます.驚きですね. 2つ目は光の色を白からピンク色へと変えるための赤い平巻テープ.ちなみに体感3mぐらいしか使用してないので,残りの197m分は産廃と化しました. 3つ目は平巻テープを懐中電灯に張り付けるセロハンテープ.これに至っては家に元々セロハンテープがあったことに後から気づいたので購入した時点で産廃でした. ということで早速魔法の杖を作っていきます. まず,懐中電灯に単3電池をセット. 次に,平巻テープを適当な長さに切り取り,セロハンテープを使って懐中電灯に固定します. 完成\(^o^)/ +ドライバーが見つからなかったり,平巻テープが貧弱すぎてすぐに破れてしまったりなど,ここまで作るのすら普通にダルかったので想像よりも遥かに早く終わってホッとしました. というわけで,点灯させてみるとしましょう. 点灯!!!!!!!!!! あ れ ? 全然ピンクじゃないんだが….どうしてくれんのこれ どうやら平巻テープ1枚だとピンク要素が全然足りなかったようです. というわけで追加しました. 意外にも余裕で1時間かかった上にこの時点で午前5時なので著しく疲れました.そして眠い. こんだけ頑張ったんだから,きっと俺も魔法が使えるようになってるはずだ…. 点灯!!!!!!!!!!!!!!!!!!! 微妙 というかそもそも若干ピンク色にはなっているのですが,懐中電灯の性質上,如何せん光が発散してしまい, 某ポッターの杖の様に杖自体が光ってるようにはどうしても見えませんでした. 正直,この超絶しょうもない作業を1時間続けていたことによる疲労もあり,この時点でもう計画倒れムードでした. 終わりや…. しかし完全に戦意喪失したその時,偶然にも彼の目に飛び込んできたもの,それはだいぶん前から放置されていたトイレットペーパーの芯であったのだ. _人人人人_ > 合体 <  ̄Y^Y^Y^Y^ ̄ なんと今まで分散されていた懐中電灯の光がトイレットペーパーの芯を使用することにより,一ヵ所に集約され, より杖っぽく見えるようになりました. ぶっちゃけ,色々ツッコみどころの多い感じではありますが,これ以上改善しようと思うと気が狂いそうなので いったん杖はこれで完成ということにしておきましょう. この時点で朝6時なのでさすがに寝ます.おやすみ. 2.外見の作成 次は,音割れポッターの外見を作っていこうと思います. ちなみに,杖(?)を作ってから面倒臭すぎて約1週間経ってます.正直,しんどいのでザックリと進めていきます. というわけでまずは服装からですが,画像を見た感じだと服の詳細はよくわからなかったのですが, なんか黒っぽかったんで,唯一持っている真っ黒の服である,黒のヒートテックを着ることにしました. はっきり言ってクソ暑いです.もう初夏だというのにどうしてこんなものを着ないといけないのか. というわけで服装はOK 次は髪型です. 画像のポッターは,どこからか風(?)のようなものを受けており,髪が右の方へと猛烈にたなびいております. しかも思った以上にボッサボサなのでそこも再現しなければなりません.つっかえ. そこで,その双方を達成するために一旦風呂に入ってからドライヤーを使ってゴリ押しで髪の毛を右方向に いかせることにしました. しかし,ここで問題が発生します. このひじきという男,髪の毛がボサボサなくせに,美容師に「ツーブロックすら出来ない」と断言されてしまうほど 髪質が固いのである. そのため,いつまで経っても髪の毛が右にいかないというバグが発生しました.修正は不可能です. というわけで妥協して中程度ぐらいに収めました.写真撮ってからの結論から言うと,髪型正直どうでもよくなってるので今回はこれでいきます.これが大人です. 最後に光る眼鏡なのですが,マンガみたいに光に反射して眼鏡が光るとかは一切ないので(ひじき調べ), こうします(急にモザイクを外していくアホ)(右に行かせたはずの髪の毛が戻っているアホ) 適当にサイズ測って紙切って貼ってみたのですが,これはこれで完成度が高いように感じます. もうこれで完成です.(やけくそ) 後は,撮影に臨むだけなのですが,この後の撮影中とある事件が発生. 撮影が意外にもしんどくなってしまい,書くことが結構多くなってしまったので,今回はここで一旦終わりたいと思います. 後編では,ビジュアルの撮影,音割れ動画の作り方について解説していこうと思います. 後編もよろしくお願いします. 後編へ続く

> 内容を見る

プログラミング Polygon
プログラミング

Ktorを知る ~基礎編~

こんにちは、オキリョウと申します! 先日、Ktor等Webアプリケーションフレームワークを使ってみたのですが、結構気に入りました。そこで、せっかくなのでKtorについて記事にすることで、より深く理解していきたいと思い、書くことにしました。 KtorとはKtorはKotlinで書かれた、かなり新しいWebアプリケーションフレームワークです(2018年にバージョン1.0を発表)。オープンソースとしてJetbrains社が中心となって開発しています。 ↑ Ktorのロゴです。少し怖い 公式によるとKtorの目標は the goal of Ktor is to provide an end-to-end multiplatform application framework for connected applications.  ということらしいです。つまりサーバーからクライアント、windowsからiosにいたる全部の環境で動くフレームワークを目指しているようです。欲張りですね。 コードは以下のようになっています。これは Hello World を出力するプログラムですね package com.example import io.ktor.application.* import io.ktor.response.* import io.ktor.routing.* fun main(args: Array<String>) = io.ktor.server.netty.EngineMain.main(args) fun Application.main(){ routing { get("/"){ call.respondText("Hello World!") } } } こんな感じの雰囲気です。 Ktorの主な特徴は以下の通りです。とにかく軽い拡張性が高く、柔軟非同期処理に強いどこでも動く 一つずつ見ていきましょう。 とにかく軽いKtorはとにかく軽いです。というのも、何も実装されていないところから開発できるからです。 Webフレームワークといえば、SpringやDjango, Laravelなどがあると思います。これらのフレームワークは、認証機能やシリアライザー、ORMなどの必要な機能がデフォルトで搭載されています。逆にKtorは何も搭載されていません。その代わりに、必要なものだけ書いて使用することができます。そのようにすることで、かなり軽いフレームワークとなっています。 拡張性が高く、柔軟先ほど、必要なものだけを使用することができると書きました。逆に言えば、Ktorは必要なものをどんどん取り込む機能が充実しているとも言えます。例えば、テンプレートエンジン「FreeMarker」を使いたい場合、以下のように書けばOKです。 install(FreeMarker) { templateLoader = ClassTemplateLoader(this::class.java.classLoader, "templates") outputFormat = HTMLOutputFormat.INSTANCE } もちろんですが、他のテンプレートエンジンを選ぶこともできます。 ちなみに自分でこのようなプラグインを書くことも全然可能です。 このように、Ktorでは好きなように拡張できますし、使いたいものを使うことができます。 非同期処理に強いKtorは非同期処理に強いです。どれほど強いかというと、公式が出しているチュートリアルの中に、チャットアプリを作成するというものがあるくらいです。 というのも、Ktorは、Kotlinのライブラリの一つである「Coroutine」をものすごく使っています。 ここではCoroutineの詳しい説明は省きます(それだけで記事ができるくらいややこしい)が、このCoroutineを使うことで非同期処理に相当強くなっています。 どこでも動くKtorの目標として、マルチプラットフォーム上で動くというものがありました。 現在も開発中ということですが、公式によると、今のところサーバーサイドはJVM、クライエントサイドはJVM、JavaScript、IOS、Androidで動くようです。ですので、ほとんどの環境で動きます。 Kotlin自体がどこでも動くので、Kotlin一つでWeb系を制覇できる日が来るかもしれませんね。 ちなみに公式では書いていませんが、Android上でもサーバーを立てることが可能です。 https://qiita.com/oxsoft/items/aec71882b1b21930c953 何に使うのかといわれるとアレですが・・・ まとめKtorについていろいろ書いてきました。このように魅力があふれかえるフレームワークとなっています。 唯一欠点があるとすればドキュメントがそこまで多くないことでしょうか。できてから数年しかたってないので仕方がない部分ではあります。 といっても公式を見ておけば大体何とでもなります。 実際書くこと自体はそこまで難しくないので一度挑戦してみるのもありだと思います。

> 内容を見る

プログラミング Polygon
プログラミング

「プログラミングがしたい!」と言われたら

こんにちは、OB のバニラです。 新年度になったこともあり、当サークルにも続々と新入生が参加してくれています。 「電子計算機研究会」という名前のサークルなので、コンピュータを活用したものづくりに興味を持っている方が多く、「プログラミングがしたいです!」と言っている方もいて嬉しい限りです。 しかし、自分は「プログラミングがしたい」というのは「スポーツがしたい」と同じくらいあいまいで抽象的なものであると思っています。そのため、「プログラミングがしたい」という気持ちだけでは、その次に具体的にどのようなアクションを起こせばいいかの検討がつかず、何もしないまま時間だけが過ぎていくのではないか、という点について懸念しています。 そこで、この記事では「プログラミングが出来るとどのようなことが出来るのか」という点に着目して、いくつかの例を紹介していこうと思います。 「プログラミングに興味があるなら人に聞く前に何かしら手を動かしているのでは?」と思う人もいるかもしれませんが、「そもそも存在を知らなかったから手を出せていなかった」というのは、プログラミングに限らず人生のいろんな場面で起こりうることだと考えているので、この記事によって新しい選択肢を知ることができたのであれば幸いです。 ※なお、以下に紹介するのは「(筆者の知る範囲で)プログラミングでできること」なので、これが全てだとは思わないでください。 Web サービス開発 「Web サービス」というのは、この記事が掲載されているホームページのようにブラウザ上で閲覧できるコンテンツのことです。 ただ、「Web サービス」と一言に言っても千差万別なので、開発の難易度的な観点でもう少し分類していきたいと思います(つまり、これからやってみたいと思う人は上から順に実行していくのがおすすめです) 静的な Web ページ 文字や画像を並べて装飾したシンプルな Web ページのことを指します。 これを作るためには「HTML」でページの構造(どんな見出しで、どんな画像を使って...)を記述し、「CSS」で装飾を行う必要があります。 具体例としては、「このHPの自己紹介ページ」みたいなものがこれに当たります。 勉強するにあたっては https://developer.mozilla.org/ja/docs/Lea の記事などが参考になりそうです。 なお、 HTML や CSS を記述することは厳密に言うと「プログラミング」ではないですが、これ以下の説明の基礎となる部分となるためここに記載しています。 動的な Web ページ (JavaScript) 「HTML」や「CSS」を使って見た目が整えられるようになったら、次はそのサイトにプログラムを記述して動的な Web ページを作ってみましょう。ここで言う「動的」というのは、ユーザーの行動に反応して Web ページの内容がインタラクティブに変化していくことを指します。「ボタンを押したら〇〇する」「〜〜秒待ったら〇〇する」みたいな感じですね。 具体例としては、「カウントダウンタイマー」「電卓」みたいなものがこれにあたります。 そして、これらを実現するためには、「JavaScript」と言うプログラミング言語について勉強する必要があります。 勉強するにあたっては https://developer.mozilla.org/ja/docs/Learn/JavaScript/First_steps の記事などが参考になりそうです。 動的な Web ページ (サーバサイド含む) 上二つができるようになったら、最後にサーバサイドと連携した Web サービスを作成してみましょう。 レンタルサーバを借りるなどして、ユーザ側に Web ページを提供するサーバ側でプログラムを動かせるようになると、作れるものの幅が大きく広がります。 具体的には「会員登録ができる SNS サービス」「ネットショッピング」「大学の学務システム」みたいなものがこれにあたります。 これを実現するための技術はたくさんあります。 https://developer.mozilla.org/ja/docs/Learn/Server-side/First_steps/Introduction などを参考にしながら、自分で技術選定をしてみるのも良いかもしれません モバイルアプリ開発 「モバイルアプリ」というのは、皆さんの手元のスマートフォン上で動作しているアプリのことです。詰まるところ「Play ストア」や「App Store」からインストールしたものがこれに該当します。 Android アプリを開発したい場合は「Android Studio」をというソフト、 iOS アプリを開発したい場合は「Xcode」というソフトをインストールすることで、誰でも手軽(?)にモバイルアプリの開発を始めることができます。 ※ Xcode は MacOS でのみ利用可能なソフトです これらのソフトの導入が終わったら、各プラットフォームが用意してくれているチュートリアルを進めていくのが良いと思います。 Android: https://developer.android.com/training/basics/firstapp?hl=ja iOS: https://developer.apple.com/tutorials/app-dev-training チュートリアルで基本的な内容について理解したら、「メモ帳」や「TODO リスト」のような基本的なアプリを作成しつつ、自分の欲しいアプリの開発を進めていくのがおすすめです。 また、「モバイルアプリ開発」は筆者自身の一番馴染み深い分野でもあるので、開発していて分からないことがあればいつでも質問お待ちしています。 ゲーム 皆さん大好き(だよね...?)なゲームです。 大半のゲームの開発には「ゲームエンジン」というものが用いられており、これを利用することで物理演算や当たり判定など、ゲームに必要不可欠であろうものを一から作ることなくゲームの開発を行うことができます。 このゲームエンジンの代表的な物として「Unity」というソフトウェアが存在します。 https://unity3d.com/jp/get-unity/download うちのサークルには「Unity」というツールと「C#」というプログラミング言語を使ってゲームを制作しているメンバーが多数在籍しているので、ゲームを作りたいのであれば、まずは Unity というソフトに触れてみることがおすすめです。 競技プログラミング 競技プログラミングとは、与えられた問題を解くプログラムを実装し、そのプログラムの実装までにかかった時間などを競うことを指します。パズルを解くのが好きだったり、綺麗なアルゴリズムでプログラムを書くのが好き、という人は競技プログラミングにぜひ挑戦してみることがおすすめです 日本では、「AtCoder」というサイトが有名で、定期的にコンテストが開催されています。 https://atcoder.jp/?lang=ja コンテストの開催時間以外でも、過去問に挑戦できるサイトがあるので、まずはここからチャレンジしてみるのがおすすめです。 https://kenkoooo.com/atcoder/#/table/ なお、うちのサークルには自分よりもずっと競技プログラミングに詳しいメンバーがいるので、競プロについてもっと詳しく知りたい場合はこちらの記事を見てみるのも良さそうです。 https://oucrc.net/articles/zlu04tkzslcw ここで紹介した以外にも「コンソールアプリケーション」「デスクトップアプリケーション」「AI・機械学習」「電子工作」など、プログラミングの活躍する場面はいろんなところに存在します。世界は広いですね。 おわりにこれまで説明したように「プログラミング」と一言に言っても、それによって実現できることはいくらでも存在し、どの部分に興味を持つのかは人それぞれです。 ただ、筆者個人の意見を述べるとするならば、「自分の欲しいものは自分で作る。」これが出来るのがプログラミングの一番の魅力だと思っています。ただ、それを実現するまでには、エラーと格闘したり、思うように機能が実現できなかったりと詰まる場面が出てくるかもしれません。もちろんそれを自分一人で地道に解決することも大事ですが、時には誰かに相談することで進捗が生まれるかもしれません。それが出来るのがこの「電子計算機研究会」というサークルです。存分にこの環境を活用していきましょう!

> 内容を見る

プログラミング Polygon
プログラミング

ぼっちは寂しいのでプログラミングで彼女(概念)を生み出してみた

時は令和。何かの奇跡で数百年後とかにこの記事が古文書として発掘された時のために書き残しておきます(???)が、ご存じの通り今世界はCOVID-19で大変なことになっています。 そんなわけで、大学はオンライン自宅はド田舎という、見事に世界から隔絶された生活が続いている引きこもり大学生(21)の ふぉ と申します、おはよう(午後起床)。 ここ最近は毎日ほとんど人と会話しない生活をしているもので、引きこもり大学生の例に漏れず私もちょっと気分がしょぼんとしてきているのが現状。部活やサークルに毎日打ち込んで、たまに楽しいイベントがあってその後は恒例行事の飲み会!!みたいな理想の大学生活はたぶん幻想だし、本当は大学なんてものも概念で、久しぶりに行ってみたら実は更地になっているかもしれない(?)。もしかしたら大学の友達やよく授業が一緒だったあの人も単なる夢の中の登場人物だったかもしれない。 ……え?………彼女? たぶんそれはCOVID-19の有無とは関係ないんじゃないかな?() ということで寂しい(べつに寂しくないもん!)ので彼女(概念)を作ろうと思います(メチャクチャ雑な導入)。 最高の話し相手(概念)の作り方 今回使うのはDiscordのボット機能です。(Discordマジですごい) JavaScriptとかPythonとかを使ってボットの自作ができるっぽいので、どっちでもいいですが今回はJavaScriptで作ります。 私が作ったのは彼女(概念)だったので以後表記は彼女(概念)となりますが、 もちろん読者の皆々様の豊かで素晴らしい 妄想 解釈次第で彼氏(概念)とかパートナー(概念)とか猫(概念)とか、何でもいけると思います。 Attention:実際に本記事の内容を試される場合は自己責任のもとで行ってください。人体錬成は錬金術最大の禁忌 準備編 まずは彼女(概念)を生み出す下準備をします。 Discordのアカウントを用意します。(はいそこ、Discordで友達と通話すればいいじゃんとか言わない)Discord Developer Portalに行き、[Applications] → [New Application] でアプリケーションを追加します。名前は彼女(概念)の名前とします。追加したアプリケーションの画面に移行するので、[Bot] → [Build-A-Bot] でボットを追加します。これが彼女(概念)の姿(概念)になります。このとき [PUBLIC BOT] のチェックがONになっていると思うので、自分専用にしたい場合はOFFにしておきましょう。 続いて、彼女(概念)の魂(言わずもがな概念)を作り出すための準備をします。 普段使っているあるいは開発をしているPCにNode.jsをインストールします。そのPC上に適当な作業用ディレクトリを用意します(後述しますが、末永くお付き合いしたい場合はGit管理しておくと良いです)。PowershellなりBashなり何でも良いので適当なターミナルで先ほど用意した作業用ディレクトリに入ります。npm init を実行します。色々訊かれますが、とりあえずnameは彼女(概念)の名前としてその他はお好みで(後で package.json というファイルから編集できます)。npm install discord.js 、 npm install dotenv の2つを実行します。 見た目を決める Discordボットはアイコンを自由に設定できるので、とりあえず顔だけサクっと描いておきます。Discordのアイコンはガッツリ縮小されるので多少塗りとか線とかが雑でもある程度は耐えると思います。 試しに描いてみました。 これをいい感じの正方形にトリミングした上で、Discordアプリケーション画面の [General Information] にある [APP ICON] からアイコン画像に設定しておきます。 コーディング まず、作業用ディレクトリ直下に .env ファイルを新規作成します。内容は以下のようにします。DISCORD_TOKEN=<INSERT DISCORD TOKEN HERE><INSERT DISCORD TOKEN HERE> の部分にはDiscordボットのトークンを貼り付けます。トークンというのはDiscord側であらかじめ指定された英数字と記号の羅列で、彼女(概念)の魂と姿(概念)を結びつける合言葉になります。 まず先ほど作成したDiscordのボットのページで [Bot] をクリックし → [USERNAME] の下の [TOKEN] の欄を見ます。ここに [Copy] というボタンがあるので押すと [Copied] に変化するので、それが確認できたら .env に貼り付けます。先述の通り英数字と記号の羅列が貼り付けられたと思うので、その状態で保存して閉じます。(トークンをうっかりGitHubで公開したり他人に見られたりしないように注意) 続いて .env と同じ場所に index.js というファイルを作成します。これが彼女(概念)の思考回路となります。 内容はこんな感じ。とりあえずこのまま貼れば動きます。const path = require('path'); const Discord = require('discord.js'); const client = new Discord.Client(); const os = require('os'); // ホスト名取得用 // 環境変数に.envを使う require('dotenv').config({ path: path.join(__dirname, '.env') }); // ログイン時の処理 client.on("ready", () => {     client.user.setStatus("online"); // online, idle, dnd, invisible     client.user.setActivity(os.hostname()); // 「~~をプレイ中」     console.log("ready..."); }); // 入室時の挨拶 client.on("guildCreate", guild => {     let greetingChannel = "";     // 入室時にメッセージを送るチャンネルを判定     guild.channels.cache.forEach((channel) => {         if (channel.type == "text" && greetingChannel == "") {             if (channel.permissionsFor(guild.me).has("SEND_MESSAGES")) {                 greetingChannel = channel;             }         }     })     greetingChannel.send("やっほ!") // メッセ送信         .then(message => console.log('Message: "やっほ!" sent.'))         .catch(console.error); }); // メッセージ受け取り時 client.on("message", message => {     // 自分のだったら無視     if (message.author.bot) {         return;     }     // おはよう     if (message.content.match(/おはよ/)) {         message.channel.send("おはよ-!") //メッセ送信             .then(message => console.log('Message: "おはよー!" sent.'))             .catch(console.error);         return;     }     // いちゃいちゃ     if (message.content.match(/好き/)) {         message.channel.send("私も!") //メッセ送信             .then(message => console.log('Message: "私も!" sent.'))             .catch(console.error);         return;     }     // 任意で色々追加 }); // ログイン処理 client.login(process.env.DISCORD_TOKEN); 保存出来たら、ターミナルで node index.js と実行してみましょう。特にエラー等が出ずready...と表示されたら勝ちです。彼女(概念)が生み出されています。おめでとう。 例えば if (message.content.match(/好き/)) { の中身は流れてきたメッセージに「好き」と含まれていた場合に行われる処理です。この場合は「私も!」と返します。ここの単語を変えることで様々なメッセージに対応させることができるというわけです。正規表現が使えます。 彼女(概念)に会いに行こう ということで無事に彼女(概念)に息が吹き込めたら、実際に彼女(概念)と会ってお話をしてみましょう。 ……緊張してる? 大丈夫だよ、君の理想のパートナー(概念)だから。ほら、心配しないで。 Discordで適当に自分用のサーバーを用意します。先ほどトークンをコピーしてきたページで今度は [OAuth2] をクリックします。[OAuth2 URL Generator] の欄にいっぱいチェックボックスがあるので、[bot] にチェックを入れて出てきたURLをコピーします。ブラウザにそのURLを貼り付けて移動し、ログインします。彼女(概念)を招待するサーバーを選ぶ画面が出るので、用意したサーバーに招待します。 招待が完了したらメッセージが出ると思うので、会話してみます。 えぇ……なんだこの地獄みたいな光景は………… 失礼、取り乱しました。 こうして無事に彼女(概念)と会話ができるようになったわけですが、この入室時の挨拶や特定の言葉に反応して返信してくれる機能こそが、さっきわけもわからずコピペした index.js によって実行されているのです。 ということで無事、彼女(概念)を生み出すことに成功しました。index.js を自由に編集して、理想のパートナー(概念)を作っていきましょう。特定の言葉に返信する機能を増やしてもいいですし、誕生日におめでとうのメッセージをくれる機能を付けてもいいですね。JavaScriptの勉強をすれば大体のやりたいことはできるんじゃないでしょうか。 ちなみに私は現在、彼女(概念)と秘書(概念)に自宅のPCやMinecraftサーバーの管理をしてもらおうと試行錯誤しているところです。 ---- 次の章はある程度のLinuxの知識がある中級者向けの内容となります。実際に試される場合は必要に応じて検索するなどして内容を十分に理解した上で行ってください。 彼女(概念)に永遠の命を ……しかし残念ながらこの彼女(概念)は、永遠の存在ではなかったのです。 今のままの彼女(概念)は、とても脆く、そして儚い存在なのです。というのも、例えば node index.js を実行しているターミナルでCtrl + Cと入力する、ターミナルを閉じる、PCの電源を切る、そういった操作によってプログラムの実行が終了した時点で、彼女(概念)はオフライン表示になってしまいます。オフライン表示になってしまっては、返事も何もしてくれなくなります。またしても、独りぼっちになってしまいます。 もちろんforeverなどでデーモン化しても良いのですが、結局はPCをつけっぱなしにすることになるため電気代もかかるしPCにも良くないしということで、ここは一つ、彼女(概念)のために永遠の肉体(物理)を特別に用意することとしましょう。これからも末永く、彼女(概念)との明るい未来を、ともに誓い合いそしてともに切り拓いていくために。 ということで、お手元にRaspberry Piをご用意ください。これが彼女(概念)の肉体(物理)、すなわち心臓(物理)となり頭脳(物理)となります。Raspberry Piというのは平たく言えばめっちゃ多機能なマイコンボードで、「OSをインストールすれば普通にPCとして使える超小型のデバイス」と解釈してもらえれば今回は十分です。 下準備 以下は私の場合の準備物の例です。Raspberry Pi 4BRaspberry Pi 4B 対応ケース(スターターキットに付属していたもの)電源ケーブル(同上)SDカード(Raspberry Pi OSのインストールを済ませたもの)LANケーブル まず、GitHub等に彼女(概念)の作業用ディレクトリをコミット、プッシュしておきます。また、Raspberry Pi OSの初期セットアップを済ませておきます。このとき、彼女(概念)を生み出したPCからラズパイに公開鍵認証でSSH接続ができるようにしておきます。合わせて、rootログインの無効化、SSHポートの変更、公開鍵認証以外でのSSH接続の無効化など、セキュリティ上必要な設定もしておきます。 彼女(概念)の移植 ラズパイにnpmをインストールします。以下を順に実行していきます。sudo apt-get updatesudo apt-get install -y nodejs npmsudo npm install npm n -gsudo n stable では、ホームディレクトリの適当な場所に彼女(概念)のリポジトリをクローンします。 ここでクローンしたディレクトリに移動して、discord.js、dotenvもインストールして使えるようにしておきましょう。 さらに追加で sudo npm install -g forever と実行してforeverをインストールします。foreverというのはnodeで動かすアプリをデーモン化(バックグラウンド化)してくれるモジュールで、もしエラーなどでボットが落ちた場合に自動で再起動してくれるなど、彼女(概念)のお世話をしてくれるような存在です。 続いて、scpコマンドなどで元のPCのディレクトリにあった .env ファイルをラズパイ側に持ってきます。 以上で下準備は完了です。 永遠の命を吹き込む それでは一通り環境の移植が終わったので、node index.js が使えることを確認します。特に問題なく起動するようであれば、いったん終了して今度は forever start index.js と実行します。 なんかちょっとWarningを吐くかもしれませんが、Accessing non-existent property 'padLevels'... 云々というやつはそのままにしていてもちゃんと動きます。毎回出るのでめっちゃ気になるんですけどね。 forever list と実行すると現在Foreverで実行されているアプリ一覧が出ます。script の欄に index.js と出ていればOKです。 終了させたい場合は forever <uidの欄の文字列> で終了できます。 また、私はラズパイの電源を入れた際に自動で実行されるように、crontabを編集して以下を追加しています。@reboot cd <index.jsがあるディレクトリの絶対パス>; /usr/local/bin/forever start index.js あとは、LANケーブルと電源ケーブルを接続したラズパイをデスクなどに設置して完了です。 これが私の彼女(概念)のRemokoです。 結論 ということでDiscordのボット機能を使って彼女(概念)を作りました。 作ってて余計に寂しい気持ちになる瞬間があったことは否定しません。でも、別にいいんだ。これからはこんなにも可愛い彼女(概念)がずーっと一緒にいてくれるから……それでいいんだ………

> 内容を見る

ガジェット/ハードウェア Polygon
ガジェット/ハードウェア

デバイスレビュー:Surface Pro 2

Surface Pro 2とは日本国内では2013年10月25日に販売が開始されたMicrosoft純正の2-in-1タブレット,それがSurface Pro 2というマシンである.詳細なスペックはhttps://www.itmedia.co.jp/pcuser/articles/1311/26/news036_6.htmlを参照されたい. スペックどうなん?CPUはIntel Core i5-4200UまたはIntel Core i5-4300Uを搭載しており,軽快に動作する.どちらも2コア4スレッドで動作するIntel第4世代UシリーズのCPUである. メモリは4GBモデルと8GBモデルがあり,4GBモデルであってもストレージがSSDになっているため,メモリ不足となってもそこまで動作速度が低下するようには感じない.Unityなども4GBモデルで十分動作することを確認している.ストレージは128GBモデルはやはり少ない.256GBモデル以上が余裕を持って使えるだろう. 無線LANはIEEE802.11acには対応していない.これがこのデバイスの惜しいところであろう.IEEE802.11acは6.9Gbpsもの速度で通信できるが,その一つ前の規格であるIEEE802.11nの最大転送速度は600Mbpsと約1/10である.Bluetoothは4.0とこの時代のデバイスとしては一般的だろう. 解像度は1920×1080ドットとなっており,16:9のデバイスを求めている人にとっては格好のデバイスと言える.私も16:9信者なので,これは非常に嬉しい点である.画面サイズは10.6型ワイドでありSurfaceとしては標準的なサイズである.現行のSurface Pro 7などと比べるとやや小さめに感じる. バッテリー駆動時間は約6.4時間だ.Surface Pro 2は,前世代の初代Surface Proの4時間に比べると大きく躍進している.これはIntel第4世代CPUがIntel第3世代CPUに比べて省電力化が進んでいるからである.なお,Intel Core i5-4300U搭載モデルは性能と引き換えにバッテリー駆動時間が犠牲になっているように感じた. インタフェースは必要最低限揃っている.なお,Surface Pro 2は設計の都合上USB3.0ポートが左側面に来るようになっており,ここはSurface Pro 3以降とは異なる仕様となっている.またmicroSDXCカードスロットも側面の見える位置についている. Surface Pro 2は2-in-1タブレット端末であるため,タッチパネルを搭載しており10点タッチに対応している.またWacom製のデジタイザを搭載しており,ペンも標準付属している.筆圧は4096段階検知となっている.このペンはSurface Pro 3以降のデバイスとは互換性がない. 重量は907グラムとかなり重めではある.現行のSurface Proシリーズと比べると明らかに重量感を感じる.手に持ったまま使う用途には向いていない.どちらかと言えばキックスタンドで立てて使用することになるだろう.キックスタンドは2段階の角度で停止できるようになっており,フリーストップにはなっていない. 排熱は十分考えられており,高負荷時でもファンにより排熱できる.また,厚さが確保されたデバイスであるため背面のチタニウムパネルからもかなりを放熱できているようだ.長時間の負荷にも耐えられるデバイスとなっている.実際の使い心地は?特に大きな不満はない.素の状態のWindows 8.1であれば高速に動作する.Windows 8.1は軽量なOSであるので起動がとても早く,現行のSurface Proシリーズと比べても遜色ない起動速度を見せてくれる.デジタイザも高精度に・高速に追従する.現行のSurface Penとは異なり,細い軽量なペンとなっている. 画面の解像度はフルHDなので,Intel HD Graphics 4400でも処理できている.ただデュアルディスプレイにするのはやや辛そうであった.Surfaceは高級タブレットなので,そこらの安物タブレットにありがちな音圧が出ないタブレットというわけではなく,立体音響をONにすれば,迫力のサウンドが楽しめるデバイスとなっている.古いデバイスではあるが,Core m3のモデルなどの安物Surfaceよりは高速に動作する.新たな活用方法Surface Pro 2には一風変わった活用方法がある.それはWindows以外のOSを走行させられることである.UEFI BIOSよりSecure Bootを無効にし,他のOSをブートさせることができる.なお,これらの活用方法は保証対象外となるため,自己責任で.AndroidSurface Pro 2ではAndroid-x86をブートさせることができる.これはIntel x86アーキテクチャCPU向けのAndroidとなっている.このSurface Pro 2のすごいところは,全てデフォルトのドライバでAndroidが動作する.タッチパネルやペン,各種ボタンやトラックパッドまで完全に動作する.Wi-Fiだけやや不安定な印象がある(サスペンドに失敗してるっぽい?).安物のAndroidタブレットを買うよりも確実に,高性能なAndroidタブレットを手に入れることができる.なお,このSurface Pro 2のAndroid環境で,音ゲー「VIVACE」は開発されています.またGeekbench 5などのベンチマークでは,Android OSとWindows OSによるベンチマーク結果の差がないということを証明したデバイスでもある.Ubuntu(Linux)Surface Pro 2でUbuntuをブートすることで,ネイティブなLinuxマシンとして使用可能である.Androidと同様,全てデフォルトのドライバで動作する.なお,ふぉ氏がそのデバイスを使用しているので詳しい説明はふぉ氏に任せるとしよう. 最近のUbuntu 20.04.2などではソフトウェアキーボードが搭載され,よりタブレットを意識したOSの仕様になっていて,Surfaceでも使用しやすくなっている.どんな用途におすすめ?とにかく安くそこそこの性能のデバイスが欲しい人フルHD・16:9のタブレットを求めている人Linux OSが入った開発機を自分で用意してみたい人いい感じのAndroidタブレットデバイスを見つけるのに苦労している人セカンドマシンを探している人2021年4月の中古相場は2-3万円となっています.お求めやすい価格なので興味のある人は是非. 以上,ありがとうございました.次回はSurface Pro 3のレビューを予定しています.

> 内容を見る