Skip to content

Commit

Permalink
feat: implement permissions with count for teleports module (#671)
Browse files Browse the repository at this point in the history
  • Loading branch information
niekcandaele authored Nov 19, 2023
1 parent a266b54 commit 946773e
Show file tree
Hide file tree
Showing 12 changed files with 177 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ const tests = [
this.setupData.gameserver.id,
this.setupData.teleportsModule.id,
{
userConfig: JSON.stringify({ maxTeleports: 42, timeout: 1337 }),
userConfig: JSON.stringify({ timeout: 1337 }),
}
);

Expand All @@ -103,7 +103,6 @@ const tests = [

expect(res.data.data.userConfig).to.deep.equal({
allowPublicTeleports: false,
maxTeleports: 42,
timeout: 1337,
});

Expand Down
2 changes: 2 additions & 0 deletions packages/app-api/src/service/RoleService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,12 @@ export class ServiceRoleCreateInputDTO extends TakaroDTO<ServiceRoleCreateInputD

export class RoleUpdateInputDTO extends TakaroDTO<RoleUpdateInputDTO> {
@Length(3, 20)
@IsOptional()
name: string;

@ValidateNested({ each: true })
@Type(() => PermissionInputDTO)
@IsOptional()
permissions: PermissionInputDTO[];
}

Expand Down
4 changes: 2 additions & 2 deletions packages/lib-apiclient/src/generated/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4736,13 +4736,13 @@ export interface RoleUpdateInputDTO {
* @type {string}
* @memberof RoleUpdateInputDTO
*/
name: string;
name?: string;
/**
*
* @type {Array<PermissionInputDTO>}
* @memberof RoleUpdateInputDTO
*/
permissions: Array<PermissionInputDTO>;
permissions?: Array<PermissionInputDTO>;
}
/**
*
Expand Down
3 changes: 3 additions & 0 deletions packages/lib-apiclient/src/lib/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ export class Client extends BaseApiClient<IApiClientConfig> {
permissionId: p.id,
}));

if (records.length !== permissions.length)
throw new Error(`Not all permissions were found: ${permissions.join(', ')}`);

return records;
}

Expand Down
13 changes: 12 additions & 1 deletion packages/lib-function-helpers/src/checkPermission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,16 @@ export function checkPermission(player: any, permission: string) {
.flat()
.map((p: any) => p.permission);

return permissions.some((p: PermissionOutputDTO) => p.permission === permission || p.permission === 'ROOT');
const specificPerm = permissions.filter((p: PermissionOutputDTO) => p.permission === permission)[0];

if (specificPerm) {
// Find the assignment record so we can return count too
const role = roles.filter((r: any) => r.permissions.some((p: any) => p.permission.permission === permission))[0];
const assignment = role.permissions.find((p: any) => {
return p.permission.permission === permission;
});
return { ...specificPerm, count: assignment.count };
}
if (permissions.some((p: PermissionOutputDTO) => p.permission === 'ROOT')) return true;
return false;
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ const tests = [
setup: cleanRoleSetup,
name: 'Player has global role -> works',
test: async function () {
const useTeleportsRole = await this.client.permissionCodesToInputs(['TELEPORTS_USE']);
await this.client.role.roleControllerUpdate(this.setupData.role.id, {
permissions: [
{
permissionId: useTeleportsRole[0].permissionId,
count: 3,
},
],
});
await this.client.player.playerControllerAssignRole(this.setupData.players[0].id, this.setupData.role.id);

const setEvents = this.setupData.eventAwaiter.waitForEvents(GameEvents.CHAT_MESSAGE, 1);
Expand Down Expand Up @@ -83,6 +92,16 @@ const tests = [
setup: cleanRoleSetup,
name: 'Player has role on correct gameserver -> works',
test: async function () {
const useTeleportsRole = await this.client.permissionCodesToInputs(['TELEPORTS_USE']);
await this.client.role.roleControllerUpdate(this.setupData.role.id, {
permissions: [
{
permissionId: useTeleportsRole[0].permissionId,
count: 3,
},
],
});

await this.client.player.playerControllerAssignRole(this.setupData.players[0].id, this.setupData.role.id, {
gameServerId: this.setupData.gameserver.id,
});
Expand Down Expand Up @@ -119,11 +138,15 @@ const tests = [
})
);

const permissions = await this.client.permissionCodesToInputs(['TELEPORTS_USE']);
const playerRoleRes = await this.client.role.roleControllerSearch({ filters: { name: ['Player'] } });
const useTeleportsRole = await this.client.permissionCodesToInputs(['TELEPORTS_USE']);
await this.client.role.roleControllerUpdate(playerRoleRes.data.data[0].id, {
name: 'Player',
permissions,
permissions: [
{
permissionId: useTeleportsRole[0].permissionId,
count: 3,
},
],
});

const setTpEvent = this.setupData.eventAwaiter.waitForEvents(GameEvents.CHAT_MESSAGE, 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,14 @@ const tests = [
setup: modulesTestSetup,
name: 'If player does not have role to create public teleports, command gets denied',
test: async function () {
const permissions = await this.client.permissionCodesToInputs(['TELEPORTS_USE']);

const useTeleportsRole = await this.client.permissionCodesToInputs(['TELEPORTS_USE']);
await this.client.role.roleControllerUpdate(this.setupData.role.id, {
name: this.setupData.role.name,
permissions,
permissions: [
{
permissionId: useTeleportsRole[0].permissionId,
count: 3,
},
],
});

await this.client.gameserver.gameServerControllerInstallModule(
Expand Down Expand Up @@ -259,6 +262,85 @@ const tests = [
expect((await setPublicEvent)[0].data.msg).to.be.eq('You do not have permission to create public teleports.');
},
}),
new IntegrationTest<IModuleTestsSetupData>({
group,
snapshot: false,
setup: modulesTestSetup,
name: 'Prohibits players from settings more public teleports than their role allows',
test: async function () {
const permissionRes = await this.client.permissionCodesToInputs(['TELEPORTS_CREATE_PUBLIC', 'TELEPORTS_USE']);
await this.client.role.roleControllerUpdate(this.setupData.role.id, {
permissions: [
{
permissionId: permissionRes[0].permissionId,
count: 3,
},
{
permissionId: permissionRes[1].permissionId,
count: 5,
},
],
});

await this.client.gameserver.gameServerControllerInstallModule(
this.setupData.gameserver.id,
this.setupData.teleportsModule.id,
{
userConfig: JSON.stringify({
allowPublicTeleports: true,
timeout: 0,
}),
}
);

const setTpEvent = this.setupData.eventAwaiter.waitForEvents(GameEvents.CHAT_MESSAGE, 4);

await Promise.all(
Array.from({ length: 4 }).map(async (_, i) => {
return this.client.command.commandControllerTrigger(this.setupData.gameserver.id, {
msg: `/settp test${i}`,
playerId: this.setupData.players[0].id,
});
})
);

expect((await setTpEvent).length).to.be.eq(4);

for (const event of await setTpEvent) {
expect(event.data.msg).to.match(/Teleport test\d set\./);
}

const setPublicEvent = this.setupData.eventAwaiter.waitForEvents(GameEvents.CHAT_MESSAGE, 3);

await Promise.all(
Array.from({ length: 3 }).map(async (_, i) => {
return this.client.command.commandControllerTrigger(this.setupData.gameserver.id, {
msg: `/setpublic test${i}`,
playerId: this.setupData.players[0].id,
});
})
);

expect((await setPublicEvent).length).to.be.eq(3);

for (const event of await setPublicEvent) {
expect(event.data.msg).to.match(/Teleport test\d is now public\./);
}

const setPublicEvent2 = this.setupData.eventAwaiter.waitForEvents(GameEvents.CHAT_MESSAGE, 1);

await this.client.command.commandControllerTrigger(this.setupData.gameserver.id, {
msg: '/setpublic test4',
playerId: this.setupData.players[0].id,
});

expect((await setPublicEvent2).length).to.be.eq(1);

expect((await setPublicEvent2)[0].data.msg).to.be.eq(
'You have reached the maximum number of public teleports for your role, maximum allowed is 3'
);
},
}),
];

describe(group, function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,19 @@ const tests = [
test: async function () {
await this.client.gameserver.gameServerControllerInstallModule(
this.setupData.gameserver.id,
this.setupData.teleportsModule.id,
{
userConfig: JSON.stringify({ maxTeleports: 3 }),
}
this.setupData.teleportsModule.id
);

const useTeleportsRole = await this.client.permissionCodesToInputs(['TELEPORTS_USE']);
await this.client.role.roleControllerUpdate(this.setupData.role.id, {
permissions: [
{
permissionId: useTeleportsRole[0].permissionId,
count: 3,
},
],
});

const setEvents = this.setupData.eventAwaiter.waitForEvents(GameEvents.CHAT_MESSAGE, 3);

await Promise.all(
Expand All @@ -98,7 +106,7 @@ const tests = [

expect((await events).length).to.be.eq(1);
expect((await events)[0].data.msg).to.be.eq(
'You have reached the maximum number of teleports, maximum allowed is 3'
'You have reached the maximum number of teleports for your role, maximum allowed is 3'
);
},
}),
Expand Down
27 changes: 26 additions & 1 deletion packages/lib-modules/src/modules/teleports/commands/setpublic.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ async function main() {
return;
}

if (!checkPermission(player, 'TELEPORTS_CREATE_PUBLIC')) {
const hasPermission = checkPermission(player, 'TELEPORTS_CREATE_PUBLIC');

if (!hasPermission) {
await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {
message: 'You do not have permission to create public teleports.',
opts: {
Expand All @@ -25,6 +27,29 @@ async function main() {
return;
}

const existingTeleportsForPlayerRes = await takaro.variable.variableControllerSearch({
search: {
key: 'tp_',
},
filters: {
gameServerId: [gameServerId],
playerId: [player.playerId],
moduleId: [mod.moduleId],
},
});

const existingPublicTeleportsForPlayer = existingTeleportsForPlayerRes.data.data.filter((tp) => {
const teleport = JSON.parse(tp.value);
return teleport.public;
});

if (existingPublicTeleportsForPlayer.length >= hasPermission.count) {
await data.player.pm(
`You have reached the maximum number of public teleports for your role, maximum allowed is ${hasPermission.count}`
);
return;
}

const teleportRes = await takaro.variable.variableControllerSearch({
filters: {
gameServerId: [gameServerId],
Expand Down
8 changes: 5 additions & 3 deletions packages/lib-modules/src/modules/teleports/commands/settp.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ async function main() {

const { player, gameServerId, module: mod, arguments: args } = data;

if (!checkPermission(player, 'TELEPORTS_USE')) {
const hasPermission = checkPermission(player, 'TELEPORTS_USE');

if (!hasPermission) {
await takaro.gameserver.gameServerControllerSendMessage(gameServerId, {
message: 'You do not have permission to use teleports.',
opts: {
Expand Down Expand Up @@ -49,9 +51,9 @@ async function main() {
},
});

if (allPlayerTeleports.data.data.length >= mod.userConfig.maxTeleports) {
if (allPlayerTeleports.data.data.length >= hasPermission.count) {
await data.player.pm(
`You have reached the maximum number of teleports, maximum allowed is ${mod.userConfig.maxTeleports}`
`You have reached the maximum number of teleports for your role, maximum allowed is ${hasPermission.count}`
);
return;
}
Expand Down
8 changes: 1 addition & 7 deletions packages/lib-modules/src/modules/teleports/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@ export class Teleports extends BuiltinModule {
$schema: 'http://json-schema.org/draft-07/schema#',
type: 'object',
properties: {
maxTeleports: {
type: 'integer',
minimum: 1,
maximum: 50,
default: 5,
},
timeout: {
type: 'integer',
description: 'The time in milliseconds required between teleports',
Expand All @@ -26,7 +20,7 @@ export class Teleports extends BuiltinModule {
default: false,
},
},
required: ['maxTeleports'],
required: [],
additionalProperties: false,
})
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"gameserverId": "1225343a-ca6a-4d64-b2a9-c7d2d3cd8270",
"moduleId": "eacf283f-760b-4ed0-b55f-3e33db83c4b5",
"userConfig": {
"maxTeleports": 42,
"timeout": 1337,
"allowPublicTeleports": false
},
Expand Down

0 comments on commit 946773e

Please sign in to comment.