1<div align="center">
2
3# ZnoteX
4
5<img width="114" height="30" alt="index_f089e12e" src="https://github.com/user-attachments/assets/8a521795-fb9b-48c3-877b-977bea4ca716" />
6
7
8**A complete website for your Open Tibia server.**
9
10Version 2.0.5 · Maintained by [Open Games Community](https://opengamescommunity.com)
11
12[Website](https://opengamescommunity.com) · [Source & releases](https://github.com/Open-Games-Community/ZnoteX) · [Themes](layouts/README.md) · [Plugins](plugins/README.md)
13
14[](https://www.codefactor.io/repository/github/open-games-community/znotex/overview/main)
15[](https://github.com/Open-Games-Community/ZnoteX/actions/workflows/php-compatibility.yml)
16
17</div>
18
19---
20
21## About
22
23ZnoteX is a full automatic account creator (AAC) and website for Open Tibia servers — account
24registration, character management, highscores, guilds, houses, a forum, a shop and an admin panel,
25all in one package. It is written in PHP with a simple procedural framework, so it is easy to read
26and easy to modify.
27
28The original ZnoteX went unmaintained for roughly five years. This repository picks the project
29back up rather than starting over — we think it is the strongest foundation among the available
30Open Tibia AAC projects, and we intend to keep building on it.
31
32---
33
34## Requirements
35
36| | |
37| --- | --- |
38| **PHP** | 8.1 or newer — 8.1, 8.2, 8.3, 8.4 and 8.5 all supported |
39| **Database** | MySQL or MariaDB |
40| **Required extension** | `mysqli` |
41| **Optional extensions** | `curl` (PayPal, reCaptcha, e-mail) · `openssl` (reCaptcha) · `gd` (guild images) · `apcu` (memory cache) |
42
43> PHP 8.0 and older are **not** supported and will be refused at startup.
44
45**Optional:** for e-mail verification and account recovery, download
46[PHPMailer 6.x](https://github.com/PHPMailer/PHPMailer/releases) and extract it into the ZnoteX
47directory as a folder named `PHPMailer`.
48
49---
50
51## Supported servers
52
53Set `$config['ServerEngine']` in `config.php` to match your server:
54
55| Server | `ServerEngine` |
56| --- | --- |
57| TFS 1.6 | `TFS_16` |
58| TFS 1.1 – 1.4.2 | `TFS_10` |
59| Canary / OTServBR-Global | `CANARY` |
60| TFS 0.3.6+ / 0.4 / OTX | `TFS_03` |
61| TFS 0.2.13+ | `TFS_02` |
62| OTHire | `OTHIRE` |
63
64TFS 1.0 is not supported.
65
66**Canary notes** — two-factor authentication is unavailable (Canary's account table has nowhere to
67store it), and the shop uses Znote's own points system rather than Canary coins.
68
69---
70
71## Web server stacks
72
73You need Apache (or nginx) + PHP 8.1+ + MySQL/MariaDB. On Windows, any of these bundles work — just
74make sure you grab a build that ships **PHP 8.1 or newer**.
75
76| Stack | Download | Why pick it |
77| --- | --- | --- |
78| **Uniform Server** (UniServerZ) | [uniformserver.com](https://www.uniformserver.com/) · [SourceForge](https://sourceforge.net/projects/miniserver/) | Portable and very light on resources. No installer — unzip and run, easy to move or back up. A great default for a home-hosted server. |
79| **XAMPP** | [apachefriends.org](https://www.apachefriends.org/) | The most popular and the easiest to set up. Includes phpMyAdmin. Changing PHP version means installing a different XAMPP build. |
80| **WampServer** | [wampserver.com](https://www.wampserver.com/) | The fastest of the three, and you can switch PHP/MySQL versions from the tray icon. **Heavy on RAM** — MySQL has been seen using 5 GB+. Only worth it if the machine has memory to spare. |
81
82On a Linux VPS or shared hosting you do not need any of these. Just set the hosting panel to PHP 8.1
83or newer (8.3 / 8.4 recommended).
84
85---
86
87## Installation
88
89### Docker (fastest way to try it)
90
91```
92git clone https://github.com/Open-Games-Community/ZnoteX.git
93cd ZnoteX
94cp .env.example .env
95docker compose up -d
96```
97
98That's it — open **http://localhost:8080**. The stack brings up:
99
100| Service | What it's for | Default URL |
101| --- | --- | --- |
102| **znotex** | PHP 8.5 + Apache, ZnoteX itself, Composer dependencies already installed | http://localhost:8080 |
103| **db** | MySQL 8.4, pre-loaded with a demo game schema matching `ZNOTE_SERVER_ENGINE` | localhost:3306 |
104| **phpmyadmin** | Browse the database | http://localhost:8081 |
105| **mailpit** | Every outgoing e-mail (registration, recovery, etc.) is caught here instead of actually sending | http://localhost:8025 |
106
107`ZNOTE_SERVER_ENGINE` in `.env` picks which game database gets imported on first boot, matching
108the same six choices the installer offers:
109
110| Value | Engine | Demo accounts/characters? |
111| --- | --- | --- |
112| `TFS_10` (default) | TFS 1.1 - 1.4.2 | Yes - account **`demo`** / password **`demo123`** already has admin panel access, with 3 demo characters |
113| `TFS_16` | TFS 1.6 | Schema only |
114| `CANARY` | Canary / OTServBR-Global | Schema only |
115| `TFS_03` | TFS 0.3.6+ / 0.4 / OTX | Schema only |
116| `TFS_02` | TFS 0.2.13+ | Falls back to the TFS_03 schema - no dedicated 0.2.x schema is bundled |
117| `OTHIRE` | OTHire | Schema only |
118
119Set it in `.env` **before** the first `docker compose up -d` — the schema is only imported once,
120into a fresh database volume. To switch engines afterward, `docker compose down -v` (this wipes
121the database) and start again. `config.local.php` is generated automatically from
122`docker-compose.yml`'s environment values on every container start — edit those instead of the
123file itself. Change ports or credentials in `.env` before the first start if the defaults collide
124with something else on your machine.
125
126This environment is for trying ZnoteX or developing on it — every bundled game schema is a demo,
127not a real Tibia server. Point `ZNOTE_DB_*` at your actual server's database for production use.
128
129### The installer
130
131Extract ZnoteX into your web directory and open **`/install/`** in a browser. Six steps:
132
133| | |
134| --- | --- |
135| **1. Requirements** | PHP version, `mysqli`, and whether `engine/cache/` is writable |
136| **2. Database** | Credentials, and a check that your **OT server's own schema is already imported** |
137| **3. Server** | Which engine this site sits in front of, the site name and its URL |
138| **4. Schema** | Imports `SQL/znote_schema.sql` — only the `znote_*` tables |
139| **5. Administrator** | Creates an account and a character, and remembers the name |
140| **6. Finish** | Writes `config.local.php` and locks the installer |
141
142**Import your OT server's schema first.** ZnoteX reads `accounts` and `players`; it has never
143created them and will not pretend to. Step 2 refuses to continue until they exist — importing
144TFS/Canary's own `schema.sql` afterwards would overwrite what the installer is about to write.
145
146Step 5 creates a real, working administrator: the account, a character on it, and the password
147hashed the way `login.php` expects on your engine. Step 6 puts that **account name** in
148`page_admin_access`, so you can reach `/admin/` the moment the installer finishes. It writes to
149**`config.local.php`**, not `config.php` — see below — though a checkbox on the last step will
150write the admin name into `config.php` instead if you prefer.
151
152When it is done, **delete the `install/` folder**. It refuses to run again on its own (step 6
153leaves a lock file), but there is no reason to leave it on a public server.
154
155### config.php and config.local.php
156
157`config.php` holds every default and every comment. `config.local.php` holds only what is
158specific to *this* install — database credentials, engine, site name, admin names — and is
159included last, so it wins.
160
161That split is what makes updating painless: a new ZnoteX release can ship a new `config.php`
162without touching your settings. **Keep `config.local.php` out of version control.**
163
164Most other settings are editable from **Admin Panel → Settings** without opening a file at all.
165
166### Installing by hand
167
168If you would rather not use the installer, or it cannot write the config file:
169
1701. Import your OT server's schema, then `SQL/znote_schema.sql`, into the same database.
1712. Create `config.local.php` next to `config.php`:
172
173```php
174<?php
175$config['sqlHost'] = '127.0.0.1';
176$config['sqlUser'] = 'your_db_user';
177$config['sqlPassword'] = 'your_db_password';
178$config['sqlDatabase'] = 'your_db_name';
179
180$config['ServerEngine'] = 'TFS_10'; // see "Supported servers" above
181$config['site_title'] = 'My Server';
182$config['site_url'] = 'https://example.com/';
183$config['page_admin_access'] = array('YourAccountName');
184```
185
1863. Make `engine/cache/` writable by the web server.
1874. Open the site. If anything is misconfigured, the page tells you what to fix.
188
189### Memory cache (APCu)
190
191ZnoteX caches highscores, news and similar pages. It can keep that cache in files under
192`engine/cache/`, or in RAM via the **APCu** extension.
193
194`config.php` ships with `'memory' => true`, so a fresh install without APCu stops on every cached
195page with *"Configuration error! APCu is not enabled."* If you see that, you have two choices —
196install APCu, or switch to the file cache by putting this in `config.local.php`:
197
198```php
199$config['cache']['memory'] = false;
200```
201
202The file cache needs no extension, works everywhere, and only requires `engine/cache/` to be
203writable.
204
205**APCu is optional.** It saves a few disk reads per request. On a local or low-traffic server you
206will not notice the difference — it is worth installing once you have real player traffic.
207
208#### Installing APCu on Windows
209
210Download from **[pecl.php.net/package/APCu/5.1.28](https://pecl.php.net/package/APCu/5.1.28)** and
211click the **DLL** link. The build must match your PHP exactly — check yours with `php -i` or
212`phpinfo()`:
213
214| Filename part | Comes from |
215| --- | --- |
216| `8.3` | your PHP version |
217| `ts` / `nts` | *Thread Safety* — `enabled` means **ts** |
218| `vs16` / `vs17` | *Compiler* — Visual C++ 2019 is `vs16`, 2022 is `vs17` |
219| `x64` / `x86` | *Architecture* |
220
221Uniform Server is thread-safe, so with PHP 8.3 it needs
222`php_apcu-5.1.28-8.3-ts-vs16-x64.zip`. Most Windows guides say `nts` because that is what other
223stacks use — picking the wrong one means the DLL is ignored with no error.
224
2251. Copy `php_apcu.dll` from the zip into your PHP `extensions` (or `ext`) folder — the path in
226 `extension_dir`.
2272. Add to your `php.ini`:
228 ```ini
229 extension=apcu
230 apc.enabled=1
231 ```
232 Uniform Server has no single `php.ini`: the web server reads `php_production.ini` or
233 `php_development.ini` from `core/php83/` depending on the mode it is running in.
2343. Restart Apache, then set `memory` to `true`.
235
236On Linux, `pecl install apcu` or your distribution's `php-apcu` package.
237
238### Already have players?
239
240Open **`/special/`** to convert an existing OT database for ZnoteX.
241
242Coming from another AAC instead? **Admin Panel → Settings → Convert SQL** takes a **MyAAC** or
243**Gesior2012** database dump and gives you back a ZnoteX conversion SQL — accounts, players,
244news, gallery and the rest. Tables ZnoteX has no equivalent for are preserved rather than
245dropped.
246
247### Upgrading
248
249Use **Admin Panel → Update** (see below) — it handles this automatically. If you would rather
250do it by hand, replace everything **except** `config.local.php`, `layouts/`, `plugins/` and
251`engine/cache/`, apply any new file in `SQL/migrations/`, and check **Admin Panel → Plugins** in
252case a plugin has an update waiting.
253
254---
255## Update ZnoteX
256
257**Admin Panel → Update** checks, verifies and installs new ZnoteX releases directly from
258GitHub — no re-running the installer, no manually copying files. It downloads the release,
259checks its digital signature and per-file checksums, runs a pre-installation check (PHP version,
260extensions, disk space, writable paths, local modifications), backs up every file it is about to
261touch, then installs. If anything goes wrong afterwards, **Restore latest file backup** puts the
262previous version straight back.
263
264---
265## Features
266
267<details open>
268<summary><b>Accounts & characters</b></summary>
269
270- Account registration, password and e-mail changes
271- E-mail verification and lost-account recovery
272- Two-factor authentication
273- reCaptcha anti-spam
274- Character creation with custom vocations, starting skills and towns
275- Starting items via the included Lua script
276- Soft character deletion, and hiding characters from the public list
277- Support helpdesk with tickets
278
279</details>
280
281<details>
282<summary><b>Community</b></summary>
283
284- **Forum** — custom boards, guild boards, admin-only feedback board, level restrictions,
285 outfit avatars, player positions, sticky / closed / hidden threads, and search
286- **Guilds** — create and disband, invites, ranks, nicknames, guild images and descriptions,
287 war declarations and ongoing war tracking
288- **Character profiles** — vocation, level, guild, skills, full outfit and equipment display,
289 achievements, deaths, quest progression and player comments
290
291</details>
292
293<details>
294<summary><b>Server information</b></summary>
295
296- Highscores with vocation and skill filters
297- Latest deaths and latest kills
298- Server info page with PvP settings, rates and experience stages (from your `config.lua` and `stages.xml`)
299- Spells list with vocation filters (from `spells.xml`)
300- Item list (from `items.xml`)
301- Creature library and monster loot tables (from your `data/monster/` folder)
302- Interactive world map from your OTClient `.otmm` minimap: drag, zoom, floor by floor
303- Houses list with town filters, house bidding, and direct purchase with shop points
304- Downloads page with client links and a connection guide
305
306All of the above are uploaded once in **Admin Panel → Server Info** — no FTP, no pasting file
307contents into a public page.
308
309</details>
310
311<details>
312<summary><b>Shop & payments</b></summary>
313
314- Database shop offers managed from the admin panel: items, premium days, gender change, name change, outfits, mounts, and custom types
315- Item market: buy and sell listings, item search, price comparison and transaction history
316- Payment gateways: **PayPal**, **PagSeguro** , **Mercado Pago**, **Stripe** and **PayGol** (SMS)
317
318</details>
319
320<details>
321<summary><b>Administration</b></summary>
322
323- New built-in admin control panel available at `/admin/`
324- Responsive sidebar layout with day/night theme switch
325- Dashboard with accounts, characters, online players, guilds, houses, shop points and moderation queues
326- Delete characters, ban characters and accounts
327- Change account passwords, grant in-game positions
328- Give shop points, edit player level and skills
329- Teleport one player or everyone to a town or position
330- Review in-game bug reports, helpdesk tickets and forum feedback
331- Shop Manager for adding, previewing, hiding and removing database shop offers
332- Shop Pending / History page for pending deliveries and completed orders
333- Moderate gallery uploads, post news and changelogs
334- Server Info pages that import `config.lua`, `stages.xml`, `items.xml`, `spells.xml`, your
335 monster folder and an OTClient `.otmm` minimap
336- Convert a **MyAAC** or **Gesior2012** database into ZnoteX from the panel
337- Rename characters, and search every page *and setting* from the top bar
338
339</details>
340
341<details>
342<summary><b>Setup, themes & extensions</b></summary>
343
344- Six-step web installer at `/install/` that checks requirements, verifies your OT schema is
345 present, imports the ZnoteX tables, creates the first administrator and writes the config
346- Theme system: every theme is a folder of plain HTML and CSS under `layouts/`, switchable from
347 the admin panel, with child themes and one-click install from a repository
348- Per-theme options edited from the panel: background image, logos, links, and an editable line of
349 footer text — images can be uploaded, and are stored outside the theme so an update keeps them
350- Plugin system: add pages, admin pages, tables and behaviour from `plugins/` with no core edit,
351 install and update from the admin panel
352- Settings editor for most of `config.php`, and a menu builder for the site navigation
353- Maintenance mode that keeps administrators and the login page reachable
354
355</details>
356
357<details>
358<summary><b>Performance</b></summary>
359
360- Built-in cache system that serves treated data from flat files instead of hitting MySQL on
361 every page load
362
363</details>
364
365---
366
367## Admin Control Panel
368
369Everything below lives at **`/admin/`**. Access is controlled by
370`$config['page_admin_access']` in `config.php`. The panel is grouped the way the sidebar is.
371
372### Overview
373
374- **Search** — every page *and every setting*, by name or by what it does. Typing `download`
375 reaches the client URL fields under Settings, not just a page whose title happens to match.
376- **Dashboard** — server and community at a glance: environment, recent accounts and characters,
377 top point balances, open queues.
378- **Visitors** — traffic ZnoteX has been recording all along.
379
380### Content
381
382- **News** — write, edit and remove front-page articles, with a BBCode editor.
383- **Changelog** — the entries shown on the public changelog page.
384- **Gallery** — moderate player screenshot submissions.
385- **Menus** — build the site navigation without touching a template. A top-level entry is a
386 *category*: a heading that opens its children rather than a link of its own, so it needs no URL.
387
388### Players
389
390- **Accounts** — search an account, see its characters, points and history.
391- **Player Tools** — punish, move, rename and maintain characters and their accounts.
392- **Character Skills** — read and rewrite level, vocation, health, mana and skills.
393
394### Server Info
395
396Your server's own files, uploaded once here instead of pasted into public pages.
397
398- **Server Information** — upload `config.lua`, `stages.xml`, `items.xml`, `spells.xml` and your
399 monster folder. Each one is parsed on upload and published to the page that uses it:
400 `serverinfo.php`, `items.php`, `spells.php`, `creatures.php` and `monster_loot.php`. For the
401 monsters, `monsters.xml` alone gives you the names; a **`.zip` of `data/monster/`** also gives
402 health, experience, speed and race.
403- **Minimap** — import the `.otmm` your OTClient/OTCv8 writes. ZnoteX converts it into map tiles
404 and shows a pan/zoom viewer with floor arrows on Server Information. Nothing is rendered at all
405 unless a minimap is imported.
406
407`config.lua` is parsed on upload and **never written to disk** — it carries your MySQL password,
408and `engine/XML/` is served by the web server. Only the whitelisted settings are kept.
409
410### Economy
411
412- **Shop Manager** — add, preview, hide and remove shop offers. They live in `znote_shop_offers`
413 now, not in `$config['shop_offers']`.
414- **Payments** — gateways, credentials and the point packages players can buy.
415- **Shop Pending / History** — pending deliveries and completed purchases.
416- **Character Auctions** — ongoing, unclaimed and completed character sales.
417
418### Support
419
420- **Bug Reports** — triage in-game reports, reward reporters, publish changelogs.
421- **Helpdesk** — answer, close and delete support tickets.
422- **Feedback Board** — forum threads awaiting a staff reply.
423
424### Settings
425
426- **Layout** — switch theme, edit its options, browse and install themes from a repository.
427- **Plugins** — install, update, enable and disable what is in `plugins/`.
428- **Settings** — most of `config.php`, from the browser.
429- **Convert SQL** — upload a **MyAAC** or **Gesior2012** database dump and download a ZnoteX
430 conversion SQL. Tables ZnoteX has no equivalent for are kept rather than dropped, and each
431 converted row is mapped back to the row it came from, so a conversion can be traced and re-run.
432
433---
434
435## Themes
436
437Every theme is a folder under `layouts/`. A theme is **plain HTML and CSS** — the PHP stays in
438ZnoteX, so editing one is editing markup, not untangling a template engine. `layouts/default/`
439is the theme that ships; `layouts/_example/` is a documented skeleton to copy.
440
441Everything below is in **Admin Panel → Layouts**.
442
443**Switching.** Every installed theme is listed with a screenshot, 12 per page. Click one to make
444it active. It applies to the public site only — the admin panel never changes.
445
446**Options.** A theme declares its own settings in `theme.json` — a background image, its logos,
447social links, a tagline, a colour, an editable line of footer text. They appear under *Options* on
448that theme's card and are stored in the database, so you change them from the panel instead of
449editing the theme's files, and updating the theme cannot lose them.
450
451An option of type `image` shows the current picture, its path, and an upload field. Uploads land
452in `engine/img/theme/<theme>/`, deliberately outside `layouts/`, so replacing or re-extracting a
453theme leaves them alone. An image that only exists inside a static stylesheet is reachable too:
454the option declares the CSS rule that places it and ZnoteX writes that into the page head, so no
455theme file has to change.
456
457The footer option is one line of your own, rendered above the credits — the copyright and engine
458credits stay in the theme's files on purpose, not in the panel.
459
460**Installing one.** Two ways:
461
462- *Manually* — unzip the theme folder into `layouts/`. It appears on the next page load.
463- *From a repository* — press **Browse themes** to list themes hosted elsewhere and install one
464 with a button.
465
466The repository is configured by `$config['layout_repository']` in `config.php`, and points at
467this project's `layouts` branch by default. Downloads are refused unless the URL is **https** and
468its host is on `allowed_hosts` — a theme is code that runs on your server, so only point it at a
469repository you trust. The tooling that packages themes and regenerates a catalogue lives on the
470`layouts` branch, alongside the archives themselves.
471
472**Child themes.** A theme can name another as its `parent` and override only the files it wants.
473The rest falls through to the parent, so a colour change is one stylesheet rather than a fork —
474and the parent can still be updated underneath it.
475
476See [layouts/README.md](layouts/README.md) for the full contract.
477
478---
479
480## Plugins
481
482A plugin is a folder under `plugins/` that adds public pages, admin pages, database tables and
483behaviour **without editing a single ZnoteX file** — so an update never costs you your work.
484
485```
486plugins/my_plugin/
487 plugin.json name, version, author, description [required]
488 plugin.php registers hooks
489 pages/<page>.php public page at page.php?plugin=my_plugin&p=<page>
490 admin/<mod>.php admin page, listed in the sidebar
491 install.sql tables, created on install
492 assets/ css, js, images
493```
494
495Everything below is in **Admin Panel → Plugins**.
496
497**Installing one.** Download it, unzip the folder into `plugins/`, reload the panel, press
498**Install**. That runs its `install.sql` and switches it on. ZnoteX **never downloads a plugin by
499itself**: a plugin is PHP that runs on every page of your site, so putting the files there stays
500a deliberate act rather than a button.
501
502**Updating one.** Replace the folder with the newer version. If its `plugin.json` carries a
503higher version than the one recorded at install time, an **Update** button appears and applies
504whatever the new version needs.
505
506**Removing one.** *Disable* stops a plugin; *Uninstall* also forgets its version. Neither ever
507drops a table — removing a plugin for good means deleting its folder and dropping its tables
508yourself.
509
510> A plugin runs with the same privileges as the rest of the site, and nothing sandboxes it.
511> Install plugins whose author you know or whose code you have read.
512
513`plugins/shop_coupons/` is a working example — redeemable codes that either credit shop points or
514take a percentage off the next purchase — and is commented as a tutorial. See
515[plugins/README.md](plugins/README.md) for the contract and the list of hooks.
516
517---
518
519## Contributing
520
521Issues and pull requests are welcome at
522[github.com/Open-Games-Community/ZnoteX](https://github.com/Open-Games-Community/ZnoteX).
523
524## License
525
526See [LICENSE](LICENSE). Original ZnoteAAC modified by Alex renamed to ZnoteX; layout by Blackwolf (Snavy).
527