Browse Source

initial commit

Kolja Strohm 6 years ago
commit
e49ea5716b
13 changed files with 2285 additions and 0 deletions
  1. 63 0
      .gitattributes
  2. 265 0
      .gitignore
  3. 3 0
      build.bat
  4. 28 0
      patcher.sln
  5. 18 0
      patcher/Keys.cpp
  6. 43 0
      patcher/Keys.h
  7. 534 0
      patcher/News.cpp
  8. 65 0
      patcher/News.h
  9. 193 0
      patcher/Patcher.cpp
  10. 42 0
      patcher/Patcher.h
  11. 186 0
      patcher/patcher.vcxproj
  12. 42 0
      patcher/patcher.vcxproj.filters
  13. 803 0
      patcher/start.cpp

+ 63 - 0
.gitattributes

@@ -0,0 +1,63 @@
+###############################################################################
+# Set default behavior to automatically normalize line endings.
+###############################################################################
+* text=auto
+
+###############################################################################
+# Set default behavior for command prompt diff.
+#
+# This is need for earlier builds of msysgit that does not have it on by
+# default for csharp files.
+# Note: This is only used by command line
+###############################################################################
+#*.cs     diff=csharp
+
+###############################################################################
+# Set the merge driver for project and solution files
+#
+# Merging from the command prompt will add diff markers to the files if there
+# are conflicts (Merging from VS is not affected by the settings below, in VS
+# the diff markers are never inserted). Diff markers may cause the following 
+# file extensions to fail to load in VS. An alternative would be to treat
+# these files as binary and thus will always conflict and require user
+# intervention with every merge. To do so, just uncomment the entries below
+###############################################################################
+#*.sln       merge=binary
+#*.csproj    merge=binary
+#*.vbproj    merge=binary
+#*.vcxproj   merge=binary
+#*.vcproj    merge=binary
+#*.dbproj    merge=binary
+#*.fsproj    merge=binary
+#*.lsproj    merge=binary
+#*.wixproj   merge=binary
+#*.modelproj merge=binary
+#*.sqlproj   merge=binary
+#*.wwaproj   merge=binary
+
+###############################################################################
+# behavior for image files
+#
+# image files are treated as binary by default.
+###############################################################################
+#*.jpg   binary
+#*.png   binary
+#*.gif   binary
+
+###############################################################################
+# diff behavior for common document formats
+# 
+# Convert binary document formats to text before diffing them. This feature
+# is only available from the command line. Turn it on by uncommenting the 
+# entries below.
+###############################################################################
+#*.doc   diff=astextplain
+#*.DOC   diff=astextplain
+#*.docx  diff=astextplain
+#*.DOCX  diff=astextplain
+#*.dot   diff=astextplain
+#*.DOT   diff=astextplain
+#*.pdf   diff=astextplain
+#*.PDF   diff=astextplain
+#*.rtf   diff=astextplain
+#*.RTF   diff=astextplain

+ 265 - 0
.gitignore

@@ -0,0 +1,265 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+patcher/data
+framework.dll
+network.dll
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# DNX
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+#*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+# NuGet v3's project.json files produces more ignoreable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+node_modules/
+orleans.codegen.cs
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# JetBrains Rider
+.idea/
+*.sln.iml
+
+# CodeRush
+.cr/
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc

+ 3 - 0
build.bat

@@ -0,0 +1,3 @@
+"D:\Visual Studio 2017\MSBuild\15.0\Bin\MSBuild.exe" "patcher.sln" /p:configuration=release /p:platform=win32
+"D:\Visual Studio 2017\MSBuild\15.0\Bin\MSBuild.exe" "patcher.sln" /p:configuration=release /p:platform=x64
+"D:\Visual Studio 2017\MSBuild\15.0\Bin\MSBuild.exe" "patcher.sln" /p:configuration=debug /p:platform=x64

+ 28 - 0
patcher.sln

@@ -0,0 +1,28 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.22823.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "patcher", "patcher\patcher.vcxproj", "{CBA67731-4D13-459A-BA44-543A7AFC6E04}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{CBA67731-4D13-459A-BA44-543A7AFC6E04}.Debug|Win32.ActiveCfg = Debug|Win32
+		{CBA67731-4D13-459A-BA44-543A7AFC6E04}.Debug|Win32.Build.0 = Debug|Win32
+		{CBA67731-4D13-459A-BA44-543A7AFC6E04}.Debug|x64.ActiveCfg = Debug|x64
+		{CBA67731-4D13-459A-BA44-543A7AFC6E04}.Debug|x64.Build.0 = Debug|x64
+		{CBA67731-4D13-459A-BA44-543A7AFC6E04}.Release|Win32.ActiveCfg = Release|Win32
+		{CBA67731-4D13-459A-BA44-543A7AFC6E04}.Release|Win32.Build.0 = Release|Win32
+		{CBA67731-4D13-459A-BA44-543A7AFC6E04}.Release|x64.ActiveCfg = Release|x64
+		{CBA67731-4D13-459A-BA44-543A7AFC6E04}.Release|x64.Build.0 = Release|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

+ 18 - 0
patcher/Keys.cpp

@@ -0,0 +1,18 @@
+#include "Keys.h"
+#include <Datei.h>
+
+using namespace Framework;
+
+// Konstruktor
+Keys::Keys()
+{}
+
+// Gibt den Schlüssel eines Servers zurück
+//  key: Ein Zeiger auf ein array von bytes. Wird als ausgabe verwendet. Enthält nach aufruf den gewünschten Key
+//  length: Enthält nach aufruf die Länge des Schlüssels
+//  sTyp: Der Servertyp, zu dem der Schlüssel ermittelt werden soll
+//  kTyp: Die art des Schlüssels der ermittelt werden soll
+void Keys::getServerKey( char **key, int &length, Server sTyp, Key kTyp )
+{
+    // Diese Methode ist nicht open source
+}

+ 43 - 0
patcher/Keys.h

@@ -0,0 +1,43 @@
+#pragma once
+
+class Keys
+{
+    // Konstruktor
+    Keys();
+public:
+    enum Server;
+    enum Key;
+
+    // Gibt den Schlüssel eines Servers zurück
+    //  key: Ein Zeiger auf ein array von bytes. Wird als ausgabe verwendet. Enthält nach aufruf den gewünschten Key
+    //  length: Enthält nach aufruf die Länge des Schlüssels
+    //  sTyp: Der Servertyp, zu dem der Schlüssel ermittelt werden soll
+    //  kTyp: Die art des Schlüssels der ermittelt werden soll
+    static void getServerKey( char **key, int &length, Server sTyp, Key kTyp );
+
+    // Servertypen
+    enum Server
+    {
+        MAIN = 0,
+        ANMELDUNG = 1,
+        CHAT = 2,
+        EDITOR = 3,
+        HISTORIE = 4,
+        INFORMATION = 5,
+        KARTEN = 6,
+        LOGIN = 7,
+        NEWS = 8,
+        REGISTER = 9,
+        SHOP = 10,
+        SPIEL = 11,
+        PATCH = 12,
+        ERHALTUNG = 13
+    };
+
+    // Keytypen
+    enum Key
+    {
+        EMPFANGEN = 0,
+        SENDEN = 0
+    };
+};

+ 534 - 0
patcher/News.cpp

@@ -0,0 +1,534 @@
+#include "News.h"
+#include <DateiSystem.h>
+#include <Bildschirm.h>
+#include <Punkt.h>
+#include <Textfeld.h>
+#include <Schrift.h>
+#include <Datei.h>
+#include <InitDatei.h>
+#include "Keys.h"
+
+void KSGSRückruf( void *p, RCArray< KSGSVariable > *parameter, KSGSVariable **ret )
+{
+	if( !p )
+		return;
+	( (News*)p )->rückruf( parameter, ret );
+}
+
+// Inhalt der News Klasse aus News.h
+// Konstruktor
+News::News( Bildschirm *zB, Schrift *zS )
+{
+	ref = 1;
+	// Ladeanimation laden
+	Animation2DData *aData = new Animation2DData();
+	LTDBDatei *aDatei = new LTDBDatei();
+	aDatei->setDatei( new Text( "data/bilder/ladeanimation.ltdb" ) );
+	aDatei->leseDaten( 0 );
+	aData->ladeAnimation( aDatei );
+	aData->setFPS( 30 );
+	aData->setWiederhohlend( 1 );
+	aData->setTransparent( 0 );
+	laden = new Animation2D();
+	laden->setPosition( zB->getBackBufferSize() / 2 - Punkt( 25, 25 ) );
+	laden->setSize( 50, 50 );
+	laden->setAPS( 450 );
+	laden->setAnimationDataZ( aData );
+	laden->setRahmen( 1 );
+	laden->setRahmenBreite( 1 );
+	laden->setRahmenFarbe( 0xFFFFFFFF );
+	laden->setSichtbar( 0 );
+	zB->setOnTopZeichnung( laden );
+	// Fehler Textfeld Initialisieren
+	fehler = new TextFeld();
+	fehler->setStyle( TextFeld::Style::Text & ~TextFeld::Style::Sichtbar );
+	fehler->setPosition( 10, 60 );
+	fehler->setSize( 480, 312 );
+	fehler->setSchriftFarbe( 0xFFFFFFFF );
+	fehler->setSchriftZ( zS->getThis() );
+	fehler->setText( "Fehler beim Laden der Seite!\n" );
+	zB->addMember( fehler );
+	// Startwerte Initialisieren
+	screen = zB->getThis();
+	schrift = zS->getThis();
+	// DLL Datei Laden
+	ksgsDll = LoadLibrary( "data/bin/KSGScript.dll" );
+	if( !ksgsDll )
+	{ // Error
+		fehler->addZeile( "Die DLL Datei 'data/bin/KSGScript.dll' wurde nicht gefunden." );
+		fehler->addStyle( TextFeld::Style::Sichtbar );
+		laden->setSichtbar( 0 );
+		screen->setOnTop( 0 );
+		run = 0;
+		return;
+	}
+	KSGSGetZeichnung getKSGSZeichnung = (KSGSGetZeichnung)GetProcAddress( ksgsDll, KSGS_START_FUNKTION );
+	if( !getKSGSZeichnung )
+	{ // Error
+		fehler->addZeile( "Die Funktion '" KSGS_START_FUNKTION "' wurde in der\nDLL Datei 'data/bil/KSGScript.dll' nicht gefunden." );
+		fehler->addStyle( TextFeld::Style::Sichtbar );
+		laden->setSichtbar( 0 );
+		screen->setOnTop( 0 );
+		run = 0;
+		return;
+	}
+	frame = getKSGSZeichnung();
+	if( !frame )
+	{ // Error
+		fehler->addZeile( "Unbekannter Fehler." );
+		fehler->addStyle( TextFeld::Style::Sichtbar );
+		laden->setSichtbar( 0 );
+		screen->setOnTop( 0 );
+		run = 0;
+		return;
+	}
+	frame->setSchriftZ( schrift->getThis() );
+	frame->setBildschirmZ( screen->getThis() );
+	frame->setPosition( 10, 60 );
+	frame->setSize( 480, 312 );
+	frame->setRückrufParam( this );
+	frame->setRückrufFunktion( KSGSRückruf );
+	screen->addMember( frame );
+	scriptName = new Text( "Patcher/Start" );
+	// Lade Thread starten
+	start();
+}
+
+// Destruktor
+News::~News()
+{
+	warteAufThread( INFINITE );
+    if( frame )
+    {
+        frame->zurücksetzen();
+        frame->release();
+    }
+	if( ksgsDll )
+		FreeLibrary( ksgsDll );
+	if( scriptName )
+		scriptName->release();
+	laden->release();
+	screen->release();
+	fehler->release();
+	schrift->release();
+}
+
+// nicht constant
+void News::rückruf( RCArray< KSGSVariable > *parameter, KSGSVariable **ret )
+{
+	if( isRunning() )
+		return;
+	KSGSVariable *bef = parameter->z( 0 );
+	if( !bef )
+		return;
+	Text *sn = bef->getText();
+	if( !sn || !sn->getLength() )
+	{
+		if( sn )
+			sn->release();
+		return;
+	}
+	scriptName->setText( sn->getText() );
+	sn->release();
+	start();
+}
+
+void News::thread()
+{
+	screen->setOnTop( 1 );
+	laden->setSichtbar( 1 );
+	frame->zurücksetzen();
+	// KSGScript Seite Herunterladen
+	NewsKlient *klient = new NewsKlient();
+	if( !klient->verbinde() )
+	{
+		klient->release();
+		fehler->addZeile( "Fehler beim verbinden mit dem News-Server." );
+		fehler->addStyle( TextFeld::Style::Sichtbar );
+		laden->setSichtbar( 0 );
+		screen->setOnTop( 0 );
+		run = 0;
+		return;
+	}
+	if( !klient->downloadSeite( scriptName->getText() ) )
+	{
+		klient->trenne( 1 );
+		klient->release();
+		fehler->addZeile( "Die Seite konnte nicht herruntergeladen werden." );
+		fehler->addStyle( TextFeld::Style::Sichtbar );
+		laden->setSichtbar( 0 );
+		screen->setOnTop( 0 );
+		run = 0;
+		return;
+	}
+	klient->trenne( 1 );
+	klient->release();
+	// KSGScript Laden
+	Text *pfad = new Text( "data/tmp/news/" );
+	pfad->append( scriptName->getText() );
+	pfad->append( "/seite.ksgs" );
+	frame->setScriptDatei( pfad );
+	if( !frame->neuLaden() )
+	{ // error
+		fehler->addZeile( "Es befindet sich ein Scriptfehler auf dieser Seite." );
+		fehler->addStyle( TextFeld::Style::Sichtbar );
+		laden->setSichtbar( 0 );
+		screen->setOnTop( 0 );
+		run = 0;
+		return;
+	}
+	laden->setSichtbar( 0 );
+	screen->setOnTop( 0 );
+	run = 0;
+}
+
+// Reference Counting
+News *News::getThis()
+{
+	ref++;
+	return this;
+}
+
+News *News::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der NewsKlient Klasse aus News.h
+// Konstruktor
+NewsKlient::NewsKlient()
+{
+	// lade Client id
+	id = 0;
+	Datei *dat = new Datei();
+	dat->setDatei( new Text( "data/tmp/k.id" ) );
+	dat->open( Datei::Style::lesen );
+	dat->lese( (char*)&id, 4 );
+	dat->close();
+	// lade Schlüssel
+	dat->setDatei( new Text( "data/tmp/schlüssel.netw" ) );
+	dat->open( Datei::Style::lesen );
+	schlüsselLän = 0;
+	dat->lese( &schlüsselLän, 1 );
+	schlüssel = new char[ schlüsselLän ];
+	dat->lese( schlüssel, schlüsselLän );
+	dat->close();
+	dat->release();
+	// Initialisierung
+	verbunden = 0;
+	klient = 0;
+	InitializeCriticalSection( &cs );
+	ref = 1;
+}
+
+// Destruktor
+NewsKlient::~NewsKlient()
+{
+	if( verbunden )
+		trenne( 1 );
+	delete[] schlüssel;
+	if( klient )
+		klient->release();
+	DeleteCriticalSection( &cs );
+}
+
+// nicht constant
+void NewsKlient::lock()
+{
+	EnterCriticalSection( &cs );
+}
+
+void NewsKlient::unlock()
+{
+	LeaveCriticalSection( &cs );
+}
+
+bool NewsKlient::verbinde()
+{
+	lock();
+	if( verbunden )
+	{
+		unlock();
+		return 1;
+	}
+	if( !klient )
+	{
+		InitDatei *dat = new InitDatei( "data/optionen.ini" );
+		dat->laden();
+		Text *ipT = dat->getWert( "ServerIP" );
+		unsigned short msPort = (unsigned short)TextZuInt( dat->zWert( "ServerPort" )->getText(), 10 );
+		dat->release();
+		int län = ipT->getLength();
+		char *msIp = new char[ län + 1 ];
+		msIp[ län ] = 0;
+		for( int i = 0; i < län; i++ )
+			msIp[ i ] = ipT->getText()[ i ];
+		ipT->release();
+		klient = new Klient();
+        int l;
+        char *key;
+        Keys::getServerKey( &key, l, Keys::MAIN, Keys::SENDEN );
+		klient->setSendeKey( key, l );
+        delete[] key;
+        Keys::getServerKey( &key, l, Keys::MAIN, Keys::SENDEN );
+		klient->setEmpfangKey( key, l );
+        delete[] key;
+		if( !klient->verbinde( msPort, msIp ) )
+		{
+			klient = klient->release();
+			delete[]msIp;
+			unlock();
+			return 0;
+		}
+		delete[]msIp;
+		klient->sende( "\0", 1 ); // verschlüsselung aktivieren
+		klient->sendeEncrypted( "\1", 1 );
+		klient->sendeEncrypted( (char*)&id, 4 );
+		char serverReturn = 0;
+		klient->getNachrichtEncrypted( &serverReturn, 1 );
+		if( serverReturn == 3 )
+		{
+			char byte = 0;
+			klient->getNachrichtEncrypted( &byte, 1 );
+			char *fehler = new char[ byte + 1 ];
+			fehler[ byte ] = 0;
+			klient->getNachrichtEncrypted( fehler, byte );
+			delete[] fehler;
+			klient->sendeEncrypted( "\3", 1 );
+			klient->getNachrichtEncrypted( &serverReturn, 1 );
+			klient->trenne();
+			klient = klient->release();
+			unlock();
+			return 0;
+		}
+		klient->setSendeKey( this->schlüssel, schlüsselLän );
+		klient->setEmpfangKey( this->schlüssel, schlüsselLän );
+		klient->sendeEncrypted( "\6\x9", 2 );
+		char byte = 0;
+		klient->getNachrichtEncrypted( &byte, 1 );
+		if( byte == 2 )
+		{
+			unsigned char nsIp[ 4 ];
+			klient->getNachrichtEncrypted( (char *)nsIp, 4 );
+			unsigned short nsPort = 0;
+			klient->getNachrichtEncrypted( (char*)&nsPort, 2 );
+			klient->sendeEncrypted( "\3", 1 );
+			klient->getNachrichtEncrypted( &serverReturn, 1 );
+			klient->trenne();
+			Text *nsIpT = new Text( "" );
+			nsIpT->append( (int)nsIp[ 0 ] );
+			nsIpT->append( "." );
+			nsIpT->append( (int)nsIp[ 1 ] );
+			nsIpT->append( "." );
+			nsIpT->append( (int)nsIp[ 2 ] );
+			nsIpT->append( "." );
+			nsIpT->append( (int)nsIp[ 3 ] );
+            int l;
+            char *key;
+            Keys::getServerKey( &key, l, Keys::NEWS, Keys::SENDEN );
+            klient->setSendeKey( key, l );
+            delete[] key;
+            Keys::getServerKey( &key, l, Keys::NEWS, Keys::SENDEN );
+            klient->setEmpfangKey( key, l );
+            delete[] key;
+			klient->verbinde( nsPort, nsIpT->getText() );
+			nsIpT = nsIpT->release();
+			klient->sendeEncrypted( "\3", 1 );
+			klient->getNachrichtEncrypted( &serverReturn, 1 );
+			klient->trenne();
+		}
+		if( byte == 3 )
+		{
+			klient->getNachrichtEncrypted( &byte, 1 );
+			char *fehler = new char[ byte + 1 ];
+			fehler[ byte ] = 0;
+			klient->getNachrichtEncrypted( fehler, byte );
+			delete[]fehler;
+			klient->sendeEncrypted( "\3", 1 );
+			klient->getNachrichtEncrypted( &serverReturn, 1 );
+			klient->trenne();
+			klient = klient->release();
+			unlock();
+			return 0;
+		}
+	}
+    int l;
+    char *key;
+    Keys::getServerKey( &key, l, Keys::NEWS, Keys::SENDEN );
+    klient->setSendeKey( key, l );
+    delete[] key;
+    Keys::getServerKey( &key, l, Keys::NEWS, Keys::SENDEN );
+    klient->setEmpfangKey( key, l );
+    delete[] key;
+	if( klient->verbinde( klient->getServerPort(), klient->getServerIp() ) )
+	{
+		if( klient->sendeEncrypted( "\1", 1 ) )
+		{
+			klient->sendeEncrypted( (char*)&id, 4 );
+			char serverReturn = 0;
+			klient->getNachrichtEncrypted( &serverReturn, 1 );
+			if( serverReturn == 3 )
+			{
+				char byte = 0;
+				klient->getNachrichtEncrypted( &byte, 1 );
+				char *fehler = new char[ byte + 1 ];
+				fehler[ byte ] = 0;
+				klient->getNachrichtEncrypted( fehler, byte );
+				delete[]fehler;
+				klient->sendeEncrypted( "\3", 1 );
+				klient->getNachrichtEncrypted( &serverReturn, 1 );
+				klient->trenne();
+				unlock();
+				return 0;
+			}
+			klient->setSendeKey( this->schlüssel, schlüsselLän );
+			klient->setEmpfangKey( this->schlüssel, schlüsselLän );
+			verbunden = 1;
+			unlock();
+			return 1;
+		}
+		else
+			klient = klient->release();
+	}
+	else
+		klient = klient->release();
+	unlock();
+	return 0;
+}
+
+bool NewsKlient::downloadSeite( char *name )
+{
+	lock();
+	if( !verbunden )
+		verbinde();
+	if( !verbunden )
+	{
+		unlock();
+		return 0;
+	}
+	klient->sendeEncrypted( "\5", 1 );
+	char ret = 0;
+	klient->getNachrichtEncrypted( &ret, 1 );
+	if( ret == 1 )
+	{
+		char län = (char)textLength( name );
+		klient->sendeEncrypted( &län, 1 );
+		klient->sendeEncrypted( name, län );
+		klient->getNachrichtEncrypted( &ret, 1 );
+		if( ret == 1 )
+		{
+			Text *pfad = new Text( "data/tmp/news/" );
+			pfad->append( name );
+			if( DateiExistiert( pfad->getThis() ) )
+				DateiRemove( pfad->getThis() );
+			pfad->append( "/" );
+			int dAnz = 0;
+			klient->getNachrichtEncrypted( (char*)&dAnz, 4 );
+			for( int i = 0; i < dAnz; i++ )
+			{
+				char nLän = 0;
+				klient->getNachrichtEncrypted( &nLän, 1 );
+				char *dName = new char[ nLän + 1 ];
+				dName[ nLän ] = 0;
+				klient->getNachrichtEncrypted( dName, nLän );
+				Text *pf = new Text( pfad->getText() );
+				pf->append( dName );
+				delete[] dName;
+				Datei *d = new Datei();
+				d->setDatei( pf );
+				d->erstellen();
+				d->open( Datei::Style::schreiben );
+				__int64 dGr = 0;
+				klient->getNachrichtEncrypted( (char*)&dGr, 8 );
+				char buffer[ 2048 ];
+				while( dGr > 0 )
+				{
+					int län = dGr > 2048 ? 2048 : (int)dGr;
+					klient->getNachricht( buffer, län );
+					d->schreibe( buffer, län );
+					dGr -= län;
+				}
+				d->close();
+				d->release();
+			}
+			pfad->release();
+		}
+	}
+	if( ret == 3 )
+	{
+		klient->getNachrichtEncrypted( &ret, 1 );
+		if( ret )
+		{
+			char *tmp = new char[ ret ];
+			klient->getNachrichtEncrypted( tmp, ret );
+			delete[] tmp;
+		}
+		unlock();
+		return 0;
+	}
+	unlock();
+	return 1;
+}
+
+bool NewsKlient::trenne( bool abmelden )
+{
+	lock();
+	if( !verbunden )
+	{
+		unlock();
+		return 1;
+	}
+	if( abmelden )
+	{
+		klient->sendeEncrypted( "\4", 1 );
+		char ret = 0;
+		klient->getNachrichtEncrypted( &ret, 1 );
+		if( ret == 3 )
+		{ // error
+			klient->getNachrichtEncrypted( &ret, 1 );
+			char *msg = new char[ ret + 1 ];
+			msg[ ret ] = 0;
+			if( ret )
+				klient->getNachrichtEncrypted( msg, ret );
+			unlock();
+			delete[] msg;
+		}
+	}
+	klient->sendeEncrypted( "\3", 1 );
+	char ret = 0;
+	klient->getNachrichtEncrypted( &ret, 1 );
+	if( ret == 3 )
+	{ // error
+		klient->getNachrichtEncrypted( &ret, 1 );
+		char *msg = new char[ ret + 1 ];
+		msg[ ret ] = 0;
+		if( ret )
+			klient->getNachrichtEncrypted( msg, ret );
+		unlock();
+		delete[] msg;
+	}
+	klient->trenne();
+	klient = klient->release();
+	verbunden = 0;
+	unlock();
+	return 1;
+}
+
+// Reference Counting
+NewsKlient *NewsKlient::getThis()
+{
+	ref++;
+	return this;
+}
+
+NewsKlient *NewsKlient::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 65 - 0
patcher/News.h

