SO AWESOME. MUST. USE. CAPSLOCK.

October 24th, 2011 by Sirius_White

Als ich 2007 mit der Entwicklung von Anti-Cheat Lösungen begonnen habe war die Zielgruppe recht überschaubar: Außer mir würde diese Software niemand benutzen. Dementsprechend waren Code und Konfiguration quasi ein und dasselbe. Wenn mir etwas aufgefallen ist habe ich es geändert. Sicherheit ist ja bekanntermaßen ein Prozess und kein Produkt. Wer erwartet mit einem Klick die lästige Sicherheitsfrage beantwortet zu haben wird früher oder später ein böses Erwachen haben. In dieser Frage leiste ich tagtäglich Aufklärungsarbeit bei Kunden. Nicht, dass Harmony akute Sicherheitsprobleme hätte. Nein, dabei geht es meistens um viel grundlegendere Probleme. Aber ein Bild sagt mehr als tausend Worte:

Auf die Google Translate Problematik gehe ich lieber gar nicht in Worten ein...

Es ist leider bittere Realität, dass nur ein Bruchteil der Kunden auch nur ansatzweise die Dokumentation- oder Konfigurationsdateien von Harmony beachtet. Ich habe es erlebt, dass mich Wochen nach den Kauf empörte E-Mails erreichten. Harmony würde nicht vor Bots schützen, Hack xy würde weiterhin funktionieren, gestern sei auch noch ihre Webseite gehackt worden und Trolls würden auch nicht automatisch gebannt.
Zugegeben, der letzte Vorwurf hat mich noch nicht erreicht, aber der Rest ist traurige Realität. Warum Harmony nicht funktioniert hat? Es wurde nie installiert.

Nach dem Kauf von Harmony begrüßt einen der freundliche Harmony Sales Monkey folgendermaßen:

Accounteinrichtung: Schritt 1


Accounteinrichtung: Schritt 2

Der betroffene Kunde hatte nach Schritt 1 den Browser geschlossen. Seine IP-Adresse müsste jetzt ja geschützt sein, wofür sollte man auf den großen Button drücken? Nachdem ich freundlich auf die Ursache hinwies läuft Harmony dort soweit ich weiß ohne Probleme, aber es zeigt deutlich das tiefgreifende Problem.

Webseitenhacks verhindert Harmony natürlich auch nicht. Ich führe derzeit bei einigen RO Servern Security Audits durch – mit erschreckenden Ergebnissen. Doch dazu vielleicht ein anderes Mal mehr.

Hm. Nun ist mein Rant fertig und das geplante Thema des Posts wurde völlig verfehlt. Tut einfach so, als würde der Titel Sinn ergeben. :)

The case of the broken bitshift

January 8th, 2011 by Sirius_White

Früher war alles einfach. Zu welchem Netz eine IP-Adresse gehörte konnte allein anhand der Adresse festgemacht werden. Das Konzept nannte sich Netzklassen und wurde bereits nach wenigen Jahren wieder verworfen, weil es nicht die benötigte Flexibilität bot.

Heutzutage werden Netze in der Regel als Subnetze angegeben. Dabei erfolgt die Angabe einer Basisadresse und einer Netzmaske. Die Netzmaske wird dabei für ein binäres AND verwendet. Jede Adresse, welche nach einem binären AND mit der Netzmaske auf die selbe Basisadresse zeigt, gehört zum selben Netz. Eigentlich recht simpel:

In C++ geht das nun noch einfacher. Da eine IP (und folglich auch die Netzmaske) aus 32 Bit bestehen kann man die IP einfach als Integer betrachten und ist nach einer Operation fertig. Soweit kein Problem.

Nun hat man festgestellt, dass es doch ein wenig aufwändig ist, wenn man für die Netzmaske quasi jedes Mal eine zweite IP aufschreiben muss. Mit der Einführung von Classless Inter-Domain Routing (CIDR) hat man daher eien neue Schreibweise eingeführt: die Slashnotation.

Beispiel: 10.0.0.0/8 gibt an, dass das Netz bei der Basisadresse 10.0.0.0 beginnt und die ersten 8 Bit der Netzmaske gesetzt sind. Dies entspricht also dem Netz 10.0.0.0 / 255.0.0.0.0.

Womit wir beim eigentlichen Thema des Postings angekommen wären: Der Umwandlung von Slashnotation zur eigentlichen Netzmaske. In einem älteren Projekt habe ich dazu folgenden Ansatz gewählt:

Netzmaske = (1 << Bitzahl) - 1

Der Gedanke dahinter: Wenn man eine Eins (also das niedrigste Bit) um n Stellen nach links schiebt, kommt eine Eins mit n Nullen heraus. Wenn man nun 1 subtrahiert wird im Binärsystem die Eins durch eine Null ersetzt und die n Nullen durch Einsen (100b - 1 = 011b). Womit wir die gewünschte Netzmaske hätten.

Klappt auch wunderbar. Mit einer Ausnahme: (1 << 32) - 1 = 0.
Bedeutet in der Praxis: Aus jedem /32 Netz - einer einzelnen IP - wird ein /0 Netz - also der gesamte Adressraum des Internets. Solch eine Situatuation ist fatal. Man stelle sich vor, dass ein Datenbankserver von 127.0.0.1/32 Administrationszugriff ohne Passwort erlaubt. Durch diesen Bug hätte jeder Besucher Vollzugriff...

