さくらのクラウドにソーリーサーバーを作る

  • 投稿日:
  • by
  • カテゴリ:

サーバーメンテナンスなどでWebサーバーを1時間ほど止めるとき、まったくレスポンスがないと利用者が困るので
どのページにアクセスしてもメンテナンス告知ページを表示するようにする。
具体的には、あらかじめDNSのTTLを短くしておき、メンテの際にソーリーサーバーのIPに振り向ける。
本番サイトはSSL化していたので、ソーリーサーバーもhttps受け入れる想定。

そのソーリーサーバーを立てた時のメモ:
1)さくらのクラウドで一番安いプランを契約して起動。環境はCentOS6.9、Apache2.2
2)SSHでログインしてhttpdインストール
yum -y install httpd
3)mod_sslをインストール
yum -y install mod_ssl
4)告知ページを作成してドキュメントルートに保存
vi /var/www/html/maintenance.html
5)アパッチの設定(httpはhttpsに飛ばす。どのURLにアクセスしても503ステータスでメンテページに飛ばす、ただし画像は除く)
vi /etc/httpd/conf/httpd.conf

-------------------
ErrorDocument 503 /maintenance.html
NameVirtualHost *:80
NameVirtualHost *:443
<VirtualHost *:80>
ServerName twipla.jp
DocumentRoot /var/www/html
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>
</VirtualHost>
<VirtualHost *:443>
ServerName twipla.jp
DocumentRoot /var/www/html
SSLEngine on
SSLCertificateFile /cert.pem
SSLCertificateKeyFile /privkey.pem
SSLCertificateChainFile /chain.pem
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !^(.*)\.(gif|png|jpg|jpeg)$ [NC]
RewriteCond %{REQUEST_URI} !=/maintenance.html
RewriteRule ^.*$ - [R=503,L]
</IfModule>
</VirtualHost>
-------------------

6)ssl.confにも書かないとリダイレクトされないかも。
vi /etc/httpd/conf.d/ssl.conf

-------------------
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !^(.*)\.(gif|png|jpg|jpeg)$ [NC]
RewriteCond %{REQUEST_URI} !=/maintenance.html
RewriteRule ^.*$ - [R=503,L]
</IfModule>
-------------------

7)SSL証明書(cert.pem、privkey.pem、chain.pem)を本番環境からコピーしてきてhttpd.confで指定した場所に配置。
8)httpsでアクセスできるよう443ポートをあける
vi /etc/sysconfig/iptables

-------------------
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
-------------------

9)iptables再起動
/etc/init.d/iptables restart

10)アパッチ起動、自動起動ON
service httpd start
chkconfig httpd on

以上でサーバーの準備完了。
手元のパソコンのhostsファイルを書き換えて、ドメイン名でアクセスしてみて動作確認する。

Let's EncryptでSSL化した時のメモ(CentOS6.9、Apache2.2)

  • 投稿日:
  • by
  • カテゴリ:

導入方法を検索したら古い情報も多くて手間取ったけど、
下記サイトに情報がまとまっている。インストールも簡単だった。
https://letsencrypt.jp/usage/#Install

まずiptablesを変更して443ポートを空けておく
> vi /etc/sysconfig/iptables
> /etc/init.d/iptables restart

インストールは下記だけで済んだ。
> sudo yum install epel-release
> wget https://dl.eff.org/certbot-auto
> chmod a+x certbot-auto
> ./certbot-auto
必要なライブラリやPythonのインストールも自動でやってくれる。
httpからhttpsにリダイレクトするか尋ねられたのでyesにしたら、httpd.confのVirtualHost設定も書き換えてくれたみたい。

certbotのstandaloneプラグインだと証明書発行時にWebサーバの停止が生じる。
稼働中のサイトが止まるのは困るのでwebrootプラグインを使うのが良い。

証明書は/etc/letsencrypt/archive内に保存される。
シンボリックリンクが/etc/letsencrypt/liveに作られるので、httpd.confに記述する証明書ファイルパスはこちらを使う。

