Skip to content

Commit

Permalink
Merge pull request #276 from RSamaium/v4.2.0
Browse files Browse the repository at this point in the history
V4.2.0
  • Loading branch information
RSamaium authored Dec 9, 2023
2 parents dcefcd5 + edbab50 commit b7e910c
Show file tree
Hide file tree
Showing 76 changed files with 33,572 additions and 2,147 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ docs/others/*
!docs/api/readme.md
!docs/others/readme.md
cache
packages/**/browser
packages/**/browser
vitest.config.ts.timestamp*
32 changes: 30 additions & 2 deletions docs/.vitepress/config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
const apiMenu = [
{
text: 'Functions',
collapsed: false,
sidebarDepth: 2,
items: [
{ text: "inject()", link: "/functions/inject" },
]

},
{
text: 'Classes Server-Side',
collapsed: false,
Expand Down Expand Up @@ -29,11 +38,27 @@ const apiMenu = [
{ text: "GUI Class", link: "/classes/gui" },
{ text: "Sound Class", link: "/classes/sound" },
{ text: "Resource Class", link: "/classes/resource" },
{ text: "Keyboard Class", link: "/classes/keyboard" },
{ text: "Vue Inject Class", link: "/classes/vue-inject" }
{ text: "Keyboard Class", link: "/classes/keyboard" }
]

},
{
text: 'VueJS',
collapsed: false,
sidebarDepth: 2,
items: [
{ text: "Vue Inject Class", link: "/classes/vue-inject" },
{ text: "Vue directives", link: "/api-gui/vue-directive" }
]
},
{
text: 'React',
collapsed: false,
sidebarDepth: 2,
items: [
{ text: "React Hooks", link: "/api-gui/react" }
]
},
{
text: 'Testing',
collapsed: false,
Expand Down Expand Up @@ -168,6 +193,7 @@ const guideMenu = [{
text: 'Advanced',
collapsed: false,
items: [
{ text: "Create Authentication System", link: "/advanced/auth" },
{ text: "Synchronization between Server and Client", link: "/guide/synchronization" },
{ text: "Creating a plugin", link: "/advanced/create-plugin" },
{ text: "Using Agones for Game Server Hosting", link: "/advanced/agones" },
Expand Down Expand Up @@ -237,10 +263,12 @@ module.exports = {
}
],
sidebar: {
'/functions/': apiMenu,
'/classes/': apiMenu,
'/commands/': apiMenu,
'/database/': apiMenu,
'/api/': apiMenu,
'/api-gui/': apiMenu,
'/guide/': guideMenu,
'/gui/': guideMenu,
'/advanced/': guideMenu,
Expand Down
119 changes: 119 additions & 0 deletions docs/advanced/auth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# `auth` Hook Documentation

## Overview

The `auth` hook in RPGJS is a authenticating players in your game. This document provides a comprehensive guide on how to implement and use the `auth` hook in the RPGJS project.

::: tip Info
Authentication in RPGJS is agnostic, in the sense that you can make it work with any authentication system. It's not tied to any database or third-party system. You're free to implement your own logic. This is useful for MMORPGs.
Below is an example with a JWT.
:::

## Implementation

In your `main/server.ts` file, follow these steps to set up the `auth` hook:

### Step 1: Import Required Modules

Import the necessary modules from `@rpgjs/server`:

```typescript
import { RpgServerEngineHooks, RpgServerEngine } from '@rpgjs/server';
```

### Step 2: Define the `auth` Hook

Implement the `auth` hook within the `RpgServerEngineHooks`:

```typescript
const server: RpgServerEngineHooks = {
auth(server: RpgServerEngine, socket) {
// Authentication logic goes here
}
};

export default server;
```

#### Functionality

- The `auth` hook must return a `Promise<string>`, a `string`, or throw an error.
- If a `string` is returned, and the ID **public** matches, the player is considered connected.
- If the hook throws an error, it indicates that the player is not authenticated.

#### Parameters

- `server`: An instance of `RpgServerEngine`.
- `socket`: The `socket.io` object. You can access various request headers using `socket.handshake.headers`.

## Client-Side Error Handling

To handle errors on the client side, such as those thrown during the authentication process, implement the `onConnectError` hook in your `main/client.ts` file.

### Step 1: Import Required Modules

Import the necessary modules from `@rpgjs/client`:

```typescript
import { RpgClientEngineHooks, RpgClientEngine } from "@rpgjs/client";
```

### Step 2: Define the `onConnectError` Hook

Implement the `onConnectError` hook within the `RpgClientEngineHooks` to handle connection errors:

```typescript
const client: RpgClientEngineHooks = {
onConnectError(engine: RpgClientEngine, err: Error) {
console.log("Connection Error:", err.message);
}
};

export default client;
```

## JWT Example

### Step 1: Import Required Modules

Import necessary modules from `@rpgjs/server` and any other required libraries (like `jsonwebtoken` for decoding JWT):

```typescript
import { RpgServerEngineHooks, RpgServerEngine } from '@rpgjs/server';
import jwt from 'jsonwebtoken';
```

> Install `jsonwebtoken` using `npm install jsonwebtoken`.
### Step 2: Define the `auth` Hook with JWT Logic

Implement the `auth` hook to handle JWT verification:

```typescript
const server: RpgServerEngineHooks = {
auth(server: RpgServerEngine, socket) {
const token = socket.handshake.headers.authorization;
if (!token) {
throw 'No token provided';
}

// Replace 'YOUR_SECRET_KEY' with your actual secret key used to sign the JWT
const decoded = jwt.verify(token, 'YOUR_SECRET_KEY');
if (!decoded) {
throw 'Invalid token';
}

// Assuming 'decoded' contains a property 'id' representing the user ID
return decoded.id;
}
};

export default server;
```

::: tip Notes
- Ensure you replace `'YOUR_SECRET_KEY'` with the secret key you used to sign your JWTs.
- The JWT is expected to be in the `authorization` header of the socket handshake. Make sure this aligns with how your client is sending the token.
- The example assumes the JWT contains an `id` field representing the user ID. Adjust this according to your JWT structure.
- Proper error handling is crucial to inform the client about authentication failures.
:::
67 changes: 67 additions & 0 deletions docs/api-gui/react.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# React Hooks

## Introduction

React hooks are a powerful feature in React that allow you to use state and other React features without writing a class. In the context of RPGJS, a framework for creating RPG games, React hooks can be particularly useful for managing game state and interactions.

## 1. `useEventPropagator()`

This hook is used to propagate events within the canvas element of your RPGJS game.

### Importing

```javascript
import { useEventPropagator } from '@rpgjs/client/react';
```

### Usage

```javascript
export default function Test() {
const propagate = useEventPropagator();

return <div ref={propagate}>test</div>;
}
```

In this example, the `useEventPropagator` hook is used to create a `propagate` function. This function is then passed to a `div` element as a reference (`ref`). This setup allows events within the `div` to be propagated through the RPGJS game canvas.

---

## 2. `RpgReactContext`

This hook provides access to the RPGJS context, allowing you to interact with various game states like the current player's health points (HP).

### Importing

```javascript
import { RpgReactContext } from '@rpgjs/client/react';
import { useContext, useEffect, useState } from 'react';
```

### Usage

```javascript
export default function MyGUI({ foo }) {
const { rpgCurrentPlayer } = useContext(RpgReactContext);
const [hp, setHp] = useState(0);

useEffect(() => {
const subscription = rpgCurrentPlayer.subscribe(({ object }) => {
setHp(object.hp);
});

return () => {
subscription.unsubscribe();
};
}, []);

return (
<div>
<h1>{hp}</h1>
</div>
);
}
```

In this example, `RpgReactContext` is used to access the current player's state. The `useContext` hook retrieves the `rpgCurrentPlayer` from `RpgReactContext`. We then use `useState` to manage the player's HP locally. The `useEffect` hook is used to subscribe to changes in the player's HP, updating the local state accordingly. When the component unmounts, the subscription is unsubscribed.
17 changes: 17 additions & 0 deletions docs/api-gui/vue-directive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Directive for VueJS

## `v-propagate`

The `v-propagate` directive is straightforward to use. Simply add it to any element in your VueJS template to enable event propagation for that element within the RPGJS canvas.

### Example

```vue
<template>
<div v-propagate>
Test
</div>
</template>
```

In this example, the `v-propagate` directive is attached to a `div` element. Any events that occur within this `div` will be propagated through the RPGJS game canvas. This is particularly useful for integrating VueJS-based GUI elements with the RPGJS game canvas, allowing for seamless interaction between the GUI and the game.
40 changes: 40 additions & 0 deletions docs/functions/inject.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Using `inject` in RPGJS

The `inject` function in RPGJS is a powerful feature for dependency injection, allowing you to retrieve instances of various classes in both client and server environments.

## Client-Side Injection

To use `inject` on the client side, import it from `@rpgjs/client`. This allows you to retrieve singleton instances of classes such as `RpgClientEngine`, `KeyboardControls`, and `RpgRenderer`.

### Retrieving the `RpgClientEngine`

```typescript
import { inject, RpgClientEngine } from '@rpgjs/client'

const client = inject(RpgClientEngine)
```

This code imports `inject` and `RpgClientEngine` from `@rpgjs/client` and then uses `inject` to retrieve the `RpgClientEngine` instance.

### Injecting Other Classes

Similarly, you can inject other classes like `KeyboardControls` and `RpgRenderer`:

```typescript
import { inject, KeyboardControls, RpgRenderer } from '@rpgjs/client'

const controls = inject(KeyboardControls)
const renderer = inject(RpgRenderer)
```

## Server-Side Injection

For server-side injection, import `inject` from `@rpgjs/server`. This is typically used to retrieve the `RpgServerEngine`.

### Retrieving the `RpgServerEngine`

```typescript
import { inject, RpgServerEngine } from '@rpgjs/server'

const server = inject(RpgServerEngine)
```
9 changes: 7 additions & 2 deletions docs/guide/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,14 @@ Configuration properties related to the compiler.
[vite]
logLevel = "silent"
```
You can insert this section after the `vite` section in your `readme.md`.
> Please note that RPGJS contains configurations. You will therefore overwrite configurations ([the basic file is in the sources]([https://github.com/RSamaium/RPG-JS/blob/v4/packages/compiler/src/build/client-config.ts#L335])).

> Please note that RPGJS contains certain configurations. You will therefore overwrite certain configurations ([the basic file is in the sources]([https://github.com/RSamaium/RPG-JS/blob/v4/packages/compiler/src/build/client-config.ts#L335])).
- `vitest`: (*object*) All [Vitest configuration](https://vitest.dev/config/). Example:
```toml
[vitest]
silent = true
```
> You will therefore overwrite configurations ([the basic file is in the sources]([https://github.com/RSamaium/RPG-JS/blob/v4/packages/compiler/src/test/vitest.config.ts#L36])).

- `express`

Expand Down
16 changes: 15 additions & 1 deletion docs/guide/inputs.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,18 @@ The key corresponds to the type of control (used by the keyboard, the mouse, or

You have information here: [Set Inputs](/classes/keyboard.html#set-inputs)

> If you want to use keyboard numbers, don't use "1" but "n1", etc.
::: tip Keyboard numbers
If you want to use keyboard numbers, don't use "1" but "n1", etc.
:::

::: tip Mouse Events
Since v4.2.0, you can use mouse events.

Example:

```toml
[inputs.action]
name = "action"
bind = ["space", "enter", "click"],
```
:::
Loading

0 comments on commit b7e910c

Please sign in to comment.