v6-game-server v0.12.381
V6-Game-Server
Сервер на node.js для пошаговых игр.
Установка
npm install v6-game-server
Запуск
var Server = require('v6-game-server',
// настройки
conf = {},
// игровой движок
engine = {},
// сервер
server = new Server(conf, engine);
server.start();
Настройки
Настройки сервера с параметрами по умолчанию
{
game: 'default', // обязательный парамерт, алиас игры и бд
port: 8080, // порт подключения веб сокета
pingTimeout:100000, // таймаут клиента в мс
pingInterval:10000, // интервал пинга клиента в мс
closeOldConnection: true, // закрывать старое соединение клиента, при открытии нового
loseOnLeave: false, // засчитывать поражение при разрыве соединения с клиентом
reconnectOldGame: true, // загружать игру клинета, в которой произошел разрыв
spectateEnable: true, // разрешить просмотр игр
logLevel:3, // уровень подробности лога, 0 - без лога, 1 - только ошибки
turnTime: 100, // время на ход игрока в секундах
timeMode: 'reset_every_switch', // режимы таймера:
// 'reset_every_turn' сбрасывать после каждого хода
// 'reset_every_switch' сбрасывать после перехода хода
// 'dont_reset' не сбрасывать таймер, время на всю партию
// 'common' у игроков общее время на ход
timeStartMode: 'after_switch', // когда запускать таймер
// 'after_turn' после первого хода
// 'after_switch' после первого перехода хода
// 'after_round_start' сразу после начала раунда
addTime: 0, // сколько милисекунд добавлять к времени на ход игрока после каждого его хода
maxTimeouts: 1, // разрешенное число пропусков хода игрока подряд до поражения
clearTimeouts: true, // обнулять число пропусков игрока после его хода
maxOfflineTimeouts: 1, // число пропусков отключенного игрока подряд до поражения
minTurns: 0, // минимальное число число ходов (переходов хода) для сохранения игры
takeBacks: 0, // число разрешенных игроку ходов назад
loadRanksInRating: false, // загружать актуальные ранги при открытии таблицы рейтинга
ratingUpdateInterval: 1000, // интервал обновления рангов в списке игроков
penalties: false, // загружать штарфы игроков
mode: 'debug', // значение 'develop' уставновит режим без использования бд
gameModes: ['default'], // игровые режимы, со своим рейтингом и историей, имена без пробелов
modesAlias:{default:'default'}, // отображаемые клиенту алиасы режимов
enableIpGames: false, // разрешает игры с одного ip
minUnfocusedTurns: 0, // минимальное число ходов с потерей фокуса для засчитывания победы как читерской
// 0 - не считать
minPerUnfocusedTurns: 0.9, // соотношение числа ходов с потерей фокуса для засчитывания победы как читерской
adminList: [], // список userId админов
adminPass: '', // пароль для функций администратора
mongo:{ // настройки подключения mongodb
host: '127.0.0.1',
port: '27017'
},
redis:{ // настройки подключения redis
host: '127.0.0.1',
port: '6379'
},
https: true, // настройки https
httpsKey: '/path../serv.key',
httpsCert: '/path../serv.crt',
httpsCa: ['/path../sub.class1.server.ca.pem', '/path../ca.pem'],
}
Примеры настроек:
- обычная игра, время на ход 30 секунд, разрешен один пропуск хода,
время игрока обнуляется после каждого хода, таймер стартует после первого хода
{
turnTime: 30,
maxTimeouts: 2,
timeMode: 'reset_every_turn',
timeStartMode: 'after_turn',
}
- блиц, время на партию 60 секунд, время игрока не обнуляется,
после каждого его хода к его времени на ход добавляется 1 секунда,
таймер стартует после перехода хода к другому игроку,
после первого пропуска хода ему засчитывается поражение
{
turnTime: 60,
maxTimeouts: 1,
timeMode: 'dont_reset',
timeStartMode: 'after_switch',
addTime: 1000
}
- игра с общим временем на ход, по типу "кто быстрее",
таймер страртует сразу после начала раунда,
по истечении часа срабатывает таймаут и необходимо решить результат игры
{
turnTime: 3600,
maxTimeouts: 2,
timeMode: 'common',
timeStartMode: 'after_round_start',
}
Игровой движок
Методы игрового движка
{
/**
* вызывается после соединения нового пользователя в первый раз
* устанавливает значения нового пользователя по умолчанию
* рейтинги, очки, и т.д.
*/
initUserData: function(mode, modeData){
return modeData;
},
/**
* вызывается перед началом игрового раунда
* возвращаемый объект будет передан всем игрокам в начале раунда
* по умолчанию возвращает объект переданный игроком в приглашении
*/
initGame: function (room) {
return {
inviteData: room.inviteData
}
},
/**
* вызывается в начале раунда
* возвращает игрока, который будет ходить первым
* по умолчанию первым ходит создатель комнаты,
* в следующем раунде ход переходит к другому игроку
*/
setFirst: function (room) {
if (!room.game.first) return room.owner;
return room.getOpponent(room.game.first)
},
/**
* вызывается каждый ход или пропуск хода игрока
* возвращаемый объект будет передан всем игрокам и записан в историю
* если вернуть false || null || undefined ход будет признан некорректным
* в случае пропуска хода, turn = {action: 'timeout'}
* если вернуть объект с полем action = 'timeout'
* он будет принят как событие пропуск хода, иначе как обычный ход
* type {'turn'|'timeout'} - ход игрока или таймаут
*/
doTurn: function(room, user, turn, type){
if (type == 'timeout'){
// this is user timeout
}
return turn;
},
/**
* вызывается каждый ход игрока или после события пропуска хода
* возвращаемый игрок будет ходить следующим
* если вернуть того же игрока, чей был ход, ход останется за ним
* type {'turn'|'timeout'} - ход игрока или таймаут
*/
switchPlayer: function(room, user, turn, type){
if (type == 'timeout'){
// this is user timeout
}
return room.getOpponent(user);
},
/**
* вызывается после отправке игроком события
* возвращаемый объект будет передан заданным игрокам, и должен быть следующего вида:
* { event, target, user } || [Array], где
* event - объект с обязательным полем type
* target - цель для отправки события null || Room || User
* может быть массивом с разными объектами событий и целями
*/
userEvent: function(room, user, event){
return {
event: event,
target: room,
user: user.userId
}
},
/**
* вызывается в начале раунда и после каждого хода игрока
* возвращаемый объект будет передан заданным игрокам, и должен быть следующего вида:
* { event, target, user } || [Array], где
* event - объект с обязательным полем type
* target - цель для отправки события null || Room || User
* может быть массивом с разными объектами событий и целями
*/
gameEvent: function(room, user, turn, roundStart){
return null;
},
/**
* вызывается каждый ход и событие, определяет окончание раунда
* возвращаемый объект будет передан всем игрокам
* и должен быть вида {winner : user}, где
* user - User (игрок победитель ) || null (ничья)
* если вернуть false - раунд еще не окончен
* дополнительное поле 'action' указывает на действие,
* по которому завершилась игра, по умолчанию 'game_over'
* если пользователь не подключен, то игра завешится по
* максимальному числу офлайн таймаутов
* если не подключены оба, завершится поражением пропустившего
* если не обрабатывать пропускать ход можно бесконечно
* type {'turn'|'event','timeout'} - ход, событие или таймаут
*/
getGameResult: function(room, user, turn, type){
switch (type){
case 'timeout':
if (type == 'timeout'){
// if user have max timeouts, other win
if (room.data[user.userId].timeouts == room.maxTimeouts){
return {
winner: room.getOpponent(user),
action: 'timeout'
};
} else return false;
}
break;
case 'event':
if (turn.type){
return false;
}
break;
case 'turn':
switch (turn.result){
case 0: // win other player
return {
winner: room.getOpponent(user)
};
break;
case 1: // win current player
return {
winner: user
};
break;
case 2: // draw
return {
winner: null
};
break;
default: // game isn't end
return false;
}
break;
}
},
/**
* вызывается по окончанию раунда
* возвращаемый объект утсанавливает значение очков игроков
* room.players[0][room.mode].['score'] = new_score
*/
getUsersScores: function(room, result){
// например
for (var i = 0; i < room.players.length; i++){
if (room.players[i] == result.winner)
room.players[i][room.mode].score += 10;
else room.players[i][room.mode].score -= 10;
}
return result;
},
/**
* вызывается после отмены хода, для изменения игрового
* состояния в комнате
*/
doTakeBack: function(room, user){
return null;
},
/**
* вызывается после авторизации пользователя
* проверяет подлинноть подписи
*/
checkSign: function(user){
return (user.userId && user.userName && user.sign);
}
/**
* действие по вызову администратора
* @param admin
* @param type
* @param data
*/
adminAction: function(admin, type, data){
}
};
Игровые сущности
Room
{
owner: User, // создатель
players: Array, // массив с игроками
spectators: Array, // массив зрителей
inviteData: Object // объект приглашения
mode: String // режим
games: Int; // сыграно раундов
turnTime: Int; // время на ход
game: {
state: String // состояние игры: waiting, playing, end
current: User, // текущий игрок
first: User, // игрок, чей ход первый, установленный функцией engine.setFirst
history: Array, // массив с иторией ходов и событий
shistory: String// массив с историей, преобразованный в строку
turnStartTime: UTC // дата начала хода игрока
},
data: Object, // массив ключ значение, где ключи - userId
// для хранения временной информации для каждого игрока
getOpponent: Function(user: User) // возвращает соперника игрока
setUserTurnTime: Function(time: ms) // устанавливает время на следующий ход
}
User
{
userId: String, // идетификатор игрока
userName: String // имя
sign: String // подпись
currentRoom: Room // текущая комната (играет или зритель)
}
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago