1.首先进入房间有四种途径
a.进入大厅界面的时候查看是个有oldRoomId,如果有直接进入对应房间
b.大厅界面update方法里看是否有cc.vv.userMgr.roomData,如果有直接进入对应房间
c.根据房间号输入对应房间的时候,如果正确,则进入房间
d.用户断线重连的时候,如果房间号存在,则直接进入房间
2.接下来就是进入房间实际操作
enterRoom:function(roomId,callback){
var self = this;
var onEnter = function(ret){
if(ret.errcode !== 0){
if(ret.errcode == -1){
setTimeout(function(){
self.enterRoom(roomId,callback);
},5000);
}
else{
cc.vv.wc.hide();
if(callback != null){
callback(ret);
}
}
}
else{
cc.vv.wc.hide();
if(callback != null){
callback(ret);
}
cc.vv.gameNetMgr.connectGameServer(ret);
}
};
var data = {
account:cc.vv.userMgr.account,
sign:cc.vv.userMgr.sign,
roomid:roomId
};
cc.vv.wc.show("正在进入房间 " + roomId);
cc.vv.http.sendRequest("/enter_private_room",data,onEnter);
},
跳转到client_server的对应方法处
app.get('/enter_private_room',function(req,res){
var data = req.query;
var roomId = data.roomid;
if(roomId == null){
http.send(res,-1,"parameters don't match api requirements.");
return;
}
if(!check_account(req,res)){
return;
}
var account = data.account;
db.get_user_data(account,function(data){
if(data == null){
http.send(res,-1,"system error");
return;
}
var userId = data.userid;
var name = data.name;
//验证玩家状态
//todo
//进入房间
room_service.enterRoom(userId,name,roomId,function(errcode,enterInfo){
if(enterInfo){
var ret = {
roomid:roomId,
ip:enterInfo.ip,
port:enterInfo.port,
token:enterInfo.token,
time:Date.now()
};
ret.sign = crypto.md5(roomId + ret.token + ret.time + config.ROOM_PRI_KEY);
http.send(res,0,"ok",ret);
}
else{
http.send(res,errcode,"enter room failed.");
}
});
});
});
第一步验证账号,接着获取用户uid和昵称,执行room_server的enterRoom方法
exports.enterRoom = function(userId,name,roomId,fnCallback){
var reqdata = {
userid:userId,
name:name,
roomid:roomId
};
reqdata.sign = crypto.md5(userId + name + roomId + config.ROOM_PRI_KEY);
var checkRoomIsRuning = function(serverinfo,roomId,callback){
var sign = crypto.md5(roomId + config.ROOM_PRI_KEY);
http.get(serverinfo.ip,serverinfo.httpPort,"/is_room_runing",{roomid:roomId,sign:sign},function(ret,data){
if(ret){
if(data.errcode == 0 && data.runing == true){
callback(true);
}
else{
callback(false);
}
}
else{
callback(false);
}
});
}
var enterRoomReq = function(serverinfo){
http.get(serverinfo.ip,serverinfo.httpPort,"/enter_room",reqdata,function(ret,data){
console.log(data);
if(ret){
if(data.errcode == 0){
db.set_room_id_of_user(userId,roomId,function(ret){
fnCallback(0,{
ip:serverinfo.clientip,
port:serverinfo.clientport,
token:data.token
});
});
}
else{
console.log(data.errmsg);
fnCallback(data.errcode,null);
}
}
else{
fnCallback(-1,null);
}
});
};
var chooseServerAndEnter = function(serverinfo){
serverinfo = chooseServer();
if(serverinfo != null){
enterRoomReq(serverinfo);
}
else{
fnCallback(-1,null);
}
}
db.get_room_addr(roomId,function(ret,ip,port){
if(ret){
var id = ip + ":" + port;
var serverinfo = serverMap[id];
if(serverinfo != null){
checkRoomIsRuning(serverinfo,roomId,function(isRuning){
if(isRuning){
enterRoomReq(serverinfo);
}
else{
chooseServerAndEnter(serverinfo);
}
});
}
else{
chooseServerAndEnter(serverinfo);
}
}
else{
fnCallback(-2,null);
}
});
};
这儿首先根据房间号查询了房间信息,包括对应的游戏服务器ip和端口,如果服务器存在,查看房间是否正在运行,如果在运行,执行进入房间的请求,否则,选择一个合适的服务器,然后执行进入房间请求
时间进入房间的操作在游戏服务器的http_server里面
app.get('/enter_room',function(req,res){
var userId = parseInt(req.query.userid);
var name = req.query.name;
var roomId = req.query.roomid;
var sign = req.query.sign;
if(userId == null || roomId == null || sign == null){
http.send(res,1,"invalid parameters");
return;
}
var md5 = crypto.md5(userId + name + roomId + config.ROOM_PRI_KEY);
console.log(req.query);
console.log(md5);
if(md5 != sign){
http.send(res,2,"sign check failed.");
return;
}
//安排玩家坐下
roomMgr.enterRoom(roomId,userId,name,function(ret){
if(ret != 0){
if(ret == 1){
http.send(res,4,"room is full.");
}
else if(ret == 2){
http.send(res,3,"can't find room.");
}
return;
}
var token = tokenMgr.createToken(userId,5000);
http.send(res,0,"ok",{token:token});
});
});
老一套的参数检查,最后调用roomMgr.enterRoom操作数据库
exports.enterRoom = function(roomId,userId,userName,callback){
var fnTakeSeat = function(room){
if(exports.getUserRoom(userId) == roomId){
//已存在
return 0;
}
for(var i = 0; i < 4; ++i){
var seat = room.seats[i];
if(seat.userId <= 0){
seat.userId = userId;
seat.name = userName;
userLocation[userId] = {
roomId:roomId,
seatIndex:i
};
//console.log(userLocation[userId]);
db.update_seat_info(roomId,i,seat.userId,"",seat.name);
//正常
return 0;
}
}
//房间已满
return 1;
}
var room = rooms[roomId];
if(room){
var ret = fnTakeSeat(room);
callback(ret);
}
else{
db.get_room_data(roomId,function(dbdata){
if(dbdata == null){
//找不到房间
callback(2);
}
else{
//construct room.
room = constructRoomFromDb(dbdata);
//
var ret = fnTakeSeat(room);
callback(ret);
}
});
}
};
首先查看房间是否存在,如果存在,则takeSeat,否则,根据房间号查找数据库 ,然后根据数据库信息创建房间,增加房间数等
下面看看takeSeat的逻辑
var fnTakeSeat = function(room){
if(exports.getUserRoom(userId) == roomId){
//已存在
return 0;
}
for(var i = 0; i < 4; ++i){
var seat = room.seats[i];
if(seat.userId <= 0){
seat.userId = userId;
seat.name = userName;
userLocation[userId] = {
roomId:roomId,
seatIndex:i
};
//console.log(userLocation[userId]);
db.update_seat_info(roomId,i,seat.userId,"",seat.name);
//正常
return 0;
}
}
//房间已满
return 1;
}
如果房间存在,则返回
,然后遍历四个座位,如果某一座位为空,则更新数据库信息,然后返回,否则,就是房间满了