Das Mysteriöse an diesem Bug war, dass er sich nicht reproduzieren ließ, wenn man direkt 32 einsetzt. (1 << 32) - 1 = 0xFFFFFFFF, aber (1 << getThirtyTwo()) - 1 = 0. Das stinkt nach einem Compilerbug.
Nachdem weder ein Umstellen des Codes, ein isoliertes Testen oder Deaktivierung der Codeoptimierung Erfolg brachte habe ich mir angeschaut, welcher Assembler-Code generiert wird:

Der Code ist korrekt. Was zum Teufel...?!
Auf die Lösung gebracht hat mich dann eine kurze Google-Suche:

The 8086 does not mask the shift count. However, all other IA-32 processors (starting with the Intel 286 processor) do mask the shift count to 5 bits, resulting in a maximum count of 31. This masking is done in all operating modes (including the virtual-8086 mode) to reduce the maximum execution time of the instructions.

http://siyobik.info/index.php?module=x86&id=285

Im Klartext: Die CPU schmeißt meinen Optimierungsversuch dezent weg. Bitter. Ein Fix ist hier die Fallunterscheidung, ob man 32 Bits shiften will. Da (1 << 32) statisch berechenbar ist, greift hier der Optimizer des Microsoft Compilers. Aber interessanterweise verhält sich dieser halt anders als die CPU. Mal sehen was Microsoft dazu sagt - werde das die Tage mal melden...

Lektion des Tages: Nichts ist so trivial, als dass man es nicht doch lieber testen sollte...

The case of the storage buttons

November 14th, 2010 by Sirius_White

Gravity ist nicht unbedingt berühmt dafür, stabilen Code zu produzieren. Die Wahl der richtigen Client Version ist daher in der Praxis für die meisten reines Glücksspiel.
Ich werde oft gefragt, welche Version man nutzen sollte. Da ich persönlich weder RO aktiv spiele, noch direkt mit Servern zusammen arbeite, kann an dieser Stelle lediglich auf Harmony Feedback zurück greifen. In der Praxis hat sich gezeigt, dass eine Version von Ende März am besten läuft.

Mit der Einführung des neuen Storage kamen einige Buttons hinzu, welche die einzelnen Kategorien in einem kleineren Fenster öffnen. Über die User Experience dieses Features lässt sich streiten, aber immerhin eine Verbesserung.

GUI Innovation made in Korea

In der erwähnten “stabilen” Version funktionieren diese Buttons nun leider nicht. Gravity wäre nicht Gravity, wenn das Problem zeitnah behoben worden wäre. Es dauerte über vier Monate, bis der Bug behoben wurde.

Mir blieben also zwei Optionen, um auch weiterhin guten Gewissens Empfehlungen geben zu können:

  • Andere Versionen untersuchen, deren Eigenheiten herausfinden und nach umfassender Analyse ggf. eine andere Version weiterempfehlen.
  • Das Problem beheben.

Eigentlich eine rhetorische Frage.

  • Ich bin faul.
  • Der RO Window Manager ist mir nicht unbekannt.
  • Reverse Engineering macht Spaß!

Klare Sache.

Was ist das Problem?
Um es im üblichen Umfang von RO Bug Reports zu formulieren:

Die Storage Buttons funktionieren nicht.

Aha. Um verwertbare Informationen über das Problem zu finden, haben sich einige Fragestellungen in der Vergangenheit als recht nützlich herausgestellt:

  • Welches Verhalten wird erwartet?
    Die sieben Buttons öffnen kleine Fenster im Stile eines einspaltigen Inventories. Die Fenstertitel entsprechen den Item-Kategorien, wie sie auch am linken Rand des Storage Fensters aufgelistet sind. Mehrfaches Drücken der Buttons blendet die Fenster ein oder aus.
  • Welches Verhalten wird beobachtet?
    Die Buttons bewirken entweder gar nichts, öffnen die falschen Fenster (Escape-Menü, korrektes Fenster mit falschem Titel) oder führen zum Absturz des Clients.

      Oft verschweigen Spieler Details! Warum sollte man die Message Box erwähnen, die 5 Sekunden vor dem Crash aufpoppte…?
  • Ist das Problem konstant reproduzierbar? Äußert es sich immer gleich?
    Ja.

      Ein entscheidender Faktor. Probleme, die nur sporadisch auftreten deuten auf Race Conditions oder (meistens) Memory Corruption hin. Diese Probleme sind weitaus komplexer, da oft keine direkte Verbindung zwischen Ursache und Wirkung besteht.
  • Tritt das Problem nur bei vereinzelten Personen auf?
    Nein.

      Im RO Bereich wird oft einen Ordner für eine Vielzahl verschiedener Server verwendet. Dass es damit zwangsläufig zu Problemen kommt, ist leider noch nicht in den Köpfen der Spieler angekommen… Standardantwort: Erneut in einen leeren Ordner installieren
  • Hat Gravity kürzlich Änderungen vorgenommen, die mit dem Problem in Verbindung stehen könnten?
    Nein.

      Oft entstehen Probleme daraus, dass Gravity interne Formate ändert und somit alte Exe Versionen mit dem aktuellen Content nicht mehr kompatibel sind. Einer der Hauptgründe, warum ich kRO Updates nicht den Spielern überlassen würde. Wer neuen Content braucht, kann ihn über eigene Patchserver verteilen.

Wie löst man das Problem?
Der entscheidende Hinweis ist, dass sich unter Umständen falsche Fenster öffnen.

In RO hat jedes Fenster eine konstante ID. Das Pet-Fenster hat beispielsweise die ID 88, das Storage die 33. Wenn falsche Fenster geöffnet werden, könnte das doch daran liegen, dass eine falsche ID übergeben wird…?
Zum Vergleich habe ich eine neuere Version heran gezogen, wo der Bug bereits behoben ist. Und tatsächlich – der Code offenbart Unterschiede:

