Project MMOの最近のブログ記事

 ゲームの調子がおかしい時やビデオカードドライバを変えたときに確認しますが、結構開発でもテスト段階の情報収集には役に立つかも。

 起動方法はスタートメニューのファイル名を指定からdxdiagと入力して起動する方法と[スタート]→[プログラム]→[アクセサリ]→[システム ツール]で[システム情報]を起動してから[ツール]→[DirectX診断ツール]を選択する方法があります。

 起動されたDirectX診断ツールのシステムタブに[情報をすべて保存]というボタンがありこれでDirectXの状態をテキストファイルに書き出すことができ、ドライバを入れ替えたときの挙動の違いの原因解析に使います。

書籍の追加

| コメント(0) このエントリーを含むはてなブックマーク

 今週はゲーム開発関連書籍を三冊追加。プログラミングは相変わらず時間が取れなくて全く組めていない。時間と余剰金の合計の絶対量が少ないと苦労するなぁ…。個人プロジェクトはゲーム開発がメインなので新規で仕事の依頼が来てもお断り中(^^;

 昨日のDDOS攻撃の関連で調べていたら、IPアドレス別でアクセス可能な地域を制限する方法があった。方法自体はIPフィルタリングだが、どのIPがどの国で使用されてるかが情報公開されていたのでそれを利用できそうです。

 メールは基本的に全世界からアクセスされるものなので国別での接続制限というのもあまり意味がないのですが、ゲームサーバに関しては負荷の集中を避けるためと、営業範囲外のアクセスを遮断する場合があります。(国別に運営会社が決まっているとかですね)

まず、国別IPの情報はここから取得できます。
http://ftp.apnic.net/stats/

さらに一網打尽を使うと整理しやすくなります。
http://www.vector.co.jp/soft/winnt/net/se316799.html

あとは前段にFWを設けてログなし破棄をすれば十分でしょう。

 fedoraを入れてからは初めてなのでまずは動作可能かどうか調査。
FLASHでオンラインゲームを行う分には問題ないことは確認できましたが、自作のFLASHクライアントが超古いのしかなくサーバとのメッセージプロトコルが違うため全くチャットができなかった。確かFLASHクライアント側はSJISにしていたのですがこれがUNIX系に対応できるかどうかも関係ありますね。だめならUTF-8に統一。あとはFLASHのセキュリティがありえないほど面倒。サイトに載せた場合は大丈夫なんだろうけど…。

事業化を検討中

| コメント(0) このエントリーを含むはてなブックマーク

 昨年分から雑所得が確定申告対象になってしまい、今年はさらに延びそうな状態になってしまいました。といっても特に大きな経費が発生しているわけでもないし不定期な仕事ではまぁ事業として見るのは変な気がします。

 でも、今年からデータセンターに占有サーバを借りてレンタル費で赤字が出ないように切り売りしつつゲームサーバの公開環境のの構築を始めようと思っています。ただこの場合フリーターの雑収入扱いでは、顧客がいない期間やサーバ本体の購入費は経費に落ちない予感…。そもそもバイト程度な収入では届出を受理してくれないというウワサもありますね。

 専用サーバなんて1台年間30万円は掛かるし、経費にならないと非常に苦しくなるので、サーバーレンタル事業として個人事業の開業申請をしようと準備しています。

早速、会計を楽にする為別途取引口座を準備したり体裁の為の各印を用意したりしていますが届出内容で気になる点がいくつか。

職業:
これはこれから始める業種を書くのか?それとも現在の身分を書くのか?

青色申告の有無:
既に株取引や雑収入課税対象で青色申告だが、ここでも再度申請が必要?来年に2通やってきてそれぞれ書いてとかだったら凹む。
2007/03/16追記:私が無知でした。毎年出してた確定申告は白色でした。orz

給与:
誰も雇う必要がないのでここは0人でいいのだろうか・・・?

思ったのが届出の書類って全部で数枚しかないのね…。もっといろいろ書いて印紙貼って登録だの調査だの事務所の見取り図だのいろいろあるかと思ったけど見たらない…。これって業種によって違うのかなー?

因みにサーバレンタル業の場合は電気通信業らしい。実際に回線やハードウェアは直接触らないから実感沸かないのですが…。

負荷分散計画

| コメント(0) | トラックバック(0) このエントリーを含むはてなブックマーク

 まだ2台目を構築完了していないのに気が早いのですが、2台をLANで接続する理由はもちろん負荷分散の為です。予定としては、

1.サーバー構築
 ⇒ネットワークカードの追加
 ⇒ファイアーウォールの設定(LAN通信分)

2.Webの負荷分散
 ⇒Apache2.2によるロードバランシング
 ⇒バックプロキシーによる静的ページとCGIの分離

3.MySQLの負荷分散
 ⇒レプリケーション構成の作成

4.PostgreSQLの負荷分散
 ⇒どんな方法があるか検討中

5.ゲームサーバの複数台構成
 ⇒プロセス間通信からサーバ間通信の実現

まぁこんなところです。勉強することは一杯ありますねぇ。

 最近WinCVSについて有名なごった煮版を探していたら以前公開されていたURLにアクセスできなくなっていた。更新停止から長い期間が経った事と今はEclipseから利用するのが多いようなのでWinCVSは流行ってないのかな。仕事上Eclipse使うハメになっているのでどうせならCVSクライアントして使おう。

 また接続方式はpserverではなくssh。CVSだけのためにinetdを有効にするのが勿体無いというのもありますが、ファイル転送をscpに限定している為pserverで構築する意味が無いのでsshで接続することにしました。

◆CVSの初期化(Server上)
自分用リポジトリ作成(例:user1ユーザ)
> mkdir ~/cvs
> cvs -d /home/user1/cvs/ init

/home/user1/cvs/にCVSROOTディレクトリが生成され、その下にいくつかの設定ファイルが生成されます。

> ls
Emptydir config editinfo,v modules,v taginfo
checkoutlist config,v history notify taginfo,v
checkoutlist,v cvswrappers loginfo notify,v val-tags
commitinfo cvswrappers,v loginfo,v rcsinfo verifymsg
commitinfo,v editinfo modules rcsinfo,v verifymsg,v


ソースのインポート(Server上)
> pwd
/home/user1/project-mmo
> ls
client server
> cvs -d /home/user1/cvs/ import ProjectMMO PJMMO PJMMO_1_0

コメントを入力

Project MMO Development
CVS: ----------------------------------------------------------------------
CVS: Enter Log. Lines beginning with `CVS:' are removed automatically
CVS:
CVS: ----------------------------------------------------------------------

/tmp/cvszL0n4K: 5 lines, 253 characters
[中略]
No conflicts created by this import


◆Eclipse(CVSクライアント)から利用

Eclipse [ウィンドウ]-[パースペクティブを開く]-[その他]で
CVSリポジトリー・エクスプローラーを選択して[OK]

CVSリポジトリーの追加ボタンをクリック
接続タイプにextsshを指定

SSH2メッセージに[はい]

これだけで接続完了。

特にMMO制作ではC++言語とバイナリ素材がメインになるのでEclipseはCVSクライアントとして利用します。

サーバー上に出来上がったファイルを見るとどれも差分ファイルの塊だったので公開用はWinSCPでローカルから送信。
別にサーバー上でコマンド使って生成してもいいのですが公開ディレクトリはCVSと絡みたくないのでローカルからコピーします。

他のプロジェクトで共同開発を行う事も多いのでEclipse+CVSを薦めてみよう。

参考書籍:CVS/WinCVSハンドブック
CVSで買った2冊目の書籍ですが、これは非常に分かりやすいです。ググって中途半端な情報を組み合わせて構築するよりずっと楽でした。(というかsshだと構築不要なんですね)

ソケットの数のOS上限

| コメント(0) このエントリーを含むはてなブックマーク

 オンラインゲームを作るに当たり全く考えてなかった問題があった。OSレベルでのファイルオープン数制限である。ソケットもOSレベルではファイルポインタとして扱われている為この制限にかかる。

C言語のプログラミングレベルであればFD_SETSIZEの定義を変えれば良いがそれだけではOSの制限は超えられない。調査方法は下記のコマンドを実行する。

Linuxの場合
# ulimit -a

この結果Linux系はデフォルトが1プロセス当たり1024個までのようだ。
これは少なすぎなのでRedHat系であれば/etc/security/limits.confに上限値を
入れてリログすると適用されるっぽい。

FreeBSDの場合
# limit
cputime unlimited
filesize unlimited
datasize 524288 kbytes
stacksize 65536 kbytes
coredumpsize unlimited
memoryuse unlimited
vmemoryuse unlimited
descriptors 7264
memorylocked unlimited
maxproc 3632
sbsize unlimited

FreeBSDは7264が上限になってた、これだけあれば大丈夫かな。

そしてFreeBSDの場合は

 なんとかインストールできました。この前失敗したのはDebugServiceを無効にしていたためVC上でデバッグするとエラーが発生。これを自動起動にした後、もう一度展開済みパッケージをインストールしたら成功。変なexeじゃなくて普通にzip圧縮してくれればメモリ1GBないPCでもインストールできるのに…。
 Sampleの実行は殆ど全滅状態。ビデオカードがDirectX9に対応していない場合とそもそもGPU積んでないPCはまるでダメですね。

Core吐かせてみよう

| コメント(0) このエントリーを含むはてなブックマーク

 今日はトンデモな実験。というかここ数年Core吐かせてないのでデバッグ用にわざと吐かせてみた。

#include
int main(){
int i=0;int j=1;int k=0;
printf("i=%d,j=%d\n",i,j);
k=j/i;
printf("k=%d\n",k);
return 0;
}

コンパイル
> gcc -o fault fault.c

実行
> ./fault
i=0,j=1
Floating exception (core dumped)

まぁ酷いプログラムです。
実行すればたちまち0除算が原因でcoreを吐きます。
今までWindowsも含めてコアダンプを利用した解析なぞやったこと無かったので、バイナリエディタで開く…。全く読めない。そこで調べていたらgdbコマンドを使えば直ぐにわかるという。これがあれば解析のためにガリガリファイルにログを書き出さなくていいかもです。

まずは試しに実行。(実行ファイル名はfaultでコアダンプはfault.coreです)

> gdb fault fault.core
#0 0x0804854e in main ()

main関数でダウンしたことがわかります。

今度はデバッグモードでコンパイル(特に再実行してコアを更新する必要はなさそうです)
> gcc -g -o fault fault.c
> gdb fault fault.core
#0 0x0804854e in main () at fault.c:8
8 k=j/i;

なるほど、fault.cの8行目で停止したことがわかります。

 以前はプログラムの起動時にPIDを入れた一時ファイルを作成する方法をとっていましたが、その方法が通用するのは正常起動・終了が前提で起動監視としては機能不足です。
 時々チャットサーバーが落ちていることがあるため(まったく原因が不明)起動監視&アラート送信を行います。その時にプロセス監視を行うためにpgrepを使用しますが、下記の項目に気をつけないとイタイ目にあいます。

Q1. デフォルトではプロセス名が部分一致なので予期しないプロセスがマッチする。
A1. xオプションをつけて完全一致にさせる

Q2. 同じプロセスが存在する。
A2. uまたはUオプションでユーザーを指定するかfオプションでディレクトリも確認する。それでも複数ヒットする場合は…。(a.outとか安易にマッチしそうな名前にしないこと?)

Q3. プロセス名が長いとマッチしない
A3. OSによるがfオプション無しの場合一定文字列長でプロセス名が切り捨てられる。fオプションをつけるか、lオプションでマッチしたプロセス名を確認する。

以上の注意よりコマンドでは下記のように検査する。

# pgrep -f -x -U username ./socket_server
10042

プロセスが生きていればこのようにPIDが出てきて(複数だと複数行に)生きてなければ空を返します。
これを利用してcrontabで監視する場合はこちら

#!/bin/sh
TARGET=socket_server
cd $TARGETDIR
ret=`pgrep -f -x -U $USER ./$TARGET`
if [ -z $ret ]; then
echo 'SERVER IS DEAD' | mail -s 'NOTIFY' info@test.net
./serverctrl.sh start
fi

crontabを利用せず、バックグランドで見張る場合はsleepで永久ループ。ただしこれ自身が落ちたら意味ない。

#!/bin/sh
INTERVAL=15
TARGET=socket_server
cd $TARGETDIR
while true; do
ret=`pgrep -f -x -U $USER ./$TARGET`
if [ -z $ret ]; then
echo 'SERVER IS DEAD' | mail -s 'NOTIFY' info@test.net
./serverctrl.sh start
fi
sleep $INTERVAL
done

プロセスは生きているけどフリーズしているとかはまた別の方法で検査します。

 万が一、プロセスが停止したときも考えてシェルからメールを送ってみたい。
今のところ確認した方法はmailコマンドを利用したもの。

本文もコマンドに書く場合
echo '本文' | mail -s 'タイトル' <メールアドレス>

テキストファイルを本文にする場合
cat <ファイル名> | mail -s 'タイトル' <メールアドレス>

ファイルを添付(この方法は自宅FreeBSDにunencodeコマンドが無かったので未実証)
unencode <ファイルパス/ファイル名> <添付ファイル名> | mail -s 'タイトル' <メールアドレス>

これでサーバーからのアラートメールを受け取れます。

Selectからマルチスレッドへ

| コメント(0) このエントリーを含むはてなブックマーク

 そろそろ、根本的な構造の組みなおしが必要になってきたのでまずはマルチスレッドからはじめたいかなっと。FreBSDなので下記のサイトも参考に複数の種類でやってみたいとおもいます。尚これからはUNIXオンリーなプログラミングになるのでWindows系のコードは外していくかも。

ネットワークプログラミングの基礎知識
http://x68000.q-e-d.net/~68user/net/

そのあとにC++化してログインしたプレイヤー情報をオブジェクトで管理しDB接続を行いたいと思います。

 FLASHでIME使用中でもエンターキーを取得してしまう問題は、イベント取得の方法をKey.ENTERからKey.getCode()==13に変えることで解決してしまった。微妙な定義の差なのだろうか…。

//if (Key.isDown(Key.ENTER) == true) {
if (Key.getCode() == 13) {

去年と同じところまでは復帰しました。部屋はありませんがチャットシステムです。去年と違うところはサーバーがPerlからC言語になったところとFLASHクライアントがMXから8になったところです。

まだ、現在のバージョンでもキーイベントにバグがありこれから対処します。
FLASHでIME使用中にEnterキーを押したとき普通はIMEでの決定キーなのですがFLASHもイベントを取得してしまう…。これをどうにか外せないものかと…。

次に、プロトコル(TCPとかじゃなくてゲームサーバー開発で一般的に言われているゲームコマンド仕様)の概念を取り入れて処理分けを行います。そしてアバターを搭載してアバターチャットに。クライアント側は全然大丈夫ですが、サーバー側は自作XMLパーサが必要。


左上:クライアント1(FLASH)
左下:クライアント2(FLASH)
右上:サーバー(FreeBSD)
右下:クライアント(telnetでダミートレース)

この前からFLASHクライアントが使えない状態だったのでteratermでサーバー側、telnetでクライアントをトレースしてみたら特に問題なかった。終端文字が改行じゃなくてNULLだからちょっとややこしいな…。

お役立ちリンク

| コメント(0) このエントリーを含むはてなブックマーク

昨年参考にしたサイトです。
一部移転されたみたいなので再掲載。

http://www.geekpage.jp/programming/linux-network/index.php

http://www.geekpage.jp/programming/winsock/

http://www.ncad.co.jp/~komata/c-kouza9.htm

FLASHのアクセス権

| コメント(0) このエントリーを含むはてなブックマーク

 今、ソケット通信を行うFLASHクライアントのデバッグ中ですが、最近はネットへのアクセス制限を考慮するひつようがでてきた。IE内で使用する場合や実行ファイルとして書き出した場合は問題ないがswfのままローカルで再生するとネットにアクセスできなかったりします。swfそのものを配布するときは注意が必要です。FLASHを設置したサーバーとソケット通信のサーバーが別だとまたややこしいことにならないかなぁ…。

 昨日のダメっぷりはもしかしてFLASHプレイヤーのバージョンに関係するのかも?と疑いもありますがどちらにしろ未完成なので新バージョンで作り直しをする事にしました。AS2になるとソケット周りは使いやすくなっているか情報を集めてみます。

送信データの末端処理

| コメント(0) このエントリーを含むはてなブックマーク

 今日はC言語版サーバーとFLASH版クライアントを接続してみた。
というものの当初はプロトタイプとしてサーバーをPerlで組んでクライアントをFLASHにしていましたが、そのPerl版をC言語に移植してからはtenetハックのみでまだFLASHクライアントからの接続をしていませんでした。

 というわけで接続してみましたが…。去年作成したFLASHなので何か処理がまずかったのか終端文字をサーバー側で認識できない。結局ログアウトして初めてサーバーが転送処理を開始し同報するのだが、相手側に伝わらない。

 何が問題なんだろう…。

アーカイブ