@@ -0,0 +1,65 @@
+#ifndef News_H
+#define News_H
+
+#include <KSGScript.h>
+#include <Animation.h>
+#include <Thread.h>
+#include <Klient.h>
+
+using namespace Framework;
+using namespace KSGScript;
+using namespace Network;
+
+class News : private Thread
+{
+private:
+	KSGScriptObj *frame;
+	HMODULE ksgsDll;
+	Text *scriptName;
+	Animation2D *laden;
+	Bildschirm *screen;
+	TextFeld *fehler;
+	Schrift *schrift;
+	int ref;
+
+public:
+	// Konstruktor
+	News( Bildschirm *zB, Schrift *zS );
+	// Destruktor
+	~News();
+	// nicht constant
+	void rückruf( RCArray< KSGSVariable > *parameter, KSGSVariable **ret );
+	void thread();
+	// Reference Counting
+	News *getThis();
+	News *release();
+};
+
+class NewsKlient
+{
+private:
+	int id;
+	Klient *klient;
+	CRITICAL_SECTION cs;
+	char *schlüssel;
+	char schlüsselLän;
+	bool verbunden;
+	int ref;
+
+public:
+	// Konstruktor
+	NewsKlient();
+	// Destruktor
+	~NewsKlient();
+	// nicht constant
+	void lock();
+	void unlock();
+	bool verbinde();
+	bool downloadSeite( char *name );
+	bool trenne( bool abmelden );
+	// Reference Counting
+	NewsKlient *getThis();
+	NewsKlient *release();
+};
+
+#endif

+ 193 - 0
patcher/Patcher.cpp