Version mit Bug

Version ohne Bug

Ein Blick auf die Switch Table der MakeWindow Funktion bestätigt, dass in beiden Versionen der Bereich von 146 bis 152 verwendet wird.
Ganz klar! Passen wir die fehlerhafte Version doch einfach an, dass sie auch 146 addiert. Und siehe da: kein Crash mehr! :D

Aber wirklich funktioniert tut es noch immer nicht. Es passiert einfach gar nichts. Hmpf.

Schauen wir uns also mal an, was beim Öffnen der Fenster passiert:
(eax ist in beiden Snippets die ID des Fensters)

2010-03-24:

loc_505202: ; jumptable 00504456 cases 146-152
mov ebx, [esi+eax*4+12]
cmp ebx, edi
jnz loc_50934E

2010-07-21:

loc_50B2FC: ; jumptable 0050A556 cases 146-152
add eax, 0FFFFFF6Eh
mov [ebp+var_18], eax
lea eax, [esi+eax*4+270h]
mov [ebp+var_14], eax
mov ebx, [eax]
cmp ebx, edi
jnz loc_50F5E7

2010-07-21 (vereinfacht):

loc_50B2FC: ; jumptable 0050A556 cases 146-152
add eax, 0FFFFFF6Eh
mov ebx, [esi+eax*4+624]
cmp ebx, edi
jnz loc_50F5E7

Sieht ähnlich aus, aber nicht identisch. Nehmen wir den zweiten Codeblock mal auseinander:

add eax, 0FFFFFF6Eh

Auf die ID des Fensters wird ein Wert addiert. Ein verdammt großer Wert.
Die Intel Architektur unterscheidet beim Addieren nicht zwischen positiven und negativen Zahlen – man muss einfach eine Zahl addieren, die zu groß ist. Durch den entstehenden Überlauf verkleinert sich dann der Wert (siehe auch Zweierkomplement).
Formen wir mal ein wenig um:

add eax, -146

Könnte man da nicht…?

ebx = esi + (eax - 146) * 4 + 624
ebx = esi + eax * 4 - 146 * 4 + 624
ebx = esi + eax * 4 + 40

Schonmal interessant. Der Code ist fast identisch – der fehlerhafte Code addiert aber 28 “zu viel”. Wir haben aber eben die Fenster ID (mit der wir hier noch immer rechnen!) um 7 verkleinert:

ebx = esi + eax * 4 + 40
ebx = esi + (eax + 7) * 4 + 12

Das würde heißen: Es wird überall die erhöhte Fenster ID verwendet. Lediglich die Switch Table der MakeWindow Funktion erwartet einen kleineren Wert. Wie soll das zustande kommen?

Gravity verwendet für die Fenster IDs Enums:

enum WINDOWID {
WID_BASICINFOWND = 0,
WID_CHATWND,
WID_SELECTSERVERWND,
WID_LOGINWND,
WID_MAKECHARWND,
WID_SELECTCHARWND,
WID_WAITWND,
WID_LOADINGWND,
WID_ITEMWND,
WID_TOOLTIPWND,
...
WID_LAST
}

Meine Vermutung: An einer Stelle wurde für die Storage-Fenster statt des Enums der entsprechende Zahlwert verwendet. Solang sich innerhalb des Enums nichts ändert, funktioniert das auch. Aber sobald im Enum ein Wert hinzugefügt oder entfernt wird verschieben sich alle Werte innerhalb des Enums. Was lehrt uns das?
Ein Enum sollte ein Enum bleiben! Zahlwerte mit Enums zu verwenden führt früher oder später zu Fehlern.

Mein Lösungsweg: Vor dem Aufruf von MakeWindow wird die ID um 7 verringert. Die Switch Table wird dann so angepasst, dass erst ein kleiner Codeblock aufgerufen wird, der die ID wieder um 7 erhöht. Man hätte auch die Switch Table verschieben können, aber damit würde man unter Umständen andere Fenster überschreiben.

Ich will den entstandenen Fix natürlich niemandem vorenthalten: Click me

The case of GrfBuilder

July 6th, 2010 by Sirius_White

Everade trug mir gerade ein recht skuriles Problem vor: Mit Harmony verschlüsselte Dateien ließen sich nicht mit GrfBuilder packen. Die Dateien würden einfach übersprungen. Die originalen Dateien hingegen würden wunderbar funktionieren.
Erste Reaktion: Wie soll das gehen? GrfBuilder sollte die Dateien schließlich neutral behandeln und unabhängig von Inhalt packen. Allerdings ließ sich das Problem mit den besagten Dateien tatsächlich nachbilden. Seltsam..

Wie man sehen kann fehlen die größeren Dateien. Könnte es sein, dass er die Dateien aus irgendeinem Grund wirklich gar nicht erst liest? Kein Problem – einfach mal einen auf Mark Russinovich machen und Process Monitor anschmeißen:

Das sieht schonmal interessant aus! Man kann erkennen, dass alle Dateien geöffnet (CreateFile) und auch vollständig gelesen (ReadFile) werden. Einen wichtigen Unterschied gibt es jedoch: Nachdem die beiden funktionierenden Dateien gelesen sind wird in die test.grf geschrieben (markierte WriteFile Einträge). Offenbar werden Änderungen sofort in die GRF geschrieben. Bei der GND Datei fehlt aber dieser Schritt. Der Fehler liegt also irgendwo zwischen dem Einlesen der Daten und dem Schreiben in die GRF.
GrfBuilder ist ein speziell für RO entwickeltes Tool. Könnte es also sein, dass die Dateiformate überprüft werden, bevor eine Datei in die GRF gepackt wird? Durch die Verschlüsselung würden hier zwangsläufig Fehler entstehen. Theoretisch sollte das nicht so sein, aber wer weiß. Also folgende 2 Testläufe:

  • Die Dateien umbenennen (.bin, .txt), den Inhalt beibehalten
  • Die Formatheader einer gültigen GAT/GND Datei an den Anfang der verschlüsselten Dateien kopieren, Inhalt und Name beibehalten

