node.js 개발 (3-3)

By | 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;

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다