Browse Source

Projektdateien hinzufügen.

Kolja Strohm 7 years ago
parent
commit
2a61fb4926

+ 30 - 0
Editor Server.sln

@@ -0,0 +1,30 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26020.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EditorServer", "EditorServer\EditorServer.vcxproj", "{FA25200A-6BBB-4EC3-9A83-D5BC151DC90A}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|ARM = Debug|ARM
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|ARM = Release|ARM
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{FA25200A-6BBB-4EC3-9A83-D5BC151DC90A}.Debug|ARM.ActiveCfg = Debug|x64
+		{FA25200A-6BBB-4EC3-9A83-D5BC151DC90A}.Debug|x64.ActiveCfg = Debug|x64
+		{FA25200A-6BBB-4EC3-9A83-D5BC151DC90A}.Debug|x64.Build.0 = Debug|x64
+		{FA25200A-6BBB-4EC3-9A83-D5BC151DC90A}.Debug|x86.ActiveCfg = Debug|x64
+		{FA25200A-6BBB-4EC3-9A83-D5BC151DC90A}.Release|ARM.ActiveCfg = Release|x64
+		{FA25200A-6BBB-4EC3-9A83-D5BC151DC90A}.Release|x64.ActiveCfg = Release|x64
+		{FA25200A-6BBB-4EC3-9A83-D5BC151DC90A}.Release|x64.Build.0 = Release|x64
+		{FA25200A-6BBB-4EC3-9A83-D5BC151DC90A}.Release|x86.ActiveCfg = Release|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

+ 292 - 0
EditorServer/BeschreibungEditor.cpp