Ergebnis: Der erste Testlauf brachte keine Ergebnisse, die Dateien wurden weiterhin ignoriert. Bei der zweiten Methode wurde nun jedoch eine Datei akzeptiert – die GND mit GAT Header. Interessant hierbei ist, dass ein Ändern des Inhaltes zum Erfolg geführt hat, obwohl der Dateityp mit dem verwendeten Inhalt eigentlich nichts zu tun hat. … Könnte es sich um Kompressionsproblem handeln?
Mit der höchsten Komprimierungsstufe wurde ein andere Datei (GAT mit GND Header) erfolgreich hinzugefügt. Und an dem Punkt kam mir der entscheidende Verdacht: Dateien innerhalb der GRF sind komprimiert. Kompression funktioniert umso besser, je mehr wiederkehrende Strukturen vorhanden sind. Durch Verschlüsselung werden diese Strukturen jedoch zerstört, was eine Kompression schwierig bis unmöglich macht. Nun könnte es sein, dass der zur Kompression verfügbare Speicher zu klein ist, weil eine zu hohe Kompressionsrate erwartet wird, die Dateigröße sich durch die zerstörte Struktur jedoch nicht verringert, sondern vergrößert. Ein Blick in den Source Code der verwendeten GRF Library bestätigte diese Vermutung:

1
2
3
4
// 1. Compress file, to have its size
ptr_comp = malloc(size+100);
if (ptr_comp == NULL) return NULL; /* out of memory? */
comp_size = zlib_buffer_deflate(ptr_comp, size + 100, ptr, size, handler->compression_level);

Der Entwickler hat wohl angenommen, dass unter keinen Umständen die Datei sich durch die Kompression um mehr als 100 Bytes vergrößert. Das könnte hier jedoch der Fall sein. Der entsprechende ASM Block war auch schnell gefunden:

Wenn man hier eine größere Zahl addiert sollte man den Bug zumindest umgehen können. Da man mit dem verwendeten Befehl maximal 127 addieren kann, habe ich den Codefluss einfach auf dir davor liegende Funktion (Datei umbenennen) umgeleitet, dort addiert und einen Rücksprung platziert.
Eine bessere Lösung wäre es übrigens, nicht einfach wild drauf los zu schätzen, sondern compressBound zu verwenden:

    The compressBound() shall return a value representing the upper bound of an array to allocate to hold the compressed data in a single call to compress() or compress2(). This function may return a conservative value that may be larger than sourceLen.

Im Fall von Everade genügte aber vorerst mein “Hackfix”. Mit der modifizierten grf.dll kann man nun zwar keine Dateien mehr umbenennen, aber dafür alle Dateien problemlos komprimieren. :)

The case of RCX

June 21st, 2010 by Sirius_White

Harmony ist dafür da, Fremdsoftware zu blockieren. Das tut es auch recht gut. Problematisch wird es nur, wenn man ein Programm explizit unterstützen muss… Die Rede ist von RCX – einer japanische Erweiterung des RO Clients, die vielen “alten Hasen” unter RoCha bekannt sein dürfte. Ansonsten verschafft dieses Video einen recht guten Überblick über die Features:

Ein Kunde sprach mich vor kurzem darauf an, dass RCX nicht mit Harmony kompatibel sei. Nicht verwunderlich, schließlich lädt RCX nicht nur eine fremde DLL, sondern fängt auch Winsock Funktionen ab, um anhand der Netzwerkpakete beispielsweise Skilleffekte anzuzeigen. So begann also mein Odysee hin zu einem RCX Fix…

Nach kurzer Codeanalyse stellte sich heraus, warum andere Bot-Protections keine derartigen Probleme haben: Die Netzwerkfunktionen arbeiten nicht direkt auf WinAPI Ebene – RCX umgeht sie daher dezent. Da Harmony auf mehreren Layern arbeitet und alle davon unter RCX liegen gestaltet sich die Sache etwas schwieriger.
Mein finaler Plan:

  • Über Whitelisting wird der RCX DLL der Zugriff auf Harmony gestattet
  • Ein- und ausgehende Netzwerkpakete werden gesammelt und über emulierte Winsock Aufrufe an RCX übergeben
  • ????
  • Profit!

Punkt 1 war schnell erledigt. Die Emulation der Winsock Aufrufe wurde etwas ekelhafter: RCX fängt alle Winsock Aufrufe ab und muss daher selbstständig die originalen Funktionen aufrufen. Bei eingehenden Paketen würde RCX also selbstständig “nachfragen”, ob Pakete vorhanden sind, feststellen, dass dem nicht so ist und einfach mal nichts tun. Ich durfte daher die originalen Winsock Funktionsaufrufe ebenfalls abfangen und RCX mit meinen Daten füttern. Dazu kommt, dass einige Harmony Layer den RO Client derart modifizieren, dass eine Rekonstruktion der originalen Pakete nur mit erheblichem Aufwand möglich ist. Yay.

Im Endeffekt konnte ich den Code auf ~300 Zeilen (und 8 Stunden Arbeit…) kürzen, trotzdem denke ich lieber nicht so oft daran, was bei aktiviertem RCX Fix mit Netzwerkpaketen angestellt wird:

