OmniAICreator/Qiita-1.07M huggingface dataset:
ハイレゾ音響信号処理(1) -- Pythonで24bitのwavファイルを読む方法

# 概要
ちょっと前にハイレゾ音源に対する信号処理を行う機会があり,
その際に24bitのwavが読み込めるPythonライブラリをいろいろ調べたので備忘録がてらメモ.

Pythonでwavを読むライブラリとしては`scipy.io.wavfile`があるが,
これは量子化bit数={8,16,32,64,96,128}のwavのみ対応.
つまり,24bitのwavが読み込めない.
巷のハイレゾ音源で一番多いのが24bitのものなので,
これは困るということで24bit wavを読む方法を調べてみた.

# 候補
- 標準のwaveモジュールでがんばる
- scikits.audiolab
- wavio

## 標準のwaveモジュールでがんばる
(実装してはいないので間違ってたらすみませn)
`readframes()`で得られる`bytes`オブジェクトをnumpy.ndarrayに適切に変換・格納すればイケるはず.
ただし24bit単位のバイト列を32bit型に格納する必要があるのでunpack処理が若干めんどくさいと思われる.

## scikits.audiolab
[http://cournape.github.io/audiolab/](http://cournape.github.io/audiolab/)
わりと昔からあるlibsndfileラッパー.
MATLABライクな記法でwavの読み書きが可能.

```test_audiolab.py
from scikits.audiolab import wavread

data, fs, fmt = wavread(fn)
```

### 利点
- libsndfileのラッパーなのでwav以外でもlibsndfileに対応している形式は扱える(flac等も可能)
- MATLABユーザに優しいAPI
- Sndfileオブジェクトを直接操作できるのでよりlow-levelに近い処理もできる

### 欠点
- libsndfileに依存しているのでインストールがめんどくさい
- 2010年を最後に更新が止まっている
- ので当然Python3非対応

## wavio
[https://github.com/WarrenWeckesser/wavio](https://github.com/WarrenWeckesser/wavio)
比較的新しいライブラリ.
(内部的にはwaveを使って実装している模様)
24bit含め任意のfs/量子化ビット数のwav読み書きが可能.

```test_wavio.py
import wavio

w = wavio.read(fn_in)
fs = w.rate
bit = 8 * w.sampwidth
data = w.data.T
data = data / float( 2**(bit-1) ) # -1.0 to 1.0に正規化 
```

### 利点
- Python3対応
- Pure-python (外部libへの依存なし)
- APIもわりとわかりやすい

### 欠点
- wavのみ対応

# で、結局どれ使えばいいの？
個人的には`wavio`が現状の最適解な気がする.
wav以外使えない,という欠点はあるが,最悪soxとかffmpegで変換するという手が使えなくはないし.

「標準以外のライブラリ依存を増やしたくない」という場合はおとなしくwaveで実装しましょう.
Visual Studio Code の拡張機能を作ってみた

[クソアプリ Advent Calendar 2016](http://qiita.com/advent-calendar/2016/kusoapp) の12日目です。

# はじめに
ソフトウェアエンジニアたるもの、クソだろうがなんだろうがモノを作らなければ始まらない。
ということで、学習もかねてAngular2 + Firebaseあたりの構成で何かWebアプリでも作ってみようと思ってAdvent Calendarに参加したんですが、特に作るものが思いつかず。
気がつけば投稿日当日になってしまい、焦った中で思いついたのが、普段使っている道具を少し便利にするものを作ってみようというものでした。

というわけでVisual Studio Codeの拡張機能についてです。

# 作り方
Visual Studio Codeの拡張機能は、公式で用意されているジェネレータを利用して作成します。さくっと雛形が用意されるので、ファイル構成を見るだけでなんとなくやることが掴めますし、Visual Studio Codeのデバッグ機能も使えるので、作成時の敷居は結構低いです。

公式サイトにも丁寧なチュートリアルが載っているので、英語に問題がない方はそちらを確認するとよいでしょう。
[公式 Example - Hello World](https://code.visualstudio.com/docs/extensions/example-hello-world)

僕は英語に問題がある方なので、こちらの方の日本語記事がとても参考になりました。
[Visual Studio Code はじめての拡張機能開発](http://qiita.com/rma/items/8c53077d1355ab8fa4c6)

# できあがり
チュートリアルも終え、早速自前の拡張機能を作成してみました。
つくったのはこちら、ステータスバーに天気が表示される拡張機能です。

<img width="785" alt="extension_js_-_tokyo-weather.png" src="https://qiita-image-store.s3.amazonaws.com/0/73451/a7f8a728-70d3-00c5-6e06-0af3cc8891ba.png">

全然いらないですね。。

Yahoo!天気のRSSから天気情報を取得してステータスバーに出力しているだけです。
とはいえ、簡単なものではあるものの、作成方法に関する知識ゼロの状態から2〜3時間で一応かたちになるというのは、なかなかお手軽で面白いのではないでしょうか。

できあがった拡張機能は、下記に配置することで常時利用可能になります。

- Windowsなら: %USERPROFILE%\.vscode\extensions
- Mac/Linuxなら: $HOME/.vscode/extensions

今回は流石に出来栄えがクソすぎてやりませんでしたが、作成した拡張機能は公式の[Marketplace](https://marketplace.visualstudio.com/)に公開することも可能です。
公開するとなるとアイコンやREADME、CHANGELOGなどをきちんと用意する必要があるので、クソのままではいられない面もあるかと思いますが、次はもうちょっと使えるものをつくってMarketplaceに公開してみたいですね。

でも普段使っているエディタはintelliJです。
QiitaアドベントカレンダーのはてブランキングをSlackに通知する

## TL;DR

[企業・学校・団体アドベントカレンダー](http://qiita.com/advent-calendar/2016/categories/company)をみんなで運営していると、「誰が一番はてブ集めたか」って気になるよね。
なので、はてブ数をSlackにランキング形式で投稿するクローラー＆ボットを作ったよ、というお話。

https://github.com/nisshiee/adventcalendar-ranking

## 中身

- 環境変数に、以下のような情報をセット
    - 取得するQiitaアドベントカレンダー名、年次など
    - 通知先のSlack Incoming WebhookのURL
- 実行すると以下のように動作
    - Qiitaアドベントカレンダーページをクロールし、記事一覧（投稿済であればURLも取得）を作成
    - はてなブックマークAPIを使って、各記事のはてブ数を取得
    - 記事一覧をはてブ数降順ソートして、それっぽく整形
    - SlackのIncoming Webhookをコールして通知
- アーキテクチャ
    - Ruby 2.3.3
    - Rake（タスクランナー）
    - Nokogiri（Qiitaアドベントカレンダーページのスクレイピング）

## 運用

- herokuにそのままデプロイ可
    - 環境変数をheroku画面からセット（環境変数制御で他のアドベントカレンダーにも使える）
    - schedulerアドオンを使ってDailyでrakeタスクを実行

## 効果

- 「はてブ集められた記事とそうでない記事の違いはどこにあるのか」等の議論が発生
- これから記事投稿予定の人のモチベーション向上

## もうちょっとがんばろうと思っている所

- Deploy to herokuボタンを作ってみたい
リリースビルドだけGsonでパースできない


# 事象
今までのコードが手作業でJsonをパースしてたので、APIのレスポンスに値が追加されるたびに自前のparserも書き足す運用だった。毎回修正箇所も多くなるのでGsonで一発Parse！スマートやん！てやろうとしてた

# Gsonの導入

```
    protected static final Gson GSON = new GsonBuilder().serializeNulls().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create();
```
これでをいろんなAPIで使いまわすつもりでstatic宣言。
`FieldNamingPolicy`をセットするとJSONが何ケースで返ってくるかを指定していい感じにDtoにパースしてくれる
この場合はjsonで`Code`をdtoの`code`に代入してくれる


http://qiita.com/yysk/items/e549ba40bc2accfdff35

# デバッグまでは何も問題なし。
デバッグまでは何も問題なく通っていたがリリースビルドにした瞬間うまくいかず。
本番APIが変わったのか、色々試したけど問題なさそう。

# 結局Proguardだった
今まで`@SerializeName`のアノテーションを使ってパースをしていたのでリリースビルドしても問題なかったが、
リリースビルドにすると難読化され、クラス名が変わってしまうのでGsonがうまくパースできないそう。
パース後のDtoがnullなので焦った。

```proguard-rules.pro
-keep class jp.co.hoge.parser.response.** { *;}

```
proguardでレスポンスをパースする対象のDtoの難読化をしないように設定するとこれは解決される。

http://stackoverflow.com/questions/30001674/gson-deserialize-null-pointer-in-released-apk

お陰で全然触ってこなかったproguardのことも勉強しなきゃなと思いました…。

完全にこの記事と同じ。結構時間かかっちゃったけどここまでたどり着くのに時間がかかってしまった
http://qiita.com/petitviolet/items/1b709f3f0db2659a271a
processingをはじめてみる

この記事は[高知工科大 Advent Calendar 2016](http://www.adventar.org/calendars/1872)の12日目の記事です。
ネタがなかったのでこれから学ぶprocessingについて書こうと思います。

# processing
中身はjavaでAPIを使って簡単にGUIが実現できるもの

# 実際に触ってみよう

```test1.pde
size(500, 350);
rect(50, 50, 100, 100);
triangle(450, 50, 450, 100, 300, 120);
ellipse(250, 250, 200, 100);
```

実行するとこうなる
![Screenshot from 2016-12-12 19-15-26.png](https://qiita-image-store.s3.amazonaws.com/0/154329/3225a9df-9466-d775-ead2-c8679bc1ca06.png)

|意味 |
|:-:|
|size(横幅のピクセル数, 縦のピクセル数)                                 |
|rect(横の座標, 縦の座標, 表示したい横のピクセル数, 表示したい縦のピクセル数)   |
|   triangle(横の座標, 縦の座標, 横の座標, 縦の座標, 横の座標, 縦の座標)|
|   ellipse(中心の横の座標, 中心の縦の座標, 横の直径, 縦の直径)|

```test.2.pde
int i = 150, j = 350;
int flag = 0;

void setup(){
  size(500, 500);
  colorMode(HSB, 100);
  background(99);
  frameRate(20);
}

void draw(){
  if(i == 350)
    flag = 1;
  if(i == 150)
    flag = 0;
  fade();
  fill(33);
  rectMode(CENTER);
  rect(i, 150, 10, 10);
  rect(j, 350, 10, 10);
  if(flag == 0){
    i += 10;
    j -= 10;
  } else if(flag == 1){
    i -= 10;
    j += 10;
  }
}

void fade(){
  rectMode(CORNER);
  fill(99);
  rect(0, 0, 500, 500);
}
```

これを実行するとこうなる
![Screenshot from 2016-12-12 19-55-53.png](https://qiita-image-store.s3.amazonaws.com/0/154329/dc0e4182-ffec-89ca-32db-078c7fcabaa9.png)
![Screenshot from 2016-12-12 19-55-59.png](https://qiita-image-store.s3.amazonaws.com/0/154329/63f76032-2bd8-78bd-9a22-3444659fb2cd.png)
![Screenshot from 2016-12-12 19-56-03.png](https://qiita-image-store.s3.amazonaws.com/0/154329/b3516efa-70bf-f7cf-ac90-2606e21e4089.png)
# 終わりに
このように簡単にGUIが実現できるのはいいと思う。
今回はネタがなくこのような記事になったので次があるならなにか需要のあることが書きたい。
tvOS10からTopShelfに必要なサイズが一つ増えたよ

このサイズがないと申請できないです。

```
Archive upload failed with error: ITMS-90470 Missing TVTopShelfImage.TVTopShelfPrimaryImageWide key
```

2320px × 720px
https://developer.apple.com/tvos/human-interface-guidelines/icons-and-images/

しれっとXcode8から増えてましたね

<img width="203" alt="スクリーンショット 2016-12-12 19.59.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/31237/613a8c89-1119-d4d1-dc80-b196c4616cf3.png">
Amazon Lexの開始の仕方


AWSのアカウントはあります。
「無料のプレビュープログラムに参加する」から実行していますが、
アカウント登録後、AWS側からも何も返信がありません。

こちらに記載されているbotの構築が行えません。
https://aws.amazon.com/jp/blogs/news/amazon-lex-build-conversational-voice-text-interfaces/
BootstrapのCollapseがガタつく件

# 事象
[BootstrapのCollapse](http://getbootstrap.com/javascript/#collapse)を使用する際、開閉させるコンテンツにpaddingが指定されていると、アニメーションの最後にガクッとした動きが入ってしまう。


<p data-height="310" data-theme-id="0" data-slug-hash="JbORyv" data-default-tab="html,result" data-user="anchoor" data-embed-version="2" data-pen-title="BootstrapのCollapseがガタつく件" class="codepen">See the Pen <a href="https://codepen.io/anchoor/pen/JbORyv/">BootstrapのCollapseがガタつく件</a> by anchoor (<a href="https://codepen.io/anchoor">@anchoor</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>




# 原因
* Bootstrapでは全要素に ```box-sizing:border-box;``` が指定されている
* アニメーションにはpadding/borderを含まない高さ指定 ```.height(val)``` が使われている
* アニメーションが終了したタイミングで ```display: none / block;``` に切り変わる⇒その際にpadding分だけガタついて見える

# 対処方法

```.collapse``` な要素に padding がついていなければ良いので

 * ```.collapse``` な要素の margin で余白調整を行う
 * ```.collapse```に子要素divを追加して余白調整を行う

で対処可能です。後者の方が汎用性が高そうですね。


<p data-height="310" data-theme-id="0" data-slug-hash="RoYVex" data-default-tab="html,result" data-user="anchoor" data-embed-version="2" data-pen-title="BootstrapのCollapseがガタつく件2" class="codepen">See the Pen <a href="https://codepen.io/anchoor/pen/RoYVex/">BootstrapのCollapseがガタつく件2</a> by anchoor (<a href="https://codepen.io/anchoor">@anchoor</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>

# 参考
https://github.com/twbs/bootstrap/issues/12093
CTO事件簿~FrontendServerをGraphQLで突然実装~

# 読むとわかること

MicroServiceの外観、フロントエンドサーバー、GraphQLの大枠が理解できる。

# 目次

1. MicroService
2. FrontendServerとは？
3. GraphQLとは？
4. FiNCでのアーキテクチャ
5. 今後の展望

# 1. FiNCとMicroService

FiNCではMicroServiceを採用している。
なぜ採用しているかは以下を参照していただきたい。

http://www.slideshare.net/fumiyashinozuka/finc-52564251

昨年から、Microserviceミートアップを企画しだしてFiNC内のイベントも活性化してきており、
Backend界隈でなかなかの盛り上がりも見せていると思う。

このミートアップで議論によく上ってくるのがFrontendServerである。
サービスがたくさん増えてくるとClientがどこのAPIを叩けば良いのか、Requestを複数呼んでしまって非効率になる等議論が勃発する。

# 2. FrontendServer

上記の問題を解決するのがFrontendServerである。
BackendのサーバーはRestに設計し、ClientはFrontendServerを叩けばViewに対応したデータを返してきてくれるといった、優れもの。

![図1.png](https://qiita-image-store.s3.amazonaws.com/0/32479/dfab19cc-c46d-2acb-20f5-8208ec4745b4.png)

現在、FiNCのアプリのフィーチャーに導入していっているところである。
FiNCはGraphQLといった、フレームワークを採用している。

# 3. GraphQLとは？


・ 本家のサイトから参照(http://graphql.org/learn/)

GraphQLはAPI用のクエリ言語であり、データ用に定義した型システムを使用してクエリを実行するためのサーバー側のランタイムです。 GraphQLは特定のデータベースまたはストレージエンジンに結びついておらず、代わりに既存のコードとデータに基づいています。
GraphQLサービスは、これらの型の型とフィールドを定義し、各型の各フィールドに関数を提供することによって作成されます。たとえば、ログインしているユーザが（私）であることとそのユーザの名前を示すGraphQLサービスは、次のようになります。

```
type User {
  id: ID
  name: String
}

type Query {
  me: User
}
```

上記の用に、Userの名前を取得する際に、方を定義することによって、Clientからクエリを発行するだけでデータを吐き出す事が可能になるのである。
上記の型を定義した返り値は以下になる。

```
{
  me: {
    name: "Mitsunori Nanno"
  }
}
```

Clientからのクエリは以下

```
{
  me {
    name
  }
}
```

# 4. FiNCでのアーキテクチャ

Node + GraphQL + koa で構築。
構築手順は以下。

```
npm install apollo-server body-parser express graphql graphql-tools
```

かなりシンプル。
ここからInternalAPIで各サービスのAPIをまとめてClientに返す。

QueryはgeneraterがGraphQL側のサービスに作成されるので、誰でも結構簡単に作ることが可能。


# 5. 今後

各サービスのAPIのResponseはJsonSchemaで定義されていて固定されているので
GraphQLとAPIを繋ぎこむところの工数が無駄と感じている。
JsonSchemaを入れると自動で、GraphQLのコードが作成されるようなGeneraterを作れば相当いい。

来年はFrontendServerを如何に工数を書けずに作っていくかを考えたい。
【ゲリラアドカレ】UE4ゲーム実装　進捗報告 5日目(バトル画面デザイン配置　その２)

【非公式】某会社設立記念ゲリラ Advent Calendar 2016 11日目の記事です。

FlashゲームをUE4で再実装するゲリラアドカレです。

前回、バトル画面の仕様を決めたので早速実装していきたいと思います。
今回はデザイン配置になります。

・注意
許可を取ってないので通常業務の空いた時間を利用して作成するため、作成中のゲーム、及びアドカレは完成保証がなければ、ゲーム自体もリリースされる保証も皆無なので、あんまり期待しないでください。

#デザイン配置

仕様を決めたので、早速素材を配置していきます。

![image](https://qiita-image-store.s3.amazonaws.com/0/104377/dfc1a96f-fc73-a1e8-6bb2-2e346c49bbd9.png)

コマンドを選択するUIを作成しました。
![image](https://qiita-image-store.s3.amazonaws.com/0/104377/0228bebd-62f1-0f7e-8be1-32ea5df554ae.png)

透明化しているボタンによるアクションにより、ボタンラベルの色を変更します。

まずテキストのカラーに対するバインドクラスを作成します。
![バインド.png](https://qiita-image-store.s3.amazonaws.com/0/104377/59450a6b-6fb6-3cb3-5ce9-c31db9ed1876.png)

色を変えるのは共通処理なので、関数を作って呼び出すようにします。
![バインド３.png](https://qiita-image-store.s3.amazonaws.com/0/104377/914f7f34-3a8f-c5b6-6c0c-ad03ab888ac4.png)

最後にバインド関数に呼び出す処理を追加して終わりです。

![バインド2.png](https://qiita-image-store.s3.amazonaws.com/0/104377/f9285239-5b88-21ba-92d8-04e779de8323.png)

このようにマウスオーバーした時に文字の色が変わるようになりました。
![image](https://qiita-image-store.s3.amazonaws.com/0/104377/84376183-8e63-77b2-7810-66a918ac5649.png)

#途中成果

ひとまずこんな感じになりました。

![image](https://qiita-image-store.s3.amazonaws.com/0/104377/4852108b-4f78-8209-099c-728cf9f55dbc.png)

今日はここまでです。
バトルが完成するか正直分かりません。実装量もまだまだあります。
完成目指して頑張っていきます。
ScalaでPlayFramework: ビュー編

この記事は以下の記事の続きです。
[ScalaでPlayFramework: コントローラ編](http://qiita.com/Yaruki00/items/1a2aaba4109f6f43f8ed)

公式ドキュメントはこちら
[Play 2.5.10 documentation](https://www.playframework.com/documentation/2.5.10/Home)
この記事の内容は、だいたい以下のページに書かれています。

* [The template engine](https://www.playframework.com/documentation/2.5.10/ScalaTemplates)

# ビューをいじってみる
PlayFrameworkではTwirlというテンプレートエンジンを使用します。
作ったビューはプロジェクトルート以下の`app/views`に入れます。
今回は`hello_twirl`という名前のビューを作ってみます。

## コメントを書く
`@*`と`*@`で囲んだ部分がコメントになります。

```scala:app/views/hello_twirl.scala.html
@* hello_twirl Template File *@
```

## パラメータを受け取る
テンプレートの先頭に以下のように書くことでパラメータを受け取ることができます。
3つ目の例のように、デフォルト引数を指定することもできます。

```scala:app/views/hello_twirl.scala.html
@(num: Int, str: String, default: String = "twirl")
...
```

### コントローラからパラメータを渡す
ビューを使うには以下のように書きます。引数がそのままビューにパラメータとして渡ります。
Eclipse上ではエラーが出ますが、問題なく動作します。エラーどうにか消せないのかな？

```scala:app/controller/HomeController.scala
...
  def hello_twirl = Action {
    Ok(views.html.hello_twirl(1, "Hello", "Play!"))
  }
...
```

ルーティングに忘れずに追加しましょう。

```scala:conf/routes
...
GET     /hello_twirl                controllers.HomeController.hello_twirl
...
```

## 変数を埋め込む
`@変数名`で変数を埋め込めます。

```scala:app/views/hello_twirl.scala.html
@(num: Int, str: String, default: String = "twirl")

<!DOCTYPE html>
<html>
	<head>
		<title>Test</title>
	</head>
	<body>
		<h1>@str @default</h1>
		num is @num!
	</body>
</html>
```

`/hello_twirl`にアクセスすると、コントローラで指定した値が表示されるはずです。

## 関数やら制御構文を使う
関数を定義することができます。制御構文は、`if`と`for`を使うことができます。

```scala:app/views/hello_twirl.scala.html
@(num: Int, str: String, default: String = "twirl")

@upperCase(c: Char) = {
  @c.toString.capitalize
}

<!DOCTYPE html>
<html>
	<head>
		<title>Test</title>
	</head>
	<body>
		<h1>@str @default</h1>
		num is @num!
		<ul>
		@for(c <- str) {
			@if( c == 'H' ) {
				<li>HHH!</li>
			} else {
				<li>@upperCase(c)</li>
			}
		}
		</ul>
	</body>
</html>
```

## 値を定義する
スコープの中で有効な値を定義することができます。使いみちはよくわからない。

```scala:app/views/hello_twirl.scala.html
...
@defining(str + " " + default) { text =>
    <div>@text</div>
}
...
```

## インポートする
できるみたいです。

```scala:app/views/hello_twirl.scala.html
@(num: Int, str: String, default: String = "twirl")

@import utils._
...
```

全てのテンプレートでインポートしたいものがあれば、`build.sbt`に書くといいみたいです。

```scala:build.sbt
TwirlKeys.templateImports += "org.abc.backend._"
```

## エスケープする
あります。

```scala:app/views/hello_twirl.scala.html
...
@Html("<>")
...
```

# おわりに
パラメータにどんなのがあるかわかるのがいいですね。
今使ってるPHPのCodeIgniterはビューだけ見てると突然謎の変数が出てきて、なんだこれってなるので。
クオリティが非常にアレな感じですが、執筆時点で絶賛風邪引き中なので許してくだされ。。。
次はモデルを扱います。

次: [ScalaでPlayFramework: モデル編](http://qiita.com/Yaruki00/items/ad61f1977571c399fdcd)
シーン内の不明なプラグインを除去する



不明なプラグインが存在する際、シーンを開くと
Errors have occurred while reading this scene that may result in data loss.
と出てしまいます。

2016で新規に追加されたコマンドのunknownPluginを使用すれば照会、除去することができ、シーンを開く際にエラーを吐くことがなくなります。

複数の不明プラグインがあることを想定しコードを書きました。

```python:DeleteUnknownPlugin.py
import maya.cmds as cmds

add=0

#シーン内の不明なプラグインをリストします。
unPl = cmds.unknownPlugin( q=True, l=True )

try:
    for i in unPl:
        print unPl[add]+' is Remove.'

        #指定された不明なプラグインをシーンから除去します
        cmds.unknownPlugin( unPl[add], r=True )
        add += 1
except:
    print 'UnknowPlugin is none.'
```

これで不明なプラグインをシーンから除去することができます。
「ここさー、ちょっとだけアニメーションしてよー」とか気軽に言われたときに

「ページ読み込んでちょっとスクロールさせたらこれが出てくる」「読み込んで２秒くらいしたらここがどーんとなる」とか「まあそんなあんまり本気なつもりじゃないんだけどーあるとなんか嬉しいっていうかー」的なサイト上の演出を、とっても簡単に話振られたりしませんか？　私はよく振られます。都度それらしいアニメーション専用のプラグイン入れるのも大仰だし、でも都度都度CSSだのJSだののアニメーションを書くのも疲れたので、この際jQueryのプラグインにまとめてみました。

[jquery.cue.js](https://github.com/kobaatsu/jquery.cue.js)

なお、動作しているのはこちらです。

http://codepen.io/kobaatsu/pen/NbLjXL

至ってシンプルに、指定のタイミングが来たら、やはり指定されたCSS transitionが動くというそれだけのシロモノです。HTML側で概ね制御できますので、調整などもそれなりに簡単に行なえます。でもやっぱり複雑なことをさせたいよ、てな場合は、指定のタイミングで任意のクラス名が付与されるという（だけの）仕組みですので、CSSに書いちゃうのがいいと思います。

折があれば複数のトランジションが指定できるようにしようとか思いますが、それはまあまたいずれ。
Ubuntu以外のディストリビューションでarmhfなDocker imageを作成する

## 背景

Dockerで、armhfなクロス環境のコンテナができると、Raspberry piでのアプリケーション開発が捗ります。
クロスコンパイラで可能ですが、apt-get等でライブラリ等をインストールするとなると、尚更敷居が高く感じます（といいますか、やり方知らないだけです…）。また、x86で作成して、Raspbianでリビルドしても、ディストリビューションの違いから、リビルドエラーや実行時エラーがでて、その手間も馬鹿にできません。

クロス環境のコンテナを動かすには、binfmtが必要となりますが、CentOS等、提供されていないディストリビューションもあります。このような背景を受けて、他ディストリビューションでもクロス環境ができないか試行錯誤してみました。

## 種明かし

最初に種明かしをしておきます。binfmtの環境をホストに作るのではなく、コンテナ上で動かしてchrootします。その際のポイントとして、

- binfmt_miscをコンテナ実行時にマウントする
- /proc/sys/fs/binfmt_misc/registerにarmefなELFを書き込む
- コンテナ実行時はSYS_ADMIN,SYS_CHROOTを--cap-add で追加する

で実行できます。

## Dockerfile

```Dockerfile
FROM ubuntu
RUN apt-get update && apt-get -y upgrade \
 && apt-get install -y \
    qemu-user-static   \
    binfmt-support     \
    vim
RUN mkdir /raspi-root \
 && mkdir /app
ADD root.tar.gz /raspi-root
ADD start.sh /
RUN chmod +x start.sh
WORKDIR /raspi-root
CMD ["/start.sh"]
```
qemu-user-staticとbinfmt-supportがあれば十分です。rootイメージについては、"[Raspbianをdebootstrapから作る](http://qiita.com/abtc/items/862e2999d7c136201a44)"を参考にしてください。

## start.sh

```shell-session
cd /raspi-root
mount -t binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc
echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-arm-static:' > /proc/sys/fs/binfmt_misc/register
mount -t sysfs sysfs sys/ && \
mount -t proc  proc  proc/ && \
mount -o bind /dev  dev/ && \
mount -o bind /dev/pts dev/pts
exec chroot . 動かしたいもの
```

実行時は、chrootの一般的なmountとbinfmt_miscのmount及びELFイメージの書き込みだけです。
（※sysfs,proc,devのmountは無くても問題ないかと思います。必要に応じてでいいかと…）

## コンテナ実行

```shell-session
docker run -it --rm \
--name コンテナ名 \
--cap-add SYS_ADMIN --cap-add SYS_CHROOT \
イメージ名
```

です。

## その他

上記の内容でDocker for Windows(Hyper-V版)で問題なく動いてます。多分、CentOS,CoreOS等でも実行できると思います。
コンパイル速度はクロスコンパイルに比べると、かなり遅くイライラします。が、あれこれ環境を作るよりも簡単ですし、本番環境も全く同じ環境でリビルドできたりするので、トータル的には良しとしています。
AndroidのSQLiteのセキュリティについて

JSSECが公開している『Androidアプリのセキュア設計・セキュアコーディングガイド』の2016-09-01版を共有用にまとめているもののうち、「4.5. SQLite を使う」のものとなります
詳細やサンプルコードについては原著の方を参考ください
なお、直接外部から読み書きを許すデータベースは想定せず、ContentProviderのバックエンドやアプリ単体での仕様を前提としています

個人的な感想ですが、この項目は、一定レベルまでの第三者の攻撃から守る対策しか乗っていません
もしセンシティブな情報を扱う場合は、DBを扱うセキュリティ全般についての対策も見ておいた方が良いと思われます

## チェックポイント
- [ ] SQLiteOpenHelperを使用している
 * ただし、適切な配布場所、アクセス権が設定されている(後述)
- [ ] 入力値をSQL文に使用する場合にはプレースホルダを利用している
- [ ] アプリ要件に従って入力値をチェックしている
- [ ] 他アプリとのDBデータを共有する場合は、ContentProveiderでアクセス制御している

## Tips
### DBのファイル配置場所、アクセス権について
アクセス権が適切であっても、SQLiteOpenHelperの第2引数にSDカードの絶対パスを指定するなど、アクセス権の設定を行えない場所に配置した場合、外部からアクセス可能になります
また、アプリディレクトリに配置しても、アクセス権が正しくない場合、意図しないアクセスになります
そのため下記2点が必要になります
 1. Context#getDatabasePath(String name)、もしくはContext#getFilesDirで取得できるディレクトリに配置する
 2. MODE_RIVATEに設定する
 
SQLiteOpenHelperを使用した場合、コンストラクタの引数にDBの名前を指定すれば、問題はありません。ただし、引数にフルパスを指定した場合、その場所に作成されてしまい、場所によってはアクセス可能になってしまうため、注意が必要です
Context#openOrCreateDatabaseを使用する場合は、明示的にMODE_PRIVATEを指定する必要があります。ファイルの配置場所に関してはSQLiteOpenHelperと同様です

### プレースホルダについて
SQLインジェクションを防ぐために、任意の入力値をSQL分に組み込む際にはプレースホルダを利用すべきです。下記の2つの方法があります
 1. SQLiteDatabase#compileStatement()を使用して SQLiteStatementを取得する。その後、SQLiteStatement#bindString()、bindLong()などを使用してパラメータをプレースホルダに配置する(ただし、SELECTコマンドの結果として先頭の1要素しか取得できないため、用途が限られます)
 2. SQLiteDatabeseクラスのexecSQL()、insert()、update()、delete()、query()、rawQuery()、replace()などを呼び出す際にプレースホルダを持ったSQL 文を使用する

ただし、テーブルの作成や削除等のDBオブジェクトを処理対象としたSQL文はテーブル名などの値に対してプレースホルダを使用できません。そのため、プレースホルダの使用できない値に対して、外部から入力された任意の文字列を使用するような設計はすべきではなく、また、入力値に危険がないどうか確認する必要があります

### DBのオープンの仕方について
読み込みのみの場合に関しては、SQLiteDatabase#openDatabaseにOPEN_READONLYを指定して、DBをオープンするのが好ましいです
SQLiteOpenHelper#getReadableDatabase、getWritableDatabaseやContext#openOrCreateDatabase、QLiteDatabase#openOrCreateDatabaseでオープンした場合は、読み書き可能な状態で開かれるため、アプリの仕様と実装の範囲で対応できますが、書き換えられる可能性が存在します。

### 入力性データの妥当性をチェックする
SQLiteは値の正当性確認については期待できません。なので、アプリの要件にしたがってSQL文を使用して値を格納、取得する前に、内容の型や長さについて確認する必要があります

### DBにいれるデータについて
 SQLiteでは
 * 全てのデータが平文の文字データとしてDBファイル何に格納されます
 * DBに対してデータの削除を行っても、データ自体はDBファイルから削除されません
 * データを更新した場合も、DBファイル内には更新前のデータも残ってます

そのため、削除されたはずのデータが残っている可能性があります。基本的には、対策をしていれば直接アクセスされません。が、root権限を奪取されている場合等はファイルを抜き出せるため、センシティブなデータはそのまま格納すべきではありません
もし、どうしても格納する場合は、暗号化したデータを格納する、DB全体を暗号化するなどの対策が必要です

## 参考

『Android アプリのセキュア設計・セキュアコーディングガイド』【2016年9月1日版】
https://www.jssec.org/dl/android_securecoding.pdf
MACの隠しファイル・フォルダを表示

## MACの隠しファイル・フォルダを表示
`$ defaults write com.apple.finder AppleShowAllFiles TRUE
$ killall Finder`

設定を変更した後、プロセスを落として有効にしています。

非表示に戻したい時は、
`$ defaults write com.apple.finder AppleShowAllFiles FALSE`
【ColdFusion】 SSL証明書の有効期限日を確認する

ColdFusionで、SSL証明書の有効期限日を確認する

以下の情報を参考にした。
https://forums.adobe.com/thread/959994



```cfm

<cfscript>

// 対象のドメイン名をセット
commonName = "www.example.com";

factory = createObject("java", "javax.net.ssl.HttpsURLConnection").getDefaultSSLSocketFactory();
socket = factory.createSocket(commonName, javacast("int",443));
socket.startHandshake();
certs = socket.getSession().getPeerCertificates();


if(isArray(certs)){
  cert = certs[1];
  expirationDate = dateFormat(cert.getNotAfter(),"yyyy/mm/dd");
  // 有効期限日を出力
  Writedump(expirationDate);

}
socket.close();

</cfscript>


```
Riot3.0にアップデートした時にRiot template errorが出てハマった

## Riot template error thrown in the <...> tag
タグ内で自身のデータにアクセスしようとした時に下記エラーが出るようになりました。

```
> Riot template error thrown in the <...> tag
```

キャプチャ
![スクリーンショット 2016-12-12 18.10.48.png](https://qiita-image-store.s3.amazonaws.com/0/29966/9628de7d-49d1-e684-8148-291a67141d48.png)

ソースではカスタムタグ内で`data.hoge`のようにオブジェクトのプロパティにアクセスしようとしていました。

```
<custom-tag>
  <h1>This is Riot 3.0</h1>
  <p>Show console, you check error <span style="color:red;">"Riot template error thrown in the <...> tag".<span></p>
  <p>{data.hoge}</p>
</custom-tag>
```

2.0ではエラーが出ない
[サンプル(codepen)](http://codepen.io/kwst/pen/QGVpMg?editors=1000)

3.0ではエラーが出る
[サンプル(codepen)](http://codepen.io/kwst/pen/GNXWOo?editors=1000)

### `No update and updated events triggered before the mount`が関係しているのかな…
色々試行錯誤していくと、mountされる前にちゃんと`update`でデータを入れてやるとエラーは解消されました。

[移行ガイド](http://riotjs.com/guide/migration-from-riot2/#breaking-changes)には、
> No update and updated events triggered before the mount

と記載されているので、おそらくmountイベントの前には`update`が走らないようになったのが関係しているのかなと。
RGSSというものがあった、そんなお話

［本記事は、[Shinosaka.rb Advent Calendar 2016](https://qiita.com/advent-calendar/2016/shinosakarb)の12/13分の記事です］

Rubyの記事を書くのは本当に久しぶりなので、緊張しておりますが、よろしくお願いいたします。

今日のテーマは、「RGSS(Ruby Game Scripting System)」なるものです。先日、その終焉を知り、筆を執ることにいたしました。

手前味噌ですが、当方も「るびま」に[Rubyistが知りたいかもしれないRGSSの世界](http://magazine.rubyist.net/?0005-RGSS)という記事を書いています。
記事の公開が2005年と、もう10年以上経っているシステムなんですね。

---

RGSSは元の名前の通り、「Rubyを使ってゲームを作る」というコンセプトで作られたシステムです。

「聞いたこと無いぞ、そんなシステム！？」と思われるかもしれません。というのも、RGSSはアプリケーションソフトの基幹システムだったので、あまり表に出てくる事がありません。

そのアプリの名は「RPGツクール」（[参考：ツクールWeb](https://tkool.jp/)）です。

RPGツクールは、様々なプラットフォーム（PC-8801,PC-9801,Windows,SFC,PS,Gameboy,Nintendo DS他）上で、難しいロジックを考えずにRPGが作れることを目的としたツールアプリです。

内部ロジックをいじるのは元々コンセプトとはずれているので、ちょっとしたフローチャートのようなろ実行構築しかできませんでした。

そんな折に登場したのが、2004年に発売された「RPGツクールXP」でした。
「XP」には、初めてロジックをプログラミングできる「RGSS」が搭載され、速度を気にしなければ（20fps、1秒間に20回しか画面を更新できなかった。通常のゲームでは60fpsが標準）、大抵のロジックが掛けるようになっていました（もちろん、低レベルな部分は無理ですが…）。

大きなポイントは、RGSSが「Rubyプラスアルファ」として存在していることでした。Rubyでゲームプログラムが掛けるようになっているのです。メインループを書き、その中にロジックや描画処理などを挿入して…という、昔ながらのやり方で実装できます。

Wikipediaにも[記事](https://ja.wikipedia.org/wiki/RGSS)がございますので、ご参考にしてくださいませ。

従来とは違い、この1行だけで「キーパッドのBボタンが押下の状態を返す」を実装できるのは大きなことでした。

```Ruby
    @final = Input.trigger?(Input::B)
```

他にも、画像をファイルから取り込んだり、位置を調整したりすることもできました。他にも、標準で付いているテキスト表示機能を使ってメッセージも制御できました。

とはいえども、いい事ずくめではなく、

 * 遅い(20fpsはちょっと…)
 * Rubyが古い(v1.8ベース)
 * 再配布に実行時モジュールが必要(結構でかい)

といったものがあり、厳しいところもありました。

とはいえ、「RPGツクール」新版(VX,VX Ace)へ映っていくごとにRGSSの性能も変わり、VXでは60fps対応、VX AceではRuby1.9ベースとなり、ますます使いやすくなっていきました。

しかし、盛者必衰かな、2016年に発表された「[RPGツクールMV](https://tkool.jp/mv/)」では、基幹部分がHTML5+Javascriptとなり、RGSSの終焉が現実のものとなりました。

ただ、VX Aceも同時販売されており、RGSSの灯が消えたわけではありません。もしご興味がお有りでしたら、一度触ってみてください。数多のフリーゲームや同人ゲームなどで動いているRubyの存在に感謝しながらプレイしてみることもおすすめします。

ちなみに、RPGツクールVX AceとRPGツクールMVの日本語版がSteamで配布されていますので、時間と資金に自身のある方はお楽しみくださいませ。

---

14日は、honeniqさんが、GR_CITRUS(mrubyボード)のハマりどころについて書かれるそうです。
いつもの電車が遅延していたら声で教えてくれるやつ作ったよ

テラテイルbluemixのアドベントカレンダーhttps://teratail.com/Bluemix の12日目です。


電車の遅延があるとみなさん困りますよね??
(はい 困ります!!)

**田◯都市線**でめえのことですよ。

そういうわけでいつも乗っている電車が遅延していたら朝出発前に教えてくれるやつを[IBM bluwmix](http://www.ibm.com/developerworks/jp/bluemix/)を使って作りました。

今回はwatsonの機能の一つのtextToSpeechを使用します。
文章を送ったら文節をいい感じに区切って音声にして返してくれます。

日本語にも対応していて好感が持てます。(対応言語数多い！！)
<img width="743" alt="スクリーンショット 2016-12-12 18.09.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/31272/27d2e4e3-8933-657c-5755-ff5baf592e50.png">


朝8時に田園都市線のサイトにHTTPリクエストを送って遅延情報があればWatsonのtextToSpeechに文章を送って音声を作ってもらいそれをRaspberry Piで再生するシンプルなものになっています。

最初にアプリを選択して以下のurl http://www.ibm.com/watson/developercloud/doc/getting_started/gs-credentials.shtml からusernameとpasswordを生成しておいて下さい。

環境は以下です。
node -v 6.7.0
npm  -v 3.10.8


以下コード

```node:app.js

var request        = require("request")
var cheerio        = require("cheerio")
var data_utils     = require('date-utils');
var fs             = require('fs');
var Iconv          = require('iconv').Iconv;
var TextToSpeechV1 = require('watson-developer-cloud/text-to-speech/v1');


// 田園都市線の遅延を表示してくれるurl
var base_url  = "http://www.tokyu.co.jp/railway/delay/print.php?line=3&d="

var dt        = new Date()
var formatted = dt.toFormat("YYYYMMDD")

//日時とかセットする
var request_url = base_url + formatted + "_1"

request({url: request_url , encoding: null},function(error, response, body){
    if(!error && response.statusCode == 200){
        // 文字コードゴニョゴニョするやつ
        var iconv = new Iconv('EUC-JP', 'UTF-8//TRANSLIT//IGNORE');
        body = iconv.convert(body).toString();
        $ = cheerio.load(body)

        //遅延情報について書いてるcssタグを指定
        var content = $('.left').text();

        var text_to_speech = new TextToSpeechV1 ({
              username: '{username}',
              password: '{password}'
        });

        var params = {
            text  : "田園都市線は只今" + content,
            voice : 'ja-JP_EmiVoice',
            accept: 'audio/wav'
        };
        text_to_speech.synthesize(params).pipe(fs.createWriteStream('late_dento.wav'));
    }
});


```
(すいませんnode.jsほとんど書いたことないのであまりイケてないですね、、、お察し下さい)

node-red editorでやろうとしたんだけどうまくいかず
nodeからで叩いてwatson apiに渡しています。

上記のnode.jsを実行してやると以下のように.wavファイルが生まれているのでそちらを
<img width="262" alt="スクリーンショット 2016-12-12 18.00.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/31272/620472aa-015a-6695-458b-3a14486542f5.png">

(女性の声にいい感じに変換してくれます。)

ラズベリーパイなりなんなりにcronを設定してもらえると
目覚まし時計がわりにその日の田園都市の遅延時間を音声として鳴らせますね。

以下ラズベリーパイの目覚まし時計の良い例があったので参考にして下さい。
http://deviceplus.jp/hobby/raspberrypi_entry_019/

明日は S346さんですね。
よろしくお願い致します。
Rubyクイズ 答えと解説

[こちら](http://qiita.com/isuke/items/471bb5672af6e761032c)のクイズの答えと解説(?)です。

ruby 2.3.0で動作確認しています。

## クイズ1

Aの出力結果は何でしょう?

```ruby
def hoge(options = {})
  foo = options.delete(:foo)
  puts "foo is #{foo}"
  puts "options is #{options}"
end

options = {foo: 'FOO', bar: 'BAR'}
hoge(options)
puts options #=> A
```
### 答え

Aの出力結果 : `{:bar=>"BAR"}`

### 解説

rubyは参照の値渡しを行いますので、引数を受け取った先(`#hoge`)で引数の破壊的な変更を行うと、
メソッドの呼び出しもとに影響があります。
`#deelte`は`!`はついていませんが破壊的メソッドなので注意です。

## クイズ2

A, Bの出力結果は何でしょう?

```ruby
INIT_STR = 'INIT STR:'

def hoge(num)
  temp = INIT_STR
  num.times do |n|
    temp << " #{n}"
  end
  temp
end

puts hoge(3) #=> A
puts hoge(3) #=> B
```

### 答え

Aの出力結果 : `INIT STR: 0 1 2`
Bの出力結果 : `INIT STR: 0 1 2 0 1 2`

### 解説

rubyは定数を書き換えてもエラーになりません。
`<<`メソッドでは値を書き換えてしまうので、このクイズの場合、実行するたびに`INIT_STR`が書き代わってしまします。

`#freeze`をつけておくと定数の変更はできなくなるので、必ず付けるようにすると良いでしょう。

```ruby
INIT_STR = 'INIT STR:'.freeze
```

## クイズ3

Aの出力結果は何でしょう?

```ruby
def hoge(options = {}, foo: 'FOO')
  puts options
  puts foo
end

hoge(bar: 'bar', foo: 'foo') #=> A
```

### 答え

Aの出力結果 : ``hoge': unknown keyword: bar (ArgumentError)`

### 解説

詳しく追っていないのですが、デフォルト引数とキーワード引数を併用するときは注意。

## クイズ4

A〜Hの実行結果は何でしょう?

```ruby
Array(1)            # => A
Array(nil)          # => B
Array([])           # => C
Array.new           # => D
Array.new(1)        # => E
Array.new(nil)      # => F
Array.new(nil.to_i) # => G
Array.new([])       # => H
```

### 答え

Aの出力結果 : [1]
Bの出力結果 : []
Cの出力結果 : []
Dの出力結果 : []
Eの出力結果 : [nil]
Fの出力結果 : `no implicit conversion from nil to integer (TypeError)`
Gの出力結果 : []
Hの出力結果 : []

### 解説

`Array`メソッドは引数で受け取った値を値として持つ配列を返します。

```ruby
Array("test") #=> ["test"]
```

引数の値はすでに配列の場合はそのまま返します。

```ruby
Array(["test"]) #=> ["test"]
```

`Array.new`は受け取った第1引数の数だけ、第2引数の値を持つ配列を返します。第2引数のデフォルト値はnilです。

```
Array.new(3) # => [nil, nil, nil]
```

ちなみに`nil.to_i`は0になります。

## クイズ5

Aの実行結果は何でしょう?

```ruby
class Hoge
  def foo
    self.bar
  end

private

  def bar
    puts 'bar'
  end
end

Hoge.new.foo # => A
```

### 答え

`private method `bar' called for #<Hoge:0x007fe96a07cde8> (NoMethodError)`

### 解説

rubyのprivateメソッドは「レシーバを指定して実行できない」メソッドなので、たとえ`self`でも付けることはできません。
初学者が引っかかりやすいので注意。

## クイズ6

Aの実行結果は何でしょう?

```ruby
class Hoge
  attr_accessor :foo,

  def initialize(foo)
    @foo = foo
    puts @foo
  end
end

Hoge.new('bar') # => A
```

### 答え

`wrong number of arguments (given 1, expected 0) (ArgumentError)`

### 解説

2行目に余計な`,`がついているのでエラーになるのですが、何故かエラー箇所が10行目になります。
なんででしょうね。

## クイズ7

A, Bの実行結果は何でしょう?

```ruby
def hoge
  sleep 1 # 重い処理
  'hoge'
end

if result1 = hoge
  puts result1 # => A
end
puts result2 if result2 = hoge # => B
```

### 答え

Aの実行結果 : hoge
Bの実行結果 : undefined local variable or method `result2' for main:Object (NameError)

### 解説

ifをインラインで書いたときのそうでないときにスコープが若干違うようです。
インラインで書いたときにはifの条件式で新しく定義した変数は他で使えないようです。

詳しい理由を[stackoverflowで教えてもらいました](https://ja.stackoverflow.com/questions/44291/ruby%E3%81%AEinline-if-%E3%81%AEscope%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)(1年越しの追記)。
Linux > UDP > port: 6000から6063 > Xプロトコル / Official: Port is registered with IANA for the application

```txt:動作環境
CentOS 6.5
```

### 前置き

これまでWindowsソフト同士でのTCPとUDP通信などを実装してきた。
将来的にそういうシステムでLinuxのデバイスと通信をすることもあるだろうか。
その場合、Linuxで使うポートとWindowsで使うポートで重なったものを使うとシステムの見通しが悪くなるように思われる。

ポートについて調べてみて、以下を見つけた。
https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers

### Port:6000-6063 > X

上記で気になったのが6000-6063の

> X11—used between an X client and server over the network

Xの転送に関して以下も見つけた。
http://www.astec-x.com/FAQ/port.html
> PC 側の X(TCP 6000番(～6063番))

以下も見つけた。

http://www.cisco.com/en/US/docs/internetworking/troubleshooting/guide/tr1907.html
> X Windows (UDP ports 6000-6063)

`ssh -X`で使うわりに、このあたりの仕組みをあまり知らずにいる。
とりあえず、このあたりのポートは他の用途に使うのは避けようと思った。

### Official

https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers

の白色の「Official」という記載が気になった。

> Official: Port is registered with IANA for the application.[5]

[IANAという団体](http://www.iana.org/)で登録済みとのこと。
少なくとも、Officialのポートは独自ソフトでは使わないようにした方がよさそうだ。
EC-CUBE3.0プラグインのデザインをカスタマイズしてみよう

EC-CUBE Advent Calendar 2016 の12日目です。

# EC-CUBE 3.0 プラグインのデザインをカスタマイズしてみよう

## 背景
プラグインの表示内容をカスタマイズしたいというケースはよくあると思います。
そのとき、プラグイン内のtwigファイルを直接編集してしまうと、バージョンアップの時に上書きされてしまうので避けたいところ...今回は`app/template`にカスタマイズしたtwigファイルを配置する方法をご紹介します。

## この記事の想定環境
- EC-CUBE 3.0.12
- 関連商品プラグインがインストールされていること  
(http://www.ec-cube.net/products/detail.php?product_id=962)

## この記事のゴール
関連商品プラグインの見出し文字列を「関連商品」→「よく一緒に購入されている商品」に変更してみます。

![image](https://qiita-image-store.s3.amazonaws.com/0/113212/ae9e0511-e9a6-a93d-6908-0a12d9052627.png)

## NGなカスタマイズ
`app/Plugin/RelatedProduct`に含まれるtwigファイルを直接編集することは避けるべきです。
将来、関連商品プラグインをバージョンアップした時に上書きされてしまいます。

## カスタマイズ方法
`app/template`にカスタマイズしたtwigファイルを配置することでカスタマイズができます。
プラグインのバージョンアップ時にも上書きされません。

### 1.twigファイルを`app/template`にコピー
twigファイルを**同じフォルダ名/階層構造**で`app/template/default`にコピー。

```
app/Plugin/RelatedProduct/Resource/template/front/related_product.twig
　↓
app/template/default/RelatedProduct/Resource/template/front/related_product.twig
```

### 2.コピーしたtwigファイルを変更
コピーしたtwigファイルのコードを「関連商品」→「よく一緒に購入されている商品」に書き換える。
`app/template/default/RelatedProduct/Resource/template/front/related_product.twig`

```html
<div id="related_product_area" class="row">
    <div class="col-sm-12">
        <h2 class="heading03">よく一緒に購入されている商品</h2>
```

### 3.キャッシュの削除
twigのキャッシュが残って表示が上手く反映できないことがあります。
`管理画面>コンテンツ管理>キャッシュ管理`からtwigのキャッシュを削除。

### 4.表示の確認
表示をカスタマイズすることができました。
![image](https://qiita-image-store.s3.amazonaws.com/0/113212/f49cfdc8-efa3-e86a-7847-1dab295601bd.png)

## 補足

### 関連商品プラグイン以外の場合
同じ手順で`app/template`側のtwigファイルを読み込ませることができます。
twigファイルを**同じフォルダ名/階層構造**でコピーすることが重要です！
(これが1文字でも間違っていると読み込んでくれません...)

※プラグインによっては`app/template`からの読み込みに対応していない場合があります。

### 表示が反映されない場合

- 手順3のキャッシュの削除を再度試してみる。
- 手順1のコピー先のパスが間違っていないか確認する。(大文字小文字にも注意)

### `app/template/default`に配置すると優先して読み込まれる理由
Application.phpでtwigファイルの探索パスを複数登録しています。
`app/Plugin`よりも`app/template/default`の方が探索の優先順位が高いため優先して読み込まれます。
https://github.com/EC-CUBE/ec-cube/blob/3.0.12-p1/src/Eccube/Application.php#L280

### 管理画面のtwigファイルをカスタマイズする場合
コピー先の`app/template/default/...`の「default」→「admin」に置き換えて下さい。

※管理画面側のカスタマイズは、トラブルの原因になりやすいためお勧めはしません。

### デザインテンプレートを使用している場合
手順１の`app/template/default/....`の`default`の部分がデザインテンプレートのコードになります。

## プラグインの実装について (プラグイン開発者向け)
EC-CUBEの仕組みを利用してtwigファイルにアクセスするようにしてください。
こうすることで、`app/template`からの読み込みに対応したプラグインになります。

```php
return $app->render('PluginCode/Resource/template/default/index.twig', array());
```

```php
$twig = $this->app['twig'];
$twig->getLoader()->getSource('PluginCode/Resource/template/default/index.twig');
```

## 最後に
twigファイルを変更しようとする前に、一歩立ち止まってこの記事を思い出していただけると嬉しいです。
わかりにくいところや間違っているところあれば、コメントおまちしています。

[EC-CUBE Advent Calendar 2016](http://qiita.com/advent-calendar/2016/ec-cube) 、明日は @mikakane さん、よろしくお願いします！
【ゲリラアドカレ】UE4ゲーム実装　進捗報告 5日目(バトル画面仕様決め)

【非公式】某会社設立記念ゲリラ Advent Calendar 2016 10日目の記事です。

FlashゲームをUE4で再実装するゲリラアドカレです。

バトル画面の実装が色々と多く、下手すると複雑になりすぎる可能性があるので、完成するか否か一旦考えず、仕様を決めてしまいたいと思います。
なので今回はプログラムのことは書きません。

・注意
許可を取ってないので通常業務の空いた時間を利用して作成するため、作成中のゲーム、及びアドカレは完成保証がなければ、ゲーム自体もリリースされる保証も皆無なので、あんまり期待しないでください。

#簡単な仕様決め

・コマンド選択形式のターン制バトル
・味方は最大３人。敵は１～５体、可能ならオリジナルの通り１０体まで
・HPがゼロになったら戦闘不能
・１ターンで敵、味方交互にコマンドを実行する。実行順は素早さの値で決まる
・選択出来るコマンドは「攻撃」「スキル」「逃げる」
・「スキル」コマンドは、キャラごとに覚える特殊行動。
・「スキル」コマンドはMPを消費して敵に攻撃を行う、もしくは味方の補助を行う。
・各スキルコマンドに消費MPが設定されており、MPの値が足りない場合はコマンドが選択できない
・「攻撃」と「逃げる」コマンドはMPを消費しない
・敵を全滅すれば勝ち、味方が全滅したら負け
・逃げるを選択することで、確立でバトルを強制終了できる
・ステータス異常は時間があれば！　できればやりたい！

まだ足りない気もしますが、増やしすぎても時間がないので一旦これで行きたいと思います。

#操作するキャラ

操作するキャラは３人とします。名前も決まってます。
名前が決まっているのは既にリリースされているIP素材というだけの話なので、プロトタイプ作りであるこの段階で詳しい設定は決めません。

・レイ（主人公）
・メイ
・ケイ

#キャラごとに特徴を出す

公式のカード説明文を参考に、大雑把にこういう感じにしていきたいと思います。

・レイ
魔術師タイプ
スキルの攻撃力、スキルに対する防御力が強い反面、攻撃力、防御力、素早さが低い
トラップを仕掛けて、敵が行動したらキャンセルしてダメージを与える
ステータス異常が実装できれば、そこそこ掛かりやすくする

トリッキーなタイプ

・メイ
攻撃値、防御値、素早さが一番高い反面、スキル攻撃に対する防御値が一番低い
スキルは攻撃値を元にした攻撃行動、もしくは各キャラに対してステータス「攻撃値、防御値、素早さ」をあげるもの
ステータス異常が実装できれば、とても掛かりやすくする

典型的な脳筋キャラ

・ケイ
魔術、体術が得意とカード説明文にあったので、スキルの攻撃力、スキルに対する防御力、攻撃力、防御力、素早さが平均的
スキルによる攻撃のほか、敵のステータスを下げたり、味方のHPを回復、ステータス異常が実装できればステータス異常回復も行う
ステータス異常が実装できれば、一番掛かりにくくする

僧侶タイプ

各キャラのスキル名は基本、オリジナルでのカードスキル名を借りる。
今の段階ではとりあえず１～２個のスキルだけ用意して、後で増やしていく。

#仕様、今後の実装方針を決めた

ひとまず仕様をこんな感じにして、実装していきたいと思います。
無事に作りきれるかはわかりませんが、せっかくなので頑張って完成させます
PowerBI DesktopにてODataデータソースのレポートを作成する

# はじめに

ODataとはHTTPベースのWebAPIとして動作する標準プロトコルです。GET/POST/PUT/DELETEといったWebAPI標準のHTTPリクエストでJSONまたはAtom形式のXMLデータをレスポンスとして返します。MicrosoftのPowerBIはデスクトップ版およびクラウド版があり、両版ともODataをデータソースとしてサポートしています。本記事では、PowerBIでODataをデータソースとして扱うための手順について説明します。

# 前提

ODataデータソースをホスティングする製品として、CData API Server( http://www.cdata.com/jp/apiserver/ )を利用しています。

# PowerBI DesktopにてODataデータソースのレポートを作成する手順

1. PowerBI Descktopのデータ取得にてODataフィードを選択します
![01.png](https://qiita-image-store.s3.amazonaws.com/0/123181/c8f50ef1-fa3a-3eb3-6622-a97dd5fa3ec9.png)

2. ODataエンドポイントを指定します
![02.png](https://qiita-image-store.s3.amazonaws.com/0/123181/9d1cb1ff-540d-2fd3-aefd-0bd7048a2b0e.png)
※テーブル一覧を取得できるルートのエンドポイントを指定可能です。

3. 認証情報を設定します
![03.png](https://qiita-image-store.s3.amazonaws.com/0/123181/936f49d4-b549-245d-6b05-5a13f96b6bdd.png)
※Basic認証の例

4. テーブル一覧がロードされるので、複数のテーブルを選択します
![04.png](https://qiita-image-store.s3.amazonaws.com/0/123181/203fed7e-be71-bfd9-3372-5b7bacecae7e.png)

5. リレーションシップを確認します
![05.png](https://qiita-image-store.s3.amazonaws.com/0/123181/d0a23d19-889f-2e2d-7689-3c15452ea6a7.png)
※同じ項目名だと自動で作成されます

6. テーブル間の結合したリストを作成します
![06.png](https://qiita-image-store.s3.amazonaws.com/0/123181/e5c2d8dc-b54a-951d-f781-948a529da7ed.png)
enebularの標準INFOMOTION Type（PieChart, ValueRangePieChart）の使い方

enebularのINFOMOTION Typeはプラグイン化されていて独自に拡張も可能ですが、まずは標準のINFOMOTION Typeの使い方を見ていきます。

## 初歩デモ準備

[enebular Advent Calendar 2016](http://qiita.com/advent-calendar/2016/enebular)初日の@satton_maroyakaのエントリ、[enebularをつかいはじめる](http://deferloader.blog.uhuru.co.jp/?p=6433)にある[スライド](http://www.slideshare.net/SatoruIshikawa1/enebular-infomotion)を見て準備すると以下のようになります。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/445a645f-6c80-b36f-510d-3a7b8a095a0e.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/a2aa2068-245e-9e05-cfc6-b457cc0f28aa.png)

今回は標準INFOMOTION TypeのPieChartとValueRangePieChart用にランダム発生データを少し変更します。Functionノードを開いて以下のように変更します。

```js
msg.payload = {
    id : "value" + Math.floor(Math.random() * 5),
    value : Math.floor(Math.random() * 100)
};
return msg;
```

## PieChart

INFOMOTIONのCreate Graphで以下のような設定でPieChartを作成します。

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/f033e909-3160-da84-7236-e7c583c42cd8.png)

これをLiveモードで開くと以下のようになります。

![infomotion.gif](https://qiita-image-store.s3.amazonaws.com/0/21109/8b909b8c-a558-85a9-5816-8f2a6c062bdc.gif)

## ValueRangePieChart

ValueRangePieChartとは送信されるデータの値を、例えば0〜20,20〜40,40〜60...のような範囲でカウントするためのINFOMOTION Typeです。

INFOMOTIONのCreate Graphで以下のような設定でValueRangePieChartを作成します。`divides`で分割する数を指定することで範囲が決まります（この例ですと`100`を`5`分割するので1つの範囲が`20`ということになります）

![image](https://qiita-image-store.s3.amazonaws.com/0/21109/37c20470-8d65-1db0-e8ca-961328802549.png)

これをLiveモードで開くと以下のようになります。

![infomotion.gif](https://qiita-image-store.s3.amazonaws.com/0/21109/bce6cad4-dd5d-c3aa-8bc4-ffcb46a8a231.gif)

## まとめ

INFOMOTIONはグラフの右上にある日付指定コントロールの抽出条件によって絞りこまれた時系列データを扱いますので、PieChartやValueRangePieChartは抽出期間のデータの割合を見るという用途に便利だと思います。
作業中のリポジトリの内容を異なるリポジトリに反映する手順

## はじめに

### この記事の趣旨
リポジトリAのブランチの内容をそのままリポジトリBに反映したい
しかも通常はリポジトリAを利用するのでデフォルトで使うものはそのままがいい
という状態があったときにどういう風にするかの意外とやり方がまとまってなかったのでメモです。

ぼやっとした例だとわかりづらい部分があるので
以下のシチュエーションを例として手順を説明します。

### 今回の想定
普段はクローズドな環境（例えばGithubEnterprise）にて
`HogeHoge` というリポジトリを使っているときに、同じ形で
公開用のオープンな環境（例えばGithub）のリポジトリに公開するというときの
作業内容です。SSHは以下のものを例として使います。

|対象gitの種別|SSH情報（ダミー）|
|:--|:---|
|クローズドな環境のgit|`git@github.ghe.jp:OreOre/HogeHoge.git`|
|オープンな環境のgit|`git@github.com:OreOre/HogeHoge.git`|
## やり方

### ベースとなるクローズドなリポジトリをcloneする

```bash
$ git clone git@github.ghe.jp:OreOre/HogeHoge.git
```

### 反映させたいオープンなリポジトリをリモートリポジトリに追加する

```bash
# 送り先のリモート名を「githubcom」で追加
$ git remote add githubcom git@github.com:OreOre/HogeHoge.git
# 追加されているか確認
$ git config --list
```

### 送りたいブランチをPush

```bash
# 送りたいブランチにいることを確認
$ git branch
# 念のためpull
$ git pull origin
# 送りたいリモートを第一引数にして送信
$ git push githubcom master
```

※master以外も移したい場合はブランチを指定して別途PushすればOK

### (おまけ)タグ情報も送りたい場合

```bash
# 現在のタグ情報を確認する
git tag
# 送信
git push githubcom --tags
```

## 参考URL

* [リモート操作 \| 逆引きGit \| サルでもわかるGit入門 〜バージョン管理を使いこなそう〜](http://www.backlog.jp/git-guide/reference/remote.html)
* [【Git】tag関連コマンド \- Qiita](http://qiita.com/chihiro/items/cba40015b1aa2c73b78a)

ちなみにリポジトリをまるごと引っ越したい場合は
この方法を行うのはいちいちブランチを移すのがめんどくさいので
以下の記事を参照のこと

[gitのリポジトリを移行する方法 \- \(ﾟ∀ﾟ\)o彡 sasata299's blog](http://blog.livedoor.jp/sasata299/archives/52050798.html)
GAのイベントトラッキングで"このページをApp Storeで開きますか？"というモーダルが出る

:::note warn
この記事はGoogle Analytics 4ではなく、Universal Analyticsを対象としています。
:::

![appstpre.png](https://qiita-image-store.s3.amazonaws.com/0/147689/32ba1652-1d73-96bf-9979-512abe72c401.png)


GAの[hitCallback](https://developers.google.com/analytics/devguides/collection/analyticsjs/sending-hits?hl=ja)を併用すると出る模様。

```js
ga('send', 'event', 'category', 'action', {
	hitCallback: function() {
		location.href = APPSTORE_URL
	}
});
```

とりあえずhitcallbackを使わず、setTimeoutで通常のイベント処理後に遅延(300ms)遷移することで回避。

```js
ga('send', 'event', 'category', 'action')
setTimeout(function(){
	location.href = APPSTORE_URL
},300)
```


リダイレクトを挟んで、イベント数とリダイレクトのカウント数を比較したところ2割程度の欠落が確認できた。(iOS)
以前hitcallback利用での欠落を調査した際も2割程度の欠落率だったので、300msでの遅延遷移でも問題はなさそう。
angular-cliプロジェクトにJavaScriptライブラリを組み込む方法

# 環境

このドキュメントでは次のバージョンのangular-cliで生成したプロジェクトについて記述しています。 

- angular-cli@1.0.0-beta.21


# 公式情報

- [3rd Party Library Installation](https://github.com/angular/angular-cli#user-content-3rd-party-library-installation)  
- [Global Library Installation](https://github.com/angular/angular-cli#global-library-installation)

Angular2用のサードパーティライブラリであれば、npm installで取得可能になっていたり、ライブラリのREADME等に説明があるため困ることはないでしょう。

また、有名どころのライブラリであればTypeScriptの型定義ファイルが[@types](https://www.npmjs.com/~types)に集約されているためこちらもnpm installしてimportして利用することができます。


# その他のJSライブラリの組み込み方法

npmに登録されていないし誰もTypeScriptの型定義の面倒を見てくれていない、何かの案件用のライブラリや昔からあるオレオレライブラリへの対応方法についてまとめます。

このドキュメントではそのようなライブラリの例として、hello.jsがあるとします。 
単純に関数1つにしておきます。

>     function Hello() {
>       console.log('hello !');
>     }

## ファイルの配置

プロジェクト内のどこかに置きます。 
このドキュメントでは `Project/src/js/hello.js` に置いてみます。

公式の[Global Library Installation](https://github.com/angular/angular-cli#global-library-installation)の通り、`angular-cli.json` に記述を追加します。

>     "scripts": [
>       "../src/js/hello.js"
>     ],

scriptsに記述を追加することで `ng build` や `ng serve` した時にAngularアプリにhello.jsが含まれるようになります。 


## ライブラリの呼び出し

hello.jsのHello関数を呼び出してみます。

>     import { Component } from '@angular/core';
>     
>     // 型定義は手抜き
>     declare var Hello: any;
>     
>     @Component({
>       selector: 'app-root',
>       templateUrl: './app.component.html',
>       styleUrls: ['./app.component.css']
>     })
>     export class AppComponent {
>       title = 'app works!';
>     
>       constructor() {
>         Hello(); // <- 呼び出せる
>       }
>     }


## ng test対応

`ng build` や `ng serve` では問題ないのですが、`ng test` では次のようなReferenceErrorが発生してしまいます。

> Failed: Error in :0:0 caused by: Hello is not defined
> ReferenceError: Hello is not defined

`ng test` のテスト中でもライブラリを利用するには `karma.conf.js` にも記述を追加する必要があるようです。

>     files: [
>       // test.tsよりも先に記述すること!!
>       { pattern: './src/js/hello.js', included: true, watched: false },
>       { pattern: './src/test.ts', watched: false }
>     ],

**※注意**
test.tsの次に追加してしまうと相変わらずReferenceErrorが発生してしまいます。test.tsの前に記述を追加しましょう。
synchronized のメモ

リファクタリングのためコードを見てたら
何回か見て忘れてしまったものが出たので忘れないようにメモしました。


## synchronized とは？
`synchronized`とは[排他制御](https://ja.wikipedia.org/wiki/%E6%8E%92%E4%BB%96%E5%88%B6%E5%BE%A1)のことで、

排他制御＝複数のプロセス（またはスレッド）が同時に入ることを防ぐことである

らしいです。

## 試してみる
言葉だけだとしっくり来なかったので
直接試してみました。

前提のイメージとして、
家族が一人ずつお風呂に入るイメージです。
（一人が終わるまで入ってはいけません。）

「メインメソッドのあるメインクラス」

```MainClass.java
public class MainClass {
    public static void main(String[] args) {
        Bathroom bathroom = new Bathroom();
        FamilyTread father = new FamilyTread(bathroom, "父");
        FamilyTread mother = new FamilyTread(bathroom, "母");
        FamilyTread sister = new FamilyTread(bathroom, "姉");
        FamilyTread me = new FamilyTread(bathroom, "私");

        father.start();
        mother.start();
        sister.start();
        me.start();
    }

}
```

「`Thread`を継承した家族に対するクラス」

```FamilyTread.java
class FamilyTread extends Thread {
    private Bathroom mBathroom;
    private String mName;

    FamilyTread(Bathroom bathroom, String name) {
        this.mBathroom = bathroom;
        this.mName = name;
    }

    public void run() {
        mBathroom.openDoor(mName);
    }

}
```

「家族クラスから呼ばれて作業をするクラス」

```
class Bathroom {
    void openDoor(String name) {
        System.out.println(name + "「お風呂に入ります！」");
        for (int count = 0; count < 100000; count++) {
            if (count == 1000) {
                System.out.println(name + "「お風呂に入りました。」");
            }
        }
        System.out.println(name + "「お風呂から出ました！」");
    }
}
```

##### 何回か実行した結果
![スクリーンショット 2016-12-12 17.17.56.png](https://qiita-image-store.s3.amazonaws.com/0/75978/b5777b7e-5ac6-d34d-e5c6-4539d7806381.png "スクリーンショット 2016-12-12 17.17.56.png")

父がまだお風呂に入ってるのに...！
順番がめちゃくちゃになってしまいました。（たまたま正しい順番になったりもします）

そこで`synchronized`を使うとお風呂(スレッド)に同時に入ることを防ぐことができると。

## synchronized を使ってみる

`Bathroom`クラスの `openDoor`メソッドに `synchronized`をつけてみました。

```
class Bathroom {
    synchronized void openDoor(String name) {
        System.out.println(name + "「お風呂に入ります！」");
        for (int count = 0; count < 100000; count++) {
            if (count == 1000) {
                System.out.println(name + "「お風呂に入りました。」");
            }
        }
        System.out.println(name + "「お風呂から出ました！」");
    }
}
```

##### 結果

![スクリーンショット 2016-12-12 17.30.31.png](https://qiita-image-store.s3.amazonaws.com/0/75978/da918ab8-3420-b89b-ff61-785cee5e5def.png "スクリーンショット 2016-12-12 17.30.31.png")

ちゃんとひとりづつ入るようになりました！

## 参照
http://www.techscore.com/tech/Java/JavaSE/Thread/3/
Android4.4系でReact-modalの表示位置がずれる

## 条件
- Android4.4系

## 現象
React-modalの表示位置がずれる

## 原因

https://www.npmjs.com/package/react-modal

Examplesの記述の`transform`はAndroid4.4系のブラウザではベンダープレフィックスが必要。
Autoprefixerを使っていたとしても、js内に直接記述して引き渡す場合にはAutoprefixerを経由しない。

```JavaScript
const customStyles = {
  content : {
    top                   : '50%',
    left                  : '50%',
    right                 : 'auto',
    bottom                : 'auto',
    marginRight           : '-50%',
    transform             : 'translate(-50%, -50%)'
  }
};
```

## 対応
cssファイルにて下記のclassにスタイルを適用させ、Autoprefixerを経由するようにする（推奨）

```css
.ReactModalPortal .ReactModal__Content {
    transform: translate(-50%,-50%);
}
```

または下記のように併記する。

```JavaScript
const customStyles = {
  content : {
    top                   : '50%',
    left                  : '50%',
    right                 : 'auto',
    bottom                : 'auto',
    marginRight           : '-50%',
    transform             : 'translate(-50%, -50%)',
    webkitTransform       : 'translate(-50%, -50%)'
  }
};
```

## 備考
js内に直接スタイルを記述する場合はベンダープレフィックスの有無に注意しましょう
通信ラグとの上手な付き合い方

※この記事は「[AltPlus Advent Calendar 2016](http://qiita.com/advent-calendar/2016/altplus)」の12日目の記事です。

2016年10月にオルトプラスに入社しましたtoshihiko-honmaです。
エンジニア出身で現在はマネージャーやってます。

ここ数年、スマホゲームでも複数人で同時に遊ぶ「マルチバトル」が増えてきていますよね。

そこで必要になるのがマルチ通信エンジンなのですが、巷にはクラウドサービスで利用できる非常に優れたエンジンがいくつか存在していて、今時フルスクラッチでゲームサーバーを開発する機会は殆どなくなったように思います。便利な世の中になりました。

とはいえ、マルチバトルを同期させるためのリアルタイム通信には落とし穴も多く、エンジンを利用してもハマってしまうポイントがいくつかあります。

ここでは、落とし穴の一つであるインターネット上の「通信ラグ」について書いてみようかと思います。

#代表的なプロトコル
リアルタイム同期式のゲームで使用される通信プロトコルとして代表的なものはTCP、UDP、RUDPの3種類ですが、それぞれに利点・欠点があります。

|              |TCP |UDP |RUDP|
|:-------------|:--:|:--:|:--:|
|再送制御      | 〇 | × | 〇 |
|順序制御      | 〇 | × | △ |
|フロー制御    | 〇 | × | 〇 |
|オーバーヘッド| × | 〇 | △ |
|NAT超え | 〇 | × | × |

TCPは相手に確実にパケットが届くけれどもオーバーヘッドが大きく処理が重くなります。
UDPは処理は軽いものの信頼性が低いため、再送処理が必要な場合は自前で実装する必要があります。
RUDPはTCPとUDPの良いとこ取りですが、正式規格になっていないため現状ではベンダーマターの実装が多いようです。

どのプロトコルを採用するかは、ゲームの特性によって変わってきます。

ターン制バトルで確実に全情報を同期する必要があればTCPを利用する、レースゲームのようにリアルタイム同期することが重視されるゲームであれば、移動情報が多少欠落してでも速度を重視してUDPを利用する、という具合です。

#通信の理想形
4人対戦のマルチバトルゲームを例にすると「Aさんが攻撃を行った瞬間にB～Dさんに行動が通知されて、全員同時に同じ画面が表示されること」が理想です。

理想を実現するためには、通信遅延やパケットロスが一切発生しない通信環境が必要ですが、インターネットでは現実的ではありません。

![image](https://qiita-image-store.s3.amazonaws.com/0/147786/2a8bca71-bedc-daa9-f547-4d275700f1b3.png "夢のような通信環境")

#実際のところ
光の速さで通信したとしても秒速30万キロメートルでしか情報は進みません。そのため、通信経路の物理的距離が長くなれば、それだけで遅延は増大します。

経路上で経由するルーターが増えれば処理遅延も加算されますし、途中の通信帯域が細ければ通信速度が制限されます。LTEなどの移動体通信であれば、ハンドオーバー（基地局の切り替え）による遅延やバーストも無視できません。

加えて、機器やケーブルの物理的な障害やソフトウェアの不具合などで、パケットがロストすることもありえます。

![image](https://qiita-image-store.s3.amazonaws.com/0/147786/7cc42519-98c2-a429-78fe-768f356cfc7d.png "世知辛い通信環境")

#どうすればよいのか？
乱暴に言ってしまうと、インターネットの通信ラグを完全に防ぐことは不可能です。通信経路上の出来事は制御できませんので、あきらめるしかありません。

かといって、何も気にしないわけにもいかないので、できる限りの対処療法を仕込むことになります。いくつかポイントを列挙してみます。

* 目的に合わせた適切なプロトコルを選択する
* パケットサイズや通信回数を効率化して回線負荷を下げる
* ラグやパケットロスが発生した場合であっても安全サイドに倒れこむ実装にする
* アプリケーション遅延を最小化できるよう、効率の良いコードを書く

当たり前のことばかりですが、「ラグが必ず発生すること」を意識しておかないと意外とハマってしまいます。

#ゲームデザインへのフィードバック
エンジニアとしてできることがもう一つあります。

「リアルタイムバトルなんて企画するの初めてです～」なんてプランナーを見かけたら、**「ラグってのはゼロになんねぇんだよ！！」** と言い続けましょう。これが**超大事**だったりします。

ラグを考慮せずにゲームデザインを決めてしまうと、社内テスト時は(LAN環境だったから)動いていたのに、運用環境に持っていったらラグってゲームにならなかった、なんてことになりがちです。

ゲームデザインレベルでラグを考慮することで、通信開始時にエフェクトを入れて時間猶予を設けたり、移動仕様を単純化して数フレーム先の位置情報補完を実現しやすくしたり、結果としてユーザーに**「ラグを感じさせない見せ方」**を提供することができるかもしれません。

よりよいゲームを開発するためにも、企画と技術の協力関係は重要です。

#最後に
私は前職もゲーム開発会社でして、7年間、時代の変遷とともに「ガラケーの通信対戦アプリ」「Webソシャゲ」「スマホのマルチ対戦アプリ」など色々なタイトル開発に関わる機会がありました。その前の12年間はSI企業に勤めていて、社会インフラの通信制御システム開発でバイナリの通信ログを眺めて暮らす日々を送っていました。

そう考えると「なんかしら通信するもの」を作り続けてもう20年くらいになります。自他ともに認めるおっさんです。最近では自分で実装する機会はすっかり減ってしまいましたが、おっさんなりの過去のノウハウが誰かの何かに役立てば嬉しいな、と思っています。

ここまで読んでいただき、ありがとうございます。

#参考URL
ネットワークゲームについて非常にわかりやすく解説されています。おすすめ。
[[CEDEC 2010]ネットゲームの裏で何が起こっているのか。ネットワークエンジニアから見た，ゲームデザインの大原則](http://www.4gamer.net/games/105/G010549/20100905002/)