Archive for Juni, 2009

Windows Live Alerts

Samstag, Juni 13th, 2009

Moin Moin,

Ebay hat schon kuhle Features.

Naja, da bin ich nun einfach einmal den Benachrichtigungen Gefolgt, und was kommt?
- eine offizielle seite von Microsoft alerts.live.com.

Ich denke einfach mal, dass das die MSN-Reaktion auf Twitter ist, jedoch für Server-Watch eventuell ganz gut zu gebrauchen.

Schauen wir doch einfach mal

PHP + Subfunctions = Fail

Dienstag, Juni 9th, 2009

Folgender Code:

[code lang="php"]class a {

	public function b($a) {
		$b = 2 * $a;
		function c() {
			printf("%d / %d\n", $a, $b);
			return 5;
		}
		return c() + 2;
	}
}

switch( @intval($_SERVER['argv'][1]) ) {
case 1:
	c();
	break;
case 2:
	$a = new a();
	$a->c();
	break;
case 3:
	$a = new a();
	$a->b(4);
	$a->c();
	break;
case 4:
	$a = new a();
	$a->b(5);
	c();
	break;
default:
	die("1-4\n");
}
echo "success\n";
exit;
[/code]

Soweit klar, theoretisch sollte die Unterfunktion c nur aus b aufrufbar sein und auf die Variablen von b zugreifen können. Praktisch sieht das ganze ein wenig anders aus:

root@sumpfkraut:/var/www/old/stats# php test.php 1
Fatal error: Call to undefined function c() in /var/www/old/stats/test.php on line 17

root@sumpfkraut:/var/www/old/stats# php test.php 2
Fatal error: Call to undefined method a::c() in /var/www/old/stats/test.php on line 21

root@sumpfkraut:/var/www/old/stats# php test.php 3
0 / 0
Fatal error: Call to undefined method a::c() in /var/www/old/stats/test.php on line 26

root@sumpfkraut:/var/www/old/stats# php test.php 4
0 / 0
0 / 0
success

Okay, damit habe ich nun eigentlich nicht gerechnet. Ein kurzer Blick auf PHP.net bestätigt dieses Verhalten:

Ich will wirklich nicht wissen, wer sich dieses Konzept ausgedacht hat – ich finde es einfach sinnlos. Vermutlich sind diese Funktionalitäten in den Urzeiten von PHP entstanden, als der gesamte OOP Ansatz noch nicht gegeben war, wobei ich auch unter diesen Umständen die gegebene Implementation äußerst suboptimal finde.

Eine semi-elegante Lösung wären anonyme Funktionen:

[code lang="php"]$a = function($p) {
  return $p + 5;
};

printf("%d\n", $a(10));
[/code]

..leider erst mit PHP 5.3 verfügbar. Ich habe nun einfach meinen Server auf 5.3 aktualisiert (PHP compilen ist doch immer wieder schön!).

Nicht unbedingt konventioneller Code, aber ich denke durchaus praktisch:


(ja, da ist ein Logikfehler drin — wer ihn findet, bekommt einen Keks)

Visual Basic 6.0 – 2005 / 2006

Montag, Juni 8th, 2009

Backups sind eine feine Sache. Wenn man sie einigermaßen ordnet. Nachdem ich nun stundenlang den Source meines screenshotbasierten Pseudo-WoW-Angelbots gesucht habe, bin ich nun wenigstens auf einige andere interessante Codes gestoßen: Visual Basic Projekte aus den Jahren 2004 bis (größtenteils) 2006. Was ich damals “ausgekotzt” habe, ist wirklich .. heftig.

Wie nicht anders zu erwarten befinden sich im “Programmierung” Ordner mit seinen stolzen 76 Unterordnern zahlreiche Chats, aber auch einige andere interessante Projekte – einige davon haben mir beim Starten den ein oder anderen “wtf” Moment beschert:

1. Der “Skalierbarkeitschat”

Gefunden im Ordner Chat trifft es dieser Name denke ich am besten. Das gesamte System beruht darauf, dass die Datenbankzugriffe über den Userserver laufen (“Cache Demon” würde ich es heute wohl nennen), Logins über den Loginserver abgewickelt werden und der eigentliche Chats auf mehrere Channelserver verteilt ist, welche über den Interserver synchronisiert werden. Die Konfiguration erfolgt über Ini Dateien, der Userserver verwendet MySQL. Ironischerweise verwenden alle öffentlichen Server (Login & Channel) auch getrennte Private/Public IPs, was den Verdacht nahe legt, dass diese Struktur indirekt von Sirius_Black inspiriert wurde, mit welchem ich Herbst 2006 erstmals Gespräche über Serversoftwaredesign, bzw. eAthena hatte.