Omnipost!

May 30th, 2010 by Sirius_White

Wie betitelt man einen Post, in dem es um alles mögliche geht? Keine Ahnung. Ich nenn ihn jetzt einfach Omnipost.

Was gibts Neues?

Green Mile
Einem Hinweis von Shinryo folgend habe ich mir vor einigen Tagen Green Mile angeschaut. Es geht um einen Gefängniswärter in den 1930er Jahren, der für den Todestrakt der Anstalt, die “Green Mile”, verantwortlich ist. Nachdem er im Laufe der Jahre bereits viele Exekutionen vollstreckt hat, beginnt sich mit der Einlieferung des mysteriösen John Coffey jedoch einiges zu ändern. Der Neue besitzt die wundersame Gabe, Menschen von Ihren Leiden befreien zu können.
Es gibt wirklich wenige Filme, die mich emotional erreichen. Meine Haupterkenntnis nach Titanic war, dass ich irgendwann eine Kreuzfahrt machen möchte. Green Mile hingegen hat es geschafft, mich selbst bei der “Wunderheilungsgeschichte” eines “Gotteswunders” mitfühlen zu lassen. Und genau dafür wird mir dieser Film wohl noch auf Jahre positiv in Erinnerung bleiben. Mein Dank an Shinryo und der Appell an all die anderen, sich diesen Film unbedingt anzusehen!

Hardware 1 : 0 Me
Ich war vor 2 Wochen in Hamburg. LAN-Party bei T-Bash, mit einigen anderen Hamburgern und Sirius_Black. Wir haben zwar nichtmal die Hälfte der geplanten Spiele geschafft, aber die meisten waren dennoch sehr lustig. Begleitet wurde die LAN natürlich – wer hätte es anders erwartet – von diversen technischen Problemen. Eine Maus ist gestorben, kein Spiel hat auf Anhieb bei allen funktioniert und ich hatte das Vergnügen mit Bluescreens. LAN-Party halt.
Aus Faulheit habe ich meinen Rechner per Post zurück geschickt und zurück in Eisenach die Systemplatte in meinen alten Rechner eingebaut. Bluescreens. Was zum..?
Logische Schlussfolgerung: Platte kaputt. Da ich eh vor hatte, die mittlerweile 3 Jahre alte Platte in naher Zukunft auszutauschen, habe ich mir daraufhin 2x 250GB 2,5″ Festplatten und ein neues Gehäuse gekauft. Es ist echt faszinierend, wie viel Speicher man in der Größe (und dem Gewicht!) einer Zigarettenschachtel unterbringen kann.
Als das Mindfactory Paket angekommen war also alles in den neuen Rebel 9 (siehe Bild) eingebaut und eingeschaltet. Lüfter drehen am Rad (na, krieg ich ein Bienchen für dieses Wortspiel?) und ansonsten … passiert nichts. Nach einigen Tests die Erkenntis: Mainboard schrott. Super! Nach kurzem Suchen habe ich sogar noch die Rechnung gefunden – Juli 2009 gekauft. Allerdings nicht bei Mindfactory, sondern bei Compuland. Über Google ließen sich schnell negative Berichte bzgl. der Gewährleistungshandhabung finden. Naja, was solls. Einfach mal probieren. Und, wer hätte es anders erwartet:

Hiermit bestätigen wir Ihnen den Erhalt der Ware, leider konnten wir nicht feststellen, das es sich um ein Gewährleistungsfall handelt.
Wir haben die Ware daher ohne Anerkennung einer Rechtspflicht zur Prüfung der Garantieansprüche zum Lieferanten / Hersteller aus Kulanz weitergeleitet.

Mal sehen. Ich glaube, das gibt noch Stress.

Fun Fact: Ich habe vor einigen Tagen zum Testen meiner Backup Platte einen komplette Scan aller Sektoren durchgefüht. Da die Platten für die Dauer der Überprüfung nicht genutzt werden können logischerweise über Nacht. Und ich muss sagen – mein Biorhythmus ist mittlerweile ziemlich effizient. Nicht nur wache ich seit einer Woche grundsätzlich vormittags auf, an dem Tag bin ich auch noch exakt eine Minute vor Abschluss der Überprüfung aufgewacht. Praktisch.

Rebel 9. Was ein Tower.

Season Finale!
Früher habe ich Serienjunkies immer ein wenig spöttisch betrachtet. Wie kann man nur so viel Freude an irgendeiner doofen US-Serie mit eingespielten Lachern finden? Mittlerweile verfolge ich selber aktiv How I Met Your Mother und The Big Bang Theory. Beide hatten diese Woche Finale. Zumindest für diese Staffel. How I Met Your Mother hat mich nicht vom Stuhl gehauen. Bei Big Bang Theory habe ich wie eigentlich jede Woche herzlich gelacht. Aber mir ist zumindest klar geworden, dass man Serien nicht vergleichen kann. Big Bang Theory setzt auf Comedy. Situationslacher. Hingegen hat How I Met Your Mother diese Staffel versucht, den feinen Grad zwischen Unterhaltung und tiefgreifenderen Inhalten zu finden. Nicht sonderlich erfolgreich, aber die Schreiber haben für sich hoffentlich Erkenntnisse gewonnen, die in der sechsten Staffel umsetzen werden. Aber wie dem auch sei – jeder hat auf dem Gebiet seine eigene Meinung.
Allgemein habe ich in letzter Zeit Gefallen an Serien gefunden: Mit The IT Crowd eine köstliche und erschreckend zutreffende Parodie auf die IT Abteilungen dieser Welt und mit Achtung! Streng Geheim! eine Serie aus den frühen 90ern. Ich habe sie damals immer nur zufällig beim “Durchzappen” gefunden und fand sie unglaublich toll. Jetzt habe ich geballte 17 Stunden davon, verteilt auf 12 85-minütige Folgen. Ein Muss für jeden Fan cooler 90er Kids.

