var express = require('express'); var app = express(); var server = require('http').Server(app); var io = require('socket.io').listen(server); var GameServer = require('./GameServer'); app.use('/css', express.static(__dirname + '/css')); app.use('/js', express.static(__dirname + '/js')); app.use('/assets', express.static(__dirname + '/assets')); app.get('/', function(req, res) { res.sendFile(__dirname + '/index.html'); }); // http 기본 포트(80)에 서버 열기 server.listen(8080, function() { console.log(new Date().toLocaleTimeString('ko-KR') + ' [SERVER] Listening on port ' + server.address().port); GameServer.serverNumber = Math.floor(Math.random() * 1000 + 1); console.log(new Date().toLocaleTimeString('ko-KR') + ' [SERVER] server number is ' + GameServer.serverNumber); }); // 클라이언트 요청에 대한 콜백 정의 io.on('connection', function(socket) { socket.emit('syncServer', GameServer.serverNumber); socket.on('idRequest', function() { socket.playerData = { id: GameServer.getPlayerNumber(), nickname: '게스트', skin: 0, currentRoom: null, playingData: null, isReceivable: false }; GameServer.currentPlayer.push(socket); console.log(new Date().toLocaleTimeString('ko-KR') + ' ['+socket.playerData.id+'] client request'); socket.emit('setId', { str: 'your number is ' + socket.playerData.id, num: socket.playerData.id }); GameServer.connectCount++; }); socket.on('enterRoom', function(msg) // string new_nickname { if(msg.nickname.length < 1) socket.emit('alert' ,'errNicknameEmpty'); else { socket.playerData.nickname = msg.nickname; socket.playerData.skiin = msg.skin; console.log(new Date().toLocaleTimeString('ko-KR') + ' ['+socket.playerData.id+'] nickname set to ' + msg.nickname); GameServer.enterEmptyRoom(socket); } }); socket.on('exitFromRoom', function(msg){ GameServer.findPlayerSocket(msg).playerData.playingData.isInThisRoom = false; }); socket.on('setPlayerTyping', function(msg) // number playerTyping { try { let player = socket.playerData.playingData; let room = socket.playerData.currentRoom; player.playerTyping = msg.playerTyping; if (room.maxTypingPlayer.playerTyping < msg.playerTyping) { room.maxTypingPlayer = player; } if (room.minTypingPlayer.playerTyping > msg.playerTyping) { room.minTypingPlayer = player; } let playerTypingRate = (msg.playerTyping - (room.minTypingPlayer.playerTyping - room.rateArrangePoint)) / (room.maxTypingPlayer.playerTyping - room.minTypingPlayer.playerTyping + room.rateArrangePoint * 2); socket.emit('setPlayerTypingRate', playerTypingRate); if (msg.isWord) { room.announceToRoom('writeWord', player.id); } if (msg.isAttackMode) { room.announceToRoom('attackMode', player.id); } if (player.tabCheckTime != undefined) { clearTimeout(player.tabCheckTime); player.tabCheckTime = setTimeout(function() { if (room.currentPhase != GameServer.Phase.GAMEEND) player.defeat(); }, 1000); } else player.tabCheckTime = setTimeout(function() { if (room.currentPhase != GameServer.Phase.GAMEEND) player.defeat(); }, 1000); } catch (e) { console.error(new Date().toLocaleTimeString('ko-KR') + ' [ERR] error catched on setPlayerTyping (' + e + ')'); socket.disconnect(); } }); socket.on('endCount', function() { socket.playerData.currentRoom.aliveCount--; //console.log('counted, ' + socket.playerData.currentRoom.aliveCount); socket.playerData.playingData.isAlive = true; if (socket.playerData.currentRoom.aliveCount === 0 && socket.playerData.currentRoom.currentPlayer.length >= socket.playerData.currentRoom.startCount) { socket.playerData.currentRoom.startRoom(); clearTimeout(socket.playerData.currentRoom.startTimer); } if (socket.playerData.currentRoom.startTimer === undefined) { const room = socket.playerData.currentRoom; room.startTimer = setTimeout(function() { let deads = room.currentPlayer.filter(element => !element.isAlive); if (room.aliveCount != 0 && room.currentPlayer.length - deads.length >= room.startCount) { console.error(new Date().toLocaleTimeString('ko-KR') + ' [ROOM#'+room.roomId+'] FORCE START!!!'); room.startRoom(); deads.forEach(function(element) { element.defeat(); }); clearTimeout(room.startTimer); } else if (deads.length > 0) { deads.forEach(function(element) { room.currentSocket[element.index].disconnect(); room.exitRoom(element.id); }); room.refreshRoom(); } }, 2000); } }); socket.on('attack', function(msg) { socket.playerData.currentRoom.announceToTarget(msg.victimId, 'attacked', msg); socket.playerData.currentRoom.announceToRoom('someoneAttacked', {attackerId: msg.attackerId, victimId: msg.victimId, multiple: msg.multiple}); //console.log('attack ' + msg.victimId + ' by ' + msg.attackerId + ' with ' + msg.text); setTimeout(function() { let target = GameServer.findPlayerSocket(msg.victimId); if (target != null) { let dataToPush = { attackerId: msg.attackerId, wrongCount: 0, word: msg.text, wordGrade: msg.grade, time: Date.now() } target.playerData.playingData.lastAttacks.push(dataToPush); while (target.playerData.playingData.lastAttacks[0].time + 20000 < Date.now()) { target.playerData.playingData.lastAttacks.splice(0, 1); } } }, 4000); }); socket.on('defeated', function() { socket.playerData.playingData.defeat(); }); socket.on('defenseFailed', function(msg) { socket.playerData.currentRoom.announceToTarget(msg.attackerId, 'attackSucceed', msg); let wrongCountIndex = socket.playerData.playingData.lastAttacks.findIndex(function(element) { return (element.word === msg.word) && (element.attackerId === msg.victimId); }); if (wrongCountIndex !== -1) socket.playerData.playingData.lastAttacks[wrongCountIndex].wrongCount++; }); socket.on('itemStart', function(msg) //playerID, item { socket.playerData.currentRoom.announceToRoom('someoneItemStart', msg); }); socket.on('itemEnd', function(msg) //playerID, item { socket.playerData.currentRoom.announceToRoom('someoneItemEnd', msg); }); socket.on('disconnect', function(reason) { GameServer.disconnectCount++; let data = socket.playerData; if (data === undefined) { console.error(new Date().toLocaleTimeString('ko-KR') + ' [ERROR] data is undefined'); console.table(GameServer.currentPlayer); GameServer.disconnectCount--; } else // data.id is not undefined { disconnectUser(data, reason); } const connectDiff = GameServer.connectCount - GameServer.disconnectCount; const playerCount = GameServer.currentPlayer.length; if (connectDiff != playerCount) { console.log({ connectDiff, playerCount }); console.table(GameServer.currentPlayer); } socket.disconnect(); }); }); var disconnectUser = function(data, reason) { console.log(new Date().toLocaleTimeString('ko-KR') + ' ['+ data.id +'] client disconnected, reason: ' + reason); let idxToDel = GameServer.currentPlayer.findIndex(function(element) { return element.playerData.id === data.id; }); if (idxToDel != -1) { // 룸에서도 제거 if (data.currentRoom != null) { if (data.currentRoom.currentPhase === GameServer.Phase.READY || data.currentRoom.currentPhase === GameServer.Phase.COUNT) { data.currentRoom.exitRoom(data.id); } else if (data.playingData.isAlive) { data.playingData.defeat(); data.currentRoom.announceToRoom('userDisconnect', data.playingData); } } GameServer.currentPlayer.splice(idxToDel, 1); } //console.log('['+ data.id +'] disconnect complete'); }