Skip to content

Commit

Permalink
Merge pull request #1732 from gettakaro/main-promotion
Browse files Browse the repository at this point in the history
  • Loading branch information
niekcandaele authored Oct 29, 2024
2 parents 876c98f + 576023b commit b69ff46
Show file tree
Hide file tree
Showing 33 changed files with 1,318 additions and 458 deletions.
20 changes: 11 additions & 9 deletions packages/app-api/src/service/Shop/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,22 +50,24 @@ export class ShopListingService extends TakaroService<
const callingUserId = ctx.data.user;
if (!callingUserId) throw new errors.UnauthorizedError();

const userHasHighPrivileges = await this.userHasHighPrivileges();
if (userHasHighPrivileges) {
this.log.debug(`User ${callingUserId} has high privileges, skipping order ownership check`);
return;
}

const userRes = await new UserService(this.domainId).find({ filters: { playerId: [order.playerId] } });
if (!userRes.results.length) throw new errors.NotFoundError('User not found');
if (userRes.results.length > 1) throw new errors.BadRequestError('Multiple users found for player');

const belongsToUser = callingUserId && userRes.results[0].id === callingUserId;

if (!belongsToUser) {
const userHasHighPrivileges = await this.userHasHighPrivileges();

if (!userHasHighPrivileges) {
this.log.warn(`User ${callingUserId} tried to access order ${order.id} that does not belong to them`, {
orderId: order.id,
userId: callingUserId,
});
throw new errors.NotFoundError('Shop order not found');
}
this.log.warn(`User ${callingUserId} tried to access order ${order.id} that does not belong to them`, {
orderId: order.id,
userId: callingUserId,
});
throw new errors.NotFoundError('Shop order not found');
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/lib-apiclient/src/generated/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Takaro app-api
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: development - f80f6d034a7760e0429de59c786ff04802006bc9
* The version of the OpenAPI document: development - 5199f209d75d036de130cfd1481e036535ab4d80
* Contact: [email protected]
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
Expand Down
2 changes: 1 addition & 1 deletion packages/lib-apiclient/src/generated/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Takaro app-api
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: development - f80f6d034a7760e0429de59c786ff04802006bc9
* The version of the OpenAPI document: development - 5199f209d75d036de130cfd1481e036535ab4d80
* Contact: [email protected]
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
Expand Down
2 changes: 1 addition & 1 deletion packages/lib-apiclient/src/generated/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Takaro app-api
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: development - f80f6d034a7760e0429de59c786ff04802006bc9
* The version of the OpenAPI document: development - 5199f209d75d036de130cfd1481e036535ab4d80
* Contact: [email protected]
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
Expand Down
2 changes: 1 addition & 1 deletion packages/lib-apiclient/src/generated/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Takaro app-api
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: development - f80f6d034a7760e0429de59c786ff04802006bc9
* The version of the OpenAPI document: development - 5199f209d75d036de130cfd1481e036535ab4d80
* Contact: [email protected]
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
Expand Down
2 changes: 1 addition & 1 deletion packages/lib-apiclient/src/generated/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Takaro app-api
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: development - f80f6d034a7760e0429de59c786ff04802006bc9
* The version of the OpenAPI document: development - 5199f209d75d036de130cfd1481e036535ab4d80
* Contact: [email protected]
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ const defaultListItems = [
icon: <AiOutlineBook />,
title: 'Documentation',
description: 'Learn how to integrate our tools with your app',
to: 'docs.takaro.io',
to: 'https://docs.takaro.io',
},
{
icon: <AiOutlineMenu />,
Expand Down
48 changes: 46 additions & 2 deletions packages/lib-modules/scripts/buildBuiltinJson.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'reflect-metadata';
import { getModules } from '@takaro/modules';
import { writeFile } from 'fs/promises';
import { readdir, readFile } from 'node:fs/promises';
import { readdir, readFile, stat } from 'node:fs/promises';
import path from 'path';

const __dirname = path.dirname(new URL(import.meta.url).pathname);
Expand All @@ -12,7 +12,7 @@ async function main() {
const modules = getModules();
const modulesJson = JSON.stringify(modules, null, 2);
await writeFile('dist/modules.json', modulesJson);
await writeFile('../web-docs/docs/modules.json', modulesJson);
await writeFile('../web-docs/docs/modules/modules.json', modulesJson);
await writeFile('../e2e/src/web-main/fixtures/modules.json', modulesJson);

// Community modules
Expand All @@ -28,6 +28,50 @@ async function main() {
await writeFile('dist/community-modules.json', communityModulesJson);
await writeFile('../web-docs/docs/community-modules.json', communityModulesJson);
await writeFile('../e2e/src/web-main/fixtures/community-modules.json', communityModulesJson);

const startMarker = '{/* START AUTO-GENERATED CONTENT */}';
const endMarker = '{/* END AUTO-GENERATED CONTENT */}';

// Generate docs pages for each builtin module
for (const mod of modules) {
const fileExists = await stat(`../web-docs/docs/modules/${mod.name}.mdx`).catch(() => null);

const autoGeneratedContent = `${startMarker}
import { Commands, Config, CronJobs, Hooks } from './helpers';
# ${mod.name}
export function Module() {
const mod = ${JSON.stringify(mod, null, 2)};
return (
<div>
<p>{mod.description}</p>
<Commands commands={mod.commands} />
<CronJobs cronJobs={mod.cronJobs} />
<Hooks hooks={mod.hooks} />
<Config configSchema={mod.configSchema} />
</div>
)
}
<Module />
---
${endMarker}`;

// If file doesnt exist yet, create it
if (!fileExists) {
await writeFile(`../web-docs/docs/modules/${mod.name}.mdx`, autoGeneratedContent);
} else {
const existingFile = await readFile(`../web-docs/docs/modules/${mod.name}.mdx`, 'utf-8');
// Otherwise, fine the auto generated content markers and replace it
const end = existingFile.indexOf(endMarker) + endMarker.length;

const newFile = autoGeneratedContent + existingFile.slice(end);
await writeFile(`../web-docs/docs/modules/${mod.name}.mdx`, newFile);
}
}
}

main().catch(console.error);
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,29 @@ const tests = [
playerId: this.setupData.players[0].id,
});

expect(await events).to.have.length(2);
expect((await events)[0].data.meta.msg).to.equal('You have purchased Test item for 100 test coin.');
expect((await events)[1].data.meta.msg).to.equal('You have received items from a shop order.');
},
}),
new IntegrationTest<IShopSetup>({
group,
snapshot: false,
setup: shopSetup,
name: 'Can buy an item when not linked to a user',
test: async function () {
const events = (await new EventsAwaiter().connect(this.client)).waitForEvents(HookEvents.CHAT_MESSAGE, 2);
const unlinkedPlayer = this.setupData.players[1];
await this.client.playerOnGameserver.playerOnGameServerControllerAddCurrency(
this.setupData.gameserver.id,
unlinkedPlayer.id,
{ currency: 250 },
);
await this.client.command.commandControllerTrigger(this.setupData.gameserver.id, {
msg: '/shop 1 1 buy',
playerId: unlinkedPlayer.id,
});

expect(await events).to.have.length(2);
expect((await events)[0].data.meta.msg).to.equal('You have purchased Test item for 100 test coin.');
expect((await events)[1].data.meta.msg).to.equal('You have received items from a shop order.');
Expand Down
15 changes: 6 additions & 9 deletions packages/web-docs/docs/advanced/modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ sidebar_position: 1

The core of Takaro is built around Modules. Modules are a very powerful and flexible way of creating features..

Takaro comes with a set of [built-in modules](../built-in-modules.mdx). When you enable these on a Gameserver, you will be able to change the configuration of the module to customize it but you cannot edit the code. This allows Takaro to automatically keep the built-in modules up-to-date.
Takaro comes with a set of [built-in modules](../modules/overview.mdx). When you enable these on a Gameserver, you will be able to change the configuration of the module to customize it but you cannot edit the code. This allows Takaro to automatically keep the built-in modules up-to-date.

Each module consists of one or more of the following components:

Expand Down Expand Up @@ -44,12 +44,11 @@ These fields offer the flexibility to adjust module functionalities according to

For instance:

- The Geo block module includes a configuration field named `countryList`. This field allows you to specify which countries should be blocked form accessing.
By making the country list a configuration field you can dynamically adjust the list for each server you install the module on.
- The Geo block module includes a configuration field named `countryList`. This field allows you to specify which countries should be blocked form accessing.
By making the country list a configuration field you can dynamically adjust the list for each server you install the module on.

- The gimme module features an `itemList` configuration field. This enables the creation of a customizable list of items that can be awarded to players.
This means the item module remains game agnostic as the module itself has no static list.

This means the item module remains game agnostic as the module itself has no static list.

### Example

Expand All @@ -65,17 +64,15 @@ As a contrived example, a config like the following exists:
And a Hook on the event `playerConnected`, which fires whenever a Player connects to the Gameserver. The Function code:

```js

import { getTakaro } from '@takaro/helpers';

async function main() {
await takaro.gameserver.gameServerControllerSendMessage(data.gameServerId, {
message: `Welcome to the server, ${data.player.name}. ${data.module.userConfig.extraMessage}`,
await takaro.gameserver.gameServerControllerSendMessage(data.gameServerId, {
message: `Welcome to the server, ${data.player.name}. ${data.module.userConfig.extraMessage}`,
});
}

main();

```

Would result in a message in-game saying `Welcome to the server, John Doe! Don't forget to read the rules :)`
117 changes: 0 additions & 117 deletions packages/web-docs/docs/built-in-modules.mdx

This file was deleted.

11 changes: 8 additions & 3 deletions packages/web-docs/docs/economy.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,38 @@ sidebar_position: 5

Takaro allows users to enable an economy system on their server. This is a virtual currency system that allows users to earn and spend money on the server. This is a great way to encourage users to be active on the server and reward them for their activity.

Players can earn money in many ways using some of the [built-in modules](./built-in-modules.mdx) or you can create your own custom modules to allow players to earn money in other ways.
Players can earn money in many ways using some of the [built-in modules](./modules/overview.mdx) or you can create your own custom modules to allow players to earn money in other ways.

Currency is kept per gameserver, so if you have multiple gameservers, each gameserver will have its own currency. This makes it easier to balance the economy on each gameserver; you might want different prices on your PvP server than on your PvE server for example.

Do note that we have in global settings, an option to enable Economy. You can override the global settings in each gameserver setting.
Do note that we have in global settings, an option to enable Economy. You can override the global settings in each gameserver setting.

## Shop

Takaro offers a built-in shop system to complement the server's economy. This feature allows community managers to create shop listings where they can sell individual items or bundles at specified prices. Each game server can have its own unique shop.

To allow players to use the shop, they need to be linked to both Takaro and your game community. The player linking process is described in the [players](./players.md) section.

### Prerequisites

1. **Enable the economy** for your game server.
2. Ensure **players are linked** to both Takaro and your game community (see [players](./players.md) for details).
3. Install the built-in module, [EconomyUtils](./built-in-modules.mdx), on your game server.
3. Install the built-in module, [EconomyUtils](./modules/overview.mdx), on your game server.

### Shop Functionalities

- **Create Shop Listing**: Allows you to list items for sale, either individually or as packages. You can set the item quality and upload custom images for your listings.
- **Orders**: Provides an overview of the orders placed by players and their status.

### Claiming an Item

An item can be claimed in two ways:

- In Takaro, by going to "Orders" and clicking "Claim Item". You need to be in-game for this to work; otherwise, you'll receive an error message.
- In-game, by typing the command `/link`.

### In-Game Store

The shop can be accessed in-game using the command `/shop`. The structure works as follows:

- `/shop 1`: Shows the first page of items.
Expand Down
Loading

0 comments on commit b69ff46

Please sign in to comment.