The Big Bang Theory

Harmony
Der obligatorische Harmony Part. :) Ich habe in den letzten Tagen am Lizenzsystem einiges umgestellt und ein paar nervige Bugs entfernt. Sehr hilfreich war hier ein LuminaRO Spieler, der mir über mehrere Stunden Debugging per TeamViewer ermöglicht hat. Anderenfalls hätte das Fixen des Bugs sicherlich eine ganze Weile länger gedauert. Insgesamt steht ein neuer Debugging Ansatz aber noch immer recht weit oben auf der Roadmap. Ein Projekt wie Harmony zu debuggen gestaltet sich sonst als absoluter Albtraum.
Robin aka Zungarius hat sich weiterhin bereit erklärt ein kleines Design für meine Infopage vorzubereiten. Die innovative Domain harmonize.it ist ja bereits registriert… :)

Grand Prix d’Eurovision de la Chanson
Eurovision Song Contest
Deutschland hat gewonnen!!!11 Ich bin so unglaublich glücklich!!!1111einseinself
No, srsly. Wie sonst auch habe ich mir gestern Abend die Punktvergabe des Eurovision Song Contest angesehen. Ich gönne es Lena. Sie wirkte einfach … natürlicher als die anderen Teilnehmer. Und mit Mezzo Mix kann man eh nichts falsch machen.
Ich weiß nicht mehr genau wann und vom der Kommentar kam, aber “sie hat da einfach mal Party mit der Masse gemacht” trifft es denke ich. Meiner Meinung nach auf jeden Fall ein verdienter Sieg. :)

Mh. Das ist jetzt doch länger als erwartet geworden…

Geschafft! – Rückblick und Ausblick auf die Harmony Entwicklung

May 22nd, 2010 by Sirius_White

Harmony 3.1 ist fertig!

“Ich werde im Laufe des heutigen Tages das 3.1 Release Package fertig machen”
Sirius_White, 07.05.2010

Zugegeben, der “heutige Tag” ist es nicht mehr ganz geworden. Aber es wurde immerhin kein Duke Nukem Forever! :)

Vor 2 Tagen sind die vermeintlich letzten Zeilen für 3.1 fertig geworden und Zephyrus hat sein lang ersehntes Update erhalten. 2 Stunden später war dann auch ein ekelhafter Race-Condition-Bug behoben und nach den tatsächlich letzten Zeilen der 3.1 Branch als abgeschlossen markiert. Ursprünglich war der Release für Ende März angesetzt, aber durch die “Verspätung” sind immerhin zahlreiche neue Features eingeflossen, die eigentlich erst für 3.2 geplant waren. Ich kann mittlerweile denke ich mit Fug und Recht behaupten, dass in Punkto Sicherheit die aktuelle Harmony Version allen mir bekannten Anti-Bot Systemen ebenbürtig bis überlegen ist. Aber das kann ja jeder sagen, also bitte reverst Harmony – ich lege Wert auf Feedback! ;)

Für die kommenden Versionen ist bereits einiges geplant. Die oft gewünschte GRF Protection wird mit 3.2 eingebaut werden. Die relevanten Funktionen sind bereits seit Monaten vorhanden, ich muss das Interface dafür nur etwas benutzerfreundlicher gestalten. Ich setze hierbei auf verschlüsselte Dateien innerhalb der GRF, um eine größtmögliche Kompatibilität mit vorhandenen Patchern zu gewährleisten. Aber mehr dazu wenn es soweit ist. :)
Auf lange Sicht steht vor allem ein Punkt im Vordergrund: Das Öffnen der Harmony Plattform für außenstehende Entwickler. Das bezieht sich einerseits natürlich auf den Window Manager (RO Interface mit Lua erweitern), aber auf das komplette Harmony Framework ansich. Durch den modularen Aufbau sollte es möglich sein, ausgewählten Entwicklern eine Harmony SDK zur Verfügung zu stellen und somit die Entwicklung neuer Client Erweiterungen zu fördern, ohne dabei die Sicherheit des Systems zu beeinträchtigen.
Aber ich will an dieser Stelle nicht zu viel vorweg nehmen. Kommt Zeit, kommt Harmony 3.2. :)

Mein Ruf nach gelangweilten Grafikern hatte übrigens Erfolg!
Beginnend mit 3.2 wird Harmony endlich einen kleinen Splash Screen haben, auf den ich dank grafischer Omni-Inkompetenz bisher leider verzichten musste. Danke an dieser Stelle an Argon!

Neulich beim Harmony coden…

May 9th, 2010 by Sirius_White

Perfect Harmony!

Na dann kann ja nichts mehr schief gehen!

Harmony – der Name ist Programm!

May 7th, 2010 by LightFighter

… oder auch nicht.

Ich habe mich vor ein paar Tagen mal wieder dazu bewegt, mich mit Harmony zu beschäftigen. Um genau zu sein, habe ich am Window Manager gearbeitet. Das, was ich während dieser Zeit allerdings empfunden habe, war alles andere als “Harmonie”. Ich würde die Zeit eher als anstrengend, nervenaufreibend oder “OMG Warum funktioniert das nicht?!” bezeichnen..

