読者です 読者をやめる 読者になる 読者になる

Minecraft のマルチプレイ用サーバをプレイ時だけ稼働させるための Lambda Function

開発 Minecraft Python AWS

三行

  • Minecraft サーバはメモリ2GB以上のインスタンスが欲しくて VPS を借りると月2000円ぐらいかかるところが多い
  • プレイ時だけ稼働させればよいので Slack からインスタンスを立てて遊び終わったらデータを退避させて壊せるようにした
  • $0.03 / hour で遊べる

minecraft-lambda-function

Minecraft サーバをプレイ時だけ稼働させるために下記の機能を持つ AWS Lambda Function を作った。

  • create: DigitalOcean にサーバインスタンスの生成 → S3 からプレイデータ(worldディレクトリ)のダウンロード → Minecraft サーバの起動 → IP アドレスを Slack に通知
  • upload: S3 へプレイデータをアップロード
  • destroy: インスタンスの破壊

インターフェイス

Slack の Slash Commands で対応する Function を呼び出す。

  • /minecraft create
  • /minecraft upload
  • /minecraft destroy

インターフェイスの図

アーキテクチャ

Lambda Function は図のような構成で動いている。
Minecraft サーバアプリケーション自体は itzg/minecraft-server という Docker イメージを利用して動かしている。環境変数に S3 上の world.zip の URL を渡すだけでそのプレイデータで起動されて便利。

create⚒

create

upload🚀

upload

destroy💥

destroy

Slack からの実行

Slack の Slash Commands から Lambda Function を実行するために API Gateway を利用した。

  1. API Gateway にエンドポイントを作成して POST したら minecraft-lambda-function を実行するように設定。
  2. Lambda Function はパラメータを JSON で受け取りたいのだけど Slack Slash Commands は JSON で送ってくれないので API Gateway で Body Mapping Template を設定。 Body Mapping Template
    このようにした。
    #set($httpPost = $input.path(‘$’).split(“&”))
    {
    #foreach( $keyValue in $httpPost )
    #set($data = $keyValue.split(“=”))
    “$data[0]” : “$data[1]”#if( $foreach.hasNext ),#end
    #end
    }
    
  3. Slack Slash Commands を設定
    URL に API Gateway のエンドポイントの URL を設定する。ここで設定する Token は Lambda Function に渡される JSON データに含まれる。(Lambda Function 側の環境変数にも同じ Token を設定しておいて Function 内で照合することで、Slack Slash Commands 以外からのリクエストを無視する) Slack Slash Commands
  4. Slack から /minecraft create を実行すると
    {“token”: “*****”, “text”: “create”}
    
    というパラメータで Lambda Function が実行されるようになる 🎉

動作

Slash Commands 自体のログは残らないけどこんな感じのログになる。 f:id:morishin127:20170220005920p:plain

料金

$0.03 / hour で遊んだ時間分しかかかってないのでお安い 💰 f:id:morishin127:20170220010515p:plain

感想

最高便利!!!!!!!!

余談

Lambda のデプロイパッケージのビルドを macOS 上で行なっても Lambda 上で動かず苦戦した際の知見です。 qiita.com

Swift っぽい UserDefaults

開発 Swift

Swift 3 の Notification

Swift 3 から Notification.Name 型が追加され、Notification の名前に生の文字列ではなく Notification.Name 型の値を指定できるようになった。

extension Notification.Name {
    static let userLoggedOut = Notification.Name("UserLoggedOut")
}
let n = Notification(name: .userLoggedOut, object: nil)

参考: Swift 3 以降の NotificationCenter の正しい使い方

Swift っぽい UserDefaults

UserDefaults のキーはまだ生の文字列を使っているけど、新しい Notification のようなインターフェイスで扱えたらうれしいなと思って薄いライブラリを書いた。

github.com

こんな感じで書ける。

import SwiftyUserDefaults

extension UserDefaults.Key {
    static let someKey = UserDefaults.Key("someKey")
}

UserDefaults.standard.set(true, for: .someKey)
UserDefaults.standard.bool(for: .someKey) // true

Notification.Name と同じように UserDefaults.Key という型でキー名を定義して使う。

ソースコード

1ファイルだけの簡単なコード。
UserDefaults+Key.swift

所感

このためにライブラリ入れるのもアレだし標準でこんな感じになればいいな。

あと書いてから気付いたけど全く同名のライブラリがあって同じようなことしてた。

github.com

遺伝的アルゴリズムでやっていく Mario AI Competition 2009

開発

この記事は CAMPHOR- Advent Calendar 2016 19日目の記事です。

Mario AI Competition 2009 とは

Mario AI Competition 2009Sergey KarakovskiyJulian Togelius という研究者の方が主催していたらしい大会で、スーパーマリオブラザーズ(を模したゲーム)を自動操作する AI を作ってスコアを競うというもの。スーパーマリオランではありません。

続きを読む

MISTEL BAROCCO MD600 買った

これ 😉👇✨ mistel barocco md600

巷で Ergodox が流行っていて、左右で分かれているタイプのキーボードがちょっと気になってた。左右を離すことによって胸を開いた自然な姿勢でタイプできて楽らしい。

続きを読む

zsh 時間のかかるコマンド実行が終了したら通知センターに通知する

コマンド実行に5秒以上かかったときだけ通知センターにコマンドの終了を通知するようにします。

image

続きを読む

Xcode プロジェクトをシュッと開く Alfred Workflow

開発

中で mdfind を叩いて *.xcworkspace *.playground *.xcodeproj を検索し、選択したファイルを Xcode で開く Workflow です。

iOS 開発者の方には最高便利だと思うのでお使いください。

Download

f:id:morishin127:20160910234218p:plain

Docker と nginx-proxy で自分だけの nbviewer をシュッと立ち上げる

開発

jupyter notebook を他人と共有したい時には nbviewer が便利ですよね。公式のページ もあるのですが簡単に Docker でドーンできるようなので自分のを作ってみました。

  1. お使いの DNS の設定で Docker ホストの IP アドレスに対し nbviewer.example.com 的なレコードを設定する。
  2. 公式の README 通りに nginx-proxy を立ち上げる
    $ docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy
  3. VIRTUAL_HOSTドメインを指定して nbviewer を立ち上げる
    $ docker run -d -e VIRTUAL_HOST=nbviewer.example.com -e GITHUB_API_TOKEN=<YOUR_API_TOKEN> jupyter/nbviewer
  4. ブラウザから http://nbviewer.example.com を開く。

以上です。nginx-proxy すごい。