IC-Computer: Schreibtisch, Fenster und Apps
Ein Computer im Spiel. Man tritt an ein Terminal, drueckt E, und bekommt eine
Oberflaeche mit Mail, Browser, Adressbuch, Kalender und weiteren Anwendungen.
Andere Resources haengen sich als App ein.
Auf ESX umgestellt:
- Fuenf harte Abhaengigkeiten zeigten auf Resources, die es hier nicht gibt.
Eine fehlende Abhaengigkeit verhindert den Start vollstaendig - die
Resource waere nie hochgekommen.
- Die Bruecke zum Framework neu geschrieben; Charakterdaten, Aktenverwaltung
und Immobilien ausgebaut, weil die zugehoerigen Systeme fehlen.
- pc_live_devices fehlte im Schema, wird vom Code aber gelesen. Ohne die
Tabelle ist kein fester PC ansprechbar. Ein PC braucht ausserdem zwei
Eintraege mit derselben Kennung: Standort in der Datenbank, Kamerafahrt in
der config.lua.
Mail ueberarbeitet:
- Postfaecher haengen an einer Anmeldung statt an der Person. Mehrere Leute
koennen dasselbe Firmenpostfach gleichzeitig offen haben.
- Ordner gehoeren zum Postfach, nicht zur Person. Eine Mail an ein geteiltes
Postfach wird je Empfaenger einmal gespeichert; damit das Einsortieren
trotzdem fuer alle gilt, tragen alle Kopien einer Zustellung dieselbe
Kennung. Gelesen und geloescht bleibt persoenlich - das ist keine
Eigenschaft der Nachricht, sondern der Person.
- Signaturen gehoeren ebenfalls zum Postfach.
- Kalender koennen privat, geteilt oder oeffentlich sein. Ein oeffentlicher
Termin haengt bewusst auch an einem Postfach, sonst koennte ihn spaeter
niemand mehr aendern oder absagen.
Neue Apps: Webhosting, Bleeter und dessen Verwaltung.
Behoben:
- prompt(), confirm() und alert() froren das NUI ein. FiveMs CEF hat keinen
Handler fuer die eingebauten Browserdialoge - der Aufruf oeffnet nichts und
kehrt nie zurueck. Ersetzt durch eigene Dialoge.
- Die Fenster tragen data-wid, keine id. Wer sie mit getElementById sucht,
schreibt ins Leere und das Fenster bleibt leer.
Enthaelt README.md mit Einrichtung und PLUGINS.md: eine Anleitung, wie man eine
eigene App baut und einhaengt, mit vollstaendigem Beispiel von der Tabelle bis
zum Schreibtischsymbol.
This commit is contained in:
commit
be502d2834
46 changed files with 13119 additions and 0 deletions
210
README.md
Normal file
210
README.md
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
# pc-live — IC-Computer
|
||||
|
||||
Ein Computer im Spiel: Schreibtisch, Fenster, Apps. Man tritt an ein
|
||||
Terminal, drückt **E**, und bekommt eine Oberfläche mit Mail, Browser,
|
||||
Adressbuch, Kalender und weiteren Anwendungen.
|
||||
|
||||
Andere Resources hängen sich als App ein — so laufen hier das IC-Webhosting
|
||||
(`ic-web`) und Bleeter.
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
### 1. Ordner
|
||||
|
||||
```
|
||||
resources/[haleoe]/pc-live/
|
||||
```
|
||||
|
||||
### 2. Datenbank
|
||||
|
||||
Reihenfolge einhalten, die Migrationen setzen auf dem Grundschema auf:
|
||||
|
||||
```bash
|
||||
mysql -u BENUTZER -p DATENBANK < sql/pc_live.sql
|
||||
mysql -u BENUTZER -p DATENBANK < sql/pc_live_devices.sql
|
||||
mysql -u BENUTZER -p DATENBANK < sql/migration_postfach_ordner.sql
|
||||
mysql -u BENUTZER -p DATENBANK < sql/migration_kalender.sql
|
||||
```
|
||||
|
||||
| Datei | legt an |
|
||||
|---|---|
|
||||
| `pc_live.sql` | Benutzer, Apps, Mail, Ordner, Kalender, Kontakte |
|
||||
| `pc_live_devices.sql` | **feste PC-Standorte** – fehlte im ursprünglichen Schema, ohne sie ist kein fester PC ansprechbar |
|
||||
| `migration_postfach_ordner.sql` | Ordner je Postfach, Zustellungskennung |
|
||||
| `migration_kalender.sql` | private, geteilte und öffentliche Kalender |
|
||||
|
||||
Alle wiederholt ausführbar.
|
||||
|
||||
### 3. server.cfg
|
||||
|
||||
```
|
||||
ensure oxmysql
|
||||
ensure es_extended
|
||||
ensure pc-live
|
||||
```
|
||||
|
||||
### 4. Einen PC in die Welt stellen
|
||||
|
||||
Ein fester PC braucht **zwei Einträge mit derselben Kennung** — das ist die
|
||||
häufigste Stolperfalle:
|
||||
|
||||
**a) Datenbank** – Standort, Beschriftung, Jobsperre:
|
||||
|
||||
```sql
|
||||
INSERT INTO pc_live_devices (id, label, x, y, z, heading, type, job, active)
|
||||
VALUES ('mission_row_1', 'LSPD Terminal',
|
||||
441.615, -979.645, 30.425, 195.0, 'public', NULL, 1);
|
||||
```
|
||||
|
||||
**b) `config.lua`** – Kamerafahrt und Einfrieren beim Öffnen:
|
||||
|
||||
```lua
|
||||
{
|
||||
id = "mission_row_1", -- muss zur Datenbank passen
|
||||
label = "LSPD Terminal",
|
||||
coords = vector3(441.615, -979.645, 30.425),
|
||||
heading = 195.0,
|
||||
type = "public", -- oder: type = "job", job = "police"
|
||||
}
|
||||
```
|
||||
|
||||
Fehlt der Eintrag in `config.lua`, lässt sich der PC benutzen — aber ohne
|
||||
Kamera und ohne dass die Spielfigur einfriert.
|
||||
|
||||
Zum `heading`: **nicht** die Ausrichtung des Props, sondern die Seite, von der
|
||||
aus man auf den Bildschirm schaut. Am einfachsten: davorstellen, in die
|
||||
gewünschte Richtung schauen, eigene Position und Blickrichtung ablesen — die
|
||||
Blickrichtung plus 180° ist der Wert.
|
||||
|
||||
### 5. Apps anderer Resources einhängen
|
||||
|
||||
Eine App besteht aus vier Teilen. Beispiel `ic-web`:
|
||||
|
||||
| Teil | Ort |
|
||||
|---|---|
|
||||
| Brücke NUI → Server | `client/…lua`, eingetragen in `fxmanifest.lua` |
|
||||
| Oberfläche | `nui/js/apps/….js`, eingetragen in `fxmanifest.lua` **und** `nui/index.html` |
|
||||
| Schreibtischsymbol | `APP_META` in `nui/js/desktop.js` |
|
||||
| Registrierung | `AppRegistry.Register` in `server/apps.lua` |
|
||||
|
||||
Antworten des Servers laufen über den Nachrichtenverteiler in `desktop.js`
|
||||
(`window.addEventListener('message', …)`). Jede App bekommt dort ihren eigenen
|
||||
`case`.
|
||||
|
||||
Resources können sich auch von außen eintragen:
|
||||
|
||||
```lua
|
||||
exports['pc-live']:RegisterApp({ app_id = 'meine.app', name = 'Meine App', … })
|
||||
```
|
||||
|
||||
Die Oberfläche muss trotzdem in `nui/` liegen — das NUI lädt nur Dateien der
|
||||
eigenen Resource.
|
||||
|
||||
**Eigene App bauen: [PLUGINS.md](PLUGINS.md)** — vollständiges Beispiel von der
|
||||
Tabelle bis zum Schreibtischsymbol, dazu die Fallen, die sonst Zeit kosten.
|
||||
|
||||
---
|
||||
|
||||
## Was drin ist
|
||||
|
||||
| App | |
|
||||
|---|---|
|
||||
| **Browser** | interne Seiten unter `ic://…`, externe über iframe |
|
||||
| **Mail** | mehrere Postfächer, Ordner je Postfach, Signaturen, Kalender |
|
||||
| **Adressbuch** | Kontakte, verknüpft mit Mail |
|
||||
| **Webhosting** | Domänen und Webseiten (`ic-web`) |
|
||||
| **Bleeter** | Feed, Werbung, Markt, Kalender, Gewerbe, Profil |
|
||||
| **Bleeter-Verwaltung** | Unternehmensprofile und Freigaben |
|
||||
| **Software Store** | Apps nachinstallieren |
|
||||
|
||||
---
|
||||
|
||||
## Mail: was hier anders ist
|
||||
|
||||
**Postfächer hängen an einer Anmeldung, nicht an der Person.** Über *Postfächer
|
||||
→ + Postfach hinzufügen* schaltet man ein Postfach mit Adresse und Passwort
|
||||
frei (geprüft von `ic-web`). Mehrere Personen können dasselbe Postfach
|
||||
gleichzeitig offen haben — ein Firmenpostfach gehört der Firma.
|
||||
|
||||
**Ordner gehören zum Postfach.** Legt jemand im Firmenpostfach einen Ordner an,
|
||||
sehen ihn alle, die es bedienen. Sortiert jemand eine Mail ein, liegt sie für
|
||||
alle im selben Ordner.
|
||||
|
||||
Das ist nicht selbstverständlich, denn eine Mail an ein geteiltes Postfach wird
|
||||
**je Empfänger einmal** gespeichert. Damit das Einsortieren trotzdem für alle
|
||||
gilt, tragen alle Kopien einer Zustellung dieselbe `delivery_id`
|
||||
(`pc_live_mail.delivery_id`) — wird eine verschoben, wandern die anderen mit.
|
||||
|
||||
Gelesen und gelöscht bleibt dagegen persönlich. Das ist keine Eigenschaft der
|
||||
Nachricht, sondern der Person.
|
||||
|
||||
**Signaturen** gehören ebenfalls zum Postfach (`ic_mail_accounts.signature`).
|
||||
Wer es bedient, schreibt mit derselben Fußzeile.
|
||||
|
||||
---
|
||||
|
||||
## Kalender
|
||||
|
||||
| Sichtbarkeit | gehört | sieht | bearbeitet |
|
||||
|---|---|---|---|
|
||||
| privat | der Person | nur sie | nur sie |
|
||||
| geteilt | einem Postfach | wer es bedient | wer es bedient |
|
||||
| öffentlich | einem Postfach | jeder auf dem Server | wer es bedient |
|
||||
|
||||
Ein öffentlicher Termin hängt bewusst auch an einem Postfach — sonst gäbe es
|
||||
niemanden, der ihn später ändern oder absagen könnte.
|
||||
|
||||
Änderungen erreichen alle Beteiligten sofort, sonst hätte jeder eine andere
|
||||
Vorstellung vom Dienstplan, bis er den PC neu öffnet.
|
||||
|
||||
---
|
||||
|
||||
## Sicherheit
|
||||
|
||||
**Welches Postfach gemeint ist, schickt der Client mit.** Der Server prüft das
|
||||
bei jeder Ordner- und Mailaktion über `ic-mail:CanAccessAddress` und fällt ohne
|
||||
Zugriff auf das persönliche Postfach zurück, statt fremde Ordner herauszugeben.
|
||||
Jede Ordneraktion hängt zusätzlich an einer Besitzprüfung, nicht an der
|
||||
mitgeschickten Id allein.
|
||||
|
||||
**Keine eingebauten Browserdialoge.** `prompt()`, `confirm()` und `alert()`
|
||||
haben in FiveMs CEF keinen Handler: der Aufruf öffnet nichts und lässt das NUI
|
||||
stehen. Stattdessen `ICWebRender.promptText` und `ICWebRender.confirmBox` aus
|
||||
`nui/js/apps/webhosting.js`.
|
||||
|
||||
**Spielerinhalte werden über `textContent` gesetzt, nie über `innerHTML`.**
|
||||
Das NUI ist derselbe Kontext wie der PC — wer dort Markup einschleusen kann,
|
||||
kann auch dessen Callbacks aufrufen.
|
||||
|
||||
---
|
||||
|
||||
## Voraussetzungen
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| `oxmysql` | Datenbankzugriff |
|
||||
| `es_extended` | Spieler, Jobs, Benachrichtigungen |
|
||||
| `ic-mail` | optional – ohne sie gibt es keine Mailadressen |
|
||||
| `ic-web` | optional – liefert Webhosting-App und Postfachanmeldung |
|
||||
|
||||
---
|
||||
|
||||
## Bekannte Fallstricke
|
||||
|
||||
**Der Fensterrahmen hat keine `id`.** `WindowManager.create` setzt
|
||||
`data-wid`. Wer sein Fenster mit `document.getElementById(WIN_ID)` sucht,
|
||||
findet nichts und schreibt ins Leere — das Fenster bleibt leer. Richtig ist
|
||||
das von `create()` zurückgegebene Element oder
|
||||
`document.querySelector('[data-wid="…"]')`.
|
||||
|
||||
**Ja/Nein-Spalten aus der Datenbank.** `TINYINT(1)` kommt je nach Treiberweg
|
||||
als `1` oder als `true` an — `oxmysql` wandelt es bei `query`/`single` in einen
|
||||
Boolean um, bei `prepare` nicht. Ein Vergleich mit `== 1` geht deshalb
|
||||
irgendwann schief, und zwar still. Siehe `ICWeb.Bool` in `ic-web`.
|
||||
|
||||
**Keine Datenbankarbeit beim Herunterfahren.** Ein `await` in `onResourceStop`
|
||||
wartet auf eine Antwort, die niemand mehr entgegennimmt — der Server meldet
|
||||
„Execution of function reference in script host failed". Aufräumen gehört in
|
||||
den Start.
|
||||
Loading…
Add table
Add a link
Reference in a new issue