Um diesem Artikel mal die Pointe vorwegzunehmen: ich habe es dennoch geschafft, ein bisschen was auf die Reihe zu kriegen. Daniel hat schließlich einige Vorarbeit geleistet und ich konnte am Anfang ohne viel Zeit- und Arbeitsaufwand ein total unschuldig wirkendes und leeres Custom Window bewundern: [Oder auch nicht - wegen kleinen PC/Mac Migrationsproblemen, ist der Screen leider abhanden gekommen. Ich werd ihn schnellstmöglich reproduzieren, sorry.]

Nachdem die erste Euphorie verflogen war, ging dann aber auch schon der Horror los. Ich war so naiv zu denken, dass mein größtes Problem das Durcharbeiten und Verstehen des bestehenden Harmony Codes sein würde. Doch als dies mehr oder weniger hinter mir lag, schien dennoch nichts zu funktionieren. Egal, was ich versuchte, früher oder später crashte mir der Client gnadenlos weg – ich hatte übrigens versucht, einen stinknormalen ImageButton auf das Formular zu klatschen. Und so verging jedenfalls der erste Tag ohne wirkliche Ergebnisse, juhu.

Ich habe mich dann letztendlich dazu entschieden, den BitmapButton erstmal ruhen zu lassen. Also nahm ich mir das Element vor, welches mir am simpelsten erschien: UIStaticText. Gesagt getan, und nach einem weiteren Tag Arbeit und viel sinnbildlichem Schweiß, hatte ich doch tatsächlich einen kleinen Text auf meinem Fenster!  Das musste natürlich erstmal mit einem kleinen, bescheidenen Freudentanz gefeiert werden ^^[Und auch bei diesem Screen muss ich euch vorerst enttäuschen..]

Nachdem das erste UI Objekt funktionierte, war es nicht mehr sonderlich schwer, weitere Objekte wie zum Beispiel eine InputBox bzw EditCtrl einzubauen. Ganz so einfach – “harmonisch” – lief der Prozess leider nicht ab, da durch das Party Booking System ein paar neue Eigenschaften dazu gekommen sind. Dabei habe ich allerdings auch ein paar nützliche Features entdeckt: Wie in der Gallery zu sehen ist, kann man diese Dinger richtig schön bunt machen :P Desweiteren kann man Rahmendicke, Passwordchars und vieles mehr einstellen – ziemlich praktisch.

Soweit so gut. Was ich zu Daniels Leiden noch nicht geschafft habe ist, den Offsetgenerator dahingehend zu erweitern, dass auch die ganzen WindowManager Offsets für die verschiedenen Clients generiert werden. Momentan läuft der WindowManager leider nur auf einer einzigen Exe; ich war bisher einfach zu faul, mich mit dem Offsetgenerator auseinander zusetzen, geschweigedenn, mir irgendwelche Suchmuster zu überlegen. Für ein Release ist das Modul sowieso noch viel zu unausgereift.

Wer sich jetzt fragt, warum ich das Modul überhaupt in Angriff genommen habe, wenn ich doch so faul bin, der bekomme jetzt einen Keks – gute Frage. Mein ursprünglicher Beweggrund ist das “Chains Of War” Projekt (WoW Mod für RO) von Everade, bei dem ich mitwirke – soviel Eigenwerbung sei mir gestattet. Everade bat mich nämlich, die Charaktererstellung so zu erweitern, dass der Spieler auch eine Rasse wählen kann. Sein Vorschlag war, die Charerstellung komplett aufs ControlPanel der Webseite zu verlagern, was ich allerdings für sehr unschön finde… Sobald das einigermaßen läuft, werde ich hier wahrscheinlich noch ein paar Screenshots posten.

Bis dahin, haltet die Ohren steif und bleibt so RO-fanatisch wie die ganzen Freaks auf diesem Blog,
Lighto.

… oder auch nicht.

Ich habe mich vor ein paar Tagen mal wieder dazu bewegt, mich mit Harmony zu beschäftigen. Um genau zu sein, habe ich am Window Manager gearbeitet. Das, was ich während dieser Zeit allerdings empfunden habe, war alles andere als “Harmonie”. Ich würde die Zeit eher als anstrengend, nervenaufreibend oder “OMG Warum funktioniert das nicht?!” bezeichnen..

Um diesem Artikel mal die Pointe vorwegzunehmen: ich habe es dennoch geschafft, ein bisschen was auf die Reihe zu kriegen. Daniel hat schließlich einige Vorarbeit geleistet und ich konnte am Anfang ohne viel Zeit- und Arbeitsaufwand ein total unschuldig wirkendes und leeres Custom Window bewundern: [Oder auch nicht - wegen kleinen PC/Mac Migrationsproblemen, ist der Screen leider abhanden gekommen. Ich werd ihn schnellstmöglich reproduzieren, sorry.]

Nachdem die erste Euphorie verflogen war, ging dann aber auch schon der Horror los. Ich war so naiv zu denken, dass mein größtes Problem das Durcharbeiten und Verstehen des bestehenden Harmony Codes sein würde. Doch als dies mehr oder weniger hinter mir lag, schien dennoch nichts zu funktionieren. Egal, was ich versuchte, früher oder später crashte mir der Client gnadenlos weg – ich hatte übrigens versucht, einen stinknormalen ImageButton auf das Formular zu klatschen. Und so verging jedenfalls der erste Tag ohne wirkliche Ergebnisse, juhu.