@@ -0,0 +1,292 @@
+#include "BeschreibungEditor.h"
+#include <Datei.h>
+#include <DateiSystem.h>
+#include <Bild.h>
+
+// Inhalt der BeschreibungEditor Klasse aus BeschreibungEditor.h
+// Konstruktor
+BeschreibungEditor::BeschreibungEditor( char *pf )
+{
+    pfad = pf;
+    pfad += "/live/map/client";
+    fehler = "";
+    ref = 1;
+}
+
+// Destruktor
+BeschreibungEditor::~BeschreibungEditor()
+{}
+
+// nicht constant
+bool BeschreibungEditor::prozessMessage( SKlient *zKlient )
+{
+    char message = 0;
+    zKlient->getNachrichtEncrypted( &message, 1 );
+    switch( message )
+    {
+    case 0x1: // Beschreibung laden
+    {
+        Text p = pfad.getText();
+        p += "/beschreibung.ksgs";
+        if( !DateiExistiert( p ) )
+        {
+            fehler = "Die Beschreibung wurde nicht gefunden.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        Datei d;
+        d.setDatei( p );
+        bool ok = d.open( Datei::Style::lesen );
+        char *buffer = new char[ 2048 ];
+        int gr = (int)d.getSize();
+        zKlient->sendeEncrypted( (char*)&gr, 4 );
+        while( gr > 0 )
+        {
+            int l = gr > 2048 ? 2048 : gr;
+            d.lese( buffer, l );
+            zKlient->sende( buffer, l );
+            gr -= l;
+        }
+        delete[] buffer;
+        d.close();
+        if( !ok )
+        {
+            fehler = "Es ist ein Fehler beim laden der Beschreibung aufgetreten.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        return 1;
+    }
+    case 0x2: // Titelbild laden
+    {
+        Text p = pfad.getText();
+        p += "/titel.ltdb";
+        if( !DateiExistiert( p ) )
+        {
+            fehler = "Das Titelbild wurde nicht gefunden.";
+            return 0;
+        }
+        LTDBDatei dat;
+        dat.setDatei( p.getThis() );
+        dat.leseDaten( 0 );
+        Bild *b = dat.laden( 0, dat.zBildListe()->get( 0 ) );
+        if( !b )
+        {
+            fehler = "Das Titelbild wurde nicht gefunden.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        int br = b->getBreite();
+        int hi = b->getHeight();
+        zKlient->sendeEncrypted( (char*)&br, 4 );
+        zKlient->sendeEncrypted( (char*)&hi, 4 );
+        char *buffer = (char*)b->getBuffer();
+        __int64 gr = br * hi * 4;
+        for( int i = 0, l = gr > 2048 ? 2048 : (int)gr; gr > 0; i += l, gr -= l, l = gr > 2048 ? 2048 : (int)gr )
+            zKlient->sende( &( buffer[ i ] ), l );
+        b->release();
+        return 1;
+    }
+    case 0x3: // Minimap laden
+    {
+        Text p = pfad.getText();
+        p += "/minimap.ltdb";
+        if( !DateiExistiert( p ) )
+        {
+            fehler = "Das Minimap Bild wurde nicht gefunden.";
+            return 0;
+        }
+        LTDBDatei dat;
+        dat.setDatei( p.getThis() );
+        dat.leseDaten( 0 );
+        Bild *b = dat.laden( 0, dat.zBildListe()->get( 0 ) );
+        if( !b )
+        {
+            fehler = "Das Minimap Bild wurde nicht gefunden.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        int br = b->getBreite();
+        int hi = b->getHeight();
+        zKlient->sendeEncrypted( (char*)&br, 4 );
+        zKlient->sendeEncrypted( (char*)&hi, 4 );
+        char *buffer = (char*)b->getBuffer();
+        __int64 gr = br * hi * 4;
+        for( int i = 0, l = gr > 2048 ? 2048 : (int)gr; gr > 0; i += l, gr -= l, l = gr > 2048 ? 2048 : (int)gr )
+            zKlient->sende( &( buffer[ i ] ), l );
+        b->release();
+        return 1;
+    }
+    case 0x4: // Ladebild laden
+    {
+        Text p = pfad.getText();
+        p += "/ladebild.ltdb";
+        if( !DateiExistiert( p ) )
+        {
+            fehler = "Das Ladebild wurde nicht gefunden.";
+            return 0;
+        }
+        LTDBDatei dat;
+        dat.setDatei( p.getThis() );
+        dat.leseDaten( 0 );
+        Bild *b = dat.laden( 0, dat.zBildListe()->get( 0 ) );
+        if( !b )
+        {
+            fehler = "Das Ladebild wurde nicht gefunden.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        int br = b->getBreite();
+        int hi = b->getHeight();
+        zKlient->sendeEncrypted( (char*)&br, 4 );
+        zKlient->sendeEncrypted( (char*)&hi, 4 );
+        char *buffer = (char*)b->getBuffer();
+        __int64 gr = br * hi * 4;
+        for( int i = 0, l = gr > 2048 ? 2048 : (int)gr; gr > 0; i += l, gr -= l, l = gr > 2048 ? 2048 : (int)gr )
+            zKlient->sende( &( buffer[ i ] ), l );
+        b->release();
+        return 1;
+    }
+    case 0x5: // Beschreibung speichern
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        Text p = pfad.getText();
+        p += "/beschreibung.ksgs";
+        Datei d;
+        d.setDatei( p );
+        if( !d.existiert() )
+            d.erstellen();
+        bool ok = d.open( Datei::Style::schreiben );
+        char *buffer = new char[ 2048 ];
+        int gr = 0;
+        zKlient->getNachrichtEncrypted( (char*)&gr, 4 );
+        while( gr > 0 )
+        {
+            int l = gr > 2048 ? 2048 : gr;
+            zKlient->getNachricht( buffer, l );
+            d.schreibe( buffer, l );
+            gr -= l;
+        }
+        delete[] buffer;
+        d.close();
+        if( !ok )
+        {
+            fehler = "Es ist ein Fehler beim schreiben der Beschreibung aufgetreten.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        return 1;
+    }
+    case 0x6: // Titelbild speichern
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        Text p = pfad.getText();
+        p += "/titel.ltdb";
+        int br = 0;
+        int hi = 0;
+        zKlient->getNachrichtEncrypted( (char*)&br, 4 );
+        zKlient->getNachrichtEncrypted( (char*)&hi, 4 );
+        __int64 gr = br * hi * 4;
+        Bild *b = new Bild();
+        b->neuBild( br, hi, 0 );
+        char *buffer = (char*)b->getBuffer();
+        for( int i = 0, l = gr > 2048 ? 2048 : (int)gr; gr > 0; i += l, gr -= l, l = gr > 2048 ? 2048 : (int)gr )
+            zKlient->getNachricht( &( buffer[ i ] ), l );
+        LTDBDatei dat;
+        dat.setDatei( p.getThis() );
+        if( !DateiExistiert( p ) )
+            dat.erstellen();
+        dat.leseDaten( 0 );
+        dat.remove( 0, dat.zBildListe()->get( 0 ) );
+        if( dat.speichern( 0, b, new Text( "titel" ) ) < 0 )
+        {
+            fehler = "Fehler beim speichern des Titelbildes.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        return 1;
+    }
+    case 0x7: // Minimap speichern
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        Text p = pfad.getText();
+        p += "/minimap.ltdb";
+        int br = 0;
+        int hi = 0;
+        zKlient->getNachrichtEncrypted( (char*)&br, 4 );
+        zKlient->getNachrichtEncrypted( (char*)&hi, 4 );
+        __int64 gr = br * hi * 4;
+        Bild *b = new Bild();
+        b->neuBild( br, hi, 0 );
+        char *buffer = (char*)b->getBuffer();
+        for( int i = 0, l = gr > 2048 ? 2048 : (int)gr; gr > 0; i += l, gr -= l, l = gr > 2048 ? 2048 : (int)gr )
+            zKlient->getNachricht( &( buffer[ i ] ), l );
+        LTDBDatei dat;
+        dat.setDatei( p.getThis() );
+        if( !DateiExistiert( p ) )
+            dat.erstellen();
+        dat.leseDaten( 0 );
+        dat.remove( 0, dat.zBildListe()->get( 0 ) );
+        if( dat.speichern( 0, b, new Text( "vorschau" ) ) < 0 )
+        {
+            fehler = "Fehler beim speichern des Minimap Bildes.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        return 1;
+    }
+    case 0x8: // Ladebild speichern
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        Text p = pfad.getText();
+        p += "/ladebild.ltdb";
+        int br = 0;
+        int hi = 0;
+        zKlient->getNachrichtEncrypted( (char*)&br, 4 );
+        zKlient->getNachrichtEncrypted( (char*)&hi, 4 );
+        __int64 gr = br * hi * 4;
+        Bild *b = new Bild();
+        b->neuBild( br, hi, 0 );
+        char *buffer = (char*)b->getBuffer();
+        for( int i = 0, l = gr > 2048 ? 2048 : (int)gr; gr > 0; i += l, gr -= l, l = gr > 2048 ? 2048 : (int)gr )
+            zKlient->getNachricht( &( buffer[ i ] ), l );
+        LTDBDatei dat;
+        dat.setDatei( p.getThis() );
+        if( !DateiExistiert( p ) )
+            dat.erstellen();
+        dat.leseDaten( 0 );
+        dat.remove( 0, dat.zBildListe()->get( 0 ) );
+        if( dat.speichern( 0, b, new Text( "spielladen" ) ) < 0 )
+        {
+            fehler = "Fehler beim speichern des Ladebildes.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        return 1;
+    }
+    default:
+        fehler = "Unbekannte Nachricht. Eventuell ist der Client nicht auf dem neusten Stand.";
+    }
+    return 0;
+}
+
+// constant
+char *BeschreibungEditor::getLetzterFehler() const
+{
+    return fehler;
+}
+
+// Reference Counting
+BeschreibungEditor *BeschreibungEditor::getThis()
+{
+    ref++;
+    return this;
+}
+
+BeschreibungEditor *BeschreibungEditor::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 28 - 0
EditorServer/BeschreibungEditor.h

@@ -0,0 +1,28 @@
+#pragma once
+
+#include <Text.h>
+#include <Server.h>
+
+using namespace Framework;
+using namespace Network;
+
+class BeschreibungEditor
+{
+private:
+    Text pfad;
+    Text fehler;
+    int ref;
+
+public:
+    // Konstruktor
+    BeschreibungEditor( char *pf );
+    // Destruktor
+    ~BeschreibungEditor();
+    // nicht constant
+    bool prozessMessage( SKlient *zKlient );
+    // constant
+    char *getLetzterFehler() const;
+    // Reference Counting
+    BeschreibungEditor *getThis();
+    BeschreibungEditor *release();
+};

+ 1079 - 0
EditorServer/DateienEditor.cpp

@@ -0,0 +1,1079 @@
+#include "DateienEditor.h"
+#include <Datei.h>
+#include <DateiSystem.h>
+#include <Bild.h>
+#include <M2Datei.h>
+#include <iostream>
+#include "GSLDateiV.h"
+#include <Model2D.h>
+#include <unistd.h>
+#define Sleep( x )               usleep( (x) * 1000 )
+#include <dlfcn.h>
+#define LoadLibrary( x )         dlopen( (x), RTLD_LAZY )
+#define GetProcAddress           dlsym
+#define FreeLibrary              dlclose
+#define HMODULE                  void*
+
+typedef GSL::GSLDateiV *( *GetGSLDatei )( );
+
+class DownloadSound : public GSL::GSLSoundV
+{
+private:
+    bool istM;
+    int sample;
+    __int64 len;
+    SKlient *k;
+    int ref;
+    bool ok;
+
+public:
+    // Konstruktor
+    DownloadSound( SKlient *zK )
+    {
+        k = zK;
+        ok = 0;
+        ref = 1;
+    }
+    // nicht constant
+    // GSL
+    void playSound() override
+    {}
+    void setPause( bool p ) override
+    {}
+    void stopSound() override
+    {}
+    void warteAufSound( int zeit ) override
+    {}
+    // Lautstärke: 0 - 0xFFFF
+    void setVolume( unsigned int links, unsigned int rechts ) override
+    {}
+    // zum Speichern
+    void open() override
+    {
+        ok = 1;
+        k->sendeEncrypted( "\1", 1 );
+        char m = 0;
+        k->getNachrichtEncrypted( &m, 1 );
+        istM = ( m == 1 );
+        sample = 0;
+        k->getNachrichtEncrypted( (char*)&sample, 4 );
+        len = 0;
+        k->getNachrichtEncrypted( (char*)&len, 8 );
+    }
+    int getDaten( char *buffer, int len ) override
+    {
+        int l = len < this->len ? len : ( int )this->len;
+        if( !l )
+            return -1;
+        k->getNachricht( buffer, l );
+        this->len -= l;
+        return l;
+    }
+    void close() override
+    {}
+    bool istMono() const override
+    {
+        return istM;
+    }
+    int getSampleRate() const override
+    {
+        return sample;
+    }
+    __int64 getDatLength() const override
+    {
+        return len;
+    }
+    bool istOk() const
+    {
+        return ok;
+    }
+    // Reference Counting
+    GSL::GSLSoundV *getThis() override
+    {
+        ref++;
+        return this;
+    }
+    GSL::GSLSoundV *release() override
+    {
+        ref--;
+        if( !ref )
+            delete this;
+        return 0;
+    }
+};
+
+// Inhalt der DateienEditor Klasse aus DateienEditor.h
+// Konstruktor
+DateienEditor::DateienEditor( char *pf, InitDatei *zIni )
+{
+    this->ini = zIni->getThis();
+    pfad = pf;
+    pfad += "/live/map/client/map/files";
+    workPfad = "";
+    fehler = "";
+    ref = 1;
+}
+
+// Destruktor
+DateienEditor::~DateienEditor()
+{
+    ini->release();
+}
+
+// nicht constant
+bool DateienEditor::prozessMessage( SKlient *zKlient )
+{
+    char message = 0;
+    zKlient->getNachrichtEncrypted( &message, 1 );
+    switch( message )
+    {
+    case 0x1: // Neue Datei erstellen
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char typ = 0;
+        zKlient->getNachrichtEncrypted( &typ, 1 );
+        char len = 0;
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *name = new char[ len + 1 ];
+        if( len )
+            zKlient->getNachrichtEncrypted( name, len );
+        name[ (int)len ] = 0;
+        if( !len )
+        {
+            delete[] name;
+            fehler = "Du musst einen Dateinamen angeben.";
+            return 0;
+        }
+        Text n = name;
+        delete[] name;
+        if( n.hat( "/" ) || n.hat( "." ) )
+        {
+            fehler = "Du musst einen gültigen Dateinamen angeben.";
+            return 0;
+        }
+        Text p = pfad.getText();
+        p += workPfad.getText();
+        p += "/";
+        p += n;
+        if( typ == 0 )
+        {
+            p += "/tmp";
+            if( !DateiPfadErstellen( p ) )
+            {
+                fehler = "Fehler beim erstellen der Datei.";
+                return 0;
+            }
+            DateiRemove( p );
+            p.remove( p.getLength() - 4, p.getLength() );
+            p.ersetzen( p.positionVon( "map/client" ), p.positionVon( "map/client" ) + textLength( "map/client" ), "map/server" );
+            if( !DateiPfadErstellen( p ) )
+            {
+                fehler = "Fehler beim erstellen der Datei.";
+                return 0;
+            }
+            DateiRemove( p );
+            p.remove( p.getLength() - 4, p.getLength() );
+            zKlient->sendeEncrypted( "\1", 1 );
+            return 1;
+        }
+        if( typ == 1 )
+        {
+            p += ".ltdb";
+            if( !DateiPfadErstellen( p ) )
+            {
+                fehler = "Fehler beim erstellen der Datei.";
+                return 0;
+            }
+            zKlient->sendeEncrypted( "\1", 1 );
+            return 1;
+        }
+        if( typ == 2 )
+        {
+            p += ".m2";
+            if( !DateiPfadErstellen( p ) )
+            {
+                fehler = "Fehler beim erstellen der Datei.";
+                return 0;
+            }
+            p.ersetzen( p.positionVon( "map/client" ), p.positionVon( "map/client" ) + textLength( "map/client" ), "map/server" );
+            if( !DateiPfadErstellen( p ) )
+            {
+                fehler = "Fehler beim erstellen der Datei.";
+                return 0;
+            }
+            zKlient->sendeEncrypted( "\1", 1 );
+            return 1;
+        }
+        if( typ == 3 )
+        {
+            p += ".gsl";
+            if( !DateiPfadErstellen( p ) )
+            {
+                fehler = "Fehler beim erstellen der Datei.";
+                return 0;
+            }
+            zKlient->sendeEncrypted( "\1", 1 );
+            return 1;
+        }
+        fehler = "Ungültiger Dateityp.";
+        return 0;
+    }
+    case 0x2: // Ordner open
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char len = 0;
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *name = new char[ len + 1 ];
+        name[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( name, len );
+        if( Text( ".." ).istGleich( name ) )
+        {
+            if( workPfad.getLength() )
+            {
+                int anz = workPfad.anzahlVon( "/" );
+                if( anz )
+                    workPfad.remove( workPfad.positionVon( "/", anz - 1 ), workPfad.getLength() );
+                else
+                    workPfad = "";
+            }
+            delete[] name;
+            zKlient->sendeEncrypted( "\1", 1 );
+            return 1;
+        }
+        else
+        {
+            Text p = pfad.getText();
+            p += workPfad.getText();
+            p += "/";
+            p += name;
+            Datei d;
+            d.setDatei( p );
+            if( !d.existiert() )
+            {
+                delete[] name;
+                fehler = "Die Datei konnte nicht gefunden werden.";
+                return 0;
+            }
+            else
+            {
+                if( d.istOrdner() )
+                {
+                    workPfad += "/";
+                    workPfad += name;
+                }
+                delete[] name;
+                zKlient->sendeEncrypted( "\1", 1 );
+                return 1;
+            }
+        }
+    }
+    case 0x3: // Bild laden
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char len = 0;
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *dName = new char[ len + 1 ];
+        dName[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( dName, len );
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *bName = new char[ len + 1 ];
+        bName[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( bName, len );
+        if( !textLength( dName ) || !textLength( bName ) )
+        {
+            delete[] dName;
+            delete[] bName;
+            fehler = "Du musst ein Bild und eine Datei angeben.";
+            return 0;
+        }
+        Text p = pfad.getText();
+        p += workPfad.getText();
+        p += "/";
+        p += dName;
+        delete[] dName;
+        if( !DateiExistiert( p ) )
+        {
+            delete[] bName;
+            fehler = "Die Datei wurde nicht gefunden.";
+            return 0;
+        }
+        LTDBDatei dat;
+        dat.setDatei( p.getThis() );
+        dat.leseDaten( 0 );
+        Bild *b = dat.laden( 0, new Text( bName ) );
+        delete[] bName;
+        if( !b )
+        {
+            fehler = "Das Bild wurde nicht gefunden.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        int br = b->getBreite();
+        int hi = b->getHeight();
+        zKlient->sendeEncrypted( (char*)&br, 4 );
+        zKlient->sendeEncrypted( (char*)&hi, 4 );
+        char *buffer = (char*)b->getBuffer();
+        __int64 gr = br * hi * 4;
+        for( int i = 0, l = gr > 2048 ? 2048 : (int)gr; gr > 0; i += l, gr -= l, l = gr > 2048 ? 2048 : (int)gr )
+            zKlient->sende( &( buffer[ i ] ), l );
+        b->release();
+        return 1;
+    }
+    case 0x4: // Datei remove
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char len = 0;
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *name = new char[ len + 1 ];
+        name[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( name, len );
+        if( Text( name ).istGleich( ".." ) )
+        {
+            fehler = "Du kannst diese Datei nicht remove.";
+            return 0;
+        }
+        Text p = pfad.getText();
+        p += workPfad.getText();
+        if( !Text( "." ).istGleich( name ) )
+        {
+            p += "/";
+            p += name;
+        }
+        else
+        {
+            int anz = workPfad.anzahlVon( "/" );
+            if( anz )
+                workPfad.remove( workPfad.positionVon( "/", anz - 1 ), workPfad.getLength() );
+            else
+                workPfad = "";
+        }
+        delete[] name;
+        if( !DateiExistiert( p ) )
+        {
+            fehler = "Die Datei wurde nicht gefunden.";
+            return 0;
+        }
+        if( !DateiRemove( p ) )
+        {
+            fehler = "Fehler beim remove der Datei.";
+            return 0;
+        }
+        p.ersetzen( p.positionVon( "map/client" ), p.positionVon( "map/client" ) + textLength( "map/client" ), "map/server" );
+        if( !DateiRemove( p ) )
+        {
+            fehler = "Fehler beim remove der Datei.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        return 1;
+    }
+    case 0x5: // Bild remove
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char len = 0;
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *dName = new char[ len + 1 ];
+        dName[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( dName, len );
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *bName = new char[ len + 1 ];
+        bName[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( bName, len );
+        if( !textLength( dName ) || !textLength( bName ) )
+        {
+            delete[] dName;
+            delete[] bName;
+            fehler = "Du musst ein Bild und eine Datei angeben.";
+            return 0;
+        }
+        Text p = pfad.getText();
+        p += workPfad.getText();
+        p += "/";
+        p += dName;
+        delete[] dName;
+        if( !DateiExistiert( p ) )
+        {
+            delete[] bName;
+            fehler = "Die Datei wurde nicht gefunden.";
+            return 0;
+        }
+        LTDBDatei dat;
+        dat.setDatei( p.getThis() );
+        dat.leseDaten( 0 );
+        dat.remove( 0, new Text( bName ) );
+        delete[] bName;
+        zKlient->sendeEncrypted( "\1", 1 );
+        return 1;
+    }
+    case 0x6: // Bild erstellen
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char len = 0;
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *dName = new char[ len + 1 ];
+        dName[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( dName, len );
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *bName = new char[ len + 1 ];
+        bName[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( bName, len );
+        if( !textLength( dName ) || !textLength( bName ) )
+        {
+            delete[] dName;
+            delete[] bName;
+            fehler = "Du musst ein Bild und eine Datei angeben.";
+            return 0;
+        }
+        Text p = pfad.getText();
+        p += workPfad.getText();
+        p += "/";
+        p += dName;
+        delete[] dName;
+        if( !DateiExistiert( p ) )
+        {
+            delete[] bName;
+            fehler = "Die Datei wurde nicht gefunden.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        int br = 0;
+        int hi = 0;
+        zKlient->getNachrichtEncrypted( (char*)&br, 4 );
+        zKlient->getNachrichtEncrypted( (char*)&hi, 4 );
+        __int64 gr = br * hi * 4;
+        Bild *b = new Bild();
+        b->neuBild( br, hi, 0 );
+        char *buffer = (char*)b->getBuffer();
+        for( int i = 0, l = gr > 2048 ? 2048 : (int)gr; gr > 0; i += l, gr -= l, l = gr > 2048 ? 2048 : (int)gr )
+            zKlient->getNachricht( &( buffer[ i ] ), l );
+        LTDBDatei dat;
+        dat.setDatei( p.getThis() );
+        dat.leseDaten( 0 );
+        dat.remove( 0, new Text( bName ) );
+        if( dat.speichern( 0, b, new Text( bName ) ) < 0 )
+        {
+            delete[] bName;
+            fehler = "Fehler beim speichern des Bildes.";
+            return 0;
+        }
+        delete[] bName;
+        zKlient->sendeEncrypted( "\1", 1 );
+        return 1;
+    }
+    case 0x7: // Datei Liste herunterladen
+    {
+        Datei d;
+        d.setDatei( Text( pfad.getText() ) += workPfad.getText() );
+        RCArray< Text > *list = d.getDateiListe();
+        zKlient->sendeEncrypted( "\1", 1 );
+        int anz = list ? list->getEintragAnzahl() : 0;
+        if( workPfad.getLength() )
+            anz++;
+        zKlient->sendeEncrypted( (char*)&anz, 4 );
+        if( workPfad.getLength() )
+        {
+            zKlient->sendeEncrypted( "\2", 1 );
+            zKlient->sendeEncrypted( "..", 2 );
+            anz--;
+        }
+        for( int i = 0; i < anz; i++ )
+        {
+            char len = (char)list->z( i )->getLength();
+            zKlient->sendeEncrypted( &len, 1 );
+            zKlient->sendeEncrypted( list->z( i )->getText(), len );
+        }
+        if( list )
+            list->release();
+        return 1;
+    }
+    case 0x8: // Bild Liste herunterladen
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char len = 0;
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *name = new char[ len + 1 ];
+        name[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( name, len );
+        if( !textLength( name ) )
+        {
+            delete[] name;
+            fehler = "Du musst eine Datei angeben.";
+            return 0;
+        }
+        Text p = pfad.getText();
+        p += workPfad.getText();
+        p += "/";
+        p += name;
+        delete[] name;
+        if( !DateiExistiert( p ) )
+        {
+            fehler = "Die Datei wurde nicht gefunden.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        LTDBDatei dat;
+        dat.setDatei( p.getThis() );
+        dat.leseDaten( 0 );
+        int anz = dat.getBildAnzahl();
+        zKlient->sendeEncrypted( (char*)&anz, 4 );
+        for( int i = 0; i < anz; i++ )
+        {
+            char len = (char)dat.zBildListe()->z( i )->getLength();
+            zKlient->sendeEncrypted( &len, 1 );
+            zKlient->sendeEncrypted( dat.zBildListe()->z( i )->getText(), len );
+        }
+        return 1;
+    }
+    case 0x9: // Modell Liste herunterladen
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char len = 0;
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *name = new char[ len + 1 ];
+        name[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( name, len );
+        if( !textLength( name ) )
+        {
+            delete[] name;
+            fehler = "Du musst eine Datei angeben.";
+            return 0;
+        }
+        Text p = pfad.getText();
+        p += workPfad.getText();
+        p += "/";
+        p += name;
+        delete[] name;
+        if( !DateiExistiert( p ) )
+        {
+            fehler = "Die Datei wurde nicht gefunden.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        M2Datei dat;
+        dat.setPfad( p );
+        dat.leseDaten();
+        int anz = dat.getModelAnzahl();
+        zKlient->sendeEncrypted( (char*)&anz, 4 );
+        for( int i = 0; i < anz; i++ )
+        {
+            char len = (char)dat.zModelName( i )->getLength();
+            zKlient->sendeEncrypted( &len, 1 );
+            zKlient->sendeEncrypted( dat.zModelName( i )->getText(), len );
+        }
+        return 1;
+    }
+    case 0xA: // Sound Liste herunterlaen
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char len = 0;
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *name = new char[ len + 1 ];
+        name[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( name, len );
+        if( !textLength( name ) )
+        {
+            delete[] name;
+            fehler = "Du musst eine Datei angeben.";
+            return 0;
+        }
+        Text p = pfad.getText();
+        p += workPfad.getText();
+        p += "/";
+        p += name;
+        delete[] name;
+        if( !DateiExistiert( p ) )
+        {
+            fehler = "Die Datei wurde nicht gefunden.";
+            return 0;
+        }
+        HMODULE gslDLL = LoadLibrary( ini->zWert( "gslPfad" )->getText() );
+        if( !gslDLL )
+        {
+            fehler = "Interner Server Fehler.";
+            std::cout << "EdS: Fehler beim laden von '" << ini->zWert( "gslPfad" )->getText() << "'.\n";
+            return 0;
+        }
+        GetGSLDatei getGSLDatei = (GetGSLDatei)GetProcAddress( gslDLL, "getGSLDatei" );
+        if( !getGSLDatei )
+        {
+            fehler = "Interner Server Fehler.";
+            std::cout << "EdS: Der Einstiegspunkt 'getGSLDatei' wurde in der Datei '" << ini->zWert( "gslPfad" )->getText() << "' nicht gefunden.\n";
+            return 0;
+        }
+        GSL::GSLDateiV *gslDatei = getGSLDatei();
+        zKlient->sendeEncrypted( "\1", 1 );
+        gslDatei->setDatei( p );
+        gslDatei->leseDaten();
+        int anz = gslDatei->getSoundAnzahl();
+        zKlient->sendeEncrypted( (char*)&anz, 4 );
+        for( int i = 0; i < anz; i++ )
+        {
+            Text *n = gslDatei->getSoundName( i );
+            char len = (char)n->getLength();
+            zKlient->sendeEncrypted( &len, 1 );
+            zKlient->sendeEncrypted( n->getText(), len );
+            n->release();
+        }
+        gslDatei->release();
+        FreeLibrary( gslDLL );
+        return 1;
+    }
+    case 0xB: // Modell remove
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char len = 0;
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *name = new char[ len + 1 ];
+        name[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( name, len );
+        if( !textLength( name ) )
+        {
+            delete[] name;
+            fehler = "Du musst eine Datei angeben.";
+            return 0;
+        }
+        Text p = pfad.getText();
+        p += workPfad.getText();
+        p += "/";
+        p += name;
+        delete[] name;
+        if( !DateiExistiert( p ) )
+        {
+            fehler = "Die Datei wurde nicht gefunden.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        name = new char[ len + 1 ];
+        name[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( name, len );
+        M2Datei dat;
+        dat.setPfad( p );
+        dat.leseDaten();
+        if( !textLength( name ) || !dat.removeModel( name ) )
+        {
+            delete[] name;
+            fehler = "Das Modell wurde nicht gefunden.";
+            return 0;
+        }
+        p.ersetzen( p.positionVon( "map/client" ), p.positionVon( "map/client" ) + textLength( "map/client" ), "map/server" );
+        dat.setPfad( p );
+        dat.leseDaten();
+        if( !textLength( name ) || !dat.removeModel( name ) )
+        {
+            delete[] name;
+            fehler = "Das Modell wurde nicht gefunden.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        delete[] name;
+        return 1;
+    }
+    case 0xC: // Sound remove
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char len = 0;
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *name = new char[ len + 1 ];
+        name[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( name, len );
+        if( !textLength( name ) )
+        {
+            delete[] name;
+            fehler = "Du musst eine Datei angeben.";
+            return 0;
+        }
+        Text p = pfad.getText();
+        p += workPfad.getText();
+        p += "/";
+        p += name;
+        delete[] name;
+        if( !DateiExistiert( p ) )
+        {
+            fehler = "Die Datei wurde nicht gefunden.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        name = new char[ len + 1 ];
+        name[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( name, len );
+        HMODULE gslDLL = LoadLibrary( ini->zWert( "gslPfad" )->getText() );
+        if( !gslDLL )
+        {
+            fehler = "Interner Server Fehler.";
+            std::cout << "EdS: Fehler beim laden von '" << ini->zWert( "gslPfad" )->getText() << "'.\n";
+            return 0;
+        }
+        GetGSLDatei getGSLDatei = (GetGSLDatei)GetProcAddress( gslDLL, "getGSLDatei" );
+        if( !getGSLDatei )
+        {
+            fehler = "Interner Server Fehler.";
+            std::cout << "EdS: Der Einstiegspunkt 'getGSLDatei' wurde in der Datei '" << ini->zWert( "gslPfad" )->getText() << "' nicht gefunden.\n";
+            return 0;
+        }
+        GSL::GSLDateiV *gslDatei = getGSLDatei();
+        gslDatei->setDatei( p );
+        gslDatei->leseDaten();
+        if( !textLength( name ) || !gslDatei->removeSound( name ) )
+        {
+            fehler = "Das Modell wurde nicht gefunden.";
+            delete[] name;
+            gslDatei->release();
+            FreeLibrary( gslDLL );
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        delete[] name;
+        gslDatei->release();
+        FreeLibrary( gslDLL );
+        return 1;
+    }
+    case 0xD: // Modell laden
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char len = 0;
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *name = new char[ len + 1 ];
+        name[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( name, len );
+        if( !textLength( name ) )
+        {
+            delete[] name;
+            fehler = "Du musst eine Datei angeben.";
+            return 0;
+        }
+        Text p = pfad.getText();
+        p += workPfad.getText();
+        p += "/";
+        p += name;
+        delete[] name;
+        if( !DateiExistiert( p ) )
+        {
+            fehler = "Die Datei wurde nicht gefunden.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        name = new char[ len + 1 ];
+        name[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( name, len );
+        M2Datei dat;
+        dat.setPfad( p );
+        dat.leseDaten();
+        Model2DData *mdl;
+        if( !textLength( name ) || !( mdl = dat.ladeModel( name ) ) )
+        {
+            delete[] name;
+            fehler = "Das Modell wurde nicht gefunden.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        int anz = mdl->polygons ? mdl->polygons->getEintragAnzahl() : 0;
+        zKlient->sendeEncrypted( (char*)&anz, 4 );
+        for( int i = 0; i < anz; i++ )
+        {
+            Polygon2D pol = mdl->polygons->get( i );
+            int anz2 = pol.vertex ? pol.vertex->getEintragAnzahl() : 0;
+            zKlient->sendeEncrypted( (char*)&anz2, 4 );
+            for( int j = 0; j < anz2; j++ )
+            {
+                float var = pol.vertex->get( j ).x;
+                zKlient->sendeEncrypted( (char*)&var, 4 );
+                var = pol.vertex->get( j ).y;
+                zKlient->sendeEncrypted( (char*)&var, 4 );
+                int ivar = ( pol.tKordinaten && pol.tKordinaten->hat( j ) ) ? pol.tKordinaten->get( j ).x : 0;
+                zKlient->sendeEncrypted( (char*)&ivar, 4 );
+                ivar = ( pol.tKordinaten && pol.tKordinaten->hat( j ) ) ? pol.tKordinaten->get( j ).y : 0;
+                zKlient->sendeEncrypted( (char*)&ivar, 4 );
+            }
+        }
+        mdl->release();
+        delete[] name;
+        return 1;
+    }
+    case 0xE: // Sound laden
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char len = 0;
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *name = new char[ len + 1 ];
+        name[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( name, len );
+        if( !textLength( name ) )
+        {
+            delete[] name;
+            fehler = "Du musst eine Datei angeben.";
+            return 0;
+        }
+        Text p = pfad.getText();
+        p += workPfad.getText();
+        p += "/";
+        p += name;
+        delete[] name;
+        if( !DateiExistiert( p ) )
+        {
+            fehler = "Die Datei wurde nicht gefunden.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        name = new char[ len + 1 ];
+        name[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( name, len );
+        HMODULE gslDLL = LoadLibrary( ini->zWert( "gslPfad" )->getText() );
+        if( !gslDLL )
+        {
+            fehler = "Interner Server Fehler.";
+            std::cout << "EdS: Fehler beim laden von '" << ini->zWert( "gslPfad" )->getText() << "'.\n";
+            return 0;
+        }
+        GetGSLDatei getGSLDatei = (GetGSLDatei)GetProcAddress( gslDLL, "getGSLDatei" );
+        if( !getGSLDatei )
+        {
+            fehler = "Interner Server Fehler.";
+            std::cout << "EdS: Der Einstiegspunkt 'getGSLDatei' wurde in der Datei '" << ini->zWert( "gslPfad" )->getText() << "' nicht gefunden.\n";
+            return 0;
+        }
+        GSL::GSLDateiV *gslDatei = getGSLDatei();
+        gslDatei->setDatei( p );
+        gslDatei->leseDaten();
+        GSL::GSLSoundV *sound;
+        if( !textLength( name ) || !( sound = gslDatei->getSound( name ) ) )
+        {
+            delete[] name;
+            gslDatei->release();
+            FreeLibrary( gslDLL );
+            fehler = "Das Modell wurde nicht gefunden.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        char channels = sound->istMono() ? 1 : 2;
+        zKlient->sendeEncrypted( &channels, 1 );
+        int sample = sound->getSampleRate();
+        zKlient->sendeEncrypted( (char*)&sample, 4 );
+        __int64 length = sound->getDatLength();
+        zKlient->sendeEncrypted( (char*)&length, 8 );
+        sound->open();
+        char *buffer = new char[ 2048 ];
+        while( length > 0 )
+        {
+            int l = length > 2048 ? 2048 : (int)length;
+            sound->getDaten( buffer, l );
+            zKlient->sende( buffer, l );
+			length -= l;
+        }
+        delete[] buffer;
+        sound->close();
+        sound->release();
+        gslDatei->release();
+        FreeLibrary( gslDLL );
+        delete[] name;
+        return 1;
+    }
+    case 0xF: // Modell erstellen
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char len = 0;
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *name = new char[ len + 1 ];
+        name[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( name, len );
+        if( !textLength( name ) )
+        {
+            delete[] name;
+            fehler = "Du musst eine Datei angeben.";
+            return 0;
+        }
+        Text p = pfad.getText();
+        p += workPfad.getText();
+        p += "/";
+        p += name;
+        delete[] name;
+        if( !DateiExistiert( p ) )
+        {
+            fehler = "Die Datei wurde nicht gefunden.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        name = new char[ len + 1 ];
+        name[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( name, len );
+        M2Datei dat;
+        dat.setPfad( p );
+        dat.leseDaten();
+        dat.removeModel( name );
+        if( !textLength( name ) )
+        {
+            delete[] name;
+            fehler = "Du musst einen Namen eingeben.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        Model2DData *mdl = new Model2DData();
+        Array< Polygon2D > *data = new Array< Polygon2D >();
+        int anz = 0;
+        zKlient->getNachrichtEncrypted( (char*)&anz, 4 );
+        for( int i = 0; i < anz; i++ )
+        {
+            Polygon2D pol;
+            pol.vertex = new Array< Vertex >();
+            pol.tKordinaten = new Array< Punkt >();
+            int anz2 = 0;
+            zKlient->getNachrichtEncrypted( (char*)&anz2, 4 );
+            for( int j = 0; j < anz2; j++ )
+            {
+                Vertex v;
+                Punkt p;
+                zKlient->getNachrichtEncrypted( (char*)&v.x, 4 );
+                zKlient->getNachrichtEncrypted( (char*)&v.y, 4 );
+                zKlient->getNachrichtEncrypted( (char*)&p.x, 4 );
+                zKlient->getNachrichtEncrypted( (char*)&p.y, 4 );
+                pol.vertex->add( v );
+                pol.tKordinaten->add( p );
+            }
+            data->add( pol );
+        }
+        if( !mdl->erstelleModell( data ) || !dat.saveModel( mdl, name ) )
+        {
+            mdl->release();
+            delete[] name;
+            fehler = "Fehler beim speichern des Modells.";
+            return 0;
+        }
+        p.ersetzen( p.positionVon( "map/client" ), p.positionVon( "map/client" ) + textLength( "map/client" ), "map/server" );
+        dat.setPfad( p );
+        dat.leseDaten();
+        dat.removeModel( name );
+        if( !dat.saveModel( mdl, name ) )
+        {
+            mdl->release();
+            delete[] name;
+            fehler = "Fehler beim speichern des Modells.";
+            return 0;
+        }
+        mdl->release();
+        zKlient->sendeEncrypted( "\1", 1 );
+        delete[] name;
+        return 1;
+    }
+    case 0x10: // Sound erstellen
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char len = 0;
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *name = new char[ len + 1 ];
+        name[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( name, len );
+        if( !textLength( name ) )
+        {
+            delete[] name;
+            fehler = "Du musst eine Datei angeben.";
+            return 0;
+        }
+        Text p = pfad.getText();
+        p += workPfad.getText();
+        p += "/";
+        p += name;
+        delete[] name;
+        if( !DateiExistiert( p ) )
+        {
+            fehler = "Die Datei wurde nicht gefunden.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        name = new char[ len + 1 ];
+        name[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( name, len );
+        HMODULE gslDLL = LoadLibrary( ini->zWert( "gslPfad" )->getText() );
+        if( !gslDLL )
+        {
+            fehler = "Interner Server Fehler.";
+            std::cout << "EdS: Fehler beim laden von '" << ini->zWert( "gslPfad" )->getText() << "'.\n";
+            return 0;
+        }
+        GetGSLDatei getGSLDatei = (GetGSLDatei)GetProcAddress( gslDLL, "getGSLDatei" );
+        if( !getGSLDatei )
+        {
+            fehler = "Interner Server Fehler.";
+            std::cout << "EdS: Der Einstiegspunkt 'getGSLDatei' wurde in der Datei '" << ini->zWert( "gslPfad" )->getText() << "' nicht gefunden.\n";
+            return 0;
+        }
+        GSL::GSLDateiV *gslDatei = getGSLDatei();
+        gslDatei->setDatei( p );
+        gslDatei->leseDaten();
+        gslDatei->removeSound( name );
+        if( !textLength( name ) )
+        {
+            delete[] name;
+            gslDatei->release();
+            FreeLibrary( gslDLL );
+            fehler = "Du musst einen Namen eingeben.";
+            return 0;
+        }
+        DownloadSound dws( zKlient );
+        gslDatei->speicherSound( &dws, name );
+        if( !dws.istOk() )
+        {
+            delete[] name;
+            gslDatei->release();
+            FreeLibrary( gslDLL );
+            fehler = "Es ist ein Fehler beim speichern aufgetreten.";
+            return 0;
+        }
+        gslDatei->release();
+        FreeLibrary( gslDLL );
+        delete[] name;
+        return 1;
+    }
+    default:
+        fehler = "Unbekannte Nachricht. Eventuell ist der Client nicht auf dem neusten Stand.";
+    }
+    return 0;
+}
+
+// constant
+char *DateienEditor::getLetzterFehler() const
+{
+    return fehler;
+}
+
+// Reference Counting
+DateienEditor *DateienEditor::getThis()
+{
+    ref++;
+    return this;
+}
+
+DateienEditor *DateienEditor::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 31 - 0
EditorServer/DateienEditor.h

@@ -0,0 +1,31 @@
+#pragma once
+
+#include <Text.h>
+#include <Server.h>
+#include <InitDatei.h>
+
+using namespace Framework;
+using namespace Network;
+
+class DateienEditor
+{
+private:
+    Text pfad;
+    Text workPfad;
+    Text fehler;
+    InitDatei *ini;
+    int ref;
+
+public:
+    // Konstruktor
+    DateienEditor( char *pf, InitDatei *zIni );
+    // Destruktor
+    ~DateienEditor();
+    // nicht constant
+    bool prozessMessage( SKlient *zKlient );
+    // constant
+    char *getLetzterFehler() const;
+    // Reference Counting
+    DateienEditor *getThis();
+    DateienEditor *release();
+};

+ 672 - 0
EditorServer/Datenbank.cpp

@@ -0,0 +1,672 @@
+#include "Datenbank.h"
+#include <Zeit.h>
+
+// Inhalt der LSDatenbank Klasse aus Datenbank.h
+// Konstruktor
+EdSDatenbank::EdSDatenbank( InitDatei *zIni )
+{
+    if( !zIni->wertExistiert( "DBBenutzer" ) )
+        zIni->addWert( "DBBenutzer", "editorserveru" );
+    if( !zIni->wertExistiert( "DBPasswort" ) )
+        zIni->addWert( "DBPasswort", "LTEditorServerPW" );
+    if( !zIni->wertExistiert( "DBName" ) )
+        zIni->addWert( "DBName", "koljadb" );
+    if( !zIni->wertExistiert( "DBIP" ) )
+        zIni->addWert( "DBIP", "127.0.0.1" );
+    if( !zIni->wertExistiert( "DBPort" ) )
+        zIni->addWert( "DBPort", "5432" );
+    datenbank = new Datenbank( zIni->zWert( "DBBenutzer" )->getText(), zIni->zWert( "DBPasswort" )->getText(),
+                               zIni->zWert( "DBName" )->getText(), zIni->zWert( "DBIP" )->getText(),
+                               (unsigned short)TextZuInt( zIni->zWert( "DBPort" )->getText(), 10 ) );
+    InitializeCriticalSection( &cs );
+    ref = 1;
+}
+
+// Destruktor
+EdSDatenbank::~EdSDatenbank()
+{
+    datenbank->release();
+    DeleteCriticalSection( &cs );
+}
+
+// nicht constant
+void EdSDatenbank::lock()
+{
+    EnterCriticalSection( &cs );
+}
+
+void EdSDatenbank::unlock()
+{
+    LeaveCriticalSection( &cs );
+}
+
+int EdSDatenbank::istAdministrator( const char *name, const char *passwort )
+{
+    Text *befehl = new Text( "SELECT id FROM benutzer WHERE name = '" );
+    befehl->append( name );
+    befehl->append( "' AND passwort = '" );
+    befehl->append( passwort );
+    befehl->append( "'" );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    int ret = 0;
+    if( res.zeilenAnzahl > 0 )
+        ret = TextZuInt( res.values[ 0 ].getText(), 10 );
+    res.destroy();
+    return ret;
+}
+
+bool EdSDatenbank::adminHatRecht( int id, int recht )
+{
+    Text *befehl = new Text( "SELECT * FROM benutzer_rechte WHERE benutzer_id = " );
+    befehl->append( id );
+    befehl->append( " AND rechte_id = " );
+    befehl->append( recht );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    int ret = datenbank->getZeilenAnzahl();
+    unlock();
+    befehl->release();
+    return ret != 0;
+}
+
+bool EdSDatenbank::proveKlient( int num, int sNum )
+{
+    Text *befehl = new Text( "SELECT * FROM server_editor_clients WHERE server_editor_id = " );
+    befehl->append( sNum );
+    befehl->append( " AND client_id = " );
+    befehl->append( num );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    bool ret = 0;
+    if( res.zeilenAnzahl == 1 )
+        ret = 1;
+    res.destroy();
+    return ret;
+}
+
+Text *EdSDatenbank::getKlientKey( int cId )
+{
+    lock();
+    if( !datenbank->befehl( Text( "SELECT schluessel FROM clients WHERE id = " ) += cId ) )
+    {
+        unlock();
+        return 0;
+    }
+    Result res = datenbank->getResult();
+    unlock();
+    if( !res.zeilenAnzahl )
+    {
+        res.destroy();
+        return 0;
+    }
+    Text *ret = new Text( res.values[ 0 ].getText() );
+    res.destroy();
+    return ret;
+}
+
+void EdSDatenbank::unregisterKlient( int num, int sNum )
+{
+    Text *befehl = new Text( "DELETE FROM server_editor_clients WHERE client_id = " );
+    befehl->append( num );
+    befehl->append( " AND server_editor_id = " );
+    befehl->append( sNum );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    unlock();
+    befehl->release();
+}
+
+bool EdSDatenbank::serverAnmelden( InitDatei *zIni )
+{
+    if( !zIni->wertExistiert( "ServerId" ) )
+        zIni->addWert( "ServerId", "0" );
+    if( !zIni->wertExistiert( "ServerName" ) )
+        zIni->addWert( "ServerName", "Name" );
+    if( !zIni->wertExistiert( "ServerPort" ) )
+        zIni->addWert( "ServerPort", "49144" );
+    if( !zIni->wertExistiert( "ServerIP" ) )
+        zIni->addWert( "ServerIP", "127.0.0.1" );
+    if( !zIni->wertExistiert( "AdminServerPort" ) )
+        zIni->addWert( "AdminServerPort", "49143" );
+    if( !zIni->wertExistiert( "Aktiv" ) )
+        zIni->addWert( "Aktiv", "FALSE" );
+    if( !zIni->wertExistiert( "MaxKarten" ) )
+        zIni->addWert( "MaxKarten", "50" );
+    bool insert = 0;
+    int id = *zIni->zWert( "ServerId" );
+    if( id )
+    {
+        lock();
+        if( !datenbank->befehl( Text( "SELECT id FROM server_editor WHERE id = " ) += id ) )
+        {
+            unlock();
+            return 0;
+        }
+        int anz = datenbank->getZeilenAnzahl();
+        unlock();
+        insert = anz == 0;
+        if( !insert )
+        {
+            lock();
+            if( !datenbank->befehl( Text( "SELECT id FROM server_editor WHERE server_status_id = 1 AND id = " ) += id ) )
+            {
+                unlock();
+                return 0;
+            }
+            int anz = datenbank->getZeilenAnzahl();
+            unlock();
+            if( !anz ) // Server läuft bereits
+                return 0;
+        }
+    }
+    if( insert || !id )
+    { // Neuer Eintrag in Tabelle server_editor
+        Text *befehl = new Text( "INSERT INTO server_editor( " );
+        if( id )
+            *befehl += "id, ";
+        *befehl += "name, ip, port, admin_port, server_status_id, max_karten ) VALUES( ";
+        if( id )
+        {
+            *befehl += id;
+            *befehl += ", ";
+        }
+        *befehl += "'";
+        *befehl += zIni->zWert( "ServerName" )->getText();
+        *befehl += "', '";
+        *befehl += zIni->zWert( "ServerIP" )->getText();
+        *befehl += "', ";
+        *befehl += zIni->zWert( "ServerPort" )->getText();
+        *befehl += ", ";
+        *befehl += zIni->zWert( "AdminServerPort" )->getText();
+        *befehl += ", 1, ";
+        *befehl += zIni->zWert( "MaxKarten" )->getText();
+        *befehl += " ) RETURNING id";
+        lock();
+        if( !datenbank->befehl( *befehl ) )
+        {
+            unlock();
+            befehl->release();
+            return 0;
+        }
+        Result res = datenbank->getResult();
+        unlock();
+        befehl->release();
+        if( !res.zeilenAnzahl )
+        {
+            res.destroy();
+            return 0;
+        }
+        zIni->setWert( "ServerId", res.values[ 0 ] );
+        return 1;
+    }
+    else
+    { // Alten Eintrag aus Tabelle server_editor ändern
+        Text *befehl = new Text( "UPDATE server_editor SET name = '" );
+        *befehl += zIni->zWert( "ServerName" )->getText();
+        *befehl += "', port = ";
+        *befehl += zIni->zWert( "ServerPort" )->getText();
+        *befehl += ", ip = '";
+        *befehl += zIni->zWert( "ServerIP" )->getText();
+        *befehl += "', max_karten = ";
+        *befehl += zIni->zWert( "MaxKarten" )->getText();
+        *befehl += ", admin_port = ";
+        *befehl += zIni->zWert( "AdminServerPort" )->getText();
+        *befehl += " WHERE id = ";
+        *befehl += id;
+        lock();
+        bool ret = datenbank->befehl( *befehl );
+        unlock();
+        befehl->release();
+        return ret;
+    }
+}
+
+bool EdSDatenbank::setServerStatus( int id, int status )
+{
+    Text *befehl = new Text( "UPDATE server_editor SET server_status_id = " );
+    *befehl += status;
+    *befehl += "WHERE id = ";
+    *befehl += id;
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    bool ret = datenbank->getZeilenAnzahl() != 0;
+    unlock();
+    befehl->release();
+    return ret;
+}
+
+bool EdSDatenbank::setMaxKarten( int id, int maxK )
+{
+    Text *befehl = new Text( "UPDATE server_editor SET max_karten = " );
+    befehl->append( maxK );
+    befehl->append( " WHERE id = " );
+    befehl->append( id );
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    bool ret = datenbank->getZeilenAnzahl() > 0;
+    unlock();
+    befehl->release();
+    return ret;
+}
+
+int EdSDatenbank::getAdminPort( int id )
+{
+    Text *befehl = new Text( "SELECT admin_port FROM server_editor WHERE id = " );
+    befehl->append( id );
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    if( !res.zeilenAnzahl )
+    {
+        res.destroy();
+        return 0;
+    }
+    int ret = TextZuInt( res.values[ 0 ].getText(), 10 );
+    res.destroy();
+    return ret;
+}
+
+bool EdSDatenbank::serverIstNichtPausiert( int id )
+{
+    Text *befehl = new Text( "SELECT server_status_id FROM server_editor WHERE id = " );
+    befehl->append( id );
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    if( !res.zeilenAnzahl )
+    {
+        res.destroy();
+        return 0;
+    }
+    bool ret = (int)res.values[ 0 ] == 3;
+    res.destroy();
+    return ret;
+}
+
+Text *EdSDatenbank::getKarteName( int id )
+{
+    Text befehl = "SELECT name FROM karte WHERE id = ";
+    befehl += id;
+    lock();
+    if( !datenbank->befehl( befehl ) )
+    {
+        unlock();
+        return 0;
+    }
+    Result res = datenbank->getResult();
+    unlock();
+    if( !res.zeilenAnzahl )
+    {
+        res.destroy();
+        return 0;
+    }
+    Text *ret = new Text( res.values[ 0 ] );
+    res.destroy();
+    return ret;
+}
+
+bool EdSDatenbank::proveKarte( int id, int cId, int sNum )
+{
+    Text befehl = "SELECT a.id FROM karte a, account_clients b WHERE a.id = ";
+    befehl += id;
+    befehl += " AND a.account_id = b.account_id AND b.client_id = ";
+    befehl += cId;
+    befehl += " AND a.server_editor_id = ";
+    befehl += sNum;
+    lock();
+    if( !datenbank->befehl( befehl ) )
+    {
+        unlock();
+        return 0;
+    }
+    bool ret = datenbank->getZeilenAnzahl() != 0;
+    unlock();
+    return ret;
+}
+
+bool EdSDatenbank::istKarteInUpdate( int id )
+{
+    Text befehl = "SELECT erlaubt FROM karte WHERE id = ";
+    befehl += id;
+    lock();
+    if( !datenbank->befehl( befehl ) )
+    {
+        unlock();
+        return 0;
+    }
+    Result res = datenbank->getResult();
+    unlock();
+    if( !res.zeilenAnzahl )
+    {
+        res.destroy();
+        return 0;
+    }
+    bool ret = res.values[ 0 ].istGleich( "f" );
+    res.destroy();
+    return ret;
+}
+
+bool EdSDatenbank::startKarteUpdate( int id )
+{
+    Text befehl = "SELECT karte_update_begin( ";
+    befehl += id;
+    befehl += " )";
+    lock();
+    if( !datenbank->befehl( befehl ) )
+    {
+        unlock();
+        return 0;
+    }
+    Result res = datenbank->getResult();
+    unlock();
+    if( !res.zeilenAnzahl )
+    {
+        res.destroy();
+        return 0;
+    }
+    bool ret = res.values[ 0 ].istGleich( "t" );
+    res.destroy();
+    return ret;
+}
+
+bool EdSDatenbank::startShopUpdate( int id )
+{
+    Text befehl = "SELECT karte_shop_update_begin( ";
+    befehl += id;
+    befehl += " )";
+    lock();
+    if( !datenbank->befehl( befehl ) )
+    {
+        unlock();
+        return 0;
+    }
+    Result res = datenbank->getResult();
+    unlock();
+    if( !res.zeilenAnzahl )
+    {
+        res.destroy();
+        return 0;
+    }
+    bool ret = res.values[ 0 ].istGleich( "t" );
+    res.destroy();
+    return ret;
+}
+
+bool EdSDatenbank::getKarteShopDaten( int karte, int &es, int &tp, int &vp )
+{
+    es = 0;
+    tp = 0;
+    vp = 0;
+    Text befehl = "SELECT karte_account_status_id, kupfer FROM karte_kauf_erlaubt WHERE karte_id = ";
+    befehl += karte;
+    lock();
+    if( !datenbank->befehl( befehl ) )
+    {
+        unlock();
+        return 0;
+    }
+    Result r = datenbank->getResult();
+    unlock();
+    for( int i = 0; i < r.zeilenAnzahl; i++ )
+    {
+        if( (int)r.values[ i * 2 ] == 1 )
+        {
+            es |= 1;
+            tp = r.values[ i * 2 + 1 ];
+        }
+        if( (int)r.values[ i * 2 ] == 2 )
+        {
+            es |= 2;
+            vp = r.values[ i * 2 + 1 ];
+        }
+    }
+    r.destroy();
+    return 1;
+}
+
+bool EdSDatenbank::setKarteShopDaten( int karte, int es, int tp, int vp )
+{
+    Text befehl = "SELECT karte_account_status_id, kupfer FROM karte_kauf_erlaubt WHERE karte_id = ";
+    befehl += karte;
+    lock();
+    if( !datenbank->befehl( befehl ) )
+    {
+        unlock();
+        return 0;
+    }
+    Result r = datenbank->getResult();
+    unlock();
+    int esAlt = 0;
+    int tpAlt = 0;
+    int vpAlt = 0;
+    for( int i = 0; i < r.zeilenAnzahl; i++ )
+    {
+        if( (int)r.values[ i * 2 ] == 1 )
+        {
+            esAlt |= 1;
+            tpAlt = r.values[ i * 2 + 1 ];
+        }
+        if( (int)r.values[ i * 2 ] == 2 )
+        {
+            esAlt |= 2;
+            vpAlt = r.values[ i * 2 + 1 ];
+        }
+    }
+    r.destroy();
+    if( esAlt != es )
+    {
+        for( int i = 1; i < 3; i++ )
+        {
+            if( ( esAlt | i ) != esAlt && ( es | i ) == es )
+            {
+                befehl = "INSERT INTO karte_kauf_erlaubt( karte_id, karte_account_status_id, kupfer ) VALUES( ";
+                befehl += karte;
+                befehl += ", ";
+                befehl += i;
+                befehl += ", ";
+                if( i == 1 )
+                    befehl += tp;
+                if( i == 2 )
+                    befehl += vp;
+                befehl += " )";
+                lock();
+                if( !datenbank->befehl( befehl ) )
+                {
+                    unlock();
+                    return 0;
+                }
+                unlock();
+            }
+            else if( ( esAlt | i ) == esAlt && ( es | i ) != es )
+            {
+                befehl = "DELETE FROM karte_kauf_erlaubt WHERE karte_id = ";
+                befehl += karte;
+                befehl += " AND karte_account_status_id = ";
+                befehl += i;
+                lock();
+                if( !datenbank->befehl( befehl ) )
+                {
+                    unlock();
+                    return 0;
+                }
+                unlock();
+            }
+            else if( ( i == 1 && tpAlt != tp ) || ( i == 2 && vpAlt != vp ) )
+            {
+                befehl = "UPDATE karte_kauf_erlaubt SET kupfer = ";
+                if( i == 1 )
+                    befehl += tp;
+                if( i == 2 )
+                    befehl += vp;
+                befehl += " WHERE karte_id = ";
+                befehl += karte;
+                befehl += " AND karte_account_status_id = ";
+                befehl += i;
+                lock();
+                if( !datenbank->befehl( befehl ) )
+                {
+                    unlock();
+                    return 0;
+                }
+                unlock();
+            }
+        }
+    }
+    return 1;
+}
+
+bool EdSDatenbank::setMaxSpieler( int karte, int spieler )
+{
+    Text befehl = "UPDATE karte SET max_spieler = ";
+    befehl += spieler;
+    befehl = " WHERE id = ";
+    befehl += karte;
+    lock();
+    if( !datenbank->befehl( befehl ) )
+    {
+        unlock();
+        return 0;
+    }
+    unlock();
+    return 1;
+}
+
+bool EdSDatenbank::karteErstellen( const char *name, int spielArt, int klient )
+{
+    Text befehl = "SELECT id FROM spiel_art WHERE editor_erlaubt = TRUE AND id = ";
+    befehl += spielArt;
+    lock();
+    if( !datenbank->befehl( befehl ) || !datenbank->getZeilenAnzahl() )
+    {
+        unlock();
+        return 0;
+    }
+    unlock();
+    befehl = "SELECT account_id FROM account_clients WHERE client_id = ";
+    befehl = klient;
+    lock();
+    if( !datenbank->befehl( befehl ) )
+    {
+        unlock();
+        return 0;
+    }
+    Result r = datenbank->getResult();
+    unlock();
+    if( !r.zeilenAnzahl )
+    {
+        r.destroy();
+        return 0;
+    }
+    int acc = r.values[ 0 ];
+    r.destroy();
+    befehl = "SELECT such_karten_server()";
+    lock();
+    if( !datenbank->befehl( befehl ) )
+    {
+        unlock();
+        return 0;
+    }
+    r = datenbank->getResult();
+    unlock();
+    if( r.zeilenAnzahl != 3 )
+    {
+        r.destroy();
+        return 0;
+    }
+    int ks = r.values[ 0 ];
+    int es = r.values[ 1 ];
+    int ss = r.values[ 2 ];
+    r.destroy();
+    if( !ks || !es || !ss )
+        return 0;
+    befehl = "INSERT INTO karte( name, spiel_art_id, account_id, server_editor_id, server_karten_id, server_shop_id ) VALUES( '";
+    befehl += name;
+    befehl += "', ";
+    befehl += spielArt;
+    befehl += ", ";
+    befehl += acc;
+    befehl += ", ";
+    befehl += es;
+    befehl += ", ";
+    befehl += ks;
+    befehl += ", ";
+    befehl += ss;
+    befehl += " )";
+    lock();
+    if( !datenbank->befehl( befehl ) )
+    {
+        unlock();
+        return 0;
+    }
+    unlock();
+    return 1;
+}
+
+int EdSDatenbank::getSpielArtId( int karte )
+{
+    Text befehl = "SELECT spiel_art_id FROM karte WHERE id = ";
+    befehl += karte;
+    lock();
+    if( !datenbank->befehl( befehl ) )
+    {
+        unlock();
+        return 0;
+    }
+    Result r = datenbank->getResult();
+    unlock();
+    int ret = r.values[ 0 ];
+    r.destroy();
+    return ret;
+}
+
+// constant
+Text *EdSDatenbank::getLetzterFehler() const
+{
+    return datenbank->getLetzterFehler();
+}
+
+// Reference Counting
+EdSDatenbank *EdSDatenbank::getThis()
+{
+    ref++;
+    return this;
+}
+
+EdSDatenbank *EdSDatenbank::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 64 - 0
EditorServer/Datenbank.h

@@ -0,0 +1,64 @@
+#ifndef Datenbank_H
+#define Datenbank_H
+
+#include <sql.h>
+#include <Text.h>
+#include <Array.h>
+#include <InitDatei.h>
+
+using namespace Framework;
+using namespace sql;
+
+namespace Admin_Recht
+{
+	const int EdSStarten = 0x00000032;
+	const int EdSBeenden = 0x00000033;
+	const int EdSPausieren = 0x00000034;
+	const int EdSMKChange = 0x00000035;
+}
+
+struct AHDaten;
+
+class EdSDatenbank
+{
+private:
+	Datenbank *datenbank;
+	CRITICAL_SECTION cs;
+	int ref;
+
+public:
+	// Konstruktor
+	EdSDatenbank( InitDatei *zIni );
+	// Destruktor
+	~EdSDatenbank();
+	// nicht constant
+	void lock();
+	void unlock();
+	int istAdministrator( const char *name, const char *passwort );
+	bool adminHatRecht( int id, int recht );
+	bool proveKlient( int num, int sNum );
+	Text *getKlientKey( int cId );
+	void unregisterKlient( int num, int sNum );
+	bool serverAnmelden( InitDatei *zIni );
+	bool setServerStatus( int id, int status );
+	bool setMaxKarten( int id, int maxK );
+	int getAdminPort( int id );
+	bool serverIstNichtPausiert( int id );
+	Text *getKarteName( int id );
+	bool proveKarte( int id, int cId, int sNum );
+    bool istKarteInUpdate( int id );
+    bool startKarteUpdate( int id );
+    bool startShopUpdate( int id );
+    bool getKarteShopDaten( int karte, int &es, int &tp, int &vp );
+    bool setKarteShopDaten( int karte, int es, int tp, int vp );
+    bool setMaxSpieler( int karte, int spieler );
+    bool karteErstellen( const char *name, int spielArt, int klient );
+    int getSpielArtId( int karte );
+	// constant
+	Text *getLetzterFehler() const;
+	// Reference Counting
+	EdSDatenbank *getThis();
+	EdSDatenbank *release();
+};
+
+#endif

+ 25 - 0
EditorServer/ESEditorV.h

@@ -0,0 +1,25 @@
+#pragma once
+
+#include <Server.h>
+#include <Thread.h>
+
+using namespace Framework;
+using namespace Network;
+
+class ESEditorV
+{
+private:
+
+public:
+    virtual ~ESEditorV()
+    {}
+    // nicht constant
+    virtual void setPfad( char *pfad ) = 0;
+    virtual void open() = 0;
+    virtual bool nachricht( SKlient *k ) = 0;
+    // constant
+    virtual char *getLetzterFehler() const = 0;
+    // Reference Counting 
+    virtual ESEditorV *getThis() = 0;
+    virtual ESEditorV *release() = 0;
+};

+ 938 - 0
EditorServer/EditorServer.cpp

@@ -0,0 +1,938 @@
+#include "EditorServer.h"
+#include <iostream>
+#include <Klient.h>
+#include <Globals.h>
+
+// Inhalt der EditorServer Klasse aus EditorServer.h
+// Konstruktor 
+EditorServer::EditorServer( InitDatei *zIni )
+    : Thread()
+{
+    Network::Start( 100 );
+    std::cout << "EdS: Verbindung mit Datenbank wird hergestellt...\n";
+    db = new EdSDatenbank( zIni );
+    klientAnzahl = 0;
+    klients = new RCArray< EdSKlient >();
+    empfangen = 0;
+    gesendet = 0;
+    fehler = new Text();
+    ini = zIni->getThis();
+    if( !db->serverAnmelden( zIni ) )
+    {
+        std::cout << "EdS: Der Server konnte nicht in die Datenbank eingetragen werden:\n";
+        Text *txt = db->getLetzterFehler();
+        std::cout << txt->getText() << "\nDas Programm wird beendet.";
+        txt->release();
+        exit( 1 );
+    }
+    id = *zIni->zWert( "ServerId" );
+    server = new Server();
+    aServer = new Server();
+    std::cout << "EdS: Starten des Admin Servers...\n";
+    if( !aServer->verbinde( (unsigned short)db->getAdminPort( id ), 10 ) )
+    {
+        std::cout << "EdS: Der Admin Server konnte nicht gestartet werden. Das Programm wird beendet.\n";
+        exit( 1 );
+    }
+    db->setServerStatus( id, 2 );
+    end = 0;
+    nichtPausiert = 0;
+    InitializeCriticalSection( &cs );
+    ref = 1;
+    if( zIni->zWert( "Aktiv" )->istGleich( "TRUE" ) )
+    {
+        serverStarten();
+        serverFortsetzen();
+    }
+}
+
+// Destruktor 
+EditorServer::~EditorServer()
+{
+    fehler->release();
+    server->trenne();
+    server->release();
+    aServer->trenne();
+    aServer->release();
+    if( klients )
+        klients->release();
+    ini->release();
+    db->release();
+    DeleteCriticalSection( &cs );
+}
+
+// nicht constant 
+void EditorServer::runn()
+{
+    while( !end )
+    {
+        SKlient *klient;
+        klient = aServer->getKlient();
+        if( end && klient )
+        {
+            klient->trenne();
+            klient = klient->release();
+            Sleep( 1000 );
+            return;
+        }
+        if( !klient )
+            return;
+        EdSAKlient *clHandle = new EdSAKlient( klient, getThis() );
+        clHandle->start();
+    }
+}
+
+void EditorServer::thread()
+{
+    while( 1 )
+    {
+        SKlient *klient;
+        klient = server->getKlient();
+        if( !klient )
+            break;
+		Framework::getThreadRegister()->cleanUpClosedThreads();
+        EdSKlient *clHandle = new EdSKlient( klient, getThis() );
+        EnterCriticalSection( &cs );
+        klients->set( clHandle, klientAnzahl );
+        klientAnzahl++;
+        LeaveCriticalSection( &cs );
+        clHandle->start();
+    }
+}
+
+void EditorServer::close()
+{
+    db->setServerStatus( id, 1 );
+    server->trenne();
+#ifdef WIN32
+    warteAufThread( 1000 );
+#endif
+    EnterCriticalSection( &cs );
+    for( int i = 0; i < klientAnzahl; i++ )
+        klients->z( i )->absturz();
+    klients = klients->release();
+    klientAnzahl = 0;
+    LeaveCriticalSection( &cs );
+    ende();
+    run = 0;
+    end = 1;
+    Klient *klient = new Klient();
+    klient->verbinde( aServer->getPort(), "127.0.0.1" );
+    Sleep( 500 );
+    aServer->trenne();
+    klient->release();
+}
+
+bool EditorServer::serverStarten()
+{
+    if( nichtPausiert )
+    {
+        fehler->setText( "Der Server konnte nicht gestartet werden: Der Server läuft bereits." );
+        return 0;
+    }
+    if( server )
+        server->release();
+    server = new Server();
+    if( server->verbinde( (unsigned short)TextZuInt( ini->zWert( "ServerPort" )->getText(), 10 ), 10 ) )
+    {
+        nichtPausiert = 1;
+        start();
+        return 1;
+    }
+    else
+    {
+        serverBeenden();
+        fehler->setText( "Der Server konnte nicht gestartet werden: Eventuell ist der Port in benutzung." );
+        return 0;
+    }
+}
+
+bool EditorServer::serverPause()
+{
+    if( !nichtPausiert )
+    {
+        fehler->setText( "Der Server konnte nicht pausiert werden: Der Server läuft nicht." );
+        return 0;
+    }
+    if( !db->setServerStatus( id, 2 ) )
+    {
+        fehler->setText( "Der Server konnte nicht pausiert werden: " );
+        fehler->append( db->getLetzterFehler() );
+        return 0;
+    }
+    return 1;
+}
+
+bool EditorServer::serverFortsetzen()
+{
+    if( !nichtPausiert )
+    {
+        fehler->setText( "Der Server konnte nicht fortgesetzt werden: Der Server läuft nicht." );
+        return 0;
+    }
+    if( !db->setServerStatus( id, 3 ) )
+    {
+        fehler->setText( "Der Server konnte nicht fortgesetzt werden: " );
+        fehler->append( db->getLetzterFehler() );
+        return 0;
+    }
+    return 1;
+}
+
+bool EditorServer::serverBeenden()
+{
+    if( !nichtPausiert )
+    {
+        fehler->setText( "Der Server konnte nicht beendet werden: Der Server läuft nicht." );
+        return 0;
+    }
+    if( db->serverIstNichtPausiert( id ) )
+    {
+        fehler->setText( "Der Server konnte nicht beendet werden: Der Server muss erst pausiert werden." );
+        return 0;
+    }
+    nichtPausiert = 0;
+    ende();
+    if( server )
+        server->trenne();
+    return 1;
+}
+
+bool EditorServer::setMaxKarten( int mk )
+{
+    if( !db->setMaxKarten( id, mk ) )
+    {
+        fehler->setText( "Die maximale Anzahl der Karten konnte nicht gesetzt werden:\n" );
+        fehler->append( db->getLetzterFehler() );
+        return 0;
+    }
+    ini->setWert( "MaxKarten", Text() += mk );
+    return 1;
+}
+
+bool EditorServer::absturzKlient( int klientId )
+{
+    bool gefunden = 0;
+    EnterCriticalSection( &cs );
+    for( int i = 0; i < klientAnzahl; i++ )
+    {
+        if( klients->z( i )->getKlientNummer() == klientId )
+        {
+            klients->z( i )->absturz();
+            klients->remove( i );
+            klientAnzahl--;
+            gefunden = 1;
+            break;
+        }
+    }
+    LeaveCriticalSection( &cs );
+    return gefunden;
+}
+
+bool EditorServer::removeKlient( EdSKlient *zKlient )
+{
+    bool gefunden = 0;
+    EnterCriticalSection( &cs );
+    for( int i = 0; i < klientAnzahl; i++ )
+    {
+        if( klients->z( i ) == zKlient )
+        {
+            klients->remove( i );
+            klientAnzahl--;
+            gefunden = 1;
+            break;
+        }
+    }
+    LeaveCriticalSection( &cs );
+    return gefunden;
+}
+
+void EditorServer::addGesendet( int bytes )
+{
+    gesendet += bytes;
+}
+
+void EditorServer::addEmpfangen( int bytes )
+{
+    empfangen += bytes;
+}
+
+// constant 
+bool EditorServer::istAn() const
+{
+    return db->serverIstNichtPausiert( id );
+}
+
+Server *EditorServer::zServer() const
+{
+    return server;
+}
+
+EdSDatenbank *EditorServer::zDB() const
+{
+    return db;
+}
+
+InitDatei *EditorServer::zIni() const
+{
+    return ini;
+}
+
+bool EditorServer::hatClients() const
+{
+    return klientAnzahl > 0;
+}
+
+int EditorServer::getId() const
+{
+    return id;
+}
+
+char *EditorServer::getLetzterFehler() const
+{
+    return fehler->getText();
+}
+
+// Reference Counting
+EditorServer *EditorServer::getThis()
+{
+    ref++;
+    return this;
+}
+
+EditorServer *EditorServer::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+
+// Inhalt der EdSAKlient Klasse aus EditorServer.h
+// Konstruktor 
+EdSAKlient::EdSAKlient( SKlient *klient, EditorServer *eds )
+    : Thread()
+{
+    this->klient = klient;
+    unsigned char key[ 20 ] = { 102, 98, 8, 248, 114, 86, 30, 28, 18, 142, 113, 108, 129, 101, 196, 53, 37, 184, 73, 108 };
+    klient->setSendeKey( (char*)key, 20 );
+    klient->setEmpfangKey( (char*)key, 20 );
+    name = new Text( "" );
+    passwort = new Text( "" );
+    adminId = 0;
+    this->eds = eds;
+}
+
+// Destruktor 
+EdSAKlient::~EdSAKlient()
+{
+    klient->trenne();
+    klient->release();
+    eds->release();
+    name->release();
+    passwort->release();
+}
+
+// nicht constant 
+void EdSAKlient::thread()
+{
+    while( 1 )
+    {
+        char c = 0;
+        if( !klient->getNachrichtEncrypted( &c, 1 ) )
+            break;
+        else
+        {
+            bool br = 0;
+            switch( c )
+            {
+            case 1: // Login
+                if( 1 )
+                {
+                    klient->sendeEncrypted( "\1", 1 );
+                    char nLen = 0;
+                    klient->getNachrichtEncrypted( &nLen, 1 );
+                    char *n = new char[ nLen + 1 ];
+                    n[ (int)nLen ] = 0;
+                    if( nLen )
+                        klient->getNachrichtEncrypted( n, nLen );
+                    char pLen = 0;
+                    klient->getNachrichtEncrypted( &pLen, 1 );
+                    char *p = new char[ pLen + 1 ];
+                    p[ (int)pLen ] = 0;
+                    if( pLen )
+                        klient->getNachrichtEncrypted( p, pLen );
+                    int adminId = eds->zDB()->istAdministrator( n, p );
+                    if( adminId )
+                    {
+                        klient->sendeEncrypted( "\1", 1 );
+                        name->setText( n );
+                        passwort->setText( p );
+                        this->adminId = adminId;
+                    }
+                    else
+                        errorZuKlient( "Falsche Kombination aus Name und Passwort." );
+                    delete[] n;
+                    delete[] p;
+                }
+                break;
+            case 2: // Logout
+                adminId = 0;
+                name->setText( "" );
+                passwort->setText( "" );
+                klient->sendeEncrypted( "\1", 1 );
+                break;
+            case 3: // Trennen
+                br = 1;
+                klient->sendeEncrypted( "\1", 1 );
+                break;
+            case 4: // Server starten
+                if( !adminId )
+                    errorZuKlient( "Du musst dich einloggen." );
+                else
+                {
+                    if( eds->zDB()->adminHatRecht( adminId, Admin_Recht::EdSStarten ) )
+                    {
+                        if( !eds->serverStarten() )
+                        {
+                            Text *err = new Text();
+                            err->append( eds->getLetzterFehler() );
+                            errorZuKlient( err->getText() );
+                            err->release();
+                        }
+                        else
+                            klient->sendeEncrypted( "\1", 1 );
+                    }
+                    else
+                        errorZuKlient( "Du bist nicht berechtigt den Server zu starten." );
+                }
+                break;
+            case 5: // Server beenden
+                if( !adminId )
+                    errorZuKlient( "Du musst dich einloggen." );
+                else
+                {
+                    if( eds->zDB()->adminHatRecht( adminId, Admin_Recht::EdSBeenden ) )
+                    {
+                        if( eds->serverBeenden() )
+                            klient->sendeEncrypted( "\1", 1 );
+                        else
+                        {
+                            Text *err = new Text();
+                            err->append( eds->getLetzterFehler() );
+                            errorZuKlient( err->getText() );
+                            err->release();
+                        }
+                    }
+                    else
+                        errorZuKlient( "Du bist nicht berechtigt den Server zu beenden." );
+                }
+                break;
+            case 6: // Programm Schließen
+                if( !adminId )
+                    errorZuKlient( "Du musst dich einloggen." );
+                else
+                {
+                    bool ok = 0;
+                    if( eds->isRunning() )
+                    {
+                        if( eds->zDB()->adminHatRecht( adminId, Admin_Recht::EdSBeenden ) )
+                        {
+                            if( eds->serverBeenden() )
+                                ok = 1;
+                            else
+                            {
+                                Text *err = new Text();
+                                err->append( eds->getLetzterFehler() );
+                                errorZuKlient( err->getText() );
+                                err->release();
+                            }
+                        }
+                        else
+                            errorZuKlient( "Du bist nicht berechtigt den Server zu beenden." );
+                    }
+                    else
+                        ok = 1;
+                    if( ok && eds->hatClients() )
+                    {
+                        errorZuKlient( "Es sind noch Klients Online. Bitte versuche es später erneut." );
+                        break;
+                    }
+                    if( ok )
+                    {
+                        klient->sendeEncrypted( "\1", 1 );
+                        std::cout << "EdS: Der Server wird von Benutzer " << adminId << " heruntergefahren.\n";
+                        eds->close();
+                        br = 1;
+                    }
+                }
+                break;
+            case 7: // Progtamm abstürzen
+                if( !adminId )
+                    errorZuKlient( "Du musst dich einloggen." );
+                else
+                {
+                    bool ok = 0;
+                    if( eds->isRunning() )
+                    {
+                        if( eds->zDB()->adminHatRecht( adminId, Admin_Recht::EdSBeenden ) )
+                        {
+                            eds->serverBeenden();
+                            ok = 1;
+                        }
+                        else
+                            errorZuKlient( "Du bist nicht berechtigt den Server zu beenden." );
+                    }
+                    else
+                        ok = 1;
+                    if( ok )
+                    {
+                        klient->sendeEncrypted( "\1", 1 );
+                        std::cout << "EdS: Der Server wurde von Benutzer " << adminId << " terminiert.\n";
+                        eds->close();
+                        br = 1;
+                    }
+                }
+                break;
+            case 8: // Status Frage
+                if( 1 )
+                {
+                    char status = 0;
+                    if( eds->isRunning() )
+                    {
+                        status = 1;
+                        if( eds->istAn() )
+                            status = 2;
+                    }
+                    klient->sendeEncrypted( "\1", 1 );
+                    klient->sendeEncrypted( &status, 1 );
+                }
+                break;
+            case 9: // Server pausieren
+                if( !adminId )
+                    errorZuKlient( "Du musst dich einloggen." );
+                else
+                {
+                    klient->sendeEncrypted( "\1", 1 );
+                    char pause = 0;
+                    klient->getNachrichtEncrypted( &pause, 1 );
+                    if( eds->zDB()->adminHatRecht( adminId, Admin_Recht::EdSPausieren ) )
+                    {
+                        bool ok = 0;
+                        if( pause )
+                            ok = eds->serverPause();
+                        else
+                            ok = eds->serverFortsetzen();
+                        if( ok )
+                            klient->sendeEncrypted( "\1", 1 );
+                        else
+                        {
+                            Text *err = new Text();
+                            err->append( eds->getLetzterFehler() );
+                            errorZuKlient( err->getText() );
+                            err->release();
+                        }
+                    }
+                    else
+                    {
+                        if( pause )
+                            errorZuKlient( "Du bist nicht berechtigt den Server zu pausieren." );
+                        else
+                            errorZuKlient( "Du bist nicht berechtigt den Server fortzusetzen." );
+                    }
+                }
+                break;
+            case 0xA: // maximale Anzahl der Clients setzen
+                if( !adminId )
+                    errorZuKlient( "Du musst dich einloggen." );
+                else
+                {
+                    klient->sendeEncrypted( "\1", 1 );
+                    int maxK = 0;
+                    klient->getNachrichtEncrypted( (char*)&maxK, 4 );
+                    if( eds->zDB()->adminHatRecht( adminId, Admin_Recht::EdSMKChange ) )
+                    {
+                        if( eds->setMaxKarten( maxK ) )
+                            klient->sendeEncrypted( "\1", 1 );
+                        else
+                        {
+                            Text *err = new Text();
+                            err->append( eds->getLetzterFehler() );
+                            errorZuKlient( err->getText() );
+                            err->release();
+                        }
+                    }
+                    else
+                        errorZuKlient( "Du bist nicht berechtigt die maximale Anzahl der Karten zu verändern." );
+                }
+                break;
+            case 0xC: // klient absturtz
+                if( 1 )
+                {
+                    klient->sendeEncrypted( "\1", 1 );
+                    int klientId = 0;
+                    klient->getNachrichtEncrypted( (char*)&klientId, 4 );
+                    if( klientId && eds->absturzKlient( klientId ) )
+                        klient->sendeEncrypted( "\1", 1 );
+                    else
+                        klient->sendeEncrypted( "\0", 1 );
+                }
+                break;
+            default:
+                errorZuKlient( "Unbekannte Nachricht!" );
+                break;
+            }
+            if( br )
+                break;
+            eds->addEmpfangen( klient->getDownloadBytes( 1 ) );
+            eds->addGesendet( klient->getUploadBytes( 1 ) );
+        }
+    }
+    eds->addEmpfangen( klient->getDownloadBytes( 1 ) );
+    eds->addGesendet( klient->getUploadBytes( 1 ) );
+    delete this;
+}
+
+void EdSAKlient::errorZuKlient( const char *nachricht ) const // sendet eine Fehlernachricht zum Klient
+{
+    klient->sendeEncrypted( "\3", 1 );
+    char len = (char)textLength( nachricht );
+    klient->sendeEncrypted( &len, 1 );
+    klient->sendeEncrypted( nachricht, len );
+}
+
+
+// Inhalt der EdSKlient aus EditorServer.h
+// Konstruktor 
+EdSKlient::EdSKlient( SKlient *klient, EditorServer *eds )
+    : Thread()
+{
+    this->klient = klient;
+    unsigned char key[ 20 ] = { 55, 124, 19, 204, 23, 5, 59, 75, 247, 138, 119, 111, 57, 250, 206, 187, 165, 6, 247, 151 };
+    klient->setSendeKey( (char*)key, 20 );
+    klient->setEmpfangKey( (char*)key, 20 );
+    klientNummer = 0;
+    this->eds = eds;
+    ked = 0;
+    ref = 1;
+}
+
+// Destruktor 
+EdSKlient::~EdSKlient()
+{
+    if( ked )
+        ked->release();
+    klient->release();
+    eds->release();
+}
+
+// nicht constant
+void EdSKlient::absturz()
+{
+    ende();
+    klient->trenne();
+    eds->zDB()->unregisterKlient( klientNummer, eds->getId() );
+}
+
+void EdSKlient::thread()
+{
+    while( 1 )
+    {
+        char c = 0;
+        if( !klient->getNachrichtEncrypted( &c, 1 ) )
+            break;
+        else
+        {
+            bool br = 0;
+            switch( c )
+            {
+            case 1: // Klient identifikation
+                klient->getNachrichtEncrypted( (char*)&klientNummer, 4 );
+                if( !eds->zDB()->proveKlient( klientNummer, eds->getId() ) )
+                {
+                    klientNummer = 0;
+                    errorZuKlient( "Du bist nicht für diesen Server eingetragen" );
+                }
+                else
+                {
+                    Text *key = eds->zDB()->getKlientKey( klientNummer );
+                    if( !key )
+                        errorZuKlient( "Es konnte kein Schlüssel ermittelt werden." );
+                    else
+                    {
+                        klient->sendeEncrypted( "\1", 1 );
+                        klient->setEmpfangKey( *key, key->getLength() );
+                        klient->setSendeKey( *key, key->getLength() );
+                        key->release();
+                    }
+                }
+                break;
+            case 2: // Main / Erhaltung Server message
+                if( 1 )
+                {
+                    char befehl = 0;
+                    klient->getNachrichtEncrypted( &befehl, 1 );
+                    switch( befehl )
+                    {
+                    case 2: // klient absturtz
+                        if( 1 )
+                        {
+                            int klientId = 0;
+                            klient->getNachrichtEncrypted( (char*)&klientId, 4 );
+                            if( klientId && eds->absturzKlient( klientId ) )
+                                klient->sendeEncrypted( "\1", 1 );
+                            else
+                                klient->sendeEncrypted( "\0", 1 );
+                        }
+                        break;
+                    default:
+                        errorZuKlient( "Befehl nicht bekannt!" );
+                        break;
+                    }
+                }
+                break;
+            case 3: // Verbindungsende
+                br = 1;
+                klient->sendeEncrypted( "\1", 1 );
+                break;
+            case 4: // unregister Klient
+                if( !klientNummer )
+                {
+                    errorZuKlient( "Du bist nicht Identifiziert." );
+                    break;
+                }
+                eds->zDB()->unregisterKlient( klientNummer, eds->getId() );
+                klient->sendeEncrypted( "\1", 1 );
+                break;
+            case 5: // keep alive
+                if( !klientNummer )
+                {
+                    errorZuKlient( "Du bist nicht Identifiziert." );
+                    break;
+                }
+                klient->sendeEncrypted( "\1", 1 );
+                break;
+            case 6: // lade Karte
+                if( !klientNummer )
+                {
+                    errorZuKlient( "Du bist nicht Identifiziert." );
+                    break;
+                }
+                else
+                {
+                    klient->sendeEncrypted( "\1", 1 );
+                    int karteId = 0;
+                    klient->getNachrichtEncrypted( (char*)&karteId, 4 );
+                    if( eds->zDB()->proveKarte( karteId, klientNummer, eds->getId() ) )
+                    {
+                        if( ked )
+                            ked->release();
+                        ked = new KarteEditor( karteId, eds->zDB()->getThis(), eds->zIni()->zWert( "KartenPfad" )->getText(), eds->zIni() );
+                        if( ked->istOk() )
+                            klient->sendeEncrypted( "\1", 1 );
+                        else
+                        {
+                            errorZuKlient( ked->getLetzterFehler() );
+                            ked = ked->release();
+                        }
+                    }
+                    else
+                        errorZuKlient( "Du kannst diese Karte nicht bearbeiten." );
+                }
+                break;
+            case 7: // Nachricht
+                if( !klientNummer )
+                {
+                    errorZuKlient( "Du bist nicht Identifiziert." );
+                    break;
+                }
+                else
+                {
+                    if( !ked || !ked->istOk() )
+                        errorZuKlient( "Es wurde keine Karte geladen." );
+                    else
+                    {
+                        klient->sendeEncrypted( "\1", 1 );
+                        if( !ked->prozessMessage( klient ) )
+                            errorZuKlient( ked->getLetzterFehler() );
+                        ked->removeError();
+                    }
+                }
+                break;
+            case 8: // Shop Seite herunterladen (Vom Shop Server)
+                if( klientNummer )
+                {
+                    errorZuKlient( "Du bist nicht berechtigt." );
+                    break;
+                }
+                else
+                {
+                    klient->sendeEncrypted( "\1", 1 );
+                    int id = 0;
+                    klient->getNachrichtEncrypted( (char*)&id, 4 );
+                    if( ked )
+                        ked->release();
+                    ked = new KarteEditor( id, eds->zDB()->getThis(), eds->zIni()->zWert( "KartenPfad" )->getText(), eds->zIni() );
+                    if( !ked->istOk() )
+                    {
+                        errorZuKlient( "Die Karte konnte nicht geladen werden." );
+                        ked = ked->release();
+                        break;
+                    }
+                    klient->sendeEncrypted( "\1", 1 );
+                    RCArray< Text > *list = new RCArray< Text >();
+                    int anz = ked->getDateiUpdateListe( ( char* )"shop", list );
+                    klient->sendeEncrypted( (char*)&anz, 4 );
+                    for( int i = 0; i < anz; i++ )
+                    {
+                        Text p = list->z( i )->getText();
+                        char l = (char)p.getLength();
+                        klient->sendeEncrypted( &l, 1 );
+                        klient->sendeEncrypted( p, l );
+                        Text tmp = ked->getPfad();
+                        tmp += "/live/shop";
+                        p.insert( 0, (char*)tmp );
+                        Datei d;
+                        d.setDatei( p );
+                        __int64 size = d.getSize();
+                        klient->sendeEncrypted( (char*)&size, 8 );
+                        d.open( Datei::Style::lesen );
+                        char *buffer = new char[ 2048 ];
+                        while( size )
+                        {
+                            int l = size > 2048 ? 2048 : (int)size;
+                            d.lese( buffer, l );
+                            klient->sende( buffer, l );
+                            size -= l;
+                        }
+                        delete[] buffer;
+                        d.close();
+                    }
+                    list->release();
+                    if( ked )
+                        ked = ked->release();
+                }
+                break;
+            case 9: // Karte Update herunterladen (Vom Karten Server)
+                if( klientNummer )
+                {
+                    errorZuKlient( "Du bist nicht berechtigt." );
+                    break;
+                }
+                else
+                {
+                    klient->sendeEncrypted( "\1", 1 );
+                    int id = 0;
+                    klient->getNachrichtEncrypted( (char*)&id, 4 );
+                    if( ked )
+                        ked->release();
+                    ked = new KarteEditor( id, eds->zDB()->getThis(), eds->zIni()->zWert( "KartenPfad" )->getText(), eds->zIni() );
+                    if( !ked->istOk() )
+                    {
+                        errorZuKlient( "Die Karte konnte nicht geladen werden." );
+                        ked = ked->release();
+                        break;
+                    }
+                    klient->sendeEncrypted( "\1", 1 );
+                    RCArray< Text > *list = new RCArray< Text >();
+                    int anz = ked->getDateiUpdateListe( ( char* )"map", list );
+                    klient->sendeEncrypted( (char*)&anz, 4 );
+                    for( int i = 0; i < anz; i++ )
+                    {
+                        Text p = list->z( i )->getText();
+                        char l = (char)p.getLength();
+                        klient->sendeEncrypted( &l, 1 );
+                        klient->sendeEncrypted( p, l );
+                        Text tmp = ked->getPfad();
+                        tmp += "/live/map";
+                        p.insert( 0, (char*)tmp );
+                        Datei d;
+                        d.setDatei( p );
+                        __int64 size = d.getSize();
+                        klient->sendeEncrypted( (char*)&size, 8 );
+                        d.open( Datei::Style::lesen );
+                        char *buffer = new char[ 2048 ];
+                        while( size )
+                        {
+                            int l = size > 2048 ? 2048 : (int)size;
+                            d.lese( buffer, l );
+                            klient->sende( buffer, l );
+                            size -= l;
+                        }
+                        delete[] buffer;
+                        d.close();
+                    }
+                    list->release();
+                    if( ked )
+                        ked = ked->release();
+                }
+                break;
+            case 10: // Neue Karte erstellen
+            {
+                if( !klientNummer )
+                {
+                    errorZuKlient( "Du bist nicht Identifiziert." );
+                    break;
+                }
+                else
+                {
+                    klient->sendeEncrypted( "\1", 1 );
+                    char l = 0;
+                    klient->getNachrichtEncrypted( &l, 1 );
+                    char *n = new char[ l + 1 ];
+                    n[ (int)l ] = 0;
+                    klient->getNachrichtEncrypted( n, l );
+                    int spielArt = 0;
+                    klient->getNachrichtEncrypted( (char*)&spielArt, 4 );
+                    if( eds->zDB()->karteErstellen( n, spielArt, klientNummer ) )
+                        klient->sendeEncrypted( "\1", 1 );
+                    else
+                        errorZuKlient( "Für dieses Spiel kann momentan keine Karte erstellt werden." );
+                    delete[] n;
+                }
+                break;
+            }
+            default:
+                errorZuKlient( "Unbekannte Nachricht!" );
+                break;
+            }
+            if( br )
+                break;
+            eds->addEmpfangen( klient->getDownloadBytes( 1 ) );
+            eds->addGesendet( klient->getUploadBytes( 1 ) );
+        }
+    }
+    eds->addEmpfangen( klient->getDownloadBytes( 1 ) );
+    eds->addGesendet( klient->getUploadBytes( 1 ) );
+    eds->removeKlient( this ); // delete this
+}
+
+// constant
+void EdSKlient::errorZuKlient( const char *nachricht ) const // sendet eine Fehlernachricht zum Klient
+{
+    klient->sendeEncrypted( "\3", 1 );
+    char len = (char)textLength( nachricht );
+    klient->sendeEncrypted( &len, 1 );
+    klient->sendeEncrypted( nachricht, len );
+}
+
+int EdSKlient::getKlientNummer() const // gibt die KlientId zurück
+{
+    return klientNummer;
+}
+
+// Reference Counting
+EdSKlient *EdSKlient::getThis()
+{
+    ref++;
+    return this;
+}
+
+EdSKlient *EdSKlient::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 115 - 0
EditorServer/EditorServer.h

@@ -0,0 +1,115 @@
+#ifndef EditorServer_H
+#define EditorServer_H
+
+#include <Server.h>
+#include <Thread.h>
+#include <Datei.h>
+#include <Text.h>
+#include <InitDatei.h>
+#ifdef WIN32
+#include "Karte/KarteEditor.h"
+#include "../Datenbank/Datenbank.h"
+#else
+#include "Datenbank.h"
+#include "KarteEditor.h"
+#endif
+
+using namespace Framework;
+using namespace Network;
+
+class EdSKlient;
+
+class EditorServer : public Thread
+{
+private:
+	Server *server;
+	Server *aServer;
+	InitDatei *ini;
+	EdSDatenbank *db;
+	CRITICAL_SECTION cs;
+	RCArray< EdSKlient > *klients;
+	Text *fehler;
+	int klientAnzahl;
+	int id;
+	bool nichtPausiert;
+	int empfangen;
+	int gesendet;
+	bool end;
+	int ref;
+
+public:
+	// Konstruktor 
+	EditorServer( InitDatei *zIni );
+	// Destruktor 
+	virtual ~EditorServer();
+	// nicht constant 
+	void runn();
+	void thread();
+	void close();
+	bool serverStarten();
+	bool serverPause();
+	bool serverFortsetzen();
+	bool serverBeenden();
+	bool setMaxKarten( int mk );
+	bool absturzKlient( int klientId );
+	bool removeKlient( EdSKlient *zKlient );
+	void addGesendet( int bytes );
+	void addEmpfangen( int bytes );
+	// conatant 
+	bool istAn() const;
+	Server *zServer() const;
+	EdSDatenbank *zDB() const;
+	InitDatei *zIni() const;
+	bool hatClients() const;
+	int getId() const;
+	char *getLetzterFehler() const;
+	// Reference Counting
+	EditorServer *getThis();
+	EditorServer *release();
+};
+
+class EdSAKlient : public Thread
+{
+private:
+	SKlient *klient;
+	Text *name;
+	Text *passwort;
+	int adminId;
+	EditorServer *eds;
+
+public:
+	// Konstruktor 
+	EdSAKlient( SKlient *klient, EditorServer *eds );
+	// Destruktor 
+	virtual ~EdSAKlient();
+	// nicht constant
+	void thread();
+	void errorZuKlient( const char *nachricht ) const; // sendet eine Fehlernachricht zum AKlient
+};
+
+class EdSKlient : public Thread
+{
+private:
+	SKlient *klient;
+	unsigned int klientNummer;
+	EditorServer *eds;
+	KarteEditor *ked;
+	int ref;
+
+public:
+	// Konstruktor 
+	EdSKlient( SKlient *klient, EditorServer *eds );
+	// Destruktor 
+	virtual ~EdSKlient();
+	// nicht constant
+	void absturz();
+	void thread();
+	// constant
+	void errorZuKlient( const char *nachricht ) const; // sendet eine Fehlernachricht zum Klient
+	int getKlientNummer() const;
+	// Reference Counting
+	EdSKlient *getThis();
+	EdSKlient *release();
+};
+
+#endif

+ 87 - 0
EditorServer/EditorServer.vcxproj

@@ -0,0 +1,87 @@
+<?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|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{fa25200a-6bbb-4ec3-9a83-d5bc151dc90a}</ProjectGuid>
+    <Keyword>Linux</Keyword>
+    <RootNamespace>EditorServer</RootNamespace>
+    <MinimumVisualStudioVersion>15.0</MinimumVisualStudioVersion>
+    <ApplicationType>Linux</ApplicationType>
+    <ApplicationTypeRevision>1.0</ApplicationTypeRevision>
+    <TargetLinuxPlatform>Generic</TargetLinuxPlatform>
+    <LinuxProjectType>{D51BCBC9-82E9-4017-911E-C93873C4EA2B}</LinuxProjectType>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <RemoteRootDir>/home/kolja/projects</RemoteRootDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <RemoteRootDir>/home/kolja/projects</RemoteRootDir>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings" />
+  <ImportGroup Label="Shared" />
+  <ImportGroup Label="PropertySheets" />
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <TargetExt />
+    <RemoteProjectDir>$(RemoteRootDir)/Server/$(ProjectName)/Release</RemoteProjectDir>
+    <IncludePath>..\..\..\..\Allgemein\Framework;../../../Framework/Release;..\..\..\..\Allgemein\Network\Network;../../../Network/Release;..\..\..\..\Allgemein\sql\sql;../../../sql/Release;$(IncludePath)</IncludePath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <TargetExt />
+    <RemoteProjectDir>$(RemoteRootDir)/Server/$(ProjectName)/Debug</RemoteProjectDir>
+    <IncludePath>..\..\..\..\Allgemein\Framework;../../../Framework/Debug;..\..\..\..\Allgemein\Network\Network;../../../Network/Debug;..\..\..\..\Allgemein\sql\sql;../../../sql/Debug;..\AppServer;$(IncludePath)</IncludePath>
+  </PropertyGroup>
+  <ItemGroup>
+    <ClInclude Include="BeschreibungEditor.h" />
+    <ClInclude Include="DateienEditor.h" />
+    <ClInclude Include="Datenbank.h" />
+    <ClInclude Include="EditorServer.h" />
+    <ClInclude Include="ESEditorV.h" />
+    <ClInclude Include="GSLDateiV.h" />
+    <ClInclude Include="GSLSoundV.h" />
+    <ClInclude Include="KarteEditor.h" />
+    <ClInclude Include="KsgsBeschreibung.h" />
+    <ClInclude Include="KsgsShopSeite.h" />
+    <ClInclude Include="SSEditor.h" />
+    <ClInclude Include="TeamsEditor.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="BeschreibungEditor.cpp" />
+    <ClCompile Include="DateienEditor.cpp" />
+    <ClCompile Include="Datenbank.cpp" />
+    <ClCompile Include="EditorServer.cpp" />
+    <ClCompile Include="KarteEditor.cpp" />
+    <ClCompile Include="main.cpp" />
+    <ClCompile Include="SSEditor.cpp" />
+    <ClCompile Include="TeamsEditor.cpp" />
+  </ItemGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Link>
+      <LibraryDependencies>dbgFramework;dbgNetwork;dbgSQL;pq;pthread;dl</LibraryDependencies>
+      <AdditionalLibraryDirectories>$(RemoteRootDir)/sql/Debug/bin/x64/debug;$(RemoteRootDir)/Network/Debug/bin/x64/debug;$(RemoteRootDir)/Framework/Debug/bin/x64/debug;/usr/lib/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalOptions>-Wl,-rpath,../lib %(AdditionalOptions)</AdditionalOptions>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Link>
+      <LibraryDependencies>Framework;Network;SQL;pq;pthread;dl</LibraryDependencies>
+      <AdditionalLibraryDirectories>$(RemoteRootDir)/sql/Release/bin/x64/release;$(RemoteRootDir)/Network/Release/bin/x64/release;$(RemoteRootDir)/Framework/Release/bin/x64/release;/usr/lib/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalOptions>-Wl,-rpath,../lib %(AdditionalOptions)</AdditionalOptions>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets" />
+</Project>

+ 78 - 0
EditorServer/EditorServer.vcxproj.filters

@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="BeschreibungEditor.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="DateienEditor.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Datenbank.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="EditorServer.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="KarteEditor.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="SSEditor.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="TeamsEditor.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="main.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="BeschreibungEditor.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="DateienEditor.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="Datenbank.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="EditorServer.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="KarteEditor.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="KsgsBeschreibung.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="KsgsShopSeite.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="SSEditor.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="TeamsEditor.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="GSLSoundV.h">
+      <Filter>Include</Filter>
+    </ClInclude>
+    <ClInclude Include="GSLDateiV.h">
+      <Filter>Include</Filter>
+    </ClInclude>
+    <ClInclude Include="ESEditorV.h">
+      <Filter>Include</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <Filter Include="Headerdateien">
+      <UniqueIdentifier>{cf01813d-a818-4d84-95cb-2321dbbe5604}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Quelldateien">
+      <UniqueIdentifier>{00ef5037-a819-4103-83a3-1bf458373f88}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Include">
+      <UniqueIdentifier>{5bb44480-3f35-4021-8d40-0edfe6a6e32f}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>

+ 31 - 0
EditorServer/GSLDateiV.h

@@ -0,0 +1,31 @@
+#pragma once
+
+#include <Text.h>
+#include "GSLSoundV.h"
+
+namespace GSL
+{
+    class GSLDateiV
+    {
+    public:
+        virtual ~GSLDateiV()
+        {}
+        virtual void setDatei( Framework::Text *txt ) = 0;
+        virtual void setDatei( char *txt ) = 0;
+        virtual bool leseDaten() = 0;
+        virtual int getSoundAnzahl() = 0;
+        virtual Framework::Text *getSoundName( int num ) = 0;
+        // Laden
+        virtual GSLSoundV *getSound( Framework::Text *name ) = 0;
+        virtual GSLSoundV *getSound( char *name ) = 0;
+        // Speichern
+        virtual bool speicherSound( GSLSoundV *zSound, Framework::Text *name ) = 0;
+        virtual bool speicherSound( GSLSoundV *zSound, char *name ) = 0;
+        // Löschen
+        virtual bool removeSound( Framework::Text *name ) = 0;
+        virtual bool removeSound( char *name ) = 0;
+        // Reference Counting
+        virtual GSLDateiV *getThis() = 0;
+        virtual GSLDateiV *release() = 0;
+    };
+}

+ 29 - 0
EditorServer/GSLSoundV.h

@@ -0,0 +1,29 @@
+#pragma once
+
+#include <Thread.h>
+
+namespace GSL
+{
+    class GSLSoundV : protected Framework::Thread
+    {
+    public:
+        virtual ~GSLSoundV()
+        {}
+        virtual void playSound() = 0;
+        virtual void setPause( bool p ) = 0;
+        virtual void stopSound() = 0;
+        virtual void warteAufSound( int zeit ) = 0;
+        // Lautstärke: 0 - 0xFFFF
+        virtual void setVolume( unsigned int links, unsigned int rechts ) = 0;
+        // zum Speichern
+        virtual void open() = 0;
+        virtual int getDaten( char *buffer, int len ) = 0;
+        virtual void close() = 0;
+        virtual bool istMono() const = 0;
+        virtual int getSampleRate() const = 0;
+        virtual __int64 getDatLength() const = 0;
+        // Reference Counting
+        virtual GSLSoundV *getThis() = 0;
+        virtual GSLSoundV *release() = 0;
+    };
+}

+ 695 - 0
EditorServer/KarteEditor.cpp

@@ -0,0 +1,695 @@
+#include "KarteEditor.h"
+#include <Datei.h>
+#include <DateiSystem.h>
+#include <Bild.h>
+#include <Zeit.h>
+#include "KsgsBeschreibung.h"
+#include "KsgsShopSeite.h"
+#include <unistd.h>
+#define Sleep( x )               usleep( (x) * 1000 )
+#include <dlfcn.h>
+#define LoadLibrary( x )         dlopen( (x), RTLD_LAZY )
+#define GetProcAddress           dlsym
+#define FreeLibrary              dlclose
+
+typedef ESEditorV*( *DllStart )( );
+
+// Inhalt der KarteEditor Klasse aus KarteEditor.h
+// Konstruktor
+KarteEditor::KarteEditor( int id, EdSDatenbank *datenbank, char *pf, InitDatei *zIni )
+{
+    this->id = id;
+    db = datenbank;
+    ini = zIni->getThis();
+    pfad = new Text( pf );
+    pfad->append( "/" );
+    pfad->append( id );
+    if( !DateiExistiert( *pfad ) )
+    { // Karte erstellen
+        // Client Daten
+        Text dn = pfad->getText();
+        dn += "/live/map/client/titel.ltdb";
+        LTDBDatei bilder;
+        bilder.setDatei( dn.getThis() );
+        bilder.erstellen();
+        Bild *bild = new Bild();
+        bild->neuBild( 200, 100, 0x00000000 );
+        bilder.speichern( 0, bild->getThis(), new Text( "titel" ) );
+        dn = pfad->getText();
+        dn += "/live/map/client/minimap.ltdb";
+        bilder.setDatei( dn.getThis() );
+        bilder.erstellen();
+        bild->neuBild( 348, 348, 0x00000000 );
+        bilder.speichern( 0, bild->getThis(), new Text( "vorschau" ) );
+        dn = pfad->getText();
+        dn += "/live/map/client/ladebild.ltdb";
+        bilder.setDatei( dn.getThis() );
+        bilder.erstellen();
+        bild->neuBild( 1300, 900, 0x00000000 );
+        bilder.speichern( 0, bild, new Text( "spielladen" ) );
+        dn = pfad->getText();
+        dn += "/live/map/client/beschreibung.ksgs";
+        Datei d;
+        d.setDatei( dn );
+        d.erstellen();
+        d.open( Datei::Style::schreiben );
+        d.schreibe( (char*)_neu_karte_ksgs_beschreibung, textLength( _neu_karte_ksgs_beschreibung ) );
+        d.close();
+        dn = pfad->getText();
+        dn += "/live/map/client/map/data/data.sts";
+        d.setDatei( dn );
+        d.erstellen();
+        d.open( Datei::Style::schreiben );
+        int i = 0;
+        d.schreibe( (char*)&i, 4 );
+        d.schreibe( (char*)&i, 4 );
+        d.close();
+        // Shop Seite
+        dn = pfad->getText();
+        dn += "/live/shop/seite/seite.ksgs";
+        d.setDatei( dn );
+        d.erstellen();
+        d.open( Datei::Style::schreiben );
+        d.schreibe( (char*)_neu_karte_ksgs_shop_seite, textLength( _neu_karte_ksgs_shop_seite ) );
+        d.close();
+        dn = pfad->getText();
+        dn += "/live/shop/titelbg.ltdb";
+        bilder.setDatei( dn.getThis() );
+        bilder.erstellen();
+        bild->neuBild( 200, 100, 0x00000000 );
+        bilder.speichern( 0, bild->getThis(), new Text( "auswbg.jpg" ) );
+        // Server Daten
+        dn = pfad->getText();
+        dn += "/live/map/server/sts.ltgd";
+        d.setDatei( dn );
+        d.erstellen();
+        d.open( Datei::Style::schreiben );
+        i = 0;
+        d.schreibe( (char*)&i, 4 );
+        d.schreibe( (char*)&i, 4 );
+        d.close();
+        dn = pfad->getText();
+        dn += "/live/map/server/...";
+
+    }
+    shop = new SSEditor( pfad->getText() );
+    beschreibung = new BeschreibungEditor( pfad->getText() );
+    teams = new TeamsEditor( id, pfad->getText(), db->getThis() );
+    dateien = new DateienEditor( pfad->getText(), zIni );
+    editor = 0;
+    editorDll = 0;
+    fehler = "";
+    ref = 1;
+}
+
+// Destruktor
+KarteEditor::~KarteEditor()
+{
+    shop->release();
+    beschreibung->release();
+    teams->release();
+    dateien->release();
+    db->release();
+    pfad->release();
+    if( editor )
+        editor->release();
+    if( editorDll )
+        FreeLibrary( editorDll );
+    ini->release();
+}
+
+// private
+int KarteEditor::findeDateien( char *pf, RCArray< Text > *pfad )
+{
+    Datei d;
+    d.setDatei( pf );
+    if( d.existiert() && !d.istOrdner() )
+    {
+        pfad->add( new Text( pf ) );
+        return 1;
+    }
+    if( d.istOrdner() )
+    {
+        RCArray< Text > *list = d.getDateiListe();
+        int anz = list->getEintragAnzahl();
+        int ret = 0;
+        for( int i = 0; i < anz; i++ )
+        {
+            Text p = pf;
+            p += "/";
+            p += list->z( i )->getText();
+            ret += findeDateien( p, pfad );
+        }
+        list->release();
+        return ret;
+    }
+    return 0;
+}
+
+// nicht constant
+bool KarteEditor::getAbbildListe( RCArray< Text > *name, RCArray< Zeit > *datum )
+{
+    name->leeren();
+    datum->leeren();
+    Text pf = pfad->getText();
+    pf += "/abbilder";
+    Datei d;
+    d.setDatei( pf );
+    if( !d.existiert() || !d.istOrdner() )
+        return 1;
+    RCArray< Text > *list = d.getDateiListe();
+    if( !list )
+        return 0;
+    int anz = list->getEintragAnzahl();
+    for( int i = 0; i < anz; i++ )
+    {
+        Text p = pf.getText();
+        p += "/";
+        p += list->z( i )->getText();
+        d.setDatei( p );
+        Zeit *z = d.getLastChange();
+        if( z )
+        {
+            name->set( list->get( i ), i );
+            datum->set( z, i );
+        }
+    }
+    list->release();
+    return 1;
+}
+
+int KarteEditor::getDateiUpdateListe( char *p, RCArray< Text > *pfad )
+{
+    pfad->leeren();
+    Text pf = this->pfad->getText();
+    pf += "/live/";
+    pf += p;
+    RCArray< Text > *list = new RCArray< Text >();
+    int anz = findeDateien( pf, list );
+    for( int i = 0; i < anz; i++ )
+    {
+        list->z( i )->remove( pf.getText() );
+        pfad->set( list->get( i ), i );
+    }
+    list->release();
+    return anz;
+}
+
+bool KarteEditor::abbildErstellen( char *name )
+{
+    Text pf = pfad->getText();
+    pf += "/abbilder/";
+    pf += name;
+    if( DateiExistiert( pf ) )
+    {
+        fehler = "Es existiert bereits ein Abbild mit diesem Namen. Du musst es vorher remove, oder einen anderen Namen angeben.";
+        return 0;
+    }
+    Text live = pfad->getText();
+    live += "/live";
+    RCArray< Text > *list = new RCArray< Text >();
+    int anz = findeDateien( live, list );
+    bool ret = 1;
+    for( int i = 0; i < anz; i++ )
+    {
+        Datei alt;
+        Datei neu;
+        alt.setDatei( list->z( i )->getText() );
+        Text pfNeu = pf.getText();
+        pfNeu += ( list->z( i )->getText() + live.getLength() );
+        neu.setDatei( pfNeu );
+        neu.erstellen();
+        ret &= alt.open( Datei::Style::lesen );
+        ret &= neu.open( Datei::Style::schreiben );
+        __int64 size = alt.getSize();
+        char *buffer = new char[ 2048 ];
+        while( size > 0 )
+        {
+            int l = size > 2048 ? 2048 : (int)size;
+            alt.lese( buffer, l );
+            neu.schreibe( buffer, l );
+            size -= l;
+        }
+        delete[] buffer;
+        alt.close();
+        neu.close();
+    }
+    list->release();
+    if( !ret )
+    {
+        DateiRemove( pf );
+        fehler = "Es ist ein Fehler beim Lesen oder Schreiben einer Datei aufgetreten.";
+    }
+    return ret;
+}
+
+bool KarteEditor::abbildRemove( char *name )
+{
+    Text pf = pfad->getText();
+    pf += "/abbilder/";
+    pf += name;
+    if( !DateiRemove( pf ) )
+    {
+        fehler = "Es ist ein Fehler beim Löschen des Abbildes aufgetreten.";
+        return 0;
+    }
+    return 1;
+}
+
+bool KarteEditor::abbildHerstellen( char *name )
+{
+    if( inUpdate() )
+    {
+        fehler = "Die Karte wird momentan aktualisiert. Bitte haben sie Geduld, bis dieser Vorgang abgeschlossen ist.";
+        return 0;
+    }
+    Text pf = pfad->getText();
+    pf += "/abbilder/";
+    pf += name;
+    if( !DateiExistiert( pf ) )
+    {
+        fehler = "Es existiert kein Abbild mit dem angegebenen Namen.";
+        return 0;
+    }
+    Text live = pfad->getText();
+    live += "/live";
+    if( !DateiRemove( live ) )
+    {
+        fehler = "Es ist ein Fehler beim Löschen der aktuellen Version aufgetreten.";
+        return 0;
+    }
+    RCArray< Text > *list = new RCArray< Text >();
+    int anz = findeDateien( pf, list );
+    bool ret = 1;
+    for( int i = 0; i < anz; i++ )
+    {
+        Datei alt;
+        Datei neu;
+        alt.setDatei( list->z( i )->getText() );
+        Text pfNeu = live.getText();
+        pfNeu += ( list->z( i )->getText() + pf.getLength() );
+        neu.setDatei( pfNeu );
+        neu.erstellen();
+        ret |= alt.open( Datei::Style::lesen );
+        ret |= neu.open( Datei::Style::schreiben );
+        __int64 size = alt.getSize();
+        char *buffer = new char[ 2048 ];
+        while( size > 0 )
+        {
+            int l = size > 2048 ? 2048 : (int)size;
+            alt.lese( buffer, l );
+            neu.schreibe( buffer, l );
+            size -= l;
+        }
+        delete[] buffer;
+        alt.close();
+        neu.close();
+    }
+    list->release();
+    if( !ret )
+    {
+        DateiRemove( pf );
+        fehler = "Es ist ein Fehler beim Lesen oder Schreiben einer Datei aufgetreten.";
+    }
+    return ret;
+}
+
+bool KarteEditor::startUpdate()
+{
+    if( inUpdate() )
+    {
+        fehler = "Die Karte wird momentan aktualisiert. Bitte haben sie Geduld, bis dieser Vorgang abgeschlossen ist.";
+        return 0;
+    }
+    if( !db->startKarteUpdate( id ) )
+    {
+        Text *t = db->getLetzterFehler();
+        fehler = t->getText();
+        t->release();
+        return 0;
+    }
+    return 1;
+}
+
+bool KarteEditor::startShopUpdate()
+{
+    if( !db->startShopUpdate( id ) )
+    {
+        Text *t = db->getLetzterFehler();
+        fehler = t->getText();
+        t->release();
+        return 0;
+    }
+    return 1;
+}
+
+bool KarteEditor::prozessMessage( SKlient *zKlient )
+{
+    char message = 0;
+    zKlient->getNachrichtEncrypted( &message, 1 );
+    switch( message )
+    {
+    case 0x1: // Abbild Erstellen
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char l = 0;
+        zKlient->getNachrichtEncrypted( &l, 1 );
+        char *name = new char[ l + 1 ];
+        name[ (int)l ] = 0;
+        if( l )
+            zKlient->getNachrichtEncrypted( name, l );
+        if( !textLength( name ) )
+        {
+            delete[] name;
+            fehler = "Du musst einen Namen angeben.";
+            return 0;
+        }
+        if( !abbildErstellen( name ) )
+        {
+            delete[] name;
+            return 0;
+        }
+        delete[] name;
+        zKlient->sendeEncrypted( "\1", 1 );
+        return 1;
+    }
+    case 0x2: // Abbild Löschen
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char l = 0;
+        zKlient->getNachrichtEncrypted( &l, 1 );
+        char *name = new char[ l + 1 ];
+        name[ (int)l ] = 0;
+        if( l )
+            zKlient->getNachrichtEncrypted( name, l );
+        if( !textLength( name ) )
+        {
+            delete[] name;
+            fehler = "Du musst einen Namen angeben.";
+            return 0;
+        }
+        if( !abbildRemove( name ) )
+        {
+            delete[] name;
+            return 0;
+        }
+        delete[] name;
+        zKlient->sendeEncrypted( "\1", 1 );
+        return 1;
+    }
+    case 0x3: // Abbild Herstellen
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char l = 0;
+        zKlient->getNachrichtEncrypted( &l, 1 );
+        char *name = new char[ l + 1 ];
+        name[ (int)l ] = 0;
+        if( l )
+            zKlient->getNachrichtEncrypted( name, l );
+        if( !textLength( name ) )
+        {
+            delete[] name;
+            fehler = "Du musst einen Namen angeben.";
+            return 0;
+        }
+        if( !abbildHerstellen( name ) )
+        {
+            delete[] name;
+            return 0;
+        }
+        delete[] name;
+        zKlient->sendeEncrypted( "\1", 1 );
+        return 1;
+    }
+    case 0x4: // Karte Veröffentlichen
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        if( !startUpdate() )
+            return 0;
+        else
+            zKlient->sendeEncrypted( "\1", 1 );
+        return 1;
+    }
+    case 0x5: // get Abbild Liste
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        RCArray< Text > *name = new RCArray< Text >();
+        RCArray< Zeit > *datum = new RCArray< Zeit >();
+        getAbbildListe( name, datum );
+        int anz = name->getEintragAnzahl();
+        zKlient->sendeEncrypted( (char*)&anz, 4 );
+        for( int i = 0; i < anz; i++ )
+        {
+            Text n = name->z( i )->getText();
+            char len = (char)n.getLength();
+            zKlient->sendeEncrypted( &len, 1 );
+            zKlient->sendeEncrypted( n, len );
+            int d = datum->z( i )->zDatum()->getJahr();
+            zKlient->sendeEncrypted( (char*)&d, 4 );
+            d = datum->z( i )->zDatum()->getMonat();
+            zKlient->sendeEncrypted( (char*)&d, 4 );
+            d = datum->z( i )->zDatum()->getTag();
+            zKlient->sendeEncrypted( (char*)&d, 4 );
+            d = datum->z( i )->zUhrzeit()->getStunde();
+            zKlient->sendeEncrypted( (char*)&d, 4 );
+            d = datum->z( i )->zUhrzeit()->getMinute();
+            zKlient->sendeEncrypted( (char*)&d, 4 );
+            d = datum->z( i )->zUhrzeit()->getSekunde();
+            zKlient->sendeEncrypted( (char*)&d, 4 );
+        }
+        name->release();
+        datum->release();
+        return 1;
+    }
+    case 0x6: // Shop Seite Veröffentlichen
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        if( !startShopUpdate() )
+            return 0;
+        else
+            zKlient->sendeEncrypted( "\1", 1 );
+        return 1;
+    }
+    case 0x7: // Shop Seite Nachricht
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        if( !shop->prozessMessage( zKlient ) )
+            fehler = shop->getLetzterFehler();
+        else
+            return 1;
+        return 0;
+    }
+    case 0x8: // Shop Seite herunterladen
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        RCArray< Text > *list = new RCArray< Text >();
+        Text pf = pfad->getText();
+        pf += "/live/shop";
+        int anz = findeDateien( pf, list );
+        zKlient->sendeEncrypted( (char*)&anz, 4 );
+        for( int i = 0; i < anz; i++ )
+        {
+            Text p = list->z( i )->getText();
+            char l = (char)( p.getLength() - pf.getLength() );
+            zKlient->sendeEncrypted( &l, 1 );
+            zKlient->sendeEncrypted( (char*)p + pf.getLength(), l );
+            Datei d;
+            d.setDatei( p );
+            __int64 size = d.getSize();
+            zKlient->sendeEncrypted( (char*)&size, 8 );
+            d.open( Datei::Style::lesen );
+            char *buffer = new char[ 2048 ];
+            while( size > 0 )
+            {
+                int l = size > 2048 ? 2048 : (int)size;
+                d.lese( buffer, l );
+                zKlient->sende( buffer, l );
+                size -= l;
+            }
+            delete[] buffer;
+            d.close();
+        }
+        list->release();
+        return 1;
+    }
+    case 0x9: // Shop Daten laden
+    {
+        int es = 0, tp = 0, vp = 0;
+        if( !db->getKarteShopDaten( id, es, tp, vp ) )
+        {
+            fehler = "Fehler beim laden der Shop Informationen.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        zKlient->sendeEncrypted( (char*)&es, 4 );
+        zKlient->sendeEncrypted( (char*)&tp, 4 );
+        zKlient->sendeEncrypted( (char*)&vp, 4 );
+        return 1;
+    }
+    case 0xA: // Set Shop Daten
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        int es = 0, tp = 0, vp = 0;
+        zKlient->getNachrichtEncrypted( (char*)&es, 4 );
+        zKlient->getNachrichtEncrypted( (char*)&tp, 4 );
+        zKlient->getNachrichtEncrypted( (char*)&vp, 4 );
+        if( db->setKarteShopDaten( id, es, tp, vp ) )
+        {
+            zKlient->sendeEncrypted( "\1", 1 );
+            return 1;
+        }
+        fehler = "Fehler beim setzen der Shop Werte.";
+        return 0;
+    }
+    case 0xB: // Beschreibung Nachricht
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        if( !beschreibung->prozessMessage( zKlient ) )
+            fehler = beschreibung->getLetzterFehler();
+        else
+            return 1;
+        return 0;
+    }
+    case 0xC: // Teams Nachricht
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        if( !teams->prozessMessage( zKlient ) )
+            fehler = teams->getLetzterFehler();
+        else
+            return 1;
+        return 0;
+    }
+    case 0xD: // Dateien Nachicht
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        if( !dateien->prozessMessage( zKlient ) )
+            fehler = dateien->getLetzterFehler();
+        else
+            return 1;
+        return 0;
+    }
+    case 0xE: // Init Editor
+    {
+        if( editorDll )
+        {
+            if( editor )
+                editor = editor->release();
+            FreeLibrary( editorDll );
+        }
+        if( !ini->wertExistiert( "spielePfad" ) )
+        {
+            fehler = "Diese Option ist noch nicht verfügbar. Error Code: " __FILE__ ":";
+            fehler += __LINE__;
+            return 0;
+        }
+        Text pf = ini->zWert( "spielePfad" )->getText();
+        pf += "/";
+        int said = db->getSpielArtId( id );
+        if( !said )
+        {
+            fehler = "Diese Option ist noch nicht verfügbar. Error Code: " __FILE__ ":";
+            fehler += __LINE__;
+            return 0;
+        }
+        pf += said;
+        pf += "/bin/game";
+#ifdef WIN32
+        pf += ".dll";
+#else
+        pf += ".so";
+#endif
+        editorDll = LoadLibrary( pfad->getText() );
+        if( !editorDll )
+        {
+            fehler = "Diese Option ist noch nicht verfügbar. Error Code: " __FILE__ ":";
+            fehler += __LINE__;
+            return 0;
+        }
+        pfad->release();
+        DllStart getEditorKlasse = (DllStart)GetProcAddress( editorDll, "getEditorKlasse" );
+        if( !getEditorKlasse )
+        {
+            fehler = "Diese Option ist noch nicht verfügbar. Error Code: " __FILE__ ":";
+            fehler += __LINE__;
+            FreeLibrary( editorDll );
+            editorDll = 0;
+            return 0;
+        }
+        editor = getEditorKlasse();
+        if( !editor )
+        {
+            fehler = "Diese Option ist noch nicht verfügbar. Error Code: " __FILE__ ":";
+            fehler += __LINE__;
+            FreeLibrary( editorDll );
+            editorDll = 0;
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        Text p = pf.getText();
+        p += "/live";
+        editor->setPfad( p );
+        editor->open();
+        return 1;
+    }
+    case 0xF:
+    { // Editor Nachricht
+        if( !editor )
+        {
+            fehler = "Der Editor wurde nicht initialisiert. Error Code: " __FILE__ ":";
+            fehler += __LINE__;
+            editorDll = 0;
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        if( !editor->nachricht( zKlient ) )
+            fehler = editor->getLetzterFehler();
+        else
+            return 1;
+        return 0;
+    }
+    default:
+        fehler = "Unbekannte Nachricht. Eventuell ist der Client nicht auf dem neusten Stand.";
+    }
+    return 0;
+}
+
+void KarteEditor::removeError()
+{
+    fehler = "";
+}
+
+// constant
+bool KarteEditor::inUpdate() const
+{
+    return db->istKarteInUpdate( id );
+}
+
+bool KarteEditor::istOk() const
+{
+    return fehler.getLength() == 0;
+}
+
+char *KarteEditor::getLetzterFehler() const
+{
+    return fehler;
+}
+
+char *KarteEditor::getPfad() const
+{
+    return pfad->getText();
+}
+
+// Reference Counting
+KarteEditor *KarteEditor::getThis()
+{
+    ref++;
+    return this;
+}
+
+KarteEditor *KarteEditor::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 65 - 0
EditorServer/KarteEditor.h

@@ -0,0 +1,65 @@
+#include <Text.h>
+#include <Zeit.h>
+#include "Server.h"
+#ifdef WIN32
+#include "../../Datenbank/Datenbank.h"
+#include "ShopSeite/SSEditor.h"
+#include "Beschreibung/BeschreibungEditor.h"
+#include "Teams/TeamsEditor.h"
+#include "Dateien/DateienEditor.h"
+#include "EditorV/ESEditorV.h"
+#else
+#include "Datenbank.h"
+#include "SSEditor.h"
+#include "BeschreibungEditor.h"
+#include "TeamsEditor.h"
+#include "DateienEditor.h"
+#include "ESEditorV.h"
+#define HINSTANCE        void*
+#endif
+
+using namespace Framework;
+using namespace Network;
+
+class KarteEditor
+{
+private:
+	int id;
+	Text *pfad;
+	EdSDatenbank *db;
+    SSEditor *shop;
+    BeschreibungEditor *beschreibung;
+    TeamsEditor *teams;
+    DateienEditor *dateien;
+	Text fehler;
+    InitDatei *ini;
+    ESEditorV *editor;
+    HINSTANCE editorDll;
+	int ref;
+    // private
+    int findeDateien( char *pf, RCArray< Text > *pfad );
+
+public:
+	// Konstruktor
+	KarteEditor( int id, EdSDatenbank *datenbank, char *pf, InitDatei *zIni );
+	// Destruktor
+	~KarteEditor();
+	// nicht constant
+	bool getAbbildListe( RCArray< Text > *name, RCArray< Zeit > *datum );
+    int getDateiUpdateListe( char *p, RCArray< Text > *pfad );
+    bool abbildErstellen( char *name );
+    bool abbildRemove( char *name );
+    bool abbildHerstellen( char *name );
+    bool startUpdate();
+    bool startShopUpdate();
+    bool prozessMessage( SKlient *zKlient );
+    void removeError();
+	// constant
+    bool inUpdate() const;
+	bool istOk() const;
+	char *getLetzterFehler() const;
+    char *getPfad() const;
+	// Reference Counting
+	KarteEditor *getThis();
+	KarteEditor *release();
+};

+ 247 - 0
EditorServer/KsgsBeschreibung.h

@@ -0,0 +1,247 @@
+const char *_neu_karte_ksgs_beschreibung = 
+"var bool erlaubt;\n"
+"var bool begin;\n"
+"\n"
+"class TextErscheinen\n"
+"{\n"
+"private:\n"
+"    var TextFeld beschreibung;\n"
+"    var Text txt;\n"
+"    var int num;\n"
+"    var int län;\n"
+"    var double z;\n"
+"public:\n"
+"    func void initKA()\n"
+"    {\n"
+"        initTextFeld( beschreibung, 5, 5, 568, 418, \"\", 0x101 );\n"
+"        txt = \"Kartenbeschreibung hier insert.\";\n"
+"        län = txt.getLength();\n"
+"        num = 0;\n"
+"        z = 0;\n"
+"    }\n"
+"    func void initIG()\n"
+"    {\n"
+"        initTextFeld( beschreibung, 5, 5, 238, 340, \"\", 0x101 );\n"
+"        txt = \"Kartenbeschreibung hier insert.\";\n"
+"        län = txt.getLength();\n"
+"        num = 0;\n"
+"        z = 0;\n"
+"    }\n"
+"    func void setErlaubt()\n"
+"    {\n"
+"        if( erlaubt == false )\n"
+"        {\n"
+"            if( beschreibung.getText().hat( \"Diese Karte ist momentan nicht verfügbar.\" ) == false )\n"
+"            {\n"
+"                beschreibung.addZeile( \"Diese Karte ist momentan nicht verfügbar.\" );\n"
+"            }\n"
+"        }\n"
+"        if( erlaubt == true )\n"
+"        {\n"
+"            if( beschreibung.getText().hat( \"Diese Karte ist momentan nicht verfügbar.\" ) == true )\n"
+"            {\n"
+"                var Text txt;\n"
+"                txt = beschreibung.getText();\n"
+"                txt.remove( txt.positionVon( \"Diese Karte ist momentan nicht verfügbar\", 0 ), txt.getLength() );\n"
+"                beschreibung.setText( txt );\n"
+"            }\n"
+"        }\n"
+"    }\n"
+"    func bool next( double zeit )\n"
+"    {\n"
+"        z += zeit;\n"
+"        if( ( z > 0.03 ) && ( num < län ) )\n"
+"        {\n"
+"            var Text t;\n"
+"            t = beschreibung.getText();\n"
+"            while( z > 0.03 )\n"
+"            {\n"
+"                z -= 0.03;\n"
+"                t.append( txt.getTeilText( num, num + 1 ) );\n"
+"                num += 1;\n"
+"                if( num < län )\n"
+"                {\n"
+"                    break;\n"
+"                }\n"
+"            }\n"
+"            beschreibung.setText( t );\n"
+"            return true;\n"
+"        }\n"
+"        return false;\n"
+"    }\n"
+"    func void render( Bild b )\n"
+"    {\n"
+"        beschreibung.render( b );\n"
+"    }\n"
+"};\n"
+"\n"
+"class Anmeldung\n"
+"{\n"
+"private:\n"
+"    var double y;\n"
+"    var double yS;\n"
+"    var double alpha;\n"
+"    var Knopf alleine;\n"
+"    var Knopf gruppe;\n"
+"public:\n"
+"\n"
+"    func void initKA()\n"
+"    {\n"
+"        yS = 268;\n"
+"        y = 0;\n"
+"        alpha = 0;\n"
+"        initKnopf( alleine, 5, 0, 100, 20, \"Anmelden\" );\n"
+"        alleine.setMausEreignis( \"alleineME\" );\n"
+"        initKnopf( gruppe, 463, 0, 100, 20, \"Gruppe Erstellen\" );\n"
+"        gruppe.setMausEreignis( \"gruppeME\" );\n"
+"    }\n"
+"    func bool tick( double z )\n"
+"    {\n"
+"        if( ( alpha == 255 ) && ( y >= 398 ) )\n"
+"        {\n"
+"            var bool ret = false;\n"
+"            ret |= alleine.tick( z );\n"
+"            ret |= gruppe.tick( z );\n"
+"            return ret;\n"
+"        }\n"
+"        alpha += ( z * 100 );\n"
+"        if( alpha > 255 )\n"
+"        {\n"
+"            alpha = 255;\n"
+"        }\n"
+"        y += ( yS * z );\n"
+"        yS -= ( z * 40 );\n"
+"        if( yS < 0 )\n"
+"        {\n"
+"            yS = 0;\n"
+"        }\n"
+"        if( y > 398 )\n"
+"        {\n"
+"            y = 398;\n"
+"        }\n"
+"        return true;\n"
+"    }\n"
+"    func void maus( MausEreignis me )\n"
+"    {\n"
+"        me.setMy( me.my - y );\n"
+"        alleine.doMausEreignis( me );\n"
+"        gruppe.doMausEreignis( me );\n"
+"        me.setMy( me.my + y );\n"
+"    }\n"
+"    func void render( Bild b )\n"
+"    {\n"
+"        b.setAlpha( alpha );\n"
+"        if( b.setDrawOptions( 0, y, 578, 200 ) )\n"
+"        {\n"
+"            alleine.render( b );\n"
+"            gruppe.render( b );\n"
+"            b.releaseDrawOptions();\n"
+"        }\n"
+"        b.releaseAlpha();\n"
+"    }\n"
+"};\n"
+"\n"
+"var TextErscheinen beschreibung;\n"
+"var Anmeldung anmeldung;\n"
+"\n"
+"func void start()\n"
+"{\n"
+"    erlaubt = false;\n"
+"    begin = false;\n"
+"}\n"
+"\n"
+"func void _set_Erlaubt( bool e )\n"
+"{\n"
+"    erlaubt = e;\n"
+"    if( begin == false )\n"
+"    {\n"
+"        beschreibung.initKA();\n"
+"        anmeldung.initKA();\n"
+"        begin = true;\n"
+"    }\n"
+"    beschreibung.setErlaubt();\n"
+"}\n"
+"\n"
+"func void _in_gruppe()\n"
+"{\n"
+"    if( begin == false )\n"
+"    {\n"
+"        beschreibung.initIG();\n"
+"        begin = true;\n"
+"    }\n"
+"}\n"
+"\n"
+"func void initTextFeld( TextFeld tf, int x, int y, int br, int hö, Text t, int style )\n"
+"{\n"
+"    tf.setPosition( x, y );\n"
+"    tf.setGröße( br, hö );\n"
+"    tf.setStyle( style );\n"
+"    tf.setSchriftFarbe( 0xFFFFFFFF );\n"
+"    tf.setText( t );\n"
+"}\n"
+"\n"
+"func void initKnopf( Knopf k, int x, int y, int br, int hö, Text t )\n"
+"{\n"
+"    k.setPosition( x, y );\n"
+"    k.setGröße( br, hö );\n"
+"    k.setText( t );\n"
+"    k.addStyle( 0x1 );\n"
+"}\n"
+"\n"
+"func bool maus( MausEreignis me )\n"
+"{\n"
+"    if( begin == false )\n"
+"    {\n"
+"        return me.verarbeitet;\n"
+"    }\n"
+"    if( erlaubt == true )\n"
+"    {\n"
+"        anmeldung.maus( me );\n"
+"    }\n"
+"    return me.verarbeitet;\n"
+"}\n"
+"\n"
+"func bool tick( double z )\n"
+"{\n"
+"    if( begin == false )\n"
+"    {\n"
+"        return false;\n"
+"    }\n"
+"    var bool ret;\n"
+"    ret = beschreibung.next( z );\n"
+"    if( erlaubt == true )\n"
+"    {\n"
+"        ret |= anmeldung.tick( z );\n"
+"    }\n"
+"    return ret;\n"
+"}\n"
+"\n"
+"func void render( Bild rObj )\n"
+"{\n"
+"    if( begin == true )\n"
+"    {\n"
+"        beschreibung.render( rObj );\n"
+"        if( erlaubt == true )\n"
+"        {\n"
+"            anmeldung.render( rObj );\n"
+"        }\n"
+"    }\n"
+"}\n"
+"\n"
+"func bool alleineME( MausEreignis me )\n"
+"{\n"
+"    if( me.id == 3 )\n"
+"    {\n"
+"        Rückruf( \"anmelden\" );\n"
+"    }\n"
+"    return true;\n"
+"}\n"
+"\n"
+"func bool gruppeME( MausEreignis me )\n"
+"{\n"
+"    if( me.id == 3 )\n"
+"    {\n"
+"        Rückruf( \"gruppeErstellen\" );\n"
+"    }\n"
+"    return true;\n"
+"}";

+ 382 - 0
EditorServer/KsgsShopSeite.h

@@ -0,0 +1,382 @@
+const char *_neu_karte_ksgs_shop_seite =
+"\n"
+"var int besitzStatus;\n"
+"var int erwerbbarStatus;\n"
+"var Bild goldBild;\n"
+"var Bild silberBild;\n"
+"var Bild kupferBild;\n"
+"\n"
+"class TextErscheinen\n"
+"{\n"
+"private:\n"
+"    var TextFeld beschreibung;\n"
+"    var Text txt;\n"
+"    var int num;\n"
+"    var int län;\n"
+"    var double z;\n"
+"public:\n"
+"    func void init( int besitzStatus )\n"
+"    {\n"
+"        initTextFeld( beschreibung, 5, 5, 545, 180, \"\", 0x101 );\n"
+"        txt = \"Kartenbeschreibung hier insert\n\";\n"
+"        txt += \"Maximale Spieleranzahl: 0\n\";\n"
+"        txt += \"Teamanzahl: 0\n\";\n"
+"        txt += \"Maximale Spieler pro Team: 0\n\";\n"
+"        txt += \"Spieltyp: Team gegen Team\n\";\n"
+"        if( besitzStatus == 1 )\n"
+"        {\n"
+"            txt += \"Du besitzt die Testversion dieser Karte.\n\";\n"
+"            txt += \"Anzahl verbleibender Spiele: \";\n"
+"            txt += Rückruf( \"GetTestVersionVerbleibend\" );\n"
+"        }\n"
+"        if( besitzStatus == 2 )\n"
+"        {\n"
+"            txt += \"Du besitzt die Vollversion dieser Karte.\";\n"
+"        }\n"
+"        län = txt.getLength();\n"
+"        num = 0;\n"
+"        z = 0;\n"
+"    }\n"
+"    func bool next( double zeit )\n"
+"    {\n"
+"        z += zeit;\n"
+"        if( ( z > 0.03 ) && ( num < län ) )\n"
+"        {\n"
+"            var Text t;\n"
+"            t = beschreibung.getText();\n"
+"            while( z > 0.03 )\n"
+"            {\n"
+"                z -= 0.03;\n"
+"                t.append( txt.getTeilText( num, num + 1 ) );\n"
+"                num += 1;\n"
+"                if( num < län )\n"
+"                {\n"
+"                    break;\n"
+"                }\n"
+"            }\n"
+"            beschreibung.setText( t );\n"
+"            return true;\n"
+"        }\n"
+"        return false;\n"
+"    }\n"
+"    func void render( Bild b )\n"
+"    {\n"
+"        beschreibung.render( b );\n"
+"    }\n"
+"};\n"
+"\n"
+"class TestVersion\n"
+"{\n"
+"private:\n"
+"    var double y;\n"
+"    var int x;\n"
+"    var double yS;\n"
+"    var int alpha;\n"
+"    var TextFeld tve;\n"
+"    var TextFeld tvkosten;\n"
+"    var TextFeld tvGoldTF;\n"
+"    var TextFeld tvSilberTF;\n"
+"    var TextFeld tvKupferTF;\n"
+"    var BildO tvGoldBildO;\n"
+"    var BildO tvSilberBildO;\n"
+"    var BildO tvKupferBildO;\n"
+"    var Knopf tvKaufen;\n"
+"    var TextFeld tvNGK;\n"
+"public:\n"
+"    func void init()\n"
+"    {\n"
+"        yS = 150;\n"
+"        x = 0;\n"
+"        y = 0;\n"
+"        alpha = 0;\n"
+"        initTextFeld( tve, 5, 0, 300, 20, \"\", 0x101 );\n"
+"        initTextFeld( tvkosten, 5, 25, 50, 20, \"\", 0x701 );\n"
+"        initTextFeld( tvGoldTF, 60, 25, 0, 0, \"\", 0x701 );\n"
+"        initTextFeld( tvSilberTF, 90, 25, 0, 0, \"\", 0x701 );\n"
+"        initTextFeld( tvKupferTF, 120, 25, 0, 0, \"\", 0x701 );\n"
+"        initTextFeld( tvNGK, 5, 75, 200, 20, \"\", 0x101 );\n"
+"        if( ( ( besitzStatus == 0 ) || ( besitzStatus == 1 ) ) && ( erwerbbarStatus != 0 ) && ( erwerbbarStatus != 2 ) )\n"
+"        {\n"
+"            tve.setText( \"10 Spiele Testversion\" );\n"
+"            tvkosten.setText( \"Kosten: \" );\n"
+"            var int preis;\n"
+"            preis = Rückruf( \"GetPreis\", 0 );\n"
+"            var Text preisT = preis / 10000;\n"
+"            tvGoldTF.setText( preisT );\n"
+"            preisT = ( preis / 100 ) % 100;\n"
+"            tvSilberTF.setText( preisT );\n"
+"            preisT = preis % 100;\n"
+"            tvKupferTF.setText( preisT );\n"
+"            tvGoldTF.setGrößeNachText();\n"
+"            tvSilberTF.setGrößeNachText();\n"
+"            tvKupferTF.setGrößeNachText();\n"
+"            tvGoldTF.setGröße( tvGoldTF.getBreite(), 20 );\n"
+"            tvSilberTF.setGröße( tvSilberTF.getBreite(), 20 );\n"
+"            tvKupferTF.setGröße( tvKupferTF.getBreite(), 20 );\n"
+"            tvSilberTF.setPosition( tvSilberTF.getX() + tvGoldTF.getBreite(), tvSilberTF.getY() );\n"
+"            tvKupferTF.setPosition( tvKupferTF.getX() + tvGoldTF.getBreite() + tvSilberTF.getBreite(), tvSilberTF.getY() );\n"
+"            initBildO( tvGoldBildO, 60 + tvGoldTF.getBreite(), 25, goldBild );\n"
+"            initBildO( tvSilberBildO, 90 + tvGoldTF.getBreite() + tvSilberTF.getBreite(), 25, silberBild );\n"
+"            initBildO( tvKupferBildO, 120 + tvGoldTF.getBreite() + tvSilberTF.getBreite() + tvKupferTF.getBreite(), 25, kupferBild );\n"
+"            initKnopf( tvKaufen, 5, 50, 100, 20, \"Erwerben\" );\n"
+"            tvKaufen.setMausEreignis( \"tvKME\" );\n"
+"            if( preis > Rückruf( \"GetKupfer\" ) )\n"
+"            {\n"
+"                tvKaufen.removeStyle( 0x2 );\n"
+"                tvNGK.setText( \"Du hast nicht genug Geld.\" );\n"
+"            }\n"
+"        }\n"
+"    }\n"
+"    func bool tick( double z )\n"
+"    {\n"
+"        if( ( alpha == 255 ) && ( y >= 280 ) )\n"
+"        {\n"
+"            return tvKaufen.tick( z );\n"
+"        }\n"
+"        alpha += ( z * 100 );\n"
+"        if( alpha > 255 )\n"
+"        {\n"
+"            alpha = 255;\n"
+"        }\n"
+"        y += ( yS * z );\n"
+"        yS -= ( z * 40 );\n"
+"        if( yS < 0 )\n"
+"        {\n"
+"            yS = 0;\n"
+"        }\n"
+"        if( y > 280 )\n"
+"        {\n"
+"            y = 280;\n"
+"        }\n"
+"        return true;\n"
+"    }\n"
+"    func void maus( MausEreignis me )\n"
+"    {\n"
+"        me.setMy( me.my - y );\n"
+"        tvKaufen.doMausEreignis( me );\n"
+"        me.setMy( me.my + y );\n"
+"    }\n"
+"    func void render( Bild b )\n"
+"    {\n"
+"        if( ( erwerbbarStatus != 0 ) && ( erwerbbarStatus != 2 ) )\n"
+"        {\n"
+"            b.setAlpha( alpha );\n"
+"            if( b.setDrawOptions( 0, y, 300, 200 ) )\n"
+"            {\n"
+"                tve.render( b );\n"
+"                tvkosten.render( b );\n"
+"                tvGoldTF.render( b );\n"
+"                tvSilberTF.render( b );\n"
+"                tvKupferTF.render( b );\n"
+"                tvGoldBildO.render( b );\n"
+"                tvSilberBildO.render( b );\n"
+"                tvKupferBildO.render( b );\n"
+"                tvKaufen.render( b );\n"
+"                tvNGK.render( b );\n"
+"                b.releaseDrawOptions();\n"
+"            }\n"
+"            b.releaseAlpha();\n"
+"        }\n"
+"    }\n"
+"};\n"
+"\n"
+"class VollVersion\n"
+"{\n"
+"private:\n"
+"    var double y;\n"
+"    var int x;\n"
+"    var double yS;\n"
+"    var int alpha;\n"
+"    var TextFeld vve;\n"
+"    var TextFeld vvkosten;\n"
+"    var TextFeld vvGoldTF;\n"
+"    var TextFeld vvSilberTF;\n"
+"    var TextFeld vvKupferTF;\n"
+"    var BildO vvGoldBildO;\n"
+"    var BildO vvSilberBildO;\n"
+"    var BildO vvKupferBildO;\n"
+"    var Knopf vvKaufen;\n"
+"    var TextFeld vvNGK;\n"
+"public:\n"
+"    func void init()\n"
+"    {\n"
+"        yS = 150;\n"
+"        x = 0;\n"
+"        y = 0;\n"
+"        alpha = 0;\n"
+"        initTextFeld( vve, 0, 0, 100, 20, \"\", 0x101 );\n"
+"        initTextFeld( vvkosten, 410, 25, 50, 20, \"\", 0x701 );\n"
+"        initTextFeld( vvGoldTF, 470, 25, 0, 0, \"\", 0x701 );\n"
+"        initTextFeld( vvSilberTF, 500, 25, 0, 0, \"\", 0x701 );\n"
+"        initTextFeld( vvKupferTF, 530, 25, 0, 0, \"\", 0x701 );\n"
+"        initTextFeld( vvNGK, 390, 75, 160, 20, \"\", 0x101 );\n"
+"        if( ( besitzStatus == 0 ) && ( erwerbbarStatus != 0 ) && ( erwerbbarStatus != 1 ) )\n"
+"        {\n"
+"            vve.setText( \"Vollversion\" );\n"
+"            vve.setGrößeNachText();\n"
+"            vve.setPosition( 550 - vve.getBreite(), vve.getY() );\n"
+"            vvkosten.setText( \"Kosten: \" );\n"
+"            var int preis;\n"
+"            preis = Rückruf( \"GetPreis\", 1 );\n"
+"            var Text preisT = preis / 10000;\n"
+"            vvGoldTF.setText( preisT );\n"
+"            preisT = ( preis / 100 ) % 100;\n"
+"            vvSilberTF.setText( preisT );\n"
+"            preisT = preis % 100;\n"
+"            vvKupferTF.setText( preisT );\n"
+"            vvGoldTF.setGrößeNachText();\n"
+"            vvSilberTF.setGrößeNachText();\n"
+"            vvKupferTF.setGrößeNachText();\n"
+"            vvGoldTF.setGröße( vvGoldTF.getBreite(), 20 );\n"
+"            vvSilberTF.setGröße( vvSilberTF.getBreite(), 20 );\n"
+"            vvKupferTF.setGröße( vvKupferTF.getBreite(), 20 );\n"
+"            vvKupferTF.setPosition( vvKupferTF.getX() - vvKupferTF.getBreite(), vvKupferTF.getY() );\n"
+"            vvSilberTF.setPosition( ( vvSilberTF.getX() - vvKupferTF.getBreite() ) - vvSilberTF.getBreite(), vvSilberTF.getY() );\n"
+"            vvGoldTF.setPosition( ( ( vvGoldTF.getX() - vvKupferTF.getBreite() ) - vvSilberTF.getBreite() ) - vvGoldTF.getBreite(), vvGoldTF.getY() );\n"
+"            vvkosten.setPosition( vvGoldTF.getX() - 55, vvkosten.getY() );\n"
+"            initBildO( vvGoldBildO, vvGoldTF.getX() + vvGoldTF.getBreite(), 25, goldBild );\n"
+"            initBildO( vvSilberBildO, vvSilberTF.getX() + vvSilberTF.getBreite(), 25, silberBild );\n"
+"            initBildO( vvKupferBildO, vvKupferTF.getX() + vvKupferTF.getBreite(), 25, kupferBild );\n"
+"            initKnopf( vvKaufen, 450, 50, 100, 20, \"Erwerben\" );\n"
+"            vvKaufen.setMausEreignis( \"vvKME\" );\n"
+"            if( preis > Rückruf( \"GetKupfer\" ) )\n"
+"            {\n"
+"                vvKaufen.removeStyle( 0x2 );\n"
+"                vvNGK.setText( \"Du hast nicht genug Geld.\" );\n"
+"            }\n"
+"        }\n"
+"    }\n"
+"    func bool tick( double z )\n"
+"    {\n"
+"        if( ( alpha == 255 ) && ( y >= 280 ) )\n"
+"        {\n"
+"            return vvKaufen.tick( z );\n"
+"        }\n"
+"        alpha += ( z * 100 );\n"
+"        if( alpha > 255 )\n"
+"        {\n"
+"            alpha = 255;\n"
+"        }\n"
+"        y += ( yS * z );\n"
+"        yS -= ( z * 40 );\n"
+"        if( yS < 0 )\n"
+"        {\n"
+"            yS = 0;\n"
+"        }\n"
+"        if( y > 280 )\n"
+"        {\n"
+"            y = 280;\n"
+"        }\n"
+"        return true;\n"
+"    }\n"
+"    func void maus( MausEreignis me )\n"
+"    {\n"
+"        me.setMy( me.my - y );\n"
+"        vvKaufen.doMausEreignis( me );\n"
+"        me.setMy( me.my - y );\n"
+"    }\n"
+"    func void render( Bild b )\n"
+"    {\n"
+"        if( ( erwerbbarStatus != 0 ) && ( erwerbbarStatus != 1 ) )\n"
+"        {\n"
+"            b.setAlpha( alpha );\n"
+"            if( b.setDrawOptions( 0, y, 700, 200 ) )\n"
+"            {\n"
+"                vve.render( b );\n"
+"                vvkosten.render( b );\n"
+"                vvGoldTF.render( b );\n"
+"                vvSilberTF.render( b );\n"
+"                vvKupferTF.render( b );\n"
+"                vvGoldBildO.render( b );\n"
+"                vvSilberBildO.render( b );\n"
+"                vvKupferBildO.render( b );\n"
+"                vvKaufen.render( b );\n"
+"                vvNGK.render( b );\n"
+"                b.releaseDrawOptions();\n"
+"            }\n"
+"            b.releaseAlpha();\n"
+"        }\n"
+"    }\n"
+"};\n"
+"\n"
+"var TextErscheinen beschreibung;\n"
+"var TestVersion tv;\n"
+"var VollVersion vv;\n"
+"\n"
+"func void start()\n"
+"{\n"
+"    besitzStatus = Rückruf( \"GetBesitzStatus\" );\n"
+"    erwerbbarStatus = Rückruf( \"GetErwerbbarStatus\" );\n"
+"    goldBild = Rückruf( \"GetBild\", \"data/bilder/system.ltdb\", \"system.ltdb/gold.jpg\" );\n"
+"    silberBild = Rückruf( \"GetBild\", \"data/bilder/system.ltdb\", \"system.ltdb/silber.jpg\" );\n"
+"    kupferBild = Rückruf( \"GetBild\", \"data/bilder/system.ltdb\", \"system.ltdb/kupfer.jpg\" );\n"
+"    beschreibung.init( besitzStatus );\n"
+"    tv.init();\n"
+"    vv.init();\n"
+"}\n"
+"\n"
+"func void initTextFeld( TextFeld tf, int x, int y, int br, int hö, Text t, int style )\n"
+"{\n"
+"    tf.setPosition( x, y );\n"
+"    tf.setGröße( br, hö );\n"
+"    tf.setStyle( style );\n"
+"    tf.setSchriftFarbe( 0xFFFFFFFF );\n"
+"    tf.setText( t );\n"
+"}\n"
+"\n"
+"func void initBildO( BildO bo, int x, int y, Bild b )\n"
+"{\n"
+"    bo.setPosition( x, y );\n"
+"    bo.setGröße( b.getBreite(), b.getHeight() );\n"
+"    bo.setStyle( 0x1 );\n"
+"    bo.setBild( b );\n"
+"}\n"
+"\n"
+"func void initKnopf( Knopf k, int x, int y, int br, int hö, Text t )\n"
+"{\n"
+"    k.setPosition( x, y );\n"
+"    k.setGröße( br, hö );\n"
+"    k.setText( t );\n"
+"    k.addStyle( 0x1 );\n"
+"}\n"
+"\n"
+"func bool maus( MausEreignis me )\n"
+"{\n"
+"    tv.maus( me );\n"
+"    vv.maus( me );\n"
+"    return me.verarbeitet;\n"
+"}\n"
+"\n"
+"func bool tick( double z )\n"
+"{\n"
+"    var bool ret;\n"
+"    ret = beschreibung.next( z );\n"
+"    ret |= tv.tick( z );\n"
+"    ret |= vv.tick( z );\n"
+"    return ret;\n"
+"}\n"
+"\n"
+"func void render( Bild rObj )\n"
+"{\n"
+"    beschreibung.render( rObj );\n"
+"    tv.render( rObj );\n"
+"    vv.render( rObj );\n"
+"}\n"
+"\n"
+"func bool tvKME( MausEreignis me )\n"
+"{\n"
+"    if( me.id == 3 )\n"
+"    {\n"
+"        Rückruf( \"Kaufen\", 0 );\n"
+"    }\n"
+"    return true;\n"
+"}\n"
+"\n"
+"func bool vvKME( MausEreignis me )\n"
+"{\n"
+"    if( me.id == 3 )\n"
+"    {\n"
+"        Rückruf( \"Kaufen\", 1 );\n"
+"    }\n"
+"    return true;\n"
+"}";

+ 525 - 0
EditorServer/SSEditor.cpp

@@ -0,0 +1,525 @@
+#include "SSEditor.h"
+#include "Datei.h"
+#include "DateiSystem.h"
+#include "Bild.h"
+
+// Inhalt der SSEditor Klasse aus SSEditor.h
+// Konstruktor
+SSEditor::SSEditor( char *pf )
+{
+    pfad = pf;
+    pfad += "/live/shop";
+    workPfad = "";
+    fehler = "";
+    ref = 1;
+}
+
+// Destruktor
+SSEditor::~SSEditor()
+{}
+
+// nicht constant
+bool SSEditor::prozessMessage( SKlient *zKlient )
+{
+    char message = 0;
+    zKlient->getNachrichtEncrypted( &message, 1 );
+    switch( message )
+    {
+    case 0x1: // Neue Datei erstellen
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char typ = 0;
+        zKlient->getNachrichtEncrypted( &typ, 1 );
+        char len = 0;
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *name = new char[ len + 1 ];
+        if( len )
+            zKlient->getNachrichtEncrypted( name, len );
+        name[ (int)len ] = 0;
+        if( !len )
+        {
+            delete[] name;
+            fehler = "Du musst einen Dateinamen angeben.";
+            return 0;
+        }
+        Text n = name;
+        delete[] name;
+        if( n.hat( "/" ) || n.hat( "." ) )
+        {
+            fehler = "Du musst einen gültigen Dateinamen angeben.";
+            return 0;
+        }
+        Text p = pfad.getText();
+        p += workPfad.getText();
+        p += "/";
+        p += n;
+        if( typ == 1 )
+        {
+            p += ".ltdb";
+            if( !DateiPfadErstellen( p ) )
+            {
+                fehler = "Fehler beim erstellen der Datei.";
+                return 0;
+            }
+            zKlient->sendeEncrypted( "\1", 1 );
+            return 1;
+        }
+        if( typ == 2 )
+        {
+            p += ".ksgs";
+            if( !DateiPfadErstellen( p ) )
+            {
+                fehler = "Fehler beim erstellen der Datei.";
+                return 0;
+            }
+            zKlient->sendeEncrypted( "\1", 1 );
+            return 1;
+        }
+        if( typ == 0 )
+        {
+            p += "/tmp";
+            if( !DateiPfadErstellen( p ) )
+            {
+                fehler = "Fehler beim erstellen der Datei.";
+                return 0;
+            }
+            DateiRemove( p );
+            p.remove( p.getLength() - 4, p.getLength() );
+            zKlient->sendeEncrypted( "\1", 1 );
+            return 1;
+        }
+        fehler = "Ungültiger Dateityp.";
+        return 0;
+    }
+    case 0x2: // Ordner open
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char len = 0;
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *name = new char[ len + 1 ];
+        name[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( name, len );
+        if( Text( ".." ).istGleich( name ) )
+        {
+            if( workPfad.getLength() )
+            {
+                int anz = workPfad.anzahlVon( "/" );
+                if( anz )
+                    workPfad.remove( workPfad.positionVon( "/", anz - 1 ), workPfad.getLength() );
+                else
+                    workPfad = "";
+            }
+            delete[] name;
+            zKlient->sendeEncrypted( "\1", 1 );
+            return 1;
+        }
+        else
+        {
+            Text p = pfad.getText();
+            p += workPfad.getText();
+            p += "/";
+            p += name;
+            Datei d;
+            d.setDatei( p );
+            if( !d.existiert() )
+            {
+                delete[] name;
+                fehler = "Die Datei konnte nicht gefunden werden.";
+                return 0;
+            }
+            else
+            {
+                if( d.istOrdner() )
+                {
+                    workPfad += "/";
+                    workPfad += name;
+                }
+                delete[] name;
+                zKlient->sendeEncrypted( "\1", 1 );
+                return 1;
+            }
+        }
+    }
+    case 0x3: // Bild laden
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char len = 0;
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *dName = new char[ len + 1 ];
+        dName[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( dName, len );
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *bName = new char[ len + 1 ];
+        bName[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( bName, len );
+        if( !textLength( dName ) || !textLength( bName ) )
+        {
+            delete[] dName;
+            delete[] bName;
+            fehler = "Du musst ein Bild und eine Datei angeben.";
+            return 0;
+        }
+        Text p = pfad.getText();
+        p += workPfad.getText();
+        p += "/";
+        p += dName;
+        delete[] dName;
+        if( !DateiExistiert( p ) )
+        {
+            delete[] bName;
+            fehler = "Die Datei wurde nicht gefunden.";
+            return 0;
+        }
+        LTDBDatei dat;
+        dat.setDatei( p.getThis() );
+        dat.leseDaten( 0 );
+        Bild *b = dat.laden( 0, new Text( bName ) );
+        delete[] bName;
+        if( !b )
+        {
+            fehler = "Das Bild wurde nicht gefunden.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        int br = b->getBreite();
+        int hi = b->getHeight();
+        zKlient->sendeEncrypted( (char*)&br, 4 );
+        zKlient->sendeEncrypted( (char*)&hi, 4 );
+        char *buffer = (char*)b->getBuffer();
+        __int64 gr = br * hi * 4;
+        for( int i = 0, l = gr > 2048 ? 2048 : (int)gr; gr > 0; i += l, gr -= l, l = gr > 2048 ? 2048 : (int)gr )
+            zKlient->sende( &( buffer[ i ] ), l );
+        b->release();
+        return 1;
+    }
+    case 0x4: // Datei remove
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char len = 0;
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *name = new char[ len + 1 ];
+        name[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( name, len );
+        if( Text( name ).istGleich( ".." ) )
+        {
+            fehler = "Du kannst diese Datei nicht remove.";
+            return 0;
+        }
+        Text p = pfad.getText();
+        p += workPfad.getText();
+        if( !Text( "." ).istGleich( name ) )
+        {
+            p += "/";
+            p += name;
+            int anz = workPfad.anzahlVon( "/" );
+            if( anz )
+                workPfad.remove( workPfad.positionVon( "/", anz - 1 ), workPfad.getLength() );
+            else
+                workPfad = "";
+        }
+        delete[] name;
+        if( !DateiExistiert( p ) )
+        {
+            fehler = "Die Datei wurde nicht gefunden.";
+            return 0;
+        }
+        if( !DateiRemove( p ) )
+        {
+            fehler = "Fehler beim remove der Datei.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        return 1;
+    }
+    case 0x5: // Text speichern
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char len = 0;
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *name = new char[ len + 1 ];
+        name[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( name, len );
+        if( Text( name ).istGleich( ".." ) )
+        {
+            fehler = "Du kannst diese Datei nicht bearbeiten.";
+            return 0;
+        }
+        Text p = pfad.getText();
+        p += workPfad.getText();
+        p += "/";
+        p += name;
+        delete[] name;
+        if( !DateiExistiert( p ) )
+        {
+            fehler = "Die Datei wurde nicht gefunden.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        Datei d;
+        d.setDatei( p );
+        bool ok = d.open( Datei::Style::schreiben );
+        char *buffer = new char[ 2048 ];
+        int gr = 0;
+        zKlient->getNachrichtEncrypted( (char*)&gr, 4 );
+        while( gr > 0 )
+        {
+            int l = gr > 2048 ? 2048 : gr;
+            zKlient->getNachricht( buffer, l );
+            d.schreibe( buffer, l );
+            gr -= l;
+        }
+        delete[] buffer;
+        d.close();
+        if( !ok )
+        {
+            fehler = "Es ist ein Fehler beim schreiben der Datei aufgetreten.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        return 1;
+    }
+    case 0x6: // Bild remove
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char len = 0;
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *dName = new char[ len + 1 ];
+        dName[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( dName, len );
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *bName = new char[ len + 1 ];
+        bName[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( bName, len );
+        if( !textLength( dName ) || !textLength( bName ) )
+        {
+            delete[] dName;
+            delete[] bName;
+            fehler = "Du musst ein Bild und eine Datei angeben.";
+            return 0;
+        }
+        Text p = pfad.getText();
+        p += workPfad.getText();
+        p += "/";
+        p += dName;
+        delete[] dName;
+        if( !DateiExistiert( p ) )
+        {
+            delete[] bName;
+            fehler = "Die Datei wurde nicht gefunden.";
+            return 0;
+        }
+        LTDBDatei dat;
+        dat.setDatei( p.getThis() );
+        dat.leseDaten( 0 );
+        dat.remove( 0, new Text( bName ) );
+        delete[] bName;
+        zKlient->sendeEncrypted( "\1", 1 );
+        return 1;
+    }
+    case 0x7: // Bild erstellen
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char len = 0;
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *dName = new char[ len + 1 ];
+        dName[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( dName, len );
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *bName = new char[ len + 1 ];
+        bName[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( bName, len );
+        if( !textLength( dName ) || !textLength( bName ) )
+        {
+            delete[] dName;
+            delete[] bName;
+            fehler = "Du musst ein Bild und eine Datei angeben.";
+            return 0;
+        }
+        Text p = pfad.getText();
+        p += workPfad.getText();
+        p += "/";
+        p += dName;
+        delete[] dName;
+        if( !DateiExistiert( p ) )
+        {
+            delete[] bName;
+            fehler = "Die Datei wurde nicht gefunden.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        int br = 0;
+        int hi = 0;
+        zKlient->getNachrichtEncrypted( (char*)&br, 4 );
+        zKlient->getNachrichtEncrypted( (char*)&hi, 4 );
+        __int64 gr = br * hi * 4;
+        Bild *b = new Bild();
+        b->neuBild( br, hi, 0 );
+        char *buffer = (char*)b->getBuffer();
+        for( int i = 0, l = gr > 2048 ? 2048 : (int)gr; gr > 0; i += l, gr -= l, l = gr > 2048 ? 2048 : (int)gr )
+            zKlient->getNachricht( &( buffer[ i ] ), l );
+        LTDBDatei dat;
+        dat.setDatei( p.getThis() );
+        dat.leseDaten( 0 );
+        dat.remove( 0, new Text( bName ) );
+        if( dat.speichern( 0, b, new Text( bName ) ) < 0 )
+        {
+            delete[] bName;
+            fehler = "Fehler beim speichern des Bildes.";
+            return 0;
+        }
+        delete[] bName;
+        zKlient->sendeEncrypted( "\1", 1 );
+        return 1;
+    }
+    case 0x8: // Datei Liste herunterladen
+    {
+        Datei d;
+        d.setDatei( Text( pfad.getText() ) += workPfad.getText() );
+        RCArray< Text > *list = d.getDateiListe();
+        if( !list )
+        {
+            fehler = "Es ist ein Fehler beim laden der Dateiliste aufgetreten.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        int anz = list->getEintragAnzahl();
+        if( workPfad.getLength() )
+            anz++;
+        zKlient->sendeEncrypted( (char*)&anz, 4 );
+        if( workPfad.getLength() )
+        {
+            zKlient->sendeEncrypted( "\2", 1 );
+            zKlient->sendeEncrypted( "..", 2 );
+            anz--;
+        }
+        for( int i = 0; i < anz; i++ )
+        {
+            char len = (char)list->z( i )->getLength();
+            zKlient->sendeEncrypted( &len, 1 );
+            zKlient->sendeEncrypted( list->z( i )->getText(), len );
+        }
+        list->release();
+        return 1;
+    }
+    case 0x9: // Bild Liste herunterladen
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char len = 0;
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *name = new char[ len + 1 ];
+        name[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( name, len );
+        if( !textLength( name ) )
+        {
+            delete[] name;
+            fehler = "Du musst ein Bild und eine Datei angeben.";
+            return 0;
+        }
+        Text p = pfad.getText();
+        p += workPfad.getText();
+        p += "/";
+        p += name;
+        delete[] name;
+        if( !DateiExistiert( p ) )
+        {
+            fehler = "Die Datei wurde nicht gefunden.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        LTDBDatei dat;
+        dat.setDatei( p.getThis() );
+        dat.leseDaten( 0 );
+        int anz = dat.getBildAnzahl();
+        zKlient->sendeEncrypted( (char*)&anz, 4 );
+        for( int i = 0; i < anz; i++ )
+        {
+            char len = (char)dat.zBildListe()->z( i )->getLength();
+            zKlient->sendeEncrypted( &len, 1 );
+            zKlient->sendeEncrypted( dat.zBildListe()->z( i )->getText(), len );
+        }
+        return 1;
+    }
+    case 0xA: // Text laden
+    {
+        zKlient->sendeEncrypted( "\1", 1 );
+        char len = 0;
+        zKlient->getNachrichtEncrypted( &len, 1 );
+        char *name = new char[ len + 1 ];
+        name[ (int)len ] = 0;
+        if( len )
+            zKlient->getNachrichtEncrypted( name, len );
+        if( Text( name ).istGleich( ".." ) )
+        {
+            fehler = "Du kannst diese Datei nicht bearbeiten.";
+            return 0;
+        }
+        Text p = pfad.getText();
+        p += workPfad.getText();
+        p += "/";
+        p += name;
+        delete[] name;
+        if( !DateiExistiert( p ) )
+        {
+            fehler = "Die Datei wurde nicht gefunden.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        Datei d;
+        d.setDatei( p );
+        bool ok = d.open( Datei::Style::lesen );
+        char *buffer = new char[ 2048 ];
+        int gr = (int)d.getSize();
+        zKlient->sendeEncrypted( (char*)&gr, 4 );
+        while( gr > 0 )
+        {
+            int l = gr > 2048 ? 2048 : gr;
+            d.lese( buffer, l );
+            zKlient->sende( buffer, l );
+            gr -= l;
+        }
+        delete[] buffer;
+        d.close();
+        if( !ok )
+        {
+            fehler = "Es ist ein Fehler beim schreiben der Datei aufgetreten.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        return 1;
+    }
+    default:
+        fehler = "Unbekannte Nachricht. Eventuell ist der Client nicht auf dem neusten Stand.";
+    }
+    return 0;
+}
+
+// constant
+char *SSEditor::getLetzterFehler() const
+{
+    return fehler;
+}
+
+// Reference Counting
+SSEditor *SSEditor::getThis()
+{
+    ref++;
+    return this;
+}
+
+SSEditor *SSEditor::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 32 - 0
EditorServer/SSEditor.h

@@ -0,0 +1,32 @@
+#ifndef SSEditor_H
+#define SSEditor_H
+
+#include <Text.h>
+#include <Server.h>
+
+using namespace Framework;
+using namespace Network;
+
+class SSEditor
+{
+private:
+    Text pfad;
+    Text workPfad;
+    Text fehler;
+    int ref;
+
+public:
+    // Konstruktor
+    SSEditor( char *pf );
+    // Destruktor
+    ~SSEditor();
+    // nicht constant
+    bool prozessMessage( SKlient *zKlient );
+    // constant
+    char *getLetzterFehler() const;
+    // Reference Counting
+    SSEditor *getThis();
+    SSEditor *release();
+};
+
+#endif

+ 147 - 0
EditorServer/TeamsEditor.cpp

@@ -0,0 +1,147 @@
+#include "TeamsEditor.h"
+#include <Datei.h>
+#include <DateiSystem.h>
+#include <Bild.h>
+
+// Inhalt der TeamsEditor Klasse aus TeamsEditor.h
+// Konstruktor
+TeamsEditor::TeamsEditor( int id, char *pf, EdSDatenbank *db )
+{
+    pfad = pf;
+    pfad += "/live/map";
+    fehler = "";
+    this->id = id;
+    this->db = db;
+    ref = 1;
+}
+
+// Destruktor
+TeamsEditor::~TeamsEditor()
+{
+    db->release();
+}
+
+// nicht constant
+bool TeamsEditor::prozessMessage( SKlient *zKlient )
+{
+    char message = 0;
+    zKlient->getNachrichtEncrypted( &message, 1 );
+    switch( message )
+    {
+    case 0x1: // Team Struktur laden
+    {
+        Text p = pfad.getText();
+        p += "/server/sts.ltgd";
+        Datei d;
+        d.setDatei( p );
+        if( !d.open( Datei::Style::lesen ) )
+        {
+            fehler = "Es ist ein Fehler beim laden der Einstellungen aufgetreten.";
+            return 0;
+        }
+        zKlient->sendeEncrypted( "\1", 1 );
+        char *buffer = new char[ 2048 ];
+        int gr = (int)d.getSize();
+        while( gr > 0 )
+        {
+            int l = gr > 2048 ? 2048 : gr;
+            d.lese( buffer, l );
+            zKlient->sendeEncrypted( buffer, l );
+            gr -= l;
+        }
+        delete[] buffer;
+        d.close();
+        return 1;
+    }
+    case 0x2: // Team Struktur speichern
+    {
+        Text p = pfad.getText();
+        p += "/server/sts.ltgd";
+        Datei d1;
+        d1.setDatei( p );
+        p = pfad.getText();
+        p += "/client/map/data/data.sts";
+        Datei d2;
+        d2.setDatei( p );
+        if( d1.open( Datei::Style::schreiben ) && d2.open( Datei::Style::schreiben ) )
+            zKlient->sendeEncrypted( "\1", 1 );
+        else
+        {
+            d1.close();
+            d2.close();
+            fehler = "Es ist ein Fehler beim speichern der Einstellungen aufgetreten.";
+            return 0;
+        }
+        int sAnz = 0;
+        zKlient->getNachrichtEncrypted( (char*)&sAnz, 4 );
+        d1.schreibe( (char*)&sAnz, 4 );
+        d2.schreibe( (char*)&sAnz, 4 );
+        db->setMaxSpieler( id, sAnz );
+        int tAnz = 0;
+        zKlient->getNachrichtEncrypted( (char*)&tAnz, 4 );
+        d1.schreibe( (char*)&tAnz, 4 );
+        d2.schreibe( (char*)&tAnz, 4 );
+        for( int i = 0; i < sAnz; i++ )
+        { // Spielerfarbe
+            int f = 0;
+            zKlient->getNachrichtEncrypted( (char*)&f, 4 );
+            d1.schreibe( (char*)&f, 4 );
+            d2.schreibe( (char*)&f, 4 );
+        }
+        for( int i = 0; i < tAnz; i++ )
+        { // Teamfarbe
+            int f = 0;
+            zKlient->getNachrichtEncrypted( (char*)&f, 4 );
+            d1.schreibe( (char*)&f, 4 );
+            d2.schreibe( (char*)&f, 4 );
+        }
+        for( int i = 0; i < tAnz; i++ )
+        { // Teamname
+            char l = 0;
+            zKlient->getNachrichtEncrypted( &l, 1 );
+            char *txt = new char[ l + 1 ];
+            txt[ (int)l ] = 0;
+            zKlient->getNachrichtEncrypted( txt, l );
+            d1.schreibe( &l, 1 );
+            d2.schreibe( &l, 1 );
+            d1.schreibe( txt, l );
+            d2.schreibe( txt, l );
+            delete[] txt;
+        }
+        for( int i = 0; i < tAnz; i++ )
+        { // Teamgröße
+            int g = 0;
+            zKlient->getNachrichtEncrypted( (char*)&g, 4 );
+            d1.schreibe( (char*)&g, 4 );
+            d2.schreibe( (char*)&g, 4 );
+        }
+        d1.close();
+        d2.close();
+        return 1;
+    }
+    default:
+        fehler = "Unbekannte Nachricht. Eventuell ist der Client nicht auf dem neusten Stand.";
+    }
+    return 0;
+}
+
+// constant
+char *TeamsEditor::getLetzterFehler() const
+{
+    return fehler;
+}
+
+// Reference Counting
+TeamsEditor *TeamsEditor::getThis()
+{
+    ref++;
+    return this;
+}
+
+TeamsEditor *TeamsEditor::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 35 - 0
EditorServer/TeamsEditor.h

@@ -0,0 +1,35 @@
+#pragma once
+
+#include <Text.h>
+#include <Server.h>
+#ifdef WIN32
+#include "../../../Datenbank/Datenbank.h"
+#else
+#include "Datenbank.h"
+#endif
+
+using namespace Framework;
+using namespace Network;
+
+class TeamsEditor
+{
+private:
+    Text pfad;
+    Text fehler;
+    EdSDatenbank *db;
+    int id;
+    int ref;
+
+public:
+    // Konstruktor
+    TeamsEditor( int id, char *pf, EdSDatenbank *db );
+    // Destruktor
+    ~TeamsEditor();
+    // nicht constant
+    bool prozessMessage( SKlient *zKlient );
+    // constant
+    char *getLetzterFehler() const;
+    // Reference Counting
+    TeamsEditor *getThis();
+    TeamsEditor *release();
+};

+ 51 - 0
EditorServer/main.cpp

@@ -0,0 +1,51 @@
+#include "EditorServer.h"
+#include <Zeit.h>
+#include <iostream>
+#include <fstream>
+#include <Globals.h>
+
+int main()
+{
+    Framework::initFramework();
+	Zeit *z = getZeit();
+	Text *pfad = new Text( "../log/editor/" );
+	pfad->append( z->getZeit( "y-m-d h-i-s.log" ) );
+	z->release();
+	DateiPfadErstellen( pfad->getThis() );
+	std::ofstream file;
+	file.open( pfad->getText() );
+	std::streambuf* sbuf = std::cout.rdbuf();
+	std::cout.rdbuf( file.rdbuf() );
+	pfad->release();
+
+	std::cout << "EdS: Startet...\n";
+	std::cout << "EdS: Lese init Datei ../data/edsInit.ini ...\n";
+	InitDatei *dat = new InitDatei( "../data/edsInit.ini" );
+	if( !dat->laden() )
+	{
+		std::cout << "EdS: error: Datei konnte nicht gelesen werden. Das Programm wird geschlossen.\n";
+		dat->release();
+		exit( 1 );
+    }
+    if( !dat->wertExistiert( "KartenPfad" ) )
+    {
+        std::cout << "EdS: error: Der Wert 'KartenPfad' wurde in der Datei '../data/edsInit.ini' nicht gefunden. Das Programm wird geschlossen.\n";
+        dat->release();
+        exit( 1 );
+    }
+
+	EditorServer *iServer = new EditorServer( dat );
+
+	std::cout << "EdS: Der Admin Server läuft. Startforgang beendet.\n";
+	iServer->runn();
+
+	iServer->ende();
+	iServer->release();
+	dat->speichern();
+	dat->release();
+	std::cout << "EdS: Der Server ist heruntergefahren.\n";
+	file.close();
+	std::cout.rdbuf( sbuf );
+    Framework::releaseFramework();
+	return 0;
+}

BIN
EditorServer/readme/images/ArchOptions.gif


BIN
EditorServer/readme/images/ChangeRemote.gif


BIN
EditorServer/readme/images/ManageConnections.gif


BIN
EditorServer/readme/images/OutputTypes.gif


BIN
EditorServer/readme/images/debuggerexport.png


BIN
EditorServer/readme/images/firstconnection.png


BIN
EditorServer/readme/images/linker.png


BIN
EditorServer/readme/images/postbuild.png


+ 85 - 0
EditorServer/readme/readme.html

@@ -0,0 +1,85 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset='utf-8'>
+
+    <link rel="stylesheet" type="text/css" href="stylesheet.css" media="screen">
+
+    <title>Getting Started</title>
+  </head>
+
+<body>
+
+    <div class="container">
+        <div id="header">
+            <h1>Getting Started</h1>
+            <h2>Visual C++ for Linux Development extension</h2>
+        </div>
+    
+    <table>
+    <tr>    
+    <div id="main_content">
+        
+        <td>
+        <div id="lpanel">
+            <h1>Setting up your project for Linux Development</h1>
+
+            <p>With this extension you can author C++ code for Linux servers, desktops and devices. You can manage your connections to these machines from within VS. VS will automatically copy and remote build your sources and can launch your application with the debugger. Our project system supports targeting specific architectures, including ARM.</p>
+            <img src="images\ArchOptions.gif"/>
+            
+            <h1>Connecting to Linux</h1>
+            <h2>Prerequisites</h2>
+            <p>Today we only support building remotely on the Linux target machine. We are not limited by specific Linux distros but we do have dependencies on the presence of some tools. Specifically, we need openssh-server, g++, gdb and gdbserver. Use your favorite package manager to install them, e.g. on Debian based systems: sudo apt-get install openssh-server g++ gdb gdbserver</p>
+            
+            <h2>First connection</h2>
+            <p>The first time you target a Linux machine you will be prompted for connection information.  This is triggered by building the project.</p>
+            <img src="images\firstconnection.png"/>
+                
+            <h2>Adding and removing connections</h2>
+            <p>To add a new connection, go to Tools > Options and search for Linux. From here you can add and remove connections.</p>
+            <img src="images\ManageConnections.gif"/>
+            
+            <p>To change which connection a project is using go to the project properties remote settings and update the target machine.</p>
+            <img src="images\ChangeRemote.gif"/>
+            
+            <h1>Project Properties</h1>
+            <p>All of the options necessary to control C++ compilation are exposed on the project properies pages. We'll cover a few specific to how things work for Linux. First under remote settings, you will see the remote root is set to ~/projects/ by default and that we are setting the remote project directory to match our project name in that location. </p>
+            <img src="images\OutputTypes.gif"/>
+            
+            <p>Looking at the General settings for the project, you can see how our output and intermediate directories were configured. Additionally, you’ll see that this project was configured as an application – thus our executable is under bin/x64/Debug/ as ConsoleApplication1.out. Notice that for configuration types we also support static and dynamic libraries.</p>
+            
+            <p>Add additional library dependencies on the Linker > Input property page.</p>
+            <img src="images\linker.png"/>
+            
+            <p>You can pass additional pre launch commands to the debugger to do things like launch graphical apps on the remote linux machine.</p>
+            <img src="images\debuggerexport.png"/>
+            
+            <p>You can also send post build events to control remote behavior, as in this example that exports a gpio pin for use without requiring the executable run as super user.</p>
+            <img src="images\postbuild.png"/>
+            
+        </div>
+        </td>
+        <td>
+        <div id="rpanel">
+
+            <h1>Resources</h1>
+
+            <p>Check out the <a href="http://aka.ms/vslinuxext">VS Gallery VC++ for Linux Development page</a> where we will keep updates posted. You can also check out our <a href="https://blogs.msdn.microsoft.com/vcblog/2016/03/30/visual-c-for-linux-development">announcment blog post</a> for more in depth details on configuring the project properties.</p>
+            
+            <p>Here are other utilities you will find useful in connection with this extension.</p>
+            <ul>
+                <li>Learn more about <a href="http://aka.ms/vsiot">IoT Development</a></li>
+                <li><a href="http://aka.ms/vsiotext">VC++ for IoT Development Tools</a></li>
+                <li><a href="https://github.com/Azure/azure-iot-sdks">Azure IoT SDK</a>, includes a C API for connecting small devices to the Azure IoT Hub</li>
+            </ul>
+
+            <h1>Give us feedback</h1>
+            <p><a href="http://aka.ms/vslinux-feedback">UserVoice</a></p>
+        </div>
+        </td>   
+    </div>
+    </tr>
+    </table>
+    </div>
+</body>
+</html>

+ 119 - 0
EditorServer/readme/stylesheet.css

@@ -0,0 +1,119 @@
+body {
+  margin: 0;
+  padding: 0;
+  border: 0;
+  color: #1E1E1E;
+  font-size: 13px;
+  font-family: "Segoe UI", Helvetica, Arial, sans-serif;
+  line-height: 1.45;
+  word-wrap: break-word;
+}
+
+/* General & 'Reset' Stuff */
+
+
+.container {
+  width: 1100px;
+  margin: 0 auto;
+}
+
+section {
+  display: block;
+  margin: 0;
+}
+
+h1, h2, h3, h4, h5, h6 {
+  margin: 0;
+}
+
+table, tr {
+    width: 1100px;
+    padding: 0px;
+    vertical-align: top;
+  }
+
+/* Header, <header>
+   header   - container
+   h1       - project name
+   h2       - project description
+*/
+
+#header {
+  color: #FFF;
+  background: #68217a;
+  position:relative;
+}
+h1, h2 {
+  font-family: "Segoe UI Light", "Segoe UI", Helvetica, Arial, sans-serif;
+  line-height: 1;
+  margin: 0 18px;;
+  padding: 0;
+}
+#header h1 {
+  font-size: 3.4em;
+  padding-top: 18px;
+  font-weight: normal;
+  margin-left: 15px;
+}
+
+#header h2 {
+  font-size: 1.5em;
+  margin-top: 10px;
+  padding-bottom: 18px;
+  font-weight: normal;
+}
+
+#main_content {
+  width: 100%;
+  display: flex;
+  flex-direction: row;
+}
+
+
+h1, h2, h3, h4, h5, h6 {
+  font-weight: bolder;
+}
+
+#main_content h1 {
+  font-size: 1.8em;
+  margin-top: 34px;
+}
+
+    #main_content h1:first-child {
+        margin-top: 30px;
+    }
+
+#main_content h2 {
+  font-size: 1.8em;
+}
+p, ul {
+    margin: 11px 18px;
+}
+
+#main_content a {
+    color: #06C;
+    text-decoration: none;
+}
+ul {
+        margin-top: 13px;
+    margin-left: 18px;
+    padding-left: 0;
+}
+    ul li {
+        margin-left: 18px;
+        padding-left: 0;
+    }
+#lpanel {
+    width: 870px;
+    float: left;
+}
+#rpanel ul {
+    list-style-type: none;
+}
+    #rpanel ul li {
+        line-height: 1.8em;
+    }
+#rpanel {
+    background: #e7e7e7;
+    width: 230px;
+}

+ 2 - 0
build.bat

@@ -0,0 +1,2 @@
+"D:\Visual Studio 2017\MSBuild\15.0\Bin\MSBuild.exe" "Editor Server.sln" /t:rebuild /p:configuration=debug /p:platform=x64
+"D:\Visual Studio 2017\MSBuild\15.0\Bin\MSBuild.exe" "Editor Server.sln" /t:rebuild /p:configuration=release /p:platform=x64