Skip to content
Snippets Groups Projects
Commit ee29e3c6 authored by Samuli Virtapohja's avatar Samuli Virtapohja
Browse files

Merge branch 'group-fix' into HEAD

parents 506079bd 79e8dcfd
No related branches found
No related tags found
3 merge requests!59Development to master,!31Development,!28Group fix
...@@ -7,12 +7,19 @@ import { ...@@ -7,12 +7,19 @@ import {
Body, Body,
Get, Get,
Put, Put,
UseInterceptors,
ClassSerializerInterceptor,
} from '@nestjs/common'; } from '@nestjs/common';
import { AuthGuard } from '../shared/auth.guard'; import { AuthGuard } from '../shared/auth.guard';
import { ValidationPipe } from '../shared/validation.pipe'; import { ValidationPipe } from '../shared/validation.pipe';
import { User } from '../user/user.decorator'; import { User } from '../user/user.decorator';
import { GameGroupDTO, PromotePlayerDTO, JoinFactionDTO } from './faction.dto'; import {
GameGroupDTO,
PromotePlayerDTO,
JoinFactionDTO,
JoinGameGroupDTO,
} from './faction.dto';
import { FactionService } from './faction.service'; import { FactionService } from './faction.service';
import { Roles } from '../shared/roles.decorator'; import { Roles } from '../shared/roles.decorator';
...@@ -20,8 +27,9 @@ import { Roles } from '../shared/roles.decorator'; ...@@ -20,8 +27,9 @@ import { Roles } from '../shared/roles.decorator';
export class FactionController { export class FactionController {
constructor(private factionservice: FactionService) {} constructor(private factionservice: FactionService) {}
@Post(':id') // takes gameId from the url to verify user role
@UseGuards(new AuthGuard()) @Post('create-group/:id')
@Roles('soldier')
@UsePipes(new ValidationPipe()) @UsePipes(new ValidationPipe())
async createGroup( async createGroup(
@User('id') person, @User('id') person,
...@@ -33,17 +41,24 @@ export class FactionController { ...@@ -33,17 +41,24 @@ export class FactionController {
} catch (error) {} } catch (error) {}
} }
@Get('get-groups') // id is faction ID
async getGroups() { @Get('get-groups/:id')
return this.factionservice.showGroups(); async getGroups(@Param('id') id) {
return this.factionservice.showGroups(id);
} }
@Put('groups/:id') // takes gameId from the url to verify user role
@UseGuards(new AuthGuard()) @Put('join-group/:id')
async joinGroup(@User('id') person, @Param('id') id) { @Roles('soldier')
return this.factionservice.joinGroup(person, id); async joinGroup(
@User('id') person,
@Param('id') id,
@Body() data: JoinGameGroupDTO,
) {
return this.factionservice.joinGroup(person, id, data);
} }
@UseInterceptors(ClassSerializerInterceptor)
@Get('get-faction-members/:id') @Get('get-faction-members/:id')
async getFactionMembers(@Param('id') factionId) { async getFactionMembers(@Param('id') factionId) {
return this.factionservice.listFactionMembers(factionId); return this.factionservice.listFactionMembers(factionId);
......
...@@ -9,6 +9,7 @@ import { ...@@ -9,6 +9,7 @@ import {
import { GameEntity } from '../game/game.entity'; import { GameEntity } from '../game/game.entity';
import { RoleValidation } from '../shared/custom-validation'; import { RoleValidation } from '../shared/custom-validation';
import { GameDTO } from '../game/game.dto'; import { GameDTO } from '../game/game.dto';
import { FactionEntity, GameGroupEntity } from './faction.entity';
export class FactionDTO { export class FactionDTO {
@IsString() @IsString()
...@@ -40,4 +41,11 @@ export class GameGroupDTO { ...@@ -40,4 +41,11 @@ export class GameGroupDTO {
@IsString() @IsString()
@Length(3, 31) @Length(3, 31)
name: string; name: string;
@IsUUID('4')
faction: FactionEntity;
}
export class JoinGameGroupDTO {
@IsUUID('4')
groupId: GameGroupEntity;
} }
...@@ -6,11 +6,13 @@ import { ...@@ -6,11 +6,13 @@ import {
ManyToOne, ManyToOne,
OneToOne, OneToOne,
Timestamp, Timestamp,
JoinColumn,
} from 'typeorm'; } from 'typeorm';
import { GameEntity } from '../game/game.entity'; import { GameEntity } from '../game/game.entity';
import { Game_PersonEntity } from '../game/game.entity'; import { Game_PersonEntity } from '../game/game.entity';
import { MapDrawingEntity } from '../draw/coordinate.entity'; import { MapDrawingEntity } from '../draw/coordinate.entity';
import { Exclude } from 'class-transformer';
//Faction, PowerUp, Faction_powerUp, FP_History, Score //Faction, PowerUp, Faction_powerUp, FP_History, Score
...@@ -18,9 +20,12 @@ import { MapDrawingEntity } from '../draw/coordinate.entity'; ...@@ -18,9 +20,12 @@ import { MapDrawingEntity } from '../draw/coordinate.entity';
export class FactionEntity { export class FactionEntity {
@PrimaryGeneratedColumn('uuid') factionId: string; @PrimaryGeneratedColumn('uuid') factionId: string;
@Column('text') factionName: string; @Column('text') factionName: string;
@Column({ type: 'text' }) factionPassword: string;
@Column({ type: 'float' }) multiplier: number; @Column({ type: 'float' }) multiplier: number;
@Exclude()
@Column({ type: 'text' })
factionPassword: string;
@OneToMany(type => Game_PersonEntity, game_persons => game_persons.faction) @OneToMany(type => Game_PersonEntity, game_persons => game_persons.faction)
game_persons: Game_PersonEntity[]; game_persons: Game_PersonEntity[];
@ManyToOne(type => GameEntity, game => game.factions) @ManyToOne(type => GameEntity, game => game.factions)
...@@ -91,12 +96,12 @@ export class GameGroupEntity { ...@@ -91,12 +96,12 @@ export class GameGroupEntity {
@OneToOne(type => Game_PersonEntity, person => person.leaderGroup, { @OneToOne(type => Game_PersonEntity, person => person.leaderGroup, {
onDelete: 'CASCADE', onDelete: 'CASCADE',
}) })
//@JoinColumn({name:'leader'}) @JoinColumn({ name: 'leader' })
leader: Game_PersonEntity; leader: Game_PersonEntity;
@OneToMany(type => Game_PersonEntity, person => person.group, { @OneToMany(type => Game_PersonEntity, person => person.group, {
onDelete: 'CASCADE', onDelete: 'CASCADE',
}) })
players: Game_PersonEntity[]; players: Game_PersonEntity[];
@ManyToOne(type => GameEntity, game => game.groups) @ManyToOne(type => FactionEntity, faction => faction.factionId)
game: GameEntity; faction: FactionEntity;
} }
import { Injectable, HttpException, HttpStatus } from '@nestjs/common'; import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm'; import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm'; import { Repository, Not } from 'typeorm';
import { FactionEntity, GameGroupEntity } from './faction.entity'; import { FactionEntity, GameGroupEntity } from './faction.entity';
import { JoinFactionDTO, GameGroupDTO } from './faction.dto'; import { JoinFactionDTO, GameGroupDTO, JoinGameGroupDTO } from './faction.dto';
import { Game_PersonEntity } from '../game/game.entity'; import { Game_PersonEntity } from '../game/game.entity';
@Injectable() @Injectable()
...@@ -64,11 +64,18 @@ export class FactionService { ...@@ -64,11 +64,18 @@ export class FactionService {
// checks the password, creates an entry in GamePerson table with associated role&faction // checks the password, creates an entry in GamePerson table with associated role&faction
async createGroup(person, gameId, groupData: GameGroupDTO) { async createGroup(person, gameId, groupData: GameGroupDTO) {
// check if the person already is in a group in this game // get gamePerson ref
const checkDuplicate = await this.game_PersonRepository.findOne({ const gamePerson = await this.game_PersonRepository.findOne({
person: person, person: person,
game: gameId,
}); });
if (checkDuplicate) { // check if the authenticated person already belongs to a group
if (
await this.game_PersonRepository.findOne({
group: Not(null),
person: person,
})
) {
throw new HttpException( throw new HttpException(
'You already belong to a group!', 'You already belong to a group!',
HttpStatus.BAD_REQUEST, HttpStatus.BAD_REQUEST,
...@@ -78,56 +85,46 @@ export class FactionService { ...@@ -78,56 +85,46 @@ export class FactionService {
// create a group entry and insert it to db // create a group entry and insert it to db
const group = await this.game_GroupRepository.create({ const group = await this.game_GroupRepository.create({
...groupData, ...groupData,
game: gameId, leader: gamePerson,
}); });
const gameGroup = await this.game_GroupRepository.insert(group); const gameGroup = await this.game_GroupRepository.insert(group);
// create game_Person entry and insert it to db // update the gamePerson entry with group data
const gamePerson = await this.game_PersonRepository.create({ gamePerson.group = gamePerson.leaderGroup = gameGroup.identifiers[0]['id'];
role: 'soldier', await this.game_PersonRepository.save(gamePerson);
faction: null,
game: gameId,
person: person,
leaderGroup: gameGroup.identifiers[0]['id'],
group: gameGroup.identifiers[0]['id'],
});
await this.game_PersonRepository.insert(gamePerson);
return { return {
message: 'created new group', message: 'created new group',
}; };
} }
async showGroups() { async showGroups(factionId) {
return await this.game_GroupRepository.find({ return await this.game_GroupRepository.find({
relations: ['leader', 'players', 'game'], relations: ['leader', 'players'],
where: { faction: factionId },
}); });
} }
async joinGroup(person, groupId) { async joinGroup(person, gameId, data: JoinGameGroupDTO) {
const gameData = await this.game_GroupRepository.findOne({ const gamePerson = await this.game_PersonRepository.findOne({
where: { id: groupId },
relations: ['players', 'game'],
});
const gamePerson = await this.game_PersonRepository.create({
role: 'soldier',
faction: null,
game: gameData.game,
person: person, person: person,
leaderGroup: null, game: gameId,
group: groupId,
}); });
await this.game_PersonRepository.insert(gamePerson); gamePerson.group = data.groupId;
await this.game_PersonRepository.save(gamePerson);
return { return {
message: 'Joined group', message: 'Joined group',
}; };
} }
async listFactionMembers(faction) { async listFactionMembers(faction) {
return await this.game_PersonRepository.find({ const members = await this.game_PersonRepository.find({
where: { faction }, where: { faction },
relations: ['person'], relations: ['person'],
order: { person: 'DESC' },
}); });
members.sort(function(a, b) {
return a['person']['name'].localeCompare(b['person']['name']);
});
return members;
} }
} }
...@@ -7,6 +7,8 @@ import { ...@@ -7,6 +7,8 @@ import {
Param, Param,
UsePipes, UsePipes,
Put, Put,
UseInterceptors,
ClassSerializerInterceptor,
} from '@nestjs/common'; } from '@nestjs/common';
import { GameService } from './game.service'; import { GameService } from './game.service';
...@@ -39,6 +41,8 @@ export class GameController { ...@@ -39,6 +41,8 @@ export class GameController {
return this.gameservice.listGames(); return this.gameservice.listGames();
} }
// ClassSerializerInterceptor removes excluded columns set in Entities
@UseInterceptors(ClassSerializerInterceptor)
@Get(':id') @Get(':id')
async returnGameInfo(@Param('id') id: string) { async returnGameInfo(@Param('id') id: string) {
return this.gameservice.returnGameInfo(id); return this.gameservice.returnGameInfo(id);
......
...@@ -31,8 +31,6 @@ export class GameEntity { ...@@ -31,8 +31,6 @@ export class GameEntity {
factions: FactionEntity[]; factions: FactionEntity[];
@OneToMany(type => Game_PersonEntity, game_persons => game_persons.game) @OneToMany(type => Game_PersonEntity, game_persons => game_persons.game)
game_persons: Game_PersonEntity[]; game_persons: Game_PersonEntity[];
@OneToMany(type => GameGroupEntity, group => group.game)
groups: GameGroupEntity[];
@OneToMany( @OneToMany(
type => ObjectivePointEntity, type => ObjectivePointEntity,
objective_points => objective_points.game, objective_points => objective_points.game,
...@@ -48,7 +46,11 @@ export class GameEntity { ...@@ -48,7 +46,11 @@ export class GameEntity {
} }
// table that stores players associated with particular game // table that stores players associated with particular game
@Entity('Game_Person') @Entity('Game_Person', {
orderBy: {
person: 'ASC',
},
})
export class Game_PersonEntity { export class Game_PersonEntity {
@PrimaryGeneratedColumn('uuid') gamepersonId: string; @PrimaryGeneratedColumn('uuid') gamepersonId: string;
@Column({ type: 'text', nullable: true }) role: string; @Column({ type: 'text', nullable: true }) role: string;
...@@ -61,7 +63,6 @@ export class Game_PersonEntity { ...@@ -61,7 +63,6 @@ export class Game_PersonEntity {
@OneToOne(type => GameGroupEntity, group => group.leader, { @OneToOne(type => GameGroupEntity, group => group.leader, {
onDelete: 'CASCADE', onDelete: 'CASCADE',
}) })
@JoinColumn({ name: 'leaderGroup' })
leaderGroup: GameGroupEntity; leaderGroup: GameGroupEntity;
@ManyToOne(type => GameGroupEntity, group => group.players, { @ManyToOne(type => GameGroupEntity, group => group.players, {
onDelete: 'CASCADE', onDelete: 'CASCADE',
......
...@@ -132,6 +132,10 @@ export class GameService { ...@@ -132,6 +132,10 @@ export class GameService {
where: { id: id }, where: { id: id },
relations: ['factions', 'objective_points'], relations: ['factions', 'objective_points'],
}); });
// sort factions by their name
game.factions.sort(function(a, b) {
return a['factionName'].localeCompare(b['factionName']);
});
return game; return game;
} }
......
...@@ -46,7 +46,6 @@ export class TaskService { ...@@ -46,7 +46,6 @@ export class TaskService {
async editTask(data: EditTaskDTO) { async editTask(data: EditTaskDTO) {
const task = await this.taskRepository.findOne(data.taskId); const task = await this.taskRepository.findOne(data.taskId);
console.log(task);
// checks if task is already closed // checks if task is already closed
if (!task.taskIsActive) { if (!task.taskIsActive) {
throw new HttpException('Task is not active', HttpStatus.BAD_REQUEST); throw new HttpException('Task is not active', HttpStatus.BAD_REQUEST);
......
...@@ -9,12 +9,16 @@ import * as bcrypt from 'bcryptjs'; ...@@ -9,12 +9,16 @@ import * as bcrypt from 'bcryptjs';
import * as jwt from 'jsonwebtoken'; import * as jwt from 'jsonwebtoken';
import { Game_PersonEntity } from '../game/game.entity'; import { Game_PersonEntity } from '../game/game.entity';
import { Exclude } from 'class-transformer';
@Entity('Person') @Entity('Person')
export class PersonEntity { export class PersonEntity {
@PrimaryGeneratedColumn('uuid') id: string; @PrimaryGeneratedColumn('uuid') id: string;
@Column({ type: 'text', unique: true }) name: string; @Column({ type: 'text', unique: true }) name: string;
@Column('text') password: string;
@Exclude()
@Column('text')
password: string;
@OneToMany(type => Game_PersonEntity, game_persons => game_persons.person) @OneToMany(type => Game_PersonEntity, game_persons => game_persons.person)
game_persons: Game_PersonEntity[]; game_persons: Game_PersonEntity[];
...@@ -31,12 +35,6 @@ export class PersonEntity { ...@@ -31,12 +35,6 @@ export class PersonEntity {
return { name, token }; return { name, token };
} }
// returns username and the id
nameObject() {
const { id, name } = this;
return { id, name };
}
async comparePassword(attempt: string) { async comparePassword(attempt: string) {
return await bcrypt.compareSync(attempt, this.password); return await bcrypt.compareSync(attempt, this.password);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment