Big World Setup begrenzt empfehlenswert
Anfangs war ich ziemlich begeistert von dem Big World Setup, der Modsammlung, die alle Teile Baldur's Gates zusammenfügt und erweitert. Nun bin ich in der letzten Erweiterung, Thron des Bhaals, angekommen, und meine Begeisterung ist verpufft.
Man stelle sich folgendes Spieldesign vor: Der Auftraggeber schickt einen zur Elfenkönigin, um mit ihr das weitere Vorgehen zu besprechen. In dem Gebiet, in dem sie sich aufhalten könnte, ist sie nicht, denn diese Elfenkönigin ist gar nicht (mehr) im regulären Spiel vorhanden. Alleine durch das Betreten des Elfengebietes wird ohne Hinweis eine Region zur Weltkarte hinzugefügt. Dort muss man hingehen, um dann dort festzusitzen. Ein Magier will auf eine Insel teleportieren und fragt nach einem Portalstein, den ich aber niemals fand.
Diese noch zu ergänzende Sammlung von Grausamkeiten erwartet den Spieler nach dem Ende von Baldur's Gate 2, wenn die Standardeinstellungen des Big World Setups übernommen wurden und dadurch der Mod "The Darkest Day" hinzugefügt wurde. Diese Brücke zwischen Hauptspiel und Addon wird so ganz schnell zur Sackgasse, nicht nur bei mir, weshalb man von den Problemen schon vor einem Jahr im Forum lesen konnte. Mir wurde das dann zu doof, ich startete das Addon manuell und importierte meinen Charakter.
Beinahe wäre ich aber nichtmal dorthin gelangt. Ein neuer Zusatzinhalt, ein Drachenkampf in Baldurs Gate 1 der Mod "Dark Side of the Sword Coast", fraß meine Spielstände - reproduzierbar. Zum Glück hatte ich in Erwartung des Drachen vorher gespeichert, sonst wäre das Spiel zuende gewesen. Nebenbei: Gegen den Drachen hatte meine Gruppe natürlich keine Chance.
Überhaupt scheint Balancing für die Questbauer oftmals ein Fremdwort zu sein. Die Belagerer des Zwergengasthauses (ein Zusatzquest in Baldurs Gate 1) sind so stark, dass man den Kampf mit fairen Mitteln auch auf dem einfachsten Schwierigkeitsgrad nicht gewinnen kann - der Autor nennt das "enjoyable". Einzeln müssen die Feinde herausgelockt werden, im Grunde ist das Bugusing. Spaßig ist was anderes.
Wirklich toll ist das Ganze also nicht. Aber natürlich ist auch nicht alles schlecht, Baldurs Gate 1 in der Baldurs Gate 2 Grafik ist nett, das Verbinden des ersten und zweiten Teils hat halbwegs funktioniert (aber wirklich nur halbwegs, die Inszenierung war an sich mangelhaft, funktionierte aber wenigstens ohne technische Probleme), wahrscheinlich haben auch die Balancingsversuche und Fixpacks nicht geschadet und die Gespräche zwischen den Charakteren auch im ersten Teil zu haben ist auch gut. Das hätte dann aber auch gelangt.
Wenn man also das Big World Setup nutzen will, sollte man bei der Installation die Questmods aussortieren.
Wave als Schachplattform
Der Einsatzzweck von Google Wave ist ja nur schwer zu bestimmen. Bei uns wird das ganze gerade etwas zweckentfremdet und es laufen ein paar Schachspiele darüber.
Die Frage ist, ob das wirklich eine Zweckentfremdung ist. Wave wurde immerhin angekündigt als moderne Email, die eben mehr als nur ein statischer Text sein kann. Alle mögliche Gadgets können eingebunden werden, und wenn das nunmal ein Schachspiel ist, dann ist es eben ein Schachspiel.
Vielleicht ist Wave genau durch diese Möglichkeiten etwas ziemlich spannendes.
SourceForge ist tot, blockt freien Zugang
Sourceforge ist eigentlich der zentrale Anlaufpunkt für offene Software, erfüllt diese Aufgabe aber nicht mehr. Gemäß amerikanischen Exportbestimmungen wird der Zugang aus Ländern wie Kuba und Iran geblockt (via). Das widerspricht natürlich dem Grundgedanken freier Software, dem offenen und freien Zugang zu Informationen bzw. der Software.
Was sind die Alternativen? Google ist keine, nicht etwa wegen einer Machtstellung, sondern weil sie schlichtweg vor dem gleichen Problem stehen und sich ebenfalls diesen US-Bestimmungen unterwerfen.
Auf der englischen Wikipedia gibt es eine gute Übersicht inklusive den vorgenommenen Zugangsbeschränkungen. Und ansonsten ist es vielleicht einfach an der Zeit, wieder mehr selbst zu hosten.
Rekursion
Eigentlich ist das ja "nur" ein Win 3.1-Nachbau (via). Aber solchen Gedankengängen kann ich einfach nicht mehr widerstehen.
Die Mövenpick, Privatversicherung-, Rabatt und Ämterpatronage-Partei
Unsere Lieblingspartei. Zu welcher sonst könnte man einen solchen Vorwurf von a bis e unterteilen?
Das passt ins Bild: Ein Versicherungslobbyist als Abteilungsleiter ins Gesundheitsministerium, ein Streiter gegen die Pharmalobby wird abgesägt, Parteifreunde werden mit hochdotierten Post in den FDP-Ministerien versorgt. Es gibt wohl keine Partei, die derart schamlos Ämterpatronage betreibt. Das diese Enttarnung schmerzt mögen Sie daran erkennen, wie aufgeregt und aggressive Guido Westerwelle darauf reagiert.
Curl ignoriert Range
Ich habe gestern nochmal ein Update des Autotitel-Plugins veröffentlicht. Eigentlich sollte nur eine Konfigurationsoption eingefügt werden, aber dabei fiel mir auf, dass curl unter PHP seine eigene Range-Option nicht beachtet.
$ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_RANGE, "0-4096"); $page = curl_exec($ch); curl_close($ch);
$page sollte hiernach nicht mehr als 4096 Byte groß sein, wird aber beliebig größer. Daher ist nun wieder
file_get_contents($url, 0, null, -1, 4096);
der Standardweg, nur wenn das scheitert wird es nochmal mit curl versucht.
Niedere Arbeit
Wir wissen ja, bei wem wir uns dafür bedanken können, dass Koch mit sowas noch gehört wird (via).
Autotitel mit curl
Autotitel ist mein Lieblingsplugin: Es macht genau eine Sache, und die macht es gut. Es setzt für jeden Link den Titel der verlinkten Seite als "title"-Attribut, sodass man diesen als Tooltip zu sehen bekommt, wenn man über den Link fährt.
Teil meiner Sympathie für das Plugin basiert darauf, dass es schnell geschrieben war und seitdem problemlos seinen Dienst verrichtet, inklusive des 7-Tage-Caches. Damit es auch auf Servern so problemlos laufen kann, bei denen fopen nicht erlaubt ist, nimmt das Plugin nun wenn möglich curl zum Holen der Seite.
Zusätzlich wird der Cache an einer geeigneteren Stelle initialisiert und Fehlermeldungen, die beim Versuch des Ladens von unerreichbaren Seiten entstehen, werden nun nicht mehr angezeigt.
Das Update auf 0.1.3 ist in Spartacus hochgeladen.
Zeitgeist und Activity Journal 0.3.2
Wie sieht Ubuntu morgen aus? Wenn Ubuntu weiterhin ein Gnome-Desktop sein wird, kann es gut sein, dass das Gnome Activity Journal Teil davon sein wird. Von diesem GAJ ist nun die erste Version herausgekommen, gekoppelt an ein neues Zeitgeist-Release.
So langsam kann man versuchen, sich eine Meinung über das Projekt zu bilden.
Wow, Realtime
Techcrunch schreibt völlig sinnbefreit, dass ICQ in der Realtime-Ära angekommen wäre (via). Dabei war ICQ schon immer realtime und wirds auch immer sein - es ist instant messaging, Nachrichten werden direkt versendet, kein Client fragt den Server jede Stunde, ob da vielleicht eine neue Nachricht vorliegt. Eben ein Push-Verfahren.
Wenn überhaupt meint der Artikel, dass ICQ durch die Integration von Facebook und ähnlichem im Web 2.0 angekommen wäre, wobei selbst dann sich die Frage stellt, ob die massive Vernetzung von Menschen untereinander durch ICQ nicht schon immer Teil des Web 2.0, des sozialen Netzes, war.
Aber was kümmern amerikanische Technikseiten die Modewörter von gestern.
Pubsubhubbub - Code
Der Pubsubhubbub-Test verlief negativ, beim Hub scheint nichts anzukommen. Wer helfen oder auch nur einen Überblick davon bekommen will, wie ich das versucht habe: Im Forum habe ich alle Codeteile gezeigt.
Pubsubhubbub
Pubsubhubbub ist ein offenes Protokoll von Google, das eine Beschleunigung der (RSS-)Feeds erreichen soll. Statt dass jeder Reader immer wieder nachschaut, ob neue Inhalte da sind, benachrichtigt die Seite mit den Inhalten einen Hub und dieser gibt dem Reader bescheid. Da jeder einen solchen Hub betreiben kann, bleibt das Prinzip dezentralisiert.
Wie ich nun darauf komme? Ich habe gerade ein paar Anpassungen an Serendipity vorgenommen, wodurch pubsubhubbub genutzt werden sollte. Das hier ist also ein Test.
Fahnenflüchtlinge
Während in Deutschland kein Mann mehr zur Armee gezwungen wird, sondern jeder verweigern kann, steckt Israel Kriegsdienstverweigerer ins Gefängnis und stigmatisiert sie. Ironie der Geschichte.
Eigene Pluginseiten in Serendipity
Nachtrag 2: Einem Plugin eigene Seiten im Adminbereich zu geben ist relativ simpel. Soll die Seite aber im offenen Bereich des Blogs dargestellt werden, wird das Verfahren etwas komplizierter. Denn anstatt einfach auf das Event zu warten, das beim Besuchen unserer Seite geworfen wird, muss bei jedem Seitenaufruf geschaut werden, ob dies nicht unsere Seite ist.
Das listsearch-Plugin dient mir als Beispiel, wobei ein Großteil des Codes direkt dem contactform-Plugin entnommen ist.
Prüfen
Kern des ganzen ist also zu erkennen, ob dies die richtige Seite ist. Deshalb ist selected() die wichtigste Funktion. Sie gibt immer dann true aus, wenn der Seitenname "searchresults" an der richtigen Stelle in der URL ist.
function selected() { global $serendipity; if (!empty($serendipity['POST']['subpage'])) { $serendipity['GET']['subpage'] = $serendipity['POST']['subpage']; } if ( $serendipity['GET']['subpage'] == '/index.php?/searchresults' || preg_match('@^' . preg_quote($serendipity['serendipityHTTPPath'].'searchresults') . '@i', $serendipity['GET']['subpage']) ) { return true; } return false; }
Im richtigen Moment Darstellen
Leider ist das Zeigen der Seite nicht ganz einfach. Obwohl es im Grunde nur ein Event ist:
case 'entries_header': if ($this->selected()) { $this->show(); }
Wobei show() dann die Seite ausgibt und weiter unten beschrieben wird. Doch es müssen noch zwei weitere Events gefangen werden, damit alles passt. Um den Seitentitel zu setzen, ist 'genpage' gefragt:
case 'genpage': $args = implode('/', serendipity_getUriArguments($eventData, true)); if ($serendipity['rewrite'] != 'none') { $nice_url = $serendipity['serendipityHTTPPath'] . $args; } else { $nice_url = $serendipity['serendipityHTTPPath'] . $serendipity['indexFile'] . '?/' . $args; } if (empty($serendipity['GET']['subpage'])) { $serendipity['GET']['subpage'] = $nice_url; } if ($this->selected()) { $serendipity['head_title'] = QUICKSEARCH; $serendipity['head_subtitle'] = htmlspecialchars($serendipity['blogTitle']); } break;
Wichtiger noch als ein guter Titel ist, dass außer unserem Inhalt keine anderen Beiträge auftauchen. Dafür muss 'clean_page' gesetzt werden:
case 'entry_display': if ($this->selected()) { if (is_array($eventData)) { $eventData['clean_page'] = true; // This is important to not display an entry list! } else { $eventData = array('clean_page' => true); } } return true; break;
show()
Nun ist klar, wann wir etwas anzeigen. Im Idealfall wird aber nun nicht einfach irgendwas ausgegeben, sondern die Ausgabe Smarty übergeben. Daher ist show() gar nicht so simpel, deshalb hier nur der elementare Teil:
function show() { ... if (!headers_sent()) { header('HTTP/1.0 200'); header('Status: 200 OK'); } if (!is_object($serendipity['smarty'])) { serendipity_smarty_init(); } $serendipity['smarty']->assign( array( 'results' => $results ) ); $template = 'listsearch.tpl'; $tfile = serendipity_getTemplateFile($template, 'serendipityPath'); #serendipity_getTemplateFiles returns filename if no file found #in the templates instead of false (?) if ($tfile == $template) { $tfile = dirname(__FILE__) . "/$template"; } $inclusion = $serendipity['smarty']->security_settings[INCLUDE_ANY]; $serendipity['smarty']->security_settings[INCLUDE_ANY] = true; $content = $serendipity['smarty']->fetch('file:'. $tfile); $serendipity['smarty']->security_settings[INCLUDE_ANY] = $inclusion; echo $content; }
Es wird der richtige header für eine gefundene Seite ausgegeben, Smarty initialisiert falls es noch nicht getan wurde und danach die listsearch.tpl mit den gefundenen Beiträgen ($results) gefüllt. An dieser Stelle könnte man natürlich noch viel mehr übergeben, so reicht der echte Code an dieser Stelle noch die Trefferanzahl weiter.
Nun kann die Seite "index.php?/searchresults" des Blogs aufgerufen werden.
Einzelschicksal
Sie: Eine wunderhübsche junge Frau mit milchkaffeefarbener Haut und langem schwarzem Haar.
Er: Seine Art entspricht mehr der eines Beamten, mit der Brille und den nach hinten gegelten Haaren.
Die beiden studierten in einem technischen Studiengang. Mir waren sie zuvor aufgefallen, als sie bei einem Testat warteten und sehr heftig ihren angeblich vorher gesicherten Platz verteidigten, insbesondere sie. Auch wenn sie schön war, war der erste Kontakt ein Ankeifen - unsympathisch.
Etwas danach sah ich die beiden wieder. Diesmal stritten sie miteinander.
Er: "Du musst dein Verhalten ändern. So geht das nicht, wie du dich verhältst."
Sie: "Wovon redest du?"
Er: "Es geht einfach darum, dass du dich richtig verhältst. Du musst mehr darüber nachdenken, was du tust."
In Worte packen, was er wirklich meinte, das konnte er nicht. Sie verfiel in ein Schweigen und saß verlegen da, um hin und wieder aufzufahren und verständnislos zurückzukeifen, während er immer weiter auf sie einredete.
Sie muss zuvor irgendwie gegen sein Ehrgefühl verstoßen haben. Sie trug kein Kopftuch, keinen Schleier, ganz normale modische und knappe Kleidung. Vielleicht hatte es auch nichts mit der Kleidung zu tun, sondern dass oder wie sie mit anderen Männern redete - was immer es war, da er es nicht in Worte packen konnte, wird sie es nie verstanden haben.
Oder vielleicht doch. An der Uni wiedergesehen habe ich sie nie.