Skip to content

Commit df6d16b

Browse files
authored
Merge pull request #11 from x-team/main
Merging main
2 parents e5eac30 + 3b122cf commit df6d16b

39 files changed

+1268
-19
lines changed

.env.example

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# API
2+
HOST=0.0.0.0
3+
PORT=3010
4+
5+
# DATABASE
6+
DB_USERNAME=postgres
7+
DB_PASSWORD=*games-2021
8+
DB_NAME=gameshq_api
9+
DB_HOSTNAME=127.0.0.1
10+
DB_PORT=5434
11+
12+
# THE ARENA APP
13+
SLACK_ARENA_TOKEN=
14+
SLACK_ARENA_SIGNING_SECRET=
15+
# Private Channel
16+
SLACK_ARENA_XHQ_CHANNEL=
17+
18+
# CAMPAIGN APP
19+
SLACK_CAMPAIGN_SIGNING_SECRET=
20+
SLACK_CAMPAIGN_TOKEN=
21+
SLACK_NEUTRAL_ZONE_CHANNEL=
22+
23+
# THE TOWER APP
24+
SLACK_TOWER_SIGNING_SECRET=
25+
SLACK_TOWER_TOKEN=
26+
SLACK_THE_TOWER_CHANNEL=
27+
28+
# FRONT-END-APP
29+
FRONT_END_SIGNING_SECRET=
30+
FRONT_END_APP_BOT_TOKEN=
31+
32+
# FIREBASE
33+
GOOGLE_APPLICATION_CREDENTIALS="/path/to/yours/service/account/file/service-account-file.json"

.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
v16.10.0