@@ -0,0 +1,193 @@
+#include "Patcher.h"
+#include <Datei.h>
+#include <Text.h>
+#include <InitDatei.h>
+#include <Text.h>
+#include <GSLDateiV.h>
+
+typedef UpdaterV *( *GetUpdater )( );
+typedef GSL::GSLDateiV *( *GetGSLDatei )( );
+
+// Inhalt der Patcher Klasse aus Patcher.h
+// Konstruktor
+Patcher::Patcher( FBalken *fortschritt, TextFeld *status, Knopf *play, bool *close )
+	: Thread()
+{
+	// Dll Laden
+	updateDll = LoadLibrary( "data/bin/update.dll" );
+	if( !updateDll )
+	{
+		updater = 0;
+		MessageBox( 0, "Die DLL Datei 'data/bin/update.dll' wurde nicht gefunden.", "Fehler", MB_ICONERROR );
+	}
+	else
+	{
+		GetUpdater getUpdater = (GetUpdater)GetProcAddress( updateDll, "getUpdater" );
+		if( !getUpdater )
+		{
+			updater = 0;
+			MessageBox( 0, "Der Einstiegspunkt 'getUpdater' konnte in der DLL Datei 'data/bin/update.dll' nicht gefunden.", "Fehler", MB_ICONERROR );
+		}
+		else
+			updater = getUpdater();
+	}
+	// Initialisierung
+	this->fortschritt = fortschritt;
+	this->status = status;
+	this->play = play;
+	this->close = close;
+	ret = 0;
+	ref = 1;
+}
+
+// Destruktor
+Patcher::~Patcher()
+{
+	if( run )
+	{
+		*close = 1;
+		warteAufPatch( 5000 );
+	}
+	if( run )
+		ende();
+	fortschritt->release();
+	status->release();
+	play->release();
+	if( updater )
+		updater->release();
+	FreeLibrary( updateDll );
+}
+
+// nicht constant
+void Patcher::startPatch()
+{
+	start();
+}
+
+void Patcher::thread()
+{
+	if( !updater )
+	{
+		status->lockZeichnung();
+		status->setText( "Es ist ein schwerer Fehler aufgetreten!" );
+		status->unlockZeichnung();
+		run = 0;
+		return;
+	}
+	status->lockZeichnung();
+	status->setText( "Suche nach Updates . . ." );
+	status->unlockZeichnung();
+	Text dgPfad;
+	int gruppe = updater->getNextDateiGruppe( &dgPfad ); // Nächste Dateigruppe die geupdatet werden muss
+	while( gruppe )
+	{
+		if( gruppe == -1 )
+		{ // error
+			status->lockZeichnung();
+			status->setText( "Es ist ein schwerer Fehler aufgetreten!" );
+			status->unlockZeichnung();
+			MessageBox( 0, updater->getError(), "Fehler", MB_ICONERROR );
+			run = 0;
+			return;
+		}
+		bool clientGruppe = !dgPfad.getLength();
+		if( !clientGruppe )
+		{ // Das Spiel kann bereits gestartet werden
+			play->addStyle( Knopf::Style::Sichtbar );
+			ret = 2;
+		}
+		status->lockZeichnung();
+		status->setText( "Update für '" );
+		if( !clientGruppe )
+			status->zText()->append( dgPfad.getText() );
+		else
+			status->zText()->append( "Client" );
+		status->zText()->append( "'. . ." );
+		status->unlockZeichnung();
+		UpdateParams params;
+		params.abbruch = close;
+		params.dateiGruppe = gruppe;
+		params.zFortschritt = fortschritt;
+		params.zStatus = 0;
+		int res = updater->update( &params );
+		if( res == 3 )
+		{ // es gibt Dateien, die der Patcher (wegen momentaner Benutzung) nicht pätchen konnte
+			status->lockZeichnung();
+			status->setText( "Klicke auf Play, um die verbleibenen Änderungen zu übernehmen." );
+			status->unlockZeichnung();
+			play->addStyle( Knopf::Style::Sichtbar );
+			ret = 1;
+			run = 0;
+			return;
+		}
+		if( res == 2 )
+			break;
+		if( res == 1 )
+			MessageBox( 0, updater->getError(), "Fehler", MB_ICONERROR );
+		status->lockZeichnung();
+		status->setText( "Suche nach Updates . . ." );
+		status->unlockZeichnung();
+		gruppe = updater->getNextDateiGruppe( &dgPfad );
+	}
+	status->lockZeichnung();
+	status->setText( "Alle ausgewählten Dateien sind aktuell." );
+	status->unlockZeichnung();
+	play->addStyle( Knopf::Style::Sichtbar );
+	ret = 2;
+	HMODULE sDll = LoadLibrary( "data/bin/GSL.dll" );
+	if( sDll )
+	{
+		GetGSLDatei getGSLDatei = (GetGSLDatei)GetProcAddress( sDll, "getGSLDatei" );
+		if( getGSLDatei )
+		{
+			GSL::GSLDateiV *sDatei = getGSLDatei();
+			sDatei->setDatei( "data/sounds/popup.gsl" );
+			sDatei->leseDaten();
+			GSL::GSLSoundV *sound = sDatei->getSound( "info.wav" );
+			sDatei->release();
+			sound->setVolume( 0xFFFF, 0xFFFF );
+			sound->playSound();
+			sound->warteAufSound( 3000 );
+			sound->stopSound();
+			sound->release();
+		}
+		FreeLibrary( sDll );
+	}
+	run = 0;
+}
+
+// constant
+bool Patcher::läuftPatch() const
+{
+	return run;
+}
+
+int Patcher::getReturn() const
+{
+	return ret;
+}
+
+void Patcher::warteAufPatch( int zeit )
+{
+	warteAufThread( zeit );
+}
+
+int Patcher::getDownload() const
+{
+	return updater ? updater->getDownload() : 0;
+}
+
+// Reference Counting
+Patcher *Patcher::getThis()
+{
+	ref++;
+	return this;
+}
+
+Patcher *Patcher::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 42 - 0
patcher/Patcher.h

@@ -0,0 +1,42 @@
+#ifndef Patcher_H
+#define Patcher_H
+
+#include <Update.h>
+#include <Thread.h>
+#include <Textfeld.h>
+#include <Knopf.h>
+#include <Thread.h>
+
+using namespace Framework;
+
+class Patcher : private Thread
+{
+private:
+	HMODULE updateDll;
+	UpdaterV *updater;
+	FBalken *fortschritt;
+	TextFeld *status;
+	Knopf *play;
+	bool *close;
+	int ret;
+	int ref;
+
+public:
+	// Konstruktor
+	Patcher( FBalken *fortschritt, TextFeld *status, Knopf *play, bool *close );
+	// Destruktor
+	~Patcher();
+	// nicht constant
+	void startPatch();
+	void thread();
+	// constant
+	bool läuftPatch() const;
+	int getReturn() const;
+	void warteAufPatch( int zeit );
+	int getDownload() const;
+	// Reference Counting
+	Patcher *getThis();
+	Patcher *release();
+};
+
+#endif

+ 186 - 0
patcher/patcher.vcxproj

@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{CBA67731-4D13-459A-BA44-543A7AFC6E04}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>patcher</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v141</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v141</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v141</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v141</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <IncludePath>..\..\..\..\Allgemein\Framework;..\..\..\..\Allgemein\Network\Network;..\..\..\..\Allgemein\ksgScript\ksgScript\Include;..\..\Include;..\..\..\..\Allgemein\GSL\GSL\Include;$(IncludePath)</IncludePath>
+    <LibraryPath>..\..\..\..\Allgemein\Framework\x64\Debug;..\..\..\..\Allgemein\Network\x64\Debug;$(LibraryPath)</LibraryPath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <IncludePath>..\..\..\..\Allgemein\Framework;..\..\..\..\Allgemein\Network\Network;..\..\..\..\Allgemein\ksgScript\ksgScript\Include;..\..\Include;..\..\..\..\Allgemein\GSL\GSL\Include;$(IncludePath)</IncludePath>
+    <LibraryPath>..\..\..\..\Allgemein\Framework\Release;..\..\..\..\Allgemein\Network\Release;..\..\..\..\Allgemein\ksgScript\Release;$(LibraryPath)</LibraryPath>
+    <CustomBuildBeforeTargets>Build</CustomBuildBeforeTargets>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+    <IncludePath>..\..\..\..\Allgemein\Framework;..\..\..\..\Allgemein\Network\Network;..\..\..\..\Allgemein\ksgScript\ksgScript\Include;..\..\Include;..\..\..\..\Allgemein\GSL\GSL\Include;$(IncludePath)</IncludePath>
+    <LibraryPath>..\..\..\..\Allgemein\Framework\x64\Release;..\..\..\..\Allgemein\Network\x64\Release;..\..\..\..\Allgemein\ksgScript\x64\Release;$(LibraryPath)</LibraryPath>
+    <CustomBuildBeforeTargets>Build</CustomBuildBeforeTargets>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>Framework.lib;Network.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+    <CustomBuildStep>
+      <Command>copy "..\x64\Debug\patcher.exe" "..\..\Fertig\Debug\x64\Data\Patch\bin\patcher.exe"</Command>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Outputs>kopieren...;%(Outputs)</Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>Framework.lib;Network.lib;Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+    <CustomBuildStep>
+      <Command>copy "..\Release\patcher.exe" "..\..\Fertig\x32\Data\Patch\bin\patcher.exe"</Command>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Outputs>kopieren...;%(Outputs)</Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>Framework.lib;Network.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+    <CustomBuildStep>
+      <Command>copy "..\x64\Release\patcher.exe" "..\..\Fertig\x64\Data\Patch\bin\patcher.exe"</Command>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Outputs>kopiern...;%(Outputs)</Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="Keys.cpp" />
+    <ClCompile Include="News.cpp" />
+    <ClCompile Include="Patcher.cpp" />
+    <ClCompile Include="start.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="Keys.h" />
+    <ClInclude Include="News.h" />
+    <ClInclude Include="Patcher.h" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>

+ 42 - 0
patcher/patcher.vcxproj.filters

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Quelldateien">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Headerdateien">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="Ressourcendateien">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="start.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Patcher.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="News.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Keys.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="Patcher.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="News.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="Keys.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>

+ 803 - 0
patcher/start.cpp