証明書取得時に使用したオプションは下記に保存されて、更新時もこの設定が使われる。
/etc/letsencrypt/renewal/****.conf

有効期限の確認方法
> openssl x509 -noout -dates -in /etc/letsencrypt/archive/ドメイン名/cert1.pem

定期的に証明書を更新するためにcronに下記を登録した。
0 4 1,15 * * root /bin/certbot-auto renew --webroot-path /var/www/html --renew-hook "/etc/rc.d/init.d/httpd reload"
毎月1日と15日に実行、/var/www/html/.well-known/acme-challenge内に一時ファイルが作られてそれを認証サーバが読みにきて認証される。
--renew-hookで証明書更新成功時にhttpdの設定を再読み込みするようにした。

蛇足:
稼働中の本番サーバーでいきなり実行するのは怖かったので、実際は下記の手順で試した。
・ちょうどrsyncで同期させたテストサーバ(ドメイン無し)があったのでそちらでmanualプラグインで実行。
> ./certbot-auto certonly --manual -d example.com
進めると、認証ファイル名とそのファイルに記述する認証コードが表示されるので指示通りのURLでアクセスできるよう本番サーバにファイルを置く。
・ENTERを押すとそのファイルにWebアクセスがあり、/etc/letsencrypt/に証明書などが生成される。
・証明書をテストサーバに持ってきてhttpd.confでSSL用のVirtualHostを設定。
・hostsファイルを書き換えてドメイン名でテストサーバにアクセス。正常にSSLが機能していることを確認。
・本番サーバーでwebrootプラグインで実行。

Blenderで作った3DモデルをFaceRigで動かす

  • 投稿日:
  • by
  • カテゴリ:

なかなかハードルが高いので、はまりポイントをメモします。
下記を参考にすればとりあえずFaceRigで単純に3Dモデル表示するところまではいける。
https://steamcommunity.com/sharedfiles/filedetails/?id=523433759

まずモデルは原点に配置、スケールは1にしないとボーンやカメラがずれる。
頭のサイズは高さ2に収まる程度にする。
(モデルの位置回転スケールを調整した後で、ctrl+Aで原点原寸に変換できる)

マテリアルの命名規則を守る。例:smileyと名付けたアバターのfaceマテリアルなら「smiley_sht_metalcloth_face」。
そのfaceマテリアルのテクスチャ画像の名前は「smiley_face_d.tga」とする。テクスチャ画像はなくても動く。
画像はTARGA形式、縦と横のpixelサイズは2の累乗にする。

モデルのUVマップを必ず作る。
(Unwarpは、Edit ModeでAキーで全メッシュ選択してUキー)
余計なUVマップがあるとエラーになる。
(モデル選択してPropertiesウィンドウのDataタブ内にUV Maps一覧があるので使わないものは削除する)

最低限必要なボーンは、BipHead , BipLEye , BipREye の3つだけ。
Armatureを作ってWeightマップを作る。
ボーン名にドット( . )を含むとインポートエラーが起きる。
エラーが出る場合は、ボーンを消していき最低限のボーンだけにしてインポート成功するか確認するとよい。

Cameraという名前のボーンも必要らしいが認識されなかった。代わりにScene内にCameraという名前のカメラがあれば大丈夫。
アバターの正面とカメラは、Y軸(緑色の線)で向き合うようにする。(一般的に前後はZ軸だけど、BlenderではY軸が標準の模様)
カメラの位置はサンプルアバターを参考に合わせる。

アバターの動きは、様々なアニメーションを用意することで実現する。
最低限必要なのは「idle1」のみ。DopeSheetのActionEditorでidle1と名付けたアニメーションを作る。
キーフレームを選択してKeyメニュー→Sample keyframe(キーフレームを抽出)を実行して、
全フレームにキーを打たないとFaceRig側で正しくアニメーションされないケースがある。

下記のモーションを用意すればそれなりに動くと思う。
idle1 待機
Head_LR 首を左右に曲げる 0(左)~15(中央)~30(右)の31フレームで作成。
Head_UD 首を上下に向ける
Head_Twist 首を左右に振る
LeftEyeClosed 左目を閉じる
RightEyeClosed 右目を閉じる

アバターの腕は、Shift+マウスドラッグで動かせる。モーションは下記を用意する。
HandL_closeDown_LR 左腕、下げたまま左から右に振る。0(左)~15(基本ポーズ)~30(右)
HandL_closeMiddle_LR 左腕、胸の位置で左から右に振る。0(左)~30(右)
HandL_closeUp_LR 左腕、頭の位置で左から上に振る。0(左)~30(右)
※HandL_closeUp_LRが反映されない場合はHandL_farUp_LRに割り当ててみる。

口の動きは下記があるとよい。
MouthOpen 口を開ける。0(閉じる)~30(開ける)
MouthOpen_base 口を開けっ放し。0~30まで同じ。
Mouth_pursedLips_LR 唇をすぼめる。0(左ですぼめる)~15(中央で)~30(右で)
MouthClosedLeft_U 左、口角を上げて笑う
MouthClosedRight_U 右、口角を上げて笑う

BlenderからデータをCollada形式で書き出す。
ファイル名に「Geometry.dae」をつける。例:smileyGeometry.dae
アニメーションはそれぞれの名前で書き出す。例:idle1.dae
ファイルパスに、スペースやハイフンがあると読み込めない。
FaceRigのインポーターは下記にあるので起動して、Data Folderを指定してImport実行。
C:\Program Files (x86)\Steam\steamapps\common\FaceRig\Bin\Tools\ImportWizardNew

インポーターから一度書き出したデータは、インポーター上でクリアしても消えないようなので
間違ったアニメが残り続ける場合は、下記にあるアバターデータを消すと良い。
C:\Program Files (x86)\Steam\steamapps\common\FaceRig\Mod\VP\PC_CustomData\Objects

FaceRigのLAUNCHボタンでクラッシュするようになってしまったときは、前述のアバターデータを消して
OPTIONSでReset to Defaultsを押してみると直るかも。
私の環境ではマルチモニター(外部ディスプレイ接続中)でLAUNCHボタン押すとクラッシュする

Qキー押したときに発動するspecial01などの特殊アクションについては
special01だけでなくベースとなるidle1、Avatar_LR、Avatar_FBの全ボーンにキーフレームを打っておかないとアバターが消える

参考:
ばけもの屋 -BAKEMONOYA- faceRig編
アニメテンプレート一覧
https://www.youtube.com/watch?v=ecLd4NsmpUw
サンプルアバター「yexample」のダウンロード

UnityでWebSocketやSoicket.io

  • 投稿日:
  • by
  • カテゴリ:

いろいろ試した結果のメモ:

WebSocketなら http://sta.github.io/websocket-sharp/ が良い。
OSXとiOSでws://echo.websocket.orgに接続できることを確認した。
しかし、wssでは接続できなかった。Socket.ioサーバにも接続できなかった。

Socket.ioでの接続は https://github.com/floatinghotpot/socket.io-unity が良い。
OSXとiOSで接続できることを確認した。
ただほかのライブラリと競合して、The imported type `xxx' is defined multiple times みたいなエラーが出る場合は対策が必要。
どちらかのActionをUnityActionに変えるとか。Func<T, TResult>を自分で用意したdelegateに変えるとか。
https://github.com/floatinghotpot/socket.io-unity/issues/1

下記も試したが、バージョンが古いせいか接続できなかった。
https://github.com/NetEase/UnitySocketIO
https://github.com/kaistseo/UnitySocketIO-WebSocketSharp
https://github.com/fpanettieri/unity-socket.io-DEPRECATED

参考:
http://littlewing.hatenablog.com/entry/2015/10/05/144124

macOS High Sierraのシステム容量が肥大

  • 投稿日:
  • by

MacBook Proを買い換えてデータ移行後、
Bootcampを入れるためにパーティション切ろうとしたら思いのほか空き容量が少ない...

空きを増やすため色々削除したものの、減るどころか逆に時間とともに増えて困った。
「このMacについて」>「ストレージ」を見るとシステム容量が多くなっている。
Macintosh HDの「情報を見る」ではパージ可能領域がかなりあるが強制パージの仕方がわからず。
原因は、Time Machineのローカルスナップショットのせいでした。
下記を参考に解決。
http://www.softantenna.com/wp/tips/macos-high-sierra-disable-local/

Blenderの基本操作

  • 投稿日:
  • by
  • カテゴリ:

覚えられないのでメモ

◆基本操作
A:全選択&解除
B:矩形範囲で選択
G:移動
R:回転
S:拡大
Ctrl+Tab:選択モード切替
テンキー5:投影切り替え

◆頂点(vertex) に関するメニュー[Ctrl+V
◆辺(edge) に関するメニュー:Ctrl+E
◆面(face) に関するメニュー:Ctrl+F
◆スペシャルメニュー:Wキー
◆機能名で検索:Spaceキー

◆ウィンドウの結合
ウィンドウの境界線上で「右クリック」→「エリアを結合」

◆オブジェクトとアーマチュア関連付け
① オブジェクトを右クリックで選択
② Shift押しながらアーマチュアを右クリックで選択
③ 「Ctrl+P」で「アーマチュア変形>自動ウェイトで」を選択

◆ボーンの削除
ボーン選択して「X」キー

◆ボーンの親変更
「Properties」→「Bone」→「Rerations」→「Parent」で親ボーンを設定

◆ボーンの親子切り離し
「Properties」→「Bone」→「Rerations」→「Connected」を無効にする

◆ボーンの複製「 Shift+D」キー

◆ボーンに新たなボーンを追加 「E」キー

◆ウェイトペイント
反対側の面も塗れるようにする:「陰面処理」アイコンで切り替え

[モデリング関連]
E:辺や面の押し出し
F:面張り(頂点選択だけでなく辺選択でもOK)
K:ナイフ
V:辺や点の分離
Gを2回押し:スライド移動
Ctrl+B:ベベル
Ctrl+J:選択メッシュを結合
Ctrl+R:ループカット、一方向に分割
Ctrl+T:三角ポリゴンに
ALT+J:四角ポリゴンに
ALT+M:頂点同士を結合
ALT+S:法線方向に拡大縮小
Ctrl+EのSubdivide:辺を分割
Ctrl+EのBridge Edge Loops:辺同士を面でつなぐ
Ctrl+VのRemove Doubles:重複頂点削除
Ctrl+VのSmooth Vertex:選択頂点を滑らかに

[選択関連]
A:全選択&解除
B:矩形範囲で選択
ALT+右クリック:ループ状に選択
ALT+B:指定領域のみ表示・非表示
H:非表示、ALT+Hで解除
Shift+H:選択箇所のみ表示
Ctrl+I:選択反転
L:カーソル上につながってるメッシュを選択
Ctrl+L:つながっているメッシュを選択

[UVマッピング関連]
・UV展開の切れ目を指定 辺を選択して「Ctrl+E」→「シームをつける」
・UV展開 面を選択して「U」→「展開」
・ピン留め 頂点選択して「P」、「ALT+P」で解除
W:溶接/整列メニュー

参考:
http://ito144.hateblo.jp/entry/2017/04/13/100817
http://cg.xyamu.net/Blender/entry188.html
http://cg.xyamu.net/Blender/entry26.html
http://riotoqll.hatenablog.com/entry/2014/02/10/162604
http://xolokix.hatenablog.com/entry/2017/12/10/234406

アドフリくんのキャッシュ

  • 投稿日:
  • by
  • カテゴリ:
リワード動画を実装したら、
アプリ起動するだけで/Library/Cachesにデータがダウンロードされ
アプリ終了後も残り続ける模様。

ストレージが逼迫したらOSが勝手に削除するディレクトリではあるものの、
iOSの「ストレージを管理」で見たときに「書類とデータ」にカウントされ、
無駄に容量を食うアプリという印象を与えてしまう。

起動時や終了時にApplication.temporaryCachePath内をクリアするのが良さそう。


public static void DeleteCaches()
    {
        string path = Application.temporaryCachePath;
        System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(path);
        foreach (System.IO.FileInfo file in di.GetFiles())
        {
            if (file.IsReadOnly == false) {
                try
                {
                    file.Delete ();
                }
                catch (IOException)
                {
                }
            }
        }
        foreach (System.IO.DirectoryInfo dir in di.GetDirectories())
        {
            //iOSが生成するSnapshotsは消せない模様
            if (dir.Name != "Snapshots") {
                try
                {
                    dir.Delete(true);
                }
                catch (IOException)
                {
                }
            }
        }
    }

追記:
AndroidだとApplication.persistentDataPath内にも色々溜め込んでいる。

アドフリくんのMovieRewardCallback

  • 投稿日:
  • by
  • カテゴリ:
自前で作成した初期化やコールバック受け取り用のクラスを
AdfurikunMovieRewardUtilityと同じGameObjectにアタッチしてはいけない。

引数の型が異なるMovieRewardCallbackが2つのクラスにあって
SendMessageで両クラスに通知されるので下記エラーが発生する。

MissingMethodException: The best match for method MovieRewardCallback has some invalid parameter.


Androidで動いてたけどiOSではクラッシュする。
以前実装した時も同じようにハマってMovieRewardCallbackが呼ばれないなぁとか思った記憶がある。