Tiger Simulator A
Ein kurzer Einblick in den Tiger Simulator.
OCCDN ist ein Portal für freie Entwickler, Open-Source-Games und Software. Projekte in JavaScript, C, C++, Python und Node.js – offen zum Lernen, Forken, Weiterbauen und Teilen.
$ git clone https://github.com/d4brain
✓ public repositories found
✓ source code available
✓ community forum online
const occdn = {
games: "open",
software: "open",
ideas: "welcome"
};
// Build something worth sharing.
Eine Auswahl rund um Games, Unreal Engine und Game Development von Ess Aitch und KI Kulisse. Klicke auf ein Bild, um das Video auf YouTube zu starten.
Mehr Videos gibt es direkt auf den Kanälen Ess Aitch und KI Kulisse.
Hi and welcome to our new developer portal!
Discover open-source projects, games, tools, and experiments built
with JavaScript,C, C++, Python, Node.js, and more.
Browse the code, explore our repositories, join the community, and build something awesome.
Explore. Learn. Build. Share.
Python für ein E2E-Chat?</h2><p>Python ist die schnellste Sprache, mit der man ein Chat-System von der ersten Zeile bis zum laufenden Betrieb begreifen kann. Für dieses Projekt brauchst du nicht mal alle Standard-Bibliotheken auswendig zu können – <code>socket</code>, <code>ssl</code>, <code>threading</code> und <code>httpx</code> reichen, um ein vollwertiges Ende-zu-ende-verschlüsseltes Chat-System zu bauen. Der eigentliche Lerneffekt liegt in der Architektur: Wer die Schichten <em>Socket → TLS → Protokoll → UI</em> einmal sauber getrennt hat, versteht auch jede größere Anwendung besser.</p><h2>Das Prinzip: E2E-Verschlüsselung statt nur TLS</h2><p>Wichtig zu verstehen ist der Unterschied zwischen Transportverschlüsselung und echter Ende-zu-Ende-Verschlüsselung:</p><ul><li><strong>TLS (Transport)</strong> schützt die Daten nur zwischen Client und Server. Der Server selbst kann die Nachrichten lesen – er sitzt als Mitleser im Tunnel.</li><li><strong>E2E-Verschlüsselung (Ziel)</strong> schützt die Daten zwischen zwei Clients. Der Server leitet nur unlesbare Bytes weiter und kann den Inhalt nicht entschlüsseln.</li></ul><p>Das Grundrezept ist asymmetrische Kryptografie: Jeder Client hat ein Schlüssel-Paar. Der <em>öffentliche</em> Schlüssel wird dem Server gemeldet (und ist für alle sichtbar), der <em>private</em> Schlüssel bleibt exklusiv auf dem Gerät. Sendet Alice eine Nachricht an Bob, verschlüsselt sie mit Bobs <strong>öffentlichem</strong> Schlüssel – nur Bobs <strong>privater</strong> Schlüssel kann sie wieder entschlüsseln.</p><h2>Der Tunnel: Nachrichten durch die Server-Masche</h2><p>Der Tunnel ist das Protokoll, das die verschlüsselten Nachrichten durch den Server transportiert – ohne dass der Server sie versteht:</p><ol><li><strong>Registrieren:</strong> Jeder Client meldet sich mit seinem öffentlichen Schlüssel an: <code>MSG("hello", "alice", "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----\n")</code></li><li><strong>Server speichert:</strong> Der Server hält eine Tabelle <code>user → pubkey</code>. Er sieht nur, dass jemand „alice" heißt – nicht, was sie schreibt.</li><li><strong>Senden:</strong> Alice verschlüsselt ihre Nachricht mit Bobs Public Key und schickt: <code>MSG("msg", "bob", "<cyphertext>")</code></li><li><strong>Server leitet weiter:</strong> Er packt die Nachricht an Bobs wartende Queue. Die Cyphertext-Bytes sind für ihn undurchsichtiges Rauschen.</li><li><strong>Bob entschlüsselt:</strong> Mit seinem privaten Schlüssel liest er die Nachricht – nur er.</li></ol><h2>Der Server (ca. 40 Zeilen)</h2><pre class="highlight"><code>import socket, ssl, json, threadingfrom collections import defaultdictSERVER = socket.socket(socket.AF_INET, socket.SOCK_STREAM)SERVER.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)SERVER.bind(("0.0.0.0", 8443))SERVER.listen()cert = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)cert.load_cert_chain("server.crt", "server.key")clients = {} # username → (socket, context)lock = threading.Lock()def handle(conn, addr): data = conn.recv(4096) msg = json.loads(data) if msg["type"] == "hello": with lock: clients[msg["user"]] = (conn, msg["pubkey"]) elif msg["type"] == "msg": with lock: target = clients.get(msg["to"]) if target: target[0].sendall(json.dumps(msg).encode()) conn.close()print("Server auf Port 8443")while True: conn, addr = SERVER.accept() threading.Thread(target=handle, args=(conn, addr), daemon=True).start()</code></pre><h2>Der Client (ca. 50 Zeilen)</h2><pre class="highlight"><code>import ssl, json, socketfrom cryptography.hazmat.primitives.asymmetric import x25519from cryptography.hazmat.primitives import serialization# 1. Schlüssel-Paar erzeugen – privater bleibt hiersk = x25519.X25519PrivateKey.generate()pk = sk.public_key()pub_b64 = base64.b64encode( pk.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo, )).decode()# 2. TLS-Verbindung (vertraulicher Kanal zum Server)ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)ctx.load_verify_locations("server.crt")s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)with ctx.wrap_socket(s) as conn: conn.connect(("occdn.com", 8443)) conn.sendall(json.dumps( {"type": "hello", "user": "alice", "pubkey": pub_b64} ).encode())</code></pre><p>Der <code>hello</code>-Handshake ist der einzige Moment, in dem der Server <em>etwas</em> über Alice erfährt: ihren Benutzernamen. Der Inhalt ihrer Nachrichten bleibt für ihn mathematisch unerreichbar.</p><h2>Was der Server wirklich kann – und was nicht</h2><table><tbody><tr><th>Was der Server sieht</th><th>Was er NICHT sieht</th></tr><tr><td>Benutzernamen und Zeitstempel</td><td>Der Klartext der Nachrichten</td></tr><tr><td>Wen mit wem gesprochen wird</td><td>Wie oft und wie lange man sich schreibt</td></tr><tr><td>Dass eine Nachricht ging</td><td>Ihren Inhalt</td></tr></tbody></table><p>Transparenz gehört ins Protokoll: Der Server kennt Metadaten. Wer wirklich „unsichtbar" sein will, braucht zusätzlich Padding und Zeitstempel-Verschleierung – das geht aber über dieses Tutorial hinaus.</p><h2>Fehler, die dich garantiert kosten</h2><ul><li><strong>Public Key direkt ins JSON-String:</strong> PEM-Strings enthalten Zeilenumbrüche – im JSON müssen die als <code>\n</code> escaped werden. Ungefixt: <code>json.decoder.JSONDecodeError</code>.</li><li><strong>Neuer Schlüssel pro Start:</strong> Wer beim Neustarten einen neuen Public Key meldet, wird von bestehenden Clients nicht erkannt. Für Prototypen ok, für Produkt: Schlüssel in einer Datei speichern.</li><li><strong>Client schließt Socket nach dem Senden:</strong> Wenn der Client nach jeder Nachricht die Verbindung trennt, verliert er die Antwort des Gegenübers. In Chat-Systemen: persistent halten.</li><li><strong>Falsches TLS-Zertifikat:</strong> Ohne <code>load_verify_locations</code> oder mit selbstsigniertem Zert ohne <code>check_hostname=False</code> (nur für Tests!) wirft <code>wrap_socket</code> eine <code>SSLError</code>.</li></ul><h2>Weiterbauen</h2><p>Wenn der Prototyp läuft, sind die nächsten Schritte:</p><ol><li><strong>Ende-zu-Ende mit X25519 + AES:</strong> Statt „nur" TLS-Tunnel: Ephemeraler Schlüssel-Austausch pro Nachricht, danach symmetrische AES-Verschlüsselung – das ist die Industrie-Praxis.</li><li><strong>UI-Integration:</strong> Der Client läuft heute im Terminal. Mit <code>httpx</code> und einem Web-Frontend wird es ein echter Chat-Dienst.</li><li><strong>Gruppen & Endorsement:</strong> Gruppen-Chats brauchen Broadcast-Logik; Endorsement (Signatur) beweist, dass eine Nachricht wirklich vom besagten User kommt.</li></ol><p>Das Schöne an Python: Du hast das ganze System in unter 100 Zeilen – und verstehst jede Zeile. Das ist der Punkt. Nicht „funktioniert" – <em>verstanden</em>.</p>
Python für ein E2E-Chat?</h2><p>Python ist die schnellste Sprache, mit der man ein Chat-System von der ersten Zeile bis zum laufenden Betrieb begreifen kann. Für dieses Projekt brauchst du nicht mal alle Standard-Bibliotheken auswendig zu können – <code>socket</code>, <code>ssl</code>, <code>threading</code> und <code>httpx</code> reichen, um ein vollwertiges Ende-zu-ende-verschlüsseltes Chat-System zu bauen. Der eigentliche Lerneffekt liegt in der Architektur: Wer die Schichten <em>Socket → TLS → Protokoll → UI</em> einmal sauber getrennt hat, versteht auch jede größere Anwendung besser.</p><h2>Das Prinzip: E2E-Verschlüsselung statt nur TLS</h2><p>Wichtig zu verstehen ist der Unterschied zwischen Transportverschlüsselung und echter Ende-zu-Ende-Verschlüsselung:</p><ul><li><strong>TLS (Transport)</strong> schützt die Daten nur zwischen Client und Server. Der Server selbst kann die Nachrichten lesen – er sitzt als Mitleser im Tunnel.</li><li><strong>E2E-Verschlüsselung (Ziel)</strong> schützt die Daten zwischen zwei Clients. Der Server leitet nur unlesbare Bytes weiter und kann den Inhalt nicht entschlüsseln.</li></ul><p>Das Grundrezept ist asymmetrische Kryptografie: Jeder Client hat ein Schlüssel-Paar. Der <em>öffentliche</em> Schlüssel wird dem Server gemeldet (und ist für alle sichtbar), der <em>private</em> Schlüssel bleibt exklusiv auf dem Gerät. Sendet Alice eine Nachricht an Bob, verschlüsselt sie mit Bobs <strong>öffentlichem</strong> Schlüssel – nur Bobs <strong>privater</strong> Schlüssel kann sie wieder entschlüsseln.</p><h2>Der Tunnel: Nachrichten durch die Server-Masche</h2><p>Der Tunnel ist das Protokoll, das die verschlüsselten Nachrichten durch den Server transportiert – ohne dass der Server sie versteht:</p><ol><li><strong>Registrieren:</strong> Jeder Client meldet sich mit seinem öffentlichen Schlüssel an: <code>MSG("hello", "alice", "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----\n")</code></li><li><strong>Server speichert:</strong> Der Server hält eine Tabelle <code>user → pubkey</code>. Er sieht nur, dass jemand „alice" heißt – nicht, was sie schreibt.</li><li><strong>Senden:</strong> Alice verschlüsselt ihre Nachricht mit Bobs Public Key und schickt: <code>MSG("msg", "bob", "<cyphertext>")</code></li><li><strong>Server leitet weiter:</strong> Er packt die Nachricht an Bobs wartende Queue. Die Cyphertext-Bytes sind für ihn undurchsichtiges Rauschen.</li><li><strong>Bob entschlüsselt:</strong> Mit seinem privaten Schlüssel liest er die Nachricht – nur er.</li></ol><h2>Der Server (ca. 40 Zeilen)</h2><pre class="highlight"><code>import socket, ssl, json, threadingfrom collections import defaultdictSERVER = socket.socket(socket.AF_INET, socket.SOCK_STREAM)SERVER.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)SERVER.bind(("0.0.0.0", 8443))SERVER.listen()cert = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)cert.load_cert_chain("server.crt", "server.key")clients = {} # username → (socket, context)lock = threading.Lock()def handle(conn, addr): data = conn.recv(4096) msg = json.loads(data) if msg["type"] == "hello": with lock: clients[msg["user"]] = (conn, msg["pubkey"]) elif msg["type"] == "msg": with lock: target = clients.get(msg["to"]) if target: target[0].sendall(json.dumps(msg).encode()) conn.close()print("Server auf Port 8443")while True: conn, addr = SERVER.accept() threading.Thread(target=handle, args=(conn, addr), daemon=True).start()</code></pre><h2>Der Client (ca. 50 Zeilen)</h2><pre class="highlight"><code>import ssl, json, socketfrom cryptography.hazmat.primitives.asymmetric import x25519from cryptography.hazmat.primitives import serialization# 1. Schlüssel-Paar erzeugen – privater bleibt hiersk = x25519.X25519PrivateKey.generate()pk = sk.public_key()pub_b64 = base64.b64encode( pk.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo, )).decode()# 2. TLS-Verbindung (vertraulicher Kanal zum Server)ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)ctx.load_verify_locations("server.crt")s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)with ctx.wrap_socket(s) as conn: conn.connect(("occdn.com", 8443)) conn.sendall(json.dumps( {"type": "hello", "user": "alice", "pubkey": pub_b64} ).encode())</code></pre><p>Der <code>hello</code>-Handshake ist der einzige Moment, in dem der Server <em>etwas</em> über Alice erfährt: ihren Benutzernamen. Der Inhalt ihrer Nachrichten bleibt für ihn mathematisch unerreichbar.</p><h2>Was der Server wirklich kann – und was nicht</h2><table><tbody><tr><th>Was der Server sieht</th><th>Was er NICHT sieht</th></tr><tr><td>Benutzernamen und Zeitstempel</td><td>Der Klartext der Nachrichten</td></tr><tr><td>Wen mit wem gesprochen wird</td><td>Wie oft und wie lange man sich schreibt</td></tr><tr><td>Dass eine Nachricht ging</td><td>Ihren Inhalt</td></tr></tbody></table><p>Transparenz gehört ins Protokoll: Der Server kennt Metadaten. Wer wirklich „unsichtbar" sein will, braucht zusätzlich Padding und Zeitstempel-Verschleierung – das geht aber über dieses Tutorial hinaus.</p><h2>Fehler, die dich garantiert kosten</h2><ul><li><strong>Public Key direkt ins JSON-String:</strong> PEM-Strings enthalten Zeilenumbrüche – im JSON müssen die als <code>\n</code> escaped werden. Ungefixt: <code>json.decoder.JSONDecodeError</code>.</li><li><strong>Neuer Schlüssel pro Start:</strong> Wer beim Neustarten einen neuen Public Key meldet, wird von bestehenden Clients nicht erkannt. Für Prototypen ok, für Produkt: Schlüssel in einer Datei speichern.</li><li><strong>Client schließt Socket nach dem Senden:</strong> Wenn der Client nach jeder Nachricht die Verbindung trennt, verliert er die Antwort des Gegenübers. In Chat-Systemen: persistent halten.</li><li><strong>Falsches TLS-Zertifikat:</strong> Ohne <code>load_verify_locations</code> oder mit selbstsigniertem Zert ohne <code>check_hostname=False</code> (nur für Tests!) wirft <code>wrap_socket</code> eine <code>SSLError</code>.</li></ul><h2>Weiterbauen</h2><p>Wenn der Prototyp läuft, sind die nächsten Schritte:</p><ol><li><strong>Ende-zu-Ende mit X25519 + AES:</strong> Statt „nur" TLS-Tunnel: Ephemeraler Schlüssel-Austausch pro Nachricht, danach symmetrische AES-Verschlüsselung – das ist die Industrie-Praxis.</li><li><strong>UI-Integration:</strong> Der Client läuft heute im Terminal. Mit <code>httpx</code> und einem Web-Frontend wird es ein echter Chat-Dienst.</li><li><strong>Gruppen & Endorsement:</strong> Gruppen-Chats brauchen Broadcast-Logik; Endorsement (Signatur) beweist, dass eine Nachricht wirklich vom besagten User kommt.</li></ol><p>Das Schöne an Python: Du hast das ganze System in unter 100 Zeilen – und verstehst jede Zeile. Das ist der Punkt. Nicht „funktioniert" – <em>verstanden</em>.</p>
Ein zentraler Einstiegspunkt für Projekte, spielbare Builds und Quellcode.
Browser-Spiele und OpenGL-Projekte direkt ausprobieren.
core.catchiai.com →Öffentliche Repositories durchsuchen, klonen, lernen und weiterentwickeln.
github.com/d4brain →Fragen stellen, Projekte zeigen, Feedback bekommen und Ideen diskutieren.
forum.occdn.com →OCCDN bündelt freie Software, spielbare Experimente und Quellcode an einem Ort. Der Fokus liegt auf nachvollziehbaren Projekten, direktem Zugriff und einer Community, die Ideen nicht nur diskutiert, sondern baut.