In späteren Versionen war das System wohl auch stabil lauffähig – jedenfalls finden sich einige Auswertungen zu mehrtägigen Testläufen auf “dem root”. Interessanterweise besitzen diese Versionen, von denen ich leider keinen kompletten Source mehr habe, keine eigene GUI mehr, was auf eine Remote Administration entweder per Client oder per RemoteAdmin etc. schließen lässt. Die bestehenden Codeteile (Interserver) enthalten außerdem zu 2/3 “Bugfix: ..” Kommentare – offensichtlich wurde dieses System entweder sehr ausgiebig getestet oder war tatsächlich irgendwo im Einsatz; keine Ahnung wo :/

2. Scriptschulenchat

Einige der “alten Hasen” mögen sich noch an die Scriptschule erinnern – dies war die dafür benutzte Chat Software. Wohl gemerkt war dies das erste Chatprojekt, welches mir deutlich vor Augen geführt hat, dass man seine Protokolle DoS-sicher gestalten sollte – beim ersten Testlauf der Scriptschule müllte Apple mit einem 5 Minuten Skript meinen damaligen Rechner relativ schnell mit Fehlermeldungen zu. Technisch gesehen verfolgt die Software einige interessante Ansätze: Der Server überprüft beim Starten die Systemzeit und verweigert ab 29.12.2006 den Dienst – hier wird wohlgemerkt mit RSA Zertifikaten gearbeitet, welche die Gültigkeitsdauer angeben. Die Userdatenbank verwendet eine Plaintextdatei, welche jedoch über einen Vignere ähnlichen Algorithmus gesichert ist. Das Nachrichtenprotokoll ist bilingual aufgebaut, von Haus aus unterstützt das System Deutsch, Englisch und Polnisch. Der Serverpart wurde später neu geschrieben und auf MySQL umgestellt:

Der Rewrite war dann größtenteils eine Optimierung und Neustrukturierung der Codebasis. Es wird nun eine relativ umfangreiche Konfigurationsdatei (gut, 29 Einstellungen) gelesen, die “Message of the Day” ist in eine Textdatei ausgelagert (mit Variablensupport für Onlinestati), die Userdatenbank nutzt konsequent MySQL. Das Netzwerkprotokoll ist nun “versioniert” (frühere Chats hatten oft Probleme mit alten Clients) und der Netzwerkstream ist einerseits verschlüsselt (Vignere lässt grüßen) und an allen relevanten Stellen wird auf mögliche DoS Lücken geachtet. Weiterhin ist Code für IP Bans zu finden, auch wenn dieser nur mit gültiger Development Lizenz greift – ja, auch das Lizenzsystem wurde massiv erweitert. Soweit ich weiß, war dies eines meiner letzten VB Chatsysteme (entweder dieses oder der “Skalierbarkeitschat”).


3. RemoteAdmin

Die Idee hinter diesem Projekt war es (sofern ich mich richtig erinnere), ein einheitliches Administrationstool für alle Chatprojekte zu schaffen. Eine Übertragung der User- und Channellisten wird unterstützt und sogar ein ‘inkognito’ Eingreifen in den Chat wird unterstützt. Weiterhin natürlich Kicks, Bans und andere Verwaltungsfunktionen. Das dahinterstehende Protokoll ist leider ein ziemlich unsauberer Mix aus Pseudo-Plaintext und Möchtegern-Binär – sprich richtig ekelhaft zu implementieren. In Anbetracht der Codebasis bezweifle ich, dass dieses Tool über längere Zeit aktiv entwickelt wurde, entsprechende Serverkomponenten lassen sich jedoch nur in den beiliegenden Testprojekten finden.


3. Pseudo-IRC-Chat

Dieser Ansatz, datiert auf Juli 2006, verwendet zu Teilen das IRC Protokoll und agiert als IRC Bot, hat aber auch irgendwie Schnittstellen zu anderen VB Chatprotokollen (ich konnte leider nicht feststellen, zu welchem Projekt das Protokoll genau gehört.. wohl irgendwas, was mittlerweile in Vergessenheit geraten ist..). Der IRC Bot beschränkt sich auf stupides Spammen von Text im “#lol” Channel… Was auch immer.

4. ROCP

Nicht nur weil ich dieses Projekt bis zur Wiederentdeckung komplett vergessen hatte, war dies wohl die heftigste “wtf” Situation. Es handelt sich hierbei um einen Webserver, welcher in VB geschrieben ist und über Pipes PHP unterstützt. Über autogenerierte zahlreiche Inklusionsdateien werden auch GET und POST Parameter unterstützt, vom Programm ansich werden Variablen wie der Onlinestatus eines Servers bereitgestellt. Auch dieses Projekt besitzt Protokollanbindungen an ältere Chatsysteme (vermutlich der ältere Chat, welcher bereits PHP verwendete). Das System ist relativ fehleranfällig gegenüber modifizierten HTTP Request Headern, bei konventionellen 404 oder 403 Fehlern (ja, es gibt Zugriffsrechte) antwortet es jedoch korrekt mit Templatedateien und passenden Headern.


