Reviewed and corrected 2 chapters

Reviewed and corrected chapters:
- quality/security.md 
- quality/clean_arch.md
Neu im Wörterbuch:
unsandboxed environment = unsandboxed Umgebung
Bemerkungen:
Lapce(Mein Editor) ist abgestürzt als ich am Ende von clean_arch.md war.
Zum Glück waren die vorherigen Dateien abgespeichert und der Anfang von
clean_arch.md auch. Allerdings ist der Rest von clean_arch.md aufgrund des
Absturzes nicht ganz so detailiert korrigiert wie geplant.
This commit is contained in:
debiankaios 2022-12-18 10:30:23 +01:00
parent 10b29f586d
commit 5923659439
3 changed files with 64 additions and 33 deletions

View File

@ -7,39 +7,54 @@ idx: 8.4
## Einleitung <!-- omit in toc -->
Sobald Ihre Mod eine beachtliche Größe erreicht hat, wird es immer schwieriger, den den Code sauber und frei von Fehlern zu halten. Dies ist ein besonders großes Problem bei der Verwendung von einer dynamisch typisierte Sprache wie Lua, da der Compiler Ihnen sehr wenig Hilfe und Möglichkeiten zur Compilerzeit gibt, wenn es darum geht, sicherzustellen, dass Typen ordnungsgemäß verwendet werden.
Sobald Ihre Mod eine beachtliche Größe erreicht hat, wird es immer schwieriger, den Code
sauber und frei von Fehlern zu halten. Dies ist ein besonders großes Problem bei der
Verwendung von einer dynamisch typisierte Sprache wie Lua, da der Compiler Ihnen sehr
wenig Hilfe und Möglichkeiten zur Compilerzeit gibt, wenn es darum geht, sicherzustellen,
dass Typen ordnungsgemäß verwendet werden.
Dieses Kapitel behandelt wichtige Konzepte, um Ihren Code sauber zu halten und gängige Entwurfsmuster, um dies zu erreichen. Bitte beachten Sie, dass dieses Kapitel nicht als Vorschrift gedacht ist, sondern Ihnen eine Vorstellung von den Möglichkeiten geben soll. Es gibt nicht nur einen guten Weg, eine Mod zu entwerfen und gutes Mod-Design ist sehr subjektiv.
Dieses Kapitel behandelt wichtige Konzepte, um Ihren Code sauber zu halten und gängige
Entwurfsmuster, um dies zu erreichen. Bitte beachten Sie, dass dieses Kapitel nicht als
Vorschrift gedacht ist, sondern Ihnen eine Vorstellung von den Möglichkeiten geben soll.
Es gibt nicht nur einen guten Weg, eine Mod zu entwerfen und gutes Mod-Design ist sehr
subjektiv.
- [Kohäsion, Kopplung und Trennung der Programmbereiche](#kohäsion-kopplung-und-trennung-der-programmbereiche)
- [Observer](#observer)
- [Modell-View-Controller](#modell-view-controller)
- [API-Sicht](#api-sicht)
- [API-View](#api-view)
- [Zusammenfassung](#zusammenfassung)
## Kohäsion, Kopplung und Trennung der Programmbereiche
Ohne jegliche Planung neigt ein Programmierprojekt dazu, allmählich in
Spaghetti-Code zu verfallen. Spaghetti-Code zeichnet sich durch einen Mangel an Struktur aus - der gesamte Code wird ohne klare Grenzen zusammengewürfelt. Das macht ein Projekt völlig unwartbar und endet damit, dass es aufgegeben wird.
Spaghetti-Code zu verfallen. Spaghetti-Code zeichnet sich durch einen Mangel an Struktur
aus - der gesamte Code wird ohne klare Grenzen zusammengewürfelt. Das macht ein Projekt
völlig unwartbar und endet damit, dass es aufgegeben wird.
Das Gegenteil davon ist, dass ein Projekt als eine Sammlung interagierender kleinerer Programme oder Code-Bereiche zu entwickeln. <!-- Weird wording? -->
Das Gegenteil davon ist, dass ein Projekt als eine Sammlung interagierender kleinerer
Programme oder Code-Bereiche zu entwickeln. <!-- Weird wording? -->
> Inside every large program, there is a small program trying to get out.
>
> --C.A.R. Hoare
Die Übersetzung davon ist: <!-- Weird wording? -->
Die deutsche Übersetzung davon: <!-- Weird wording? -->
> In jedem großen Programm gibt es ein kleines Programm, das versucht, herauszukommen.
Dies sollte so geschehen, dass Sie eine Trennung der Programmteile erreichen - jeder Bereich sollte klar abgegrenzt sein und einem separaten Bedürfnis oder einer Aufgabe entsprechen.
Dies sollte so geschehen, dass Sie eine Trennung der Programmteile erreichen - jeder
Bereich sollte klar abgegrenzt sein und einem separaten Bedürfnis oder einer Aufgabe
entsprechen.
Diese Programme/Bereiche sollten die folgenden zwei Eigenschaften haben:
* **Hohe Kohäsion** - die Bereiche sollten eng miteinander verbunden sein.
* **Niedrige Kopplung** - die Abhängigkeiten zwischen den Bereichen sollten so gering wie möglich sein und es sollte vermieden werden,
sich auf interne Implementierungen zu verlassen. Es ist eine sehr gute Idee, sicherzustellen, dass Sie eine geringe Kopplung zu gewährleisten, da dies bedeutet, dass eine Änderung der APIs bestimmter Bereiche
leichter durchführbar sein wird.
* **Niedrige Kopplung** - die Abhängigkeiten zwischen den Bereichen sollten so gering
wie möglich sein und es sollte vermieden werden, sich auf interne Implementierungen zu
verlassen. Es ist eine sehr gute Idee, sicherzustellen, dass Sie eine geringe Kopplung
gewährleisten, da dies bedeutet, dass eine Änderung der APIs bestimmter Bereiche
leichter durchführbar sein wird.
Beachten Sie, dass dies sowohl für die Beziehung zwischen Mods gilt,
als auch für die Beziehung zwischen Bereichen innerhalb eines Mods.
@ -50,7 +65,7 @@ als auch für die Beziehung zwischen Bereichen innerhalb eines Mods.
Eine einfache Möglichkeit, verschiedene Bereiche des Codes zu trennen, ist die Verwendung des Observer-Musters.
Nehmen wir als Beispiel der Freischaltung einer Leistung, wenn ein Spieler zum ersten Mal ein seltenes Tier tötet. Der naive Ansatz wäre, den Code für die Errungenschaft in der mobkill-Funktion den Mob-Namen überprüfen zu lassen und die Auszeichnung freizuschalten, wenn er übereinstimmt.
Dies ist jedoch eine schlechte Idee, da es den Mobs-Mod an die Errungenschaften gekoppelt macht. Wenn man so weitermacht - zum Beispiel, indem man XP zum Mob-Todescode hinzufügt - könnte man eine Menge chaotischer Abhängigkeiten haben.
Dies ist jedoch eine schlechte Idee, da es den Mobs-Mod an die Errungenschaften gekoppelt macht. Wenn man so weitermacht - zum Beispiel, indem man XP zum Mob-Todescode hinzufügt - könnte man eine Menge chaotischer Abhängigkeiten haben.
Hier kommt das Observer-Muster ins Spiel. Anstatt dass sich die mymobs-Mod um Auszeichnungen kümmert,
erhält die mymobs-Mod eine Möglichkeit für andere Bereiche des Codes, ihr Interesse an an einem Ereignis zu registrieren und Daten über das Ereignis zu erhalten.
@ -90,7 +105,7 @@ Eine Möglichkeit, dies zu tun, ist, darüber nachzudenken:
* Welche **Daten** Sie haben.
* Welche **Aktionen** man mit diesen Daten durchführen kann.
* Wie **Ereignisse** (z.B. Formspecs, Stempel, etc.) diese Aktionen auslösen und wie
* Wie **Ereignisse** (z.B. Formspecs, Schläge, etc.) diese Aktionen auslösen und wie
diese Aktionen in der Engine etwas bewirken.
Nehmen wir ein Beispiel für einen Landschutz-Mod. Die Daten, die Sie haben, sind die Gebiete und alle zugehörigen Metadaten. Mögliche Aktionen sind `Erzeugen`, `Bearbeiten` oder `löschen`. Die Ereignisse, die diese Aktionen auslösen, sind Chat-Befehle und Formspec-Empfangsfelder. Dies sind 3 Bereiche, die sich in der Regel gut voneinander trennen lassen.
@ -99,10 +114,10 @@ In Ihren Tests können Sie sicherstellen, dass eine Aktion, wenn sie ausgelöst
das Richtige mit den Daten macht. Sie brauchen nicht zu testen, dass ein Ereignis eine
Aktion aufruft (dazu müsste die Minetest-API verwendet werden, und dieser Bereich des Codes sollte ohnehin so klein wie möglich gehalten werden).
Sie sollten Ihre Datendarstellung in reinem Lua schreiben. "Sauber" bedeutet in diesem Zusammenhang, dass die Funktionen außerhalb von Minetest ausgeführt werden können - keine der Funktionen der Engine müssen aufgerufen werden.
Sie sollten Ihre Datendarstellung in reinem Lua schreiben. "Sauber" bedeutet in diesem Zusammenhang, dass die Funktionen außerhalb von Minetest ausgeführt werden können - keiner der Funktionen der Engine aufgerufen werden müssen.
```lua
-- Data
-- Daten
function land.create(name, area_name)
land.lands[area_name] = {
name = area_name,
@ -136,7 +151,7 @@ end
Ihre Event-Handler müssen mit der Minetest-API interagieren. Sie sollten die die Anzahl der Berechnungen auf ein Minimum beschränken, da Sie diesen Bereich nicht sehr gut testen können.
```lua
-- Siehe
-- View
function land.show_create_formspec(name)
-- Beachten Sie, dass es hier keine komplexen Berechnungen gibt!
return [[
@ -171,7 +186,7 @@ es keine Minetest-Aufrufe oder View-Funktionen, die ihnen ähneln, gibt. Sie sol
<img
width="100%"
src="{{ page.root }}/static/mvc_diagram.svg"
alt="Diagram showing a centered text element">
alt="Diagramm mit einem zentrierten Textelement">
</figure>
Es ist wichtig, dass jeder Bereich nur mit seinen direkten Nachbarn kommuniziert,
@ -183,7 +198,7 @@ wird man häufig eine weniger formale und strenge Art von Design sehen -
Varianten der API-Ansicht.
### API-Sicht
### API-View
In einer idealen Welt würden Sie die oben genannten 3 Bereiche perfekt getrennt haben, wobei alle Ereignisse in den Controller gehen, bevor sie in die normale Ansicht zurückkehren. Aber das ist nicht die reale Welt. Ein guter Kompromiss ist die Reduzierung der Mod in zwei
Teile:
@ -195,12 +210,12 @@ Teile:
rubenwardy's [crafting mod](https://github.com/rubenwardy/crafting 🇬🇧) folgt ungefähr diesem Design. Die Datei `api.lua` besteht fast ausschließlich aus reinen Lua-Funktionen, die die Daten Speicherung und Controller-ähnliche Berechnungen handhaben. `gui.lua` ist die Ansicht für Formspecs und Formspec-Übermittlung, und `async_crafter.lua` ist der View und Controller für einen Knoten formspec und Nodezeitgeber.
Wenn man die Mods auf diese Weise trennt, kann man den API-Teil sehr einfach testen,
da er keine Minetest-APIs verwendet - wie im [nächstes Kapitel](unit_testing.html) und in der Crafting-Mod zu sehen.
da sie keine Minetest-APIs verwendet - wie im [nächstes Kapitel](unit_testing.html) und in der Crafting-Mod zu sehen.
## Zusammenfassung
Gutes Code-Design ist subjektiv und hängt stark von dem Projekt ab, an dem Sie arbeiten. Generell sollte man versuchen, die Kohäsion hoch und die Kopplung niedrig zu halten. Anders formuliert, Halten Sie verwandten Code zusammen und nicht verwandten Code auseinander und halten Sie Abhängigkeiten einfach.
Ich empfehle dringend die Lektüre des [Game Programming Patterns 🇬🇧](http://gameprogrammingpatterns.com/) Buch. Es ist frei verfügbar, [online (auf Englisch) lesbar](http://gameprogrammingpatterns.com/contents.html)
rubenwardy empfehlt dringend die Lektüre des [Game Programming Patterns 🇬🇧](http://gameprogrammingpatterns.com/) Buch. Es ist frei verfügbar, [online (auf Englisch) lesbar](http://gameprogrammingpatterns.com/contents.html)
und geht viel detaillierter als in diesem Buch auf allgemeine Programmiermuster ein, die für Spiele relevant sind.

View File

@ -7,7 +7,7 @@ idx: 8.3
## Einleitung <!-- omit in toc -->
Sicherheit ist sehr wichtig, um sicherzustellen, dass Serverbesitzer durch den Mod keine Daten oder die Kontrolle verlieren.
Sicherheit ist sehr wichtig, um sicherzustellen, dass Serverbesitzer durch die Mod keine Daten oder die Kontrolle verlieren.
- [Zentrale Konzepte](#zentrale-konzepte)
- [Formspecs](#formspecs)
@ -18,11 +18,16 @@ Sicherheit ist sehr wichtig, um sicherzustellen, dass Serverbesitzer durch den M
## Zentrale Konzepte
Das wichtigste Sicherheitskonzept lautet: **Niemals dem Benutzer vertrauen**.
Alles, was der Benutzer eingibt, sollte als bösartig betrachtet werden. Das bedeutet, dass Sie immer prüfen sollten, ob die eingegebenen Informationen gültig sind, dass der Benutzer über die richtigen Berechtigungen verfügt und dass er ansonsten berechtigt ist, diese Aktion durchzuführen (d.h. im Bereich oder als Eigentümer).
Alles, was der Benutzer eingibt, sollte als bösartig betrachtet werden. Das
bedeutet, dass Sie immer prüfen sollten, ob die eingegebenen Informationen
gültig sind, dass der Benutzer über die richtigen Berechtigungen verfügt und
dass er ansonsten berechtigt ist, diese Aktion durchzuführen
(d.h. im Bereich oder als Eigentümer).
Eine böswillige Aktion ist nicht unbedingt die Änderung oder Zerstörung von Daten,
sondern kann der Zugriff auf sensible Daten sein, z. B. Passwort-Hashes oder
private Nachrichten. Dies ist besonders schlimm, wenn der Server Informationen wie E-Mails oder das Alter speichert, was manche zu Überprüfungszwecken tun.
private Nachrichten. Dies ist besonders schlimm, wenn der Server Informationen
wie E-Mails oder das Alter speichert, was manche zu Überprüfungszwecken tun.
## Formspecs
@ -47,22 +52,28 @@ minetest.register_on_player_receive_fields(function(player,
end
```
Können Sie das Problem erkennen? Ein böswilliger Benutzer könnte eine Formularvorgabe mit selbst bestimmten Positionswerten übermitteln, die es ihm ermöglichen, sich an jeden beliebigen Ort zu teleportieren.
Dies könnte sogar automatisiert werden, indem man Änderungen am Client vornimmt, um im Wesentlichen den Befehl den Befehl `/teleport` zu replizieren, ohne dass ein Privileg erforderlich ist.
Können Sie das Problem erkennen? Ein böswilliger Benutzer könnte eine Formularvorgabe
mit selbst bestimmten Positionswerten übermitteln, die es ihm ermöglichen, sich an
jeden beliebigen Ort zu teleportieren. Dies könnte sogar automatisiert werden, indem
man Änderungen am Client vornimmt, um im Wesentlichen den Befehl den Befehl `/teleport`
zu replizieren, ohne dass ein Privileg erforderlich ist.
Die Lösung für diese Art von Problem ist die Verwendung einer
[Context](../players/formspecs.html#contexts), wie zuvor im Kapitel Formspecs gezeigt.
Die Lösung für diese Art von Problem ist die Verwendung eines
[Contexts](../players/formspecs.html#contexts), wie zuvor im Kapitel Formspecs gezeigt.
### Der Zeitpunkt der Prüfung ist nicht der Zeitpunkt der Nutzung <a name="check-use"></a>
Jeder Benutzer kann jederzeit einen beliebigen Formspec mit beliebigen Werten übermitteln, außer wenn die Engine dies verbietet:
Jeder Benutzer kann jederzeit einen beliebigen Formspec mit beliebigen Werten übermitteln,
außer wenn die Engine dies verbietet:
* Die Eingabe eines Knoten-formspec-Einsendungen wird blockiert, wenn der Benutzer zu weit entfernt ist.
* Die Eingabe einer `Node Meta Formspec-Einsendungen` wird blockiert, wenn der Benutzer zu weit entfernt ist.
* Ab 5.0 werden benannte formspecs blockiert, wenn sie noch nicht angezeigt wurden.
Das bedeutet, dass Sie im Handler prüfen sollten, ob der Benutzer die Bedingungen erfüllt, um die Formspec überhaupt anzuzeigen, sowie alle entsprechenden Aktionen.
Das bedeutet, dass Sie im Handler prüfen sollten, ob der Benutzer die Bedingungen erfüllt,
um die Formspec überhaupt anzuzeigen, sowie alle entsprechenden Aktionen.
Die Schwachstelle, die dadurch entsteht, dass die Berechtigungen in der show formspec geprüft werden, aber nicht in der handle formspec verursacht wird, wird Time Of Check is not Time Of Use (TOCTOU) genannt.
Die Schwachstelle, die dadurch entsteht, dass die Berechtigungen in der show formspec geprüft werden,
aber nicht in der handle formspec verursacht wird, wird Time Of Check is not Time Of Use (TOCTOU) genannt.
## (Unsichere) Umgebungen <a name="umgebungen"></a>
@ -76,7 +87,8 @@ local ie = minetest.request_insecure_environment()
ie.os.execute(("path/to/prog %d"):format(3))
```
`string.format` ist eine Funktion in der globalen gemeinsamen Tabelle `string`. Ein bösartiger Mod könnte diese Funktion überschreiben und Material an os.execute übergeben:
`string.format` ist eine Funktion in der globalen gemeinsamen Tabelle `string`. Eine
bösartige Mod könnte diese Funktion überschreiben und Material an os.execute übergeben:
```lua
string.format = function()
@ -84,9 +96,12 @@ string.format = function()
end
```
Der Mod könnte etwas viel Bösartigeres als das Öffnen einer Website weitergeben, wie z. B. einem entfernten Benutzer die Kontrolle über den Rechner zu geben.
Die Mod könnte etwas viel Bösartigeres als das Öffnen einer Website weitergeben, wie z. B.
einem entfernten Benutzer die Kontrolle über den Rechner zu geben.
Einige Regeln für die Verwendung einer unsicheren Umgebung:
* Speichern Sie sie immer in einem lokalen Verzeichnis und geben Sie sie nie in eine Funktion ein.
* Stellen Sie sicher, dass Sie jeder Eingabe in eine unsichere Funktion vertrauen können, um das oben genannte Problem zu vermeiden. Dies bedeutet, dass global umdefinierbare Funktionen vermieden werden sollten.
* Stellen Sie sicher, dass Sie jeder Eingabe in eine unsichere Funktion vertrauen können, um das
oben genannte Problem zu vermeiden. Dies bedeutet, dass global umdefinierbare Funktionen vermieden
werden sollten.

View File

@ -136,6 +136,7 @@ Top node = Oberer Node
true = wahr
Unit Testing = Unit-Tests
unsandboxed = unsandboxed
unsandboxed environment = unsandboxed Umgebung
Version Control System = Version Control System
wear = Abnutzung
Your turn = Sie sind dran