pc-live/README.md
Bjoern Flessing 785d5f6268 Verwaisten Bleeter-Callback entfernt
Der Callback openBleeter oeffnete Bleeters eigenes Fenster ueber dem PC. Das
nahm dem PC den Fokus - SetNuiFocus gilt global fuer den Client, zwei Resources
sperren sich dabei gegenseitig die Maus aus.

Seit Bleeter als eigene App im PC laeuft (client/bleeter.lua), rief ihn niemand
mehr auf.
2026-08-09 12:43:37 +00:00

7.2 KiB
Raw Blame History

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:

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:

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:

{
    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:

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 — 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 soziales Netz: 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.