summaryrefslogtreecommitdiff
path: root/src/api
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2018-03-07 17:48:32 +0900
committersyuilo <syuilotan@yahoo.co.jp>2018-03-07 17:48:32 +0900
commit161fd4afab323ca6bf491def473f84bb7557b481 (patch)
tree4c8a2215dc9d3e3b817bbd82ca9b8f88fb0a0420 /src/api
parentwip (diff)
downloadsharkey-161fd4afab323ca6bf491def473f84bb7557b481.tar.gz
sharkey-161fd4afab323ca6bf491def473f84bb7557b481.tar.bz2
sharkey-161fd4afab323ca6bf491def473f84bb7557b481.zip
wip
Diffstat (limited to 'src/api')
-rw-r--r--src/api/endpoints.ts20
-rw-r--r--src/api/endpoints/othello/games.ts22
-rw-r--r--src/api/endpoints/othello/invitations.ts11
-rw-r--r--src/api/endpoints/othello/match.ts22
-rw-r--r--src/api/endpoints/othello/match/cancel.ts9
-rw-r--r--src/api/event.ts6
-rw-r--r--src/api/models/othello-game.ts20
-rw-r--r--src/api/models/othello-matching.ts31
-rw-r--r--src/api/stream/othello-game.ts63
-rw-r--r--src/api/stream/othello.ts (renamed from src/api/stream/othello-matching.ts)6
-rw-r--r--src/api/streaming.ts4
11 files changed, 188 insertions, 26 deletions
diff --git a/src/api/endpoints.ts b/src/api/endpoints.ts
index cbc016f20f..fad6667111 100644
--- a/src/api/endpoints.ts
+++ b/src/api/endpoints.ts
@@ -234,6 +234,26 @@ const endpoints: Endpoint[] = [
},
{
+ name: 'othello/match',
+ withCredential: true
+ },
+
+ {
+ name: 'othello/match/cancel',
+ withCredential: true
+ },
+
+ {
+ name: 'othello/invitations',
+ withCredential: true
+ },
+
+ {
+ name: 'othello/games',
+ withCredential: true
+ },
+
+ {
name: 'mute/create',
withCredential: true,
kind: 'account/write'
diff --git a/src/api/endpoints/othello/games.ts b/src/api/endpoints/othello/games.ts
new file mode 100644
index 0000000000..62388b01d4
--- /dev/null
+++ b/src/api/endpoints/othello/games.ts
@@ -0,0 +1,22 @@
+import $ from 'cafy';
+import Game, { pack } from '../../models/othello-game';
+
+module.exports = (params, user) => new Promise(async (res, rej) => {
+ // Get 'my' parameter
+ const [my = false, myErr] = $(params.my).boolean().$;
+ if (myErr) return rej('invalid my param');
+
+ const q = my ? {
+ $or: [{
+ black_user_id: user._id
+ }, {
+ white_user_id: user._id
+ }]
+ } : {};
+
+ // Fetch games
+ const games = await Game.find(q);
+
+ // Reponse
+ res(Promise.all(games.map(async (g) => await pack(g, user))));
+});
diff --git a/src/api/endpoints/othello/invitations.ts b/src/api/endpoints/othello/invitations.ts
new file mode 100644
index 0000000000..f462ef0bf9
--- /dev/null
+++ b/src/api/endpoints/othello/invitations.ts
@@ -0,0 +1,11 @@
+import Matching, { pack as packMatching } from '../../models/othello-matching';
+
+module.exports = (params, user) => new Promise(async (res, rej) => {
+ // Find session
+ const invitations = await Matching.find({
+ child_id: user._id
+ });
+
+ // Reponse
+ res(Promise.all(invitations.map(async (i) => await packMatching(i, user))));
+});
diff --git a/src/api/endpoints/othello/match.ts b/src/api/endpoints/othello/match.ts
index 2dc22d11f9..65243a5571 100644
--- a/src/api/endpoints/othello/match.ts
+++ b/src/api/endpoints/othello/match.ts
@@ -1,6 +1,6 @@
import $ from 'cafy';
-import Matching from '../../models/othello-matchig';
-import Game, { pack } from '../../models/othello-game';
+import Matching, { pack as packMatching } from '../../models/othello-matching';
+import Game, { pack as packGame } from '../../models/othello-game';
import User from '../../models/user';
import { publishOthelloStream } from '../../event';
@@ -33,17 +33,14 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
created_at: new Date(),
black_user_id: parentIsBlack ? exist.parent_id : user._id,
white_user_id: parentIsBlack ? user._id : exist.parent_id,
+ turn_user_id: parentIsBlack ? exist.parent_id : user._id,
logs: []
});
- const packedGame = await pack(game);
-
// Reponse
- res(packedGame);
+ res(await packGame(game, user));
- publishOthelloStream(exist.parent_id, 'matched', {
- game
- });
+ publishOthelloStream(exist.parent_id, 'matched', await packGame(game, exist.parent_id));
} else {
// Fetch child
const child = await User.findOne({
@@ -64,17 +61,16 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
});
// セッションを作成
- await Matching.insert({
+ const matching = await Matching.insert({
+ created_at: new Date(),
parent_id: user._id,
child_id: child._id
});
// Reponse
- res(204);
+ res();
// 招待
- publishOthelloStream(child._id, 'invited', {
- user_id: user._id
- });
+ publishOthelloStream(child._id, 'invited', await packMatching(matching, child));
}
});
diff --git a/src/api/endpoints/othello/match/cancel.ts b/src/api/endpoints/othello/match/cancel.ts
new file mode 100644
index 0000000000..6f751ef835
--- /dev/null
+++ b/src/api/endpoints/othello/match/cancel.ts
@@ -0,0 +1,9 @@
+import Matching from '../../../models/othello-matching';
+
+module.exports = (params, user) => new Promise(async (res, rej) => {
+ await Matching.remove({
+ parent_id: user._id
+ });
+
+ res();
+});
diff --git a/src/api/event.ts b/src/api/event.ts
index e68082f0a9..4c9cc18e4d 100644
--- a/src/api/event.ts
+++ b/src/api/event.ts
@@ -42,6 +42,10 @@ class MisskeyEvent {
this.publish(`othello-stream:${userId}`, type, typeof value === 'undefined' ? null : value);
}
+ public publishOthelloGameStream(gameId: ID, type: string, value?: any): void {
+ this.publish(`othello-game-stream:${gameId}`, type, typeof value === 'undefined' ? null : value);
+ }
+
public publishChannelStream(channelId: ID, type: string, value?: any): void {
this.publish(`channel-stream:${channelId}`, type, typeof value === 'undefined' ? null : value);
}
@@ -71,4 +75,6 @@ export const publishMessagingIndexStream = ev.publishMessagingIndexStream.bind(e
export const publishOthelloStream = ev.publishOthelloStream.bind(ev);
+export const publishOthelloGameStream = ev.publishOthelloGameStream.bind(ev);
+
export const publishChannelStream = ev.publishChannelStream.bind(ev);
diff --git a/src/api/models/othello-game.ts b/src/api/models/othello-game.ts
index a6beaaf9c7..b9fd94ebc0 100644
--- a/src/api/models/othello-game.ts
+++ b/src/api/models/othello-game.ts
@@ -1,6 +1,7 @@
import * as mongo from 'mongodb';
import deepcopy = require('deepcopy');
import db from '../../db/mongodb';
+import { IUser, pack as packUser } from './user';
const Game = db.get<IGame>('othello_games');
export default Game;
@@ -15,19 +16,30 @@ export interface IGame {
/**
* Pack an othello game for API response
- *
- * @param {any} game
- * @return {Promise<any>}
*/
export const pack = (
- game: any
+ game: any,
+ me?: string | mongo.ObjectID | IUser
) => new Promise<any>(async (resolve, reject) => {
+ // Me
+ const meId: mongo.ObjectID = me
+ ? mongo.ObjectID.prototype.isPrototypeOf(me)
+ ? me as mongo.ObjectID
+ : typeof me === 'string'
+ ? new mongo.ObjectID(me)
+ : (me as IUser)._id
+ : null;
+
const _game = deepcopy(game);
// Rename _id to id
_game.id = _game._id;
delete _game._id;
+ // Populate user
+ _game.black_user = await packUser(_game.black_user_id, meId);
+ _game.white_user = await packUser(_game.white_user_id, meId);
+
resolve(_game);
});
diff --git a/src/api/models/othello-matching.ts b/src/api/models/othello-matching.ts
index bd7aeef3cf..89fcd6df6a 100644
--- a/src/api/models/othello-matching.ts
+++ b/src/api/models/othello-matching.ts
@@ -1,11 +1,42 @@
import * as mongo from 'mongodb';
+import deepcopy = require('deepcopy');
import db from '../../db/mongodb';
+import { IUser, pack as packUser } from './user';
const Matching = db.get<IMatching>('othello_matchings');
export default Matching;
export interface IMatching {
_id: mongo.ObjectID;
+ created_at: Date;
parent_id: mongo.ObjectID;
child_id: mongo.ObjectID;
}
+
+/**
+ * Pack an othello matching for API response
+ */
+export const pack = (
+ matching: any,
+ me?: string | mongo.ObjectID | IUser
+) => new Promise<any>(async (resolve, reject) => {
+
+ // Me
+ const meId: mongo.ObjectID = me
+ ? mongo.ObjectID.prototype.isPrototypeOf(me)
+ ? me as mongo.ObjectID
+ : typeof me === 'string'
+ ? new mongo.ObjectID(me)
+ : (me as IUser)._id
+ : null;
+
+ const _matching = deepcopy(matching);
+
+ delete _matching._id;
+
+ // Populate user
+ _matching.parent = await packUser(_matching.parent_id, meId);
+ _matching.child = await packUser(_matching.child_id, meId);
+
+ resolve(_matching);
+});
diff --git a/src/api/stream/othello-game.ts b/src/api/stream/othello-game.ts
index ab91ef6422..17cdd3a9e7 100644
--- a/src/api/stream/othello-game.ts
+++ b/src/api/stream/othello-game.ts
@@ -1,12 +1,69 @@
import * as websocket from 'websocket';
import * as redis from 'redis';
+import Game from '../models/othello-game';
+import { publishOthelloGameStream } from '../event';
+import Othello from '../../common/othello';
-export default function(request: websocket.request, connection: websocket.connection, subscriber: redis.RedisClient): void {
- const game = request.resourceURL.query.game;
+export default function(request: websocket.request, connection: websocket.connection, subscriber: redis.RedisClient, user: any): void {
+ const gameId = request.resourceURL.query.game;
// Subscribe game stream
- subscriber.subscribe(`misskey:othello-game-stream:${game}`);
+ subscriber.subscribe(`misskey:othello-game-stream:${gameId}`);
subscriber.on('message', (_, data) => {
connection.send(data);
});
+
+ connection.on('message', async (data) => {
+ const msg = JSON.parse(data.utf8Data);
+
+ switch (msg.type) {
+ case 'set':
+ if (msg.pos == null) return;
+ const pos = msg.pos;
+
+ const game = await Game.findOne({ _id: gameId });
+
+ 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 {
+ turn = myColor == 'black' ? 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
+ },
+ $push: {
+ logs: log
+ }
+ });
+
+ publishOthelloGameStream(gameId, 'set', {
+ color: myColor,
+ pos
+ });
+ break;
+ }
+ });
}
diff --git a/src/api/stream/othello-matching.ts b/src/api/stream/othello.ts
index f30ce6eb0a..5056eb535c 100644
--- a/src/api/stream/othello-matching.ts
+++ b/src/api/stream/othello.ts
@@ -2,10 +2,8 @@ import * as websocket from 'websocket';
import * as redis from 'redis';
export default function(request: websocket.request, connection: websocket.connection, subscriber: redis.RedisClient, user: any): void {
- const otherparty = request.resourceURL.query.otherparty;
-
- // Subscribe matching stream
- subscriber.subscribe(`misskey:othello-matching:${user._id}-${otherparty}`);
+ // Subscribe othello stream
+ subscriber.subscribe(`misskey:othello-stream:${user._id}`);
subscriber.on('message', (_, data) => {
connection.send(data);
});
diff --git a/src/api/streaming.ts b/src/api/streaming.ts
index 66c2e0cec0..7d67ba9574 100644
--- a/src/api/streaming.ts
+++ b/src/api/streaming.ts
@@ -11,7 +11,7 @@ import driveStream from './stream/drive';
import messagingStream from './stream/messaging';
import messagingIndexStream from './stream/messaging-index';
import othelloGameStream from './stream/othello-game';
-import othelloMatchingStream from './stream/othello-matching';
+import othelloStream from './stream/othello';
import serverStream from './stream/server';
import requestsStream from './stream/requests';
import channelStream from './stream/channel';
@@ -65,7 +65,7 @@ module.exports = (server: http.Server) => {
request.resourceURL.pathname === '/messaging' ? messagingStream :
request.resourceURL.pathname === '/messaging-index' ? messagingIndexStream :
request.resourceURL.pathname === '/othello-game' ? othelloGameStream :
- request.resourceURL.pathname === '/othello-matching' ? othelloMatchingStream :
+ request.resourceURL.pathname === '/othello' ? othelloStream :
null;
if (channel !== null) {