package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,17 @@
3838
"license": "ISC",
3939
"dependencies": {
4040
"@hapi/boom": "9.1.2",
41+
"@hapi/catbox": "11.1.1",
42+
"@hapi/catbox-memory": "5.0.1",
4143
"@hapi/hapi": "20.1.5",
4244
"@hapi/inert": "6.0.3",
4345
"@hapi/vision": "6.1.0",
4446
"@slack/client": "5.0.2",
47+
"@types/catbox": "10.0.7",
48+
"@types/catbox-memory": "4.0.0",
4549
"dotenv": "10.0.0",
4650
"fast-safe-stringify": "2.0.7",
51+
"firebase-admin": "10.0.0",
4752
"hapi-swagger": "14.2.1",
4853
"indefinite": "2.4.1",
4954
"joi": "17.4.0",
@@ -59,6 +64,7 @@
5964
"devDependencies": {
6065
"@types/boom": "7.3.1",
6166
"@types/chai": "4.2.19",
67+
"@types/hapi__catbox-memory": "4.1.3",
6268
"@types/hapi__hapi": "20.0.9",
6369
"@types/hapi__inert": "5.2.3",
6470
"@types/hapi__vision": "5.5.3",

src/config/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ interface NameToType {
2525
SLACK_TOWER_SIGNING_SECRET: string;
2626
SLACK_CAMPAIGN_SIGNING_SECRET: string;
2727
SLACK_THE_TOWER_CHANNEL: string;
28+
FRONT_END_APP_BOT_TOKEN: string;
29+
FRONT_END_SIGNING_SECRET: string;
30+
GOOGLE_APPLICATION_CREDENTIALS: string;
2831
}
2932

3033
export function getConfig<T extends keyof NameToType>(name: T): NameToType[T];

src/games/arena/consts.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ export enum ARENA_HEALTHKITS {
110110
// REPOSITORIEs
111111
export const ARENA_REPOSITORY_NAME = 'arena-repository';
112112
export const ZONE_REPOSITORY_NAME = 'zone-repository';
113+
export const WEAPON_REPOSITORY_NAME = 'weapon-repository';
114+
export const ENEMY_REPOSITORY_NAME = 'enemy-repository';
113115

114116
// GAME
115117
export const SEARCH_WEAPONS_SUCCESS_RATE = 0.8;

src/games/arena/utils/index.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ import {
3535
ARENA_PLAYER_PERFORMANCE,
3636
ARENA_SECONDARY_ACTIONS,
3737
ChangeLocationParams,
38+
ENEMY_REPOSITORY_NAME,
39+
WEAPON_REPOSITORY_NAME,
3840
ZONE_REPOSITORY_NAME,
3941
} from '../consts';
4042
import {
@@ -243,6 +245,28 @@ export function withArenaTransaction<T>(fn: (transaction: Transaction) => Promis
243245
});
244246
}
245247

248+
export function withWeaponTransaction<T>(fn: (transaction: Transaction) => Promise<T>) {
249+
return withTransaction((transaction) => {
250+
return fn(transaction).catch(async (error) => {
251+
if (error instanceof GameError) {
252+
error.addRepository(WEAPON_REPOSITORY_NAME);
253+
}
254+
throw error;
255+
});
256+
});
257+
}
258+
259+
export function withEnemyTransaction<T>(fn: (transaction: Transaction) => Promise<T>) {
260+
return withTransaction((transaction) => {
261+
return fn(transaction).catch(async (error) => {
262+
if (error instanceof GameError) {
263+
error.addRepository(ENEMY_REPOSITORY_NAME);
264+
}
265+
throw error;
266+
});
267+
});
268+
}
269+
246270
export function withZoneTransaction<T>(fn: (transaction: Transaction) => Promise<T>) {
247271
return withTransaction((transaction) => {
248272
return fn(transaction).catch(async (error) => {

src/games/general/commands/index.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { getGameResponse } from '../../utils';
2+
import { GAMES_SLACK_COMMANDS } from '../consts';
3+
4+
import { register } from './register';
5+
6+
interface GamesHQSwitchCommandOptions {
7+
command: string;
8+
commandText: string;
9+
slackId: string;
10+
channelId: string;
11+
triggerId: string;
12+
}
13+
14+
export function gamesSwitchCommand({ command, slackId }: GamesHQSwitchCommandOptions) {
15+
switch (command) {
16+
// ADMIN
17+
case GAMES_SLACK_COMMANDS.REGISTER:
18+
return register(slackId);
19+
20+
default:
21+
return getGameResponse('Invalid command.');
22+
}
23+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import Boom from '@hapi/boom';
2+
3+
import { USER_ROLE_LEVEL } from '../../../consts/model';
4+
import { findOrganizationByName } from '../../../models/Organization';
5+
import { createUser, userExists } from '../../../models/User';
6+
import { getGameResponse, getSlackUserInfo } from '../../utils';
7+
8+
export const register = async (slackUserId: string) => {
9+
const exists = await userExists(slackUserId);
10+
if (exists) {
11+
return getGameResponse(`Your user is already registered.`);
12+
}
13+
14+
const xteamOrganization = await findOrganizationByName('x-team');
15+
const { user } = await getSlackUserInfo(slackUserId);
16+
17+
if (!user || !user.profile || !xteamOrganization) {
18+
throw Boom.badRequest(`Failed to create new user on GamesHQ.`);
19+
}
20+
const { profile } = user;
21+
const { email, image_512 } = profile;
22+
23+
await createUser({
24+
email: email,
25+
displayName: user.real_name,
26+
firebaseUserUid: null,
27+
profilePictureUrl: image_512,
28+
slackId: user.id,
29+
_teamId: null,
30+
_roleId: USER_ROLE_LEVEL.USER,
31+
_organizationId: xteamOrganization?.id,
32+
});
33+
34+
return getGameResponse(
35+
`Your e-mail _${email}_ is now registered to all our games :partyparrot: `
36+
);
37+
};

src/games/general/consts.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export enum GAMES_SLACK_COMMANDS {
2+
// USER COMMANDS
3+
REGISTER = '/games-register',
4+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { createOrUpdateArenaZone, deleteZoneById } from '../../../../models/ArenaZone';
2+
import { ARENA_ZONE_RING } from '../../../arena/consts';
3+
import { withZoneTransaction } from '../../../arena/utils';
4+
5+
export interface IZoneEditorData {
6+
id?: number;
7+
name: string;
8+
emoji: string;
9+
ring: string;
10+
isArchived: boolean;
11+
}
12+
13+
export const upsertZone = async (data: IZoneEditorData) => {
14+
return withZoneTransaction(async () => {
15+
const values = {
16+
...(data.id && { id: data.id }),
17+
name: data.name,
18+
emoji: data.emoji,
19+
isArchived: data.isArchived,
20+
ring: data.ring as ARENA_ZONE_RING,
21+
isActive: data.isArchived,
22+
};
23+
return createOrUpdateArenaZone(values);
24+
});
25+
};
26+
27+
export const deleteZone = async (zoneId: number) => {
28+
return withZoneTransaction(async (transaction) => {
29+
return deleteZoneById(zoneId, transaction);
30+
});
31+
};

0 commit comments

Comments
 (0)