マッチングサーバーの仕事の大部分はフレームワークがやってくれる。
モジュールで実装する必要があるのは、ゲーム準備リクエスト(ReadyGameRequest) とゲーム案内通知(GuideGameNotify) をカスタマイズすることだけである。
void SampleRoomModule::setupReadyGameRequest(Room* _pRoom, ReadyGameRequest* pReq)
{
}
void SampleRoomModule::setupGuideGameNotify(Room* _pRoom, int memberIndex, GuideGameNotify* pMsg)
{
}
サンプルではカスタマイズしていない。
ゲームサーバーでは ReadyGameRequest を受け取って処理する必要がある。
class ReadyGameRequest: public ExtMessage< 0xD2, ReadyGameRequest >
{
uint16_t domainIndex;
uint16_t matchIndex;
uint16_t tagRoomId;
std::vector< MemberInfoIon* > members;
};
class MemberInfoIon: public ExtIon
{
std::string userId;
std::string secret;
};
void GameServer::handleReadyGameRequest(ReadyGameRequest* pMsg)
{
ResponseMessage res(pMsg);
uint8_t err;
printf("<< ReadyGameRequest\n");
res.setDomainIndex(pMsg->domainIndex);
ReadyGameResponse::SetTagRoomId(&res, pMsg->tagRoomId);
if (! checkMatchId(pMsg->domainIndex, pMsg->matchIndex)) {
err = ResponseMessage::ERR_BADPARAM;
goto fail;
}
{
Game* pGame = &m_vecGame[pMsg->domainIndex];
Match* pMatch = &pGame->vecMatch[pMsg->matchIndex];
if (! pMatch->open(pMsg)) {
goto fail;
}
}
goto fin;
fail:
res.setResult((err != 0)? err: ResponseMessage::ERR_UNKNOWN);
fin:
post(m_matchCommId, &res);
printf(">> ReadyGameResponse: %d\n", res.getResult());
}
ResponseMessage に、先ほど説明した tagRoomId を拡張データとして付加していることに注意。
後は ReadyGameRequest の情報に従って、ゲーム場(Match) をセットアップしている。
ゲームサーバーの準備が終わった後で、各クライアントに GuideGameNotify が投げられる。 ゲームクライアントはこの情報を元にゲームサーバーへ接続し、ゲームを開始する。
どうゲームを始めるかはゲームサーバーの仕様範囲であり、マッチングフレームワークは何も強制しない。ただ、利便のために LoginGameRequest というメッセージを提供している。
サンプルでは、ゲームクライアントはこのメッセージを利用してゲームサーバーへのログインを行っている。
void MainDialog::handleGuideGameNotify(GuideGameNotify* pMsg)
{
m_msgLoginGameRequest.userId = m_userId;
m_msgLoginGameRequest.secret = pMsg->secret;
m_msgLoginGameRequest.tagDomain = pMsg->tagDomain;
m_msgLoginGameRequest.tagMatch = pMsg->tagMatch;
m_nine.connectGameLater(pMsg->host.c_str(), pMsg->port);
}
void MainDialog::onGameConnect(bool succeed)
{
postGame(&m_msgLoginGameRequest);
}
GuideGameNotify に含まれている、シークレット情報とタグ情報をそのまま LoginGameRequest へコピーする。実際にこのメッセージを送信するのは、ゲームサーバーへ接続した後である。
ゲームサーバーのアドレスは GuideGameNotify に含まれている。この情報を使って接続を行う。