misskey/src/api/stream/othello-game.ts

88 lines
2.1 KiB
TypeScript
Raw Normal View History

2018-03-07 03:40:40 +01:00
import * as websocket from 'websocket';
import * as redis from 'redis';
2018-03-07 09:48:32 +01:00
import Game from '../models/othello-game';
import { publishOthelloGameStream } from '../event';
import Othello from '../../common/othello';
2018-03-07 03:40:40 +01:00
2018-03-07 09:48:32 +01:00
export default function(request: websocket.request, connection: websocket.connection, subscriber: redis.RedisClient, user: any): void {
const gameId = request.resourceURL.query.game;
2018-03-07 03:40:40 +01:00
// Subscribe game stream
2018-03-07 09:48:32 +01:00
subscriber.subscribe(`misskey:othello-game-stream:${gameId}`);
2018-03-07 03:40:40 +01:00
subscriber.on('message', (_, data) => {
connection.send(data);
});
2018-03-07 09:48:32 +01:00
connection.on('message', async (data) => {
const msg = JSON.parse(data.utf8Data);
switch (msg.type) {
case 'set':
if (msg.pos == null) return;
2018-03-07 10:45:16 +01:00
set(msg.pos);
2018-03-07 09:48:32 +01:00
break;
}
});
2018-03-07 10:45:16 +01:00
async function set(pos) {
const game = await Game.findOne({ _id: gameId });
if (game.is_ended) return;
2018-03-07 11:03:32 +01:00
if (!game.black_user_id.equals(user._id) && !game.white_user_id.equals(user._id)) return;
2018-03-07 10:45:16 +01:00
const o = new Othello();
game.logs.forEach(log => {
o.set(log.color, log.pos);
});
const myColor = game.black_user_id.equals(user._id) ? 'black' : 'white';
const opColor = myColor == 'black' ? 'white' : 'black';
if (!o.canReverse(myColor, pos)) return;
o.set(myColor, pos);
let turn;
if (o.getPattern(opColor).length > 0) {
turn = myColor == 'black' ? game.white_user_id : game.black_user_id;
} else if (o.getPattern(myColor).length > 0) {
turn = myColor == 'black' ? game.black_user_id : game.white_user_id;
} else {
turn = null;
}
const isEnded = turn === null;
let winner;
if (isEnded) {
const blackCount = o.board.filter(s => s == 'black').length;
const whiteCount = o.board.filter(s => s == 'white').length;
winner = blackCount == whiteCount ? null : blackCount > whiteCount ? game.black_user_id : game.white_user_id;
}
const log = {
at: new Date(),
color: myColor,
pos
};
await Game.update({
_id: gameId
}, {
$set: {
turn_user_id: turn,
is_ended: isEnded,
winner_id: winner
},
$push: {
logs: log
}
});
publishOthelloGameStream(gameId, 'set', {
color: myColor,
pos
});
}
2018-03-07 03:40:40 +01:00
}