@@ -0,0 +1,803 @@
+#include <Klient.h>
+#include <main.h>
+#include <Fenster.h>
+#include <Text.h>
+#include <Datei.h>
+#include <Punkt.h>
+#include <Bildschirm.h>
+#include <Prozess.h>
+#include <Knopf.h>
+#include <Bild.h>
+#include <DateiSystem.h>
+#include <MausEreignis.h>
+#include <TastaturEreignis.h>
+#include <Fortschritt.h>
+#include <Schrift.h>
+#include <Liste.h>
+#include <Rahmen.h>
+#include <AlphaFeld.h>
+#include <TextFeld.h>
+#include <Maus.h>
+#include <Zeit.h>
+#include <InitDatei.h>
+#include <Tabelle.h>
+#include <Scroll.h>
+#include <AuswahlBox.h>
+#include <KSGTDatei.h>
+#define Global
+#include <Globals.h>
+#include "Patcher.h"
+#include "News.h"
+
+using namespace Framework;
+using namespace Network;
+
+bool _exitB = 0;
+WFenster *_frame;
+FBalken *_fortschritt;
+TextFeld *_aktion;
+TextFeld *_kbps;
+Knopf *_play;
+Patcher *_patcher;
+Fenster *_optionenF;
+ObjTabelle *_o_rt;
+Knopf *_o_rno;
+Knopf *_o_rnu;
+TextFeld *_o_ülps;
+AuswahlBox *_o_üle;
+
+bool _newWechsel = 1;
+bool _abbruch = 0;
+
+bool _o_rkkME( void *p, void *obj, MausEreignis me );
+
+void _frameSchließen( void *p, void *obj )
+{
+
+}
+
+bool _frameME( void *p, void *obj, MausEreignis me )
+{
+	return 1;
+}
+
+bool _frameTE( void *p, void *obj, TastaturEreignis me )
+{
+	return 1;
+}
+
+bool closeME( void *p, void *obj, MausEreignis me )
+{
+	if( me.id == ME_RLinks )
+	{
+		_abbruch = 1;
+		PostQuitMessage( 0 );
+	}
+	return 1;
+}
+
+bool minimierenME( void *p, void *obj, MausEreignis me )
+{
+	if( me.id == ME_RLinks )
+	{
+		_frame->setAnzeigeModus( 2 );
+	}
+	return 1;
+}
+
+bool _playME( void *p, void *obj, MausEreignis me )
+{
+	if( me.id == ME_Betritt )
+		MausZeiger.ladeMaus( MausId::hand );
+	if( me.id == ME_Leaves )
+		MausZeiger.ladeMaus( MausId::normal );
+	MausZeiger.update();
+	if( me.id == ME_RLinks )
+		PostQuitMessage( 0 );
+	return 1;
+}
+
+bool optionenME( void *p, void *obj, MausEreignis me )
+{
+	if( me.id == ME_RLinks )
+	{
+        _o_rno->removeStyle( Knopf::Style::Erlaubt );
+        _o_rnu->removeStyle( Knopf::Style::Erlaubt );
+		while( _o_rt->getZeilenAnzahl() > 1 )
+		{
+			if( _o_rt->zZeichnung( 0, 1 ) )
+				( (TextFeld*)_o_rt->zZeichnung( 0, 1 ) )->release();
+			if( _o_rt->zZeichnung( 1, 1 ) )
+				( (KontrollKnopf*)_o_rt->zZeichnung( 1, 1 ) )->release();
+			_o_rt->removeZeile( 1 );
+		}
+		KSGTDatei *dat = new KSGTDatei( "data/dg.ksgt" ); // Tabellen Spalten: Id, Pfad, Version, Priorität
+		dat->laden();
+		int max = -1;
+		for( int i = 0; i < dat->getZeilenAnzahl(); i++ )
+		{
+			if( !dat->zFeld( i, 3 ) || dat->zFeld( i, 3 )->istGleich( "NICHT" ) || dat->zFeld( i, 3 )->istGleich( "" ) )
+				continue;
+			if( max < (int)TextZuInt( dat->zFeld( i, 3 )->getText(), 10 ) )
+				max = (int)TextZuInt( dat->zFeld( i, 3 )->getText(), 10 );
+		}
+		for( int i = 0; i <= max; i++ )
+		{
+			for( int j = 0; j < dat->getZeilenAnzahl(); j++ )
+			{
+				if( !dat->zFeld( j, 1 ) || dat->zFeld( j, 1 )->istGleich( "" ) )
+					continue;
+				Text *iT = new Text( "" );
+				iT->append( i );
+				if( dat->zFeld( j, 3 ) && dat->zFeld( j, 3 )->istGleich( iT ) )
+				{
+					Text *name = dat->zFeld( j, 1 )->getTeilText( dat->zFeld( j, 1 )->positionVon( "spiele/" ) + 7 );
+					if( !name || !name->getLength() || !dat->zFeld( j, 1 )->hat( "spiele/" ) )
+					{
+						if( name )
+							name->release();
+						name = dat->zFeld( j, 1 )->getTeilText( dat->zFeld( j, 1 )->positionVon( "Spiele/" ) + 7 );
+					}
+					if( !name || !name->getLength() || ( !dat->zFeld( j, 1 )->hat( "Spiele/" ) && !dat->zFeld( j, 1 )->hat( "spiele/" ) ) )
+					{
+						if( name )
+							name->release();
+						name = new Text( dat->zFeld( j, 1 )->getText() );
+						if( name->hat( '/' ) )
+							name->remove( 0, name->positionVon( '/', name->anzahlVon( '/' ) - 1 ) + 1 );
+					}
+					int anz = _o_rt->getZeilenAnzahl();
+					_o_rt->addZeile( dat->zFeld( j, 0 )->getText() );
+					Text *spielN = 0;
+					if( name->positionVon( '/' ) >= 0 )
+						spielN = name->getTeilText( 0, name->positionVon( '/' ) );
+					else
+						spielN = new Text( name->getText() );
+					name = name->release();
+					TextFeld *spiel = new TextFeld();
+					spiel->setStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Center );
+					spiel->setSchriftZ( _optionenF->getTSchrift() );
+					spiel->setSchriftFarbe( 0xFFFFFFFF );
+					spiel->setHintergrundFarbe( 0xFF003000 );
+					spiel->setText( spielN );
+					_o_rt->setZeichnungZ( 0, anz, spiel );
+					KontrollKnopf *erlaubt = new KontrollKnopf();
+					erlaubt->addStyle( KontrollKnopf::Style::Sichtbar | KontrollKnopf::Style::Erlaubt | KontrollKnopf::Style::KlickBuffer | KontrollKnopf::Style::Selected );
+					erlaubt->setHintergrundFarbe( 0xFF003000 );
+					erlaubt->setSBgFarbe( 0xFF003000 );
+					erlaubt->loadData( "data/bilder/system.ltdb" );
+					erlaubt->setMausEreignis( _o_rkkME );
+					_o_rt->setZeichnungZ( 1, anz, erlaubt );
+				}
+			}
+		}
+		for( int i = 0; i < dat->getZeilenAnzahl(); i++ )
+		{
+			if( dat->zFeld( i, 3 ) && dat->zFeld( i, 3 )->istGleich( "NICHT" ) )
+			{
+				Text *name = dat->zFeld( i, 1 )->getTeilText( dat->zFeld( i, 1 )->positionVon( "spiele/" ) + 7 );
+				if( !name || !name->getLength() )
+				{
+					if( name )
+						name->release();
+					name = dat->zFeld( i, 1 )->getTeilText( dat->zFeld( i, 1 )->positionVon( "Spiele/" ) + 7 );
+				}
+				if( !name || !name->getLength() )
+				{
+					if( name )
+						name->release();
+					name = new Text( dat->zFeld( i, 1 )->getText() );
+					if( name->hat( '/' ) )
+						name->remove( 0, name->positionVon( '/', name->anzahlVon( '/' ) - 1 ) );
+				}
+				int anz = _o_rt->getZeilenAnzahl();
+				_o_rt->addZeile( dat->zFeld( i, 0 )->getText() );
+				Text *spielN = 0;
+				if( name->positionVon( '/' ) >= 0 )
+					spielN = name->getTeilText( 0, name->positionVon( '/' ) );
+				else
+					spielN = new Text( name->getText() );
+				name = name->release();
+				TextFeld *spiel = new TextFeld();
+				spiel->setStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Center );
+				spiel->setSchriftZ( _optionenF->getTSchrift() );
+				spiel->setSchriftFarbe( 0xFFFFFFFF );
+				spiel->setHintergrundFarbe( 0xFF003000 );
+				spiel->setText( spielN );
+				_o_rt->setZeichnungZ( 0, anz, spiel );
+				KontrollKnopf *erlaubt = new KontrollKnopf();
+				erlaubt->addStyle( KontrollKnopf::Style::Sichtbar | KontrollKnopf::Style::Erlaubt | KontrollKnopf::Style::KlickBuffer );
+				erlaubt->setHintergrundFarbe( 0xFF003000 );
+				erlaubt->loadData( "data/bilder/system.ltdb" );
+				erlaubt->setMausEreignis( _o_rkkME );
+				_o_rt->setZeichnungZ( 1, anz, erlaubt );
+			}
+		}
+		dat->release();
+		InitDatei *ini = new InitDatei( "data/patch/po.ini" );
+		ini->laden();
+		if( ini->wertExistiert( "ülps" ) )
+			_o_ülps->setText( ini->zWert( "ülps" )->getText() );
+		if( ini->wertExistiert( "üle" ) )
+			_o_üle->setAuswahl( _o_üle->getEintragPos( ini->zWert( "üle" )->getThis() ) );
+		ini->release();
+		_optionenF->setPosition( 100, 100 );
+		_optionenF->addStyle( Fenster::Style::Sichtbar );
+	}
+	return 1;
+}
+
+bool oAbbrechen( void *p, void *obj, MausEreignis me )
+{
+	if( me.id == ME_RLinks )
+		_optionenF->removeStyle( Fenster::Style::Sichtbar );
+	return 1;
+}
+
+bool _o_rtME( void *p, void *obj, MausEreignis me )
+{
+	if( me.id == ME_RLinks )
+	{
+		for( int i = 1; i < _o_rt->getZeilenAnzahl(); i++ )
+		{
+			if( _o_rt->zZeichnung( 0, i ) )
+				( (TextFeld*)_o_rt->zZeichnung( 0, i ) )->removeStyle( TextFeld::Style::Hintergrund );
+			if( _o_rt->zZeichnung( 1, i ) )
+				( (KontrollKnopf*)_o_rt->zZeichnung( 1, i ) )->removeStyle( KontrollKnopf::Style::Hintergrund | KontrollKnopf::Style::SelectFarbe );
+		}
+		int zeile = (int)_o_rt->getMausZeile( me.my - _o_rt->getY() - _o_rt->getVertikalScrollPos() );
+		if( zeile <= 0 )
+		{
+			_o_rno->removeStyle( Knopf::Style::Erlaubt );
+			_o_rnu->removeStyle( Knopf::Style::Erlaubt );
+		}
+		else
+		{
+			if( _o_rt->zZeichnung( 0, zeile ) )
+				( (TextFeld*)_o_rt->zZeichnung( 0, zeile ) )->addStyle( TextFeld::Style::Hintergrund );
+			if( _o_rt->zZeichnung( 1, zeile ) )
+				( (KontrollKnopf*)_o_rt->zZeichnung( 1, zeile ) )->addStyle( KontrollKnopf::Style::Hintergrund | KontrollKnopf::Style::SelectFarbe );
+			if( zeile > 1 )
+				_o_rno->addStyle( Knopf::Style::Erlaubt );
+			else
+				_o_rno->removeStyle( Knopf::Style::Erlaubt );
+			int max = 0;
+			for( int i = 1; i < _o_rt->getZeilenAnzahl(); i++ )
+			{
+				if( !_o_rt->zZeichnung( 1, i ) || ( (KontrollKnopf*)_o_rt->zZeichnung( 1, i ) )->hatStyleNicht( KontrollKnopf::Style::Selected ) )
+					break;
+				max = i;
+			}
+			if( zeile < max )
+				_o_rnu->addStyle( Knopf::Style::Erlaubt );
+			else
+				_o_rnu->removeStyle( Knopf::Style::Erlaubt );
+			if( ( _o_rt->zZeichnung( 1, zeile ) && ( (KontrollKnopf*)_o_rt->zZeichnung( 1, zeile ) )->hatStyleNicht( KontrollKnopf::Style::Selected ) ) )
+			{
+				_o_rno->removeStyle( Knopf::Style::Erlaubt );
+				_o_rnu->removeStyle( Knopf::Style::Erlaubt );
+			}
+		}
+	}
+	return 1;
+}
+
+bool _o_rnoME( void *p, void *obj, MausEreignis me )
+{
+	if( me.id == ME_RLinks )
+	{
+		int zeile = -1;
+		for( int i = 1; i < _o_rt->getZeilenAnzahl(); i++ )
+		{
+			if( _o_rt->zZeichnung( 0, i ) && ( (TextFeld*)_o_rt->zZeichnung( 0, i ) )->hatStyle( TextFeld::Style::Hintergrund ) )
+			{
+				zeile = i;
+				break;
+			}
+		}
+		if( zeile > 1 )
+		{
+			_o_rt->setZeilePosition( zeile, zeile - 1 );
+			_o_rnu->addStyle( Knopf::Style::Erlaubt );
+		}
+		if( zeile - 1 <= 1 )
+			_o_rno->removeStyle( Knopf::Style::Erlaubt );
+	}
+	return 1;
+}
+
+bool _o_rnuME( void *p, void *obj, MausEreignis me )
+{
+	if( me.id == ME_RLinks )
+	{
+		int zeile = -1;
+		for( int i = 1; i < _o_rt->getZeilenAnzahl(); i++ )
+		{
+			if( _o_rt->zZeichnung( 0, i ) && ( (TextFeld*)_o_rt->zZeichnung( 0, i ) )->hatStyle( TextFeld::Style::Hintergrund ) )
+			{
+				zeile = i;
+				break;
+			}
+		}
+		int max = 0;
+		for( int i = 1; i < _o_rt->getZeilenAnzahl(); i++ )
+		{
+			if( !_o_rt->zZeichnung( 1, i ) || ( (KontrollKnopf*)_o_rt->zZeichnung( 1, i ) )->hatStyleNicht( KontrollKnopf::Style::Selected ) )
+				break;
+			max = i;
+		}
+		if( zeile > 0 && zeile < max )
+		{
+			_o_rt->setZeilePosition( zeile, zeile + 1 );
+			_o_rno->addStyle( Knopf::Style::Erlaubt );
+		}
+		if( zeile + 1 >= _o_rt->getZeilenAnzahl() - 1 )
+			_o_rnu->removeStyle( Knopf::Style::Erlaubt );
+	}
+	return 1;
+}
+
+bool _o_rkkME( void *p, void *obj, MausEreignis me )
+{
+	if( me.id == ME_RLinks )
+	{
+		if( ( (KontrollKnopf*)obj )->hatStyleNicht( KontrollKnopf::Style::Hintergrund | KontrollKnopf::Style::SelectFarbe ) )
+		{
+			( (KontrollKnopf*)obj )->setStyle( KontrollKnopf::Style::Selected, ( (KontrollKnopf*)obj )->hatStyleNicht( KontrollKnopf::Style::Selected ) );
+			return 1;
+		}
+		if( ( (KontrollKnopf*)obj )->hatStyle( KontrollKnopf::Style::Selected ) )
+		{
+			_o_rno->removeStyle( Knopf::Style::Erlaubt );
+			_o_rnu->removeStyle( Knopf::Style::Erlaubt );
+			int zeile = -1;
+			for( int i = 1; i < _o_rt->getZeilenAnzahl(); i++ )
+			{
+				if( _o_rt->zZeichnung( 1, i ) == obj )
+				{
+					zeile = i;
+					break;
+				}
+			}
+			int max = 0;
+			for( int i = 1; i < _o_rt->getZeilenAnzahl(); i++ )
+			{
+				if( !_o_rt->zZeichnung( 1, i ) || ( (KontrollKnopf*)_o_rt->zZeichnung( 1, i ) )->hatStyleNicht( KontrollKnopf::Style::Selected ) )
+					break;
+				max = i;
+			}
+			_o_rt->setZeilePosition( zeile, max );
+		}
+		else
+		{
+			int zeile = -1;
+			for( int i = 1; i < _o_rt->getZeilenAnzahl(); i++ )
+			{
+				if( _o_rt->zZeichnung( 1, i ) == obj )
+				{
+					zeile = i;
+					break;
+				}
+			}
+			int max = 0;
+			for( int i = 1; i < _o_rt->getZeilenAnzahl(); i++ )
+			{
+				if( !_o_rt->zZeichnung( 1, i ) || ( (KontrollKnopf*)_o_rt->zZeichnung( 1, i ) )->hatStyleNicht( KontrollKnopf::Style::Selected ) )
+					break;
+				max = i;
+			}
+			_o_rt->setZeilePosition( zeile, max + 1 );
+			if( max > 1 )
+				_o_rno->addStyle( Knopf::Style::Erlaubt );
+		}
+	}
+	return 1;
+}
+
+bool _o_ülpsTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( te.taste == T_Links || te.taste == T_Rechts || te.taste == T_Entf || te.taste == T_BackSpace || ( te.taste >= '0' && te.taste <= '9' ) )
+		return 1;
+	return 0;
+}
+
+bool o_okME( void *p, void *obj, MausEreignis me )
+{
+	if( me.id == ME_RLinks )
+	{
+		KSGTDatei *dat = new KSGTDatei( "data/dg.ksgt" );
+		dat->laden();
+		for( int i = 0; i < dat->getZeilenAnzahl(); i++ )
+		{
+			for( int j = 0; j < _o_rt->getZeilenAnzahl(); j++ )
+			{
+				if( !_o_rt->zZeichnung( 1, j ) )
+					continue;
+				if( !_o_rt->zZeilenName( j )->istGleich( dat->zFeld( i, 0 )->getText() ) )
+					continue;
+				if( ( (KontrollKnopf*)_o_rt->zZeichnung( 1, j ) )->hatStyle( KontrollKnopf::Style::Selected ) )
+				{
+					Text *t = new Text();
+					t->append( j );
+					dat->zFeld( i, 3 )->setText( t );
+				}
+				else
+					dat->zFeld( i, 3 )->setText( "NICHT" );
+				break;
+			}
+		}
+		dat->speichern();
+		dat->release();
+		InitDatei *ini = new InitDatei( "data/patch/po.ini" );
+		ini->addWert( "ülps", _o_ülps->zText()->getText() );
+		ini->addWert( "üle", _o_üle->zEintragText( _o_üle->getAuswahl() )->getText() );
+		ini->speichern();
+		ini->release();
+		_optionenF->removeStyle( Fenster::Style::Sichtbar );
+	}
+	return 1;
+}
+
+DWORD WINAPI runThread( void *args )
+{
+	Bildschirm *screen = (Bildschirm *)args;
+	double i = 0;
+	double tickVal = 1.0 / 60.0;
+	ZeitMesser *tstop = new ZeitMesser();
+	while( !_exitB )
+	{
+		tstop->messungStart();
+		screen->render();
+		screen->tick( tickVal );
+		Sleep( 10 );
+		if( _kbps )
+		{
+			i += tickVal * 60;
+			if( i >= 60 && _kbps )
+			{
+				screen->lock();
+				_kbps->setText( "" );
+				_kbps->zText()->append( _patcher ? ( _patcher->getDownload() / 1024 ) : 0 );
+				_kbps->zText()->append( " kb/s, " );
+				_kbps->zText()->append( (unsigned int)( ( _fortschritt->getAktionAnzahl() - _fortschritt->getAktion() ) / 1024 ) );
+				_kbps->zText()->append( " kb verbleibend..." );
+				screen->unlock();
+				i -= 60;
+			}
+		}
+		tstop->messungEnde();
+		tickVal = tstop->getSekunden() + tstop->getSekunden() - tickVal;
+	}
+	tstop->release();
+	return 0;
+}
+
+int KSGStart Framework::Start( Startparam p )
+{
+	_abbruch = 0;
+	Network::Start( 10 );
+
+	LTDBDatei *patcherBilder = new LTDBDatei();
+	patcherBilder->setDatei( new Text( "data/patch/bilder/patcher.ltdb" ) );
+	patcherBilder->leseDaten( 0 );
+	Bild *patcherRahmen = patcherBilder->laden( 0, new Text( "patcherrahmen." ) );
+	Bild *patcherHintergrund = patcherBilder->laden( 0, new Text( "patcher.png" ) );
+	Bild *playBild = patcherBilder->laden( 0, new Text( "play.png" ) );
+	Bild *playKlick = patcherBilder->laden( 0, new Text( "playklick.png" ) );
+	patcherBilder->release();
+
+	LTDBDatei *systemBilder = new LTDBDatei();
+	systemBilder->setDatei( new Text( "data/bilder/system.ltdb" ) );
+	systemBilder->leseDaten( 0 );
+	Bild *systemSchließen = systemBilder->laden( 0, new Text( "schließen.png" ) );
+	Bild *systemMinimieren = systemBilder->laden( 0, new Text( "minimieren.png" ) );
+	Bild *systemOptionen = systemBilder->laden( 0, new Text( "optionen.png" ) );
+	Bild *systemFortschrittL = systemBilder->laden( 0, new Text( "fortschrittleh" ) );
+	Bild *systemFortschrittV = systemBilder->laden( 0, new Text( "fortschrittvol" ) );
+	systemBilder->release();
+
+	LTDSDatei *normalSchrift = new LTDSDatei();
+	normalSchrift->setPfad( new Text( "data/schriften/normal.ltds" ) );
+	normalSchrift->leseDaten();
+	Schrift *sNormal = normalSchrift->ladeSchrift();
+	normalSchrift->release();
+
+	WNDCLASS wc = F_Normal( p.hinst );
+	wc.lpszClassName = "Kolja-Strohm Games Patcher";
+	_frame = new WFenster();
+	_frame->setVerschiebbar( 1 );
+	_frame->erstellen( WS_POPUP, wc );
+	_frame->setSize( Punkt( 500, 500 ) );
+	_frame->setPosition( Bildschirmmitte( _frame->getThis() ) );
+	_frame->ladeRahmenFenster( patcherRahmen, p.hinst );
+	_frame->setMausAktion( _frameME );
+	_frame->setTastaturAktion( _frameTE );
+	_frame->setVSchließAktion( _frameSchließen );
+	Bildschirm *screen = new Bildschirm3D( _frame->getThis() );
+	screen->update();
+	screen->render();
+	_frame->setBildschirm( screen->getThis() );
+	_frame->setAnzeigeModus( 1 );
+
+	screen->lock();
+	BildZ *hintergrund = new BildZ();
+	hintergrund->setStyle( BildZ::Style::Sichtbar );
+	hintergrund->setBildZ( patcherHintergrund->getThis() );
+	hintergrund->setPosition( 0, 0 );
+	hintergrund->setSize( patcherHintergrund->getBreite(), patcherHintergrund->getHeight() );
+	screen->addMember( hintergrund );
+
+	Knopf *close = new Knopf();
+	close->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	close->setHintergrundBildZ( systemSchließen->getThis() );
+	close->setKBFarbe( 0xFF000000 );
+    close->setHintergrundFarbe( 0 );
+	close->setKBStrength( 30 );
+	close->setPosition( 475, 5 );
+	close->setSize( 20, 20 );
+	close->setMausEreignis( closeME );
+	screen->addMember( close );
+
+	Knopf *minimieren = new Knopf();
+	minimieren->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	minimieren->setHintergrundBildZ( systemMinimieren->getThis() );
+    minimieren->setHintergrundFarbe( 0 );
+	minimieren->setKBFarbe( 0xFF000000 );
+	minimieren->setKBStrength( 30 );
+	minimieren->setPosition( 454, 5 );
+	minimieren->setSize( 20, 20 );
+	minimieren->setMausEreignis( minimierenME );
+	screen->addMember( minimieren );
+
+	Knopf *optionen = new Knopf();
+	optionen->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	optionen->setHintergrundBildZ( systemOptionen->getThis() );
+    optionen->setHintergrundFarbe( 0 );
+	optionen->setKBFarbe( 0xFF000000 );
+	optionen->setKBStrength( 30 );
+	optionen->setPosition( 433, 5 );
+	optionen->setSize( 20, 20 );
+	optionen->setMausEreignis( optionenME );
+	screen->addMember( optionen );
+
+	News *news = new News( screen, sNormal );
+
+	_aktion = new TextFeld();
+	_aktion->setStyle( TextFeld::Style::Sichtbar );
+	_aktion->setSchriftZ( sNormal->getThis() );
+	_aktion->setSchriftFarbe( 0xFFFFFFFF );
+	_aktion->setText( "Ermittle änderungen..." );
+	_aktion->setPosition( 49, 403 );
+	_aktion->setSize( 502, 20 );
+	screen->addMember( _aktion );
+
+	_kbps = new TextFeld();
+	_kbps->setStyle( TextFeld::Style::Sichtbar );
+	_kbps->setSchriftZ( sNormal->getThis() );
+	_kbps->setSchriftFarbe( 0xFFFFFFFF );
+	_kbps->setText( "0 kb/s" );
+	_kbps->setPosition( 49, 460 );
+	_kbps->setSize( 402, 20 );
+	screen->addMember( _kbps );
+
+	_fortschritt = new FBalken();
+	_fortschritt->setStyle( FBalken::Style::Sichtbar | FBalken::Style::Hintergrund | FBalken::Style::HBild | FBalken::Style::FBild | FBalken::Style::Rahmen | FBalken::Style::Prozent | FBalken::Style::L_R );
+	_fortschritt->setLinienRahmenFarbe( 0xFFFFFFFF );
+	_fortschritt->setHintergrundBild( systemFortschrittL->getThis() );
+	_fortschritt->setFBgBild( systemFortschrittV->getThis() );
+	_fortschritt->setSchriftZ( sNormal->getThis() );
+	_fortschritt->setSFarbe( 0xFFFFFFFF );
+	_fortschritt->setSSize( 12 );
+	_fortschritt->setPosition( 49, 428 );
+	_fortschritt->setSize( 402, 22 );
+	screen->addMember( _fortschritt );
+
+	_play = new Knopf();
+	_play->setStyle( Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::KlickBild );
+	_play->setMausEreignis( _playME );
+	_play->setHintergrundBildZ( playBild->getThis() );
+	_play->setKlickBildZ( playKlick->getThis() );
+	_play->setPosition( 200, 466 );
+	_play->setSize( 101, 30 );
+	screen->addMember( _play );
+
+	_optionenF = new Fenster();
+	_optionenF->setStyle( Fenster::Style::Erlaubt | Fenster::Style::Closable | Fenster::Style::Titel | Fenster::Style::TitelBuffered |
+						  Fenster::Style::TitelHintergrund | Fenster::Style::BodyHintergrund | Fenster::Style::TitelHAlpha |
+						  Fenster::Style::BodyHAlpha | Fenster::Style::Rahmen | Fenster::Style::ClosingKlickBuffer |
+						  Fenster::Style::ClosingHintergrund | Fenster::Style::ClosingHAlpha | Fenster::Style::Beweglich | Fenster::Style::VScroll );
+	_optionenF->setSize( 300, 300 );
+	_optionenF->setPosition( 100, 100 );
+	_optionenF->setVSBMax( 300 );
+	_optionenF->zVScrollBar()->setKlickScroll( 10 );
+	_optionenF->zVScrollBar()->setFarbe( 0xFFFFFFFF );
+	_optionenF->zVScrollBar()->setBgFarbe( 0xF0000000, 1 );
+	_optionenF->setRBreite( 2 );
+	_optionenF->setRFarbe( 0xFFFFFFFF );
+	_optionenF->setTSchriftZ( sNormal->getThis() );
+	_optionenF->zTTextFeld()->addStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Center );
+	_optionenF->setTitel( "Optionen" );
+	_optionenF->zTTextFeld()->setSize( 0, 20 );
+	_optionenF->setTBgFarbe( 0xF0000000 );
+	_optionenF->setTAfFarbe( 0xA0FFFFFF );
+	_optionenF->setTAfStrength( 15 );
+	_optionenF->setTSFarbe( 0xFFFFFFFF );
+	_optionenF->setSBgFarbe( 0xF0000000 );
+	_optionenF->setSKAfFarbe( 0xFFFFFFFF );
+	_optionenF->setSKAfStrength( 30 );
+	_optionenF->setKBgFarbe( 0xF0000000 );
+	_optionenF->setClosingMe( oAbbrechen );
+	screen->addMember( _optionenF );
+
+	TextFeld *oReihenfolge = new TextFeld();
+	oReihenfolge->setStyle( TextFeld::Style::Sichtbar | TextFeld::Style::VCenter );
+	oReihenfolge->setSchriftZ( sNormal->getThis() );
+	oReihenfolge->setSchriftFarbe( 0xFFFFFFFF );
+	oReihenfolge->setText( "Update Reihenfolge:" );
+	oReihenfolge->setPosition( 2, 2 );
+	oReihenfolge->setSize( 276, 20 );
+	_optionenF->addMember( oReihenfolge );
+
+	_o_rt = new ObjTabelle();
+	_o_rt->setStyle( ObjTabelle::Style::Sichtbar | ObjTabelle::Style::Erlaubt | ObjTabelle::Style::Rahmen | 
+                     ObjTabelle::Style::Raster | ObjTabelle::Style::VScroll );
+	_o_rt->setPosition( 2, 24 );
+	_o_rt->setSize( 276, 150 );
+	_o_rt->setLinienRahmenBreite( 1 );
+	_o_rt->setLinienRahmenFarbe( 0xFFFFFFFF );
+	_o_rt->setRasterBreite( 1 );
+	_o_rt->setRasterFarbe( 0xFFFFFFFF );
+	_o_rt->setVertikalKlickScroll( 10 );
+	_o_rt->setMausEreignis( _o_rtME );
+	_o_rt->addSpalte( "Spiel" );
+	_o_rt->addSpalte( "Erlaubt" );
+	_o_rt->setSpaltenBreite( 0, 237 );
+	_o_rt->setSpaltenBreite( 1, 20 );
+	_o_rt->addZeile( "Überschrift" );
+	_o_rt->setZeilenHeight( 0, 15 );
+	TextFeld *ortSpielT = new TextFeld();
+	ortSpielT->setStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Center );
+	ortSpielT->setSchriftZ( sNormal->getThis() );
+	ortSpielT->setSchriftFarbe( 0xFFFFFFFF );
+	ortSpielT->setText( "Spiel" );
+	_o_rt->setZeichnungZ( 0, 0, ortSpielT );
+	_optionenF->addMember( _o_rt );
+
+	_o_rno = new Knopf();
+	_o_rno->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Buffered | Knopf::Style::KlickBuffer | Knopf::Style::Rahmen );
+	_o_rno->setPosition( 76, 176 );
+	_o_rno->setSize( 100, 20 );
+	_o_rno->setText( "nach Oben" );
+	_o_rno->setSchriftZ( sNormal->getThis() );
+	_o_rno->setMausEreignis( _o_rnoME );
+	_optionenF->addMember( _o_rno );
+
+	_o_rnu = new Knopf();
+	_o_rnu->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Buffered | Knopf::Style::KlickBuffer | Knopf::Style::Rahmen );
+	_o_rnu->setPosition( 178, 176 );
+	_o_rnu->setSize( 100, 20 );
+	_o_rnu->setText( "nach Unten" );
+	_o_rnu->setSchriftZ( sNormal->getThis() );
+	_o_rnu->setMausEreignis( _o_rnuME );
+	_optionenF->addMember( _o_rnu );
+
+	TextFeld *oLimit = new TextFeld();
+	oLimit->setStyle( TextFeld::Style::Sichtbar | TextFeld::Style::VCenter );
+	oLimit->setSchriftZ( sNormal->getThis() );
+	oLimit->setSchriftFarbe( 0xFFFFFFFF );
+	oLimit->setText( "Übertragungslimit pro Sekunde:" );
+	oLimit->setPosition( 2, 200 );
+	oLimit->setSize( 276, 20 );
+	_optionenF->addMember( oLimit );
+
+	_o_ülps = new TextFeld();
+	_o_ülps->setStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Erlaubt | TextFeld::Style::Rahmen | TextFeld::Style::Buffered | TextFeld::Style::VCenter );
+	_o_ülps->setPosition( 2, 222 );
+	_o_ülps->setSize( 100, 20 );
+	_o_ülps->setLinienRahmenFarbe( 0xFF00FF00 );
+	_o_ülps->setSchriftZ( sNormal->getThis() );
+	_o_ülps->setText( "" );
+	_o_ülps->setSchriftFarbe( 0xFFFFFFFF );
+	_o_ülps->setSchriftSize( 12 );
+	_o_ülps->setAlphaFeldFarbe( 0x5500FF00 );
+	_o_ülps->setAlphaFeldStrength( -5 );
+	_o_ülps->setTastaturEreignis( _o_ülpsTE );
+	_optionenF->addMember( _o_ülps );
+
+	_o_üle = new AuswahlBox();
+	_o_üle->setStyle( AuswahlBox::Style::Sichtbar | AuswahlBox::Style::Erlaubt | AuswahlBox::Style::Rahmen | AuswahlBox::Style::AuswahlBuffer |
+					  AuswahlBox::Style::MausBuffer | AuswahlBox::Style::Hintergrund );
+	_o_üle->setPosition( 104, 222 );
+	_o_üle->setSize( 55, 20 );
+	_o_üle->setSchriftZ( sNormal->getThis() );
+	_o_üle->setLinienRahmenFarbe( 0xFFFFFFFF );
+	_o_üle->setHintergrundFarbe( 0xFF000000 );
+	_o_üle->setAuswAlphaFeldFarbe( 0x5500FF00 );
+	_o_üle->setAuswAlphaFeldStrength( -5 );
+	_o_üle->setMausAlphaFeldFarbe( 0x2200FF00 );
+	_o_üle->setMausAlphaFeldStrength( -5 );
+	_o_üle->setMausEreignis( _ret1ME );
+	_o_üle->setTastaturEreignis( _ret1TE );
+	_o_üle->addEintrag( "kb/s" );
+	_o_üle->addEintrag( "mb/s" );
+	_optionenF->addMember( _o_üle );
+
+	Knopf *o_ok = new Knopf();
+	o_ok->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Buffered | Knopf::Style::KlickBuffer | Knopf::Style::Rahmen );
+	o_ok->setPosition( 178, 254 );
+	o_ok->setSize( 100, 20 );
+	o_ok->setText( "Fertig" );
+	o_ok->setSchriftZ( sNormal->getThis() );
+	o_ok->setMausEreignis( o_okME );
+	_optionenF->addMember( o_ok );
+
+	screen->unlock();
+
+	DWORD threadId;
+	HANDLE handle = CreateThread( NULL, 0, runThread, screen, 0, &threadId );
+
+	_patcher = new Patcher( _fortschritt->getThis(), _aktion->getThis(), _play->getThis(), &_exitB );
+	_patcher->startPatch();
+
+	StartNachrichtenSchleife();
+
+	_exitB = 1;
+	WaitForSingleObject( handle, INFINITE );
+
+	news->release();
+
+	_patcher->warteAufPatch( INFINITE );
+	int returnVal = _patcher->getReturn();
+	_patcher->release();
+
+	optionen->release();
+	_optionenF->release();
+	oReihenfolge->release();
+	for( int i = 0; i < _o_rt->getZeilenAnzahl(); i++ )
+	{
+		if( _o_rt->zZeichnung( 0, i ) )
+			( (TextFeld*)_o_rt->zZeichnung( 0, i ) )->release();
+		if( _o_rt->zZeichnung( 1, i ) )
+			( (KontrollKnopf*)_o_rt->zZeichnung( 1, i ) )->release();
+		_o_rt->setZeichnungZ( 0, i, 0 );
+		_o_rt->setZeichnungZ( 1, i, 0 );
+	}
+	_o_rt->release();
+	_o_rno->release();
+	_o_rnu->release();
+	oLimit->release();
+	_o_ülps->release();
+	_o_üle->release();
+	o_ok->release();
+
+	hintergrund->release();
+	close->release();
+	minimieren->release();
+	_fortschritt->release();
+	_aktion->release();
+	_kbps->release();
+	_play->release();
+	sNormal->release();
+
+	patcherRahmen->release();
+	patcherHintergrund->release();
+	playBild->release();
+	playKlick->release();
+	systemSchließen->release();
+	systemMinimieren->release();
+	systemOptionen->release();
+	systemFortschrittL->release();
+	systemFortschrittV->release();
+
+	screen->release();
+	_frame->setBildschirm( 0 );
+	_frame->zerstören();
+	_frame->release();
+	Network::Exit();
+
+	DateiPfadErstellen( new Text( "data/tmp/keinabsturz" ) );
+
+	if( _abbruch )
+		return 0;
+	return returnVal;
+}