5. RO Bot

Aufgrund mangelnder Binaries sind hier leider keine Programmscreenshots verfügbar. Im Nachhinein betrachtet war dies wohl eines der letzten interessanten VB 6 Projekte: Ein funktionsfähiger Ragnarok Bot. Der Bot konnte, zumindest soweit sich aus dem Source und meiner löchrigen Erinnerung schließen lässt, ingame herumlaufen, chatten und angreifen. Interessanterweise war sogar eine eigene Skriptsprache integriert, welche syntaktisch grob an PHP anlehnte und ala Warcraft III mit dem bewährten Trigger/Condition/Action System arbeitete. Zu meinem Erstaunen lesen sich die Parsing Routinen der Skriptsprachen wie rudimentäre Compilingalgorithmen, wie sie in entsprechender Fachliteratur beschrieben sind (das Drachenbuch lebe hoch…) – mit dem Unterschied, dass ich damals keine Ahnung von der Materie hatte und einfach auf Gutdünken los geschrieben habe, in der Hoffnung, dass es irgendwie funktioniert. In Anbetracht der Tatsache, dass ich damals 13 war, habe ich irgendwie das Gefühl, dass meine Lernkurve ein wenig an Steigung verloren hat…


6. WoW Proxy

Der genaue Sinn dieser Anwendung ist mir ehrlich gesagt schleierhaft. Jedenfalls dient diese Programm als Proxy für WoW – es werden dabei bestimmte Bytesequenzen gesucht und, nach mir heute unverständlichen Bedingungen, manipuliert. Ich vermute, dass damit irgendwelche Sprachflags gesetzt werden, damit man den Chat der anderen Fraktion lesen kann. Ich habe mir im Rahmen der “Angelbot”/”Angelproxy” Aktion das WoW Protokoll zwar schon angeschaut und es daher anders in Erinnerung, aber gut.. Vielleicht sah das 2005 noch ein wenig anders aus.


7. SimpleChat

Eigentlich eines der schönsten VB Projekte – ein VB Chat, welcher mit PHP Skripten erweitert wurde. PHP wurde lokal über HTTP angesprochen, Befehle etc. waren dann einfach geskriptet. Das Projekt wurde im Oktober 2005 von Timo und mir begonnen und Anfang Dezember eingestellt, da wir unsere Aufmerksamkeit dem “WOWMod” widmen wollten, aus dem sich ja dann später das allseits bekannte InCel entwickelte. Schade um SimpleChat, es hätte mehr Ergebnisse gebracht als InCel.

Ich habe mir das Protokoll nun nicht komplett angeschaut, aber irgendwie kommunizieren die Clients teilweise mit dem Server und dem PHP Skript, beide Seiten pollen dann jeweils die andere und haben somit Informationen zum aktuellen Datenstand. Der eigentliche Reiz bei der Entwicklung des Chats war.. nunja, die Entwicklung. Timo hat immer bei seinem Vater ohne Internet daran gebaut, ich über die Woche hinweg (damals hatte mein PC noch kein Internet). Der Code wurde vor und nach dem Wochenende dann immer per zip ausgetauscht, in einer Notes.txt standen dann immer unsere kreativen Gedankenergüsse zu den letzten Implementierungen. Wohl gemerkt war dies der mit Abstand stabilste Chat, auch wenn der Featureumfang in keinem Verhältnis zum DSG-Chat (Ende 2004/Anfang 2005, leider kaum noch Material vorhanden) steht.


8. WowStatus

Zwei Haushalte, ein WoW Account, ein Problem: Man kickt sich permanent gegenseitig. Man hätte nun einfach XFire benutzen können, um zu sehen, ob der andere gerade spielt, aber das wäre ja bekanntlich viel zu einfach gewesen. Nein, es musste eine eigene Software her! So entstand dann das WoWStatus Projekt: Auf beiden PCs lief ein Server, welcher, sofern der WoW Prozess lief, einem PHP Skript dies mitgeteilt hat. Der jeweils andere hatte nun einen schönen Client, welcher mit einer bunten Infoseite freundlich erklärte, ob man gerade spielen könne:

——

Ich könnte diese Liste nun noch stundenlang weiterführen, so wären mein “Wer wird Millionär” Nachbau, der DSG Chat, MultiChat und einige andere Programme noch erwähnenswert, aber das würde den Rahmen nun eindeutig sprengen. Allein der DSG Chat bestand aus gut 150.000 Zeilen Code…

PHP, Graphen und .. Räume!

Freitag, Juni 5th, 2009

Note: Veröffentlichumsdatum dieses Posts ist aufgrund der Downtime meines Servers leicht verschoben.