Ich habe mich dann letztendlich dazu entschieden, den BitmapButton erstmal ruhen zu lassen. Also nahm ich mir das Element vor, welches mir am simpelsten erschien: UIStaticText. Gesagt getan, und nach einem weiteren Tag Arbeit und viel sinnbildlichem Schweiß, hatte ich doch tatsächlich einen kleinen Text auf meinem Fenster!  Das musste natürlich erstmal mit einem kleinen, bescheidenen Freudentanz gefeiert werden ^^[Und auch bei diesem Screen muss ich euch vorerst enttäuschen..]

Nachdem das erste UI Objekt funktionierte, war es nicht mehr sonderlich schwer, weitere Objekte wie zum Beispiel eine InputBox bzw EditCtrl einzubauen. Ganz so einfach – “harmonisch” – lief der Prozess leider nicht ab, da durch das Party Booking System ein paar neue Eigenschaften dazu gekommen sind. Dabei habe ich allerdings auch ein paar nützliche Features entdeckt: Wie in der Gallery zu sehen ist, kann man diese Dinger richtig schön bunt machen :P Desweiteren kann man Rahmendicke, Passwordchars und vieles mehr einstellen – ziemlich praktisch.

Soweit so gut. Was ich zu Daniels Leiden noch nicht geschafft habe ist, den Offsetgenerator dahingehend zu erweitern, dass auch die ganzen WindowManager Offsets für die verschiedenen Clients generiert werden. Momentan läuft der WindowManager leider nur auf einer einzigen Exe; ich war bisher einfach zu faul, mich mit dem Offsetgenerator auseinander zusetzen, geschweigedenn, mir irgendwelche Suchmuster zu überlegen. Für ein Release ist das Modul sowieso noch viel zu unausgereift.

Wer sich jetzt fragt, warum ich das Modul überhaupt in Angriff genommen habe, wenn ich doch so faul bin, der bekomme jetzt einen Keks – gute Frage. Mein ursprünglicher Beweggrund ist das “Chains Of War” Projekt (WoW Mod für RO) von Everade, bei dem ich mitwirke – soviel Eigenwerbung sei mir gestattet. Everade bat mich nämlich, die Charaktererstellung so zu erweitern, dass der Spieler auch eine Rasse wählen kann. Sein Vorschlag war, die Charerstellung komplett aufs ControlPanel der Webseite zu verlagern, was ich allerdings für sehr unschön finde… Sobald das einigermaßen läuft, werde ich hier wahrscheinlich noch ein paar Screenshots posten.

Bis dahin, haltet die Ohren steif und bleibt so RO-fanatisch wie die ganzen Freaks auf diesem Blog,

Lighto.

Warum ich nicht poste!

May 7th, 2010 by Sirius_White

Zugegeben, ich war schreibfaul. Aber abgesehen davon waren die letzten Wochen hauptsächlich durch Abiturprüfungen sowie vorausgehende und anschließende Feiern geprägt. Mitte April hatte ich meine letzte Schulwoche, in der letzten Aprilwoche dann meine drei schriftlichen Prüfungen (Mathe, Englisch, Info) und heute die abschließende, mündliche Prüfung in Geschichte. Und abgesehen von der Tatsache, dass ich um 7.30 Uhr (!) in der Schule sein musste, lief auch alles ganz gut. :)

Also wie gesagt. Ich habe die vergangenen Wochen zum intensiven Lernen genutzt. Zumindest … größtenteils. Für die drei schriftlichen Prüfungen mindestens eine Stunde.

Okay, hier meine tatsächlichen Beschäftigungen:

Assassins Creed 2

Nachdem ich den ersten Teil nur auf der Xbox bei Freunden angespielt hatte, waren meine Erwartungen an den zweiten Teil der Reihe nicht sonderlich hoch. Trotz des neuen Ubisoft DRM Systems musste ich mir das Ganze aber einmal anschauen.
Seit meiner Point&Click-Adventure Phase Ende letzten Jahres (Geheimakte Tunguska bei der Fraunhofer Talent School!) habe ich eigentlich gar nichts mehr gespielt. Von daher ist es umso bemerkenswerter, wie schnell mich der Assassins Creed Sog gefasst hat. Die Story ist zwar noch immer etwas eintönig nach dem Motto “Na, wer ist der nächste Verräter?”, aber die Entwickler haben sich sichtlich Mühe gegeben, die Missionen abwechslungsreich zu gestalten. Über das nächtliche Venedig zu fliegen oder Leonardo da Vinci in einer wilden Kutschenverfolgung zu retten macht schon Spaß! :)

ROorg

Beim ROorg Projekt gab es in letzter Zeit einige Umplanungen, im Laufe des Tages werden wir auch noch das Press Release fertig machen. Da wir nun endgültig auf die Entwicklung eines eigenen Clients umgestiegen sind, wurde die Entwicklungszeit etwas verlängert. Aber mehr dazu in nächster Zeit auf der Projektseite. Es bleibt spannend!

Harmony
Fortschritt. Im Zuge des 3.1 Updates haben mehrere Designänderungen Einzug gehalten. Nebenbei sind einige neue Features dazu gekommen und alte wurden verbessert. Sprich: Ich werde im Laufe des heutigen Tages das 3.1 Release Package fertig machen und dann bekommt Zephyrus endlich seine neue Version.
Timo hat offenbar noch einen Artikel über seine Arbeit am Window Manager im Arbeit, ich werde ihn gleich mal anhauen, den fertig zu machen. Klick mich
Ansonsten wird es zu Harmony in den nächsten Tagen noch einmal eine Informationsseite oder etwas in der Richtung geben. So wirklich wissen ja die meisten noch immer nicht, was Harmony überhaupt ist.
Apropos: Ist irgendein Grafiker da draußen gelangweilt und möchte mir ein kleines Harmony Logo machen? ._.