Skip to content

Commit

Permalink
feat: system events, document checking, etc. (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
Stuyk authored May 22, 2024
1 parent 472fbcc commit e3cc199
Show file tree
Hide file tree
Showing 15 changed files with 264 additions and 17 deletions.
11 changes: 11 additions & 0 deletions docs/api/server/document/document-account.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@ const someAccountData = someDatabaseFetchOrCreateFunction();
const document = Rebar.document.account.useAccountBinder(player).bind(someAccountData);
```

## Checking Validity

If you need to check if a player has a document bound to them, you can use the following method.

```ts
if (!Rebar.document.account.useAccount(player).isValid()) {
// No account bound
return;
}
```

## Getting Data

Data can be retrieved for the bound account like this.
Expand Down
11 changes: 11 additions & 0 deletions docs/api/server/document/document-character.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@ const someCharacterData = someDatabaseFetchOrCreateFunction();
const document = Rebar.document.character.useCharacterBinder(player).bind(someCharacterData);
```

## Checking Validity

If you need to check if a player has a document bound to them, you can use the following method.

```ts
if (!Rebar.document.character.useCharacter(player).isValid()) {
// No character bound
return;
}
```

## Getting Data

Data can be retrieved for the bound character like this.
Expand Down
11 changes: 11 additions & 0 deletions docs/api/server/document/document-vehicle.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@ const someVehicleData = someDatabaseFetchOrCreateFunction();
const document = Rebar.document.vehicle.useVehicleBinder(someVehicle).bind(someVehicleData);
```

## Checking Validity

If you need to check if a vehicle has a document bound to them, you can use the following method.

```ts
if (!Rebar.document.vehicle.useVehicle(player).isValid()) {
// No vehicle document bound
return;
}
```

## Getting Data

Data can be retrieved for the bound character like this.
Expand Down
32 changes: 32 additions & 0 deletions docs/api/server/events/events.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Events

These events are unique to the Rebar framework, and help provide information about when something happens.

## Usage

```ts
import { useRebar } from '@Server/index.js';

const Rebar = useRebar();
const RebarEvents = Rebar.events.useEvents();

// Called when an account is bound to a player
RebarEvents.on('account-bound', (player, document) => {
console.log(document);
});

// Called when a character is bound to a player
RebarEvents.on('character-bound', (player, document) => {
console.log(document);
});

// Called when a vehicle document is bound to a vehicle
RebarEvents.on('vehicle-bound', (vehicle, document) => {
console.log(document);
});

// Called when a player sends a message
RebarEvents.on('message', (player, msg) => {
console.log(msg);
});
```
3 changes: 3 additions & 0 deletions docs/api/server/events/index.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
expanded: false
label: 'Events'
order: -1000
12 changes: 12 additions & 0 deletions docs/api/server/player/player-status.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Check

Check if a player has an account bound, or character bound.

```ts
import { useRebar } from '@Server/index.js';

const Rebar = useRebar();

Rebar.player.useStatus(somePlayer).hasCharacter(); // Returns true / false
Rebar.player.useStatus(somePlayer).hasAccount(); // Returns true / false
```
20 changes: 20 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,26 @@ order: -1000

# Changelog

## Version 5

### Code Changes

- Added `isValid` to `character`, `account`, and `vehicle` documents to check if an entity has a bound document
- Added `useStatus` to `player` API pathway to check for `account` and `character` status
- Added `events` to the `Rebar` API
- Added on account bound
- Added on character bound
- Added on vehicle bound
- Added on message
- Fixed small bug with case-sensitive commands
- Fixed bug that allowed sending messages when a `character` was not bound

### Docs Changes

- Added `isValid` examples to `character`, `account`, and `vehicle`.
- Added `useStatus` to `player` section
- Added `events` section to Server API

## Version 4

### Code Changes
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"author": "stuyk",
"type": "module",
"version": "4",
"version": "5",
"scripts": {
"clean": "shx rm -rf resources/core",
"dev": "nodemon -V -x pnpm start",
Expand Down
31 changes: 30 additions & 1 deletion src/main/server/document/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,29 @@ import { useDatabase } from '@Server/database/index.js';
import { CollectionNames, KeyChangeCallback } from './shared.js';
import { Character } from '@Shared/types/character.js';
import { usePermission } from '@Server/systems/permission.js';
import { useRebar } from '../index.js';

const Rebar = useRebar();
const sessionKey = 'document:account';
const callbacks: { [key: string]: Array<KeyChangeCallback> } = {};
const db = useDatabase();

export function useAccount(player: alt.Player) {
/**
* Check if the player currently has an account bound to them
*/
function isValid() {
if (!player.hasMeta(sessionKey)) {
return false;
}

if (!player.getMeta(sessionKey)) {
return false;
}

return true;
}

/**
* Return current player data and their associated account object.
*
Expand Down Expand Up @@ -220,7 +237,18 @@ export function useAccount(player: alt.Player) {
setBanned,
};

return { addPermission, get, getCharacters, getField, permission, set, setBulk, setPassword, checkPassword };
return {
addPermission,
get,
getCharacters,
getField,
isValid,
permission,
set,
setBulk,
setPassword,
checkPassword,
};
}

export function useAccountBinder(player: alt.Player) {
Expand All @@ -237,6 +265,7 @@ export function useAccountBinder(player: alt.Player) {
}

player.setMeta(sessionKey, document);
Rebar.events.useEvents().invoke('account-bound', player, document);
return useAccount(player);
}

Expand Down
20 changes: 19 additions & 1 deletion src/main/server/document/character.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,29 @@ import { CollectionNames, KeyChangeCallback } from './shared.js';
import { Vehicle } from 'main/shared/types/vehicle.js';
import { usePermission } from '@Server/systems/permission.js';
import { usePermissionGroup } from '@Server/systems/permissionGroup.js';
import { useRebar } from '../index.js';

const Rebar = useRebar();
const sessionKey = 'document:character';
const callbacks: { [key: string]: Array<KeyChangeCallback> } = {};
const db = useDatabase();

export function useCharacter(player: alt.Player) {
/**
* Check if the player currently has a character bound to them
*/
function isValid() {
if (!player.hasMeta(sessionKey)) {
return false;
}

if (!player.getMeta(sessionKey)) {
return false;
}

return true;
}

/**
* Return current player data and their associated character object.
*
Expand Down Expand Up @@ -270,7 +287,7 @@ export function useCharacter(player: alt.Player) {
hasGroupPermission,
};

return { get, getField, getVehicles, permission, set, setBulk };
return { get, getField, isValid, getVehicles, permission, set, setBulk };
}

export function useCharacterBinder(player: alt.Player) {
Expand All @@ -287,6 +304,7 @@ export function useCharacterBinder(player: alt.Player) {
}

player.setMeta(sessionKey, document);
Rebar.events.useEvents().invoke('character-bound', player, document);
return useCharacter(player);
}

Expand Down
20 changes: 19 additions & 1 deletion src/main/server/document/vehicle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,29 @@ import { Vehicle } from '@Shared/types/vehicle.js';
import { KnownKeys } from '@Shared/utilityTypes/index.js';
import { useDatabase } from '@Server/database/index.js';
import { CollectionNames, KeyChangeCallback } from './shared.js';
import { useRebar } from '../index.js';

const Rebar = useRebar();
const sessionKey = 'document:vehicle';
const callbacks: { [key: string]: Array<KeyChangeCallback<alt.Vehicle>> } = {};
const db = useDatabase();

export function useVehicle(vehicle: alt.Vehicle) {
/**
* Check if the vehicle currently has a character bound to them
*/
function isValid() {
if (!vehicle.hasMeta(sessionKey)) {
return false;
}

if (!vehicle.getMeta(sessionKey)) {
return false;
}

return true;
}

/**
* Return current vehicle data and their associated Vehicle object.
*
Expand Down Expand Up @@ -117,7 +134,7 @@ export function useVehicle(vehicle: alt.Vehicle) {
});
}

return { get, getField, set, setBulk };
return { get, getField, isValid, set, setBulk };
}

export function useVehicleBinder(vehicle: alt.Vehicle) {
Expand All @@ -134,6 +151,7 @@ export function useVehicleBinder(vehicle: alt.Vehicle) {
}

vehicle.setMeta(sessionKey, document);
Rebar.events.useEvents().invoke('vehicle-bound', vehicle, document);
return useVehicle(vehicle);
}

Expand Down
39 changes: 39 additions & 0 deletions src/main/server/events/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import * as alt from 'alt-server';
import { Account } from '@Shared/types/account.js';
import { Character } from '@Shared/types/character.js';
import { Vehicle } from '@Shared/types/vehicle.js';

type RebarEvents = {
'account-bound': (player: alt.Player, document: Account) => void;
'character-bound': (player: alt.Player, document: Character) => void;
'vehicle-bound': (vehicle: alt.Vehicle, document: Vehicle) => void;
message: (player: alt.Player, message: string) => void;
};

type EventCallbacks<K extends keyof RebarEvents> = { [key in K]: RebarEvents[K][] };

const eventCallbacks: EventCallbacks<keyof RebarEvents> = {
'account-bound': [],
'character-bound': [],
'vehicle-bound': [],
message: [],
};

export function useEvents() {
function on<K extends keyof RebarEvents>(event: K, callback: RebarEvents[K]) {
eventCallbacks[event].push(callback);
}

function invoke<K extends keyof RebarEvents>(event: K, ...args: Parameters<RebarEvents[K]>) {
for (let cb of eventCallbacks[event]) {
// Normally I would not do this but I know this works, and TypeScript is being a jerk.
// @ts-ignore
cb(...args);
}
}

return {
invoke,
on,
};
}
Loading

0 comments on commit e3cc199

Please sign in to comment.