Was haben Lexer, Parser und Counter-Strike gemeinsam? Richtig! Eine schöne Open Source Story.
Computerspiele sind für viele Software-Entwicklerinnen und -Entwickler der Einstieg. Andere wiederum steigen über den klassischen Bildungsweg eines Informatik-Studiums in die Softwareentwicklung ein. Dabei wird oft viel Theorie wie Lexer, Parser und Compilerbau durchgenommen. Doch was haben Computerspiele mit Lexer und Parser gemeinsam?
Andy erzählt eine Story, wie er vor Jahren sich mit Lexer und Parser anhand einer Counter-Strike-Konfigurationsdatei vertraut gemacht hat. Eigentlich nur, um eine datengetriebene Spielanalyse zu betreiben. Raus kam ein Lexer und Parser für das Valve Data Format (VDF).
Eine Geschichte voller Over-Engineering, Open Source, Spaß und einem Job-Angebot.
Bonus: Wie Wolfgang nur ans cheaten denkt, was autoexec mit Maustreibern zu tun hat und was Landmaschinen auf YouTube mit Rabbitholes zu tun haben.
Unsere aktuellen Werbepartner findest du auf https://engineeringkiosk.dev/partners
Links
- Return to Monkey Island: https://returntomonkeyisland.com/
- Crash Bandicoot: https://www.crashbandicoot.com/de
- DreamHack LAN-Party: https://de.wikipedia.org/wiki/DreamHack
- Counter-Strike: Global Offensive: https://store.steampowered.com/app/730/CounterStrike_Global_Offensive/
- LANSuite auf GitHub: https://github.com/lansuite/lansuite
- Episode #41 SQL-Injections https://engineeringkiosk.dev/episodes/41
- Tactical Ops: Assault on Terror: https://de.wikipedia.org/wiki/Tactical_Ops:_Assault_on_Terror
- ESL: https://esl.com/
- Source (Spiel-Engine): https://de.wikipedia.org/wiki/Source_(Spiel-Engine)
- Philips HUE: https://www.philips-hue.com/de-de
- Valve Data Format (VDF) - Format: https://developer.valvesoftware.com/wiki/KeyValues
- Valve Data Format (VDF) - Sample Configuration File: https://developer.valvesoftware.com/wiki/Counter-Strike:_Global_Offensive_Game_State_Integration#Sample_Configuration_File
- Counter-Strike: Global Offensive Game State Integration: https://developer.valvesoftware.com/wiki/Counter-Strike:_Global_Offensive_Game_State_Integration
- A Lexer and Parser for Valves Data Format (known as vdf) written in Go: https://github.com/andygrunwald/vdf
- Engineering Kiosk #38 Monitoring, Metriken, Tracing, Alerting, Observability: https://engineeringkiosk.dev/podcast/episode/38-monitoring-metriken-tracing-alerting-observability/
- Drachenbuch (Compiler Bau): https://de.wikipedia.org/wiki/Drachenbuch
- Handwritten Parsers & Lexers in Go: https://blog.gopheracademy.com/advent-2014/parsers-lexers/
- InfluxDB: https://www.influxdata.com/
- Influx Query Language: https://docs.influxdata.com/influxdb/v1.8/query_language/
- Flow-Status: https://de.wikipedia.org/wiki/Flow_(Psychologie)
- ANTLR (ANother Tool for Language Recognition): https://www.antlr.org/
- Erweiterte Backus-Naur-Form: https://de.wikipedia.org/wiki/Erweiterte_Backus-Naur-Form
- FOSDEM 2023 - Konferenz: https://fosdem.org/
- Faceit: https://www.faceit.com/de
- Engineering Kiosk #03 Over-Engineering, das Werkzeug des Teufels?: https://engineeringkiosk.dev/podcast/episode/03-over-engineering-das-werkzeug-des-teufels/
- Engineering Kiosk #23 Schaltest du noch oder automatisiert du schon: Home Automation: https://engineeringkiosk.dev/podcast/episode/23-schaltest-du-noch-oder-automatisiert-du-schon-home-automation/
- Open Broadcaster Software (OBS): https://obsproject.com/de
- Anwendungsfall "Home Assistant CS:GO game state integration": https://www.youtube.com/watch?v=kEM54QmAMlw
- Anwendungsfall "CS:GO C4 Hue Lights (Game State Integration)": https://www.youtube.com/watch?v=QBdI54MHB-k
- Anwendungsfall "CS:GO Game State Integration Broadcast HUD": https://www.youtube.com/watch?v=TQPU03yLSoA
- Monkey Island Sound am Ende https://www.youtube.com/watch?v=qUMKy2Jk3Oo
Sprungmarken
Hosts
- Wolfgang Gassler (https://twitter.com/schafele)
- Andy Grunwald (https://twitter.com/andygrunwald)
Feedback (gerne auch als Voice Message)
- Email: stehtisch@engineeringkiosk.dev
- Twitter: https://twitter.com/EngKiosk
- WhatsApp +49 15678 136776
Transkript
Wolfi Gassler (00:00:05 - 00:00:36)
Wie findet man heutzutage einen Job in einer internationalen Firma? Genau, durch Over-Engineering. Man setzt sich also als zockender Informatiker hin und schreibt für Counter-Strike einen Lexer und einen Barser in Go, um seine Freunde auszuspionieren. Klingt komisch? Habe ich mir auch gedacht. Und darum habe ich mir die Geschichte von Andy ganz genau erklären lassen. Ich sag's euch, parade Beispiel, wie man als Nerd Probleme begegnet, was man aber dabei lernen kann und worum Gaming und LAN-Partys vielleicht nicht nur vergeudete Zeit sind.
Wolfi Gassler (00:00:41 - 00:00:56)
So, wir starten heute mal ein Experiment. Und zwar, ihr habt keine Ahnung, was Andi heute vorbereitet hat. Er hat mir nur gesagt, es geht um Counter-Strike und Lexer. Was für mich absolut keinen Sinn macht. Also, Andi, erklär mir mal.
Andy Grunwald (00:00:56 - 00:01:09)
Ich fange jetzt nicht an mit der Erklärung, sondern einfach mal mit so ein paar Fragen. Wolfgang, du bist ja auch keine 20 mehr, ne? Also... 22. Ja, ist ja trotzdem keine 20 mehr, ne? Wann hattest du deinen ersten Computer? Mit welchem Alter?
Wolfi Gassler (00:01:16 - 00:01:38)
Ich hab keine Ahnung. Ich hab den von meinem Bruder bekommen, der hat schon in der IT irgendwie gearbeitet. Und es war ... Ja, ich hab keine Ahnung. Es war auf jeden Fall mit Disketten, ich glaub, ohne Festplatte. Man hat nur Disketten irgendwie reingeschoben fürs Betriebssystem booten und dann wieder gewechselt, wenn man irgendwas spielen wollte. Und da war irgendwie so ein Jump & Run oder so, hab ich drauflaufen lassen können.
Andy Grunwald (00:01:38 - 00:01:51)
Kennst du den Namen von dem Jump & Run noch? Aber das war schon der erste Use-Case von dir, oder? Mit dem Computer. Als elfjähriger Wolfgang in Österreich, hattest du eine Diskette in der Hand, wahrscheinlich noch die großen Disketten, oder?
Andy Grunwald (00:02:01 - 00:02:08)
Aber der erste Use-Case war schon zocken, war schon spielen? Oder hast du mit Basic irgendwas und Turbo Pascal programmiert?
Wolfi Gassler (00:02:08 - 00:02:47)
Ich glaube, das war vor der Zeit noch. Also es war definitiv der Game-Use-Case. Und auch später, wie ich meinen ersten 386er bekommen habe, das war so der erste, den ich mal, glaube ich, selber gekauft habe dann wirklich. Oder mehr oder weniger selber gekauft habe. Da hat es dann alles angefangen, dass man vier Spiele in der Autoexec.bat die Maustreiber nicht lädt, damit man mehr Memory hat und mit dieser HighRAM-Geschichte und diesen ganzen Sachen, die wir absolut nichts gesagt haben damals, aber ich habe halt einfach irgendwo gehört, das macht Sinn und habe dann halt da je nach Spiel den Maustreiber geladen oder nicht geladen und habe mir da meine eigenen Menüs irgendwie geschrieben in der Autoexec.bat. Und so hat alles angefangen.
Andy Grunwald (00:02:47 - 00:03:00)
An welche Spiele kannst du dich denn noch erinnern die du gespielt hast? Also warst du so ein Pac-Man oder so ein Monkey Island Mensch oder warst du eher so der Crash Bandicoot Kollege oder Wipeout, so dieses Flugzeugrennen?
Wolfi Gassler (00:03:00 - 00:03:27)
Also definitiv Monkey Island. Monkey Island habe ich schon gespielt auf Englisch, wie ich selber kein Englisch gekonnt habe, habe ich auch von meinen Geschwistern irgendwie bekommen. Hab null verstanden, aber trotzdem probiert es irgendwie zu spielen. Und seitdem bin ich Monkey Island Fan und ich bin extrem enttäuscht, dass ich das neue Monkey Island Return to Monkey Island nicht spielen kann, weil man braucht Windows dafür. Und ich hab eigentlich aktuell einfach keinen Windows PC oder eine Konsole, wo ich das spielen könnte. Und auf Linux funktioniert das Ding nicht.
Wolfi Gassler (00:03:29 - 00:03:38)
Nein, aber für Monkey Island hätte ich eine Ausnahme gemacht. Ich spiele mit dir die ganze Zeit, das ist wohl Aufwand genug. Jede Woche einmal für dieses Podcast. Den Podcast, sorry.
Andy Grunwald (00:03:43 - 00:03:46)
Was war denn das letzte Spiel, was du so gespielt hast? Und wann war das?
Wolfi Gassler (00:03:47 - 00:04:04)
Viele, viele Jahre her und wahrscheinlich zumindest motiviert habe ich vor allem diese Adventure immer gespielt. So irgendwelche Ballerspiele oder so habe ich nur bei irgendwelchen LAN-Partys oder so gespielt und ich war eigentlich immer recht schlecht darin. Also Counter-Strike sagt mir was, habe ich mal gespielt, aber wenn nur irgendwie bei Freunden.
Andy Grunwald (00:04:04 - 00:04:11)
Und diese Adventure-Games dann zusammen oder immer als Eigenbrötler und alleine?
Wolfi Gassler (00:04:12 - 00:04:17)
Alleine im Keller sozusagen, wie das ein richtiger Informatiker so macht.
Andy Grunwald (00:04:17 - 00:04:32)
Aber du hast ein gutes Thema angesprochen, Ladenpartys, da kommen wir gleich auch nochmal drauf, klasse. Warst du selbst mit deinem Rechner auf einer Ladenparty oder warst du immer einer dieser Besucher, die abends mal kurz rumkamen, sich irgendwo bei einem Kumpel am Computer gesetzt haben, eine Wurst gegessen haben und dann weitergezogen sind?
Wolfi Gassler (00:04:33 - 00:04:42)
Ich glaub eher Zweiteres, ja. Ich kann mich nicht erinnern, dass ich da mal ... Also, vielleicht für andere Spiele schon, aber so klassische LAN-Partys, da war ich meistens Besucher, ja.
Andy Grunwald (00:04:42 - 00:04:49)
Aber das war dann eher schon so diese kleinen privaten LAN-Partys mit fünf bis zehn Leuten und nicht diese großen wie Dreamforce oder Ähnliches, oder?
Wolfi Gassler (00:04:49 - 00:04:59)
Hey, das hat's in Österreich sowieso nicht gegeben, glaub ich. Außerdem ist das vor dieser ganzen Internetzeit und so weiter, das war ja wirklich so lokale LAN-Partys, wo man noch irgendwie so selber ein Netzwerk aufbaut.
Andy Grunwald (00:05:00 - 00:05:06)
Das war die Netzwerkverbindung damals, wirklich T-Stücke und Endterminatoren, also 100 Mbit Kabel.
Wolfi Gassler (00:05:07 - 00:05:28)
Habe ich auf jeden Fall auch verwendet, ja, aber das war dann mehr so mit Freunden in kleineren LAN-Partys oder so fixe Verkabelungen mit Nachbarn oder so, hat es da auch mal gegeben bei einem Freund, da hatten wir das installiert, ja, stimmt, mit T-Stücken und so, das klassische, was war denn das, ein Gigabit, ein Megabit, nein, das war nicht mal ein Megabit, oder?
Andy Grunwald (00:05:32 - 00:05:43)
War ne tolle Zeit auf jeden Fall. Wer hat denn noch ein T-Stück? Und oh, ich hab keinen Endterminator mehr. Oh. Naja, auf der anderen Seite, die Probleme haben sich halt auch nur geändert. Später ging's halt darum, oh, wer hat noch ein Sechser-Switch?
Andy Grunwald (00:05:48 - 00:06:10)
Logisch. Was war so der Grund, warum du Computer gespielt hast? Einfach so zum Abschalten oder weil du das nächste Rätsel bei Monkey Island wirklich haben wolltest und nicht mehr schlafen konntest? War das die Zeit, wo du schon arbeiten gegangen bist? Oder warst du noch in der Schule oder wieder in der Uni? Nur, um das ein bisschen einzuordnen.
Wolfi Gassler (00:06:10 - 00:06:53)
Nein, nein, also die Spielerei war alles Schulzeit. Wie ich dann studieren angefangen habe, da habe ich dann schon an Projekten gearbeitet, gefreelanced und solche Sachen gemacht, da war das Spiel genug sozusagen, das war alles davor. Mir fällt übrigens gerade ein sehr cooles Spiel ein, was wir auch hatten, das war so der Vorgänger. Das war so ein rundenbasiertes Weltraumspiel, wo wir den Spielstand dann auf Disketten abgespeichert haben und in der Schule hat es dann einen Host gegeben. Dem haben wir diese Disketten dann alle mitgegeben. Der hat diese Runden zusammengeführt. Am nächsten Tag hat er wieder alle Disketten zurückgebracht, den Spielstand wieder verteilt. Wir haben wieder einen Zug machen können. Am nächsten Tag ist es wieder losgegangen, zurück in die Schule, Disketten verteilt. Und so haben wir so ein Weltraumspiel, ein Netzwerkspiel quasi.
Wolfi Gassler (00:06:55 - 00:07:04)
Halb analog gespielt, genau. Ich hab mal rausgesucht den Namen, aber ich weiß ihn leider nicht mehr genau. Ist recht schwierig zu finden, wie das Ding geheißen hat.
Andy Grunwald (00:07:04 - 00:07:08)
Was blockt dich denn heutzutage vom Computerspielen? Warum spielst du heutzutage keinen Computer mehr?
Wolfi Gassler (00:07:09 - 00:07:17)
Ich würd mal sagen, primär die Zeit. Ist mir zu schade. Arbeite lieber an Projekten. Ist ja auch ein gewisses Spiel und eine Herausforderung. Spielst du noch?
Andy Grunwald (00:07:17 - 00:07:38)
In letzter Zeit spiel ich nicht mehr, nein. Ich hab ungefähr Anfang Corona, Anfang erstes Jahr, Mitte ersten Jahres Corona hab ich aufgehört, weil ich ... da irgendwie hinterfragt habe, wie ich meine Zeit verbringe. Und dann hab ich gemerkt, mit Zocken verschwende ich sie recht viel. Und dann hab ich einfach aufgehört.
Wolfi Gassler (00:07:38 - 00:07:47)
Du bist wirklich gut, dir halb Deutschland immer zum Feind zu machen. Du schaffst das wirklich ganz gut. Wenn du sagst, alle Gamer, das ist Zeitverschwendung.
Andy Grunwald (00:07:48 - 00:08:15)
Nein, nein, nein. Und warum, das sag ich dir gleich in einer Minute. Aber der andere Grund war ganz einfach, ich habe einen unglaublich alten Windows-PC. Mit unglaublich alt mein ich so zwölf Jahre alt, 13 Jahre alt. Und du kannst dir vorstellen, dass die Grafikkarte natürlich auch nicht mehr die aktuellste ist und somit dann die aktuellste Version von Counter-Strike natürlich auch auf der kleinsten Grafikstufe dann so ein bisschen ruckelt. Und wenn du dann tot bist, du siehst den Gegner noch niemals, weil der Computer ruckelt, das macht dann irgendwie keinen Spaß.
Wolfi Gassler (00:08:16 - 00:08:20)
Siehst du, Return of Monkey Island könntest du wahrscheinlich spielen. Du musst nur die richtigen Spiele spielen.
Andy Grunwald (00:08:20 - 00:08:29)
Könnte ich sehr wahrscheinlich spielen, aber dann hatte ich mir gedacht, okay, investierst du jetzt wieder Geld dafür. Ah, habe ich dann auch nicht gemacht. Und dann war es, habe ich gesagt, komm, probierst du es mal aus.
Wolfi Gassler (00:08:30 - 00:08:35)
Ich bin ja schon kurz davor, nur einen Windows-Rechner zu kaufen für das dumme Return of Monkey Island.
Wolfi Gassler (00:08:37 - 00:08:44)
Ich weiß nicht mal, wie das heutzutage funktioniert mit diesen Lizenzen. Man kann ja Windows nicht mehr einfach so rabkopieren, oder? Geht gar nicht mehr so einfach.
Andy Grunwald (00:08:44 - 00:08:58)
Aber die ganze Story, die du gerade so ein bisschen erzählt hast, da habe ich mich wiedergefunden. Das bedeutet, ich war früher auch immer so auf so kleinen Ladenpartys und wir haben dann auch mal größere Ladenpartys in der Autowerkstatt organisiert, wo dann so 30, 40 Leute waren.
Andy Grunwald (00:09:05 - 00:10:15)
Naja war halt richtig dodgy so auf dem Hinterhof in so einer Autowerkstatt Hebebühne wurde zum Buffet umfunktioniert, wo dann die Pizza angeliefert wurde und so weiter und so fort und wir hatten das natürlich dann auch ein paar Leute, die waren in der Clique über uns, die waren ein bisschen älter und die hatten dann ein bisschen mehr Geld schon und ein bisschen mehr Ahnung von IT die haben sich dann, so ein Open-Source-System aufgesetzt, so einen zentralen Server, und die haben dann immer so den Counter-Strike-Server gehostet und den Unreal Tournament und Tactical Ops-Server, und dann hatten wir so ein LAN-Management, PHP-System und so weiter und so fort, das ich zwischenzeitlich dann auch mal auf GitHub gehoben habe und ganz viel SQL-Injections gefixt habe. Grüße an unsere letzte Episode. Wer also ein bisschen was über SQL-Injections hören möchte, kann gerne in die Episode 41 einmal reinhören. Na ja, auf jeden Fall ging das über die letzten paar Jahre immer so ein Up and Down. Früher hab ich sehr, sehr, sehr viel Unreal Tournament 1999 gespielt. Und davon ein Mod, der nennte sich Tactical Ops. Und Tactical Ops war eigentlich die Unreal-Tournament-Version von Counter-Strike. Weil Counter-Strike ist ja dann dieser Team-Ego-Shooter auf Basis von Half-Life.
Andy Grunwald (00:10:19 - 00:10:28)
Ja, das war die Unreal-Tournament-Version damals, genau. Es gibt ja Unreal-Tournament 2003 und da gibt's ja noch verschiedene Unreal-Tournament-Versionen. Das war also die ganz alte.
Andy Grunwald (00:10:31 - 00:10:45)
Nee, Counter-Strike gab's ja schon ein bisschen was länger, aber Counter-Strike selbst hatte ja mehrere Versionen. Das ist normalerweise Counter-Strike 1.6, dann Counter-Strike Source und dann Counter-Strike Global Offensive. Das ist jetzt dieses sogenannte CSGO. GO steht für Global Offensive.
Wolfi Gassler (00:10:45 - 00:10:50)
Drum wolltest du es unbedingt spielen, oder? Wenn das Go heißt, so wie deine Lieblingsprogrammiersprache.
Andy Grunwald (00:10:50 - 00:11:07)
Ich bin ein Riesen-Go-Fan, aber ich glaub, Counter-Strike Global Offensive kam raus, bevor es die Programmiersprache Go gab. Es könnte natürlich auch sein, dass jemand bei Google gearbeitet hat, sehr früh an der Sprache Go gearbeitet hat und dann nach Valve gewechselt ist, um ... Weiß ich nicht.
Andy Grunwald (00:11:08 - 00:11:21)
Auf jeden Fall war's dann immer so ein Up and Down und irgendwann hat keiner mehr Tactical Ops gespielt und dann bin ich zur bösen Konkurrenz gewechselt und hab immer mal wieder Counter-Strike gespielt. Primär der Use-Case war Kopf ausschalten.
Wolfi Gassler (00:11:21 - 00:11:24)
Moment, das machst du ja den ganzen Tag. Was machst du da als Ausgleich?
Andy Grunwald (00:11:27 - 00:12:01)
Touché. Muss ich zugeben. Nee, aber wenn man jetzt einfach mal einen stressigen Tag hatte, dann lockt man sich da ein und wählt ein Team und kauft sich eine Waffe und macht dann Team-Taktiken, ja? Ich wollt grad sagen, kauft eine Waffe und ballert ein bisschen rum, das hört sich total schlimm an. So ist das nicht, aber es ist halt einfach nur so ein bisschen abschalten. Auf jeden Fall hab ich dann immer hier und da mal mit ein paar Freunden gespielt. So und dann ging es eigentlich genau dieselbe Route runter wie du. Man geht in die Config-Datei von dem Spiel und fängt an was zu tweaken.
Wolfi Gassler (00:12:02 - 00:12:07)
Moment, was tweakt man denn da? Ich habe ja das Operating System getweakt. Was tweakt man bei einem Spiel?
Andy Grunwald (00:12:07 - 00:12:20)
Ja, du kannst zum Beispiel das Fadenkreuz abändern, die Fadenkreuz-Farbe. Du kannst dir Befehle auf verschiedene Tasten legen, wie zum Beispiel, dass du automatisch eine Message schreibst.
Wolfi Gassler (00:12:20 - 00:12:29)
Das heißt, statt dem Fadenkreuz kann ich mir dann so ein rosarotes, pinkes Herz zum Beispiel da hinsetzen, statt dem Fadenkreuz.
Andy Grunwald (00:12:29 - 00:12:39)
Ich weiß nicht, ob du Custom-Emojis, nenn ich das jetzt mal, Custom-Zeichen da reinsetzen kannst. Du kannst aber auf jeden Fall verschiedene vorgefertigte Fadenkreuze hinsetzen, ja.
Wolfi Gassler (00:12:40 - 00:12:46)
Aber dazu muss ich in irgendein Skript rein. Das kann ich nicht irgendwo in den Settings auswählen, sondern das muss ich ...
Andy Grunwald (00:12:46 - 00:12:56)
Das kannst du schon in einer Spielkonfiguration in einem File ändern, ähnlich wie dein Mouse Speed oder ähnlich, ob du die Waffe von dem Männchen links oder rechts hältst und so.
Andy Grunwald (00:12:57 - 00:15:51)
Na ja, und auf jeden Fall ist das halt die klassische Config-Datei. Die endet mit .cfg. So weit, so gut. Und irgendwann kam halt dieser Zeitpunkt, wo eSports in Deutschland und in Europa relativ groß wurde. Hast du vielleicht schon mal gehört, so die ESL und GameStar Liga und so weiter und so fort. Und diese Firmen, Magazine damals, die haben große Turniere veranstaltet. Und die machen das ja nicht, weil das tolle Menschen sind, sondern weil das natürlich ein profitorientiertes Business ist. Und irgendwann fingen die an, diese Events in großen Stadien zu streamen. Und dann haben die die Pro-Spieler da reingeholt und dann haben die Pro-Spieler vor Ort gegeneinander das Finale ausgespielt und so weiter und so fort. Das sind Riesen-Events inzwischen. Ja? Und wenn du dann ... Ich war noch nie in so einem Stadion. Aber wenn du in so einem E-Sport-Stadion sitzt, dann hast du überall Screens, wo dann das ganze Match übertragen wird, wo du dann links und rechts immer siehst, wie viele Leute leben noch, wer hat welche Waffe, wer hat wie viele Granaten noch, und Rüstung und wie viel Geld und alle in der Ruhe dran. Weil anhand dieser Attribute, wie viel Geld ein Team hat und so weiter, bestimmt sich natürlich auch die Strategie, wo stellen die sich hin, wer kauft welche Waffen und so weiter. Das ist ein Teamspiel, ein strategisches Teamspiel. Und dann fing der Nerd in mir an. Hä? Wie kriegen die denn die ganzen Infos von dem Spiel? Weil du hast da, ich sag mal, eine Beobachterrolle in dem Spiel. Es sind aber nur zehn Menschen auf dem Server, fünf gegen fünf. Und dieser Beobachter hat irgendwie alle Informationen. Wer lebt? Wer ist tot? Wie viele Lebenspunkte haben die noch? Liegt die Bombe auf irgendeinem Bombspot? Wie viele Geiseln wurden gerettet? Und so weiter und so fort. Ähnlich wie ein aktueller Twitch-Stream. Da hab ich gedacht, hä? Da muss was im Spiel implementiert sein, was die Informationen gibt. Hab ich angefangen zu googeln. Und zwar gibt es in Counter-Strike, in Counter-Strike Global Offensive, in der aktuellen meistgespielten Version, eine sogenannte Game-State-Integration. Ich denk so, what? Was ist das denn Geiles? Okay, mal durchgelesen. Die Dokumentation verlinken wir auch in den Shownotes. Die Game-State-Integration ist ein Weg für Drittapplikationen, ihre Services mit dem Spiel zu verbinden. Das bedeutet, du kannst dem Spiel, dem Counter-Strike-Spiel sagen, gib mir mal bitte alle Informationen, was jetzt gerade in dieses Spiel abgeht. Und was kann man dann damit machen? Damit kann man zum Beispiel diese Beobachterscreens bei so großen Turnieren steuern. Man kann dadurch aber zum Beispiel auch eine Philips Huey, also eine Lampe, die Farbe ändern, abhängig davon, in wie viel Sekunden die Bombe gleich explodiert. Weil im Spiel geht's ja sehr viel um Taktik, ja? Und die Bombe hat dann, die tickt dann zum Beispiel 30 Sekunden. Und wenn du dann erst bei fünf Sekunden anfängst, die Bombe zu entschärfen, kann das sein, dass du das nicht mehr schaffst und dann stirbst.
Wolfi Gassler (00:15:51 - 00:15:57)
Und wo ist diese API? Wer kann darauf zugreifen? Jeder? Oder gibt's da irgendwie eine Limitierung?
Andy Grunwald (00:15:57 - 00:16:22)
Das hab ich ja dann grad auch. Das war dann meine nächste Frage. Erst mal bin ich über die Use Cases gegangen und hab dann gedacht, hey, cool, was gibt's denn da und so weiter und so fort. Im Allgemeinen kann diese Game-State-Integration dich über alle Game-State-Änderungen informieren. Also alle. Wer hat welche Waffe gekauft? Wer wechselt grade welche Waffe? Wer hat welche Granate geschmissen? Und wo sind die, mit welchen Koordinaten X und Y auf der Karte?
Andy Grunwald (00:16:25 - 00:16:59)
Ja, das ist das Geile. Die API liegt im Client. Das bedeutet, du kannst eine Adresse zu einem Webserver in deiner Config hinterlegen und dann postet dein Client ... alle Game State Changes zu einem zentralen Server. Das bedeutet, wenn wir beide gegeneinander Counter-Strike spielen würden, dann müsstest du eine Webhook-Adresse eigentlich in deine Config mit eintragen, und dann bekommt der zentrale Webhook-Server all deine Informationen über deinen Spielverlauf.
Wolfi Gassler (00:16:59 - 00:17:04)
Aber muss es dann jeder machen, der da mitspielt? Oder reicht da ein Client, und der bekommt alle Infos von allen?
Andy Grunwald (00:17:05 - 00:17:25)
Da gibt es zwei Arten. Und zwar gibt es wohl auch eine Möglichkeit, das auf dem zentralen Server irgendwie zu machen. Der hat dann alle Informationen. In einem klassischen LAN-Umfeld wird das dann eigentlich jeder machen. Aber wenn du zum Beispiel jetzt auf so einem großen Turnier wärst, dann ist das halt ein Teil, was von dem Veranstalter halt vorgeschrieben wird.
Wolfi Gassler (00:17:26 - 00:17:31)
Aber kann ich da dann die Position von anderen Leuten auslesen? Da könnt ihr ja voll cheaten.
Andy Grunwald (00:17:31 - 00:17:41)
Wenn du real-time-technisch den Webhook-Server, die Daten, die du da kriegst, während du spielst, das machst, dann wäre das möglich, ja. Darum geht's ...
Andy Grunwald (00:17:43 - 00:17:52)
Dann würde ich ja nicht hier sitzen, oder? Dann würde ich irgendwo in der Sonne sitzen, mir einen Cocktail trinken und mich mit meinem wohlverdienten Preisgeld zurücklehnen. Aber was das Geile ...
Wolfi Gassler (00:17:52 - 00:18:07)
Man sieht schon die kriminelle Energie, die du hast. Letztes Mal SQL-Injections. Hast du allen erklärt, wie man richtig SQL-Injections macht? Wie man richtig die Game-Industrie hackt oder cheatet und Preisgeld einsammelt? Was kommt nächste Woche?
Andy Grunwald (00:18:08 - 00:18:20)
Na ja, du musst halt schon sehen, dass dein Gegner dann auf jeden Fall auch die Webhook-Adresse von deinem Server eingetragen hat, ne? Es sei denn, du hostest natürlich den Server, das ist eine andere Baustelle. Wie dem auch sei.
Andy Grunwald (00:18:23 - 00:18:37)
Jaja, genau, und dann bin ich da tiefer, ich bin weiter das Rabbit Hole runter, du kennst das ja. Das ist ungefähr so wie, als wenn du dich über Landmaschinen auf YouTube informierst, dann endest du auch irgendwann ganz schlimm, irgendwo in Arkansas in Amerika und in ganz großen Landmaschinen.
Wolfi Gassler (00:18:37 - 00:18:55)
Ich hab mir gedacht, ich kann mich eigentlich nicht reinversetzen, dass ich da das Rabbit Hole eines Spieles runtergehen würde. Noch weniger kann ich mir vorstellen, dass ich das Rabbit Hole von irgendwelchen Landmaschinen nach unten gehe. Aber klar, alle Hörer und Hörerinnen werden sich jetzt da reinfühlen können und mit dir mitleiden, wie man da das Landmaschinenrabbit Hole runtersteigt.
Andy Grunwald (00:18:57 - 00:19:30)
Zurück zur Counter-Strike Global Offensive Game State Integration. Du addest also eine Adresse, eine Webadresse zu einem Server in deine Config. Und wenn du das Spiel dann startest, dann kriegt dieser Server konstant HTTP-Post-Requests und schickt dir JSON-Daten mit der Game-Struktur. Ja, mit diesen Informationen. Es ist grad die Kaufrunde, wir sind grad in Runde drei von 15. Es ist nur noch eine Minute verfügbar und die Bombe liegt noch nicht und jemand hat eine Granate geschmissen und was weiß ich nicht noch alles.
Andy Grunwald (00:19:34 - 00:20:08)
HTTP-Post-Request, ganz normal wie bei einer ganz klassischen REST-API. Der PostBody ist in JSON. Ja, ganz normal wie bei GitHub oder bei IFTTT oder bei was auch immer, welche API, mit der du gerade sprechen möchtest. Die Art und Weise, ich hab ja gesagt, du musst die Webhook-Adresse in deine Config eintragen. Die config ist aber jetzt nicht im ini-format oder im json-format oder im xml-format, sondern die config ist in einem vdf-format, vdf wealth data format, weil du bist ja nur als firma cool, wenn du dein eigenes datenformat hast. Natürlich.
Andy Grunwald (00:20:11 - 00:21:01)
Es ist ein Klartextformat. Und dieses Format ist relativ einfach. Du musst jetzt wissen, dass dieses Format, dieses VDF, Valve Data Format, in der Source Game Engine verwendet wird. Das bedeutet, dass es nichts Counter-Strike-spezifisches, sondern das gleiche Format wird auch in Half-Life 2, in Portal 1 und 2, in Team Fortress 2 oder in Left 4 Dead 1 und 2 verwendet. Also eigentlich in allen Spielen, die auf der Source-Spiele-Engine basieren. Was schon mal ganz geil ist, weil es besteht nämlich die Hoffnung, dass diese Art von Spielen dann eine ähnliche Game-State-Integration haben. Naja, machen wir weiter. Dieses Format ist halt meines Erachtens nach sehr, sehr simpel und es gibt eigentlich nur drei Control-Character. Eine geschweifte Klammer, also eine offene geschweifte Klammer, eine geschlossene geschweifte Klammer und ein Anführungszeichen. Mehr nicht.
Andy Grunwald (00:21:02 - 00:22:44)
Ja, Jason hat noch einen Doppelpunkt und einen Komma haben wir hier nicht. Das bedeutet, Zwei Settings werden einfach nur über eine Newline getrennt. Und zwischen Key und Value besteht einfach nur ein Whitespace. Ja? Und der Key ist dann in Anführungszeichen ... Also, das ist relativ einfach. Und du kannst dann Sub-Ebenen machen mit geschweiften Klammern. Ja? So ähnlich wie JSON. Okay, und jetzt hab ich gedacht, hm, wenn ich jetzt also mit meinen Freunden Counter-Strike spielen möchte, und ich möchte Daten von deren Spielverhalten haben, weil ich hab festgestellt, ich bin gar nicht so gut in Counter-Strike, und ich krieg immer relativ oft auf die Mütze, und ich hab mir gedacht, wenn ich doch viele spiele, dann hab ich doch auch viele Daten, und somit kann ich doch über mein Spielverhalten lernen. Also, ich schau mir einfach an, ne klassische Datenanalyse, ne? der Observability und Monitoring-Folge darüber gesprochen haben, dass wir so was wie Sentry einbinden, um Exceptions zu kriegen, hab ich mir gedacht, warum sammle ich nicht mal detaillierte Daten über mein Spielverhalten bei Counter-Strike? Und dann habe ich gedacht, okay, wäre das nicht toll, wenn nicht nur ich lernen könnte, sondern alle. Und dann war die nächste Frage, wie bekomme ich meine Freunde dazu, dass die jetzt meinen Webhook-Server in ihre Config eintragen. Ich könnte jetzt jedem über WhatsApp schreiben, hey, pass mal auf, ich habe hier diese dodgy URL, kannst du die mal bitte bei dir eintragen. Dann fragen die fünf mal nach, Moment, wo ist denn jetzt noch die Datei und was muss ich denn noch mal eintragen und das sind ja alles keine Programmierer. Das sind alles in Anführungszeichen professionelle Counter-Strike-Spieler. Also habe ich mir gedacht, wir lösen das Problem so wie jeder normale Mensch.
Andy Grunwald (00:22:46 - 00:23:11)
Wir schreiben einen Installer. Also habe ich mich hingesetzt und habe einen Installer geschrieben, den startest du und der sucht dir automatisch das Installationsverzeichnis auf deinem Betriebssystem für Counter-Strike und sucht dir dann die entsprechende Config-Datei, wo das hin muss und legt dann da eine automatische Config-Datei hin von den Settings, die ich haben möchte für den Webhook-Server.
Wolfi Gassler (00:23:12 - 00:23:22)
Okay, was für Sprache hast du dazu verwendet? Und du musst wahrscheinlich die Datei auslesen, die schon dort ist, und dann irgendwie abändern, oder? Du kannst ja nicht einfach eine dazulegen.
Andy Grunwald (00:23:26 - 00:23:57)
Ist halt, lässt sich super einfach überall kompilieren und kann ich vorkompilieren, vorkrosskompilieren, ohne dass ich ein Linux-System habe und so weiter und so fort. Und es gibt zwei Möglichkeiten, wie du diese Config dahinlegst. Entweder du legst eine neue dahin mit einem speziellen Namen. Das bedeutet, du kannst mehrere Webhook-Server haben, was ziemlich cool ist eigentlich. Ich kenn aber nicht das Limit. Wie viel Webhook-Server brauchst du, bis das Senden der Daten von Counter-Strike während des Spiels das Spiel selbst beeinflusst?
Wolfi Gassler (00:23:58 - 00:24:02)
Das heißt, du hast pro Datei einen Webhook-Server, wenn ich den mal so nenne.
Andy Grunwald (00:24:03 - 00:24:10)
Nee, du kannst ja auch in jeder Datei schon dieselbe Adresse eingeben, ja? Oder mit einem anderen Pfad oder was.
Wolfi Gassler (00:24:10 - 00:24:15)
Ja, aber kannst du mehrere Server in einer so einer VDF eingeben?
Andy Grunwald (00:24:18 - 00:24:30)
Genau. Was ich dann gemacht hab, ich hab gesagt, wenn du diese Go-Applikation, diesen Go-Installer gestartet hast, dann hat dein HTTP-Request gemacht an meinen zentralen Server, um sich die aktuellste Config zu holen. Ja?
Andy Grunwald (00:24:31 - 00:24:45)
Dann, Da steht zum Beispiel die Adresse des Webhook-Servers drin und welche Informationen der senden soll. Wie zum Beispiel, welche Präzision hat zum Beispiel die Zeitangabe, ja? Mit wieviel Mikrosekunden hinten dran.
Wolfi Gassler (00:24:45 - 00:24:54)
Okay, du holst dir dann diese Datei, da stehen ein paar Infos drinnen, und dann suchst du dir den Installationsfolder raus und legst sie dorthin.
Andy Grunwald (00:24:54 - 00:25:10)
Auf dem Web-Server habe ich einen Endpunkt, der nennt sich slash-config, da habe ich immer die Config hinterlegt, damit ich später sagen kann, hey Jungs, führt den Installer bitte nochmal aus, und der überschreibt dann die Config. Damit ich auch ganz einfach Configs updaten kann.
Wolfi Gassler (00:25:10 - 00:25:26)
Okay, also du hast jetzt ziemlich viele verrückte Leute gefunden, die da irgendein Executable von dir ausführen, das irgendwas bei ihnen macht. Okay, und jetzt nehmen wir mal an, du hast jetzt weniger kriminelle Energie als sonst und hast nur brav diesen Hook da eingetragen bzw. die Config. Und was passiert dann?
Andy Grunwald (00:25:27 - 00:26:14)
Also erstmal hab ich die Config vom Webserver untergeladen und hab die dann auf Festplatte geschrieben. Der Punkt ist aber, irgendwie muss ich ja gucken, ich hab nicht ganz einfach, ganz doof die Datei immer überschrieben oder dahingesetzt, sondern ich hab jedem, du kannst in dieser Konfiguration auch noch eine eindeutige ID mitgeben. Also hab ich immer eine neue ID generiert. Und beim Updaten wollte ich die ID aber beibehalten. Das bedeutet, ich muss das Valve Data Format, die Config, irgendwie verstehen. Das bedeutet, ich kann natürlich die Datei öffnen und dann per Regex da rüber gehen. Kann ich schon. Das wäre aber zu einfach, habe ich mir gedacht. Und ich hatte noch nie eine Ahnung, wie ich eigentlich ein Parser oder ein Lexer oder so schreibe. Und dann habe ich mir gedacht, warum schreibe ich nicht ein Parser und ein Lexer für das Valve-Data-Format, baue das in den Installer ein, damit ich diese Config-Datei automatisch modifiziere.
Wolfi Gassler (00:26:15 - 00:26:26)
Okay, wenn ich jetzt dich zahlen würde als Angestellten zum Beispiel, würde ich sagen, Moment, Andi, hast du mal auf GitHub gesucht? Gibt's da nicht schon vielleicht einen Parser? Das ist ja ein Standardformat.
Andy Grunwald (00:26:26 - 00:26:41)
Ich hab auf GitHub gesucht, und da gab's auch die ein oder andere Library. Da gab's eine in PHP, da gab's eine in Python. Und dann hab ich einfach mal eine komplette Config, die ich schreiben wollte, da reingehauen. Und soll ich dir was sagen? Alle sind auf die Nase gefallen.
Wolfi Gassler (00:26:42 - 00:26:53)
Also wie jeder gute Entwickler hast du probiert ein Edgecase zu finden, als guten Grund, warum du eine Library nicht verwenden willst, um die selber programmieren zu können. Ich verstehe schon, ja?
Andy Grunwald (00:26:53 - 00:26:56)
Sie haben auf jeden Fall nicht genau das gemacht, was ich wollte.
Wolfi Gassler (00:26:56 - 00:27:17)
Genau, das ist die zweite Ausrede nochmal, wenn man eine Library nicht verwenden will. Entweder sie hat irgendwo ein Edgecase, da fliegt ein Arrow, den ich nicht verstehe und irgendwas funktioniert nicht auf Anhieb, was ich gerne hätte, was auch niemand braucht. Aber okay. Gehen wir mal davon aus, dass es war wirklich so und du hast deine eigene Library programmiert. Wie hast du das gemacht?
Andy Grunwald (00:27:17 - 00:27:20)
Fangen wir mal an. Hast du schon mal ein Parser und ein Lexer geschrieben?
Wolfi Gassler (00:27:23 - 00:27:30)
Ich weiß es ehrlich gesagt nicht mehr, aber es war an der Universität, um funktionale Programmiersprachen zu testen oder zu lernen.
Andy Grunwald (00:27:30 - 00:27:51)
Ich hab das auf jeden Fall noch nie gemacht und ich hab da immer ein bisschen Respekt vor, Ich denke mir, okay, jede Programmiersprache hat einen Compiler und Pasa und Lexa sind oft irgendwie Teile eines Compilers. Und ich hab immer allerhöchsten Respekt vor Leuten, die Compiler-Bau betreiben, weil ich halte die für unglaublich intelligent, weil ich davon einfach nichts verstehe.
Wolfi Gassler (00:27:56 - 00:28:22)
Siehst du, normal als guter Entwickler würde man normal das ordentlich machen und sich dann das Drachenbuch kaufen. Es gibt das berühmte Drachenbuch über Compiler Bau. Das ist ein Standardwerk, ziemlich alt, gibt es glaube ich eine zweite Auflage auch, hat irgendwie 900 Seiten und am Cover ist ein Drache und darum heißt es das Drachenbuch. Verlinken wir natürlich in den Shownotes. Eigentlich hättest du es kaufen sollen zuerst 900 Seiten durchlesen, damit du das richtig verstehst und dann als die Library Ist das wirklich gut?
Wolfi Gassler (00:28:23 - 00:28:32)
Natürlich habe ich es nicht gelesen. Aber ich kenne Leute, die es gelesen haben und es ist wirklich ein absolutes Standardwerk. Aber 900 Seiten nur zu Compiler ist mir dann auch zu viel, ehrlich gesagt.
Andy Grunwald (00:28:33 - 00:29:00)
Naja, auf jeden Fall hab ich dann angefangen, hm, wie schreib ich denn Parser und Lexer für das Valve-Data-Format? In Go, logisch. Gab's ja noch nicht alles. Und dann hab ich ein bisschen gegoogelt, und dann hab ich einen sehr, sehr guten Artikel gefunden, der heißt Handwritten Parsers and Lexers in Go. Und was er in diesem Artikel macht, ist, der baut einen Lexer und einen Parser für SQL-Queries. Ja, select Sternchen from table where where condition.
Andy Grunwald (00:29:04 - 00:29:26)
Na ja, gut, aber der Artikel war halt eher so dafür bei, ich bring das mal bei. Und dann hab ich mir gedacht, ey, cool, das ist ja eigentlich genau das, was ich möchte, nur dass das Format ein bisschen anders ist. Fun fact, der parser und lexer aus dem Blogartikel, den verlinken wir natürlich auch in den Shownotes, basiert auf dem parser und lexer von InfluxDB für die Influx Query Language.
Andy Grunwald (00:29:29 - 00:29:52)
InfluxDB ist eine Datenbank mit dem Spezialfokus auf Timeseries-Daten. Also das bedeutet, wenn ihr zum Beispiel irgendwie einen Temperatursensor habt, dann könnt ihr da zum Beispiel kontinuierlich die Temperaturen in Relation zu einer Zeit reinsetzen und darauf schon eine Grafen machen. Ja, also eigentlich alles mit zeitbasierten Daten, da ist diese Datenbank wundervoll für.
Andy Grunwald (00:29:56 - 00:30:07)
Die hat ein ähnliches SQL-Interface, nennt sich... SQL-Dialekt. Influx Query Language, genau. Naja, jetzt stand ich erstmal vor dem Problem, ich hab keine Ahnung, wie ich ein Lexer und Parser baue.
Wolfi Gassler (00:30:07 - 00:30:25)
So Moment, bevor du da jetzt mal bauen anfängst, erklär mal, was ein Lexer und Parser ist, wenn du es dann schon so sinnvoll gelesen hast. Und zwar in dem, ich hab das jetzt neulich eingeführt in einem anderen Podcast mit einem Kollegen, in dem Twitter-Format. Erklär mal in dem Twitter-Format 240 Zeichen, was ein Lexer und Parser ist.
Andy Grunwald (00:30:26 - 00:30:34)
Und genau vor diesem Problem stand ich. Ich wusste gar nicht, was ein Lexer und was ein Parser ist. Ich hab die Wörter schon mal gehört, aber ich wusste ja gar nicht, wofür die da sind und wer kommt überhaupt wann.
Andy Grunwald (00:30:36 - 00:31:24)
Ja, das schaff ich jetzt nicht. Also, ein Lexer selbst wird auch unter anderem ein Tokenizer oder einen lexikalischen Scanner genannt. Also immer, wenn ihr so was hört, ja, Tokenizer, lexikalischer Scanner oder Lexer, das ist alles dasselbe. Und zwar beschreibt man als lexikanische Analyse die Zerlegung einer Zeichenkette in eine Folge von logisch zusammengehörigen Einheiten, sogenannten Tokens. Jetzt denkt man, hä? Was ist das denn? Ja, was das jetzt ist, kommen wir jetzt gleich zu. Ein Lexer oder ein Tokenizer ist meist ein Teil eines Compilers und wird als erster Schritt in der Analysephase ausgeführt. Okay, klasse. Das bedeutet, ich fange erstmal mit einem Lexer an. Ohne Lexer geht erstmal nix. Das Ergebnis eines Lexers wird dann im nächsten Schritt von einem Parser weiterverarbeitet. Ah, okay.
Andy Grunwald (00:31:25 - 00:32:21)
Verstehe ich. das bedeutet also eigentlich ich habe einen block von text und zwar ist das eigentlich meine vdf datei das bedeutet ich mache die datei auf lese die komplette datei und schmeiß das in den lexer und der lexer bricht mir dieses format in sogenannte einzelne bruchteile auf sogenannten tokens und jeder token hat dann in so einer art ein Eine Bedeutung. Ein Token ist also eigentlich nur eine Zeichenkette, der von einer formalen Grammatik ein Typ zugewiesen wird. Wenn ich jetzt sage, das Format ist sehr einfach, wie ich gerade beschrieben habe, und da gibt es eine geöffnete geschweifte Klammer und eine schließende geschweifte Klammer und diese geschweiften Klammern bilden den Start zu einer weiteren Unterebene ab. Dann kann ich sagen, okay, die geschweifte Klammer ist ein Token. Und was vor der geschweiften Klammer steht, ist ein Key. Und alles, was in der geschweiften Klammer ist, ist wieder ein assoziatives Array von Key und Values. Ja?
Wolfi Gassler (00:32:21 - 00:32:33)
Aber ein Tokenizer, der bricht die Sachen ja nur auf. Der beschreibt ja nicht, was drinnen ist. Der versteht das ja noch nicht. Das, was du jetzt machst, ist Start und Ende und so weiter. Das ist ja schon eine Zuordnung von den Tokens.
Andy Grunwald (00:32:33 - 00:33:03)
Ja, nee, der Token ... Der Tokenizer muss schon wissen, was ist denn ein vollständiges Token? Der Token gibt dir jetzt nicht jeden einzelnen Buchstaben oder jedes einzelne Zeichen zurück, sondern der gibt dir schon die logische Sequenz von den einzelnen Zeichen. Wieder Beispiel. Wenn ich eine Key-Value-Relation habe, dann gibt der Tokenizer mir den Key alleine zurück und das Value. Ja, aber Key und Value sind dann in der Regel eine Kombination von Zeichen. Sagen wir mal, der Key ist Foo und das Value Bar.
Wolfi Gassler (00:33:03 - 00:33:12)
Aber versteht der Lexer schon, was ein Key und was ein Value ist? Also gibt er zurück, das ist ein Key und das ist ein Value, oder gibt er dir zurück, da ist Token 1 und da ist Token 2?
Andy Grunwald (00:33:12 - 00:33:18)
Der Lexer gibt mir schon zurück, das ist ein Token vom Typ geöffnete geschweifte Klammer.
Andy Grunwald (00:33:19 - 00:33:46)
Und der Lexer gibt mir bei diesem Key-Value-Pair, da gibt er mir die Zeichenketten zurück. Der Lexer weiß aber nicht, dass das eine ein Key oder eine andere ein Value ist. Das bedeutet, die Interpretation der Semantik, ob das ein Key oder ein Value ist und wie man das dann hierarchisch zusammenstöpselt, das wiederum macht dann der Parser. Aber erstmal wird der Content von deiner VDF-Datei, von meiner Config, vom Tokenizer zerlegt.
Wolfi Gassler (00:33:47 - 00:33:51)
Und wie hast du das gemacht? Hast du das selber programmiert? Hast du da irgendwelche Libraries verwendet?
Andy Grunwald (00:33:51 - 00:35:07)
Nö, das hab ich selber programmiert. Bin ich auch ein bisschen stolz drauf, muss ich zugeben. Wie das eigentlich funktioniert, vielleicht haben das manche Leute im Programmierumfeld schon mal gehört, aber wenden das gar nicht so täglich an. Und zwar, bei Lexern ist man oft im sogenannten State Machine unterwegs. Auf Deutsch heißt das Endlicher Automat. Und zwar juckelst du eigentlich über das komplette File, über die komplette Zeichenkette und versuchst, daraus irgendwie Sinn zu ergeben. Du musst natürlich schon das Format verstehen, wie das aufgebaut ist. Aber was ich eigentlich mache ist, ich lese mir jedes einzelne Zeichen von dieser Datei nacheinander durch und sage, oh, das hier ist ein Leerzeichen. Ja, dann scanne ich bis zum nächsten Nicht-Lehrzeichen, also bis zum nächsten Zeichen, was ich kenne. Und dann, ich schaue mir einfach jedes Zeichen an und anhand des Zeichens entscheide ich, okay, lese ich einfach weiter oder packe ich das gelesene Zeichen in einen Buffer und lese bis ein neues Zeichen kommt, damit ich weiß, okay, ist das der Start eines Tokens, ist das das Ende eines Tokens? Und mit dieser semantischen Analyse anhand des Wissens, wie ein Token aussieht, was ein Anführungszeichen ist, was eine geöffnete Klammer ist, was eine schließende Klammer ist, zerlege ich die ganzen Sachen dann einfach.
Wolfi Gassler (00:35:07 - 00:35:19)
Okay, jetzt bekommst du da am Ende diese Tokens raus. Das sind jetzt bei dir da diese zwischen den geschwungenen Klammern, diese Werte oder mit den geschwungenen Klammern, keine Ahnung, wie dieses VDF-Ding halt aufgebaut ist. Was machst du danach damit?
Andy Grunwald (00:35:20 - 00:35:38)
Die ganzen Tokens schmeiß ich dann in einen sogenannten Parser. Und den Parser hab ich auch geschrieben. Was der Parser eigentlich macht, der macht eigentlich aus diesem Haufen von Tokens, macht der eigentlich einen Sinn. Das bedeutet, der kümmert sich darum, um die geordnete Weiterverarbeitung in ein geeignetes Format.
Wolfi Gassler (00:35:39 - 00:35:55)
Bevor du weiterredest, noch eine Frage vorweg, weil du hast das wirklich alles selber programmiert, du hast auch keine Libraries für irgendwelche State Machines, endliche Automaten, irgendwas diesbezüglich verwendet, auch beim Parser, alles wirklich hardcore, ohne irgendwas Externes geschrieben.
Andy Grunwald (00:35:55 - 00:36:03)
Ja, also die Frage hört sich jetzt total voll intelligent an von dir, aber bei mir ist die State Machine und der endliche Automaten eine scheiß Vorschleife.
Wolfi Gassler (00:36:04 - 00:36:12)
Ja, ja, ist es ja am Ende auch. Du hast keine Rekursion verwendet in dem Fall? Es sind auch so klassische Anwendungen normalerweise für Rekursion.
Andy Grunwald (00:36:12 - 00:36:19)
Ja, doch, natürlich hab ich Rekursion verwendet, weil du musst ... Ich muss ja ... Ich weiß ja nicht, wie viel Level die Konfig runtergeht.
Wolfi Gassler (00:36:20 - 00:36:32)
Okay, ja. Okay, aber du hast die Tokens. Und jetzt, wie ist dein Parser aufgebaut? Wie bist du überhaupt da an das Problem drangegangen? Woher weißt du, wie du einen Parser schreiben musst? Oder hast du das zusammengedacht?
Andy Grunwald (00:36:32 - 00:37:18)
Nö, ich hab mir diesen Blogartikel genommen, und der Blogartikel hat darüber beschrieben, wie der das für einen SQL-Query macht, und ich hab das dann, das SQL-Query-Problem auf mein VDF-Problem übertragen, weil eine SQL-Query ist halt auch so eine Basis-SQL-Query, ja? Also jetzt ohne Subselects, ohne Having, ohne GroupBy, sondern einfach select from where. Hat ja eigentlich auch nur drei Elemente. Und da gibt's dann ein paar Charakter, da gibt's dann wie zum Beispiel Feldnamen, da gibt's ein Komma, da gibt's ein Asterix, also ein Sternchen für alle Felder und so weiter und so fort. Also, die Anzahl der Tokens, die in diesem Blogartikel beschrieben wurden, waren auch sehr minimal gehalten. Und da bin ich einfach an diesem Blogartikel weitergehangelt und hab dadurch dann ein paar Nächte gebraucht, bis ich das mal für das VDF-Format gemacht hab.
Andy Grunwald (00:37:21 - 00:39:21)
Naja, mein Parser versucht, dem ganzen Token dann irgendeine Semantik zu geben. Allgemein werden Parser dazu verwendet, den Text in eine neue Struktur zu übersetzen. Und zum Beispiel in einen Syntaxbaum. Und genau das habe ich gemacht. Da ich ja gerade gesagt habe, dass das While-the-Data-Format mehrere Ebenen haben kann. Die können Config-Settings auf der Top-Level-Ebene haben und jeder einzelne Key kann nochmal Unter-Settings haben. Was der Parser dann macht, der baut daraus ein assoziatives Array. Der baut also eigentlich eine klassische Hash-Map auf, die ich dann in Golang ganz klassisch und strukturiert verwenden kann. Das bedeutet, dieses klassische Key-Value-Format mit Unterebenen und so weiter transformiere ich eigentlich in einen nativen Goaling-Datentyp. Du kannst dir vorstellen, eigentlich wie HTML-Code. Und da kommen Parser eigentlich auch super oft zum Einsatz. Und zwar jeder Webbrowser hat einen Parser, der aus der Webseite, aus dem klassischen HTML, irgendeine semantische Struktur baut. Das ist der sogenannte DOM, ja? Und wo dann die ganzen JavaScript-Leute drauf rumhantieren und dann Elemente verschieben und so weiter und so fort. Und dieser Syntaxbaum von HTML muss ja auch irgendwie vom Webbrowser verstanden werden. Also er muss ja wissen, wann du ein kursives HTML-Element hast, damit er den Text kursiv macht. Und der Parser im Webbrowser macht eigentlich genau das. Der baut sich einen Syntax-Tree auf und schaut dann, wie muss ich diesen Syntax-Tree darstellen. Das gleiche wie beim XML-Parser oder beim SLS-Parser oder ähnliches. Oder auch beim URL-Parser, beim URI-Parser. Eine URL hat ja eine gewisse Semantik. Und jetzt kannst du ein Tokenizer darüber laufen lassen. Und der Tokenizer schmeißt dir die einzelnen Elemente einer URL raus. Username, Passwort, Port, Fahrt, Fragment und so weiter und so fort. Und der Parser bringt dir das dann in die Semantik. Was ist denn der Username? Was ist denn das Passwort? Was ist denn der Port? Ja, und wie werden die unter anderem zusammengesetzt? Und genau das macht mein Parser dann eigentlich auch.
Wolfi Gassler (00:39:21 - 00:39:24)
Und das hast du alles nur gemacht, damit du diese ID auslesen kannst?
Andy Grunwald (00:39:24 - 00:39:27)
Das klingt jetzt alles so, als wäre das alles nicht notwendig gewesen.
Andy Grunwald (00:39:31 - 00:40:33)
Vielleicht hast du recht, aber es war enorm spaßig, weil der Clou ist, ich konnte, dann habe ich das halt so halbwegs ans Fliegen gekriegt und dann kam ja diese, dann kam ja mein Production Diplomate, ja, mein Production Diplomate war ja, ich habe meine Kollegen angerufen, Mama, Jungs, ich gebe euch jetzt eine Adresse, ladet mal die Dodgy Exe Datei da runter und führt die mal bitte aus, ja. Und dann war das so eine Art Remote-Debugging. Und das Tolle ist, in meiner eigenen Testphase, also das Testing war schon ziemlich cool, weil ich hab das immer gebaut, gebaut, programmiert, hab das kompiliert, hab das bei mir ausgeführt, hab Counter-Strike gestartet, ob wirklich Dateien und Elemente und Webhooks auf meinem Web-Server ankommen. Scheiße, hat nicht funktioniert, Counter-Strike wieder aus. Wieder gemacht. Also, ich muss schon sagen, das war wieder so ein paar Abende, wo ich ... voll im Flow war. Ja, also wirklich, ich hab vergessen zu essen, zu trinken, weil das war so spaßig. Also, es hatte eigentlich nichts mehr mit Counter-Strikes zu tun. Ich hab eigentlich nur versucht, daraus zu erfinden, wie ich ein parserlexer fürs VDF-Data-Format.
Wolfi Gassler (00:40:33 - 00:40:37)
... Hast du eigentlich in deinem Studium nie irgendwas in die Richtung gemacht?
Andy Grunwald (00:40:37 - 00:40:45)
Also, ich meine, etwas in den Studienunterlagen gelesen zu haben. Und gegebenenfalls hätte mir diese Vorlesung dann auch sehr viel Zeit erspart.
Wolfi Gassler (00:40:45 - 00:41:15)
So ein Klassiker ist übrigens, dass man da Antel-R verwendet, da definiert man dann die Grammatik und der spuckt dir dann am Ende den Parser aus dafür. Das ist so, der Klassiker definiert man in der EBNF, das ist die, wie hat die geheißen, Extended Bacchus-Nauer-Form, genau, und da definiert man die Sprache und am Ende wird da ein Compiler ausgespuckt. Ist aber auch nicht so einfach zu verwenden, also muss schon sagen, ist auch gewisser Overheight, aber wenn man in dem Bereich mehr machen will, ist es definitiv wert, da mal reinzuschauen.
Andy Grunwald (00:41:15 - 00:41:37)
Jetzt, wo du's sagst, diese Bacchus-Nauer-Form, doch, die sagt mir was. Und die hab ich auch schon gelesen und die hatte ich auch im Studium. Doch, du weißt ja, wie das ist. Im Studium lernt man ein bisschen Theorie, doch wann wendet man die in der Praxis an? Nur wenn man wirklich hands-on ist. Ich bin so ein Lerntyp, ich kann nicht über Udemy-Kurse lernen, ich muss Prototypen bauen. So hab ich Lexar und Parser für Valves Data-Format für Counter-Strike geschrieben.
Wolfi Gassler (00:41:38 - 00:42:01)
Also ich bin ja auch der Meinung, wenn man was lernen will und verstehen will, sollte man das auch mal selber programmiert haben. Definitiv. Ganz allgemein, wenn es um Lexer und Barser geht, ist es so ähnlich wie mit Security. Das sollte man einfach produktiv nicht selber machen. Oder man kann ja eben auch dann auch zurückgreifen auf andere Libraries, so wie jetzt Andis Library. Ich habe übrigens gerade nachgeschaut, hat auf GitHub schon 23 Stars bekommen. Verwendet die? Sorry, 24 Stars. Verwendet die schon jemand?
Andy Grunwald (00:42:02 - 00:45:53)
Ja, pass auf, das ist ja jetzt das Geile. Die ganze Sache hab ich im Februar 2016 programmiert, als ich nämlich auf der FOSDEM war. Die FOSDEM ist die Free and Open Source Developer Europe Meeting-Konferenz in Brüssel. Findet jedes Jahr statt. war bisher immer on-site, und jetzt wegen Corona war's zwei Jahre nur virtuell. Aber jetzt in 2023, erstes Wochenende Februar, findet die wieder statt. Sehr zu empfehlen. Auf jeden Fall habe ich da im Hotelzimmer, und da gibt es so einen Hacking-Room, irgendwo habe ich einen Talk über irgendwas gelesen, weiß ich jetzt nicht mehr. Auf jeden Fall habe ich dann angefangen, hey geil, was fängst du jetzt an? So, Februar 2016. Dezember 2020 kriege ich auf einmal eine E-Mail. Eine E-Mail von der Firma FaceIt. Du musst wissen, FaceIt ist die größte Firma im Counter-Strike-Sektor, die professionelle Counter-Strike-Server hostet. Jetzt sagst du, hä? Ja, also folgendermaßen. Ein bisschen Historie. Valve selbst, also die Firma hinter Counter-Strike und Steam und so weiter und so fort, hostet auch Counter-Strike-Server. Und eigentlich kann jeder einen Counter-Strike-Server hosten. Der Punkt ist aber, die Standard-Counter-Strike-Server, die laufen auf einer 64-Tick-Rate. Das bedeutet, der Server refresht 64-mal pro Sekunde sein Stati. Ja? Die Server von FaceIt laufen aber auf einer 128er-Tickrate. Das bedeutet eigentlich doppelt so schnell. Ja? Also, die refreshen doppelt so schnell. Und im professionellen Gaming, keine Angst, da sind wir beide mit unserer Reaktionszeit schon längst raus, im professionellen Gaming ist das ein enormer Unterschied. Das kann dann wirklich das Spiel ein bisschen verändern, wenn der Server mehrmals, also doppelt so schnell, den Game State refreshed. So. Und Faceit ist unter anderem die Firma, die ganz viele solcher Servers betreibt, aber auch professionelle Turniere macht. Unter anderem halt auch diese Streaming-Overlays, von denen ich am Anfang erzählt hab, wer hat wie viel Leben noch und wer hat welche Waffe und so weiter und so fort. Und dann schreibt mir ein Developer von denen und sagt, hör mal Anni, hast du Lust auf ein Jobangebot? Hast du Lust bei uns zu arbeiten? Ich denk so, wie, hä? Wie kommt ihr da? Ja, pass auf, wir haben deine, wir benutzen Go und wir schreiben alles in Go und wir haben deine Library gesehen und wir setzen die auch ein und wir sind ziemlich begeistert davon. Ich denk so, ach ihr wollt mich doch jetzt veräppeln, ja. Also die nutzen jetzt wirklich in deren kompletten Live-Streaming-Events, also immer wenn ihr jetzt hier so ein großes ESL-Tournament seht, in der Lenxes-Arena findet das zum Beispiel sehr oft statt, da läuft Teil meines Quellcodes auf diesem Scheiß-Screen, ja, damit diese Daten da angezeigt werden. Naja, auf jeden Fall hab ich dann gesagt, komm, das hör ich mir mal an, was sie damit machen und so weiter und so fort. Im Endeffekt war es dann alles ein bisschen komplizierter, weil die ja nicht wirklich, also die wollten, dass ich dann nach London umziehe und mit Remote Work waren sie jetzt noch nicht ganz weit vorne, damals im Dezember 2020. Aber was ich damit eigentlich sagen möchte ist, aus dieser wirklich vollkommenen Schnapsidee, und ja ich hätte diese ganze UID Replacement sehr wahrscheinlich auch mit einer ganz klassischen Rack Axe machen können, kommt dann irgendwann so um Weihnachten rum eine E-Mail von einem der größten Turnierbetreiber in dem ganzen Sektor, weil der dann der library nutzt und das muss ich zugeben war ein neben dem job angebot war es natürlich was auch sehr toll war fand ich eine ungemein schöne bestätigung weil man bekommt ja immer um source umfeld sehr sehr wenig feedback für was dein kram eigentlich genutzt wird Ich hab dann natürlich auch versucht, dass FaceIt irgendwie das Ding ein bisschen sponsort und mich ein bisschen unterstützt und die Entwicklung ein bisschen nach vorne treibt und sowas halt. Ist dann irgendwie nicht ganz erfolgreich gelaufen.
Wolfi Gassler (00:45:53 - 00:46:00)
Das heißt zusammengefasst, du hast gelernt, was ein Lexer ist, was ein Barser ist und hast noch ein Jobangebot bekommen.
Wolfi Gassler (00:46:02 - 00:46:06)
Und wie viele von deinen Freunden haben sich beschwert, dass du bei ihnen da irgendwas ausführst?
Andy Grunwald (00:46:06 - 00:46:25)
Nichts, die haben's installiert. Ich hab ihnen dann versucht zu erklären im ersten Spiel, was das ist. Die haben alles nicht verstanden. Vielleicht hab ich's zu kompliziert erklärt. Irgendwann haben sie's vergessen. Ich hatte diesen Webhook-Server locker noch ein Jahr laufen. Irgendwann ist die Festplatte vollgelaufen, weil ich so viel Daten geschrieben hab.
Wolfi Gassler (00:46:25 - 00:46:29)
Hast du mit den Daten was gemacht am Ende? Oder hast du die nur abgespeichert?
Andy Grunwald (00:46:30 - 00:47:02)
Ich hab die in der MySQL gepumpt und irgendwann hab ich diesen Server ausgemacht und hab die MySQL vorher noch gebackupt, also ich hab die noch irgendwo. Aber inzwischen gibt es Online-Services, die dir dann im Web Spieleanalysen davon machen. Und die basieren genau auf diesem Konzept. Das bedeutet, du siehst, du hast unten so einen Timeslider und siehst, wie das ganze Team sich über die Karte bewegt hat und wo ihr zu welchem Zeitpunkt standet. Ja, weil da geht's halt wirklich fünf gegen fünf, ist halt wirklich Strategie. Also da gibt es jetzt Services, die machen genau das, was ich vorhatte, nur halt ein Jahr oder ein paar Jahre später.
Wolfi Gassler (00:47:02 - 00:47:05)
Das heißt, du hättest ein Produkt draus bauen können eigentlich.
Andy Grunwald (00:47:05 - 00:47:12)
Tun die. Und ich hab da mal reingeguckt und das ist wirklich superior, also das ist wirklich gut gemacht.
Wolfi Gassler (00:47:12 - 00:47:41)
Also du hast ja jetzt wirklich geschafft, Andi. Wir hatten mal im Zuge von ganz am Anfang von unserer Episode 3, wo wir über Overengineering gesprochen haben, haben wir eine Rückmeldung bekommen von einem Hörer, dem Christian, der da sehr viel geschrieben hat und der auch vorgeschlagen hat, er würde gern mal so Geschichten vom Krieg, der Opa erzählt vom Krieg hören. Ich glaube, du hast damit jetzt geschafft, Over-Engineering kombiniert mit den Geschichten aus dem Krieg eine ideale Episode daraus gebaut zu haben. Christian würde es dir erdanken.
Andy Grunwald (00:47:42 - 00:48:00)
Wir verlinken euch auch nochmal in den Shownotes ein paar Videos, was Leute auf YouTube denn mit dieser Game State Integration machen. Wie zum Beispiel, was ich gerade erzählt habe, die verändern das Licht in ihrem Zimmer mit Home Assistant. Dafür haben wir auch schon eine Episode gemacht.
Andy Grunwald (00:48:02 - 00:49:03)
Machen dann die Lampe rot, wenn sie die Bombe nicht mehr entschärfen können. Oder falls ihr irgendwie Twitch-Streamer seid oder ähnliches, auf jeden Fall in diesem Streaming-Business seid, wie man so ein Game-State-Overlay, von dem ich grad gesprochen hab, was ihr immer von diesen großen E-Sport-Turnieren kennt, wie ihr so was selbst bauen könnt. Weil, Achtung, diese Twitch-Overlays ... Das ist alles nur HTML. Das ist so funny. Das ist so geil. Du kannst damit eigentlich alles bauen. Ein bisschen HTML, ein bisschen JavaScript, vielleicht ein bisschen Web-Server-Kram und Webhooks da hinten dran und Abfahrt. Das kannst du da mit OBS oben drauflegen und top. Ich hab immer gedacht, das ist komplette Rocket Science und mit on the fly Videobearbeitung, aber nein, das sind einfach HTML-Elemente. Und diese großen professionellen E-Sport-Overlays in den Turnieren, das ist alles HTML. Mir platzt gleich der Kopf, weil das einfach so geil ist. Was man da einfach bauen kann, wenn du ein bisschen Programmierverständnis hast. Und dann hab ich halt ein Lexar und ein Parser für ein VDL-Format gebaut, ja.
Wolfi Gassler (00:49:03 - 00:49:46)
Ich wäre ja neugierig, ob die heutigen Anfänger und Anfängerinnen im Computerbereich, ob die bei Spiele dann genau über diesen Weg einsteigen. Also das, was bei uns früher Autoexec editieren war und irgendwie ein bisschen rumtweaken, dass man überhaupt was spielen kann. Ob das heutzutage einfach in die Richtung geht. Ich finde dann raus, da gibt es APIs. Ich will meine Lampe rot stellen, weil ich gesehen habe auf YouTube oder Twitch, wie cool das ist, dass die Lampenfarben sich automatisch einstellen, je nach Spielstatus. Und man steigt dann so vielleicht in das ganze Programmieren. Also wäre ich neugierig, falls wer da Geschichten kennt oder auch das bestätigen kann, ob das da die neue Einstiegsdroge in die IT und ins Programmieren ist bei Jugendlichen. Würde mich sehr interessieren.
Andy Grunwald (00:49:46 - 00:50:22)
Allgemein kann ich sagen, dass ich finde das eine relativ schöne Open Source Story. Natürlich macht Faceit damit jetzt auch Geld und allem drum und dran. Dieser, dieser klassische, dieses klassische Problem, dass eine Firma, die profitorientiert ist, meine Arbeit nutzt, um irgendwie ein Feature zu verkaufen und das leider nicht sponsern wollte. Das finde ich auch sehr schade. Retrospektiv muss ich sagen, ich hatte sehr, sehr viel Spaß die paar Abende. Ich hatte sehr, sehr viel Spaß das zu testen. Und es wird hier und da auch noch genutzt ja es wird auch noch irgendwo in china oder in japan genutzt da haben das auch ein paar leute integriert für was genau weiß ich jetzt auch noch nicht wollte ich noch mal ein bisschen recherchieren und die kontaktieren.
Andy Grunwald (00:50:25 - 00:50:31)
Also anhand der comet history habe ich so circa sechs sieben stunden dafür gebraucht bis die erste version lief.
Wolfi Gassler (00:50:32 - 00:50:42)
So ein Take-Home-Test bei einer Bewerbung braucht ungefähr gleich lang. Also für das, dass du eine Job-Offer dann quasi bekommen hast oder zumindest den Kontakt.
Andy Grunwald (00:50:42 - 00:51:34)
Danach kam natürlich noch ein bisschen Bug-Fixing, ja. Also ich habe das dann im Februar, März gemacht und im August 2016 habe ich dann nochmal was gemacht und dann habe ich Da kam noch mal ein Bug im Oktober 2019. Und dann kam noch irgendwann mal ein Bug im Oktober 2021, weil ich C++-Comments nicht ordentlich supportet hab. Du musst wissen, die Valve-SDKs, die das Format eigentlich parsen, sind alle in C++ geschrieben. Und das Lustige in der Wiki-Seite vom Valve steht auch, nur weil das die Formatspezifikation ist, heißt nicht, dass das Valve-C++-SDK diese Spezifikation eins zu eins implementiert. Also die schreiben halt Spezifikationen, aber implementieren sie halt auch nicht komplett oder sagen, die geben da keine Garantie drauf. Aber ja, genau 5, 6, 7 Stunden habe ich für den initialen Code gebraucht, bis ich das dann das Fliegen hatte. Klar, der Installer hat dann ein bisschen länger gebraucht und so weiter und so fort.
Wolfi Gassler (00:51:34 - 00:51:47)
Falls jemand weiß, warum das kein JSON oder irgendein allgemeingültiges Format ist, gerne auch die Info senden. Aber wahrscheinlich war damals JSON einfach noch kein Standard in dem Bereich. Ist wahrscheinlich einfach ein historischer Grund.
Andy Grunwald (00:51:47 - 00:52:21)
Das war meine kleine Story über Lexer, Tokens und Parser. Falls ihr eine ähnlich motivierende Story habt, Wo ihr ergebenenfalls was neues gelernt habt in der Softwareentwicklung, Softwareengineering und das mit irgendwas mit einem Hobby kombiniert habt. Zum Beispiel wolltet ihr mal ein Hochbeet automatisch bewässern oder ihr habt zum Beispiel die Game State Integration von Left 4 Dead 1 und 2 auf eine ähnliche Art und Weise getweakt. Lasst uns doch mal wissen, was ihr da im Detail gemacht habt. Wir würden uns auf jeden Fall über eure Story freuen.
Wolfi Gassler (00:52:22 - 00:52:32)
Gerne auch bei Twitter, EngKiosk wie immer oder wenn es persönlicher sein soll, an die E-Mail-Adresse steht dies. Andi ist immer teilbar.
Andy Grunwald (00:52:32 - 00:53:02)
Schickt uns auch mal eine Sprechnachricht, eine Sprachnachricht. Wir sind über WhatsApp for Business angebunden. Deswegen einfach mal in die Show Notes gehen, da habt ihr unsere WhatsApp-Nummer. Speichert die kurz ein, schreibt uns eine Nachricht. Ich glaube, da antworten wir auch schneller drauf als E-Mails oder auf Twitter. Von daher, wir würden uns auf jeden Fall freuen, da mal eine Text- oder Sprachnachricht zu bekommen. Hoffentlich haben wir euch ein bisschen motiviert, auch ein bisschen Open Source zu machen, auch ein bisschen reale Anwendungsfälle damit abzudecken. Wenn nicht, würden wir uns freuen, dass ihr uns weiterempfehlt. Ansonsten sehen wir uns nächste Woche. Bis bald.