Ein IC-Hostinganbieter im Spiel. Er vergibt Domaenen, richtet je Domaene einen Zugang ein, und die Inhaber pflegen darauf ihre Webseite. Die gesamte Verwaltung haengt an einer Anmeldung, nicht an Job oder Serverrechten. Ein Zugang ist zugleich ein Postfach: wer sich anmeldet, bekommt das Postfach dieser Adresse. Mehrere Personen koennen denselben Zugang benutzen und dasselbe Postfach gleichzeitig offen haben - ein Firmenpostfach gehoert der Firma, nicht einer Person. Drei Ebenen: superadmin vergibt Domaenen und setzt je Domaene einen Admin ein admin pflegt die Seiten seiner Domaene und legt dort Zugaenge an editor pflegt nur die Seiten Seiteninhalte sind kein HTML, sondern typisierte Bloecke. Die Seiten werden im NUI des IC-Computers angezeigt, also im selben Kontext wie dieser selbst - wer dort Markup einschleusen kann, kann auch dessen Callbacks aufrufen. Ein Blockmodell schliesst das konstruktiv aus, statt es filtern zu muessen. Passwoerter liegen gesalzen und gehasht in der Datenbank, gerechnet wird in der Datenbank. Fuenf Fehlversuche je Benutzername sperren den Namen kurzzeitig. Enthaelt README.md mit Einrichtung und Anbindung an den IC-Computer sowie ANLEITUNG.md fuer die Bedienung im Spiel. |
||
|---|---|---|
| server | ||
| shared | ||
| sql | ||
| .gitignore | ||
| ANLEITUNG.md | ||
| config.lua | ||
| fxmanifest.lua | ||
| README.md | ||
ic-web — IC-Webhosting
Ein IC-Hostinganbieter: er vergibt Domänen, richtet je Domäne einen Zugang
ein, und die Domäneninhaber pflegen darauf ihre Webseite und ihre Postfächer.
Aufgerufen werden die Seiten im Browser von pc-live unter ic://domäne.
Die drei Ebenen
| Rolle | Zugang | Darf |
|---|---|---|
Anbieter (superadmin) |
admin@liveinvader.ls |
Domänen anlegen, übertragen, sperren, löschen; überall Zugänge und Seiten |
Domänenadmin (admin) |
<name>@<domäne> |
Seiten der eigenen Domäne pflegen, dort Zugänge anlegen und verwalten |
Redakteur (editor) |
<name>@<domäne> |
nur Seiten der eigenen Domäne pflegen |
Job und Serverrechte spielen keine Rolle. Wer den Zugang kennt, verwaltet die Seite — unabhängig davon, welchen Charakter er gerade spielt.
Ein Zugang ist ein Postfach
presse@weazel-news.ls ist Benutzername, Passwort und Mailadresse in einem.
Beim Anmelden wird der Zugriff auf das Postfach in ic-mail erteilt, beim
Abmelden wieder entzogen. Deshalb können mehrere Personen gleichzeitig
dasselbe Postfach offen haben — ein Firmenpostfach gehört der Firma, nicht
einer Person.
Wird ein Zugang gelöscht, bleibt das Postfach mit seinen Nachrichten bestehen.
Aufgeräumt wird beim Start, nicht beim Herunterfahren: ic-web widerruft
dann alle Postfachzugriffe, die es je erteilt hat (granted_by = 'ic-web').
Beim Stoppen ginge das nicht — der Aufruf nach ic-mail wartet auf eine
Datenbankantwort, und eine wartende Koroutine lässt sich während des
Herunterfahrens nicht mehr fortsetzen; der Server meldet dann
„Execution of function reference in script host failed". Der Umweg über den
Start deckt außerdem den Fall ab, den ein Stop-Handler nie erwischt: den
Absturz.
Postfächer im Mailclient
Der Mailclient von pc-live kann weitere Postfächer aufnehmen: Postfächer →
+ Postfach hinzufügen fragt Adresse und Passwort ab — dieselbe Prüfung
wie die Anmeldung, aber ohne Verwaltungsrechte. Man kann zehn Postfächer
offen haben (Config.MaxOpenMailboxes) und trotzdem nur für eines Seiten
pflegen dürfen.
Freigeschaltete Postfächer tragen ein ✕ zum Entfernen; das eigene und dienstlich zugewiesene nicht — die gehören einem nicht. Beim Verlassen des Servers werden alle wieder geschlossen, ebenso beim nächsten Start von ic-web.
Das Abmelden von der Verwaltung nimmt ein eigenständig geöffnetes Postfach nicht weg.
Signaturen
Die Signatur gehört zum Postfach, nicht zur Person: eine Firmenadresse trägt dieselbe Fußzeile, egal wer sie gerade bedient. Ändern darf sie jeder mit Zugriff auf das Postfach (Signatur im Mailclient).
Beim Schreiben wird sie unter den Text gesetzt, getrennt durch eine Zeile mit
--. Beim Wechsel des Absenders tauscht sie sich aus, der geschriebene Text
bleibt stehen.
Gespeichert wird in ic_mail_accounts.signature (ic-mail, Migration
sql/migration_signaturen.sql).
Ordner je Postfach
Ordner gehören zum Postfach, nicht zur Person (pc_live_mail_folders.address,
Migration pc-live/sql/migration_postfach_ordner.sql). Ein geteiltes Postfach
hat für alle dieselbe Struktur.
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: wird eine Kopie verschoben, wandern die anderen mit.
Gelesen und gelöscht bleibt persönlich — das ist keine Eigenschaft der
Nachricht, sondern der Person.
Welches Postfach gemeint ist, schickt der Client mit; der Server prüft es über
ic-mail:CanAccessAddress und fällt ohne Zugriff auf das persönliche Postfach
zurück, statt fremde Ordner herauszugeben.
Kalender
Dieselbe Mechanik wie bei Postfächern und Ordnern
(pc_live_calendar.address + visibility, Migration
pc-live/sql/migration_kalender.sql):
| Sichtbarkeit | gehört | sieht | bearbeitet |
|---|---|---|---|
private |
der Person | nur sie | nur sie |
shared |
einem Postfach | wer es bedient | wer es bedient |
public |
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. Wer ein Postfach bedient, darf dessen Termine auch dann ändern, wenn jemand anderes sie eingetragen hat; genau das macht sie geteilt.
Änderungen erreichen alle Beteiligten sofort, sonst hätte jeder eine andere Vorstellung vom Dienstplan, bis er den PC neu öffnet.
Ablauf
- Der Anbieter meldet sich in der App Webhosting mit
admin@liveinvader.lsan (Startpasswort siehe unten) und ändert sein Passwort. - Er legt unter Verwaltung eine Domäne an, wählt den Besitzer-Job und den ersten Zugang. Benutzername und Passwort werden einmal angezeigt.
- Der Domänenadmin meldet sich damit an, ändert sein Passwort und legt unter Zugänge weitere Zugänge für seine Leute an.
- Alle Zugänge dieser Domäne pflegen die Seiten unter Meine Seite und veröffentlichen sie.
Ersteinrichtung
Beim ersten Start legt ic-web den Anbieterzugang aus Config.MainAdmin an und
schreibt Benutzername und Startpasswort in die Serverkonsole. Vorgabe:
admin@liveinvader.ls / liveinvader
Beim ersten Anmelden wird zum Ändern aufgefordert.
Passwort vergessen? In der Serverkonsole:
webpasswd admin@liveinvader.ls neues-passwort
Inhalte sind kein HTML
Seiten bestehen aus typisierten Blöcken (shared/blocks.lua), nicht aus
Markup. Der Grund: die Seiten werden im NUI von pc-live angezeigt — im selben
Kontext wie der PC selbst. Wer dort Markup einschleusen kann, kann auch dessen
NUI-Callbacks aufrufen. Ein Blockmodell schließt das konstruktiv aus, statt es
filtern zu müssen; HTML zu filtern ist ein Wettlauf, den man langfristig
verliert.
B.Validate baut jeden Block aus dem Schema neu auf. Was nicht im Schema
steht, fällt weg — es wird nicht bereinigt, sondern verworfen.
Blocktypen: heading, text, image, list, button, contact, divider.
Der Renderer in pc-live setzt Text ausschließlich über textContent, niemals
über innerHTML. Deshalb bleiben < und > im Text erhalten statt
verstümmelt zu werden.
Domänennamen
Form: name.endung, nur Kleinbuchstaben, Ziffern und Bindestriche, 3–30
Zeichen, Endung aus Config.Domain.allowedTlds (.ls .sa .gov .org .net).
Config.Domain.reserved sperrt Namen nur gegen die Selbstanmeldung — der
Anbieter darf lspd.ls sehr wohl vergeben, dafür ist er da.
Unabhängig davon gesperrt sind Domänen des Mailsystems: existiert der Realm
schon in ic-mail als is_default, system oder citizen (etwa mail.ls),
lehnt D.EnsureRealm ab — für alle. Sonst hinge eine Firmenwebseite an der
Domäne sämtlicher persönlicher Postfächer. Eine herrenlose Firmen-Domäne
(type = company) wird dagegen übernommen.
Bilder und Meldungen
Bilder werden extern verlinkt — NUI kann keine Dateien hochladen. Erlaubt sind
nur https und die Hosts aus Config.ImageHosts (Subdomains eingeschlossen).
Die Hostliste ist der Rahmen, die Meldefunktion fängt den Rest — sie greift
aber erst nachträglich.
Jeder Spieler kann eine Seite melden (Link unten auf jeder Seite), einmal je Seite und Stunde. Der Anbieter sieht die Meldungen unter Meldungen.
Passwörter
Gespeichert wird SHA2(salt || passwort), gerechnet in der Datenbank — das
Passwort läuft nur als Abfrageparameter durch den Server. Fünf Fehlversuche je
Benutzername innerhalb von fünf Minuten sperren den Namen kurzzeitig
(Config.Login).
Das ist ein IC-Passwort, keine Sicherheitsgrenze gegen Serveradmins: wer Datenbankzugriff hat, kann jeden Zugang zurücksetzen. Es verhindert, dass Mitspieler fremde Seiten ändern — nicht mehr.
Installation
1. Ordner
Der Ordner ic-web gehört in dein Resource-Verzeichnis, zum Beispiel:
resources/[haleoe]/ic-web/
2. Datenbank
mysql -u BENUTZER -p DATENBANK < sql/ic_web.sql
Legt an: ic_web_sites, ic_web_pages, ic_web_accounts,
ic_web_login_fails, ic_web_reports. Wiederholt ausführbar.
3. server.cfg
ensure oxmysql
ensure es_extended
ensure ic-mail
ensure ic-web # nach ic-mail
Liegt alles in einem Ordner mit eckigen Klammern, genügt ensure [haleoe] —
dann startet ic-web automatisch mit. Die Reihenfolge stimmt dabei von selbst,
weil ic-mail alphabetisch vorher kommt.
4. Anbindung an pc-live
ic-web bringt keine eigene Oberfläche mit — sie sitzt im PC. Diese Dateien
gehören nach pc-live:
| Datei | Ziel in pc-live | Zweck |
|---|---|---|
client/webhosting.lua |
client/ |
Brücke zwischen NUI und Server |
nui/js/apps/webhosting.js |
nui/js/apps/ |
die App selbst |
Dazu in pc-live eintragen:
fxmanifest.lua
client_scripts { …, 'client/webhosting.lua' }
files { …, 'nui/js/apps/webhosting.js' }
nui/index.html — vor desktop.js, weil andere Apps den Dialogbaukasten
daraus benutzen:
<script src="js/apps/webhosting.js"></script>
nui/js/desktop.js — App eintragen und den Antwortkanal anschließen:
'pc.webhosting': { name: 'Webhosting', icon: '🌍', open: () => WebhostingApp.open() },
…
case 'icweb_response': ICWebNet.onResponse(data); break;
server/apps.lua — damit die App auf dem Schreibtisch erscheint:
AppRegistry.Register({
app_id = "pc.webhosting", name = "Webhosting", icon = "🌍",
version = "1.0.0", category = "system", default = true,
permissions = {}, dependencies = {}, price = 0,
description = "IC-Domänen und Webseiten verwalten. Anmeldung erforderlich.",
})
nui/js/apps/browser.js — damit ic://domäne.ls im Browser aufgeht:
der Zweig, der Adressen der Form name.endung an ICWebNet.call('getSite', …)
gibt und mit ICWebRender.renderPage zeichnet.
5. Erste Anmeldung
Beim ersten Start legt ic-web den Anbieterzugang an und schreibt ihn in die
Serverkonsole. Vorgabe: admin@liveinvader.ls / liveinvader. Beim ersten
Anmelden wird ein eigenes Passwort verlangt.
Voraussetzungen
oxmysql |
Datenbankzugriff |
es_extended |
Spielername, Jobliste, Benachrichtigungen |
ic-mail |
Domänen und Postfächer. Fehlt es, laufen die Webseiten trotzdem – nur ohne Mailadressen |
pc-live |
die Oberfläche |
fmsdk |
Protokoll. Fehlt es, wird verworfen statt zu scheitern |
ic-mail braucht dafür sechs Exports, die dieses Projekt voraussetzt:
GetRealmByName, CreateRealm, EnsureSharedAddress, GrantAddressAccess,
RevokeAddressAccess, RevokeAccessGrantedBy.
Selbstanmeldung (optional, aus)
Config.SelfRegistration.enabled = true erlaubt Behörden und Unternehmen, sich
ohne Anbieter selbst eine Domäne zu holen — Grundlage ist dann der ESX-Job ab
minGrade. Der Zugang wird dabei automatisch erzeugt und einmalig angezeigt.
Standardmäßig aus, weil die Vergabe über den Anbieter läuft.
Konsolenbefehle
Notbremse des Serverbetreibers, kein IC-Weg. Erlaubt sind Serverkonsole sowie
ESX-Gruppe admin/superadmin bzw. ACE ic_web.admin (Config.Console).
| Befehl | Wirkung |
|---|---|
webpasswd <benutzer@domäne> <passwort> |
Passwort setzen |
webaccounts |
alle Zugänge auflisten |
webreports |
offene Meldungen |
webblock <domäne> |
Seite sperren bzw. freigeben |
webreport done|dismiss <id> |
Meldung abschließen |
Exports
exports['ic-web']:GetSite(domain, slug) -- (seite, nil) oder (nil, fehlertext)
exports['ic-web']:DomainExists(domain)
exports['ic-web']:GetSitesForJob(job)
exports['ic-web']:GetSession(src) -- wer ist an diesem PC angemeldet
ic-mail wurde um vier Exports ergänzt, die ic-web benutzt:
EnsureSharedAddress, GrantAddressAccess, RevokeAddressAccess,
DeleteAddress — sowie GetRealmByName und CreateRealm für die Domänen.
Netzwerkereignisse
Jedes Ereignis bekommt eine Anfrage-Id und antwortet über
ic-web:client:response mit { ok, data, error }. Alle sind gedrosselt;
Rechte werden ausnahmslos serverseitig aus der Anmeldung abgeleitet.
Anmeldung: login, logout, session, changePassword.
Seiten: getSite, listMine, getEditable, savePage, deletePage,
updateSite, report.
Zugänge: listAccounts, createAccount, setAccountPassword,
setAccountActive, setAccountRole, deleteAccount.
Anbieter: adminListSites, adminListAccounts, adminListJobs,
adminRegister, adminSetBlocked, adminSetOwner, adminDeleteSite,
adminListReports, adminSetReportStatus.
Tabellen
ic_web_sites, ic_web_pages, ic_web_accounts, ic_web_login_fails,
ic_web_reports.
Die Domäne wird über den Namen referenziert, nicht über einen
Fremdschlüssel auf ic_mail_realms — Fremdschlüssel über Resource-Grenzen
hinweg koppeln zwei Lebenszyklen aneinander, die unabhängig voneinander
installiert werden.