trucoshi 0.0.13 → 0.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,3 @@
1
1
  import { IPlayer } from "../types";
2
+ export type IPublicPlayer = Pick<IPlayer, "id" | "disabled" | "ready" | "hand" | "usedHand" | "teamIdx" | "session">;
2
3
  export declare function Player(id: string, teamIdx: number): IPlayer;
@@ -4,12 +4,16 @@ exports.Player = void 0;
4
4
  function Player(id, teamIdx) {
5
5
  var player = {
6
6
  id: id,
7
+ session: undefined,
7
8
  teamIdx: teamIdx,
8
9
  hand: [],
9
10
  commands: [],
10
11
  usedHand: [],
11
12
  disabled: false,
12
13
  ready: false,
14
+ setSession: function (session) {
15
+ player.session = session;
16
+ },
13
17
  enable: function () {
14
18
  player.disabled = false;
15
19
  },
@@ -1,2 +1,3 @@
1
1
  import { IPlayer, ITeam } from "../types";
2
+ export type IPublicTeam = Pick<ITeam, "players" | "points">;
2
3
  export declare function Team(players: Array<IPlayer>): ITeam;
@@ -1,4 +1,4 @@
1
- import { IPlayInstance, ITeam, ITrucoshi } from "./types";
1
+ import { IHand, IPlayInstance, ITeam, ILobby } from "./types";
2
2
  export type IWinnerCallback = (winner: ITeam, teams: [ITeam, ITeam]) => Promise<void>;
3
3
  export type ITurnCallback = (play: IPlayInstance) => Promise<void>;
4
4
  export type ITrucoCallback = (play: IPlayInstance) => Promise<void>;
@@ -6,13 +6,11 @@ export interface IGameLoop {
6
6
  _onTruco: ITrucoCallback;
7
7
  _onTurn: ITurnCallback;
8
8
  _onWinner: IWinnerCallback;
9
+ teams: Array<ITeam>;
10
+ hands: Array<IHand>;
9
11
  onTurn: (callback: ITurnCallback) => IGameLoop;
10
12
  onWinner: (callback: IWinnerCallback) => IGameLoop;
11
13
  onTruco: (callback: ITrucoCallback) => IGameLoop;
12
- begin: () => void;
14
+ begin: () => Promise<void>;
13
15
  }
14
- export declare function Trucoshi(teamSize?: 1 | 2 | 3): {
15
- addPlayer: (id: string, teamIdx?: 0 | 1 | undefined) => import("./types").IPlayer;
16
- removePlayer: (id: string) => ITrucoshi;
17
- startMatch: (matchPoint?: 9 | 12 | 15 | undefined) => IGameLoop;
18
- };
16
+ export declare function Lobby(teamSize?: 1 | 2 | 3): ILobby;
package/dist/lib/index.js CHANGED
@@ -36,7 +36,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
36
36
  }
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.Trucoshi = void 0;
39
+ exports.Lobby = void 0;
40
40
  var Match_1 = require("./classes/Match");
41
41
  var Player_1 = require("./classes/Player");
42
42
  var Table_1 = require("./classes/Table");
@@ -48,6 +48,8 @@ var GameLoop = function (match) {
48
48
  _onTruco: function () { return Promise.resolve(); },
49
49
  _onTurn: function () { return Promise.resolve(); },
50
50
  _onWinner: function () { return Promise.resolve(); },
51
+ teams: [],
52
+ hands: [],
51
53
  onTruco: function (callback) {
52
54
  gameloop._onTruco = callback;
53
55
  return gameloop;
@@ -66,25 +68,29 @@ var GameLoop = function (match) {
66
68
  return __generator(this, function (_a) {
67
69
  switch (_a.label) {
68
70
  case 0:
69
- if (!!match.winner) return [3 /*break*/, 5];
71
+ gameloop.teams = match.teams;
72
+ _a.label = 1;
73
+ case 1:
74
+ if (!!match.winner) return [3 /*break*/, 6];
70
75
  play = match.play();
76
+ gameloop.hands = match.hands;
71
77
  if (!play || !play.player) {
72
- return [3 /*break*/, 0];
78
+ return [3 /*break*/, 1];
73
79
  }
74
- if (!(play.state === types_1.EHandState.WAITING_FOR_TRUCO_ANSWER)) return [3 /*break*/, 2];
80
+ if (!(play.state === types_1.EHandState.WAITING_FOR_TRUCO_ANSWER)) return [3 /*break*/, 3];
75
81
  return [4 /*yield*/, gameloop._onTruco(play)];
76
- case 1:
77
- _a.sent();
78
- return [3 /*break*/, 0];
79
82
  case 2:
80
- if (!(play.state === types_1.EHandState.WAITING_PLAY)) return [3 /*break*/, 4];
81
- return [4 /*yield*/, gameloop._onTurn(play)];
83
+ _a.sent();
84
+ return [3 /*break*/, 1];
82
85
  case 3:
86
+ if (!(play.state === types_1.EHandState.WAITING_PLAY)) return [3 /*break*/, 5];
87
+ return [4 /*yield*/, gameloop._onTurn(play)];
88
+ case 4:
83
89
  _a.sent();
84
- return [3 /*break*/, 0];
85
- case 4: return [3 /*break*/, 0];
86
- case 5: return [4 /*yield*/, gameloop._onWinner(match.winner, match.teams)];
87
- case 6:
90
+ return [3 /*break*/, 1];
91
+ case 5: return [3 /*break*/, 1];
92
+ case 6: return [4 /*yield*/, gameloop._onWinner(match.winner, match.teams)];
93
+ case 7:
88
94
  _a.sent();
89
95
  return [2 /*return*/];
90
96
  }
@@ -94,68 +100,69 @@ var GameLoop = function (match) {
94
100
  };
95
101
  return gameloop;
96
102
  };
97
- function Trucoshi(teamSize) {
98
- var trucoshi = {
103
+ function Lobby(teamSize) {
104
+ var lobby = {
99
105
  lastTeamIdx: 1,
100
106
  _players: new Map(),
101
107
  get players() {
102
- return Array.from(trucoshi._players.values());
108
+ return Array.from(lobby._players.values());
103
109
  },
104
110
  teams: [],
105
111
  table: null,
106
112
  maxPlayers: teamSize ? teamSize * 2 : 6,
107
113
  full: false,
108
114
  ready: false,
115
+ gameLoop: undefined,
109
116
  calculateReady: function () {
110
- trucoshi.ready = trucoshi.players.reduce(function (prev, curr) { return prev && curr.ready; }, true);
111
- return trucoshi.ready;
117
+ lobby.ready = lobby.players.reduce(function (prev, curr) { return prev && curr.ready; }, true);
118
+ return lobby.ready;
112
119
  },
113
120
  calculateFull: function () {
114
- trucoshi.full = trucoshi._players.size >= trucoshi.maxPlayers;
115
- return trucoshi.full;
121
+ lobby.full = lobby._players.size >= lobby.maxPlayers;
122
+ return lobby.full;
116
123
  },
117
- addPlayer: function (id, teamIdx) {
124
+ addPlayer: function (id, session, teamIdx) {
118
125
  var maxSize = teamSize ? teamSize : 3;
119
- if (trucoshi.full || trucoshi.players.filter(function (p) { return p.teamIdx === teamIdx; }).length > maxSize) {
126
+ if (lobby.full || lobby.players.filter(function (p) { return p.teamIdx === teamIdx; }).length > maxSize) {
120
127
  throw new Error(constants_1.GAME_ERROR.TEAM_IS_FULL);
121
128
  }
122
- var player = (0, Player_1.Player)(id, teamIdx !== undefined ? teamIdx : Number(!trucoshi.lastTeamIdx));
123
- trucoshi.lastTeamIdx = Number(!trucoshi.lastTeamIdx);
124
- trucoshi._players.set(id, player);
125
- trucoshi.calculateFull();
126
- trucoshi.calculateReady();
129
+ var player = (0, Player_1.Player)(id, teamIdx !== undefined ? teamIdx : Number(!lobby.lastTeamIdx));
130
+ player.setSession(session);
131
+ lobby.lastTeamIdx = Number(!lobby.lastTeamIdx);
132
+ lobby._players.set(id, player);
133
+ lobby.calculateFull();
134
+ lobby.calculateReady();
127
135
  return player;
128
136
  },
129
137
  removePlayer: function (id) {
130
- trucoshi._players.delete(id);
131
- trucoshi.calculateFull();
132
- trucoshi.calculateReady();
133
- return trucoshi;
138
+ lobby._players.delete(id);
139
+ lobby.calculateFull();
140
+ lobby.calculateReady();
141
+ return lobby;
134
142
  },
135
143
  startMatch: function (matchPoint) {
136
144
  if (matchPoint === void 0) { matchPoint = 9; }
137
- trucoshi.calculateReady();
138
- var teamSize = trucoshi._players.size / 2;
145
+ lobby.calculateReady();
146
+ var teamSize = lobby._players.size / 2;
139
147
  if (!constants_1.TEAM_SIZE_VALUES.includes(teamSize)) {
140
148
  throw new Error(constants_1.GAME_ERROR.UNEXPECTED_TEAM_SIZE);
141
149
  }
142
- if (!trucoshi.ready) {
150
+ if (!lobby.ready) {
143
151
  throw new Error(constants_1.GAME_ERROR.TEAM_NOT_READY);
144
152
  }
145
- trucoshi.teams.push((0, Team_1.Team)(trucoshi.players.filter(function (p) { return p.teamIdx === 0; })));
146
- trucoshi.teams.push((0, Team_1.Team)(trucoshi.players.filter(function (p) { return p.teamIdx === 1; })));
147
- if (trucoshi.teams[0].players.length !== teamSize ||
148
- trucoshi.teams[1].players.length !== teamSize) {
153
+ lobby.teams = [
154
+ (0, Team_1.Team)(lobby.players.filter(function (p) { return p.teamIdx === 0; })),
155
+ (0, Team_1.Team)(lobby.players.filter(function (p) { return p.teamIdx === 1; })),
156
+ ];
157
+ if (lobby.teams[0].players.length !== teamSize ||
158
+ lobby.teams[1].players.length !== teamSize) {
149
159
  throw new Error(constants_1.GAME_ERROR.UNEXPECTED_TEAM_SIZE);
150
160
  }
151
- trucoshi.table = (0, Table_1.Table)(trucoshi.players, trucoshi.teams);
152
- return GameLoop((0, Match_1.Match)(trucoshi.table, trucoshi.teams, matchPoint));
161
+ lobby.table = (0, Table_1.Table)(lobby.players, lobby.teams);
162
+ lobby.gameLoop = GameLoop((0, Match_1.Match)(lobby.table, lobby.teams, matchPoint));
163
+ return lobby.gameLoop;
153
164
  },
154
165
  };
155
- return {
156
- addPlayer: trucoshi.addPlayer,
157
- removePlayer: trucoshi.removePlayer,
158
- startMatch: trucoshi.startMatch,
159
- };
166
+ return lobby;
160
167
  }
161
- exports.Trucoshi = Trucoshi;
168
+ exports.Lobby = Lobby;
@@ -1,4 +1,5 @@
1
1
  import { IGameLoop } from ".";
2
+ import { IPublicPlayer } from "./classes/Player";
2
3
  import { CARDS } from "./constants";
3
4
  export type ICard = keyof typeof CARDS;
4
5
  export interface IDeck {
@@ -8,17 +9,19 @@ export interface IDeck {
8
9
  shuffle(): IDeck;
9
10
  }
10
11
  export interface IPlayedCard {
11
- player: IPlayer;
12
+ player: IPlayer & IPublicPlayer;
12
13
  card: ICard;
13
14
  }
14
15
  export interface IPlayer {
15
16
  teamIdx: number;
16
17
  id: string;
18
+ session?: string;
17
19
  hand: Array<ICard>;
18
20
  commands: Array<ECommand>;
19
21
  usedHand: Array<ICard>;
20
22
  disabled: boolean;
21
23
  ready: boolean;
24
+ setSession(session: string): void;
22
25
  enable(): void;
23
26
  disable(): void;
24
27
  setReady(ready: boolean): void;
@@ -144,7 +147,8 @@ export interface IHand {
144
147
  setState(state: EHandState): EHandState;
145
148
  getNextPlayer(): IteratorResult<IHand, IHand | void>;
146
149
  }
147
- export interface IPrivateTrucoshi {
150
+ export interface IPrivateLobby {
151
+ gameLoop?: IGameLoop;
148
152
  lastTeamIdx: 0 | 1;
149
153
  _players: Map<string, IPlayer>;
150
154
  get players(): Array<IPlayer>;
@@ -153,13 +157,13 @@ export interface IPrivateTrucoshi {
153
157
  table: ITable | null;
154
158
  ready: boolean;
155
159
  full: boolean;
156
- addPlayer(id: string, teamIdx?: 0 | 1): IPlayer;
157
- removePlayer(id: string): ITrucoshi;
160
+ addPlayer(id: string, session: string, teamIdx?: 0 | 1): IPlayer;
161
+ removePlayer(id: string): ILobby;
158
162
  calculateReady(): boolean;
159
163
  calculateFull(): boolean;
160
164
  startMatch(matchPoint?: 9 | 12 | 15): IGameLoop;
161
165
  }
162
- export interface ITrucoshi extends Pick<IPrivateTrucoshi, 'addPlayer' | 'removePlayer' | 'startMatch'> {
166
+ export interface ILobby extends Pick<IPrivateLobby, "addPlayer" | "removePlayer" | "startMatch" | "ready" | "full" | "teams" | "players" | "gameLoop" | "table"> {
163
167
  }
164
168
  export interface ITable {
165
169
  forehandIdx: number;
@@ -0,0 +1,25 @@
1
+ import { IPublicPlayer } from "../../lib/classes/Player";
2
+ import { IPublicTeam } from "../../lib/classes/Team";
3
+ import { ILobby, IPlayedCard } from "../../lib/types";
4
+ export interface IPublicMatch {
5
+ teams: Array<IPublicTeam>;
6
+ players: Array<IPublicPlayer>;
7
+ rounds: IPlayedCard[][];
8
+ state: EMatchTableState;
9
+ }
10
+ export interface IMatchTable {
11
+ matchSessionId: string;
12
+ currentPlayer: IPublicPlayer | null;
13
+ lobby: ILobby;
14
+ state: EMatchTableState;
15
+ setState(state: EMatchTableState): void;
16
+ setCurrentPlayer(player: IPublicPlayer): void;
17
+ isSessionPlaying(session: string): IPublicPlayer | null;
18
+ getPublicMatch(session?: string): IPublicMatch;
19
+ }
20
+ export declare enum EMatchTableState {
21
+ UNREADY = 0,
22
+ STARTED = 1,
23
+ FINISHED = 2
24
+ }
25
+ export declare function MatchTable(matchSessionId: string, teamSize?: 1 | 2 | 3): IMatchTable;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.MatchTable = exports.EMatchTableState = void 0;
15
+ var lib_1 = require("../../lib");
16
+ var EMatchTableState;
17
+ (function (EMatchTableState) {
18
+ EMatchTableState[EMatchTableState["UNREADY"] = 0] = "UNREADY";
19
+ EMatchTableState[EMatchTableState["STARTED"] = 1] = "STARTED";
20
+ EMatchTableState[EMatchTableState["FINISHED"] = 2] = "FINISHED";
21
+ })(EMatchTableState = exports.EMatchTableState || (exports.EMatchTableState = {}));
22
+ function MatchTable(matchSessionId, teamSize) {
23
+ var matchTable = {
24
+ matchSessionId: matchSessionId,
25
+ currentPlayer: null,
26
+ lobby: (0, lib_1.Lobby)(teamSize),
27
+ state: EMatchTableState.UNREADY,
28
+ setState: function (state) {
29
+ matchTable.state = state;
30
+ },
31
+ setCurrentPlayer: function (player) {
32
+ matchTable.currentPlayer = player;
33
+ },
34
+ isSessionPlaying: function (session) {
35
+ var lobby = matchTable.lobby;
36
+ var search = lobby.players.find(function (player) { return player.session === session; });
37
+ return search || null;
38
+ },
39
+ getPublicMatch: function (userSession) {
40
+ var _a, _b, _c;
41
+ var lobby = matchTable.lobby;
42
+ var lastHand = (((_a = lobby.gameLoop) === null || _a === void 0 ? void 0 : _a.hands.length) || 1) - 1;
43
+ var rounds = (_c = (_b = lobby.gameLoop) === null || _b === void 0 ? void 0 : _b.hands[lastHand]) === null || _c === void 0 ? void 0 : _c.rounds.map(function (round) { return round.cards; });
44
+ return {
45
+ matchSessionId: matchSessionId,
46
+ state: matchTable.state,
47
+ teams: [],
48
+ players: lobby.players.map(function (player) {
49
+ return player.session === userSession
50
+ ? player
51
+ : __assign(__assign({}, player), { hand: player.hand.map(function () { return "xx"; }) });
52
+ }),
53
+ rounds: rounds || [[]],
54
+ };
55
+ },
56
+ };
57
+ return matchTable;
58
+ }
59
+ exports.MatchTable = MatchTable;
@@ -1,5 +1,5 @@
1
1
  export interface IUser {
2
2
  id: string;
3
- session: string;
3
+ socketId: string;
4
4
  }
5
- export declare function User(id: string, session: string): IUser;
5
+ export declare function User(id: string, socketId: string): IUser;
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.User = void 0;
4
- function User(id, session) {
4
+ function User(id, socketId) {
5
5
  var user = {
6
6
  id: id,
7
- session: session,
7
+ socketId: socketId,
8
8
  };
9
9
  return user;
10
10
  }
@@ -1,9 +1,45 @@
1
1
  "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
2
38
  Object.defineProperty(exports, "__esModule", { value: true });
3
39
  var crypto_1 = require("crypto");
4
40
  var http_1 = require("http");
5
41
  var socket_io_1 = require("socket.io");
6
- var lib_1 = require("../lib");
42
+ var MatchTable_1 = require("./classes/MatchTable");
7
43
  var user_1 = require("./classes/user");
8
44
  var types_1 = require("./types");
9
45
  var PORT = 4001;
@@ -14,48 +50,306 @@ var io = new socket_io_1.Server(httpServer, {
14
50
  methods: ["GET", "POST"],
15
51
  },
16
52
  });
17
- var sessions = new Map();
18
- var tables = new Map();
19
- var matches = new Map();
53
+ var users = new Map(); // sessionId, user
54
+ var tables = new Map(); // sessionId, table
55
+ var turns = new Map(); // sessionId, play instance
56
+ var getUser = function (session) {
57
+ var user = users.get(session);
58
+ if (user) {
59
+ return user;
60
+ }
61
+ throw new Error("User not found");
62
+ };
63
+ var getTable = function (matchSessionId) {
64
+ var table = tables.get(matchSessionId);
65
+ if (table) {
66
+ return table;
67
+ }
68
+ throw new Error("Match Session not found");
69
+ };
20
70
  io.on("connection", function (_socket) {
21
71
  var socket = _socket;
72
+ var getTableSockets = function (table, callback) {
73
+ return new Promise(function (resolve) { return __awaiter(void 0, void 0, void 0, function () {
74
+ var sockets, _i, sockets_1, socket_1;
75
+ return __generator(this, function (_a) {
76
+ switch (_a.label) {
77
+ case 0: return [4 /*yield*/, io.sockets.adapter.fetchSockets({
78
+ rooms: new Set([table.matchSessionId]),
79
+ })];
80
+ case 1:
81
+ sockets = _a.sent();
82
+ _i = 0, sockets_1 = sockets;
83
+ _a.label = 2;
84
+ case 2:
85
+ if (!(_i < sockets_1.length)) return [3 /*break*/, 5];
86
+ socket_1 = sockets_1[_i];
87
+ return [4 /*yield*/, callback(socket_1)];
88
+ case 3:
89
+ _a.sent();
90
+ _a.label = 4;
91
+ case 4:
92
+ _i++;
93
+ return [3 /*break*/, 2];
94
+ case 5:
95
+ resolve();
96
+ return [2 /*return*/];
97
+ }
98
+ });
99
+ }); });
100
+ };
101
+ var emitMatchUpdate = function (table) {
102
+ table.lobby.players.map(function (player) {
103
+ var user = users.get(player.session);
104
+ if (user && user.socketId) {
105
+ io.to(user.socketId).emit(types_1.EServerEvent.UPDATE_MATCH, table.getPublicMatch(player.session));
106
+ }
107
+ });
108
+ };
22
109
  socket.on(types_1.EClientEvent.PING, function (msg) {
23
110
  socket.emit(types_1.EServerEvent.PONG, msg);
24
111
  });
112
+ /**
113
+ * Create Match
114
+ */
25
115
  socket.on(types_1.EClientEvent.CREATE_MATCH, function (callback) {
26
- var _a;
27
- if ((_a = socket.user) === null || _a === void 0 ? void 0 : _a.session) {
28
- var trucoshi = (0, lib_1.Trucoshi)();
29
- tables.set(socket.user.session, trucoshi);
30
- return callback({ success: true });
116
+ if (socket.session) {
117
+ try {
118
+ var user = getUser(socket.session);
119
+ var existingTable = tables.get(socket.session);
120
+ if (existingTable) {
121
+ return callback({
122
+ success: false,
123
+ match: existingTable.getPublicMatch(socket.session),
124
+ });
125
+ }
126
+ var table = (0, MatchTable_1.MatchTable)(socket.session);
127
+ table.lobby.addPlayer(user.id, socket.session);
128
+ tables.set(socket.session, table);
129
+ return callback({ success: true, match: table.getPublicMatch(user.id) });
130
+ }
131
+ catch (e) {
132
+ console.error("ERROR", e);
133
+ return callback({ success: false, error: e });
134
+ }
31
135
  }
32
- callback({ success: false });
136
+ callback({ success: false, error: new Error("Can't create match without an ID") });
33
137
  });
34
- socket.on(types_1.EClientEvent.START_MATCH, function () {
35
- var _a, _b;
36
- if ((_a = socket.user) === null || _a === void 0 ? void 0 : _a.session) {
37
- var table = tables.get((_b = socket.user) === null || _b === void 0 ? void 0 : _b.session);
38
- if (table) {
39
- matches.set(socket.user.session, table.startMatch());
138
+ var sendWaitingForPlay = function (table, session, play) { return __awaiter(void 0, void 0, void 0, function () {
139
+ return __generator(this, function (_a) {
140
+ switch (_a.label) {
141
+ case 0: return [4 /*yield*/, getTableSockets(table, function (playerSocket) { return __awaiter(void 0, void 0, void 0, function () {
142
+ return __generator(this, function (_a) {
143
+ playerSocket.emit(types_1.EServerEvent.UPDATE_MATCH, table.getPublicMatch(playerSocket.session));
144
+ return [2 /*return*/];
145
+ });
146
+ }); })];
147
+ case 1:
148
+ _a.sent();
149
+ return [4 /*yield*/, getTableSockets(table, function (playerSocket) {
150
+ return new Promise(function (resolve) {
151
+ if (playerSocket.session === session) {
152
+ playerSocket.emit(types_1.EServerEvent.WAITING_PLAY, table.getPublicMatch(session));
153
+ playerSocket.once(types_1.EClientEvent.PLAY, function (_a) {
154
+ var cardIdx = _a.cardIdx, command = _a.command;
155
+ if (cardIdx !== undefined) {
156
+ var playedCard = play.use(cardIdx);
157
+ if (playedCard) {
158
+ return resolve();
159
+ }
160
+ return console.error("ERROR", new Error("Couldnt play card"));
161
+ }
162
+ if (command) {
163
+ var saidCommand = play.say(command);
164
+ if (saidCommand) {
165
+ return resolve();
166
+ }
167
+ return console.error("ERROR", new Error("Couldnt say command"));
168
+ }
169
+ return console.error("ERROR", new Error("Play callback didn't have data"));
170
+ });
171
+ }
172
+ else {
173
+ resolve();
174
+ }
175
+ });
176
+ })];
177
+ case 2:
178
+ _a.sent();
179
+ return [2 /*return*/];
180
+ }
181
+ });
182
+ }); };
183
+ var startMatch = function () { return __awaiter(void 0, void 0, void 0, function () {
184
+ var tableId_1, table_1;
185
+ return __generator(this, function (_a) {
186
+ try {
187
+ tableId_1 = socket.session;
188
+ table_1 = getTable(tableId_1);
189
+ if (table_1 && !table_1.lobby.gameLoop) {
190
+ table_1.setState(MatchTable_1.EMatchTableState.STARTED);
191
+ table_1.lobby
192
+ .startMatch()
193
+ .onTurn(function (play) {
194
+ return new Promise(function (resolve) { return __awaiter(void 0, void 0, void 0, function () {
195
+ var session, user, e_1;
196
+ var _a;
197
+ return __generator(this, function (_b) {
198
+ switch (_b.label) {
199
+ case 0:
200
+ table_1.setCurrentPlayer(play.player);
201
+ turns.set(tableId_1, { play: play, resolve: resolve });
202
+ _b.label = 1;
203
+ case 1:
204
+ _b.trys.push([1, 3, , 4]);
205
+ session = (_a = play.player) === null || _a === void 0 ? void 0 : _a.session;
206
+ if (!session) {
207
+ throw new Error("Unexpected Error");
208
+ }
209
+ user = users.get(session);
210
+ if (!user) {
211
+ throw new Error("Unexpected Error");
212
+ }
213
+ return [4 /*yield*/, sendWaitingForPlay(table_1, session, play)];
214
+ case 2:
215
+ _b.sent();
216
+ resolve();
217
+ return [3 /*break*/, 4];
218
+ case 3:
219
+ e_1 = _b.sent();
220
+ console.error("ERROR", e_1);
221
+ return [3 /*break*/, 4];
222
+ case 4: return [2 /*return*/];
223
+ }
224
+ });
225
+ }); });
226
+ })
227
+ .onTruco(function (play) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
228
+ return [2 /*return*/];
229
+ }); }); })
230
+ .onWinner(function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
231
+ return [2 /*return*/];
232
+ }); }); })
233
+ .begin();
234
+ return [2 /*return*/, tables.set(socket.session, table_1)];
235
+ }
236
+ console.error("ASL:KDJALSk");
237
+ }
238
+ catch (e) {
239
+ console.error("ERROR", e);
40
240
  }
241
+ return [2 /*return*/];
242
+ });
243
+ }); };
244
+ /**
245
+ * Start Match
246
+ */
247
+ socket.on(types_1.EClientEvent.START_MATCH, function () {
248
+ if (socket.session && users.has(socket.session)) {
249
+ startMatch();
41
250
  }
42
251
  });
43
- socket.on(types_1.EClientEvent.SET_SESSION, function (session, id, callback) {
44
- var _a;
45
- if ((_a = socket.user) === null || _a === void 0 ? void 0 : _a.session) {
46
- socket.user.id = id;
47
- return callback({ success: true });
252
+ /**
253
+ * Join Match
254
+ */
255
+ socket.on(types_1.EClientEvent.JOIN_MATCH, function (matchSessionId, callback) {
256
+ if (!socket.session) {
257
+ return callback({ success: false });
48
258
  }
49
- var storedSession = sessions.get(session);
50
- if (storedSession) {
51
- storedSession.id = id;
52
- socket.user = storedSession;
53
- return callback({ success: true });
259
+ var user = getUser(socket.session);
260
+ var table = tables.get(matchSessionId);
261
+ if (table && table.state === MatchTable_1.EMatchTableState.UNREADY) {
262
+ table.lobby.addPlayer(user.id || "satoshi", socket.session);
263
+ emitMatchUpdate(table);
264
+ return callback({ success: true, match: table.getPublicMatch(socket.session) });
265
+ }
266
+ callback({ success: false });
267
+ });
268
+ /**
269
+ * Get Match
270
+ */
271
+ socket.on(types_1.EClientEvent.GET_MATCH, function (matchSessionId, callback) {
272
+ var table = tables.get(matchSessionId);
273
+ if (table) {
274
+ return callback({ success: true, match: table.getPublicMatch(socket.session) });
275
+ }
276
+ callback({ success: false });
277
+ });
278
+ /**
279
+ * Set Session
280
+ */
281
+ socket.on(types_1.EClientEvent.SET_SESSION, function (session, id, callback) {
282
+ if (id === void 0) { id = "satoshi"; }
283
+ var user = users.get(session);
284
+ if (user) {
285
+ var updatedUser = {
286
+ id: id,
287
+ socketId: socket.id,
288
+ };
289
+ users.set(session, updatedUser);
290
+ socket.session = session;
291
+ tables.forEach(function (table, id) { return __awaiter(void 0, void 0, void 0, function () {
292
+ var _a, play, resolve, session_1, user_2, e_2;
293
+ var _b, _c;
294
+ return __generator(this, function (_d) {
295
+ switch (_d.label) {
296
+ case 0:
297
+ if (!table.isSessionPlaying(session)) return [3 /*break*/, 5];
298
+ socket.join(id);
299
+ if (!(session === ((_b = table.currentPlayer) === null || _b === void 0 ? void 0 : _b.session))) return [3 /*break*/, 4];
300
+ _d.label = 1;
301
+ case 1:
302
+ _d.trys.push([1, 3, , 4]);
303
+ _a = turns.get(id) || {}, play = _a.play, resolve = _a.resolve;
304
+ session_1 = (_c = play === null || play === void 0 ? void 0 : play.player) === null || _c === void 0 ? void 0 : _c.session;
305
+ if (!play || !session_1) {
306
+ throw new Error("Unexpected Error");
307
+ }
308
+ user_2 = users.get(session_1);
309
+ if (!user_2) {
310
+ throw new Error("Unexpected Error");
311
+ }
312
+ return [4 /*yield*/, sendWaitingForPlay(table, session_1, play)];
313
+ case 2:
314
+ _d.sent();
315
+ resolve === null || resolve === void 0 ? void 0 : resolve();
316
+ return [3 /*break*/, 4];
317
+ case 3:
318
+ e_2 = _d.sent();
319
+ console.error("ERROR", e_2);
320
+ return [3 /*break*/, 4];
321
+ case 4:
322
+ socket.emit(types_1.EServerEvent.UPDATE_MATCH, table.getPublicMatch(session));
323
+ _d.label = 5;
324
+ case 5: return [2 /*return*/];
325
+ }
326
+ });
327
+ }); });
328
+ return callback({ success: true, session: session });
54
329
  }
55
330
  var newSession = (0, crypto_1.randomUUID)();
56
- socket.user = (0, user_1.User)(id, newSession);
57
- sessions.set(newSession, socket.user);
58
- return callback({ success: true, session: newSession });
331
+ socket.session = newSession;
332
+ users.set(newSession, (0, user_1.User)(id, socket.id));
333
+ callback({ success: true, session: newSession });
334
+ });
335
+ /**
336
+ * Set Player Ready
337
+ */
338
+ socket.on(types_1.EClientEvent.SET_PLAYER_READY, function (matchSessionId, ready) {
339
+ try {
340
+ var table = getTable(matchSessionId);
341
+ var player = table.lobby.players.find(function (player) { return player.session === socket.session; });
342
+ if (player) {
343
+ player.setReady(ready);
344
+ if (ready) {
345
+ socket.join(matchSessionId);
346
+ }
347
+ emitMatchUpdate(table);
348
+ }
349
+ }
350
+ catch (e) {
351
+ console.error("ERROR", e);
352
+ }
59
353
  });
60
354
  });
61
355
  httpServer.listen(PORT);
@@ -1,16 +1,33 @@
1
1
  import { Socket } from "socket.io";
2
- import { IUser } from "./classes/user";
2
+ import { ECommand } from "../lib/types";
3
3
  export declare enum EClientEvent {
4
4
  PING = "PING",
5
+ PLAY = "PLAY",
5
6
  CREATE_MATCH = "CREATE_MATCH",
7
+ GET_MATCH = "GET_MATCH",
6
8
  JOIN_MATCH = "JOIN_MATCH",
7
9
  START_MATCH = "START_MATCH",
8
- SET_USER_ID = "SET_USER_ID",
10
+ SET_PLAYER_READY = "SET_PLAYER_READY",
9
11
  SET_SESSION = "SET_SESSION"
10
12
  }
11
13
  export declare enum EServerEvent {
12
- PONG = "PONG"
14
+ PONG = "PONG",
15
+ UPDATE_MATCH = "UPDATE_MATCH",
16
+ WAITING_PLAY = "WAITING_PLAY"
13
17
  }
14
18
  export interface TrucoshiSocket extends Socket {
15
- user?: IUser;
19
+ session?: string;
16
20
  }
21
+ export declare enum ETrucoshiMatchState {
22
+ UNREADY = 0,
23
+ STARTED = 1,
24
+ FINISHED = 2
25
+ }
26
+ export type IWaitingPlayData = {
27
+ cardIdx: number;
28
+ command?: undefined;
29
+ } | {
30
+ cardIdx?: undefined;
31
+ command: ECommand;
32
+ };
33
+ export type IWaitingPlayCallback = (data: IWaitingPlayData) => void | null;
@@ -1,16 +1,26 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EServerEvent = exports.EClientEvent = void 0;
3
+ exports.ETrucoshiMatchState = exports.EServerEvent = exports.EClientEvent = void 0;
4
4
  var EClientEvent;
5
5
  (function (EClientEvent) {
6
6
  EClientEvent["PING"] = "PING";
7
+ EClientEvent["PLAY"] = "PLAY";
7
8
  EClientEvent["CREATE_MATCH"] = "CREATE_MATCH";
9
+ EClientEvent["GET_MATCH"] = "GET_MATCH";
8
10
  EClientEvent["JOIN_MATCH"] = "JOIN_MATCH";
9
11
  EClientEvent["START_MATCH"] = "START_MATCH";
10
- EClientEvent["SET_USER_ID"] = "SET_USER_ID";
12
+ EClientEvent["SET_PLAYER_READY"] = "SET_PLAYER_READY";
11
13
  EClientEvent["SET_SESSION"] = "SET_SESSION";
12
14
  })(EClientEvent = exports.EClientEvent || (exports.EClientEvent = {}));
13
15
  var EServerEvent;
14
16
  (function (EServerEvent) {
15
17
  EServerEvent["PONG"] = "PONG";
18
+ EServerEvent["UPDATE_MATCH"] = "UPDATE_MATCH";
19
+ EServerEvent["WAITING_PLAY"] = "WAITING_PLAY";
16
20
  })(EServerEvent = exports.EServerEvent || (exports.EServerEvent = {}));
21
+ var ETrucoshiMatchState;
22
+ (function (ETrucoshiMatchState) {
23
+ ETrucoshiMatchState[ETrucoshiMatchState["UNREADY"] = 0] = "UNREADY";
24
+ ETrucoshiMatchState[ETrucoshiMatchState["STARTED"] = 1] = "STARTED";
25
+ ETrucoshiMatchState[ETrucoshiMatchState["FINISHED"] = 2] = "FINISHED";
26
+ })(ETrucoshiMatchState = exports.ETrucoshiMatchState || (exports.ETrucoshiMatchState = {}));
@@ -40,13 +40,13 @@ var lib_1 = require("../lib");
40
40
  (function () { return __awaiter(void 0, void 0, void 0, function () {
41
41
  var trucoshi;
42
42
  return __generator(this, function (_a) {
43
- trucoshi = (0, lib_1.Trucoshi)();
44
- trucoshi.addPlayer("lukini").setReady(true);
45
- trucoshi.addPlayer("denoph").setReady(true);
46
- trucoshi.addPlayer("guada").setReady(true);
47
- trucoshi.addPlayer("juli").setReady(true);
48
- trucoshi.addPlayer("day").setReady(true);
49
- trucoshi.addPlayer("fran").setReady(true);
43
+ trucoshi = (0, lib_1.Lobby)();
44
+ trucoshi.addPlayer("lukini", "lukini").setReady(true);
45
+ trucoshi.addPlayer("denoph", "denoph").setReady(true);
46
+ trucoshi.addPlayer("guada", "guada").setReady(true);
47
+ trucoshi.addPlayer("juli", "juli").setReady(true);
48
+ trucoshi.addPlayer("day", "day").setReady(true);
49
+ trucoshi.addPlayer("fran", "fran").setReady(true);
50
50
  trucoshi
51
51
  .startMatch()
52
52
  .onTurn(function (play) { return __awaiter(void 0, void 0, void 0, function () {
package/dist/test/play.js CHANGED
@@ -158,11 +158,11 @@ var sayCommand = function (play, canPlay) {
158
158
  (function () { return __awaiter(void 0, void 0, void 0, function () {
159
159
  var trucoshi;
160
160
  return __generator(this, function (_a) {
161
- trucoshi = (0, lib_1.Trucoshi)();
162
- trucoshi.addPlayer("lukini", 0).setReady(true);
163
- trucoshi.addPlayer("guada", 0).setReady(true);
164
- trucoshi.addPlayer("denoph", 1).setReady(true);
165
- trucoshi.addPlayer("juli", 1).setReady(true);
161
+ trucoshi = (0, lib_1.Lobby)();
162
+ trucoshi.addPlayer("lukini", "lukini").setReady(true);
163
+ trucoshi.addPlayer("denoph", "denoph").setReady(true);
164
+ trucoshi.addPlayer("guada", "guada").setReady(true);
165
+ trucoshi.addPlayer("juli", "juli").setReady(true);
166
166
  trucoshi
167
167
  .startMatch()
168
168
  .onTruco(function (play) { return __awaiter(void 0, void 0, void 0, function () {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trucoshi",
3
- "version": "0.0.13",
3
+ "version": "0.0.15",
4
4
  "main": "build/lib/trucoshi.js",
5
5
  "license": "GPL-3.0",
6
6
  "scripts": {