node.js 개발 (3-3)
2013년 9월 4일 수요일
Server 구현 (2)
User와 Lobby
소스
user.js
/**
* server/user.js
* 사용자
*/
// module
var util = require('util')
// include
var proto = require('../common/protocol')
var InitStage = require('./stage').InitStage
var LoginStage = require('./stage').LoginStage
var LobbyStage = require('./stage').LobbyStage
var User = function (world, conn) {
this.conn = conn
this.world = world
this.lobby = world.lobby
this.logined = false
this.name = ''
this.id = ''
this.point = 0
this.stageList = []
this.stage = new InitStage(this)
}
User.prototype = {
light: function () {
var user = {
id: this.id,
logined: this.logined,
name: this.name,
nickname: this.nickname,
}
return user
},
end: function () {
this.conn.close()
},
leaveWorld: function () {
if (this.room) this.room.leave(this)
this.lobby.leave(this)
this.world.leave(this)
console.log('bye bye~')
},
nextStage: function (stage) {
this.stageList.push(this.stage)
this.stage = stage
this.stage.start()
},
rollbackStage: function () {
if (this.stageList) {
this.stage = this.stageList.pop()
}
},
send: function (header, data) {
console.log('send:', header, data)
if (!header) {
console.log('wrong header')
return
}
if (!this.conn) {
console.log('closed socket')
return
}
if (typeof data == 'object') {
if (!Buffer.isBuffer(data)) {
data = JSON.stringify(data)
}
}
this.conn.send(header, data)
},
goLogin: function () {
this.nextStage(new LoginStage(this))
return true
},
goLobby: function () {
this.nextStage(new LobbyStage(this))
var err = this.lobby.enter(this)
if (err) this.rollbackStage()
return err
},
// connection
onPacket: function (header, data) {
//console.log('User:parsePacket', data);
console.log('stage-name:' + this.stage.name)
this.stage.clientLink(header, data)
},
onPacketError: function (err) {
console.log('packet_error:', err)
this.conn.close(proto.PK_CRITICALERROR)
this.conn.pause()
},
onError: function (err) {
console.log('socket error:', err)
if (err.code != 'ECONNRESET') {
this.conn.close(proto.PK_CRITICALERROR)
}
this.conn.pause()
},
onClose: function () {
console.log('socket closed')
this.conn = null
this.leaveWorld()
},
}
module.exports = User
lobby.js
/**
* lobby.js
* 로비
*/
// module
var util = require('util')
// include
var proto = require('../common/protocol')
var PokerRoom = require('./poker_room')
var Lobby = function (world) {
this.world = world
this.users = []
for (i = 0; i < this.world.option.maxRoom; i++) {
this.freeRoomNo.push(i + 1)
}
}
util._extend(Lobby.prototype, {
broadcast: function (method, without) {
this.users.forEach(function (other) {
if (!without || other != without) {
method(other)
}
})
},
enter: function (user) {
if (this.world.option.maxUser <= this.users.length) {
return '현재 서버가 모두 찻습니다.'
}
this.users.push(user)
return null
},
leave: function (user) {
var index = this.users.indexOf(user)
this.users.splice(index, 1)
return null
},
chat: function (user, message) {
this.broadcast(function (other) {
other.stage.sendChat(user, message)
}, user)
},
})
module.exports = Lobby