# NoteBook

> **Escrow note:** This resource is designed to be delivered via **CFX Escrow**, so your customers typically **cannot read/modify the server.lua/client.lua/JS/**. The only customer-editable file is the config (`Configs/shared.lua`).\
> This documentation explains **exactly what the script does** and **how to use it** as an end user / server owner.

***

### What this script does

**codex\_notebook** adds an in-game **notebook UI (NUI)** that players can open using a **usable inventory item**. Players can type notes into multiple pages and **save them permanently**. When they open the notebook later, their saved pages are loaded back automatically.

#### Player flow (in-game)

1. Player uses the notebook item (default: `notebook`).
2. Script checks if the player has the required item (default: `pen`).
3. If the player has a pen → the notebook UI opens.
4. The UI loads saved pages from the database.
5. Player edits pages and presses **Save**.
6. Pages are stored in the database under the player’s **character identifier** (fallback: user identifier).

***

### Features

* **Book-style UI** with page flipping and a page counter (“Spread X / Y”).
* **Editable pages** (`contenteditable`) for free-form text/notes.
* **Save** button to persist all pages.
* **Close** button + **Escape key** to close the UI.
* **Database-backed storage** (JSON-encoded pages), loaded automatically when opened.
* **Pen requirement**: prevents using the notebook without the configured required item (default: pen).

***

### Requirements / Dependencies

#### Required dependency: `codex_core`

The server script loads CodexCore via:

* `exports['codex_core']:getLibServer()`

And expects CodexCore to provide:

* `RegisterUsableItem(itemName, cb)` – registers a usable inventory item.
* `CloseInventory(source)` – closes inventory before opening the notebook UI.
* `ExecuteSql(query, params)` – runs SQL queries for save/load.
* `GetCharacterIdentifier(source)` – returns a character identifier (preferred).
* `GetUserIdentifier(source)` – fallback identifier if character id is unavailable.
* (Recommended) `GetItemCount(source, itemName)` – used to check for required items.

CodexCore documentation link (reference only):

* <https://codexstudios.gitbook.io/codexstudios-store/codex-docs/redm-resources/codexcore>

> **Important:** This notebook resource includes a small “inventory adapter” that currently checks for everything above and `CodexCore.GetItemCount.` &#x20;

***

### Installation (server owner)

1. Ensure **`codex_core` starts before `codex_notebook`** in your server config.
2. Ensure your database is connected and CodexCore SQL functions are working.
3. Create the required database table (see below).
4. Add the notebook and pen items to your inventory system:
   * Notebook item name (default): `notebook`
   * Required item name (default): `pen`

***

### Configuration (customer-editable)

File: `Configs/shared.lua`

```lua
Config = {
    ItemName = "notebook",
    ItemNeeded = "pen"
}
```

#### What these values mean

* `Config.ItemName`: the item that should open the notebook.
* `Config.ItemNeeded`: the required item that must be present (pen) to open/write.

> DO NOT CHANGE THE ITEM NAME AND THE ITEMNEEDED ITEM NAME!

***

### Database

#### Table used

* **Table:** `codex_notebooks`
* **Key column:** `char_identifier`
* **Data column:** `pages` (JSON string)

#### Required behavior

Saving uses an **UPSERT** statement:

* `INSERT ... ON DUPLICATE KEY UPDATE ...`

That means `char_identifier` **must be UNIQUE or PRIMARY KEY**.

#### &#x20;SQL (MySQL/MariaDB)

```sql
CREATE TABLE IF NOT EXISTS codex_notebooks (
  char_identifier VARCHAR(64) NOT NULL,
  pages LONGTEXT NOT NULL,
  PRIMARY KEY (char_identifier)
);
```

***

### Events & Data Flow (developer-friendly)

#### Server → Client

* `codex_notebook:openFromItem`\
  Tells the client to open the NUI.
* `codex_notebook:load (pages)`\
  Sends decoded pages array to the client (which forwards it to the UI).
* `codex_notebook:notify (text, duration, type)`\
  Sends a notification to the client (client forwards to `codex-core:notification`).

#### Client → Server

* `codex_notebook:save (pages)`\
  Saves pages for the player key (character/user id).
* `codex_notebook:request`\
  Requests saved pages; server responds with `codex_notebook:load`.

#### NUI callbacks (UI → Client)

* `requestNotebook` → client triggers `codex_notebook:request`
* `saveNotebook` → client triggers `codex_notebook:save` with `{ pages = [...] }`
* `close` → closes UI focus

***

### How customers use it (end-user instructions)

#### Opening the notebook

1. Put the **notebook item** in your inventory.
2. Put the **pen item** in your inventory.
3. Use the notebook item (from your inventory, depending on your framework).
4. The notebook UI appears.

If you don’t have a pen, you will see:

* “You need a pen to write in the notebook.”

#### Writing & saving

* Click into any page and type.
* Use the arrows to flip pages.
* Press **Save** to store your notes.
* Press **Close** (or hit **Escape**) to exit.

***

### Examples (RP-friendly)

#### Example 1: Personal journal

* Spread 1: “Day 1 – arriving in Valentine…”
* Spread 2: “People met / debts owed / leads…”

#### Example 2: Lawman case notes

* Left: suspect list + descriptions
* Right: witness statements + locations

#### Example 3: Trading / crafting checklist

* Ingredients to buy
* Prices seen in different towns
* Delivery drop-offs

***

### Troubleshooting

#### Notebook doesn’t open

Check:

* The usable item exists and matches the script (default is `notebook`).
* You have the required item (default is `pen`).
* `codex_core` is started before this resource.
* Your CodexCore build supports the inventory check method (`GetItemCount`) or the resource was adapted to your inventory.

#### Notes don’t save / don’t load

Check:

* The `codex_notebooks` table exists.
* `char_identifier` is UNIQUE/PRIMARY KEY.
* CodexCore database connectivity works and `ExecuteSql` is functional.

***

### Security & privacy notes

* Notes are saved server-side in the database under the player’s character/user key.
* Because saving uses JSON and `innerHTML`, notes are considered user-generated content.

***

### Changelog / Support&#x20;

* Resource: `codex_notebook`
* Support: discord.gg/gMzg84SFup
