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) {
|
2018-03-07 13:57:06 +01:00
|
|
|
winner = o.blackCount == o.whiteCount ? null : o.blackCount > o.whiteCount ? game.black_user_id : game.white_user_id;
|
2018-03-07 10:45:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2018-03-07 13:57:06 +01:00
|
|
|
publishOthelloGameStream(gameId, 'set', log);
|
2018-03-07 10:45:16 +01:00
|
|
|
}
|
2018-03-07 03:40:40 +01:00
|
|
|
}
|