Rein technisch betrachtet war wohl GlobeRO 2008 einer der RO Server mit dem meisten Potenzial – dass es in anderer Hinsicht mehr als in die Hose ging, muss aber wohl nicht erwähnt werden. Wie dem auch sei – da gerade mein Server in Hannover offline ist, habe ich in den letzten Tagen einige der alten PHP Codes herausgekramt und bin dabei auch durchaus fündig geworden. Neben zahlreichen Sprite APIs (welche alle irgendwann entnervt aufgegeben wurden :( ) und diversen experimentellen Gatewaycodes lag dort auch noch das geplante Statistiktool. Die Idee dahinter: Der Server dumpt regelmäßig die Spielerzahl in eine SQL Tabelle und über ein PHP Skript wird periodisch ein hübscher Graph generiert.

Die Grundlagen der Lib sind, laut meinen Unterlagen, gegen Ende Juli 2008 entstanden. Es war damals eigentlich nur eine fixe Idee von Yashiro/T-Bash, bedingt durch dramatische (!) Langeweile wurde diese Idee dann jedoch tatsächlich umgesetzt. Vor ein paar Tagen habe ich nun also die alten Codes herausgesucht, etwas aufgeräumt und die Zeiteinteilungen über eine Wrapperklasse abstrahiert. Dazu noch die in weiser Voraussicht gesammelten Onlineinformationen von PhaseRO eingespeist und heraus kamen einiges recht hübsche Graphen:

…die Jahresansicht ist hier nun nicht dabei, sieht aber nicht groß anders aus. Das Design ist wohlgemerkt noch von GlobeRO, daher das viele Blau ;)

Ich werde die API vermutlich zusammen mit diversem anderen PHP Code gebündelt releasen.

Eine weitere Idee, die vor einiger Zeit (genau genommen Ende März) entstand, wurde nun ein wenig optimiert: Eine etwas erweiterte Version einer RO Datenbank. Alle Daten werden hierbei direkt aus dem db Ordner, bzw. dem Client generiert – soweit nichts komplexes, nur ein wenig Tipparbeit. Grundlegend sollte das System auch jeden NPC visuell darstellen können, sprich mit Sprite und/oder Markierung auf der passenden Minimap. An dieser Stelle wird es dann recht schnell etwas komplexer: wenn man schon die Position von NPCs anzeigt, sollte man ja auch Informationen bieten, wie man dort hin kommt – Stichwort indoor NPCs. In der Theorie ist die Herangehensweise klar: Man lädt den Skriptordner von eA, parst alles auf Warps, liest anschließend die GAT Datei der indoor Map ein, prüft diese auf zusammenhängende Räume und betreibt ein wenig rekursives Pathfinding. In der Praxis war dies auch recht schnell umgesetzt: Ein kleines C Tool zum Laden der GAT geschrieben, dieses hat über eine Cache Datei alles in ein Skript gefüttert und mit knappen 420 Zeilen PHP wurde der Rest erledigt. Leider einerseits relativ ineffizient und andererseits war der Umweg über das C Tool ziemlich umständlich. Ergo: Version 2!

Mit überraschend schnell entstandenen 120 Zeilen PHP lässt sich nun ohne weiteres die GRF auslesen, weitere 150 Zeilen übernehmen das gesamte Lesen und Verarbeiten der GAT Datei. Zum Debuggen hat sich hierbei die GD2 Lib wieder einmal als ziemlich nützlich herausgestellt: Diverse Schritte der Raumerkennung (welche ganz nebenbei gut 400% schneller ist als die erste Version..) lassen sich nun visuall darstellen:


..der erste Durchlauf der Raumeinteilung, noch ohne Partialmerge.


..das sieht doch ganz gut aus :)

Der eigentliche Algorithmus ist dabei relativ simpel aufgebaut: Die Karte wird von unten links Zelle für Zelle durchgegangen, die erste freie Zelle bekommt eine Raum ID. Jede weitere freie Zelle prüft nun zuerst, ob sich links oder darunter eine Zelle mit zugewiesener Raum ID befindet. Ist dies der Fall, wird die benachbarte Raum ID verwendet. Befinden sich links und unterhalb der Zelle unterschiedliche IDs, werden beide Räume zusammengefasst. Wesentlich einfacher und schneller als die erste Version, welche für jede Zelle in alle 8 Richtungen über eine Taskqueue Zusammenhänge überprüft hat. Wohlgemerkt konnte ich bei Version 1 keine Rekursion anwenden, da dies aus irgendeinem Grund PHP dazu brachte, mir eine Segmentation Fault um die Ohren zu werfen.

Mein Codingstil ist hier mal wieder auf Schnellcoding eingestellt, sprich keine Kommentare und zumeist sehr kurze und für Außenstehende nichtssagende Variablennamen. Ich sollte mir wohl wieder ein wenig Tippfaulheit abgewöhnen…: