Browse Source

Initial Commit

Kolja Strohm 6 years ago
commit
6c04ec14b1
151 changed files with 54860 additions and 0 deletions
  1. 63 0
      .gitattributes
  2. 265 0
      .gitignore
  3. 28 0
      KSGClient.sln
  4. 546 0
      KSGClient/Aktionen/AktionsThread.cpp
  5. 31 0
      KSGClient/Aktionen/AktionsThread.h
  6. 124 0
      KSGClient/Global/Bilder.cpp
  7. 38 0
      KSGClient/Global/Bilder.h
  8. 94 0
      KSGClient/Global/DLLDateien.cpp
  9. 37 0
      KSGClient/Global/DLLDateien.h
  10. 126 0
      KSGClient/Global/Fps.cpp
  11. 49 0
      KSGClient/Global/Fps.h
  12. 351 0
      KSGClient/Global/Initialisierung.cpp
  13. 42 0
      KSGClient/Global/Initialisierung.h
  14. 185 0
      KSGClient/Global/Render.cpp
  15. 42 0
      KSGClient/Global/Render.h
  16. 93 0
      KSGClient/Global/Variablen.cpp
  17. 43 0
      KSGClient/Global/Variablen.h
  18. 338 0
      KSGClient/KSGClient.vcxproj
  19. 462 0
      KSGClient/KSGClient.vcxproj.filters
  20. 247 0
      KSGClient/Leser/KartenLeser.cpp
  21. 41 0
      KSGClient/Leser/KartenLeser.h
  22. 661 0
      KSGClient/NachLogin/Account/AccountAnsehen.cpp
  23. 75 0
      KSGClient/NachLogin/Account/AccountAnsehen.h
  24. 320 0
      KSGClient/NachLogin/Account/Aktivität/AccountAktivität.cpp
  25. 44 0
      KSGClient/NachLogin/Account/Aktivität/AccountAktivität.h
  26. 1526 0
      KSGClient/NachLogin/Account/Historie/AccountHistorie.cpp
  27. 287 0
      KSGClient/NachLogin/Account/Historie/AccountHistorie.h
  28. 140 0
      KSGClient/NachLogin/Account/Historie/AccountHistorieDaten.cpp
  29. 82 0
      KSGClient/NachLogin/Account/Historie/AccountHistorieDaten.h
  30. 1126 0
      KSGClient/NachLogin/Account/SpielPartner/AccountSpielPartner.cpp
  31. 145 0
      KSGClient/NachLogin/Account/SpielPartner/AccountSpielPartner.h
  32. 921 0
      KSGClient/NachLogin/Account/Spiele_Karten/AccountSpieleUndKarten.cpp
  33. 171 0
      KSGClient/NachLogin/Account/Spiele_Karten/AccountSpieleUndKarten.h
  34. 403 0
      KSGClient/NachLogin/Account/Statistik/AccountStatistik.cpp
  35. 60 0
      KSGClient/NachLogin/Account/Statistik/AccountStatistik.h
  36. 364 0
      KSGClient/NachLogin/Account/Suchen/AccountSuchen.cpp
  37. 64 0
      KSGClient/NachLogin/Account/Suchen/AccountSuchen.h
  38. 1421 0
      KSGClient/NachLogin/Chat/ChatLeiste.cpp
  39. 200 0
      KSGClient/NachLogin/Chat/ChatLeiste.h
  40. 1255 0
      KSGClient/NachLogin/Chat/FreundesListe.cpp
  41. 176 0
      KSGClient/NachLogin/Chat/FreundesListe.h
  42. 816 0
      KSGClient/NachLogin/Chat/NachrichtenListe.cpp
  43. 142 0
      KSGClient/NachLogin/Chat/NachrichtenListe.h
  44. 429 0
      KSGClient/NachLogin/Editor/Auswahl/Auswahl.cpp
  45. 58 0
      KSGClient/NachLogin/Editor/Auswahl/Auswahl.h
  46. 216 0
      KSGClient/NachLogin/Editor/Editor.cpp
  47. 55 0
      KSGClient/NachLogin/Editor/Editor.h
  48. 246 0
      KSGClient/NachLogin/Editor/Karte/Beschreibung/KEBEditor.cpp
  49. 48 0
      KSGClient/NachLogin/Editor/Karte/Beschreibung/KEBEditor.h
  50. 352 0
      KSGClient/NachLogin/Editor/Karte/Beschreibung/KEBVorschau.cpp
  51. 78 0
      KSGClient/NachLogin/Editor/Karte/Beschreibung/KEBVorschau.h
  52. 428 0
      KSGClient/NachLogin/Editor/Karte/Beschreibung/KEBeschreibung.cpp
  53. 52 0
      KSGClient/NachLogin/Editor/Karte/Beschreibung/KEBeschreibung.h
  54. 1212 0
      KSGClient/NachLogin/Editor/Karte/Dateien/KEDEditor.cpp
  55. 196 0
      KSGClient/NachLogin/Editor/Karte/Dateien/KEDEditor.h
  56. 1103 0
      KSGClient/NachLogin/Editor/Karte/Dateien/KEDModel2DEditor.cpp
  57. 207 0
      KSGClient/NachLogin/Editor/Karte/Dateien/KEDModel2DEditor.h
  58. 537 0
      KSGClient/NachLogin/Editor/Karte/Dateien/KEDateien.cpp
  59. 50 0
      KSGClient/NachLogin/Editor/Karte/Dateien/KEDateien.h
  60. 99 0
      KSGClient/NachLogin/Editor/Karte/Dateien/WAVDatei.cpp
  61. 69 0
      KSGClient/NachLogin/Editor/Karte/Dateien/WAVDatei.h
  62. 606 0
      KSGClient/NachLogin/Editor/Karte/KartenEditor.cpp
  63. 64 0
      KSGClient/NachLogin/Editor/Karte/KartenEditor.h
  64. 721 0
      KSGClient/NachLogin/Editor/Karte/ShopSeite/KESSEditor.cpp
  65. 138 0
      KSGClient/NachLogin/Editor/Karte/ShopSeite/KESSEditor.h
  66. 727 0
      KSGClient/NachLogin/Editor/Karte/ShopSeite/KESSVorschau.cpp
  67. 120 0
      KSGClient/NachLogin/Editor/Karte/ShopSeite/KESSVorschau.h
  68. 431 0
      KSGClient/NachLogin/Editor/Karte/ShopSeite/KEShopSeite.cpp
  69. 51 0
      KSGClient/NachLogin/Editor/Karte/ShopSeite/KEShopSeite.h
  70. 478 0
      KSGClient/NachLogin/Editor/Karte/Teams/KETeams.cpp
  71. 65 0
      KSGClient/NachLogin/Editor/Karte/Teams/KETeams.h
  72. 86 0
      KSGClient/NachLogin/Einstellungen/Einstellungen.cpp
  73. 34 0
      KSGClient/NachLogin/Einstellungen/Einstellungen.h
  74. 242 0
      KSGClient/NachLogin/ImSpiel/ImSpiel.cpp
  75. 48 0
      KSGClient/NachLogin/ImSpiel/ImSpiel.h
  76. 603 0
      KSGClient/NachLogin/ImSpiel/Laden/SpielLaden.cpp
  77. 133 0
      KSGClient/NachLogin/ImSpiel/Laden/SpielLaden.h
  78. 289 0
      KSGClient/NachLogin/MiniGames/MiniGame.cpp
  79. 51 0
      KSGClient/NachLogin/MiniGames/MiniGame.h
  80. 540 0
      KSGClient/NachLogin/MiniGames/Minigames.cpp
  81. 102 0
      KSGClient/NachLogin/MiniGames/Minigames.h
  82. 482 0
      KSGClient/NachLogin/NachLogin.cpp
  83. 86 0
      KSGClient/NachLogin/NachLogin.h
  84. 326 0
      KSGClient/NachLogin/Neuigkeiten/Neuigkeiten.cpp
  85. 74 0
      KSGClient/NachLogin/Neuigkeiten/Neuigkeiten.h
  86. 1055 0
      KSGClient/NachLogin/Shop/Karten/KartenKaufen.cpp
  87. 153 0
      KSGClient/NachLogin/Shop/Karten/KartenKaufen.h
  88. 257 0
      KSGClient/NachLogin/Shop/Shop.cpp
  89. 56 0
      KSGClient/NachLogin/Shop/Shop.h
  90. 1035 0
      KSGClient/NachLogin/Shop/Spiele/SpieleKaufen.cpp
  91. 150 0
      KSGClient/NachLogin/Shop/Spiele/SpieleKaufen.h
  92. 397 0
      KSGClient/NachLogin/Spiele/Angemeldet/Angemeldet.cpp
  93. 60 0
      KSGClient/NachLogin/Spiele/Angemeldet/Angemeldet.h
  94. 2461 0
      KSGClient/NachLogin/Spiele/Gruppe/Gruppe.cpp
  95. 391 0
      KSGClient/NachLogin/Spiele/Gruppe/Gruppe.h
  96. 747 0
      KSGClient/NachLogin/Spiele/Karte Auswahl/KarteAuswahl.cpp
  97. 105 0
      KSGClient/NachLogin/Spiele/Karte Auswahl/KarteAuswahl.h
  98. 1032 0
      KSGClient/NachLogin/Spiele/Spiel Auswahl/SpielAuswahl.cpp
  99. 113 0
      KSGClient/NachLogin/Spiele/Spiel Auswahl/SpielAuswahl.h
  100. 842 0
      KSGClient/NachLogin/Spiele/Spiele.cpp
  101. 115 0
      KSGClient/NachLogin/Spiele/Spiele.h
  102. 269 0
      KSGClient/NachLogin/Spiele/Statistik/SpielStatistik.cpp
  103. 56 0
      KSGClient/NachLogin/Spiele/Statistik/SpielStatistik.h
  104. 1133 0
      KSGClient/NachLogin/Spiele/Team Auswahl/TeamAuswahl.cpp
  105. 238 0
      KSGClient/NachLogin/Spiele/Team Auswahl/TeamAuswahl.h
  106. 742 0
      KSGClient/NachLogin/Titel/TitelLeiste.cpp
  107. 79 0
      KSGClient/NachLogin/Titel/TitelLeiste.h
  108. 296 0
      KSGClient/NachLogin/UpdateGUI/UpdateGUI.cpp
  109. 73 0
      KSGClient/NachLogin/UpdateGUI/UpdateGUI.h
  110. 501 0
      KSGClient/Netzwerk/KSGKlient.h
  111. 56 0
      KSGClient/Netzwerk/KSGServer.cpp
  112. 20 0
      KSGClient/Netzwerk/KSGServer.h
  113. 47 0
      KSGClient/Netzwerk/KeepAlive.cpp
  114. 21 0
      KSGClient/Netzwerk/KeepAlive.h
  115. 18 0
      KSGClient/Netzwerk/Keys.cpp
  116. 43 0
      KSGClient/Netzwerk/Keys.h
  117. 833 0
      KSGClient/Netzwerk/Klients/AnmeldungK.cpp
  118. 1184 0
      KSGClient/Netzwerk/Klients/ChatK.cpp
  119. 2829 0
      KSGClient/Netzwerk/Klients/EditorK.cpp
  120. 203 0
      KSGClient/Netzwerk/Klients/HistorieK.cpp
  121. 2079 0
      KSGClient/Netzwerk/Klients/InformationK.cpp
  122. 461 0
      KSGClient/Netzwerk/Klients/KartenK.cpp
  123. 486 0
      KSGClient/Netzwerk/Klients/LoginK.cpp
  124. 381 0
      KSGClient/Netzwerk/Klients/NewsK.cpp
  125. 956 0
      KSGClient/Netzwerk/Klients/RegisterK.cpp
  126. 1150 0
      KSGClient/Netzwerk/Klients/ShopK.cpp
  127. 622 0
      KSGClient/Netzwerk/Klients/SpielK.cpp
  128. 103 0
      KSGClient/Netzwerk/Patcher.cpp
  129. 35 0
      KSGClient/Netzwerk/Patcher.h
  130. 182 0
      KSGClient/Start/Start.cpp
  131. 38 0
      KSGClient/Strukturen/Strukturen.cpp
  132. 29 0
      KSGClient/Strukturen/Strukturen.h
  133. 414 0
      KSGClient/VorLogin/Account verwalten/Bestätigung.cpp
  134. 63 0
      KSGClient/VorLogin/Account verwalten/Bestätigung.h
  135. 618 0
      KSGClient/VorLogin/Account verwalten/EMail.cpp
  136. 91 0
      KSGClient/VorLogin/Account verwalten/EMail.h
  137. 573 0
      KSGClient/VorLogin/Account verwalten/Geheimnis.cpp
  138. 88 0
      KSGClient/VorLogin/Account verwalten/Geheimnis.h
  139. 254 0
      KSGClient/VorLogin/Account verwalten/Name.cpp
  140. 47 0
      KSGClient/VorLogin/Account verwalten/Name.h
  141. 610 0
      KSGClient/VorLogin/Account verwalten/Passwort.cpp
  142. 93 0
      KSGClient/VorLogin/Account verwalten/Passwort.h
  143. 637 0
      KSGClient/VorLogin/Account verwalten/Registrierung.cpp
  144. 76 0
      KSGClient/VorLogin/Account verwalten/Registrierung.h
  145. 461 0
      KSGClient/VorLogin/Account verwalten/Unregistrierung.cpp
  146. 66 0
      KSGClient/VorLogin/Account verwalten/Unregistrierung.h
  147. 406 0
      KSGClient/VorLogin/Login/Login.cpp
  148. 59 0
      KSGClient/VorLogin/Login/Login.h
  149. 509 0
      KSGClient/VorLogin/VorLogin.cpp
  150. 84 0
      KSGClient/VorLogin/VorLogin.h
  151. 3 0
      build.bat

+ 63 - 0
.gitattributes

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

+ 265 - 0
.gitignore

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

+ 28 - 0
KSGClient.sln

@@ -0,0 +1,28 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.22823.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "KSGClient", "KSGClient\KSGClient.vcxproj", "{BF0DC22E-98E5-4B97-9F31-BFDD9FBC08E4}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{BF0DC22E-98E5-4B97-9F31-BFDD9FBC08E4}.Debug|Win32.ActiveCfg = Debug|Win32
+		{BF0DC22E-98E5-4B97-9F31-BFDD9FBC08E4}.Debug|Win32.Build.0 = Debug|Win32
+		{BF0DC22E-98E5-4B97-9F31-BFDD9FBC08E4}.Debug|x64.ActiveCfg = Debug|x64
+		{BF0DC22E-98E5-4B97-9F31-BFDD9FBC08E4}.Debug|x64.Build.0 = Debug|x64
+		{BF0DC22E-98E5-4B97-9F31-BFDD9FBC08E4}.Release|Win32.ActiveCfg = Release|Win32
+		{BF0DC22E-98E5-4B97-9F31-BFDD9FBC08E4}.Release|Win32.Build.0 = Release|Win32
+		{BF0DC22E-98E5-4B97-9F31-BFDD9FBC08E4}.Release|x64.ActiveCfg = Release|x64
+		{BF0DC22E-98E5-4B97-9F31-BFDD9FBC08E4}.Release|x64.Build.0 = Release|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

+ 546 - 0
KSGClient/Aktionen/AktionsThread.cpp

@@ -0,0 +1,546 @@
+#include "AktionsThread.h"
+#include "..\Global\Variablen.h"
+
+// Inhalt der AktionsThread Klasse aus AktionsThread.h
+// Konstruktor
+AktionsThread::AktionsThread( int aktion, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5 )
+	: Thread()
+{
+	this->aktion = aktion;
+	this->arg1 = arg1;
+	this->arg2 = arg2;
+	this->arg3 = arg3;
+	this->arg4 = arg4;
+	this->arg5 = arg5;
+	ref = 1;
+	start();
+}
+
+// nicht constant
+void AktionsThread::thread()
+{
+	switch( aktion )
+	{
+	case 1: // Login
+		// arg1 = char* -- Account Name
+		// arg2 = char* -- Account Passwort
+		if( 1 )
+		{
+			hauptScreen->setdeckFarbe( 0x00000000 );
+			hauptScreen->setOnTop( 1 );
+			ladeAnimation->setSichtbar( 1 );
+			int ret = loginKlient->login( (const char*)arg1, (const char*)arg2 );
+			do
+			{
+				if( ret != 1 )
+					continue;
+				if( !infoKlient->verbinde() )
+				{
+					ret = 0;
+					loginKlient->setLetzterFehler( infoKlient->getLetzterFehler() );
+					loginKlient->logout();
+					continue;
+				}
+				if( !chatKlient->verbinde() )
+				{
+					ret = 0;
+					loginKlient->setLetzterFehler( chatKlient->getLetzterFehler() );
+					loginKlient->logout();
+					infoKlient->trenne();
+					continue;
+				}
+				loginKlient->trenne();
+			}
+			while( 0 );
+			ladeAnimation->setSichtbar( 0 );
+			hauptScreen->setOnTop( 0 );
+			vorLogin->zLogin()->setLoginReturn( ret );
+		}
+		break;
+	case 2: // Login Erfolgreich
+		hauptScreen->setdeckFarbe( 0x00000000 );
+		hauptScreen->setOnTop( 1 );
+		ladeAnimation->setSichtbar( 1 );
+		for( unsigned char deckAlpha = 0; deckAlpha < 255; )
+		{
+			hauptScreen->setdeckFarbe( deckAlpha << 24 );
+			Sleep( 40 );
+			deckAlpha += 15;
+		}
+		hauptScreen->setdeckFarbe( 255 << 24 );
+		hauptScreen->setRenderZeichnungen( 0 );
+		vorLogin->setSichtbar( 0 );
+		nachLogin->setAnzeige( NLANormal );
+		hauptScreen->setRenderZeichnungen( 1 );
+		ladeAnimation->setSichtbar( 0 );
+		for( unsigned char deckAlpha = 255; deckAlpha > 0; )
+		{
+			hauptScreen->setdeckFarbe( deckAlpha << 24 );
+			Sleep( 40 );
+			deckAlpha -= 15;
+		}
+		hauptScreen->setdeckFarbe( 0 << 24 );
+		hauptScreen->setOnTop( 0 );
+		break;
+	case 3: // Kick
+		// arg1 = char* -- Account Geheimnis
+		if( 1 )
+		{
+			hauptScreen->setdeckFarbe( 0x00000000 );
+			hauptScreen->setOnTop( 1 );
+			ladeAnimation->setSichtbar( 1 );
+			int ret = (int)loginKlient->kick( (const char*)arg1 );
+			do
+			{
+				if( !ret )
+					continue;
+				if( !infoKlient->verbinde() )
+				{
+					ret = 2;
+					loginKlient->setLetzterFehler( infoKlient->getLetzterFehler() );
+					loginKlient->logout();
+					continue;
+				}
+				if( !chatKlient->verbinde() )
+				{
+					ret = 2;
+					loginKlient->setLetzterFehler( chatKlient->getLetzterFehler() );
+					loginKlient->logout();
+					infoKlient->trenne();
+					continue;
+				}
+				loginKlient->trenne();
+			}
+			while( 0 );
+			ladeAnimation->setSichtbar( 0 );
+			hauptScreen->setOnTop( 0 );
+			vorLogin->zLogin()->setKickReturn( ret );
+		}
+		break;
+	case 4: // Logout
+		if( 1 )
+		{
+			hauptScreen->setdeckFarbe( 0x00000000 );
+			hauptScreen->setOnTop( 1 );
+			ladeAnimation->setSichtbar( 1 );
+			bool ret = loginKlient->logout();
+			if( ret )
+			{
+				hauptScreen->lock();
+				nachLogin->zChatLeiste()->removeAll();
+				nachLogin->zFreundesListe()->removeAll();
+				nachLogin->zNachrichtenListe()->removeAll();
+				hauptScreen->unlock();
+				infoKlient->trenne();
+				spielKlient->trenne();
+				chatKlient->trenne();
+				loginKlient->trenne();
+			}
+			else
+			{
+				nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Das Ausloggen konnte nicht erfolgreich abgeschlossen werden." ),
+																  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+				ladeAnimation->setSichtbar( 0 );
+				hauptScreen->setOnTop( 0 );
+				break;
+			}
+			ladeAnimation->setSichtbar( 0 );
+			hauptScreen->setOnTop( 0 );
+		}
+	case 5: // Logout Erfolgreich
+		hauptScreen->setdeckFarbe( 0x00000000 );
+		hauptScreen->setOnTop( 1 );
+		ladeAnimation->setSichtbar( 1 );
+		for( unsigned char deckAlpha = 0; deckAlpha < 255; )
+		{
+			hauptScreen->setdeckFarbe( deckAlpha << 24 );
+			Sleep( 40 );
+			deckAlpha += 15;
+		}
+		hauptScreen->setdeckFarbe( 255 << 24 );
+		_render = 0;
+		hauptScreen->lock();
+		nachLogin->setAnzeige( NLALogin );
+		vorLogin->setSichtbar( 1 );
+		hauptScreen->unlock();
+		_render = 1;
+		ladeAnimation->setSichtbar( 0 );
+		for( unsigned char deckAlpha = 255; deckAlpha > 0; )
+		{
+			hauptScreen->setdeckFarbe( deckAlpha << 24 );
+			Sleep( 40 );
+			deckAlpha -= 15;
+		}
+		hauptScreen->setdeckFarbe( 0 << 24 );
+		hauptScreen->setOnTop( 0 );
+		break;
+	case 6: // Account Bestätigung
+		// arg1 = char* -- Account Name
+		// arg2 = char* -- Account Passwort
+		if( 1 )
+		{
+			hauptScreen->setdeckFarbe( 0x00000000 );
+			hauptScreen->setOnTop( 1 );
+			ladeAnimation->setSichtbar( 1 );
+			int ret = registerKlient->accountBestätigen( (const char*)arg1, (const char*)arg2 );
+			ladeAnimation->setSichtbar( 0 );
+			hauptScreen->setOnTop( 0 );
+			vorLogin->zBestätigung()->setWeiterResult( ret );
+		}
+		break;
+	case 7: // Account Bestätigung Fertig
+		// arg1 = char* -- Schlüssel
+		if( 1 )
+		{
+			hauptScreen->setdeckFarbe( 0x00000000 );
+			hauptScreen->setOnTop( 1 );
+			ladeAnimation->setSichtbar( 1 );
+			bool ret = registerKlient->bestätigen( (const char*)arg1 );
+			ladeAnimation->setSichtbar( 0 );
+			hauptScreen->setOnTop( 0 );
+			vorLogin->zBestätigung()->setFertigResult( ret );
+		}
+		break;
+	case 8: // Account E-Mail ändern
+		// arg1 = char* -- Account Name
+		// arg2 = char* -- Account Passwort
+		// arg3 = char* -- Account Geheimnis
+		// arg4 = char* -- Neue E-Mail
+		if( 1 )
+		{
+			hauptScreen->setdeckFarbe( 0x00000000 );
+			hauptScreen->setOnTop( 1 );
+			ladeAnimation->setSichtbar( 1 );
+			bool ret = registerKlient->eMailÄndern( (const char*)arg1, (const char*)arg2, (const char*)arg3, (const char*)arg4 );
+			ladeAnimation->setSichtbar( 0 );
+			hauptScreen->setOnTop( 0 );
+			vorLogin->zEMailÄndern()->setReturn( ret );
+		}
+		break;
+	case 9: // Account E-Mail Vergessen
+		// arg1 = char* -- Account Name
+		// arg2 = char* -- Account Passwort
+		// arg3 = char* -- Account Geheimnis
+		if( 1 )
+		{
+			hauptScreen->setdeckFarbe( 0x00000000 );
+			hauptScreen->setOnTop( 1 );
+			ladeAnimation->setSichtbar( 1 );
+			char *eMail = 0;
+			char **pEMail = &eMail;
+			bool ret = registerKlient->eMailVergessen( (const char*)arg1, (const char*)arg2, (const char*)arg3, pEMail );
+			ladeAnimation->setSichtbar( 0 );
+			hauptScreen->setOnTop( 0 );
+			vorLogin->zEMailVergessen()->setReturn( ret, *pEMail );
+		}
+		break;
+	case 10: // Account Geheimnis Ändern
+		// arg1 = char* -- Account Name
+		// arg2 = char* -- Account Passwort
+		// arg3 = char* -- Account Geheimnis
+		// arg4 = char* -- Neues Geheimnis
+		if( 1 )
+		{
+			hauptScreen->setdeckFarbe( 0x00000000 );
+			hauptScreen->setOnTop( 1 );
+			ladeAnimation->setSichtbar( 1 );
+			bool ret = registerKlient->geheimnisÄndern( (const char*)arg1, (const char*)arg2, (const char*)arg3, (const char*)arg4 );
+			ladeAnimation->setSichtbar( 0 );
+			hauptScreen->setOnTop( 0 );
+			vorLogin->zGeheimnisÄndern()->setResult( ret );
+		}
+		break;
+	case 11: // Account Geheimnis Vergessen
+		// arg1 = char* -- Account Name
+		// arg2 = char* -- Account Passwort
+		if( 1 )
+		{
+			hauptScreen->setdeckFarbe( 0x00000000 );
+			hauptScreen->setOnTop( 1 );
+			ladeAnimation->setSichtbar( 1 );
+			bool ret = registerKlient->geheimnisVergessen( (const char*)arg1, (const char*)arg2 );
+			ladeAnimation->setSichtbar( 0 );
+			hauptScreen->setOnTop( 0 );
+			vorLogin->zGeheimnisVergessen()->setResult( ret );
+		}
+		break;
+	case 12: // Account Name Vergessen
+		// arg1 = char* -- Account Passwort
+		// arg2 = char* -- Account Geheimnis
+		if( 1 )
+		{
+			hauptScreen->setdeckFarbe( 0x00000000 );
+			hauptScreen->setOnTop( 1 );
+			ladeAnimation->setSichtbar( 1 );
+			bool ret = registerKlient->nameVergessen( (const char*)arg1, (const char*)arg2 );
+			ladeAnimation->setSichtbar( 0 );
+			hauptScreen->setOnTop( 0 );
+			vorLogin->zNameVergessen()->setResult( ret );
+		}
+		break;
+	case 13: // Account Passwort Ändern
+		// arg1 = char* -- Account Name
+		// arg2 = char* -- Account Passwort
+		// arg3 = char* -- Account Geheimnis
+		// arg4 = char* -- Neues Passwort
+		if( 1 )
+		{
+			hauptScreen->setdeckFarbe( 0x00000000 );
+			hauptScreen->setOnTop( 1 );
+			ladeAnimation->setSichtbar( 1 );
+			bool ret = registerKlient->passwortÄndern( (const char*)arg1, (const char*)arg2, (const char*)arg3, (const char*)arg4 );
+			ladeAnimation->setSichtbar( 0 );
+			hauptScreen->setOnTop( 0 );
+			vorLogin->zPasswortÄndern()->setResult( ret );
+		}
+		break;
+	case 14: // Account Passwort Vergessen
+		// arg1 = char* -- Account Name
+		// arg2 = char* -- Account Geheimnis
+		if( 1 )
+		{
+			hauptScreen->setdeckFarbe( 0x00000000 );
+			hauptScreen->setOnTop( 1 );
+			ladeAnimation->setSichtbar( 1 );
+			bool ret = registerKlient->passwortVergessen( (const char*)arg1, (const char*)arg2 );
+			ladeAnimation->setSichtbar( 0 );
+			hauptScreen->setOnTop( 0 );
+			vorLogin->zPasswortVergessen()->setResult( ret );
+		}
+		break;
+	case 15: // Account Erstellen
+		// arg1 = char* -- Account Name
+		// arg2 = char* -- Account Passwort
+		// arg3 = char* -- Account Geheimnis
+		// arg4 = char* -- Account E-Mail
+		// arg5 = Datum* -- Geburtsdatum
+		if( 1 )
+		{
+			hauptScreen->setdeckFarbe( 0x00000000 );
+			hauptScreen->setOnTop( 1 );
+			ladeAnimation->setSichtbar( 1 );
+			bool ret = registerKlient->accountErstellen( (const char*)arg1,
+														 (const char*)arg2,
+														 (const char*)arg3,
+														 (const char*)arg4,
+														 (unsigned short)( (Datum*)arg5 )->getJahr(),
+														 (char)( (Datum*)arg5 )->getMonat(),
+														 (char)( (Datum*)arg5 )->getTag() );
+			ladeAnimation->setSichtbar( 0 );
+			hauptScreen->setOnTop( 0 );
+			vorLogin->zRegistrierung()->setWeiterReturn( ret );
+			( (Datum*)arg5 )->release();
+		}
+		break;
+	case 16: // account Erstellen Fertig
+		// arg1 = char* -- Schlüssel
+		if( 1 )
+		{
+			hauptScreen->setdeckFarbe( 0x00000000 );
+			hauptScreen->setOnTop( 1 );
+			ladeAnimation->setSichtbar( 1 );
+			bool ret = registerKlient->bestätigen( (const char*)arg1 );
+			ladeAnimation->setSichtbar( 0 );
+			hauptScreen->setOnTop( 0 );
+			vorLogin->zRegistrierung()->setFertigReturn( ret );
+		}
+		break;
+	case 17: // account Löschen Fertig
+		// arg1 = char* -- Account Name
+		// arg2 = char* -- Account Passwort
+		// arg3 = char* -- Account Geheimnis
+		if( 1 )
+		{
+			hauptScreen->setdeckFarbe( 0x00000000 );
+			hauptScreen->setOnTop( 1 );
+			ladeAnimation->setSichtbar( 1 );
+			bool ret = registerKlient->accountLöschen( (const char*)arg1, (const char*)arg2, (const char*)arg3 );
+			ladeAnimation->setSichtbar( 0 );
+			hauptScreen->setOnTop( 0 );
+			vorLogin->zUnregistrierung()->setWeiterReturn( ret );
+		}
+		break;
+	case 18: // account Löschen Fertig
+		// arg1 = char* -- Schlüssel
+		if( 1 )
+		{
+			hauptScreen->setdeckFarbe( 0x00000000 );
+			hauptScreen->setOnTop( 1 );
+			ladeAnimation->setSichtbar( 1 );
+			bool ret = registerKlient->bestätigen( (const char*)arg1 );
+			ladeAnimation->setSichtbar( 0 );
+			hauptScreen->setOnTop( 0 );
+			vorLogin->zUnregistrierung()->setFertigReturn( ret );
+		}
+		break;
+	case 19: // Spiel Laden
+		if( 1 )
+		{
+			hauptScreen->setdeckFarbe( 0x00000000 );
+			hauptScreen->setOnTop( 1 );
+			ladeAnimation->setSichtbar( 1 );
+			for( unsigned char deckAlpha = 0; deckAlpha < 255; )
+			{
+				hauptScreen->setdeckFarbe( deckAlpha << 24 );
+				Sleep( 40 );
+				deckAlpha += 15;
+			}
+			hauptScreen->setdeckFarbe( 255 << 24 );
+			_render = 0;
+			hauptScreen->lock();
+			int karteId = nachLogin->zSpielenFenster()->getKarteId();
+			SpielerTeamStruktur *sts = nachLogin->zSpielenFenster()->getSTS();
+			nachLogin->setAnzeige( NLAImSpiel );
+			hauptScreen->unlock();
+			_render = 1;
+			nachLogin->zImSpiel()->beginnLaden( karteId, sts );
+			ladeAnimation->setSichtbar( 0 );
+			for( unsigned char deckAlpha = 255; deckAlpha > 0; )
+			{
+				hauptScreen->setdeckFarbe( deckAlpha << 24 );
+				Sleep( 40 );
+				deckAlpha -= 15;
+			}
+			hauptScreen->setdeckFarbe( 0 << 24 );
+			hauptScreen->setOnTop( 0 );
+		}
+		break;
+	case 20: // Spiel Statistik laden
+		if( 1 )
+		{
+			hauptScreen->setdeckFarbe( 0x00000000 );
+			hauptScreen->setOnTop( 1 );
+			ladeAnimation->setSichtbar( 1 );
+			for( unsigned char deckAlpha = 0; deckAlpha < 255; )
+			{
+				hauptScreen->setdeckFarbe( deckAlpha << 24 );
+				Sleep( 40 );
+				deckAlpha += 15;
+			}
+			hauptScreen->setdeckFarbe( 255 << 24 );
+			_render = 0;
+			hauptScreen->lock();
+			int karteId = nachLogin->zImSpiel()->getKarteId();
+			nachLogin->setAnzeige( NLANormal );
+			hauptScreen->unlock();
+			_render = 1;
+			if( spielKlient->istVerbunden() )
+				nachLogin->zSpielenFenster()->ladeSpielStatistik( karteId );
+			ladeAnimation->setSichtbar( 0 );
+			for( unsigned char deckAlpha = 255; deckAlpha > 0; )
+			{
+				hauptScreen->setdeckFarbe( deckAlpha << 24 );
+				Sleep( 40 );
+				deckAlpha -= 15;
+			}
+			hauptScreen->setdeckFarbe( 0 << 24 );
+			hauptScreen->setOnTop( 0 );
+		}
+		break;
+	case 21: // Spiel Aufzeichnung betreten
+		if( 1 )
+		{
+			hauptScreen->setdeckFarbe( 0x00000000 );
+			hauptScreen->setOnTop( 1 );
+			ladeAnimation->setSichtbar( 1 );
+			for( unsigned char deckAlpha = 0; deckAlpha < 255; )
+			{
+				hauptScreen->setdeckFarbe( deckAlpha << 24 );
+				Sleep( 40 );
+				deckAlpha += 15;
+			}
+			hauptScreen->setdeckFarbe( 255 << 24 );
+			_render = 0;
+			hauptScreen->lock();
+			nachLogin->setAnzeige( NLASpielVideo );
+			hauptScreen->unlock();
+			_render = 1;
+			ladeAnimation->setSichtbar( 0 );
+			for( unsigned char deckAlpha = 255; deckAlpha > 0; )
+			{
+				hauptScreen->setdeckFarbe( deckAlpha << 24 );
+				Sleep( 40 );
+				deckAlpha -= 15;
+			}
+			hauptScreen->setdeckFarbe( 0 << 24 );
+			hauptScreen->setOnTop( 0 );
+		}
+		break;
+	case 22: // Spiel Aufzeichnung / Editor verlassen
+		if( 1 )
+		{
+			hauptScreen->setdeckFarbe( 0x00000000 );
+			hauptScreen->setOnTop( 1 );
+			ladeAnimation->setSichtbar( 1 );
+			for( unsigned char deckAlpha = 0; deckAlpha < 255; )
+			{
+				hauptScreen->setdeckFarbe( deckAlpha << 24 );
+				Sleep( 40 );
+				deckAlpha += 15;
+			}
+			hauptScreen->setdeckFarbe( 255 << 24 );
+			_render = 0;
+			hauptScreen->lock();
+			nachLogin->setAnzeige( NLANormal );
+			hauptScreen->unlock();
+			_render = 1;
+			ladeAnimation->setSichtbar( 0 );
+			for( unsigned char deckAlpha = 255; deckAlpha > 0; )
+			{
+				hauptScreen->setdeckFarbe( deckAlpha << 24 );
+				Sleep( 40 );
+				deckAlpha -= 15;
+			}
+			hauptScreen->setdeckFarbe( 0 << 24 );
+			hauptScreen->setOnTop( 0 );
+		}
+		break;
+    case 23: // Editor betreten
+        if( 1 )
+        {
+            hauptScreen->setdeckFarbe( 0x00000000 );
+            hauptScreen->setOnTop( 1 );
+            ladeAnimation->setSichtbar( 1 );
+            for( unsigned char deckAlpha = 0; deckAlpha < 255; )
+            {
+                hauptScreen->setdeckFarbe( deckAlpha << 24 );
+                Sleep( 40 );
+                deckAlpha += 15;
+            }
+            hauptScreen->setdeckFarbe( 255 << 24 );
+            _render = 0;
+            hauptScreen->lock();
+            nachLogin->setAnzeige( NLAEditor );
+            hauptScreen->unlock();
+            _render = 1;
+            ladeAnimation->setSichtbar( 0 );
+            for( unsigned char deckAlpha = 255; deckAlpha > 0; )
+            {
+                hauptScreen->setdeckFarbe( deckAlpha << 24 );
+                Sleep( 40 );
+                deckAlpha -= 15;
+            }
+            hauptScreen->setdeckFarbe( 0 << 24 );
+            hauptScreen->setOnTop( 0 );
+        }
+        break;
+	}
+	release();
+}
+
+// constant
+
+// Reference Counting
+AktionsThread *AktionsThread::getThis()
+{
+	ref++;
+	return this;
+}
+
+AktionsThread *AktionsThread::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 31 - 0
KSGClient/Aktionen/AktionsThread.h

@@ -0,0 +1,31 @@
+#ifndef AktionsThread_H
+#define AktionsThread_H
+
+#include <Klient.h>
+#include <Thread.h>
+
+using namespace Framework;
+
+class AktionsThread : public Thread
+{
+private:
+	int aktion;
+	int ref;
+	void *arg1;
+	void *arg2;
+	void *arg3;
+	void *arg4;
+	void *arg5;
+
+public:
+	// Konstruktor
+	AktionsThread( int aktion, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5 );
+	// nicht constant
+	virtual void thread();
+	// constant
+	// Reference Counting
+	AktionsThread *getThis();
+	AktionsThread *release();
+};
+
+#endif

+ 124 - 0
KSGClient/Global/Bilder.cpp

@@ -0,0 +1,124 @@
+#include "Bilder.h"
+
+// Inhalt der Bilder Klasse aus Bilder.h
+// Konstruktor
+Bilder::Bilder()
+{
+	next = 0;
+	name = new Text( "" );
+	bild = 0;
+}
+
+// Destruktor
+Bilder::~Bilder()
+{
+	if( bild )
+		bild->release();
+	name->release();
+	delete (Bilder*)next;
+}
+
+// nicht constant
+bool Bilder::add( const char *name, Bild *bild )
+{
+	if( this->name->istGleich( name ) )
+	{
+		bild->release();
+		return 0;
+	}
+	if( !this->bild )
+	{
+		this->name->setText( name );
+		this->bild = bild;
+		return 1;
+	}
+	if( !next )
+		next = new Bilder();
+	return next->add( name, bild );
+}
+
+bool Bilder::set( const char *name, Bild *bild )
+{
+	if( this->name->istGleich( name ) )
+	{
+		this->bild->release();
+		this->bild = bild;
+		return 1;
+	}
+	if( !next )
+	{
+		bild->release();
+		return 0;
+	}
+	return next->set( name, bild );
+}
+
+bool Bilder::remove( const char *name )
+{
+	if( this->name->istGleich( name ) )
+	{
+		this->bild->release();
+		this->bild = next->zThis();
+		this->name->setText( ((Bilder*)next)->name );
+		BilderV *tmp = next->zNext();
+		next->setNext( 0 );
+		next->release();
+		next = tmp;
+		return 1;
+	}
+	if( !next )
+		return 0;
+	return next->remove( name );
+}
+
+void Bilder::setNext( BilderV *next )
+{
+	this->next = next;
+}
+
+void Bilder::deleteAll()
+{
+	bild = bild->release();
+	name->setText( "" );
+	next->release();
+	next = 0;
+}
+
+void Bilder::release()
+{
+	delete this;
+}
+
+// constant
+Bild *Bilder::get( const char *name ) const
+{
+	if( this->name->istGleich( name ) )
+		return bild ? bild->getThis() : 0;
+	if( !next )
+		return 0;
+	return next->get( name );
+}
+
+Bild *Bilder::z( const char *name ) const
+{
+	if( this->name->istGleich( name ) )
+		return bild;
+	if( !next )
+		return 0;
+	return next->get( name );
+}
+
+Bild *Bilder::zThis() const
+{
+	return bild;
+}
+
+BilderV *Bilder::zNext() const
+{
+	return next;
+}
+
+char *Bilder::getName() const
+{
+	return name->getText();
+}

+ 38 - 0
KSGClient/Global/Bilder.h

@@ -0,0 +1,38 @@
+#ifndef Bilder_H
+#define Bilder_H
+
+#include <Klient.h>
+#include <Text.h>
+#include <Bild.h>
+#include <BilderV.h>
+
+using namespace Framework;
+
+class Bilder : public BilderV
+{
+private:
+	Text *name;
+	Bild *bild;
+	BilderV *next;
+
+public:
+	// Konstruktor
+	Bilder();
+	// Destruktor
+	~Bilder();
+	// nicht constant
+	virtual bool add( const char *name, Bild *bild );
+	virtual bool set( const char *name, Bild *bild );
+	virtual bool remove( const char *name );
+	virtual void setNext( BilderV *next );
+	virtual void deleteAll();
+	virtual void release();
+	// constant
+	virtual Bild *get( const char *name ) const;
+	virtual Bild *z( const char *name ) const;
+	virtual Bild *zThis() const;
+	virtual BilderV *zNext() const;
+	virtual char *getName() const;
+};
+
+#endif

+ 94 - 0
KSGClient/Global/DLLDateien.cpp

@@ -0,0 +1,94 @@
+#include "DLLDateien.h"
+
+// Inhalt der DLLDateien Klasse aus DLLDateien.h
+// Konstruktor
+DLLDateien::DLLDateien()
+{
+	dlls = new Array< DLLDatei* >();
+	ref = 1;
+}
+
+// Destruktor
+DLLDateien::~DLLDateien()
+{
+    cs.lock();
+	int anz = dlls->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+	{
+		DLLDatei *tmp = dlls->get( i );
+		if( tmp )
+		{
+			tmp->name->release();
+			FreeLibrary( tmp->handle );
+		}
+		delete tmp;
+	}
+	dlls->release();
+    cs.unlock();
+}
+
+// nicht constant
+HINSTANCE DLLDateien::ladeDLL( char *name, char *pfad )
+{
+    cs.lock();
+	int anz = dlls->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+	{
+		DLLDatei *tmp = dlls->get( i );
+		if( tmp && tmp->name->istGleich( name ) )
+		{
+			tmp->ref++;
+            cs.unlock();
+			return tmp->handle;
+		}
+	}
+	HINSTANCE h = LoadLibrary( pfad );
+	if( !h )
+		return 0;
+	DLLDatei *dll = new DLLDatei();
+	dll->name = new Text( name );
+	dll->handle = h;
+	dll->ref = 1;
+	dlls->add( dll );
+    cs.unlock();
+	return h;
+}
+
+void DLLDateien::releaseDLL( char *name )
+{
+    cs.lock();
+	int anz = dlls->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+	{
+		DLLDatei *tmp = dlls->get( i );
+		if( tmp && tmp->name->istGleich( name ) )
+		{
+			tmp->ref--;
+			if( !tmp->ref )
+			{
+				tmp->name->release();
+				FreeLibrary( tmp->handle );
+				delete tmp;
+				dlls->remove( i );
+			}
+            cs.unlock();
+			return;
+		}
+	}
+    cs.unlock();
+}
+
+// Reference Counting
+DLLDateien *DLLDateien::getThis()
+{
+	ref++;
+	return this;
+}
+
+DLLDateien *DLLDateien::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 37 - 0
KSGClient/Global/DLLDateien.h

@@ -0,0 +1,37 @@
+#ifndef DLLDateien_H
+#define DLLDateien_H
+
+#include <Text.h>
+#include <Array.h>
+#include <Critical.h>
+
+using namespace Framework;
+
+struct DLLDatei
+{
+	Text *name;
+	HINSTANCE handle;
+	int ref;
+};
+
+class DLLDateien
+{
+private:
+	Array< DLLDatei* > *dlls;
+	Critical cs;
+	int ref;
+
+public:
+	// Konstruktor
+	DLLDateien();
+	// Destruktor
+	~DLLDateien();
+	// nicht constant
+	HINSTANCE ladeDLL( char *name, char *pfad );
+	void releaseDLL( char *name );
+	// Reference Counting
+	DLLDateien *getThis();
+	DLLDateien *release();
+};
+
+#endif

+ 126 - 0
KSGClient/Global/Fps.cpp

@@ -0,0 +1,126 @@
+#include "Fps.h"
+#include <Bild.h>
+#include <Prozess.h>
+#include <Schrift.h>
+#include <Text.h>
+
+using namespace Framework;
+
+// Inhalt der Fps Klasse aus Fps.h
+// Konstruktor 
+Fps::Fps()
+{
+	pr = new Prozess();
+	i = 0;
+	fpsCount = 0;
+	nowFps = 0;
+	nowCpu = 0;
+	nowMem = 0;
+	schrift = 0;
+	sFarbe = 0;
+	ref = 1;
+}
+
+// Destruktor 
+Fps::~Fps()
+{
+	delete pr;
+	if( schrift )
+		schrift = schrift->release();
+}
+
+// nicht constant
+void Fps::setSchriftZ( Schrift *schrift ) // setzt die Schrift
+{
+	if( this->schrift )
+		this->schrift = this->schrift->release();
+	this->schrift = schrift;
+	rend = 1;
+}
+
+void Fps::setSFarbe( int f ) // setzt die Schrift Farbe
+{
+	sFarbe = f;
+	rend = 1;
+}
+
+bool Fps::tick( double tickval ) // tick
+{
+	i += tickval * 60;
+	if( i >= 60 )
+	{
+		nowFps = fpsCount;
+		nowCpu = (int)pr->getCPU();
+		nowMem = (int)(pr->getMem() / 1024);
+		fpsCount = 0;
+		i -= 60;
+		rend = 1;
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void Fps::render( Bild &zrObj ) // zeichnet nach zrObj
+{
+	fpsCount++;
+	if( schrift && sFarbe )
+	{
+		Text renderT( "FPS: " );
+		renderT.append( nowFps );
+		renderT.append( "\nCPU: " );
+		renderT.append( nowCpu );
+		renderT.append( "%\nMem: " );
+		renderT.append( nowMem );
+		renderT.append( "kb" );
+		schrift->setDrawPosition( 10, 10 );
+		schrift->setSchriftSize( 12 );
+		schrift->renderText( &renderT, zrObj, sFarbe );
+	}
+}
+
+// constant
+int Fps::getFps() const // gibt fps zurück
+{
+	return nowFps;
+}
+
+int Fps::getCpu() const // gibt die Cpu zurück
+{
+	return nowCpu;
+}
+
+int Fps::getMem() const // gibt den Arbeitsspeicher zurück
+{
+	return nowMem;
+}
+
+Schrift *Fps::getSchrift() const // gibt die Schrift zurück
+{
+	return schrift ? schrift->getThis() : 0;
+}
+
+Schrift *Fps::zSchrift() const
+{
+	return schrift;
+}
+
+int Fps::getFarbe() const // gibt die Farbe zurück
+{
+	return sFarbe;
+}
+
+// Reference Counting
+Fps *Fps::getThis()
+{
+	ref++;
+	return this;
+}
+
+Fps *Fps::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 49 - 0
KSGClient/Global/Fps.h

@@ -0,0 +1,49 @@
+#ifndef Fps_H
+#define Fps_H
+
+#include <Zeichnung.h>
+
+namespace Framework
+{
+	class Prozess; // Prozess.h
+	class Bild; // Bild.h
+	class Schrift; // Schrift.h
+	class Fps; // aus dieser Datei
+
+	class Fps : public Zeichnung
+	{
+	private:
+		Prozess *pr;
+		double i;
+		int fpsCount;
+		int nowFps;
+		int nowCpu;
+		int nowMem;
+		Schrift *schrift;
+		int sFarbe;
+		int ref;
+
+	public:
+		// Konstruktor 
+		Fps();
+		// Destruktor 
+		~Fps();
+		// nicht constant
+		void setSchriftZ( Schrift *schrift ); // setzt die Schrift
+		void setSFarbe( int f ); // setzt die Schrift Farbe
+		bool tick( double tickval ) override; // tick
+		void render( Bild &zRObj ) override; // zeichnet nach zrObj
+		// constant
+		Schrift *getSchrift() const; // gibt die Schrift zurück
+		Schrift *zSchrift() const;
+		int getFarbe() const; // gibt die Farbe zurück
+		int getFps() const; // gibt fps zurück
+		int getCpu() const; // gibt die Cpu zurück
+		int getMem() const; // gibt den Arbeitsspeicher zurück
+		// Reference Counting
+		Fps *getThis();
+		Fps *release();
+	};
+}
+
+#endif

+ 351 - 0
KSGClient/Global/Initialisierung.cpp

@@ -0,0 +1,351 @@
+#include "Initialisierung.h"
+#include <ToolTip.h>
+#include <Bildschirm.h>
+#include <MausEreignis.h>
+#include <DateiSystem.h>
+#include "Variablen.h"
+
+Knopf *initKnopf( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, char *titel )
+{
+	Knopf *ret = new Knopf();
+	ret->addStyle( style );
+	ret->setPosition( x, y );
+	ret->setSize( br, hö );
+	if( zSchrift )
+		ret->setSchriftZ( zSchrift->getThis() );
+	ret->setText( titel );
+	return ret;
+}
+
+KontrollKnopf *initKontrollKnopf( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, char *txt )
+{
+	KontrollKnopf *ret = new KontrollKnopf();
+    ret->setMausEreignis( _ret1ME );
+	ret->setStyle( style );
+	ret->setSchriftZ( zSchrift->getThis() );
+	ret->setText( txt );
+	ret->setSText( txt );
+	ret->setSFarbe( 0xFFFFFFFF );
+	ret->setSSize( 12 );
+	if( ret->hatStyle( TextFeld::Style::Buffered ) )
+	{
+		ret->setAlphaFeldFarbe( 0x5500FF00 );
+		ret->setAlphaFeldStrength( -5 );
+	}
+	if( ret->hatStyle( TextFeld::Style::Rahmen ) )
+	{
+		ret->setLinienRahmenBreite( 1 );
+		ret->setLinienRahmenFarbe( 0xFF00FF00 );
+	}
+	ret->setPosition( x, y );
+	ret->setSize( br, hö );
+	ret->loadData( "data/bilder/system.ltdb" );
+	return ret;
+}
+
+Fenster *initFenster( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, char *titel )
+{
+	Fenster *ret = new Fenster();
+    ret->setMausEreignis( _ret1ME );
+    ret->setTastaturEreignis( _ret1TE );
+	ret->setStyle( style );
+	ret->setPosition( x, y );
+	ret->setSize( br, hö );
+	if( ret->hatStyle( Fenster::Style::Rahmen ) )
+	{
+		ret->setRBreite( 1 );
+		ret->setRFarbe( 0xFFFFFFFF );
+	}
+	if( ret->hatStyle( Fenster::Style::Titel ) )
+	{
+		ret->setTitel( titel );
+		ret->setTSchriftZ( zSchrift->getThis() );
+		ret->setTSFarbe( 0xFFFFFFFF );
+		ret->zTTextFeld()->setSize( 0, 20 );
+		ret->zTTextFeld()->addStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Center | TextFeld::Style::Rahmen );
+		ret->setTRFarbe( 0xFF00FF00 );
+		ret->setTRBreite( 1 );
+		if( ret->hatStyle( Fenster::Style::TitelBuffered ) )
+		{
+			ret->setTAfFarbe( 0x1000FF00 );
+			ret->setTAfStrength( -15 );
+		}
+	}
+    if( ret->hatStyle( Fenster::Style::Closable ) )
+    {
+        if( ret->hatStyle( Fenster::Style::ClosingKlickBuffer ) )
+        {
+            ret->setSKAfFarbe( 0xFF00FF00 );
+            ret->setSKAfStrength( 30 );
+        }
+    }
+	return ret;
+}
+
+TextFeld *initTextFeld( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, char *txt )
+{
+    TextFeld *ret = new TextFeld();
+    ret->setStyle( style );
+    ret->setSchriftZ( zSchrift->getThis() );
+    ret->setText( txt );
+    ret->setSchriftFarbe( 0xFFFFFFFF );
+    ret->setSchriftSize( 12 );
+    if( ret->hatStyle( TextFeld::Style::Buffered ) )
+    {
+        ret->setAlphaFeldFarbe( 0x5500FF00 );
+        ret->setAlphaFeldStrength( -5 );
+    }
+    if( ret->hatStyle( TextFeld::Style::Rahmen ) )
+    {
+        ret->setLinienRahmenBreite( 1 );
+        ret->setLinienRahmenFarbe( 0xFF00FF00 );
+    }
+    ret->setPosition( x, y );
+    ret->setSize( br, hö );
+    return ret;
+}
+
+BildZ *initBildZ( int x, int y, int br, int hö, __int64 style, Bild *b )
+{
+	BildZ *ret = new BildZ();
+	ret->setStyle( style );
+	ret->setPosition( x, y );
+	ret->setSize( br, hö );
+	if( b )
+		ret->setBildZ( b );
+	if( ( style | BildZ::Style::Rahmen ) == style )
+	{
+		ret->setLinienRahmenBreite( 1 );
+		ret->setLinienRahmenFarbe( 0xFFFFFFFF );
+	}
+	return ret;
+}
+
+AuswahlBox *initAuswahlBox( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, std::initializer_list< char * > values )
+{
+	AuswahlBox *ret = new AuswahlBox();
+	ret->setStyle( style );
+	ret->setPosition( x, y );
+	ret->setSize( br, hö );
+	if( ( style | AuswahlBox::Style::Hintergrund ) == style )
+		ret->setHintergrundFarbe( 0xFF000000 );
+	if( ( style | AuswahlBox::Style::Erlaubt ) == style )
+		ret->setMausEreignis( _ret1ME );
+	if( zSchrift )
+		ret->setSchriftZ( zSchrift->getThis() );
+	if( ( style | AuswahlBox::Style::Rahmen ) == style )
+	{
+		ret->setLinienRahmenBreite( 1 );
+		ret->setLinienRahmenFarbe( 0xFFFFFFFF );
+	}
+	if( ( style | AuswahlBox::Style::MaxHeight ) == style )
+		ret->setMaxAuskappHeight( 100 );
+	if( ( style | AuswahlBox::Style::MausRahmen ) == style )
+	{
+		ret->setMausRahmenBreite( 1 );
+		ret->setMausRahmenFarbe( 0xFF005500 );
+	}
+	if( ( style | AuswahlBox::Style::MausBuffer ) == style )
+	{
+		ret->setMausAlphaFeldFarbe( 0x00008700 );
+		ret->setMausAlphaFeldStrength( -8 );
+	}
+	if( ( style | AuswahlBox::Style::AuswahlRahmen ) == style )
+	{
+		ret->setAuswRahmenBreite( 1 );
+		ret->setAuswRahmenFarbe( 0xFF00FF00 );
+	}
+	if( ( style | AuswahlBox::Style::AuswahlBuffer ) == style )
+	{
+		ret->setAuswAlphaFeldFarbe( 0x0000FF00 );
+		ret->setAuswAlphaFeldStrength( -8 );
+	}
+	for( auto i = values.begin(); i != values.end(); i++ )
+		ret->addEintrag( *i );
+	return ret;
+}
+
+ObjTabelle *initObjTabelle( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, std::initializer_list< OBJTabelleSpalteIni > spalten, int überschriftHöhe )
+{
+	ObjTabelle *ret = new ObjTabelle();
+	ret->setStyle( style );
+	ret->setPosition( x, y );
+	ret->setSize( br, hö );
+	if( ( style | ObjTabelle::Style::Erlaubt ) == style )
+		ret->setMausEreignis( _ret1ME );
+	if( ( style | ObjTabelle::Style::Rahmen ) == style )
+	{
+		ret->setLinienRahmenBreite( 1 );
+		ret->setLinienRahmenFarbe( 0xFFFFFFFF );
+	}
+	if( ( style | ObjTabelle::Style::Raster ) == style )
+	{
+		ret->setRasterBreite( 1 );
+		ret->setRasterFarbe( 0xFFFFFFFF );
+	}
+	if( ( style | ObjTabelle::Style::VScroll ) == style )
+		ret->setVertikalKlickScroll( 5 );
+	if( ( style | ObjTabelle::Style::HScroll ) == style )
+		ret->setHorizontalKlickScroll( 5 );
+	for( auto i = spalten.begin(); i != spalten.end(); i++ )
+	{
+		ret->addSpalte( i->name );
+		ret->setSpaltenBreite( i->name, i->breite );
+		if( ( style | ObjTabelle::Style::SpaltenBreiteMin ) == style )
+			ret->setMinSpaltenBreite( i->name, i->minBreite );
+		if( ( style | ObjTabelle::Style::SpaltenBreiteMax ) == style )
+			ret->setMaxSpaltenBreite( i->name, i->maxBreite );
+		if( überschriftHöhe )
+		{
+			if( ret->getZeilenNummer( "Überschrift" ) < 0 )
+			{
+				ret->addZeile( 0, "Überschrift" );
+				ret->setZeilenHeight( 0, 20 );
+			}
+			ret->setZeichnungZ( i->name, "Überschrift", initTextFeld( 0, 0, i->breite, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, i->name ) );
+		}
+	}
+	return ret;
+}
+
+LDiag *initLinienDiagramm( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, DiagDaten *data )
+{
+	LDiag *ret = new LDiag();
+	ret->setStyle( style );
+	ret->setPosition( x, y );
+	ret->setSize( br, hö );
+	if( zSchrift )
+	{
+		ret->setSchriftZ( zSchrift->getThis() );
+		ret->setSchriftSize( 12 );
+	}
+	if( data )
+		ret->setDiagDatenZ( data );
+	if( ret->hatStyle( LDiag::Style::Rahmen ) )
+	{
+		ret->setLinienRahmenBreite( 1 );
+		ret->setLinienRahmenFarbe( 0xFFFFFFFF );
+	}
+	if( ret->hatStyle( LDiag::Style::DatenRahmen ) )
+	{
+		ret->setDatenRahmenBreite( 1 );
+		ret->setDatenRahmenFarbe( 0xFFFFFFFF );
+	}
+	if( ret->hatStyle( LDiag::Style::Hintergrund ) )
+		ret->setHintergrundFarbe( 0xFF000000 );
+	if( ret->hatStyle( LDiag::Style::DatenHintergrund ) )
+		ret->setHintergrundFarbe( 0xFF000000 );
+	return ret;
+}
+
+FBalken *initFBalken( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style )
+{
+	FBalken *ret = new FBalken();
+	ret->setStyle( style );
+	ret->setPosition( x, y );
+	ret->setSize( br, hö );
+	if( zSchrift )
+	{
+		ret->setSchriftZ( zSchrift->getThis() );
+		ret->setSFarbe( 0xFFFFFFFF );
+		ret->setSSize( 12 );
+	}
+	if( ret->hatStyle( FBalken::Style::Rahmen ) )
+	{
+		ret->setLinienRahmenFarbe( 0xFFFFFFFF );
+		ret->setLinienRahmenBreite( 1 );
+	}
+	if( ret->hatStyle( FBalken::Style::HBild ) )
+	{
+		Bild *fbhb = bilder->get( "system.ltdb/fortschritt lehr.png" );
+		if( !fbhb )
+		{
+			LTDBDatei *datei = new LTDBDatei();
+			datei->setDatei( new Text( "data/bilder/system.ltdb" ) );
+			datei->leseDaten( 0 );
+			fbhb = datei->laden( 0, new Text( "fortschrittleh" ) );
+			datei->release();
+			bilder->add( "system.ltdb/fortschritt lehr.png", fbhb->getThis() );
+		}
+		ret->setHintergrundBildZ( fbhb );
+	}
+	if( ret->hatStyle( FBalken::Style::FBild ) )
+	{
+		Bild *fbfhb = bilder->get( "system.ltdb/fortschritt voll.png" );
+		if( !fbfhb )
+		{
+			LTDBDatei *datei = new LTDBDatei();
+			datei->setDatei( new Text( "data/bilder/system.ltdb" ) );
+			datei->leseDaten( 0 );
+			fbfhb = datei->laden( 0, new Text( "fortschrittvol" ) );
+			datei->release();
+			bilder->add( "system.ltdb/fortschritt voll.png", fbfhb->getThis() );
+		}
+		ret->setFBgBildZ( fbfhb );
+	}
+	else if( ret->hatStyle( FBalken::Style::FFarbe ) )
+		ret->setFBgFarbe( 0xFF00FF00 );
+	return ret;
+}
+
+AuswahlListe *initAuswahlListe( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, std::initializer_list< char * > values )
+{
+    AuswahlListe *ret = new AuswahlListe();
+    ret->setPosition( x, y );
+    ret->setSize( br, hö );
+    ret->setStyle( style );
+    ret->setSchriftZ( zSchrift->getThis() );
+    if( ret->hatStyle( AuswahlListe::Style::Buffered ) )
+    {
+        ret->setAlphaFeldFarbe( 0x5500FF00 );
+        ret->setAlphaFeldStrength( -5 );
+    }
+    if( ret->hatStyle( AuswahlListe::Style::Rahmen ) )
+    {
+        ret->setLinienRahmenBreite( 1 );
+        ret->setLinienRahmenFarbe( 0xFFFFFFFF );
+    }
+    if( ( style | AuswahlListe::Style::Hintergrund ) == style )
+        ret->setHintergrundFarbe( 0xFF000000 );
+    if( ( style | AuswahlListe::Style::Erlaubt ) == style )
+        ret->setMausEreignis( _ret1ME );
+    if( ( style | AuswahlListe::Style::AuswahlRahmen ) == style )
+    {
+        ret->setALRBreite( 1 );
+        ret->setALRFarbe( 0xFF00FF00 );
+    }
+    if( ( style | AuswahlListe::Style::AuswahlBuffer ) == style )
+    {
+        ret->setAAFFarbe( 0x0000FF00 );
+        ret->setAAFStrength( -8 );
+    }
+    for( auto i = values.begin(); i != values.end(); i++ )
+        ret->addEintrag( *i );
+    ret->update();
+    return ret;
+}
+
+ZeichnungHintergrund *initZeichnungHintergrund( int x, int y, int br, int hö, __int64 style, int farbe )
+{
+    ZeichnungHintergrund *ret = new ZeichnungHintergrund();
+    ret->setStyle( style );
+    ret->setHintergrundFarbe( farbe );
+    if( ret->hatStyle( ZeichnungHintergrund::Style::Rahmen ) )
+    {
+        ret->setLinienRahmenBreite( 1 );
+        ret->setLinienRahmenFarbe( 0xFF00FF00 );
+    }
+    ret->setPosition( x, y );
+    ret->setSize( br, hö );
+    return ret;
+}
+
+void initToolTip( Zeichnung *obj, const char *txt, Schrift *schrift, Bildschirm *zBs )
+{
+	obj->setToolTipText( txt , zBs );
+	obj->zToolTip()->setSchriftZ( schrift );
+	obj->zToolTip()->addStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Rahmen | TextFeld::Style::Hintergrund | TextFeld::Style::HAlpha | TextFeld::Style::Mehrzeilig );
+	obj->zToolTip()->setHintergrundFarbe( 0xA0000000 );
+	obj->zToolTip()->setLinienRahmenFarbe( 0xFFFFFFFF );
+	obj->zToolTip()->setSchriftFarbe( 0xFFFFFFFF );
+}

+ 42 - 0
KSGClient/Global/Initialisierung.h

@@ -0,0 +1,42 @@
+#ifndef Initialisierung_H
+#define Initialisierung_H
+
+#include <Fenster.h>
+#include <Knopf.h>
+#include <TextFeld.h>
+#include <Schrift.h>
+#include <initializer_list>
+#include <AuswahlBox.h>
+#include <Tabelle.h>
+#include <Bild.h>
+#include <Diagramm.h>
+#include <Fortschritt.h>
+#include <Liste.h>
+
+using namespace Framework;
+
+struct OBJTabelleSpalteIni
+{
+	char *name;
+	int breite;
+	int minBreite;
+	int maxBreite;
+};
+
+#define ABSTYLE AuswahlBox::Style::Sichtbar | AuswahlBox::Style::Erlaubt | AuswahlBox::Style::Rahmen | AuswahlBox::Style::AuswahlBuffer | AuswahlBox::Style::MausBuffer | AuswahlBox::Style::MaxHeight | AuswahlBox::Style::Hintergrund | AuswahlBox::Style::VScroll
+#define OTSTYLE ObjTabelle::Style::Sichtbar | ObjTabelle::Style::Erlaubt | ObjTabelle::Style::Rahmen | ObjTabelle::Style::Raster
+
+Knopf *initKnopf( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, char *titel );
+KontrollKnopf *initKontrollKnopf( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, char *txt );
+Fenster *initFenster( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, char *titel );
+TextFeld *initTextFeld( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, char *txt );
+BildZ *initBildZ( int x, int y, int br, int hö, __int64 style, Bild *b );
+AuswahlBox *initAuswahlBox( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, std::initializer_list< char * > values );
+ObjTabelle *initObjTabelle( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, std::initializer_list< OBJTabelleSpalteIni > spalten, int überschriftHöhe );
+LDiag *initLinienDiagramm( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, DiagDaten *data );
+FBalken *initFBalken( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style );
+AuswahlListe *initAuswahlListe( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, std::initializer_list< char * > values );
+ZeichnungHintergrund *initZeichnungHintergrund( int x, int y, int br, int hö, __int64 style, int farbe );
+void initToolTip( Zeichnung *obj, const char *txt, Schrift *schrift, Bildschirm *zBs );
+
+#endif

+ 185 - 0
KSGClient/Global/Render.cpp

@@ -0,0 +1,185 @@
+#include "Variablen.h"
+#include "Render.h"
+#include <Globals.h>
+#include <TastaturEreignis.h>
+#include "..\Aktionen\AktionsThread.h"
+
+// Inhalt der Render Klasse aus Render.h
+// Konstruktor 
+Render::Render( Schrift *schrift )
+    : Thread()
+{
+	exit = 0;
+	bildschirm = 0;
+	ref = 1;
+	time = new ZeitMesser();
+	tickval = 1.0 / 60;
+	fps = new Fps();
+	fps->setSchriftZ( schrift );
+	fps->setSFarbe( 0xFFFFFFFF );
+	deckAlpha = 0;
+	inAnimation = 0;
+	exit = 0;
+}
+
+// Destruktor 
+Render::~Render()
+{
+	if( bildschirm )
+		bildschirm = bildschirm->release();
+	time = time->release();
+	fps = fps->release();
+}
+
+// nicht constant 
+void Render::setBildschirm( Bildschirm *bildschirm ) // setzt den Bildschirm
+{
+	this->bildschirm = bildschirm;
+}
+
+void Render::thread() // Render Schleife
+{
+	bool fpsAdd = 0;
+	time->messungStart();
+	double ausgleich = 0;
+	while( !exit )
+	{
+		if( bildschirm )
+		{
+			if( Framework::getTastenStand( T_F1 ) )
+			{
+				if( !fpsAdd )
+				{
+					bildschirm->addMember( fps );
+					fpsAdd = 1;
+				}
+			}
+			else
+			{
+				if( fpsAdd )
+				{
+					bildschirm->removeMember( fps );
+					fpsAdd = 0;
+
+				}
+			}
+			if( _render == 1 )
+			{
+				bildschirm->render();
+				bildschirm->tick( tickval );
+			}
+			else
+				Sleep( 100 );
+		}
+		else
+			Sleep( 100 );
+		ausgleich += 1.0 / 30 - tickval;
+		if( ausgleich > 0 )
+			Sleep( (int)( ausgleich * 1000 ) );
+		time->messungEnde();
+		time->messungStart();
+		tickval = time->getSekunden();
+		switch( aktion )
+		{
+		case 1: // Chat Client neu verbinden
+			if( 1 )
+			{
+				bool verbunden = chatKlient->istVerbunden();
+				chatKlient = chatKlient->release();
+				chatKlient = new ChatKlient();
+				if( verbunden )
+					chatKlient->verbinde();
+				aktion = 0;
+			}
+			break;
+		case 2: // Login Oberfläche erschenen lassen (Programmstart)
+			if( !inAnimation )
+			{
+				deckAlpha = 250;
+				bildschirm->setdeckFarbe( deckAlpha << 24 );
+				bildschirm->setOnTop( 1 );
+				vorLogin->setSichtbar( 1 );
+				inAnimation = 1;
+				aktion = 0;
+			}
+			break;
+		case 3: // Ausloggen
+			new AktionsThread( 4, 0, 0, 0, 0, 0 );
+			aktion = 0;
+			break;
+		case 4: // Client wurde gekickt, zur login Oberfläche wechseln
+			new AktionsThread( 5, 0, 0, 0, 0, 0 );
+			aktion = 0;
+			break;
+		case 5: // Spiel Laden
+			new AktionsThread( 19, 0, 0, 0, 0, 0 );
+			aktion = 0;
+			break;
+		case 6: // Nach dem Spiel die Statistik laden
+			new AktionsThread( 20, 0, 0, 0, 0, 0 );
+			aktion = 0;
+			break;
+		case 7: // Spiel Aufzeichnung betreten
+			new AktionsThread( 21, 0, 0, 0, 0, 0 );
+			aktion = 0;
+			break;
+		case 8: // Spiel Aufzeichnung / Editor verlassen
+			new AktionsThread( 22, 0, 0, 0, 0, 0 );
+			aktion = 0;
+			break;
+        case 9: // Editor betreten
+            new AktionsThread( 23, 0, 0, 0, 0, 0 );
+            aktion = 0;
+            break;
+		}
+		if( inAnimation )
+		{
+			deckAlpha -= 25;
+			bildschirm->setdeckFarbe( deckAlpha << 24 );
+			if( deckAlpha == 0 )
+			{
+				bildschirm->setOnTop( 0 );
+				inAnimation = 0;
+			}
+		}
+	}
+	time->messungEnde();
+}
+
+void Render::beginn() // beginnt rendering
+{
+	exit = 0;
+	start();
+}
+
+void Render::beenden() // exit = 1;
+{
+	exit = 1;
+	WaitForSingleObject( threadHandle, 5000 );
+}
+
+// constant
+Bildschirm *Render::getBildschirm() // gibt den Bildschirm zurück
+{
+	return bildschirm ? bildschirm->getThis() : 0;
+}
+
+Bildschirm *Render::zBildschirm()
+{
+	return bildschirm;
+}
+
+// Reference Counting
+Render *Render::getThis()
+{
+	ref++;
+	return this;
+}
+
+Render *Render::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 42 - 0
KSGClient/Global/Render.h

@@ -0,0 +1,42 @@
+#ifndef Render_H
+#define Render_H
+
+#include <Bildschirm.h>
+#include <Thread.h>
+#include <Zeit.h>
+#include <Schrift.h>
+#include "Fps.h"
+
+using namespace Framework;
+
+class Render : public Thread
+{
+private:
+	bool exit;
+	Bildschirm *bildschirm;
+	ZeitMesser *time;
+	double tickval;
+	Fps *fps;
+	unsigned char deckAlpha;
+	bool inAnimation;
+	int ref;
+
+public:
+	// Konstruktor 
+	Render( Schrift *schrift );
+	// Destruktor 
+	~Render();
+	// nicht constant 
+	void setBildschirm( Bildschirm *bildschirm ); // setzt den Bildschirm
+	virtual void thread(); // Render Schleife
+	void beginn(); // beginnt rendering
+	void beenden(); // exit = 1;
+	// constant
+	Bildschirm *getBildschirm(); // gibt den Bildschirm zurück
+	Bildschirm *zBildschirm();
+	// Reference Counting
+	Render *getThis();
+	Render *release();
+};
+
+#endif

+ 93 - 0
KSGClient/Global/Variablen.cpp

@@ -0,0 +1,93 @@
+#define variable
+#include "Variablen.h"
+#include <Punkt.h>
+#include <DateiSystem.h>
+
+void initVariables( Schrift *zSchrift, Bildschirm *zBildschirm )
+{
+	loginKlient = new LoginKlient();
+	registerKlient = new RegisterKlient();
+	infoKlient = new InformationKlient();
+	chatKlient = new ChatKlient();
+	anmeldungKlient = new AnmeldungKlient();
+	spielKlient = new SpielKlient();
+	shopKlient = new ShopKlient();
+	historieKlient = new HistorieKlient();
+	newsKlient = new NewsKlient();
+	editorKlient = new EditorKlient();
+    kartenKlient = new KartenKlient();
+	vorLogin = new VorLogin( zSchrift, zBildschirm );
+	nachLogin = new NachLogin( zSchrift, zBildschirm );
+	Animation2DData *lad = new Animation2DData();
+	LTDBDatei *ladd = new LTDBDatei();
+	ladd->setDatei( new Text( "data/bilder/ladeanimation.ltdb" ) );
+	lad->ladeAnimation( ladd );
+	lad->setFPS( 30 );
+	lad->setWiederhohlend( 1 );
+	ladeAnimation = new Animation2D();
+	ladeAnimation->setPosition( BildschirmGröße() / 2 - Punkt( 25, 25 ) );
+	ladeAnimation->setSize( 50, 50 );
+	ladeAnimation->setAPS( 450 );
+	ladeAnimation->setAnimationDataZ( lad );
+	ladeAnimation->setRahmen( 1 );
+	ladeAnimation->setRahmenBreite( 1 );
+	ladeAnimation->setRahmenFarbe( 0xFFFFFFFF );
+	zBildschirm->setOnTopZeichnung( ladeAnimation );
+	aktion = 2;
+	hauptScreen = zBildschirm->getThis();
+	bilder = new Bilder();
+	updateH = new UpdateHandler();
+	dllDateien = new DLLDateien();
+	keepAliveTh = new KeepAliveTh();
+	_render = 1;
+}
+
+void releaseVariables()
+{
+	_render = 0;
+	keepAliveTh->doExit();
+	keepAliveTh->warteAufThread( 1000 );
+	if( keepAliveTh->isRunning() )
+		keepAliveTh->ende();
+	delete keepAliveTh;
+	keepAliveTh = 0;
+	if( vorLogin )
+		vorLogin = vorLogin->release();
+	if( nachLogin )
+		nachLogin = nachLogin->release();
+	if( loginKlient )
+		loginKlient = loginKlient->release();
+	if( registerKlient )
+		registerKlient = registerKlient->release();
+	if( infoKlient )
+		infoKlient = (InformationKlient*)infoKlient->release();
+	if( chatKlient )
+		chatKlient = chatKlient->release();
+	if( anmeldungKlient )
+		anmeldungKlient = anmeldungKlient->release();
+	if( spielKlient )
+		spielKlient = (SpielKlient*)spielKlient->release();
+	if( shopKlient )
+		shopKlient = shopKlient->release();
+	if( historieKlient )
+		historieKlient = historieKlient->release();
+	if( newsKlient )
+		newsKlient = newsKlient->release();
+	if( editorKlient )
+		editorKlient = (EditorKlient*)editorKlient->release();
+    if( kartenKlient )
+        kartenKlient = kartenKlient->release();
+	if( ladeAnimation )
+		ladeAnimation = ladeAnimation->release();
+	if( hauptScreen )
+		hauptScreen = hauptScreen->release();
+	if( bilder )
+	{
+		bilder->release();
+		bilder = 0;
+	}
+	if( updateH )
+		updateH->release();
+	if( dllDateien )
+		dllDateien = dllDateien->release();
+}

+ 43 - 0
KSGClient/Global/Variablen.h

@@ -0,0 +1,43 @@
+#ifndef Variablen_H
+#define Variablen_H
+
+#ifndef variable
+#define variable extern
+#endif
+
+#include "..\Netzwerk\KSGKlient.h"
+#include "../Netzwerk/KeepAlive.h"
+#include "..\VorLogin\Login\Login.h"
+#include "..\VorLogin\VorLogin.h"
+#include "..\NachLogin\NachLogin.h"
+#include "..\NachLogin\UpdateGUI\UpdateGUI.h"
+#include "Bilder.h"
+#include "DLLDateien.h"
+#include <Animation.h>
+
+variable LoginKlient *loginKlient;
+variable RegisterKlient *registerKlient;
+variable InformationKlient *infoKlient;
+variable ChatKlient *chatKlient;
+variable AnmeldungKlient *anmeldungKlient;
+variable SpielKlient *spielKlient;
+variable ShopKlient *shopKlient;
+variable HistorieKlient *historieKlient;
+variable NewsKlient *newsKlient;
+variable EditorKlient *editorKlient;
+variable KartenKlient *kartenKlient;
+variable VorLogin *vorLogin;
+variable NachLogin *nachLogin;
+variable int aktion;
+variable Framework::Animation2D *ladeAnimation;
+variable Bildschirm *hauptScreen;
+variable Bilder *bilder;
+variable UpdateHandler *updateH;
+variable DLLDateien *dllDateien;
+variable bool _render;
+variable KeepAliveTh *keepAliveTh;
+
+void initVariables( Schrift *zSchrift, Bildschirm *zBildschirm );
+void releaseVariables();
+
+#endif

+ 338 - 0
KSGClient/KSGClient.vcxproj

@@ -0,0 +1,338 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{BF0DC22E-98E5-4B97-9F31-BFDD9FBC08E4}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>MyKSGClient</RootNamespace>
+    <ProjectName>KSGClient</ProjectName>
+    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v141</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v141</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v141</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v141</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <IncludePath>..\..\..\..\Allgemein\Framework;..\..\..\..\Allgemein\Network\Network;..\..\Include;..\..\..\..\Allgemein\GSL\GSL\Include;..\..\..\..\Allgemein\ksgScript\ksgScript\Include;$(IncludePath)</IncludePath>
+    <LibraryPath>..\..\..\..\Allgemein\Framework\x64\Debug;..\..\..\..\Allgemein\Network\x64\Debug;$(LibraryPath)</LibraryPath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <LibraryPath>..\..\..\..\Allgemein\Framework\Release;..\..\..\..\Allgemein\Network\Release;$(LibraryPath)</LibraryPath>
+    <IncludePath>..\..\..\..\Allgemein\Framework;..\..\..\..\Allgemein\Network\Network;..\..\Include;..\..\..\..\Allgemein\GSL\GSL\Include;..\..\..\..\Allgemein\ksgScript\ksgScript\Include;$(IncludePath)</IncludePath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+    <LibraryPath>..\..\..\..\Allgemein\Framework\x64\Release;..\..\..\..\Allgemein\Network\x64\Release;$(LibraryPath)</LibraryPath>
+    <IncludePath>..\..\..\..\Allgemein\Framework;..\..\..\..\Allgemein\Network\Network;..\..\Include;..\..\..\..\Allgemein\GSL\GSL\Include;..\..\..\..\Allgemein\ksgScript\ksgScript\Include;$(IncludePath)</IncludePath>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>Framework.lib;network.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+    <CustomBuildStep>
+      <Command>copy "..\..\..\..\Allgemein\Framework\x64\Debug\Framework.dll" "framework.dll"
+copy "..\..\..\..\Allgemein\Network\x64\Debug\Network.dll" "network.dll"
+copy "..\..\..\..\Allgemein\GSL\x64\Debug\GSL.dll" "data\bin\GSL.dll"
+copy "..\..\..\..\Allgemein\KSGScript\x64\Debug\KSGScript.dll" "data\bin\KSGScript.dll"
+copy "..\..\Update\x64\Debug\Update.dll" "data\bin\Update.dll"
+copy "..\..\Minigames\Asteroids\x64\Debug\Asteroids.dll" "data\Minigames\Asteroids\bin\game.dll"
+copy "..\..\Minigames\Blöcke\x64\Debug\Bloecke.dll" "data\Minigames\Blöcke\bin\game.dll"
+copy "..\..\Minigames\Fangen\x64\Debug\Fangen.dll" "data\Minigames\Fangen\bin\game.dll"
+copy "..\..\Minigames\Snake\x64\Debug\Snake.dll" "data\Minigames\Snake\bin\game.dll"
+copy "..\..\Minigames\Tetris\x64\Debug\Tetris.dll" "data\Minigames\Tetris\bin\game.dll"
+copy "..\..\..\Spiele\Klient\Asteroids\x64\Debug\Asteroids.dll" "data\spiele\Asteroids\bin\Asteroids.dll"
+copy "..\..\..\Spiele\Klient\Linie\x64\Debug\Linie.dll" "data\spiele\Linie\bin\Linie.dll"
+copy "..\x64\Debug\KSGClient.exe" "..\..\Fertig\Debug\x64\data\client\bin\game client.exe"</Command>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Outputs>kopieren...;%(Outputs)</Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>Framework.lib;network.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+    <CustomBuildStep>
+      <Command>copy "..\Release\KSGClient.exe" "..\..\Fertig\x32\data\client\bin\game client.exe"</Command>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Outputs>kopieren...;%(Outputs)</Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>Framework.lib;network.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+    <CustomBuildStep>
+      <Command>copy "..\x64\Release\KSGClient.exe" "..\..\Fertig\x64\data\client\bin\game client.exe"</Command>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Outputs>kopieren...;%(Outputs)</Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="Aktionen\AktionsThread.cpp" />
+    <ClCompile Include="Global\Bilder.cpp" />
+    <ClCompile Include="Global\DLLDateien.cpp" />
+    <ClCompile Include="Global\Fps.cpp" />
+    <ClCompile Include="Global\Initialisierung.cpp" />
+    <ClCompile Include="Global\Render.cpp" />
+    <ClCompile Include="Global\Variablen.cpp" />
+    <ClCompile Include="Leser\KartenLeser.cpp" />
+    <ClCompile Include="NachLogin\Account\AccountAnsehen.cpp" />
+    <ClCompile Include="NachLogin\Account\Aktivität\AccountAktivität.cpp" />
+    <ClCompile Include="NachLogin\Account\Historie\AccountHistorie.cpp" />
+    <ClCompile Include="NachLogin\Account\Historie\AccountHistorieDaten.cpp" />
+    <ClCompile Include="NachLogin\Account\Spiele_Karten\AccountSpieleUndKarten.cpp" />
+    <ClCompile Include="NachLogin\Account\SpielPartner\AccountSpielPartner.cpp" />
+    <ClCompile Include="NachLogin\Account\Statistik\AccountStatistik.cpp" />
+    <ClCompile Include="NachLogin\Account\Suchen\AccountSuchen.cpp" />
+    <ClCompile Include="NachLogin\Chat\ChatLeiste.cpp" />
+    <ClCompile Include="NachLogin\Chat\FreundesListe.cpp" />
+    <ClCompile Include="NachLogin\Chat\NachrichtenListe.cpp" />
+    <ClCompile Include="NachLogin\Editor\Auswahl\Auswahl.cpp" />
+    <ClCompile Include="NachLogin\Editor\Editor.cpp" />
+    <ClCompile Include="NachLogin\Editor\Karte\Beschreibung\KEBEditor.cpp" />
+    <ClCompile Include="NachLogin\Editor\Karte\Beschreibung\KEBeschreibung.cpp" />
+    <ClCompile Include="NachLogin\Editor\Karte\Beschreibung\KEBVorschau.cpp" />
+    <ClCompile Include="NachLogin\Editor\Karte\Dateien\KEDateien.cpp" />
+    <ClCompile Include="NachLogin\Editor\Karte\Dateien\KEDEditor.cpp" />
+    <ClCompile Include="NachLogin\Editor\Karte\Dateien\KEDModel2DEditor.cpp" />
+    <ClCompile Include="NachLogin\Editor\Karte\Dateien\WAVDatei.cpp" />
+    <ClCompile Include="NachLogin\Editor\Karte\KartenEditor.cpp" />
+    <ClCompile Include="NachLogin\Editor\Karte\Release\KERelease.cpp" />
+    <ClCompile Include="NachLogin\Editor\Karte\ShopSeite\KEShopSeite.cpp" />
+    <ClCompile Include="NachLogin\Editor\Karte\ShopSeite\KESSEditor.cpp" />
+    <ClCompile Include="NachLogin\Editor\Karte\ShopSeite\KESSVorschau.cpp" />
+    <ClCompile Include="NachLogin\Editor\Karte\Teams\KETeams.cpp" />
+    <ClCompile Include="NachLogin\Einstellungen\Einstellungen.cpp" />
+    <ClCompile Include="NachLogin\ImSpiel\ImSpiel.cpp" />
+    <ClCompile Include="NachLogin\ImSpiel\Laden\SpielLaden.cpp" />
+    <ClCompile Include="NachLogin\MiniGames\MiniGame.cpp" />
+    <ClCompile Include="NachLogin\MiniGames\Minigames.cpp" />
+    <ClCompile Include="NachLogin\NachLogin.cpp" />
+    <ClCompile Include="NachLogin\Neuigkeiten\Neuigkeiten.cpp" />
+    <ClCompile Include="NachLogin\Shop\Karten\KartenKaufen.cpp" />
+    <ClCompile Include="NachLogin\Shop\Shop.cpp" />
+    <ClCompile Include="NachLogin\Shop\Spiele\SpieleKaufen.cpp" />
+    <ClCompile Include="NachLogin\Spiele\Angemeldet\Angemeldet.cpp" />
+    <ClCompile Include="NachLogin\Spiele\Gruppe\Gruppe.cpp" />
+    <ClCompile Include="NachLogin\Spiele\Karte Auswahl\KarteAuswahl.cpp" />
+    <ClCompile Include="NachLogin\Spiele\Spiel Auswahl\SpielAuswahl.cpp" />
+    <ClCompile Include="NachLogin\Spiele\Spiele.cpp" />
+    <ClCompile Include="NachLogin\Spiele\Statistik\SpielStatistik.cpp" />
+    <ClCompile Include="NachLogin\Spiele\Team Auswahl\TeamAuswahl.cpp" />
+    <ClCompile Include="NachLogin\Titel\TitelLeiste.cpp" />
+    <ClCompile Include="NachLogin\UpdateGUI\UpdateGUI.cpp" />
+    <ClCompile Include="Netzwerk\KeepAlive.cpp" />
+    <ClCompile Include="Netzwerk\Keys.cpp" />
+    <ClCompile Include="Netzwerk\Klients\AnmeldungK.cpp" />
+    <ClCompile Include="Netzwerk\Klients\ChatK.cpp" />
+    <ClCompile Include="Netzwerk\Klients\EditorK.cpp" />
+    <ClCompile Include="Netzwerk\Klients\HistorieK.cpp" />
+    <ClCompile Include="Netzwerk\Klients\InformationK.cpp" />
+    <ClCompile Include="Netzwerk\Klients\KartenK.cpp" />
+    <ClCompile Include="Netzwerk\Klients\LoginK.cpp" />
+    <ClCompile Include="Netzwerk\Klients\NewsK.cpp" />
+    <ClCompile Include="Netzwerk\Klients\RegisterK.cpp" />
+    <ClCompile Include="Netzwerk\Klients\ShopK.cpp" />
+    <ClCompile Include="Netzwerk\Klients\SpielK.cpp" />
+    <ClCompile Include="Netzwerk\KSGServer.cpp" />
+    <ClCompile Include="Netzwerk\Patcher.cpp" />
+    <ClCompile Include="Start\Start.cpp" />
+    <ClCompile Include="Strukturen\Strukturen.cpp" />
+    <ClCompile Include="VorLogin\Account verwalten\Bestätigung.cpp" />
+    <ClCompile Include="VorLogin\Account verwalten\EMail.cpp" />
+    <ClCompile Include="VorLogin\Account verwalten\Geheimnis.cpp" />
+    <ClCompile Include="VorLogin\Account verwalten\Name.cpp" />
+    <ClCompile Include="VorLogin\Account verwalten\Passwort.cpp" />
+    <ClCompile Include="VorLogin\Account verwalten\Registrierung.cpp" />
+    <ClCompile Include="VorLogin\Account verwalten\Unregistrierung.cpp" />
+    <ClCompile Include="VorLogin\Login\Login.cpp" />
+    <ClCompile Include="VorLogin\VorLogin.cpp" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="Aktionen\AktionsThread.h" />
+    <ClInclude Include="Global\Bilder.h" />
+    <ClInclude Include="Global\DLLDateien.h" />
+    <ClInclude Include="Global\Fps.h" />
+    <ClInclude Include="Global\Initialisierung.h" />
+    <ClInclude Include="Global\Render.h" />
+    <ClInclude Include="Global\Variablen.h" />
+    <ClInclude Include="Leser\KartenLeser.h" />
+    <ClInclude Include="NachLogin\Account\AccountAnsehen.h" />
+    <ClInclude Include="NachLogin\Account\Aktivität\AccountAktivität.h" />
+    <ClInclude Include="NachLogin\Account\Historie\AccountHistorie.h" />
+    <ClInclude Include="NachLogin\Account\Historie\AccountHistorieDaten.h" />
+    <ClInclude Include="NachLogin\Account\Spiele_Karten\AccountSpieleUndKarten.h" />
+    <ClInclude Include="NachLogin\Account\SpielPartner\AccountSpielPartner.h" />
+    <ClInclude Include="NachLogin\Account\Statistik\AccountStatistik.h" />
+    <ClInclude Include="NachLogin\Account\Suchen\AccountSuchen.h" />
+    <ClInclude Include="NachLogin\Chat\ChatLeiste.h" />
+    <ClInclude Include="NachLogin\Chat\FreundesListe.h" />
+    <ClInclude Include="NachLogin\Chat\NachrichtenListe.h" />
+    <ClInclude Include="NachLogin\Editor\Auswahl\Auswahl.h" />
+    <ClInclude Include="NachLogin\Editor\Editor.h" />
+    <ClInclude Include="NachLogin\Editor\Karte\Beschreibung\KEBEditor.h" />
+    <ClInclude Include="NachLogin\Editor\Karte\Beschreibung\KEBeschreibung.h" />
+    <ClInclude Include="NachLogin\Editor\Karte\Beschreibung\KEBVorschau.h" />
+    <ClInclude Include="NachLogin\Editor\Karte\Dateien\KEDateien.h" />
+    <ClInclude Include="NachLogin\Editor\Karte\Dateien\KEDEditor.h" />
+    <ClInclude Include="NachLogin\Editor\Karte\Dateien\KEDModel2DEditor.h" />
+    <ClInclude Include="NachLogin\Editor\Karte\Dateien\WAVDatei.h" />
+    <ClInclude Include="NachLogin\Editor\Karte\KartenEditor.h" />
+    <ClInclude Include="NachLogin\Editor\Karte\Release\KERelease.h" />
+    <ClInclude Include="NachLogin\Editor\Karte\ShopSeite\KEShopSeite.h" />
+    <ClInclude Include="NachLogin\Editor\Karte\ShopSeite\KESSEditor.h" />
+    <ClInclude Include="NachLogin\Editor\Karte\ShopSeite\KESSVorschau.h" />
+    <ClInclude Include="NachLogin\Editor\Karte\Teams\KETeams.h" />
+    <ClInclude Include="NachLogin\Einstellungen\Einstellungen.h" />
+    <ClInclude Include="NachLogin\ImSpiel\ImSpiel.h" />
+    <ClInclude Include="NachLogin\ImSpiel\Laden\SpielLaden.h" />
+    <ClInclude Include="NachLogin\MiniGames\MiniGame.h" />
+    <ClInclude Include="NachLogin\MiniGames\Minigames.h" />
+    <ClInclude Include="NachLogin\NachLogin.h" />
+    <ClInclude Include="NachLogin\Neuigkeiten\Neuigkeiten.h" />
+    <ClInclude Include="NachLogin\Shop\Karten\KartenKaufen.h" />
+    <ClInclude Include="NachLogin\Shop\Shop.h" />
+    <ClInclude Include="NachLogin\Shop\Spiele\SpieleKaufen.h" />
+    <ClInclude Include="NachLogin\Spiele\Angemeldet\Angemeldet.h" />
+    <ClInclude Include="NachLogin\Spiele\Gruppe\Gruppe.h" />
+    <ClInclude Include="NachLogin\Spiele\Karte Auswahl\KarteAuswahl.h" />
+    <ClInclude Include="NachLogin\Spiele\Spiel Auswahl\SpielAuswahl.h" />
+    <ClInclude Include="NachLogin\Spiele\Spiele.h" />
+    <ClInclude Include="NachLogin\Spiele\Statistik\SpielStatistik.h" />
+    <ClInclude Include="NachLogin\Spiele\Team Auswahl\TeamAuswahl.h" />
+    <ClInclude Include="NachLogin\Titel\TitelLeiste.h" />
+    <ClInclude Include="NachLogin\UpdateGUI\UpdateGUI.h" />
+    <ClInclude Include="Netzwerk\KeepAlive.h" />
+    <ClInclude Include="Netzwerk\Keys.h" />
+    <ClInclude Include="Netzwerk\KSGKlient.h" />
+    <ClInclude Include="Netzwerk\KSGServer.h" />
+    <ClInclude Include="Netzwerk\Patcher.h" />
+    <ClInclude Include="Strukturen\Strukturen.h" />
+    <ClInclude Include="VorLogin\Account verwalten\Bestätigung.h" />
+    <ClInclude Include="VorLogin\Account verwalten\EMail.h" />
+    <ClInclude Include="VorLogin\Account verwalten\Geheimnis.h" />
+    <ClInclude Include="VorLogin\Account verwalten\Name.h" />
+    <ClInclude Include="VorLogin\Account verwalten\Passwort.h" />
+    <ClInclude Include="VorLogin\Account verwalten\Registrierung.h" />
+    <ClInclude Include="VorLogin\Account verwalten\Unregistrierung.h" />
+    <ClInclude Include="VorLogin\Login\Login.h" />
+    <ClInclude Include="VorLogin\VorLogin.h" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>

+ 462 - 0
KSGClient/KSGClient.vcxproj.filters

@@ -0,0 +1,462 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Quelldateien">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Headerdateien">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="Ressourcendateien">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="Start\Start.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Global\Variablen.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Netzwerk\Klients\AnmeldungK.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Netzwerk\Klients\ChatK.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Netzwerk\Klients\EditorK.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Netzwerk\Klients\HistorieK.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Netzwerk\Klients\InformationK.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Netzwerk\Klients\KartenK.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Netzwerk\Klients\LoginK.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Netzwerk\Klients\NewsK.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Netzwerk\Klients\RegisterK.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Netzwerk\Klients\ShopK.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Netzwerk\Klients\SpielK.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Netzwerk\KeepAlive.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Netzwerk\KSGServer.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Netzwerk\Patcher.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Global\Bilder.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Global\DLLDateien.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Strukturen\Strukturen.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="VorLogin\Account verwalten\Bestätigung.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="VorLogin\Account verwalten\EMail.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="VorLogin\Account verwalten\Geheimnis.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="VorLogin\Account verwalten\Name.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="VorLogin\Account verwalten\Passwort.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="VorLogin\Account verwalten\Registrierung.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="VorLogin\Account verwalten\Unregistrierung.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="VorLogin\Login\Login.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="VorLogin\VorLogin.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Aktionen\AktionsThread.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Global\Initialisierung.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Global\Render.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Global\Fps.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Account\Aktivität\AccountAktivität.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Account\Historie\AccountHistorie.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Account\Historie\AccountHistorieDaten.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Account\Spiele_Karten\AccountSpieleUndKarten.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Account\SpielPartner\AccountSpielPartner.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Account\Statistik\AccountStatistik.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Account\Suchen\AccountSuchen.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Account\AccountAnsehen.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Chat\ChatLeiste.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Chat\FreundesListe.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Chat\NachrichtenListe.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Editor\Auswahl\Auswahl.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Editor\Karte\Beschreibung\KEBEditor.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Editor\Karte\Beschreibung\KEBeschreibung.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Editor\Karte\Beschreibung\KEBVorschau.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Editor\Karte\Dateien\KEDateien.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Editor\Karte\Dateien\KEDEditor.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Editor\Karte\Dateien\KEDModel2DEditor.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Editor\Karte\Dateien\WAVDatei.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Editor\Karte\Release\KERelease.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Editor\Karte\ShopSeite\KEShopSeite.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Editor\Karte\ShopSeite\KESSEditor.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Editor\Karte\ShopSeite\KESSVorschau.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Editor\Karte\Teams\KETeams.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Editor\Karte\KartenEditor.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Editor\Editor.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Einstellungen\Einstellungen.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\ImSpiel\Laden\SpielLaden.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\ImSpiel\ImSpiel.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\MiniGames\MiniGame.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\MiniGames\Minigames.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Neuigkeiten\Neuigkeiten.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Shop\Karten\KartenKaufen.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Shop\Spiele\SpieleKaufen.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Shop\Shop.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Spiele\Angemeldet\Angemeldet.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Spiele\Gruppe\Gruppe.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Spiele\Karte Auswahl\KarteAuswahl.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Spiele\Spiel Auswahl\SpielAuswahl.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Spiele\Statistik\SpielStatistik.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Spiele\Team Auswahl\TeamAuswahl.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Spiele\Spiele.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\Titel\TitelLeiste.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\UpdateGUI\UpdateGUI.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="NachLogin\NachLogin.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Leser\KartenLeser.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Netzwerk\Keys.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="Global\Variablen.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="Netzwerk\KeepAlive.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="Netzwerk\KSGKlient.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="Netzwerk\KSGServer.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="Netzwerk\Patcher.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="Global\Bilder.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="Global\DLLDateien.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="Strukturen\Strukturen.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="VorLogin\Account verwalten\Bestätigung.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="VorLogin\Account verwalten\EMail.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="VorLogin\Account verwalten\Geheimnis.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="VorLogin\Account verwalten\Name.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="VorLogin\Account verwalten\Passwort.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="VorLogin\Account verwalten\Registrierung.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="VorLogin\Account verwalten\Unregistrierung.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="VorLogin\Login\Login.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="VorLogin\VorLogin.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="Aktionen\AktionsThread.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="Global\Initialisierung.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="Global\Render.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="Global\Fps.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Account\Aktivität\AccountAktivität.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Account\Historie\AccountHistorie.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Account\Historie\AccountHistorieDaten.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Account\Spiele_Karten\AccountSpieleUndKarten.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Account\SpielPartner\AccountSpielPartner.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Account\Statistik\AccountStatistik.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Account\Suchen\AccountSuchen.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Account\AccountAnsehen.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Chat\ChatLeiste.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Chat\FreundesListe.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Chat\NachrichtenListe.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Editor\Auswahl\Auswahl.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Editor\Karte\Beschreibung\KEBEditor.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Editor\Karte\Beschreibung\KEBeschreibung.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Editor\Karte\Beschreibung\KEBVorschau.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Editor\Karte\Dateien\KEDateien.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Editor\Karte\Dateien\KEDEditor.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Editor\Karte\Dateien\KEDModel2DEditor.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Editor\Karte\Dateien\WAVDatei.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Editor\Karte\Release\KERelease.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Editor\Karte\ShopSeite\KEShopSeite.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Editor\Karte\ShopSeite\KESSEditor.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Editor\Karte\ShopSeite\KESSVorschau.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Editor\Karte\Teams\KETeams.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Editor\Karte\KartenEditor.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Editor\Editor.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Einstellungen\Einstellungen.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\ImSpiel\Laden\SpielLaden.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\ImSpiel\ImSpiel.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\MiniGames\MiniGame.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\MiniGames\Minigames.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Neuigkeiten\Neuigkeiten.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Shop\Karten\KartenKaufen.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Shop\Spiele\SpieleKaufen.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Shop\Shop.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Spiele\Angemeldet\Angemeldet.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Spiele\Gruppe\Gruppe.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Spiele\Karte Auswahl\KarteAuswahl.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Spiele\Spiel Auswahl\SpielAuswahl.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Spiele\Statistik\SpielStatistik.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Spiele\Team Auswahl\TeamAuswahl.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Spiele\Spiele.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\Titel\TitelLeiste.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\UpdateGUI\UpdateGUI.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="NachLogin\NachLogin.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="Leser\KartenLeser.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="Netzwerk\Keys.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>

+ 247 - 0
KSGClient/Leser/KartenLeser.cpp

@@ -0,0 +1,247 @@
+#include "KartenLeser.h"
+#include "..\Global\Variablen.h"
+#include <Datei.h>
+#include <DateiSystem.h>
+#include <KSGTDatei.h>
+#include <Bild.h>
+#include <Punkt.h>
+
+// Inhalt der KartenLeser Klasse aus KartenLeser.h
+// Konstruktor
+KartenLeser::KartenLeser()
+{
+    letzterFehler = new Text( "" );
+    karteId = 0;
+    ref = 1;
+}
+
+// Destruktor
+KartenLeser::~KartenLeser()
+{
+    letzterFehler->release();
+}
+
+// nicht constant
+void KartenLeser::setKarteId( int karteId )
+{
+    this->karteId = karteId;
+}
+
+// constant
+Bild *KartenLeser::getKartenTitelBild( Schrift *zSchrift ) const
+{
+    bool ok = 1;
+    int port = 0;
+    Text ip;
+    infoKlient->getKartenServer( karteId, &port, &ip );
+    if( !kartenKlient->verbinde( port, ip ) )
+    {
+        letzterFehler->setText( kartenKlient->getLetzterFehler() );
+        ok = 0;
+    }
+    if( !kartenKlient->downloadKarteTitel( karteId ) )
+    {
+        letzterFehler->setText( kartenKlient->getLetzterFehler() );
+        ok = 0;
+    }
+    Bild *ret = 0;
+    if( ok )
+    {
+        Text *pfad = getKartePfad();
+        pfad->append( "titel.ltdb" );
+        LTDBDatei *datei = new LTDBDatei();
+        datei->setDatei( pfad );
+        datei->leseDaten( 0 );
+        ret = datei->laden( 0, datei->zBildListe()->get( 0 ) );
+        datei->release();
+    }
+    if( !ret )
+    {
+        ret = new Bild();
+        ret->neuBild( 200, 100, 0xFF000000 );
+        zSchrift->lock();
+        zSchrift->setSchriftSize( 12 );
+        zSchrift->setDrawPosition( 10, 10 );
+        Text *kn = getKarteName();
+        zSchrift->renderText( kn, *ret, 0xFFFFFFFF );
+        kn->release();
+        zSchrift->unlock();
+    }
+    return ret;
+}
+
+Bild *KartenLeser::getKartenVorschauBild() const
+{
+    int port = 0;
+    Text ip;
+    infoKlient->getKartenServer( karteId, &port, &ip );
+    if( !kartenKlient->verbinde( port, ip ) )
+    {
+        letzterFehler->setText( kartenKlient->getLetzterFehler() );
+        return 0;
+    }
+    if( !kartenKlient->downloadKarteMinimap( karteId ) )
+    {
+        letzterFehler->setText( kartenKlient->getLetzterFehler() );
+        return 0;
+    }
+    Text *pfad = getKartePfad();
+    pfad->append( "minimap.ltdb" );
+    Bild *ret = 0;
+    LTDBDatei *datei = new LTDBDatei();
+    datei->setDatei( pfad );
+    datei->leseDaten( 0 );
+    ret = datei->laden( 0, datei->zBildListe()->get( 0 ) );
+    datei->release();
+    if( !ret )
+        letzterFehler->append( "Bild nicht gefunden." );
+    return ret;
+}
+
+Bild *KartenLeser::getLadeBild() const
+{
+    int port = 0;
+    Text ip;
+    infoKlient->getKartenServer( karteId, &port, &ip );
+    if( !kartenKlient->verbinde( port, ip ) )
+    {
+        letzterFehler->setText( kartenKlient->getLetzterFehler() );
+        return 0;
+    }
+    if( !kartenKlient->downloadKarteLadebild( karteId ) )
+    {
+        letzterFehler->setText( kartenKlient->getLetzterFehler() );
+        return 0;
+    }
+    Text *pfad = getKartePfad();
+    pfad->append( "ladebild.ltdb" );
+    Bild *ret = 0;
+    LTDBDatei *datei = new LTDBDatei();
+    datei->setDatei( pfad );
+    datei->leseDaten( 0 );
+    ret = datei->laden( 0, datei->zBildListe()->get( 0 ) );
+    datei->release();
+    if( !ret )
+        letzterFehler->append( "Bild nicht gefunden." );
+    return ret;
+}
+
+bool KartenLeser::getKartenBeschreibung() const
+{
+    int port = 0;
+    Text ip;
+    infoKlient->getKartenServer( karteId, &port, &ip );
+    if( !kartenKlient->verbinde( port, ip ) )
+    {
+        letzterFehler->setText( kartenKlient->getLetzterFehler() );
+        return 0;
+    }
+    if( !kartenKlient->downloadKarteBeschreibung( karteId ) )
+    {
+        letzterFehler->setText( kartenKlient->getLetzterFehler() );
+        return 0;
+    }
+    return 1;
+}
+
+int KartenLeser::getSpielId() const
+{
+    if( !karteId )
+    {
+        letzterFehler->setText( "Karte Id ist nicht gesetzt." );
+        return 0;
+    }
+    if( infoKlient )
+    {
+        int id = infoKlient->getSpielId( karteId );
+        if( !id )
+            letzterFehler->setText( infoKlient->getLetzterFehler() );
+        return id;
+    }
+    else
+        letzterFehler->setText( "Informations Klient ist nicht Initialisiert." );
+    return 0;
+}
+
+int KartenLeser::getKarteId() const
+{
+    return karteId;
+}
+
+Text *KartenLeser::getSpielName() const
+{
+    if( infoKlient )
+    {
+        int id = getSpielId();
+        if( !id )
+            return 0;
+        Text *name = infoKlient->getSpielName( id );
+        if( !name )
+            letzterFehler->setText( infoKlient->getLetzterFehler() );
+        return name;
+    }
+    else
+        letzterFehler->setText( "Informations Klient ist nicht Initialisiert." );
+    return 0;
+}
+
+Text *KartenLeser::getSpielPfad() const
+{
+    int sId = getSpielId();
+    int dg = infoKlient->getDateiGruppeIdVonSpiel( sId );
+    Text *pfad = infoKlient->getDateiGruppePfad( dg );
+    if( !pfad )
+    {
+        letzterFehler->setText( "Der Pfad des Spieles konnte nicht ermittelt werden." );
+        return 0;
+    }
+    pfad->append( "/" );
+    return pfad;
+}
+
+Text *KartenLeser::getKarteName() const
+{
+    if( !karteId )
+    {
+        letzterFehler->setText( "Karte Id ist nicht gesetzt." );
+        return 0;
+    }
+    if( infoKlient )
+    {
+        Text *name = infoKlient->getKarteName( karteId );
+        if( !name )
+            letzterFehler->setText( infoKlient->getLetzterFehler() );
+        return name;
+    }
+    else
+        letzterFehler->setText( "Informations Klient ist nicht Initialisiert." );
+    return 0;
+}
+
+Text *KartenLeser::getKartePfad() const
+{
+    Text *pf = new Text( "data/tmp/Karten/" );
+    pf->append( karteId );
+    pf->append( "/" );
+    return pf;
+}
+
+char *KartenLeser::getLetzterFehler() const
+{
+    return letzterFehler->getText();
+}
+
+// Reference Counting
+KartenLeser *KartenLeser::getThis()
+{
+    ref++;
+    return this;
+}
+
+KartenLeser *KartenLeser::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 41 - 0
KSGClient/Leser/KartenLeser.h

@@ -0,0 +1,41 @@
+#ifndef KartenLeser_H
+#define KartenLeser_H
+
+#include <Klient.h>
+#include <Bild.h>
+#include <Schrift.h>
+
+using namespace Framework;
+
+class KartenLeser
+{
+private:
+	Text *letzterFehler;
+	int karteId;
+	int ref;
+
+public:
+	// Konstruktor
+	KartenLeser();
+	// Destruktor
+	~KartenLeser();
+	// nicht constant
+	void setKarteId( int karteId );
+	// constant
+	Bild *getKartenTitelBild( Schrift *zSchrift ) const;
+	Bild *getKartenVorschauBild() const;
+	Bild *getLadeBild() const;
+	bool getKartenBeschreibung() const;
+	int getSpielId() const;
+	int getKarteId() const;
+	Text *getSpielName() const;
+	Text *getSpielPfad() const;
+	Text *getKarteName() const;
+	Text *getKartePfad() const;
+	char *getLetzterFehler() const;
+	// Reference Counting
+	KartenLeser *getThis();
+	KartenLeser *release();
+};
+
+#endif

+ 661 - 0
KSGClient/NachLogin/Account/AccountAnsehen.cpp

@@ -0,0 +1,661 @@
+#include "AccountAnsehen.h"
+#include "../../Global/Variablen.h"
+#include "../../Global/Initialisierung.h"
+#include <Punkt.h>
+#include <Rahmen.h>
+
+// inhalt der AccountAnsehen Klasse aus AccountAnsehen.h
+// Konstruktor
+AccountAnsehen::AccountAnsehen( Schrift *zSchrift, Fenster *zNachLoginFenster, int x )
+	: Zeichnung(),
+  laden( (Animation2D*)ladeAnimation->dublizieren() ),
+  bildschirmGröße( BildschirmGröße() ),
+  rahmen( new LRahmen() ),
+  aktivitätK( initKnopf( 145, 10, 120, 20, zSchrift, Knopf::Style::Sichtbar, "Spieler Aktivität" ) ),
+  historieK( initKnopf( 665, 10, 120, 20, zSchrift, Knopf::Style::Sichtbar, "Spiel Historie" ) ),
+  spieleUndKartenK( initKnopf( 275, 10, 120, 20, zSchrift, Knopf::Style::Sichtbar, "Spiele / Karten" ) ),
+  spielPartnerK( initKnopf( 405, 10, 120, 20, zSchrift, Knopf::Style::Sichtbar, "Spielpartner" ) ),
+  statistikK( initKnopf( 535, 10, 120, 20, zSchrift, Knopf::Style::Sichtbar, "Spiel Statistik" ) ),
+  suchenK( initKnopf( 15, 10, 120, 20, zSchrift, Knopf::Style::Sichtbar, "Spieler suchen" ) ),
+  suche( new AccountSuchen( zSchrift->getThis() ) ),
+  aktivität( new AccountAktivität( zSchrift ) ),
+  spieleUndKarten( new AccountSpieleUndKarten( zSchrift ) ),
+  partner( new AccountSpielPartner( zSchrift ) ),
+  statistik( new AccountStatistik( zSchrift ) ),
+  historie( new AccountHistorie( zSchrift ) ),
+  account( 0 ),
+  alpha( 0 ),
+  alpha2( 255 ),
+  sichtbar( 0 ),
+  jetzt( 0 ),
+  nachher( 0 ),
+  prozent1( 0 ),
+  prozent2( 0 ),
+  tickVal( 0 ),
+  animation( 0 ),
+  knopfX( 810 ),
+  rend( 0 ),
+  ref( 1 )
+{
+	laden->setSichtbar( 0 );
+	rahmen->setFarbe( 0xFFFFFFFF );
+	rahmen->setSize( 102, 32 );
+	begPos = Punkt( x, 67 );
+	begGröße = Punkt( 102, 32 );
+	pos = Punkt( x, 67 );
+	gr = Punkt( 102, 32 );
+	pos1 = begPos;
+	größe1 = begGröße;
+	größe2 = Punkt( 800, 500 );
+	pos2 = bildschirmGröße / 2 - größe2 / 2;
+	laden->setPosition( 375, 225 );
+	zNachLoginFenster->addMember( this );
+}
+
+// Destruktor
+AccountAnsehen::~AccountAnsehen()
+{
+	laden->release();
+	rahmen->release();
+	aktivitätK->release();
+	historieK->release();
+	spieleUndKartenK->release();
+	spielPartnerK->release();
+	statistikK->release();
+	suchenK->release();
+	suche->release();
+	aktivität->release();
+	spieleUndKarten->release();
+	partner->release();
+	statistik->release();
+	historie->release();
+}
+
+// nicht constant
+void AccountAnsehen::setSichtbar( bool sicht )
+{
+	begPos = pos;
+	begGröße = gr;
+	animation |= ( sicht ? 0x1 : 0x2 );
+	rend = 1;
+}
+
+bool AccountAnsehen::setSpielerDetails( int account, int nachher )
+{
+	if( laden->istSichtbar() )
+		return 0;
+	laden->setSichtbar( 1 );
+	if( nachher == 2 )
+		aktivität->ladeStatistik( account );
+	if( nachher == 3 )
+		spieleUndKarten->ladeStatistik( account );
+	if( nachher == 4 )
+		partner->ladeStatistik( account );
+	if( nachher == 5 )
+		statistik->ladeStatistik( account );
+	if( nachher == 6 )
+		historie->ladeStatistik( account );
+	this->nachher = nachher;
+	this->account = account;
+	return 1;
+}
+
+bool AccountAnsehen::tick( double tickVal )
+{
+	if( !knopfX )
+	{
+		rend |= aktivitätK->tick( tickVal );
+		rend |= historieK->tick( tickVal );
+		rend |= spieleUndKartenK->tick( tickVal );
+		rend |= spielPartnerK->tick( tickVal );
+		rend |= statistikK->tick( tickVal );
+		rend |= suchenK->tick( tickVal );
+	}
+	rend |= laden->tick( tickVal );
+	rend |= suche->tick( tickVal );
+	rend |= aktivität->tick( tickVal );
+	rend |= spieleUndKarten->tick( tickVal );
+	rend |= partner->tick( tickVal );
+	rend |= statistik->tick( tickVal );
+	rend |= historie->tick( tickVal );
+	this->tickVal += tickVal;
+	int val = (int)( this->tickVal * 150 );
+	int val2 = (int)( this->tickVal * 500 );
+	this->tickVal -= val / 150.0;
+	if( val )
+	{
+		if( ( animation | 0x1 ) == animation ) // Einblenden
+		{
+			if( prozent1 != 100 )
+			{
+				prozent1 += val;
+				if( prozent1 >= 100 )
+				{
+					prozent1 = 100;
+					if( !jetzt && !nachher )
+						setSpielerDetails( loginKlient->getAccountId(), 2 );
+				}
+				pos = begPos + (Punkt)( ( ( Vec2< double > )( pos2 - begPos ) / 100.0 ) * prozent1 );
+				gr = begGröße + (Punkt)( ( ( Vec2< double > )( größe2 - begGröße ) / 100.0 ) * prozent1 );
+			}
+			else if( alpha != 255 )
+			{
+				alpha += val * 2;
+				if( alpha >= 255 || ( animation | 0x2 ) == animation )
+				{
+					alpha = 255;
+					animation &= ~0x1;
+					sichtbar = 1;
+					prozent1 = 0;
+				}
+			}
+			rend = 1;
+		}
+		if( ( animation | 0x2 ) == animation ) // ausblenden
+		{
+			if( alpha != 0 )
+			{
+				alpha -= val * 2;
+				if( alpha < 0 )
+					alpha = 0;
+			}
+			else
+			{
+				prozent2 += val;
+				if( prozent2 > 100 )
+					prozent2 = 100;
+				pos = begPos + (Punkt)( ( ( Vec2< double > )( pos1 - begPos ) / 100.0 ) * prozent2 );
+				gr = begGröße + (Punkt)( ( ( Vec2< double > )( größe1 - begGröße ) / 100.0 ) * prozent2 );
+				if( prozent2 == 100 )
+				{
+					prozent2 = 0;
+					animation &= ~0x2;
+					sichtbar = 0;
+				}
+			}
+			rend = 1;
+		}
+		if( laden->istSichtbar() && alpha2 != 100 )
+		{
+			if( alpha2 - val <= 100 )
+				alpha2 = 100;
+			else
+				alpha2 -= val;
+			rend = 1;
+		}
+		if( !laden->istSichtbar() && alpha2 != 255 )
+		{
+			if( alpha2 + val >= 255 )
+				alpha2 = 255;
+			else
+				alpha2 += val;
+			rend = 1;
+		}
+	}
+	if( val2 )
+	{
+		if( jetzt > 1 && !laden->istSichtbar() && knopfX != 0 )
+		{
+			if( knopfX - val2 < 0 )
+				knopfX = 0;
+			else
+				knopfX -= val2;
+			rend = 1;
+		}
+		if( jetzt < 2 && !laden->istSichtbar() && knopfX != 810 )
+		{
+			if( knopfX + val2 > 810 )
+				knopfX = 810;
+			else
+				knopfX += val2;
+			rend = 1;
+		}
+	}
+	switch( nachher )
+	{
+	case 2:
+		if( aktivität->getStatus() == 2 )
+		{
+			switch( jetzt )
+			{
+			case 0:
+				aktivität->setSichtbar( 1, 0 );
+				break;
+			case 1:
+				suchenK->setAlphaFeldStrength( -5 );
+				suchenK->setAlphaFeldFarbe( 0x5500FF00 );
+				suche->setSichtbar( 0 );
+				aktivität->setSichtbar( 1, 0 );
+				break;
+			case 3:
+				spieleUndKartenK->setAlphaFeldStrength( -5 );
+				spieleUndKartenK->setAlphaFeldFarbe( 0x5500FF00 );
+				spieleUndKarten->setSichtbar( 0, 1 );
+				aktivität->setSichtbar( 1, 1 );
+				break;
+			case 4:
+				spielPartnerK->setAlphaFeldStrength( -5 );
+				spielPartnerK->setAlphaFeldFarbe( 0x5500FF00 );
+				partner->setSichtbar( 0, 1 );
+				aktivität->setSichtbar( 1, 1 );
+				break;
+			case 5:
+				statistikK->setAlphaFeldStrength( -5 );
+				statistikK->setAlphaFeldFarbe( 0x5500FF00 );
+				statistik->setSichtbar( 0, 1 );
+				aktivität->setSichtbar( 1, 1 );
+				break;
+			case 6:
+				historieK->setAlphaFeldStrength( -5 );
+				historieK->setAlphaFeldFarbe( 0x5500FF00 );
+				historie->setSichtbar( 0, 1 );
+				aktivität->setSichtbar( 1, 1 );
+				break;
+			}
+			aktivitätK->setAlphaFeldStrength( -2 );
+			aktivitätK->setAlphaFeldFarbe( 0x3000FF00 );
+			laden->setSichtbar( 0 );
+			jetzt = nachher;
+			nachher = 0;
+		}
+		if( !aktivität->getStatus() )
+		{
+			laden->setSichtbar( 0 );
+			jetzt = nachher;
+			nachher = 0;
+		}
+		break;
+	case 3:
+		if( spieleUndKarten->getStatus() == 2 )
+		{
+			switch( jetzt )
+			{
+			case 0:
+				spieleUndKarten->setSichtbar( 1, 0 );
+				break;
+			case 1:
+				suchenK->setAlphaFeldStrength( -5 );
+				suchenK->setAlphaFeldFarbe( 0x5500FF00 );
+				suche->setSichtbar( 0 );
+				spieleUndKarten->setSichtbar( 1, 0 );
+				break;
+			case 2:
+				aktivitätK->setAlphaFeldStrength( -5 );
+				aktivitätK->setAlphaFeldFarbe( 0x5500FF00 );
+				aktivität->setSichtbar( 0, 0 );
+				spieleUndKarten->setSichtbar( 1, 0 );
+				break;
+			case 4:
+				spielPartnerK->setAlphaFeldStrength( -5 );
+				spielPartnerK->setAlphaFeldFarbe( 0x5500FF00 );
+				partner->setSichtbar( 0, 1 );
+				spieleUndKarten->setSichtbar( 1, 1 );
+				break;
+			case 5:
+				statistikK->setAlphaFeldStrength( -5 );
+				statistikK->setAlphaFeldFarbe( 0x5500FF00 );
+				statistik->setSichtbar( 0, 1 );
+				spieleUndKarten->setSichtbar( 1, 1 );
+				break;
+			case 6:
+				historieK->setAlphaFeldStrength( -5 );
+				historieK->setAlphaFeldFarbe( 0x5500FF00 );
+				historie->setSichtbar( 0, 1 );
+				spieleUndKarten->setSichtbar( 1, 1 );
+				break;
+			}
+			spieleUndKartenK->setAlphaFeldStrength( -2 );
+			spieleUndKartenK->setAlphaFeldFarbe( 0x3000FF00 );
+			laden->setSichtbar( 0 );
+			jetzt = nachher;
+			nachher = 0;
+		}
+		if( !spieleUndKarten->getStatus() )
+		{
+			laden->setSichtbar( 0 );
+			jetzt = nachher;
+			nachher = 0;
+		}
+		break;
+	case 4:
+		if( partner->getStatus() == 2 )
+		{
+			switch( jetzt )
+			{
+			case 0:
+				partner->setSichtbar( 1, 0 );
+				break;
+			case 1:
+				suchenK->setAlphaFeldStrength( -5 );
+				suchenK->setAlphaFeldFarbe( 0x5500FF00 );
+				suche->setSichtbar( 0 );
+				partner->setSichtbar( 1, 0 );
+				break;
+			case 2:
+				aktivitätK->setAlphaFeldStrength( -5 );
+				aktivitätK->setAlphaFeldFarbe( 0x5500FF00 );
+				aktivität->setSichtbar( 0, 0 );
+				partner->setSichtbar( 1, 0 );
+				break;
+			case 3:
+				spieleUndKartenK->setAlphaFeldStrength( -5 );
+				spieleUndKartenK->setAlphaFeldFarbe( 0x5500FF00 );
+				spieleUndKarten->setSichtbar( 0, 0 );
+				partner->setSichtbar( 1, 0 );
+				break;
+			case 5:
+				statistikK->setAlphaFeldStrength( -5 );
+				statistikK->setAlphaFeldFarbe( 0x5500FF00 );
+				statistik->setSichtbar( 0, 1 );
+				partner->setSichtbar( 1, 1 );
+				break;
+			case 6:
+				historieK->setAlphaFeldStrength( -5 );
+				historieK->setAlphaFeldFarbe( 0x5500FF00 );
+				historie->setSichtbar( 0, 1 );
+				partner->setSichtbar( 1, 1 );
+				break;
+			}
+			spielPartnerK->setAlphaFeldStrength( -2 );
+			spielPartnerK->setAlphaFeldFarbe( 0x3000FF00 );
+			laden->setSichtbar( 0 );
+			jetzt = nachher;
+			nachher = 0;
+		}
+		if( !partner->getStatus() )
+		{
+			laden->setSichtbar( 0 );
+			jetzt = nachher;
+			nachher = 0;
+		}
+		break;
+	case 5:
+		if( statistik->getStatus() == 2 )
+		{
+			switch( jetzt )
+			{
+			case 0:
+				statistik->setSichtbar( 1, 0 );
+				break;
+			case 1:
+				suchenK->setAlphaFeldStrength( -5 );
+				suchenK->setAlphaFeldFarbe( 0x5500FF00 );
+				suche->setSichtbar( 0 );
+				statistik->setSichtbar( 1, 0 );
+				break;
+			case 2:
+				aktivitätK->setAlphaFeldStrength( -5 );
+				aktivitätK->setAlphaFeldFarbe( 0x5500FF00 );
+				aktivität->setSichtbar( 0, 0 );
+				statistik->setSichtbar( 1, 0 );
+				break;
+			case 3:
+				spieleUndKartenK->setAlphaFeldStrength( -5 );
+				spieleUndKartenK->setAlphaFeldFarbe( 0x5500FF00 );
+				spieleUndKarten->setSichtbar( 0, 0 );
+				statistik->setSichtbar( 1, 0 );
+				break;
+			case 4:
+				spielPartnerK->setAlphaFeldStrength( -5 );
+				spielPartnerK->setAlphaFeldFarbe( 0x5500FF00 );
+				partner->setSichtbar( 0, 0 );
+				statistik->setSichtbar( 1, 0 );
+				break;
+			case 6:
+				historieK->setAlphaFeldStrength( -5 );
+				historieK->setAlphaFeldFarbe( 0x5500FF00 );
+				historie->setSichtbar( 0, 1 );
+				statistik->setSichtbar( 1, 1 );
+				break;
+			}
+			statistikK->setAlphaFeldStrength( -2 );
+			statistikK->setAlphaFeldFarbe( 0x3000FF00 );
+			laden->setSichtbar( 0 );
+			jetzt = nachher;
+			nachher = 0;
+		}
+		if( !statistik->getStatus() )
+		{
+			laden->setSichtbar( 0 );
+			jetzt = nachher;
+			nachher = 0;
+		}
+		break;
+	case 6:
+		if( historie->getStatus() == 2 )
+		{
+			switch( jetzt )
+			{
+			case 0:
+				historie->setSichtbar( 1, 0 );
+				break;
+			case 1:
+				suchenK->setAlphaFeldStrength( -5 );
+				suchenK->setAlphaFeldFarbe( 0x5500FF00 );
+				suche->setSichtbar( 0 );
+				historie->setSichtbar( 1, 0 );
+				break;
+			case 2:
+				aktivitätK->setAlphaFeldStrength( -5 );
+				aktivitätK->setAlphaFeldFarbe( 0x5500FF00 );
+				aktivität->setSichtbar( 0, 0 );
+				historie->setSichtbar( 1, 0 );
+				break;
+			case 3:
+				spieleUndKartenK->setAlphaFeldStrength( -5 );
+				spieleUndKartenK->setAlphaFeldFarbe( 0x5500FF00 );
+				spieleUndKarten->setSichtbar( 0, 0 );
+				historie->setSichtbar( 1, 0 );
+				break;
+			case 4:
+				spielPartnerK->setAlphaFeldStrength( -5 );
+				spielPartnerK->setAlphaFeldFarbe( 0x5500FF00 );
+				partner->setSichtbar( 0, 0 );
+				historie->setSichtbar( 1, 0 );
+				break;
+			case 5:
+				statistikK->setAlphaFeldStrength( -5 );
+				statistikK->setAlphaFeldFarbe( 0x5500FF00 );
+				statistik->setSichtbar( 0, 0 );
+				historie->setSichtbar( 1, 0 );
+				break;
+			}
+			historieK->setAlphaFeldStrength( -2 );
+			historieK->setAlphaFeldFarbe( 0x3000FF00 );
+			laden->setSichtbar( 0 );
+			jetzt = nachher;
+			nachher = 0;
+		}
+		if( !historie->getStatus() )
+		{
+			laden->setSichtbar( 0 );
+			jetzt = nachher;
+			nachher = 0;
+		}
+		break;
+	}
+	int tmp = suche->getAuswahlAccountId();
+	if( tmp )
+		setSpielerDetails( tmp, 2 );
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void AccountAnsehen::doMausEreignis( MausEreignis &me )
+{
+	if( !sichtbar || animation || laden->istSichtbar() )
+		return;
+	int mx = me.mx;
+	int my = me.my;
+	me.mx -= pos.x;
+	me.my -= pos.y;
+	if( jetzt > 1 )
+	{
+		int ak = 0;
+		bool tmp = me.verarbeitet;
+		suchenK->doMausEreignis( me );
+		ak = me.verarbeitet ? 1 : 0;
+		aktivitätK->doMausEreignis( me );
+		ak = me.verarbeitet && !ak ? 2 : ak;
+		spieleUndKartenK->doMausEreignis( me );
+		ak = me.verarbeitet && !ak ? 3 : ak;
+		spielPartnerK->doMausEreignis( me );
+		ak = me.verarbeitet && !ak ? 4 : ak;
+		statistikK->doMausEreignis( me );
+		ak = me.verarbeitet && !ak ? 5 : ak;
+		historieK->doMausEreignis( me );
+		ak = me.verarbeitet && !ak ? 6 : ak;
+		if( tmp )
+			ak = 0;
+		if( me.id == ME_RLinks )
+		{
+			switch( ak )
+			{
+			case 1: // Suchen Klick
+				if( jetzt == 1 )
+					break;
+				switch( jetzt )
+				{
+				case 2:
+					aktivitätK->setAlphaFeldStrength( -5 );
+					aktivitätK->setAlphaFeldFarbe( 0x5500FF00 );
+					aktivität->setSichtbar( 0, 1 );
+					break;
+				case 3:
+					spieleUndKartenK->setAlphaFeldStrength( -5 );
+					spieleUndKartenK->setAlphaFeldFarbe( 0x5500FF00 );
+					spieleUndKarten->setSichtbar( 0, 1 );
+					break;
+				case 4:
+					spielPartnerK->setAlphaFeldStrength( -5 );
+					spielPartnerK->setAlphaFeldFarbe( 0x5500FF00 );
+					partner->setSichtbar( 0, 1 );
+					break;
+				case 5:
+					statistikK->setAlphaFeldStrength( -5 );
+					statistikK->setAlphaFeldFarbe( 0x5500FF00 );
+					statistik->setSichtbar( 0, 1 );
+					break;
+				case 6:
+					historieK->setAlphaFeldStrength( -5 );
+					historieK->setAlphaFeldFarbe( 0x5500FF00 );
+					historie->setSichtbar( 0, 1 );
+					break;
+				}
+				suchenK->setAlphaFeldStrength( -2 );
+				suchenK->setAlphaFeldFarbe( 0x3000FF00 );
+				this->suche->setSichtbar( 1 );
+				jetzt = 1;
+				break;
+			case 2: // Aktivität Klick
+				setSpielerDetails( account, 2 );
+				break;
+			case 3: // SpieleUndKarten Klick
+				setSpielerDetails( account, 3 );
+				break;
+			case 4: // SpielPartner Klick
+				setSpielerDetails( account, 4 );
+				break;
+			case 5: // Statistik Klick
+				setSpielerDetails( account, 5 );
+				break;
+			case 6: // Historie Klick
+				setSpielerDetails( account, 6 );
+				break;
+			}
+		}
+	}
+	switch( jetzt )
+	{
+	case 1: // Suchen
+		suche->doMausEreignis( me );
+		break;
+	case 3: // SpieleUndKarten
+		spieleUndKarten->doMausEreignis( me );
+		break;
+	case 4: // SpielPartner
+		partner->doMausEreignis( me );
+		break;
+	case 5: // Statistik
+		statistik->doMausEreignis( me );
+		break;
+	case 6: // Historie
+		historie->doMausEreignis( me );
+		break;
+	}
+	me.mx = mx;
+	me.my = my;
+}
+
+void AccountAnsehen::doTastaturEreignis( TastaturEreignis &te )
+{
+	if( !sichtbar || animation || laden->istSichtbar() )
+		return;
+	switch( jetzt )
+	{
+	case 1: // Suchen
+		suche->doTastaturEreignis( te );
+		break;
+	case 6: // Historie
+		historie->doTastaturEreignis( te );
+		break;
+	}
+}
+
+void AccountAnsehen::render( Bild &zRObj )
+{
+	if( pos == pos1 )
+		return;
+	if( !zRObj.setDrawOptions( pos, gr ) )
+		return;
+	rahmen->setSize( gr );
+	rahmen->render( zRObj );
+	int rbr = rahmen->getRBreite();
+	zRObj.setAlpha( (unsigned char)alpha );
+	zRObj.setAlpha( (unsigned char)alpha2 );
+	zRObj.addScrollOffset( -knopfX, 0 );
+	aktivitätK->render(zRObj );
+	historieK->render( zRObj );
+	spieleUndKartenK->render( zRObj );
+	spielPartnerK->render( zRObj );
+	statistikK->render( zRObj );
+	suchenK->render( zRObj );
+	zRObj.addScrollOffset( knopfX, 0 );
+	suche->render( zRObj );
+	aktivität->render( zRObj );
+	spieleUndKarten->render( zRObj );
+	partner->render( zRObj );
+	statistik->render( zRObj );
+	historie->render( zRObj );
+	zRObj.releaseAlpha();
+	laden->render( zRObj );
+	zRObj.releaseAlpha();
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+bool AccountAnsehen::istAnimiert() const
+{
+	return animation != 0;
+}
+
+bool AccountAnsehen::istSichtbar() const
+{
+	return sichtbar || prozent1 != 0;
+}
+
+// Reference Counting
+AccountAnsehen *AccountAnsehen::getThis()
+{
+	ref++;
+	return this;
+}
+
+AccountAnsehen *AccountAnsehen::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 75 - 0
KSGClient/NachLogin/Account/AccountAnsehen.h

@@ -0,0 +1,75 @@
+#ifndef AccountAnsehen_H
+#define AccountAnsehen_H
+
+#include <Klient.h>
+#include <Fenster.h>
+#include <Animation.h>
+#include <Knopf.h>
+#include "Aktivität/AccountAktivität.h"
+#include "Historie/AccountHistorie.h"
+#include "Spiele_Karten/AccountSpieleUndKarten.h"
+#include "SpielPartner/AccountSpielPartner.h"
+#include "Statistik/AccountStatistik.h"
+#include "Suchen/AccountSuchen.h"
+
+using namespace Framework;
+
+class AccountAnsehen : public Zeichnung
+{
+private:
+	Animation2D *laden;
+	Punkt begPos;
+	Punkt begGröße;
+	Punkt pos1;
+	Punkt größe1;
+	Punkt pos2;
+	Punkt größe2;
+	Punkt bildschirmGröße;
+	LRahmen *rahmen;
+	Knopf *aktivitätK;
+	Knopf *historieK;
+	Knopf *spieleUndKartenK;
+	Knopf *spielPartnerK;
+	Knopf *statistikK;
+	Knopf *suchenK;
+	AccountSuchen *suche;
+	AccountAktivität *aktivität;
+	AccountSpieleUndKarten *spieleUndKarten;
+	AccountSpielPartner *partner;
+	AccountStatistik *statistik;
+	AccountHistorie *historie;
+	int account;
+	int alpha;
+	int alpha2;
+	bool sichtbar;
+	int jetzt;
+	int nachher;
+	int prozent1;
+	int prozent2;
+	double tickVal;
+	int animation;
+	int knopfX;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	AccountAnsehen( Schrift *zSchrift, Fenster *zNachLoginFenster, int x );
+	// Destruktor
+	~AccountAnsehen();
+	// nicht constant
+	void setSichtbar( bool sicht );
+	bool setSpielerDetails( int account, int nachher );
+	bool tick( double tickVal ) override;
+	void doMausEreignis( MausEreignis &me ) override;
+	void doTastaturEreignis( TastaturEreignis &te ) override;
+	void render( Bild &zRObj ) override;
+	// constant
+	bool istAnimiert() const;
+	bool istSichtbar() const;
+	// Reference Counting
+	AccountAnsehen *getThis();
+	AccountAnsehen *release();
+};
+
+#endif

+ 320 - 0
KSGClient/NachLogin/Account/Aktivität/AccountAktivität.cpp

@@ -0,0 +1,320 @@
+#include "AccountAktivität.h"
+#include "../../../Global/Initialisierung.h"
+#include "../../../Global/Variablen.h"
+
+// Inhalt der AccountAktivität Klasse aus AccountAktivität.h
+// Konstruktor
+AccountAktivität::AccountAktivität( Schrift *zSchrift )
+	: Thread(),
+  aktivitätF( initFenster( 810, 40, 780, 450, zSchrift, Fenster::Style::Sichtbar | Fenster::Style::Titel | Fenster::Style::TitelBuffered | Fenster::Style::Rahmen, "Aktivität von " ) ),
+  online( initLinienDiagramm( 10, 10, 760, 200, zSchrift, LDiag::Style::DatenRahmen, 0 ) ),
+  spiele( initLinienDiagramm( 10, 220, 760, 200, zSchrift, LDiag::Style::DatenRahmen, 0 ) ),
+  status( 0 ),
+  accId( 0 ),
+  animation( 0 ),
+  alpha( 255 ),
+  tickVal( 0 ),
+  rend( 0 ),
+  ref( 1 )
+{
+	online->setHIntervallBreite( 36.8 );
+	spiele->setVIntervallHeight( 36.8 );
+	online->setDatenStyle( DiagDaten::Style::autoRaster | DiagDaten::Style::intervallTexte | DiagDaten::Style::intervalle | DiagDaten::Style::Sichtbar | DiagDaten::Style::autoIntervall );
+	spiele->setDatenStyle( DiagDaten::Style::autoRaster | DiagDaten::Style::intervallTexte | DiagDaten::Style::intervalle | DiagDaten::Style::Sichtbar | DiagDaten::Style::autoIntervall );
+	online->setRasterDicke( 1 );
+	spiele->setRasterDicke( 1 );
+	online->setRasterFarbe( 0xFF505050 );
+	spiele->setRasterFarbe( 0xFF505050 );
+	online->setHIntervallFarbe( 0xFFFFFFFF );
+	spiele->setHIntervallFarbe( 0xFFFFFFFF );
+	online->setHIntervallName( "Tage" );
+	spiele->setHIntervallName( "Tage" );
+	online->setVIntervallFarbe( 0xFFFFFFFF );
+	spiele->setVIntervallFarbe( 0xFFFFFFFF );
+	online->setVIntervallName( "Stunden" );
+	spiele->setVIntervallName( "Spiele" );
+	aktivitätF->addMember( online );
+	aktivitätF->addMember( spiele );
+}
+
+// Destruktor
+AccountAktivität::~AccountAktivität()
+{
+	if( run )
+	{
+		warteAufThread( 1000 );
+		ende();
+	}
+	aktivitätF->release();
+	online->release();
+	spiele->release();
+}
+
+// nicht constant
+void AccountAktivität::reset()
+{
+	int wAnz = online->zDiagDaten()->werte->getEintragAnzahl();
+	for( int i = 0; i < wAnz; i++ )
+		online->removeWert( 0 );
+	wAnz = spiele->zDiagDaten()->werte->getEintragAnzahl();
+	for( int i = 0; i < wAnz; i++ )
+		spiele->removeWert( 0 );
+	wAnz = online->zDiagDaten()->hIntervallWerte->getEintragAnzahl();
+	for( int i = 0; i < wAnz; i++ )
+		online->removeHIntervallText( online->zDiagDaten()->hIntervallWerte->get( 0 ) );
+	wAnz = spiele->zDiagDaten()->hIntervallWerte->getEintragAnzahl();
+	for( int i = 0; i < wAnz; i++ )
+		spiele->removeHIntervallText( spiele->zDiagDaten()->hIntervallWerte->get( 0 ) );
+	wAnz = online->zDiagDaten()->vIntervallWerte->getEintragAnzahl();
+	for( int i = 0; i < wAnz; i++ )
+		online->removeVIntervallText( online->zDiagDaten()->vIntervallWerte->get( 0 ) );
+	wAnz = spiele->zDiagDaten()->vIntervallWerte->getEintragAnzahl();
+	for( int i = 0; i < wAnz; i++ )
+		spiele->removeVIntervallText( spiele->zDiagDaten()->vIntervallWerte->get( 0 ) );
+}
+
+void AccountAktivität::ladeStatistik( int accId )
+{
+	if( this->accId == accId )
+		return;
+	this->status = 0;
+	if( run )
+	{
+		warteAufThread( 1000 );
+		ende();
+	}
+	if( ( animation | 0x1 ) == animation )
+	{
+		animation |= 0x4;
+		this->accId = accId;
+		this->status = 1;
+		return;
+	}
+	if( this->accId )
+		reset();
+	this->accId = accId;
+	start();
+	this->status = 1;
+}
+
+void AccountAktivität::thread()
+{
+	Text *name = infoKlient->getSpielerName( accId );
+	if( name )
+	{
+		name->insert( 0, "Aktivität von " );
+		aktivitätF->setTitel( *name );
+		name->release();
+	}
+	RCArray< Text > *datum = new RCArray< Text >();
+	Array< double > *stOnline = new Array< double >();
+	Array< double > *stGespielt = new Array< double >();
+	Array< int > *anzSpiele = new Array< int >();
+	Array< int > *anzGewonnen = new Array< int >();
+	if( infoKlient->getSpielerAktivität( accId, datum, stOnline, stGespielt, anzSpiele, anzGewonnen ) )
+	{
+		int anz = datum->getEintragAnzahl();
+		double maxO = 0;
+		int maxS = 0;
+		for( int i = 0; i < anz; i++ )
+		{
+			if( stOnline->hat( i ) && stOnline->get( i ) > maxO )
+				maxO = stOnline->get( i );
+			if( stGespielt->hat( i ) && stGespielt->get( i ) > maxO )
+				maxO = stGespielt->get( i );
+			if( anzSpiele->hat( i ) && anzSpiele->get( i ) > maxS )
+				maxS = anzSpiele->get( i );
+			if( anzGewonnen->hat( i ) && anzGewonnen->get( i ) > maxS )
+				maxS = anzGewonnen->get( i );
+		}
+		maxO += ( maxO / 100 ) * 10;
+		maxS++;
+		online->addVIntervallText( 0, "0" );
+		online->addVIntervallText( (int)maxO + 1, Text() += (int)( maxO + 1 ) );
+		spiele->addVIntervallText( 0, "0" );
+		spiele->addVIntervallText( (int)maxS + 1, Text() += (int)( maxS + 1 ) );
+		online->addHIntervallText( 0, datum->z( 0 )->getText() );
+		online->addHIntervallText( anz - 1, datum->z( anz - 1 )->getText() );
+		spiele->addHIntervallText( 0, datum->z( 0 )->getText() );
+		spiele->addHIntervallText( anz - 1, datum->z( anz - 1 )->getText() );
+		DiagWert *w = new DiagWert();
+		w->farbe = 0xFF00FFFF;
+		w->hintergrund = 0xFF205050;
+		w->name->setText( "Zeit Online" );
+		w->style = DiagWert::Style::Sichtbar | DiagWert::Style::Name | DiagWert::Style::Hintergrund;
+		online->addWert( w );
+		w = new DiagWert();
+		w->farbe = 0xFF00FF00;
+		w->hintergrund = 0xFF205020;
+		w->name->setText( "Zeit im Spiel" );
+		w->style = DiagWert::Style::Sichtbar | DiagWert::Style::Name | DiagWert::Style::Hintergrund;
+		online->addWert( w );
+		w = new DiagWert();
+		w->farbe = 0xFF00FFFF;
+		w->hintergrund = 0xFF205050;
+		w->name->setText( "Spiele am Tag" );
+		w->style = DiagWert::Style::Sichtbar | DiagWert::Style::Name | DiagWert::Style::Hintergrund;
+		spiele->addWert( w );
+		w = new DiagWert();
+		w->farbe = 0xFF00FF00;
+		w->hintergrund = 0xFF205020;
+		w->name->setText( "Gewonnene Spiele" );
+		w->style = DiagWert::Style::Sichtbar | DiagWert::Style::Name | DiagWert::Style::Hintergrund;
+		spiele->addWert( w );
+		for( int i = 0; i < anz; i++ )
+		{
+			online->addPunkt( 0, i, stOnline->get( i ) );
+			online->addPunkt( 1, i, stGespielt->get( i ) );
+			spiele->addPunkt( 0, i, anzSpiele->get( i ) );
+			spiele->addPunkt( 1, i, anzGewonnen->get( i ) );
+		}
+	}
+	else
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Die Aktivität des Spielers konnte nicht ermittelt werden." ), new Text( "Ok" ) );
+	datum->release();
+	stOnline->release();
+	stGespielt->release();
+	anzSpiele->release();
+	anzGewonnen->release();
+	animation &= ~0x4;
+	status = 2;
+	run = 0;
+}
+
+void AccountAktivität::setSichtbar( bool sichtbar, bool nachRechts )
+{
+	if( sichtbar )
+	{
+		if( ( animation | 0x1 ) != animation || ( ( nachRechts && ( animation | 0x2 ) != animation ) || !nachRechts && ( animation | 0x2 ) == animation ) )
+		{
+			if( nachRechts )
+				aktivitätF->setPosition( -810, 40 );
+			else
+				aktivitätF->setPosition( 810, 40 );
+		}
+		animation |= 0x1;
+	}
+	else
+		animation &= ~0x1;
+	if( nachRechts )
+		animation |= 0x2;
+	else
+		animation &= ~0x2;
+}
+
+bool AccountAktivität::tick( double zeit )
+{
+	rend |= aktivitätF->tick( zeit );
+	tickVal += zeit;
+	int valA = (int)( tickVal * 150 );
+	int valB = (int)( tickVal * 500 );
+	tickVal -= valA / 150.0;
+	if( valA )
+	{
+		if( ( animation | 0x4 ) == animation && alpha )
+		{
+			if( alpha - valA <= 0 )
+				alpha = 0;
+			else
+				alpha -= valA;
+			rend = 1;
+			if( !alpha )
+			{
+				reset();
+				start();
+			}
+		}
+		if( ( animation | 0x4 ) != animation && alpha != 255 )
+		{
+			if( alpha + valA >= 255 )
+				alpha = 255;
+			else
+				alpha += valA;
+			rend = 1;
+		}
+	}
+	if( valB )
+	{
+		if( ( animation | 0x1 ) == animation )
+		{ // Sichtbar
+			if( ( animation | 0x2 ) == animation )
+			{ // Nach Rechts
+				if( aktivitätF->getX() != 10 )
+				{
+					if( aktivitätF->getX() + valB > 10 )
+						aktivitätF->setPosition( 10, aktivitätF->getY() );
+					else
+						aktivitätF->setPosition( aktivitätF->getX() + valB, aktivitätF->getY() );
+					rend = 1;
+				}
+			}
+			else
+			{ // Nach Links
+				if( aktivitätF->getX() != 10 )
+				{
+					if( aktivitätF->getX() - valB < 10 )
+						aktivitätF->setPosition( 10, aktivitätF->getY() );
+					else
+						aktivitätF->setPosition( aktivitätF->getX() - valB, aktivitätF->getY() );
+					rend = 1;
+				}
+			}
+		}
+		else
+		{ // Unsichtbar
+			if( ( animation | 0x2 ) == animation )
+			{ // Nach Rechts
+				if( aktivitätF->getX() != 810 )
+				{
+					if( aktivitätF->getX() + valB > 810 )
+						aktivitätF->setPosition( 810, aktivitätF->getY() );
+					else
+						aktivitätF->setPosition( aktivitätF->getX() + valB, aktivitätF->getY() );
+					rend = 1;
+				}
+			}
+			else
+			{ // Nach Links
+				if( aktivitätF->getX() != -810 )
+				{
+					if( aktivitätF->getX() - valB < -810 )
+						aktivitätF->setPosition( -810, aktivitätF->getY() );
+					else
+						aktivitätF->setPosition( aktivitätF->getX() - valB, aktivitätF->getY() );
+					rend = 1;
+				}
+			}
+		}
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void AccountAktivität::render( Bild &zRObj )
+{
+	zRObj.setAlpha( alpha );
+	aktivitätF->render( zRObj );
+	zRObj.releaseAlpha();
+}
+
+// constant
+int AccountAktivität::getStatus() const
+{
+	return status;
+}
+
+// Reference Counting
+AccountAktivität *AccountAktivität::getThis()
+{
+	ref++;
+	return this;
+}
+
+AccountAktivität *AccountAktivität::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 44 - 0
KSGClient/NachLogin/Account/Aktivität/AccountAktivität.h

@@ -0,0 +1,44 @@
+#ifndef AccountAktivität_H
+#define AccountAktivität_H
+
+#include <AuswahlBox.h>
+#include <Diagramm.h>
+#include <Fenster.h>
+#include <Thread.h>
+
+using namespace Framework; 
+
+class AccountAktivität : public Thread
+{
+private:
+	Fenster *aktivitätF;
+	LDiag *online;
+	LDiag *spiele;
+	int status;
+	int accId;
+	int animation;
+	unsigned char alpha;
+	double tickVal;
+	bool rend;
+	int ref;
+	
+public:
+	// Konstruktor
+	AccountAktivität( Schrift *zSchrift );
+	// Destruktor
+	~AccountAktivität();
+	// nicht constant
+	void reset();
+	void ladeStatistik( int accId );
+	virtual void thread();
+	void setSichtbar( bool sichtbar, bool nachRechts );
+	bool tick( double zeit );
+	void render( Bild &zRObj );
+	// constant
+	int getStatus() const;
+	// Reference Counting
+	AccountAktivität *getThis();
+	AccountAktivität *release();
+};
+
+#endif

+ 1526 - 0
KSGClient/NachLogin/Account/Historie/AccountHistorie.cpp

@@ -0,0 +1,1526 @@
+#include "AccountHistorie.h"
+#include "AccountHistorieDaten.h"
+#include "../../../Global/Initialisierung.h"
+#include "../../../Leser/KartenLeser.h"
+#include "../../../Global/Variablen.h"
+#include <Text.h>
+#include <Rahmen.h>
+#include <DateiSystem.h>
+#include <Zeit.h>
+#include <Punkt.h>
+
+typedef AccountHistorieStatistikV* ( *AHSSDLLStart )( void );
+typedef AufzeichnungV* ( *AHSADLLStart )( void );
+
+// Inahlt der AHSpielStatistik Klasse aus AccountHistorie.h
+// Konstruktor
+AHSpielStatistik::AHSpielStatistik( Schrift *schrift )
+	: Thread(),
+	  schrift( schrift )
+{
+	statistikF = initFenster( 10, 40, 780, 450, schrift, Fenster::Style::Sichtbar | Fenster::Style::Titel | Fenster::Style::TitelBuffered | Fenster::Style::Rahmen, "Spiel Ergebnis" );
+	laden = (Animation2D*)ladeAnimation->dublizieren();
+	laden->setSichtbar( 0 );
+	laden->setPosition( 380, 245 );
+	dllName = new Text( "" );
+	dllHandle = 0;
+	alpha = 0;
+	sichtbar = 0;
+	statistik = 0;
+	tickVal = 0;
+	ref = 1;
+}
+
+// Destruktor
+AHSpielStatistik::~AHSpielStatistik()
+{
+	statistikF->release();
+	if( dllHandle )
+		reset();
+	dllName->release();
+	schrift->release();
+	laden->release();
+}
+
+// nicht constant
+void AHSpielStatistik::reset()
+{
+	if( run )
+		warteAufThread( INFINITE );
+	if( dllHandle )
+	{
+		if( statistik )
+			statistik = statistik->release();
+		dllDateien->releaseDLL( *dllName );
+		dllHandle = 0;
+	}
+}
+
+bool AHSpielStatistik::ladeDaten( int spielId, int karteId )
+{
+	if( dllHandle )
+		reset();
+	KartenLeser *reader = new KartenLeser();
+	reader->setKarteId( karteId );
+	Text *pfad = reader->getSpielPfad();
+	if( !pfad )
+	{
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( reader->getLetzterFehler() ), new Text( "Ok" ) );
+		reader->release();
+		return 0;
+	}
+	pfad->append( "bin/" );
+	Text *spielArtName = reader->getSpielName();
+	if( !spielArtName )
+	{
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( reader->getLetzterFehler() ), new Text( "Ok" ) );
+		reader->release();
+		pfad->release();
+		return 0;
+	}
+	pfad->append( spielArtName->getText() );
+	pfad->append( ".dll" );
+	reader->release();
+	dllName->setText( "Spiele/" );
+	dllName->append( spielArtName->getText() );
+	dllName->append( ".dll" );
+	spielArtName->release();
+	dllHandle = dllDateien->ladeDLL( *dllName, *pfad );
+	if( !dllHandle )
+	{
+		Text *msg = new Text( "Die DLL Datei '" );
+		msg->append( pfad->getText() );
+		msg->append( "' konnte nicht geladen werden." );
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), msg, new Text( "Ok" ) );
+		pfad->release();
+		return 0;
+	}
+	AHSSDLLStart startFunk = (AHSSDLLStart)GetProcAddress( dllHandle, "GetAccountHistorieStatistik" );
+	if( !startFunk )
+	{
+		if( dllHandle )
+		{
+			dllDateien->releaseDLL( *dllName );
+			dllHandle = 0;
+		}
+		Text *msg = new Text( "Die Funktion 'GetAccountHistorieStatistik' konnte in der DLL Datei '" );
+		msg->append( pfad->getText() );
+		msg->append( "' nicht gefunden werden." );
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), msg, new Text( "Ok" ) );
+		pfad->release();
+		return 0;
+	}
+	pfad->release();
+	statistik = startFunk();
+	if( !statistik )
+	{
+		if( dllHandle )
+		{
+			dllDateien->releaseDLL( *dllName );
+			dllHandle = 0;
+		}
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Für diese Spielart ist keine genauere Ansicht der Spiel Ergebnisse verfügbar." ), new Text( "Ok" ) );
+		return 0;
+	}
+	this->spielId = spielId;
+	statistik->setSchrift( schrift->getThis() );
+	statistik->setBildschirm( hauptScreen->getThis() );
+	start();
+	return 1;
+}
+
+void AHSpielStatistik::thread()
+{
+	laden->setSichtbar( 1 );
+	if( !historieKlient->downloadSpielHistorie( spielId ) )
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( historieKlient->getLetzterFehler() ), new Text( "Ok" ) );
+	statistik->ladeDaten( spielId );
+	laden->setSichtbar( 0 );
+	if( sichtbar )
+		statistik->setSichtbar( 1 );
+	run = 0;
+}
+
+void AHSpielStatistik::setPosition( int x, int y )
+{
+	statistikF->setPosition( x, y );
+}
+
+void AHSpielStatistik::setSichtbar( bool sichtbar )
+{
+	if( !statistik )
+		return;
+	if( !run )
+		statistik->setSichtbar( sichtbar );
+	this->sichtbar = sichtbar;
+	if( sichtbar && !alpha )
+		alpha = 1;
+}
+
+void AHSpielStatistik::doMausEreignis( MausEreignis &me )
+{
+	if( !statistik || alpha != 255 )
+		return;
+	me.mx -= 1 + statistikF->getX();
+	me.my -= 20 + statistikF->getY();
+	statistik->doMausEreignis( me );
+	if( statistik->wurdeGeschlossen() )
+		setSichtbar( 0 );
+	me.mx += 1 + statistikF->getX();
+	me.my += 20 + statistikF->getY();
+}
+
+void AHSpielStatistik::doTastaturEreignis( TastaturEreignis &te )
+{
+	if( !statistik || alpha != 255 )
+		return;
+	statistik->doTastaturEreignis( te );
+}
+
+bool AHSpielStatistik::tick( double tickVal )
+{
+	if( !statistik || !alpha )
+		return 0;
+	bool ret = statistik->tick( tickVal );
+	ret |= laden->tick( tickVal );
+	this->tickVal += tickVal * 150;
+	int val = ( int )this->tickVal;
+	this->tickVal -= val;
+	if( val )
+	{
+		if( sichtbar && alpha != 255 )
+		{
+			if( alpha + val > 255 )
+				alpha = 255;
+			else
+				alpha += (unsigned char)val;
+			ret = 1;
+		}
+		if( !sichtbar && alpha )
+		{
+			if( alpha - val < 0 )
+				alpha = 0;
+			else
+				alpha -= (unsigned char)val;
+			if( !alpha && statistik->istNochSichtbar() )
+				alpha = 1;
+			ret = 1;
+		}
+	}
+	return ret;
+}
+
+void AHSpielStatistik::render( Bild &zRObj )
+{
+	if( !statistik || !alpha )
+		return;
+	zRObj.setAlpha( alpha );
+	statistikF->render( zRObj );
+	if( !zRObj.setDrawOptions( statistikF->getX() + 1, statistikF->getY() + 21, statistikF->getBreite() - 2, statistikF->getHeight() - 22 ) )
+	{
+		zRObj.releaseAlpha();
+		return;
+	}
+	statistik->render( zRObj );
+	zRObj.releaseDrawOptions();
+	laden->render( zRObj );
+	zRObj.releaseAlpha();
+}
+
+// constant
+bool AHSpielStatistik::istNochSichtbar() const
+{
+	if( alpha )
+		return 1;
+	return statistik ? statistik->istNochSichtbar() : 0;
+}
+
+// Refernce Counting
+AHSpielStatistik *AHSpielStatistik::getThis()
+{
+	ref++;
+	return this;
+}
+
+AHSpielStatistik *AHSpielStatistik::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inahlt der AHSpielVideo Klasse aus AccountHistorie.h
+// Konstruktor
+AHSpielVideo::AHSpielVideo( Schrift *schrift )
+	: Thread(),
+	schrift( schrift )
+{
+	videoF = initFenster( 10, 40, 780, 450, schrift, Fenster::Style::Sichtbar | Fenster::Style::Titel | Fenster::Style::TitelBuffered | Fenster::Style::Rahmen, "Spiel Aufzeichnung" );
+	laden = (Animation2D*)ladeAnimation->dublizieren();
+	laden->setSichtbar( 0 );
+	laden->setPosition( 380, 245 );
+	dllName = new Text( "" );
+	dllHandle = 0;
+	alpha = 0;
+	sichtbar = 0;
+	video = 0;
+	tickVal = 0;
+	ref = 1;
+}
+
+// Destruktor
+AHSpielVideo::~AHSpielVideo()
+{
+	videoF->release();
+	if( dllHandle )
+		reset();
+	dllName->release();
+	schrift->release();
+	laden->release();
+}
+
+// nicht constant
+void AHSpielVideo::reset()
+{
+	if( run )
+		warteAufThread( INFINITE );
+	if( dllHandle )
+	{
+		if( video )
+			video = video->release();
+		dllDateien->releaseDLL( *dllName );
+		dllHandle = 0;
+	}
+}
+
+bool AHSpielVideo::ladeDaten( int spielId, int karteId )
+{
+	if( dllHandle )
+		reset();
+	KartenLeser *reader = new KartenLeser();
+	reader->setKarteId( karteId );
+	Text *pfad = reader->getSpielPfad();
+	if( !pfad )
+	{
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( reader->getLetzterFehler() ), new Text( "Ok" ) );
+		reader->release();
+		return 0;
+	}
+	pfad->append( "bin/" );
+	Text *spielArtName = reader->getSpielName();
+	if( !spielArtName )
+	{
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( reader->getLetzterFehler() ), new Text( "Ok" ) );
+		reader->release();
+		pfad->release();
+		return 0;
+	}
+	pfad->append( spielArtName->getText() );
+	pfad->append( ".dll" );
+	reader->release();
+	dllName->setText( "Spiele/" );
+	dllName->append( spielArtName->getText() );
+	dllName->append( ".dll" );
+	spielArtName->release();
+	dllHandle = dllDateien->ladeDLL( *dllName, *pfad );
+	if( !dllHandle )
+	{
+		Text *msg = new Text( "Die DLL Datei '" );
+		msg->append( pfad->getText() );
+		msg->append( "' konnte nicht geladen werden." );
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), msg, new Text( "Ok" ) );
+		pfad->release();
+		return 0;
+	}
+	AHSADLLStart startFunk = (AHSADLLStart)GetProcAddress( dllHandle, "GetAufzeichnung" );
+	if( !startFunk )
+	{
+		if( dllHandle )
+		{
+			dllDateien->releaseDLL( *dllName );
+			dllHandle = 0;
+		}
+		Text *msg = new Text( "Die Funktion 'GetAufzeichnung' konnte in der DLL Datei '" );
+		msg->append( pfad->getText() );
+		msg->append( "' nicht gefunden werden." );
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), msg, new Text( "Ok" ) );
+		pfad->release();
+		return 0;
+	}
+	pfad->release();
+	video = startFunk();
+	if( !video )
+	{
+		if( dllHandle )
+		{
+			dllDateien->releaseDLL( *dllName );
+			dllHandle = 0;
+		}
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Für diese Spielart ist keine Aufzeichnung verfügbar." ), new Text( "Ok" ) );
+		return 0;
+	}
+	this->spielId = spielId;
+	video->setSchrift( schrift->getThis() );
+	video->setBildschirm( hauptScreen->getThis() );
+	start();
+	return 1;
+}
+
+void AHSpielVideo::thread()
+{
+	laden->setSichtbar( 1 );
+	if( !historieKlient->downloadSpielHistorie( spielId ) )
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( historieKlient->getLetzterFehler() ), new Text( "Ok" ) );
+	video->ladeSpiel( spielId );
+	laden->setSichtbar( 0 );
+	if( sichtbar )
+	{
+		nachLogin->setSpielAufzeichnung( video->getThis() );
+		aktion = 7; // Aufzeichnung betreten
+	}
+	run = 0;
+}
+
+void AHSpielVideo::setSichtbar( bool sichtbar )
+{
+	if( !video )
+		return;
+	if( sichtbar && !run )
+	{
+		nachLogin->setSpielAufzeichnung( video->getThis() );
+		aktion = 7; // Aufzeichnung betreten
+	}
+	this->sichtbar = sichtbar;
+	if( sichtbar && !alpha )
+		alpha = 1;
+}
+
+bool AHSpielVideo::tick( double tickVal )
+{
+	if( !video || !alpha )
+		return 0;
+	if( video->hatVerlassen( 0 ) && sichtbar )
+		setSichtbar( 0 );
+	bool ret = laden->tick( tickVal );
+	this->tickVal += tickVal * 150;
+	int val = ( int )this->tickVal;
+	this->tickVal -= val;
+	if( val )
+	{
+		if( sichtbar && alpha != 255 )
+		{
+			if( alpha + val > 255 )
+				alpha = 255;
+			else
+				alpha += (unsigned char)val;
+			ret = 1;
+		}
+		if( !sichtbar && alpha )
+		{
+			if( alpha - val < 0 )
+				alpha = 0;
+			else
+				alpha -= (unsigned char)val;
+			ret = 1;
+		}
+	}
+	return ret;
+}
+
+void AHSpielVideo::render( Bild &zRObj )
+{
+	if( !video || !alpha )
+		return;
+	if( !zRObj.setDrawOptions( 0, 0, videoF->getBreite() + 10, videoF->getHeight() + 40 ) )
+		return;
+	zRObj.setAlpha( alpha );
+	videoF->render( zRObj );
+	laden->render( zRObj );
+	zRObj.releaseAlpha();
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+bool AHSpielVideo::istNochSichtbar() const
+{
+	return alpha != 0;
+}
+
+// Refernce Counting
+AHSpielVideo *AHSpielVideo::getThis()
+{
+	ref++;
+	return this;
+}
+
+AHSpielVideo *AHSpielVideo::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der AHSLETeamListeSpieler Klasse aus AccountHistorie.h
+// Konstruktor
+AHSLETeamListeSpieler::AHSLETeamListeSpieler( Schrift *zSchrift, char *name, int punkte, char *status, int farbe, int br )
+	: nameTF( initTextFeld( 5, 0, 100, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, name ) ),
+  punkteTF( initTextFeld( 110, 0, 100, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, Text( "Punkte: " ) += punkte ) ),
+  statusTF( initTextFeld( 215, 0, 100, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, status ) ),
+  ram( new LRahmen() ),
+  ref( 1 )
+{
+	zSchrift->lock();
+	zSchrift->setSchriftSize( 12 );
+	nameTF->setSize( zSchrift->getTextBreite( nameTF->zText() ) + 5, 20 );
+	punkteTF->setSize( zSchrift->getTextBreite( punkteTF->zText() ) + 5, 20 );
+	statusTF->setSize( zSchrift->getTextBreite( statusTF->zText() ) + 5, 20 );
+	zSchrift->unlock();
+	if( nameTF->getBreite() > 100 )
+		punkteTF->setPosition( 10 + nameTF->getBreite(), 0 );
+	if( punkteTF->getX() + punkteTF->getBreite() > 210 )
+		statusTF->setPosition( punkteTF->getX() + punkteTF->getBreite() + 5, 0 );
+	ram->setFarbe( farbe );
+	ram->setSize( br, 20 );
+	ram->setRamenBreite( 1 );
+}
+
+// Destruktor
+AHSLETeamListeSpieler::~AHSLETeamListeSpieler()
+{
+	nameTF->release();
+	punkteTF->release();
+	statusTF->release();
+	ram->release();
+}
+
+// nicht constant
+void AHSLETeamListeSpieler::render( int yOff, Bild &zRObj )
+{
+	if( !zRObj.setDrawOptions( 2, yOff, ram->getBreite(), ram->getHeight() ) )
+		return;
+	nameTF->render( zRObj );
+	punkteTF->render( zRObj );
+	statusTF->render( zRObj );
+	ram->render( zRObj );
+	zRObj.releaseDrawOptions();
+}
+
+// cnstant
+
+// Reference Counting
+AHSLETeamListeSpieler *AHSLETeamListeSpieler::getThis()
+{
+	ref++;
+	return this;
+}
+
+AHSLETeamListeSpieler *AHSLETeamListeSpieler::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der AHSLETeamListeTeam Klasse aus AccountHistorie.h
+// Konstruktor
+AHSLETeamListeTeam::AHSLETeamListeTeam( Schrift *zSchrift, char *name, int sAnz, char *status, int farbe, int br )
+	: nameTF( initTextFeld( 5, 0, 100, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, name ) ),
+  sAnzahlTF( initTextFeld( 110, 0, 100, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, Text( "Spieleranzahl: " ) += sAnz ) ),
+  statusTF( initTextFeld( 215, 0, 100, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, status ) ),
+  ram( new LRahmen() ),
+  members( new RCArray< AHSLETeamListeSpieler >() ),
+  ref( 1 )
+{
+	zSchrift->lock();
+	zSchrift->setSchriftSize( 12 );
+	nameTF->setSize( zSchrift->getTextBreite( nameTF->zText() ) + 5, 20 );
+	sAnzahlTF->setSize( zSchrift->getTextBreite( sAnzahlTF->zText() ) + 5, 20 );
+	statusTF->setSize( zSchrift->getTextBreite( statusTF->zText() ) + 5, 20 );
+	zSchrift->unlock();
+	if( nameTF->getBreite() > 100 )
+		sAnzahlTF->setPosition( 10 + nameTF->getBreite(), 0 );
+	if( sAnzahlTF->getX() + sAnzahlTF->getBreite() > 210 )
+		statusTF->setPosition( sAnzahlTF->getX() + sAnzahlTF->getBreite() + 5, 0 );
+	ram->setFarbe( farbe );
+	ram->setSize( br, 20 );
+	ram->setRamenBreite( 1 );
+}
+
+// Destruktor
+AHSLETeamListeTeam::~AHSLETeamListeTeam()
+{
+	nameTF->release();
+	sAnzahlTF->release();
+	statusTF->release();
+	ram->release();
+	members->release();
+}
+
+// nicht constant
+void AHSLETeamListeTeam::addSpieler( AHSLETeamListeSpieler *s )
+{
+	members->add( s );
+	int maxHö = 20;
+	int anz = members->getEintragAnzahl();
+	if( anz )
+		maxHö += 4 + 20 * anz;
+	ram->setSize( ram->getBreite(), maxHö );
+}
+
+void AHSLETeamListeTeam::render( int xOff, int yOff, Bild &zRObj )
+{
+	if( !zRObj.setDrawOptions( xOff, yOff, ram->getBreite(), ram->getHeight() ) )
+		return;
+	nameTF->render( zRObj );
+	sAnzahlTF->render( zRObj );
+	statusTF->render( zRObj );
+	ram->render( zRObj );
+	yOff = 22;
+	int anz = members->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+	{
+		members->z( i )->render( yOff, zRObj );
+		yOff += 20;
+	}
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+int AHSLETeamListeTeam::getHeight() const
+{
+	return ram->getHeight();
+}
+
+// Reference Counting
+AHSLETeamListeTeam *AHSLETeamListeTeam::getThis()
+{
+	ref++;
+	return this;
+}
+
+AHSLETeamListeTeam *AHSLETeamListeTeam::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der AHSLETeamListe Klasse aus AccountHistorie.h
+// Konstruktor
+AHSLETeamListe::AHSLETeamListe( int xPos )
+	: members( new RCArray< AHSLETeamListeTeam >() ),
+  xPos( xPos ),
+  ref( 1 )
+{
+}
+
+// Destruktor
+AHSLETeamListe::~AHSLETeamListe()
+{
+	members->release();
+}
+
+// nicht constant
+void AHSLETeamListe::addTeam( AHSLETeamListeTeam *t )
+{
+	members->add( t );
+}
+
+void AHSLETeamListe::render( Bild &zRObj )
+{
+	int y = 25;
+	int anz = members->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+	{
+		members->z( i )->render( xPos, y, zRObj );
+		y += members->z( i )->getHeight();
+	}
+}
+
+// constant
+int AHSLETeamListe::getHeight() const
+{
+	int anz = members->getEintragAnzahl();
+	int hö = 0;
+	for( int i = 0; i < anz; i++ )
+		hö += members->z( i )->getHeight();
+	return hö;
+}
+
+int AHSLETeamListe::getBreite() const
+{
+	return 730 - xPos;
+}
+
+// Reference Counting
+AHSLETeamListe *AHSLETeamListe::getThis()
+{
+	ref++;
+	return this;
+}
+
+AHSLETeamListe *AHSLETeamListe::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der AHSpielListeEintrag Klasse aus AccountHistorie.h
+// Konstruktor
+AHSpielListeEintrag::AHSpielListeEintrag( int id, int karteId, Schrift *zSchrift, char *spiel, char *karte, char *datum, char *status,
+										  char *dauer, char *spielStatus, char *gewinner, int sAnzahl )
+: spielTF( initTextFeld( 5, 0, 100, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, Text( "Spiel: " ) += spiel ) ),
+  karteTF( initTextFeld( 110, 0, 100, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, Text( "Karte: " ) += karte ) ),
+  datumTF( initTextFeld( 215, 0, 180, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, Text( "Datum: " ) += datum ) ),
+  statusTF( initTextFeld( 400, 0, 100, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, Text( "Status: " ) += status ) ),
+  spiel( new Text( spiel ) ),
+  karte( new Text( karte ) ),
+  datum( new Text( datum ) ),
+  status( new Text( status ) ),
+  detailsK( initKnopf( 715, 0, 20, 20, 0, 0, "" ) ),
+  dauerTF( initTextFeld( 5, 25, 100, 20, zSchrift, TextFeld::Style::Text, Text( "Dauer: " ) += dauer ) ),
+  spielStatusTF( initTextFeld( 5, 45, 100, 20, zSchrift, TextFeld::Style::Text, Text( "Status: " ) += spielStatus ) ),
+  gewinnerTF( initTextFeld( 5, 65, 100, 20, zSchrift, TextFeld::Style::Text, Text( "Gewinner: " ) += gewinner ) ),
+  sAnzahlTF( initTextFeld( 5, 85, 100, 20, zSchrift, TextFeld::Style::Text, Text( "Spieleranzahl: " ) += sAnzahl ) ),
+  statistikK( initKnopf( 5, 105, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Statistik" ) ),
+  videoK( initKnopf( 5, 130, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Aufzeichnung" ) ),
+  liste( 0 ),
+  ram( new LRahmen() ),
+  ausklappen( bilder->get( "account.ltdb/ausklappen.png" ) ),
+  einklappen( bilder->get( "account.ltdb/einklappen.png" ) ),
+  id( id ),
+  karteId( karteId ),
+  tickVal( 0 ),
+  aktion( 0 ),
+  maxHö( 155 ),
+  ref( 1 )
+{
+	if( !einklappen )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/account.ltdb" ) );
+		datei->leseDaten( 0 );
+		einklappen = datei->laden( 0, new Text( "einklappen.png" ) );
+		datei->release();
+		bilder->add( "account.ltdb/einklappen.png", einklappen->getThis() );
+	}
+	if( !ausklappen )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/account.ltdb" ) );
+		datei->leseDaten( 0 );
+		ausklappen = datei->laden( 0, new Text( "ausklappen.png" ) );
+		datei->release();
+		bilder->add( "account.ltdb/ausklappen.png", ausklappen->getThis() );
+	}
+	detailsK->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	detailsK->setHintergrundBildZ( ausklappen->getThis() );
+	initToolTip( detailsK, "Details anzeigen.", zSchrift->getThis(), hauptScreen );
+	zSchrift->lock();
+	zSchrift->setSchriftSize( 12 );
+	spielTF->setSize( zSchrift->getTextBreite( spielTF->zText() ) + 5, 20 );
+	karteTF->setSize( zSchrift->getTextBreite( karteTF->zText() ) + 5, 20 );
+	datumTF->setSize( zSchrift->getTextBreite( datumTF->zText() ) + 5, 20 );
+	statusTF->setSize( zSchrift->getTextBreite( statusTF->zText() ) + 5, 20 );
+	dauerTF->setSize( zSchrift->getTextBreite( dauerTF->zText() ), 20 );
+	spielStatusTF->setSize( zSchrift->getTextBreite( spielStatusTF->zText() ), 20 );
+	gewinnerTF->setSize( zSchrift->getTextBreite( gewinnerTF->zText() ), 20 );
+	sAnzahlTF->setSize( zSchrift->getTextBreite( sAnzahlTF->zText() ), 20 );
+	zSchrift->unlock();
+	if( spielTF->getBreite() > 100 )
+		karteTF->setPosition( 10 + spielTF->getBreite(), 0 );
+	if( karteTF->getX() + karteTF->getBreite() > 210 )
+		datumTF->setPosition( karteTF->getX() + karteTF->getBreite() + 5, 0 );
+	if( datumTF->getX() + datumTF->getBreite() > 395 )
+		statusTF->setPosition( datumTF->getX() + datumTF->getBreite() + 5, 0 );
+	ram->setFarbe( 0xFFFFFFFF );
+	ram->setSize( 735, 20 );
+	ram->setRamenBreite( 1 );
+	int br = dauerTF->getBreite();
+	br = br > spielStatusTF->getBreite() ? br : spielStatusTF->getBreite();
+	br = br > gewinnerTF->getBreite() ? br : gewinnerTF->getBreite();
+	br = br > sAnzahlTF->getBreite() ? br : sAnzahlTF->getBreite();
+	statistikK->setSize( br, statistikK->getHeight() );
+	videoK->setSize( br, videoK->getHeight() );
+	liste = new AHSLETeamListe( br + 10 );
+}
+
+// Destruktor
+AHSpielListeEintrag::~AHSpielListeEintrag()
+{
+	spielTF->release();
+	karteTF->release();
+	datumTF->release();
+	statusTF->release();
+	spiel->release();
+	karte->release();
+	datum->release();
+	status->release();
+	detailsK->release();
+	dauerTF->release();
+	spielStatusTF->release();
+	gewinnerTF->release();
+	sAnzahlTF->release();
+	statistikK->release();
+	videoK->release();
+	liste->release();
+	ram->release();
+	einklappen->release();
+	ausklappen->release();
+}
+
+// nicht constant
+void AHSpielListeEintrag::addTeam( AHSLETeamListeTeam *t )
+{
+	liste->addTeam( t );
+	maxHö = liste->getHeight();
+	maxHö = 155 > maxHö + 30 ? 155 : maxHö + 30;
+}
+
+bool AHSpielListeEintrag::tick( double tickVal )
+{
+	bool ret = detailsK->tick( tickVal );
+	ret |= statistikK->tick( tickVal );
+	ret |= videoK->tick( tickVal );
+	this->tickVal += tickVal * 150;
+	int val = ( int )this->tickVal;
+	this->tickVal -= val;
+	if( val )
+	{
+		if( detailsK->zHintergrundBild() == ausklappen && ram->getHeight() != 20 )
+		{
+			if( ram->getHeight() - val < 20 )
+				ram->setSize( ram->getBreite(), 20 );
+			else
+				ram->setSize( ram->getBreite(), ram->getHeight() - val );
+			ret = 1;
+		}
+		if( detailsK->zHintergrundBild() == einklappen )
+		{
+			if( ram->getHeight() > maxHö )
+			{
+				if( ram->getHeight() - val < maxHö )
+					ram->setSize( ram->getBreite(), maxHö );
+				else
+					ram->setSize( ram->getBreite(), ram->getHeight() - val );
+				ret = 1;
+			}
+			if( ram->getHeight() < maxHö )
+			{
+				if( ram->getHeight() + val > maxHö )
+					ram->setSize( ram->getBreite(), maxHö );
+				else
+					ram->setSize( ram->getBreite(), ram->getHeight() + val );
+				ret = 1;
+			}
+		}
+	}
+	return ret;
+}
+
+void AHSpielListeEintrag::doMausEreignis( MausEreignis &me )
+{
+	bool meVera = 0;
+	bool meVeraTmp = 0;
+	if( me.mx < 0 || me.my < 0 || me.mx >= ram->getBreite() || me.my >= ram->getHeight() )
+	{
+		meVeraTmp = me.verarbeitet;
+		me.verarbeitet = 1;
+		meVera = 1;
+	}
+	int vera = me.verarbeitet;
+	detailsK->doMausEreignis( me );
+	if( !vera && me.verarbeitet && me.id == ME_RLinks )
+	{
+		if( detailsK->zHintergrundBild() == einklappen )
+			detailsK->setHintergrundBildZ( ausklappen->getThis() );
+		else
+			detailsK->setHintergrundBildZ( einklappen->getThis() );
+	}
+	vera = me.verarbeitet;
+	statistikK->doMausEreignis( me );
+	if( !vera && me.verarbeitet && me.id == ME_RLinks )
+		aktion = 1;
+	vera = me.verarbeitet;
+	videoK->doMausEreignis( me );
+	if( !vera && me.verarbeitet && me.id == ME_RLinks )
+		aktion = 2;
+	if( meVera )
+		me.verarbeitet = meVeraTmp;
+}
+
+void AHSpielListeEintrag::render( int yOff, Bild &zRObj )
+{
+	if( !zRObj.setDrawOptions( 5, yOff, ram->getBreite(), ram->getHeight() ) )
+		return;
+	ram->render( zRObj );
+	if( ram->getHeight() > 20 )
+		zRObj.drawLinieH( 1, 20, ram->getBreite() - 2, ram->getFarbe() );
+	if( !zRObj.setDrawOptions( 1, 1, ram->getBreite() - 2, ram->getHeight() - 2 ) )
+	{
+		zRObj.releaseDrawOptions();
+		return;
+	}
+	spielTF->render( zRObj );
+	karteTF->render( zRObj );
+	datumTF->render( zRObj );
+	statusTF->render( zRObj );
+	detailsK->render( zRObj );
+	dauerTF->render( zRObj );
+	spielStatusTF->render( zRObj );
+	gewinnerTF->render( zRObj );
+	sAnzahlTF->render( zRObj );
+	statistikK->render( zRObj );
+	videoK->render( zRObj );
+	liste->render( zRObj );
+	zRObj.releaseDrawOptions();
+	zRObj.releaseDrawOptions();
+}
+
+int AHSpielListeEintrag::getAktion()
+{
+	int ret = aktion;
+	aktion = 0;
+	return ret;
+}
+
+// constant
+int AHSpielListeEintrag::getKarteId() const
+{
+	return karteId;
+}
+
+int AHSpielListeEintrag::getHeight() const
+{
+	return ram->getHeight();
+}
+
+int AHSpielListeEintrag::getId() const
+{
+	return id;
+}
+
+int AHSpielListeEintrag::getListeBreite() const
+{
+	return liste->getBreite();
+}
+
+Text *AHSpielListeEintrag::zSpiel() const
+{
+	return spiel;
+}
+
+Text *AHSpielListeEintrag::zKarte() const
+{
+	return karte;
+}
+
+Text *AHSpielListeEintrag::zDatum() const
+{
+	return datum;
+}
+
+Text *AHSpielListeEintrag::zStatus() const
+{
+	return status;
+}
+
+// Reference Counting
+AHSpielListeEintrag *AHSpielListeEintrag::getThis()
+{
+	ref++;
+	return this;
+}
+
+AHSpielListeEintrag *AHSpielListeEintrag::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der AHSpielListe Klasse aus AccountHistorie.h
+// Konstruktor
+AHSpielListe::AHSpielListe()
+	: Zeichnung(),
+  ram( new LRahmen() ),
+  scroll( new VScrollBar() ),
+  members( new RCArray< AHSpielListeEintrag >() ),
+  sortSpalte( new Text( "Spiel" ) ),
+  sortAbsteigend( 0 ),
+  ref( 1 )
+{
+	pos = Punkt( 10, 40 );
+	ram->setFarbe( 0xFFFFFFFF );
+	ram->setRamenBreite( 1 );
+	ram->setSize( 760, 380 );
+	scroll->update( 0, 380 );
+}
+
+// Destruktor
+AHSpielListe::~AHSpielListe()
+{
+	ram->release();
+	scroll->release();
+	members->release();
+	sortSpalte->release();
+}
+
+// privat
+int AHSpielListe::getReihenfolge( int *arr )
+{
+	lockZeichnung();
+	int anz = members->getEintragAnzahl();
+	if( !anz )
+	{
+		unlockZeichnung();
+		return 0;
+	}
+	int ret = 0;
+	bool *fertig = new bool[ anz ];
+	ZeroMemory( fertig, anz );
+	for( int i = 0; i < anz; i++ )
+	{
+		int index = -1;
+		Text minMaxT;
+		Zeit minMaxZ;
+		for( int j = 0; j < anz; j++ )
+		{
+			AHSpielListeEintrag *tmp = members->z( j );
+			if( sortSpalte->istGleich( "Spiel" ) && !fertig[ j ] && ( index < 0 ||
+				( sortAbsteigend && *tmp->zSpiel() > minMaxT ) || ( !sortAbsteigend && *tmp->zSpiel() < minMaxT ) ) )
+			{
+				minMaxT = tmp->zSpiel()->getText();
+				index = j;
+			}
+			else if( sortSpalte->istGleich( "Karte" ) && !fertig[ j ] && ( index < 0 ||
+				( sortAbsteigend && *tmp->zKarte() > minMaxT ) || ( !sortAbsteigend && *tmp->zKarte() < minMaxT ) ) )
+			{
+				minMaxT = tmp->zKarte()->getText();
+				index = j;
+			}
+			else if( sortSpalte->istGleich( "Datum" ) && !fertig[ j ] && ( index < 0 ||
+				( sortAbsteigend && minMaxZ.istKleiner( "y-m-d h:i", tmp->zDatum()->getText() ) ) ||
+				( !sortAbsteigend && minMaxZ.istLater( "y-m-d h:i", tmp->zDatum()->getText() ) ) ) )
+			{
+				minMaxZ.setZeit( "y-m-d h:i", tmp->zDatum()->getText() );
+				index = j;
+			}
+			else if( sortSpalte->istGleich( "Status" ) && !fertig[ j ] && ( index < 0 ||
+				( sortAbsteigend && *tmp->zStatus() > minMaxT ) || ( !sortAbsteigend && *tmp->zStatus() < minMaxT ) ) )
+			{
+				minMaxT = tmp->zStatus()->getText();
+				index = j;
+			}
+		}
+		if( index < 0 )
+			break;
+		fertig[ index ] = 1;
+		arr[ ret ] = index;
+		ret++;
+	}
+	delete[] fertig;
+	unlockZeichnung();
+	return ret;
+}
+
+// nicht constant
+void AHSpielListe::setSortSpalte( char *sp )
+{
+	lockZeichnung();
+	sortSpalte->setText( sp );
+	unlockZeichnung();
+}
+
+void AHSpielListe::setSortRichtung( bool absteigend )
+{
+	sortAbsteigend = absteigend;
+}
+
+void AHSpielListe::reset()
+{
+	lockZeichnung();
+	members->leeren();
+	unlockZeichnung();
+}
+
+void AHSpielListe::addSpiel( AHSpielListeEintrag *s )
+{
+	lockZeichnung();
+	members->add( s );
+	unlockZeichnung();
+}
+
+bool AHSpielListe::tick( double tickVal )
+{
+	bool ret = scroll->getRend();
+	lockZeichnung();
+	int anz = members->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+		ret |= members->z( i )->tick( tickVal );
+	unlockZeichnung();
+	return ret;
+}
+
+void AHSpielListe::doMausEreignis( MausEreignis &me )
+{
+	bool vera = 0;
+	if( me.mx - pos.x <= 0 || me.mx - pos.x >= ram->getBreite() || me.my - pos.y <= 0 || me.my - pos.y >= ram->getHeight() )
+	{
+		vera = 1;
+		me.verarbeitet = 1;
+	}
+	int mx = me.mx, my = me.my;
+	me.mx -= pos.x;
+	me.my -= pos.y;
+	scroll->doMausMessage( ram->getBreite() - 16, 1, 15, ram->getHeight() - 2, me );
+	me.mx -= 5;
+	me.my -= 5 - scroll->getScroll();
+	lockZeichnung();
+	int anz = members->getEintragAnzahl();
+	int *rf = new int[ anz ];
+	int rfAnz = getReihenfolge( rf );
+	for( int i = 0; i < rfAnz; i++ )
+	{
+		members->z( rf[ i ] )->doMausEreignis( me );
+		me.my -= members->z( rf[ i ] )->getHeight() + 5;
+	}
+	delete[] rf;
+	unlockZeichnung();
+	me.mx = mx, me.my = my;
+	if( vera )
+		me.verarbeitet = 0;
+}
+
+void AHSpielListe::render( Bild &zRObj )
+{
+	if( !zRObj.setDrawOptions( pos, ram->getSize() ) )
+		return;
+	ram->render( zRObj );
+	scroll->render( ram->getBreite() - 16, 1, 15, ram->getHeight() - 2, zRObj );
+	if( !zRObj.setDrawOptions( 1, 1, ram->getBreite() - 15, ram->getHeight() - 2 ) )
+	{
+		zRObj.releaseDrawOptions();
+		return;
+	}
+	int anzHö = 5;
+	lockZeichnung();
+	int anz = members->getEintragAnzahl();
+	int *rf = new int[ anz ];
+	int rfAnz = getReihenfolge( rf );
+	for( int i = 0; i < rfAnz; i++ )
+	{
+		members->z( rf[ i ] )->render( anzHö - scroll->getScroll(), zRObj );
+		anzHö += members->z( rf[ i ] )->getHeight() + 5;
+	}
+	delete[] rf;
+	unlockZeichnung();
+	scroll->update( anzHö, ram->getHeight() - 2 );
+	zRObj.releaseDrawOptions();
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+int AHSpielListe::getAktion( int *spielId, int *karteId ) const
+{
+	int anz = members->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+	{
+		int ak = members->z( i )->getAktion();
+		if( ak )
+		{
+			*spielId = members->z( i )->getId();
+			*karteId = members->z( i )->getKarteId();
+			return ak;
+		}
+	}
+	return 0;
+}
+
+// Reference Counting
+AHSpielListe *AHSpielListe::getThis()
+{
+	ref++;
+	return this;
+}
+
+AHSpielListe *AHSpielListe::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der AccountHistorie Klasse aus AccountHistorie.h
+// Konstruktor
+AccountHistorie::AccountHistorie( Schrift *zSchrift )
+	: Thread(),
+  schrift( zSchrift->getThis() ),
+  historieF( initFenster( 810, 40, 780, 450, zSchrift, Fenster::Style::Sichtbar | Fenster::Style::Titel | Fenster::Style::TitelBuffered | Fenster::Style::Rahmen | Fenster::Style::Erlaubt, "Historie von " ) ),
+  sortSpalte( initAuswahlBox( 10, 10, 150, 20, zSchrift, ABSTYLE, { "Spiel", "Karte", "Datum", "Status" } ) ),
+  sortRichtung( initAuswahlBox( 170, 10, 150, 20, zSchrift, ABSTYLE, { "Aufwärts", "Abwärts" } ) ),
+  liste( new AHSpielListe() ),
+  statistik( new AHSpielStatistik( zSchrift->getThis() ) ),
+  video( new AHSpielVideo( zSchrift->getThis() ) ),
+  status( 0 ),
+  accId( 0 ),
+  animation( 0 ),
+  alpha( 255 ),
+  alpha2( 255 ),
+  alpha3( 255 ),
+  tickVal( 0 ),
+  rend( 0 ),
+  ref( 1 )
+{
+	initToolTip( sortSpalte, "Wähle aus, nach welcher Spalte die\nTabelle sortiert werden soll.", zSchrift->getThis(), hauptScreen );
+	initToolTip( sortRichtung, "Wähle aus, ob Aufwärts oder Abwärts\nsortiert werden soll.", zSchrift->getThis(), hauptScreen );
+	historieF->addMember( liste );
+	historieF->addMember( sortSpalte );
+	historieF->addMember( sortRichtung );
+	historieF->setMausEreignis( _ret1ME );
+}
+
+// Destruktor
+AccountHistorie::~AccountHistorie()
+{
+	schrift->release();
+	historieF->release();
+	sortSpalte->release();
+	sortRichtung->release();
+	statistik->release();
+	liste->release();
+	video->release();
+}
+
+// nicht constant
+void AccountHistorie::reset()
+{
+	liste->reset();
+	statistik->reset();
+	video->reset();
+}
+
+void AccountHistorie::ladeStatistik( int accId )
+{
+	if( this->accId == accId )
+		return;
+	this->status = 0;
+	if( run )
+	{
+		warteAufThread( 1000 );
+		ende();
+	}
+	if( ( animation | 0x1 ) == animation )
+	{
+		animation |= 0x4;
+		this->accId = accId;
+		this->status = 1;
+		return;
+	}
+	if( this->accId )
+		reset();
+	this->accId = accId;
+	start();
+	this->status = 1;
+}
+
+void AccountHistorie::thread()
+{
+	Text *name = infoKlient->getSpielerName( accId );
+	if( name )
+	{
+		name->insert( 0, "Historie von " );
+		historieF->setTitel( *name );
+		name->release();
+	}
+	AHDaten *daten = infoKlient->getSpielHistorieDaten( accId );
+	int anz = daten->spiele->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+	{
+		AHSpielDaten *spiel = daten->spiele->z( i );
+		AHSpielListeEintrag *spielE = new AHSpielListeEintrag( spiel->id, spiel->karteId, schrift, *spiel->spiel, *spiel->karte,
+															   *spiel->datum, *spiel->status, *spiel->dauer,
+															   *spiel->spielStatus, *spiel->gewinner, spiel->sAnzahl );
+		int tAnz = spiel->teams->getEintragAnzahl();
+		for( int j = 0; j < tAnz; j++ )
+		{
+			AHSpielTeamDaten *team = spiel->teams->z( j );
+			AHSLETeamListeTeam *teamE = new AHSLETeamListeTeam( schrift, *team->name, team->sAnzahl, *team->status,
+																team->farbe, spielE->getListeBreite() );
+			int sAnz = team->spieler->getEintragAnzahl();
+			for( int k = 0; k < sAnz; k++ )
+			{
+				AHSpielSpielerDaten *spieler = team->spieler->z( k );
+				AHSLETeamListeSpieler *spielerE = new AHSLETeamListeSpieler( schrift, *spieler->name, spieler->punkte, *spieler->status,
+																			 spieler->farbe, spielE->getListeBreite() - 4 );
+				teamE->addSpieler( spielerE );
+			}
+			spielE->addTeam( teamE );
+		}
+		liste->addSpiel( spielE );
+	}
+	daten->release();
+	animation &= ~0x4;
+	status = 2;
+	run = 0;
+}
+
+void AccountHistorie::setSichtbar( bool sichtbar, bool nachRechts )
+{
+	if( sichtbar )
+	{
+		if( ( animation | 0x1 ) != animation || ( ( nachRechts && ( animation | 0x2 ) != animation ) || !nachRechts && ( animation | 0x2 ) == animation ) )
+		{
+			if( nachRechts )
+				historieF->setPosition( -810, 40 );
+			else
+				historieF->setPosition( 810, 40 );
+		}
+		animation |= 0x1;
+	}
+	else
+		animation &= ~0x1;
+	if( nachRechts )
+		animation |= 0x2;
+	else
+		animation &= ~0x2;
+}
+
+bool AccountHistorie::tick( double zeit )
+{
+	if( !statistik->istNochSichtbar() && !video->istNochSichtbar() )
+		rend |= historieF->tick( zeit );
+	rend |= statistik->tick( zeit );
+	rend |= video->tick( zeit );
+	tickVal += zeit;
+	int valA = (int)( tickVal * 150 );
+	int valB = (int)( tickVal * 500 );
+	tickVal -= valA / 150.0;
+	if( valA )
+	{
+		if( ( animation | 0x8 ) == animation && alpha2 )
+		{
+			if( alpha2 - valA <= 0 )
+			{
+				alpha2 = 0;
+				statistik->setSichtbar( 1 );
+			}
+			else
+				alpha2 -= valA;
+			rend = 1;
+		}
+		if( ( animation | 0x8 ) != animation && alpha2 != 255 )
+		{
+			if( alpha2 + valA >= 255 )
+				alpha2 = 255;
+			else
+				alpha2 += valA;
+			rend = 1;
+		}
+		if( ( animation | 0x10 ) == animation && alpha3 )
+		{
+			if( alpha3 - valA <= 0 )
+			{
+				alpha3 = 0;
+				video->setSichtbar( 1 );
+			}
+			else
+				alpha3 -= valA;
+			rend = 1;
+		}
+		if( ( animation | 0x10 ) != animation && alpha3 != 255 )
+		{
+			if( alpha3 + valA >= 255 )
+				alpha3 = 255;
+			else
+				alpha3 += valA;
+			rend = 1;
+		}
+		if( ( animation | 0x4 ) == animation && alpha )
+		{
+			if( alpha - valA <= 0 )
+				alpha = 0;
+			else
+				alpha -= valA;
+			rend = 1;
+			if( !alpha )
+			{
+				reset();
+				start();
+			}
+		}
+		if( ( animation | 0x4 ) != animation && alpha != 255 )
+		{
+			if( alpha + valA >= 255 )
+				alpha = 255;
+			else
+				alpha += valA;
+			rend = 1;
+		}
+	}
+	if( valB )
+	{
+		if( ( animation | 0x1 ) == animation )
+		{ // Sichtbar
+			if( ( animation | 0x2 ) == animation )
+			{ // Nach Rechts
+				if( historieF->getX() != 10 )
+				{
+					if( historieF->getX() + valB > 10 )
+						historieF->setPosition( 10, historieF->getY() );
+					else
+						historieF->setPosition( historieF->getX() + valB, historieF->getY() );
+					statistik->setPosition( historieF->getX(), historieF->getY() );
+					rend = 1;
+				}
+			}
+			else
+			{ // Nach Links
+				if( historieF->getX() != 10 )
+				{
+					if( historieF->getX() - valB < 10 )
+						historieF->setPosition( 10, historieF->getY() );
+					else
+						historieF->setPosition( historieF->getX() - valB, historieF->getY() );
+					statistik->setPosition( historieF->getX(), historieF->getY() );
+					rend = 1;
+				}
+			}
+		}
+		else
+		{ // Unsichtbar
+			if( ( animation | 0x2 ) == animation )
+			{ // Nach Rechts
+				if( historieF->getX() != 810 )
+				{
+					if( historieF->getX() + valB > 810 )
+						historieF->setPosition( 810, historieF->getY() );
+					else
+						historieF->setPosition( historieF->getX() + valB, historieF->getY() );
+					statistik->setPosition( historieF->getX(), historieF->getY() );
+					rend = 1;
+				}
+			}
+			else
+			{ // Nach Links
+				if( historieF->getX() != -810 )
+				{
+					if( historieF->getX() - valB < -810 )
+						historieF->setPosition( -810, historieF->getY() );
+					else
+						historieF->setPosition( historieF->getX() - valB, historieF->getY() );
+					statistik->setPosition( historieF->getX(), historieF->getY() );
+					rend = 1;
+				}
+			}
+		}
+	}
+	if( !alpha2 && !statistik->istNochSichtbar() )
+	{
+		animation &= ~0x8;
+		statistik->reset();
+	}
+	if( !alpha3 && !video->istNochSichtbar() )
+	{
+		animation &= ~0x10;
+		video->reset();
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void AccountHistorie::doMausEreignis( MausEreignis &me )
+{
+	if( !statistik->istNochSichtbar() && !video->istNochSichtbar() && alpha == 255 && alpha2 == 255 && alpha3 == 255 )
+	{
+		int sortSpalteS = sortSpalte->getAuswahl();
+		int sortRichtungS = sortRichtung->getAuswahl();
+		historieF->doMausEreignis( me );
+		if( sortSpalte->getAuswahl() != sortSpalteS )
+		{
+			liste->setSortSpalte( sortSpalte->zEintrag( sortSpalte->getAuswahl() )->zText()->getText() );
+			sortSpalte->einklappen();
+		}
+		if( sortRichtung->getAuswahl() != sortRichtungS )
+		{
+			liste->setSortRichtung( sortRichtung->getAuswahl() != 0 );
+			sortRichtung->einklappen();
+		}
+		int spielId = 0;
+		int karteId = 0;
+		int ak = liste->getAktion( &spielId, &karteId );
+		if( ak == 1 )
+		{ // Statistik anzeigen
+			if( statistik->ladeDaten( spielId, karteId ) )
+				animation |= 0x8;
+		}
+		if( ak == 2 )
+		{ // Aufzeichnung abspielen
+			if( video->ladeDaten( spielId, karteId ) )
+				animation |= 0x10;
+		}
+	}
+	if( statistik->istNochSichtbar() )
+		statistik->doMausEreignis( me );
+}
+
+void AccountHistorie::doTastaturEreignis( TastaturEreignis &te )
+{
+	if( statistik->istNochSichtbar() )
+		statistik->doTastaturEreignis( te );
+}
+
+void AccountHistorie::render( Bild &zRObj )
+{
+	zRObj.setAlpha( alpha );
+	if( alpha2 && alpha3 )
+	{
+		zRObj.setAlpha( alpha2 );
+		zRObj.setAlpha( alpha3 );
+		historieF->render( zRObj );
+		zRObj.releaseAlpha();
+		zRObj.releaseAlpha();
+	}
+	if( statistik->istNochSichtbar() )
+		statistik->render( zRObj );
+	if( video->istNochSichtbar() )
+		video->render( zRObj );
+	zRObj.releaseAlpha();
+}
+
+// constant
+int AccountHistorie::getStatus() const
+{
+	return status;
+}
+
+// Reference Counting
+AccountHistorie *AccountHistorie::getThis()
+{
+	ref++;
+	return this;
+}
+
+AccountHistorie *AccountHistorie::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 287 - 0
KSGClient/NachLogin/Account/Historie/AccountHistorie.h

@@ -0,0 +1,287 @@
+#ifndef AccountHistorie_H
+#define AccountHistorie_H
+
+#include <Zeichnung.h>
+#include <Thread.h>
+#include <Knopf.h>
+#include <Array.h>
+#include <AuswahlBox.h>
+#include <Fenster.h>
+#include <Animation.h>
+#include <AccountHistorieStatistikV.h>
+#include <AufzeichnungV.h>
+
+using namespace Framework;
+
+class AHSpielStatistik : private Thread
+{
+private:
+	Fenster *statistikF;
+	Animation2D *laden;
+	Schrift *schrift;
+	Text *dllName;
+	HINSTANCE dllHandle;
+	AccountHistorieStatistikV *statistik;
+	double tickVal;
+	unsigned char alpha;
+	bool sichtbar;
+	int spielId;
+	int ref;
+
+public:
+	// Konstruktor
+	AHSpielStatistik( Schrift *schrift );
+	// Destruktor
+	~AHSpielStatistik();
+	// nicht constant
+	void reset();
+	bool ladeDaten( int spielId, int spielArtId );
+	void thread();
+	void setPosition( int x, int y );
+	void setSichtbar( bool sichtbar );
+	void doMausEreignis( MausEreignis &me );
+	void doTastaturEreignis( TastaturEreignis &te );
+	bool tick( double tickVal );
+	void render( Bild &zRObj );
+	// constant
+	bool istNochSichtbar() const;
+	// Refernce Counting
+	AHSpielStatistik *getThis();
+	AHSpielStatistik *release();
+};
+
+class AHSpielVideo : private Thread
+{
+private:
+	Fenster *videoF;
+	Animation2D *laden;
+	Schrift *schrift;
+	Text *dllName;
+	HINSTANCE dllHandle;
+	AufzeichnungV *video;
+	double tickVal;
+	unsigned char alpha;
+	bool sichtbar;
+	int spielId;
+	int ref;
+
+public:
+	// Konstruktor
+	AHSpielVideo( Schrift *schrift );
+	// Destruktor
+	~AHSpielVideo();
+	// nicht constant
+	void reset();
+	bool ladeDaten( int spielId, int spielArtId );
+	void thread();
+	void setSichtbar( bool sichtbar );
+	bool tick( double tickVal );
+	void render( Bild &zRObj );
+	// constant
+	bool istNochSichtbar() const;
+	// Refernce Counting
+	AHSpielVideo *getThis();
+	AHSpielVideo *release();
+};
+
+class AHSLETeamListeSpieler
+{
+private:
+	TextFeld *nameTF;
+	TextFeld *punkteTF;
+	TextFeld *statusTF;
+	LRahmen *ram;
+	int ref;
+
+public:
+	// Konstruktor
+	AHSLETeamListeSpieler( Schrift *zSchrift, char *name, int punkte, char *status, int farbe, int br );
+	// Destruktor
+	~AHSLETeamListeSpieler();
+	// nicht constant
+	void render( int yOff, Bild &zRObj );
+	// cnstant
+
+	// Reference Counting
+	AHSLETeamListeSpieler *getThis();
+	AHSLETeamListeSpieler *release();
+};
+
+class AHSLETeamListeTeam
+{
+private:
+	TextFeld *nameTF;
+	TextFeld *sAnzahlTF;
+	TextFeld *statusTF;
+	LRahmen *ram;
+	RCArray< AHSLETeamListeSpieler > *members;
+	int ref;
+
+public:
+	// Konstruktor
+	AHSLETeamListeTeam( Schrift *zSchrift, char *name, int sAnz, char *status, int farbe, int br );
+	// Destruktor
+	~AHSLETeamListeTeam();
+	// nicht constant
+	void addSpieler( AHSLETeamListeSpieler *s );
+	void render( int xOff, int yOff, Bild &zRObj );
+	// constant
+	int getHeight() const;
+	// Reference Counting
+	AHSLETeamListeTeam *getThis();
+	AHSLETeamListeTeam *release();
+};
+
+class AHSLETeamListe
+{
+private:
+	RCArray< AHSLETeamListeTeam > *members;
+	int xPos;
+	int ref;
+
+public:
+	// Konstruktor
+	AHSLETeamListe( int xPos );
+	// Destruktor
+	~AHSLETeamListe();
+	// nicht constant
+	void addTeam( AHSLETeamListeTeam  *t );
+	void render( Bild &zRObj );
+	// constant
+	int getHeight() const;
+	int getBreite() const;
+	// Reference Counting
+	AHSLETeamListe *getThis();
+	AHSLETeamListe *release();
+};
+
+class AHSpielListeEintrag
+{
+private:
+	TextFeld *spielTF;
+	TextFeld *karteTF;
+	TextFeld *datumTF;
+	TextFeld *statusTF;
+	Text *spiel;
+	Text *karte;
+	Text *datum;
+	Text *status;
+	Knopf *detailsK;
+	TextFeld *dauerTF;
+	TextFeld *spielStatusTF;
+	TextFeld *gewinnerTF;
+	TextFeld *sAnzahlTF;
+	Knopf *statistikK;
+	Knopf *videoK;
+	AHSLETeamListe *liste;
+	LRahmen *ram;
+	Bild *einklappen;
+	Bild *ausklappen;
+	int karteId;
+	int id;
+	double tickVal;
+	int aktion;
+	int maxHö;
+	int ref;
+
+public:
+	// Konstruktor
+	AHSpielListeEintrag( int id, int karteId, Schrift *zSchrift, char *spiel, char *karte, char *datum, char *status, 
+						 char *dauer, char *spielStatus, char *gewinner, int sAnzahl );
+	// Destruktor
+	~AHSpielListeEintrag();
+	// nicht constant
+	void addTeam( AHSLETeamListeTeam *t );
+	bool tick( double tickVal );
+	void doMausEreignis( MausEreignis &me );
+	void render( int yOff, Bild &zRObj );
+	int getAktion();
+	// constant
+	int getKarteId() const;
+	int getHeight() const;
+	int getId() const;
+	int getListeBreite() const;
+	Text *zSpiel() const;
+	Text *zKarte() const;
+	Text *zDatum() const;
+	Text *zStatus() const;
+	// Reference Counting
+	AHSpielListeEintrag *getThis();
+	AHSpielListeEintrag *release();
+};
+
+class AHSpielListe : public Zeichnung
+{
+private:
+	LRahmen *ram;
+	VScrollBar *scroll;
+	RCArray< AHSpielListeEintrag > *members;
+	Text *sortSpalte;
+	bool sortAbsteigend;
+	int ref;
+
+	// privat
+	int getReihenfolge( int *arr );
+
+public:
+	// Konstruktor
+	AHSpielListe();
+	// Destruktor
+	~AHSpielListe();
+	// nicht constant
+	void setSortSpalte( char *sp );
+	void setSortRichtung( bool absteigend );
+	void reset();
+	void addSpiel( AHSpielListeEintrag *s );
+	bool tick( double tickVal ) override;
+	void doMausEreignis( MausEreignis &me ) override;
+	void render( Bild &zRObj ) override;
+	// constant
+	int getAktion( int *spielId, int *karteId ) const;
+	// Reference Counting
+	AHSpielListe *getThis();
+	AHSpielListe *release();
+};
+
+class AccountHistorie : public Thread
+{
+private:
+	Schrift *schrift;
+	Fenster *historieF;
+	AuswahlBox *sortSpalte;
+	AuswahlBox *sortRichtung;
+	AHSpielListe *liste;
+	AHSpielStatistik *statistik;
+	AHSpielVideo *video;
+	int status;
+	int accId;
+	int animation;
+	unsigned char alpha;
+	unsigned char alpha2;
+	unsigned char alpha3;
+	double tickVal;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	AccountHistorie( Schrift *zSchrift );
+	// Destruktor
+	~AccountHistorie();
+	// nicht constant
+	void reset();
+	void ladeStatistik( int accId );
+	virtual void thread();
+	void setSichtbar( bool sichtbar, bool nachRechts );
+	bool tick( double zeit );
+	void doMausEreignis( MausEreignis &me );
+	void doTastaturEreignis( TastaturEreignis &te );
+	void render( Bild &zRObj );
+	// constant
+	int getStatus() const;
+	// Reference Counting
+	AccountHistorie *getThis();
+	AccountHistorie *release();
+};
+
+#endif

+ 140 - 0
KSGClient/NachLogin/Account/Historie/AccountHistorieDaten.cpp

@@ -0,0 +1,140 @@
+#include "AccountHistorieDaten.h"
+
+// Inhalt der AHSpielSpielerDaten Struktur aus AccountHistorieDaten.h
+// Konstruktor
+AHSpielSpielerDaten::AHSpielSpielerDaten()
+: name( new Text() ),
+  status( new Text() ),
+  ref( 1 )
+{
+}
+
+// Destruktor
+AHSpielSpielerDaten::~AHSpielSpielerDaten()
+{
+	name->release();
+	status->release();
+}
+
+// Reference Counting
+AHSpielSpielerDaten *AHSpielSpielerDaten::getThis()
+{
+	ref++;
+	return this;
+}
+
+AHSpielSpielerDaten *AHSpielSpielerDaten::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der AHSpielTeamDaten Struktur aus AccountHistorieDaten.h
+// Konstruktor
+AHSpielTeamDaten::AHSpielTeamDaten()
+: name( new Text() ),
+  status( new Text() ),
+  spieler( new RCArray< AHSpielSpielerDaten >() ),
+  ref( 1 )
+{
+}
+
+// Destruktor
+AHSpielTeamDaten::~AHSpielTeamDaten()
+{
+	name->release();
+	status->release();
+	spieler->release();
+}
+
+// Reference Counting
+AHSpielTeamDaten *AHSpielTeamDaten::getThis()
+{
+	ref++;
+	return this;
+}
+
+AHSpielTeamDaten *AHSpielTeamDaten::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der AHSpielDaten Struktur aus AccountHistorieDaten.h
+// Konstruktor
+AHSpielDaten::AHSpielDaten()
+: spiel( new Text() ),
+  karte( new Text() ),
+  datum( new Text() ),
+  status( new Text() ),
+  dauer( new Text() ),
+  spielStatus( new Text() ),
+  gewinner( new Text() ),
+  teams( new RCArray< AHSpielTeamDaten >() ),
+  ref( 1 )
+{
+}
+
+// Destruktor
+AHSpielDaten::~AHSpielDaten()
+{
+	spiel->release();
+	karte->release();
+	datum->release();
+	status->release();
+	dauer->release();
+	spielStatus->release();
+	gewinner->release();
+	teams->release();
+}
+
+// Reference Counting
+AHSpielDaten *AHSpielDaten::getThis()
+{
+	ref++;
+	return this;
+}
+
+AHSpielDaten *AHSpielDaten::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der AHDaten Struktur aus AccountHistorieDaten.h
+// Konstruktor
+AHDaten::AHDaten()
+: spiele( new RCArray< AHSpielDaten >() ),
+  ref( 1 )
+{
+}
+
+// Destruktor
+AHDaten::~AHDaten()
+{
+	spiele->release();
+}
+
+// Reference Counting
+AHDaten *AHDaten::getThis()
+{
+	ref++;
+	return this;
+}
+
+AHDaten *AHDaten::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 82 - 0
KSGClient/NachLogin/Account/Historie/AccountHistorieDaten.h

@@ -0,0 +1,82 @@
+#ifndef AccountHistorieDaten_H
+#define AccountHistorieDaten_H
+
+#include <Array.h>
+#include <Text.h>
+
+using namespace Framework;
+
+struct AHSpielSpielerDaten
+{
+	Text *name;
+	int punkte;
+	Text *status;
+	int farbe;
+	int ref;
+
+	// Konstruktor
+	AHSpielSpielerDaten();
+	// Destruktor
+	~AHSpielSpielerDaten();
+	// Reference Counting
+	AHSpielSpielerDaten *getThis();
+	AHSpielSpielerDaten *release();
+};
+
+struct AHSpielTeamDaten
+{
+	Text *name;
+	int sAnzahl;
+	Text *status;
+	int farbe;
+	RCArray< AHSpielSpielerDaten > *spieler;
+	int ref;
+
+	// Konstruktor
+	AHSpielTeamDaten();
+	// Destruktor
+	~AHSpielTeamDaten();
+	// Reference Counting
+	AHSpielTeamDaten *getThis();
+	AHSpielTeamDaten *release();
+};
+
+struct AHSpielDaten
+{
+	int id;
+	int karteId;
+	Text *spiel;
+	Text *karte;
+	Text *datum;
+	Text *status;
+	Text *dauer;
+	Text *spielStatus;
+	Text *gewinner;
+	int sAnzahl;
+	RCArray< AHSpielTeamDaten > *teams;
+	int ref;
+
+	// Konstruktor
+	AHSpielDaten();
+	// Destruktor
+	~AHSpielDaten();
+	// Reference Counting
+	AHSpielDaten *getThis();
+	AHSpielDaten *release();
+};
+
+struct AHDaten
+{
+	RCArray< AHSpielDaten > *spiele;
+	int ref;
+
+	// Konstruktor
+	AHDaten();
+	// Destruktor
+	~AHDaten();
+	// Reference Counting
+	AHDaten *getThis();
+	AHDaten *release();
+};
+
+#endif

+ 1126 - 0
KSGClient/NachLogin/Account/SpielPartner/AccountSpielPartner.cpp

@@ -0,0 +1,1126 @@
+#include "AccountSpielPartner.h"
+#include "../../../Global/Initialisierung.h"
+#include "../../../Global/Variablen.h"
+#include <Rahmen.h>
+#include <DateiSystem.h>
+#include <ToolTip.h>
+#include <Punkt.h>
+
+#define HATSTYLE( b )  ( daten->style | (b) ) == daten->style
+
+// Inhalt der AccountSPListeEintrag Klasse aus AccountSpielPartner.h
+// Konstruktor
+AccountSPListeEintrag::AccountSPListeEintrag( AccountSPListeEintragDaten *daten, Schrift *zSchrift )
+	: daten( daten ),
+  ram( new LRahmen() ),
+  members( new RCArray< AccountSPListeEintrag >() ),
+  name( initTextFeld( 5, 0, 100, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Name" ) ),
+  anzahl( initTextFeld( 110, 0, 100, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Spiele: " ) ),
+  prozent( initFBalken( 220, 0, 400, 20, zSchrift, FBalken::Style::normal ) ),
+  details( initKnopf( 580, 0, 20, 20, 0, 0, "" ) ),
+  ausklappen( bilder->get( "account.ltdb/ausklappen.png" ) ),
+  einklappen( bilder->get( "account.ltdb/einklappen.png" ) ),
+  sortSpalte( new Text( "Name" ) ),
+  sortAbsteigend( 0 ),
+  tickVal( 0 ),
+  rend( 0 ),
+  ref( 1 )
+{
+	if( !einklappen )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/account.ltdb" ) );
+		datei->leseDaten( 0 );
+		einklappen = datei->laden( 0, new Text( "einklappen.png" ) );
+		datei->release();
+		bilder->add( "account.ltdb/einklappen.png", einklappen->getThis() );
+	}
+	if( !ausklappen )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/account.ltdb" ) );
+		datei->leseDaten( 0 );
+		ausklappen = datei->laden( 0, new Text( "ausklappen.png" ) );
+		datei->release();
+		bilder->add( "account.ltdb/ausklappen.png", ausklappen->getThis() );
+	}
+	details->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	details->setHintergrundBildZ( ausklappen->getThis() );
+	initToolTip( details, "Details anzeigen.", zSchrift->getThis(), hauptScreen );
+	ram->setFarbe( 0xFFFFFFFF );
+	ram->setRamenBreite( 1 );
+	ram->setSize( 0, 20 );
+	if( daten->name )
+		name->setText( daten->name->getText() );
+	anzahl->zText()->append( daten->anzahl );
+	zSchrift->lock();
+	zSchrift->setSchriftSize( 12 );
+	name->setSize( zSchrift->getTextBreite( name->zText() ) + 5, name->getHeight() );
+	anzahl->setPosition( ( name->getX() + name->getBreite() + 10 ) < 100 ? 100 : ( name->getX() + name->getBreite() + 10 ), anzahl->getY() );
+	anzahl->setSize( zSchrift->getTextBreite( anzahl->zText() ) + 5, anzahl->getHeight() );
+	zSchrift->unlock();
+	prozent->setPosition( ( anzahl->getX() + anzahl->getBreite() + 10 ) < 200 ? 200 : ( anzahl->getX() + anzahl->getBreite() + 10 ), prozent->getY() );
+	prozent->setAktionAnzahl( 100 );
+	prozent->aktionPlus( daten->prozent );
+}
+
+// Destruktor
+AccountSPListeEintrag::~AccountSPListeEintrag()
+{
+	ram->release();
+	members->release();
+	name->release();
+	anzahl->release();
+	prozent->release();
+	details->release();
+	ausklappen->release();
+	einklappen->release();
+	sortSpalte->release();
+	daten->name->release();
+	delete daten;
+}
+
+// privat
+int AccountSPListeEintrag::getReihenfolge( int *arr )
+{
+	int anz = members->getEintragAnzahl();
+	if( !anz || !HATSTYLE( ASPLEDStyle::Ausklappbar ) )
+		return 0;
+	int ret = 0;
+	bool *fertig = new bool[ anz ];
+	ZeroMemory( fertig, anz );
+	for( int i = 0; i < anz; i++ )
+	{
+		int index = -1;
+		int minMax = 0;
+		Text minMaxT;
+		for( int j = 0; j < anz; j++ )
+		{
+			AccountSPListeEintrag *tmp = members->z( j );
+			if( sortSpalte->istGleich( "Name" ) && !fertig[ j ] && ( index < 0 ||
+				( sortAbsteigend && *tmp->zDaten()->name > minMaxT ) || ( !sortAbsteigend && *tmp->zDaten()->name < minMaxT ) ) )
+			{
+				minMaxT = tmp->zDaten()->name->getText();
+				index = j;
+			}
+			else if( sortSpalte->istGleich( "Spiele" ) && !fertig[ j ] && ( index < 0 ||
+				( sortAbsteigend && tmp->zDaten()->anzahl > minMax ) || ( !sortAbsteigend && tmp->zDaten()->anzahl < minMax ) ) )
+			{
+				minMax = tmp->zDaten()->anzahl;
+				index = j;
+			}
+			else if( sortSpalte->istGleich( "Prozent" ) && !fertig[ j ] && ( index < 0 ||
+				( sortAbsteigend && tmp->zDaten()->prozent > minMax ) || ( !sortAbsteigend && tmp->zDaten()->prozent < minMax ) ) )
+			{
+				minMax = tmp->zDaten()->prozent;
+				index = j;
+			}
+		}
+		if( index < 0 )
+			break;
+		fertig[ index ] = 1;
+		arr[ ret ] = index;
+		ret++;
+	}
+	delete[] fertig;
+	return ret;
+}
+
+// nicht constant
+void AccountSPListeEintrag::addMember( AccountSPListeEintrag *e )
+{
+	members->add( e );
+	rend = 1;
+}
+
+void AccountSPListeEintrag::setSortSpalte( char *sp )
+{
+	sortSpalte->setText( sp );
+	if( HATSTYLE( ASPLEDStyle::Ausklappbar ) )
+	{
+		int anz = members->getEintragAnzahl();
+		for( int i = 0; i < anz; i++ )
+			members->z( i )->setSortSpalte( sp );
+	}
+	rend = 1;
+}
+
+void AccountSPListeEintrag::setSortRichtung( bool absteigend )
+{
+	sortAbsteigend = absteigend;
+	if( HATSTYLE( ASPLEDStyle::Ausklappbar ) )
+	{
+		int anz = members->getEintragAnzahl();
+		for( int i = 0; i < anz; i++ )
+			members->z( i )->setSortRichtung( absteigend );
+	}
+	rend = 1;
+}
+
+bool AccountSPListeEintrag::tick( double tickVal )
+{
+	rend |= details->tick( tickVal );
+	int anz = members->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+		rend |= members->z( i )->tick( tickVal );
+	this->tickVal += tickVal * 150;
+	int val = ( int )this->tickVal;
+	this->tickVal -= val;
+	if( val )
+	{
+		if( details->zHintergrundBild() == ausklappen && ram->getHeight() != 20 )
+		{
+			if( ram->getHeight() - val < 20 )
+				ram->setSize( ram->getBreite(), 20 );
+			else
+				ram->setSize( ram->getBreite(), ram->getHeight() - val );
+			rend = 1;
+		}
+		if( details->zHintergrundBild() == einklappen )
+		{
+			int maxHö = 20;
+			for( int i = 0; i < anz; i++ )
+				maxHö += 5 + members->z( i )->getHeight();
+			if( maxHö > 20 )
+				maxHö += 5;
+			if( ram->getHeight() > maxHö )
+			{
+				if( ram->getHeight() - val < maxHö )
+					ram->setSize( ram->getBreite(), maxHö );
+				else
+					ram->setSize( ram->getBreite(), ram->getHeight() - val );
+				rend = 1;
+			}
+			if( ram->getHeight() < maxHö )
+			{
+				if( ram->getHeight() + val > maxHö )
+					ram->setSize( ram->getBreite(), maxHö );
+				else
+					ram->setSize( ram->getBreite(), ram->getHeight() + val );
+				rend = 1;
+			}
+		}
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void AccountSPListeEintrag::doMausEreignis( MausEreignis &me )
+{
+	int mx = me.mx;
+	int my = me.my;
+	bool vera = 0;
+	if( me.mx < 0 || me.my < 0 || me.mx > ram->getBreite() || me.my > ram->getHeight() )
+	{
+		vera = 1;
+		me.verarbeitet = 1;
+	}
+	if( HATSTYLE( ASPLEDStyle::Ausklappbar ) )
+	{
+		bool ok = me.verarbeitet;
+		details->doMausEreignis( me );
+		if( !ok && me.verarbeitet && me.id == ME_RLinks )
+		{
+			if( details->zHintergrundBild() == ausklappen )
+			{
+				details->setHintergrundBildZ( einklappen->getThis() );
+				details->zToolTip()->setText( "Karten verbergen." );
+			}
+			else
+			{
+				details->setHintergrundBildZ( ausklappen->getThis() );
+				details->zToolTip()->setText( "Karten anzeigen." );
+			}
+		}
+	}
+	if( ram->getHeight() > 20 )
+	{
+		int anz = members->getEintragAnzahl();
+		int *rf = new int[ anz ];
+		int rfAnz = getReihenfolge( rf );
+		me.my -= 25;
+		for( int i = 0; i < rfAnz; i++ )
+		{
+			members->z( rf[ i ] )->doMausEreignis( me );
+			me.my -= members->z( rf[ i ] )->getHeight() + 5;
+		}
+		delete[] rf;
+	}
+	me.mx = mx;
+	me.my = my;
+	if( vera )
+		me.verarbeitet = 0;
+}
+
+void AccountSPListeEintrag::render( int xOff, int yOff, int breite, Bild &zRObj )
+{
+	ram->setSize( breite, ram->getHeight() );
+	details->setPosition( ram->getBreite() - 20, details->getY() );
+	if( !zRObj.setDrawOptions( xOff, yOff, breite, ram->getHeight() ) )
+		return;
+	name->render( zRObj );
+	anzahl->render( zRObj );
+	prozent->render( zRObj );
+	if( HATSTYLE( ASPLEDStyle::Ausklappbar ) )
+		details->render( zRObj );
+	ram->render( zRObj );
+	if( ram->getHeight() > 20 )
+	{
+		zRObj.drawLinieH( 0, 20, ram->getBreite(), ram->getFarbe() );
+		int anz = members->getEintragAnzahl();
+		int *rf = new int[ anz ];
+		int rfAnz = getReihenfolge( rf );
+		yOff = 0;
+		for( int i = 0; i < rfAnz; i++ )
+		{
+			members->z( rf[ i ] )->render( 5, yOff + 25, breite - 10, zRObj );
+			yOff += 5 + members->z( rf[ i ] )->getHeight();
+		}
+		delete[] rf;
+	}
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+int AccountSPListeEintrag::getHeight() const
+{
+	return ram->getHeight();
+}
+
+AccountSPListeEintragDaten *AccountSPListeEintrag::zDaten() const
+{
+	return daten;
+}
+
+// Reference Counting
+AccountSPListeEintrag *AccountSPListeEintrag::getThis()
+{
+	ref++;
+	return this;
+}
+
+AccountSPListeEintrag *AccountSPListeEintrag::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der AccountSPListe Klasse aus AccountSpielPartner.h
+// Konstruktor
+AccountSPListe::AccountSPListe( Schrift *zSchrift )
+	: Zeichnung(),
+  schrift( zSchrift->getThis() ),
+  ram( new LRahmen() ),
+  scroll( new VScrollBar() ),
+  skp( new RCArray< AccountSPListeEintrag >() ),
+  spk( new RCArray< AccountSPListeEintrag >() ),
+  psk( new RCArray< AccountSPListeEintrag >() ),
+  gruppierung( new Text( "Spieler/Spiel/Karte" ) ),
+  sortSpalte( new Text( "Name" ) ),
+  sortAbsteigend( 0 ),
+  rend( 0 ),
+  ref( 1 )
+{
+	pos = Punkt( 10, 40 );
+	ram->setSize( 760, 380 );
+	ram->setFarbe( 0xFFFFFFFF );
+	ram->setRamenBreite( 1 );
+}
+
+// Destruktor
+AccountSPListe::~AccountSPListe()
+{
+	schrift->release();
+	ram->release();
+	scroll->release();
+	skp->release();
+	spk->release();
+	psk->release();
+	gruppierung->release();
+	sortSpalte->release();
+}
+
+// privat
+int AccountSPListe::getReihenfolge( int *arr )
+{
+	RCArray< AccountSPListeEintrag > *members = 0;
+	if( gruppierung->istGleich( "Spiel/Karte/Spieler" ) )
+		members = skp;
+	if( gruppierung->istGleich( "Spiel/Spieler/Karte" ) )
+		members = spk;
+	if( gruppierung->istGleich( "Spieler/Spiel/Karte" ) )
+		members = psk;
+	int anz = members->getEintragAnzahl();
+	if( !anz )
+		return 0;
+	int ret = 0;
+	bool *fertig = new bool[ anz ];
+	ZeroMemory( fertig, anz );
+	for( int i = 0; i < anz; i++ )
+	{
+		int index = -1;
+		int minMax = 0;
+		Text minMaxT;
+		for( int j = 0; j < anz; j++ )
+		{
+			AccountSPListeEintrag *tmp = members->z( j );
+			if( sortSpalte->istGleich( "Name" ) && !fertig[ j ] && ( index < 0 ||
+				( sortAbsteigend && *tmp->zDaten()->name > minMaxT ) || ( !sortAbsteigend && *tmp->zDaten()->name < minMaxT ) ) )
+			{
+				minMaxT = tmp->zDaten()->name->getText();
+				index = j;
+			}
+			else if( sortSpalte->istGleich( "Spiele" ) && !fertig[ j ] && ( index < 0 ||
+				( sortAbsteigend && tmp->zDaten()->anzahl > minMax ) || ( !sortAbsteigend && tmp->zDaten()->anzahl < minMax ) ) )
+			{
+				minMax = tmp->zDaten()->anzahl;
+				index = j;
+			}
+			else if( sortSpalte->istGleich( "Prozent" ) && !fertig[ j ] && ( index < 0 ||
+				( sortAbsteigend && tmp->zDaten()->prozent > minMax ) || ( !sortAbsteigend && tmp->zDaten()->prozent < minMax ) ) )
+			{
+				minMax = tmp->zDaten()->prozent;
+				index = j;
+			}
+		}
+		if( index < 0 )
+			break;
+		fertig[ index ] = 1;
+		arr[ ret ] = index;
+		ret++;
+	}
+	delete[] fertig;
+	return ret;
+}
+
+// nicht constant
+void AccountSPListe::reset()
+{
+	lockZeichnung();
+	skp->leeren();
+	spk->leeren();
+	psk->leeren();
+	unlockZeichnung();
+}
+
+void AccountSPListe::ladeDaten( int accId )
+{
+	Array< int > *spieler = new Array< int >();
+	Array< int > *karten = new Array< int >();
+	Array< int > *anzahl = new Array< int >();
+	if( infoKlient->getSpielPartnerListe( accId, spieler, karten, anzahl ) )
+	{
+		int anz = spieler->getEintragAnzahl();
+		int spielerAnzahl = 0;
+		int spielArtAnzahl = 0;
+		int anzahlGesammt = 0;
+		Array< int > *spielerUnique = new Array< int >();
+		Array< int > *spielArt = new Array< int >();
+		for( int i = 0; i < anz; i++ )
+		{ // Spiel Art Ids ermitteln
+			anzahlGesammt += anzahl->get( i );
+			if( spieler->hat( i ) && spielerUnique->getWertIndex( spieler->get( i ) ) < 0 )
+			{
+				spielerUnique->set( spieler->get( i ), spielerAnzahl );
+				spielerAnzahl++;
+			}
+			if( !spielArt->hat( i ) )
+			{
+				spielArtAnzahl++;
+				int id = infoKlient->getSpielId( karten->get( i ) );
+				for( int j = i; j < anz; j++ )
+				{
+					if( karten->get( j ) == karten->get( i ) )
+						spielArt->set( id, j );
+				}
+			}
+		}
+		spielerUnique->release();
+		// Spiel/Karte/Spieler Tabelle initialisieren
+		Array< int > *spielArtVera = new Array< int >();
+		for( int i = 0; i < spielArtAnzahl; i++ )
+		{ // Spiel Arten Einträge
+			int id = 0;
+			for( int j = 0; j < anz; j++ )
+			{
+				if( spielArtVera->getWertIndex( spielArt->get( j ) ) < 0 )
+				{
+					id = spielArt->get( j );
+					spielArtVera->add( id );
+					break;
+				}
+			}
+			if( !id )
+				break;
+			AccountSPListeEintragDaten *tmp = new AccountSPListeEintragDaten();
+			tmp->id = id;
+			tmp->name = infoKlient->getSpielName( tmp->id );
+			tmp->style = ASPLEDStyle::SpielArt | ASPLEDStyle::Ausklappbar;
+			tmp->anzahl = 0;
+			for( int j = 0; j < anz; j++ )
+			{
+				if( spielArt->get( j ) == tmp->id )
+					tmp->anzahl += anzahl->get( j );
+			}
+			tmp->prozent = tmp->anzahl * 100 / anzahlGesammt;
+			AccountSPListeEintrag *spielE = new AccountSPListeEintrag( tmp, schrift );
+			skp->add( spielE );
+			Array< int > *kartenVera = new Array< int >();
+			for( int j = 0; j < anz; j++ )
+			{ // Karten Einträge
+				int id = 0;
+				for( int k = 0; k < anz; k++ )
+				{
+					if( spielArt->get( k ) == tmp->id )
+					{
+						if( kartenVera->getWertIndex( karten->get( k ) ) < 0 )
+						{
+							id = karten->get( k );
+							kartenVera->add( id );
+							break;
+						}
+					}
+				}
+				if( !id )
+					break;
+				AccountSPListeEintragDaten *tmpk = new AccountSPListeEintragDaten();
+				tmpk->id = id;
+				tmpk->name = infoKlient->getKarteName( tmpk->id );
+				tmpk->style = ASPLEDStyle::Ausklappbar | ASPLEDStyle::Karte;
+				tmpk->anzahl = 0;
+				for( int k = 0; k < anz; k++ )
+				{
+					if( karten->get( k ) == tmpk->id )
+						tmpk->anzahl += anzahl->get( k );
+				}
+				tmpk->prozent = tmpk->anzahl * 100 / tmp->anzahl;
+				AccountSPListeEintrag *karteE = new AccountSPListeEintrag( tmpk, schrift );
+				spielE->addMember( karteE );
+				Array< int > *spielerVera = new Array< int >();
+				for( int k = 0; k < anz; k++ )
+				{ // Spieler Einträge
+					int id = 0;
+					int gAnz = 0;
+					for( int l = 0; l < anz; l++ )
+					{
+						if( karten->get( l ) == tmpk->id )
+						{
+							if( spielerVera->getWertIndex( spieler->get( l ) ) < 0 )
+							{
+								id = spieler->get( l );
+								spielerVera->add( id );
+								gAnz = anzahl->get( l );
+								break;
+							}
+						}
+					}
+					if( !id )
+						break;
+					AccountSPListeEintragDaten *tmps = new AccountSPListeEintragDaten();
+					tmps->id = id;
+					tmps->name = infoKlient->getSpielerName( tmps->id );
+					tmps->style = ASPLEDStyle::Spieler;
+					tmps->anzahl = gAnz;
+					tmps->prozent = tmps->anzahl * 100 / tmpk->anzahl;
+					karteE->addMember( new AccountSPListeEintrag( tmps, schrift ) );
+				}
+				spielerVera->release();
+			}
+			kartenVera->release();
+		}
+		spielArtVera->leeren();
+		// Spiel/Spieler/Karte Tabelle initialisieren
+		for( int i = 0; i < spielArtAnzahl; i++ )
+		{ // Spiel Arten Einträge
+			int id = 0;
+			for( int j = 0; j < anz; j++ )
+			{
+				if( spielArtVera->getWertIndex( spielArt->get( j ) ) < 0 )
+				{
+					id = spielArt->get( j );
+					spielArtVera->add( id );
+					break;
+				}
+			}
+			if( !id )
+				break;
+			AccountSPListeEintragDaten *tmp = new AccountSPListeEintragDaten();
+			tmp->id = id;
+			tmp->name = infoKlient->getSpielName( tmp->id );
+			tmp->style = ASPLEDStyle::SpielArt | ASPLEDStyle::Ausklappbar;
+			tmp->anzahl = 0;
+			for( int j = 0; j < anz; j++ )
+			{
+				if( spielArt->get( j ) == tmp->id )
+					tmp->anzahl += anzahl->get( j );
+			}
+			tmp->prozent = tmp->anzahl * 100 / anzahlGesammt;
+			AccountSPListeEintrag *spielE = new AccountSPListeEintrag( tmp, schrift );
+			spk->add( spielE );
+			Array< int > *spielerVera = new Array< int >();
+			for( int j = 0; j < anz; j++ )
+			{ // Spieler Einträge
+				int id = 0;
+				for( int k = 0; k < anz; k++ )
+				{
+					if( spielArt->get( k ) == tmp->id )
+					{
+						if( spielerVera->getWertIndex( spieler->get( k ) ) < 0 )
+						{
+							id = spieler->get( k );
+							spielerVera->add( id );
+							break;
+						}
+					}
+				}
+				if( !id )
+					break;
+				AccountSPListeEintragDaten *tmps = new AccountSPListeEintragDaten();
+				tmps->id = id;
+				tmps->name = infoKlient->getSpielerName( tmps->id );
+				tmps->style = ASPLEDStyle::Ausklappbar | ASPLEDStyle::Spieler;
+				tmps->anzahl = 0;
+				for( int k = 0; k < anz; k++ )
+				{
+					if( spieler->get( k ) == tmps->id && spielArt->get( k ) == tmp->id )
+						tmps->anzahl += anzahl->get( k );
+				}
+				tmps->prozent = tmps->anzahl * 100 / tmp->anzahl;
+				AccountSPListeEintrag *spielerE = new AccountSPListeEintrag( tmps, schrift );
+				spielE->addMember( spielerE );
+				Array< int > *karteVera = new Array< int >();
+				for( int k = 0; k < anz; k++ )
+				{ // Karten Einträge
+					int id = 0;
+					int gAnz = 0;
+					for( int l = 0; l < anz; l++ )
+					{
+						if( spieler->get( l ) == tmps->id && spielArt->get( l ) == tmp->id )
+						{
+							if( karteVera->getWertIndex( karten->get( l ) ) < 0 )
+							{
+								id = karten->get( l );
+								karteVera->add( id );
+								gAnz = anzahl->get( l );
+								break;
+							}
+						}
+					}
+					if( !id )
+						break;
+					AccountSPListeEintragDaten *tmpk = new AccountSPListeEintragDaten();
+					tmpk->id = id;
+					tmpk->name = infoKlient->getKarteName( tmpk->id );
+					tmpk->style = ASPLEDStyle::Karte;
+					tmpk->anzahl = gAnz;
+					tmpk->prozent = tmpk->anzahl * 100 / tmps->anzahl;
+					spielerE->addMember( new AccountSPListeEintrag( tmpk, schrift ) );
+				}
+				karteVera->release();
+			}
+			spielerVera->release();
+		}
+		spielArtVera->release();
+		// Spieler/Spiel/Karte Tabelle initialisieren
+		Array< int > *spielerVera = new Array< int >();
+		for( int i = 0; i < spielerAnzahl; i++ )
+		{ // Spieler Einträge
+			int id = 0;
+			for( int j = 0; j < anz; j++ )
+			{
+				if( spielerVera->getWertIndex( spieler->get( j ) ) < 0 )
+				{
+					id = spieler->get( j );
+					spielerVera->add( id );
+					break;
+				}
+			}
+			if( !id )
+				break;
+			AccountSPListeEintragDaten *tmp = new AccountSPListeEintragDaten();
+			tmp->id = id;
+			tmp->name = infoKlient->getSpielerName( tmp->id );
+			tmp->style = ASPLEDStyle::Spieler | ASPLEDStyle::Ausklappbar;
+			tmp->anzahl = 0;
+			for( int j = 0; j < anz; j++ )
+			{
+				if( spieler->get( j ) == tmp->id )
+					tmp->anzahl += anzahl->get( j );
+			}
+			tmp->prozent = tmp->anzahl * 100 / anzahlGesammt;
+			AccountSPListeEintrag *spielerE = new AccountSPListeEintrag( tmp, schrift );
+			psk->add( spielerE );
+			Array< int > *spielVera = new Array< int >();
+			for( int j = 0; j < anz; j++ )
+			{ // Spiel Einträge
+				int id = 0;
+				for( int k = 0; k < anz; k++ )
+				{
+					if( spieler->get( k ) == tmp->id )
+					{
+						if( spielVera->getWertIndex( spielArt->get( k ) ) < 0 )
+						{
+							id = spielArt->get( k );
+							spielVera->add( id );
+							break;
+						}
+					}
+				}
+				if( !id )
+					break;
+				AccountSPListeEintragDaten *tmps = new AccountSPListeEintragDaten();
+				tmps->id = id;
+				tmps->name = infoKlient->getSpielName( tmps->id );
+				tmps->style = ASPLEDStyle::Ausklappbar | ASPLEDStyle::SpielArt;
+				tmps->anzahl = 0;
+				for( int k = 0; k < anz; k++ )
+				{
+					if( spieler->get( k ) == tmp->id && spielArt->get( k ) == tmps->id )
+						tmps->anzahl += anzahl->get( k );
+				}
+				tmps->prozent = tmps->anzahl * 100 / tmp->anzahl;
+				AccountSPListeEintrag *spielE = new AccountSPListeEintrag( tmps, schrift );
+				spielerE->addMember( spielE );
+				Array< int > *karteVera = new Array< int >();
+				for( int k = 0; k < anz; k++ )
+				{ // Karte Einträge
+					int id = 0;
+					int gAnz = 0;
+					for( int l = 0; l < anz; l++ )
+					{
+						if( spieler->get( l ) == tmp->id && spielArt->get( l ) == tmps->id )
+						{
+							if( karteVera->getWertIndex( karten->get( l ) ) < 0 )
+							{
+								id = karten->get( l );
+								karteVera->add( id );
+								gAnz = anzahl->get( l );
+								break;
+							}
+						}
+					}
+					if( !id )
+						break;
+					AccountSPListeEintragDaten *tmpk = new AccountSPListeEintragDaten();
+					tmpk->id = id;
+					tmpk->name = infoKlient->getKarteName( tmpk->id );
+					tmpk->style = ASPLEDStyle::Karte;
+					tmpk->anzahl = gAnz;
+					tmpk->prozent = tmpk->anzahl * 100 / tmps->anzahl;
+					spielE->addMember( new AccountSPListeEintrag( tmpk, schrift ) );
+				}
+				karteVera->release();
+			}
+			spielVera->release();
+		}
+		spielerVera->release();
+		spielArt->release();
+	}
+	else
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Die Spielpartner dieses Spielers konnten nicht ermittelt werden." ), new Text( "Ok" ) );
+	spieler->release();
+	karten->release();
+	anzahl->release();
+}
+
+void AccountSPListe::setGruppierung( char *gp )
+{
+	lockZeichnung();
+	gruppierung->setText( gp );
+	rend = 1;
+	unlockZeichnung();
+}
+
+void AccountSPListe::setSortSpalte( char *sp )
+{
+	lockZeichnung();
+	sortSpalte->setText( sp );
+	int anz = skp->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+		skp->z( i )->setSortSpalte( sp );
+	anz = spk->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+		spk->z( i )->setSortSpalte( sp );
+	anz = psk->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+		psk->z( i )->setSortSpalte( sp );
+	rend = 1;
+	unlockZeichnung();
+}
+
+void AccountSPListe::setSortRichtung( bool absteigend )
+{
+	lockZeichnung();
+	sortAbsteigend = absteigend;
+	int anz = skp->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+		skp->z( i )->setSortRichtung( absteigend );
+	anz = spk->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+		spk->z( i )->setSortRichtung( absteigend );
+	anz = psk->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+		psk->z( i )->setSortRichtung( absteigend );
+	rend = 1;
+	unlockZeichnung();
+}
+
+bool AccountSPListe::tick( double tickVal )
+{
+	lockZeichnung();
+	RCArray< AccountSPListeEintrag > *members = 0;
+	if( gruppierung->istGleich( "Spiel/Karte/Spieler" ) )
+		members = skp;
+	if( gruppierung->istGleich( "Spiel/Spieler/Karte" ) )
+		members = spk;
+	if( gruppierung->istGleich( "Spieler/Spiel/Karte" ) )
+		members = psk;
+	int anz = members->getEintragAnzahl();
+	int *rf = new int[ anz ];
+	int rfAnz = getReihenfolge( rf );
+	for( int i = 0; i < rfAnz; i++ )
+		rend |= members->z( rf[ i ] )->tick( tickVal );
+	delete[] rf;
+	unlockZeichnung();
+	rend |= scroll->getRend();
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void AccountSPListe::doMausEreignis( MausEreignis &me )
+{
+	bool vera = 0;
+	if( me.mx - pos.x <= 0 || me.mx - pos.x >= ram->getBreite() || me.my - pos.y <= 0 || me.my - pos.y >= ram->getHeight() )
+	{
+		vera = 1;
+		me.verarbeitet = 1;
+	}
+	int mx = me.mx, my = me.my;
+	me.mx -= pos.x;
+	me.my -= pos.y;
+	scroll->doMausMessage( ram->getBreite() - 16, 1, 15, ram->getHeight() - 2, me );
+	me.mx -= 10;
+	me.my -= 10 - scroll->getScroll();
+	lockZeichnung();
+	RCArray< AccountSPListeEintrag > *members = 0;
+	if( gruppierung->istGleich( "Spiel/Karte/Spieler" ) )
+		members = skp;
+	if( gruppierung->istGleich( "Spiel/Spieler/Karte" ) )
+		members = spk;
+	if( gruppierung->istGleich( "Spieler/Spiel/Karte" ) )
+		members = psk;
+	int anz = members->getEintragAnzahl();
+	int *rf = new int[ anz ];
+	int rfAnz = getReihenfolge( rf );
+	for( int i = 0; i < rfAnz; i++ )
+	{
+		members->z( rf[ i ] )->doMausEreignis( me );
+		me.my -= members->z( rf[ i ] )->getHeight() + 10;
+	}
+	delete[] rf;
+	unlockZeichnung();
+	me.mx = mx, me.my = my;
+	if( vera )
+		me.verarbeitet = 0;
+}
+
+void AccountSPListe::render( Bild &zRObj )
+{
+	if( !zRObj.setDrawOptions( pos, ram->getSize() ) )
+		return;
+	ram->render( zRObj );
+	scroll->render( ram->getBreite() - 16, 1, 15, ram->getHeight() - 2, zRObj );
+	if( !zRObj.setDrawOptions( 1, 1, ram->getBreite() - 15, ram->getHeight() - 2 ) )
+	{
+		zRObj.releaseDrawOptions();
+		return;
+	}
+	int anzHö = 10;
+	lockZeichnung();
+	RCArray< AccountSPListeEintrag > *members = 0;
+	if( gruppierung->istGleich( "Spiel/Karte/Spieler" ) )
+		members = skp;
+	if( gruppierung->istGleich( "Spiel/Spieler/Karte" ) )
+		members = spk;
+	if( gruppierung->istGleich( "Spieler/Spiel/Karte" ) )
+		members = psk;
+	int anz = members->getEintragAnzahl();
+	int *rf = new int[ anz ];
+	int rfAnz = getReihenfolge( rf );
+	for( int i = 0; i < rfAnz; i++ )
+	{
+		members->z( rf[ i ] )->render( 10, anzHö - scroll->getScroll(), ram->getBreite() - 36, zRObj );
+		anzHö += members->z( rf[ i ] )->getHeight() + 10;
+	}
+	delete[] rf;
+	unlockZeichnung();
+	scroll->update( anzHö, ram->getHeight() - 2 );
+	zRObj.releaseDrawOptions();
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+
+// Reference Counting
+AccountSPListe *AccountSPListe::getThis()
+{
+	ref++;
+	return this;
+}
+
+AccountSPListe *AccountSPListe::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der AccountSpielPartner Klasse aus AccountSpielPartner.h
+// Konstruktor
+AccountSpielPartner::AccountSpielPartner( Schrift *zSchrift )
+	: Thread(),
+  spielPartnerF( initFenster( 810, 40, 780, 450, zSchrift, Fenster::Style::Sichtbar | Fenster::Style::Titel | Fenster::Style::TitelBuffered | Fenster::Style::Rahmen | Fenster::Style::Erlaubt, "Spielpartner von " ) ),
+  gruppAusw( initAuswahlBox( 10, 10, 150, 20, zSchrift, ABSTYLE, { "Spieler/Spiel/Karte", "Spiel/Karte/Spieler", "Spiel/Spieler/Karte" } ) ),
+  sortSpalte( initAuswahlBox( 170, 10, 150, 20, zSchrift, ABSTYLE, { "Name", "Spiele", "Prozent" } ) ),
+  sortRichtung( initAuswahlBox( 330, 10, 150, 20, zSchrift, ABSTYLE, { "Aufwärts", "Abwärts" } ) ),
+  liste( new AccountSPListe( zSchrift ) ),
+  status( 0 ),
+  accId( 0 ),
+  animation( 0 ),
+  alpha( 255 ),
+  tickVal( 0 ),
+  rend( 0 ),
+  ref( 1 )
+{
+	initToolTip( gruppAusw, "Wähle Gruppierung aus, nach der die Daten angezeigt werden sollen.", zSchrift->getThis(), hauptScreen );
+	initToolTip( sortSpalte, "Wähle aus, nach welcher Spalte die\nTabelle sortiert werden soll.", zSchrift->getThis(), hauptScreen );
+	initToolTip( sortRichtung, "Wähle aus, Ob Aufwärts oder Abwärts sortiert werden soll.", zSchrift->getThis(), hauptScreen );
+	spielPartnerF->addMember( liste );
+	spielPartnerF->addMember( gruppAusw );
+	spielPartnerF->addMember( sortSpalte );
+	spielPartnerF->addMember( sortRichtung );
+	spielPartnerF->setMausEreignis( _ret1ME );
+}
+
+// Destruktor
+AccountSpielPartner::~AccountSpielPartner()
+{
+	spielPartnerF->release();
+	gruppAusw->release();
+	sortSpalte->release();
+	sortRichtung->release();
+	liste->release();
+}
+
+// nicht constant
+void AccountSpielPartner::reset()
+{
+	liste->reset();
+}
+
+void AccountSpielPartner::ladeStatistik( int accId )
+{
+	if( this->accId == accId )
+		return;
+	this->status = 0;
+	if( run )
+	{
+		warteAufThread( 1000 );
+		ende();
+	}
+	if( ( animation | 0x1 ) == animation )
+	{
+		animation |= 0x4;
+		this->accId = accId;
+		this->status = 1;
+		return;
+	}
+	if( this->accId )
+		reset();
+	this->accId = accId;
+	start();
+	this->status = 1;
+}
+
+void AccountSpielPartner::thread()
+{
+	Text *name = infoKlient->getSpielerName( accId );
+	if( name )
+	{
+		name->insert( 0, "Spielpartner von " );
+		spielPartnerF->setTitel( *name );
+		name->release();
+	}
+	liste->ladeDaten( accId );
+	animation &= ~0x4;
+	status = 2;
+	run = 0;
+}
+
+void AccountSpielPartner::setSichtbar( bool sichtbar, bool nachRechts )
+{
+	if( sichtbar )
+	{
+		if( ( animation | 0x1 ) != animation || ( ( nachRechts && ( animation | 0x2 ) != animation ) || !nachRechts && ( animation | 0x2 ) == animation ) )
+		{
+			if( nachRechts )
+				spielPartnerF->setPosition( -810, 40 );
+			else
+				spielPartnerF->setPosition( 810, 40 );
+		}
+		animation |= 0x1;
+	}
+	else
+		animation &= ~0x1;
+	if( nachRechts )
+		animation |= 0x2;
+	else
+		animation &= ~0x2;
+}
+
+bool AccountSpielPartner::tick( double zeit )
+{
+	rend |= spielPartnerF->tick( zeit );
+	tickVal += zeit;
+	int valA = (int)( tickVal * 150 );
+	int valB = (int)( tickVal * 500 );
+	tickVal -= valA / 150.0;
+	if( valA )
+	{
+		if( ( animation | 0x4 ) == animation && alpha )
+		{
+			if( alpha - valA <= 0 )
+				alpha = 0;
+			else
+				alpha -= valA;
+			rend = 1;
+			if( !alpha )
+			{
+				reset();
+				start();
+			}
+		}
+		if( ( animation | 0x4 ) != animation && alpha != 255 )
+		{
+			if( alpha + valA >= 255 )
+				alpha = 255;
+			else
+				alpha += valA;
+			rend = 1;
+		}
+	}
+	if( valB )
+	{
+		if( ( animation | 0x1 ) == animation )
+		{ // Sichtbar
+			if( ( animation | 0x2 ) == animation )
+			{ // Nach Rechts
+				if( spielPartnerF->getX() != 10 )
+				{
+					if( spielPartnerF->getX() + valB > 10 )
+						spielPartnerF->setPosition( 10, spielPartnerF->getY() );
+					else
+						spielPartnerF->setPosition( spielPartnerF->getX() + valB, spielPartnerF->getY() );
+					rend = 1;
+				}
+			}
+			else
+			{ // Nach Links
+				if( spielPartnerF->getX() != 10 )
+				{
+					if( spielPartnerF->getX() - valB < 10 )
+						spielPartnerF->setPosition( 10, spielPartnerF->getY() );
+					else
+						spielPartnerF->setPosition( spielPartnerF->getX() - valB, spielPartnerF->getY() );
+					rend = 1;
+				}
+			}
+		}
+		else
+		{ // Unsichtbar
+			if( ( animation | 0x2 ) == animation )
+			{ // Nach Rechts
+				if( spielPartnerF->getX() != 810 )
+				{
+					if( spielPartnerF->getX() + valB > 810 )
+						spielPartnerF->setPosition( 810, spielPartnerF->getY() );
+					else
+						spielPartnerF->setPosition( spielPartnerF->getX() + valB, spielPartnerF->getY() );
+					rend = 1;
+				}
+			}
+			else
+			{ // Nach Links
+				if( spielPartnerF->getX() != -810 )
+				{
+					if( spielPartnerF->getX() - valB < -810 )
+						spielPartnerF->setPosition( -810, spielPartnerF->getY() );
+					else
+						spielPartnerF->setPosition( spielPartnerF->getX() - valB, spielPartnerF->getY() );
+					rend = 1;
+				}
+			}
+		}
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void AccountSpielPartner::doMausEreignis( MausEreignis &me )
+{
+	int gruppAuswS = gruppAusw->getAuswahl();
+	int sortSpalteS = sortSpalte->getAuswahl();
+	int sortRichtungS = sortRichtung->getAuswahl();
+	spielPartnerF->doMausEreignis( me );
+	if( gruppAusw->getAuswahl() != gruppAuswS )
+	{
+		liste->setGruppierung( gruppAusw->zEintrag( gruppAusw->getAuswahl() )->zText()->getText() );
+		gruppAusw->einklappen();
+	}
+	if( sortSpalte->getAuswahl() != sortSpalteS )
+	{
+		liste->setSortSpalte( sortSpalte->zEintrag( sortSpalte->getAuswahl() )->zText()->getText() );
+		sortSpalte->einklappen();
+	}
+	if( sortRichtung->getAuswahl() != sortRichtungS )
+	{
+		liste->setSortRichtung( sortRichtung->getAuswahl() != 0 );
+		sortRichtung->einklappen();
+	}
+}
+
+void AccountSpielPartner::render( Bild &zRObj )
+{
+	zRObj.setAlpha( alpha );
+	spielPartnerF->render( zRObj );
+	zRObj.releaseAlpha();
+}
+
+// constant
+int AccountSpielPartner::getStatus() const
+{
+	return status;
+}
+
+// Reference Counting
+AccountSpielPartner *AccountSpielPartner::getThis()
+{
+	ref++;
+	return this;
+}
+
+AccountSpielPartner *AccountSpielPartner::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 145 - 0
KSGClient/NachLogin/Account/SpielPartner/AccountSpielPartner.h

@@ -0,0 +1,145 @@
+#ifndef AccountSpielPartner_H
+#define AccountSpielPartner_H
+
+#include <Fortschritt.h>
+#include <Fenster.h>
+#include <Knopf.h>
+#include <AuswahlBox.h>
+#include <Thread.h>
+
+using namespace Framework;
+
+namespace ASPLEDStyle
+{
+	const int SpielArt = 1;
+	const int Karte = 2;
+	const int Spieler = 4;
+	const int Ausklappbar = 8;
+}
+
+struct AccountSPListeEintragDaten
+{
+	int style;
+	int id;
+	Text *name;
+	int anzahl;
+	int prozent;
+};
+
+class AccountSPListeEintrag
+{
+private:
+	LRahmen *ram;
+	RCArray< AccountSPListeEintrag > *members;
+	TextFeld *name;
+	TextFeld *anzahl;
+	FBalken *prozent;
+	Knopf *details;
+	Bild *ausklappen;
+	Bild *einklappen;
+	AccountSPListeEintragDaten *daten;
+	Text *sortSpalte;
+	bool sortAbsteigend;
+	double tickVal;
+	bool rend;
+	int ref;
+
+	// privat
+	int getReihenfolge( int *arr );
+
+public:
+	// Konstruktor
+	AccountSPListeEintrag( AccountSPListeEintragDaten *daten, Schrift *zSchrift );
+	// Destruktor
+	~AccountSPListeEintrag();
+	// nicht constant
+	void addMember( AccountSPListeEintrag *e );
+	void setSortSpalte( char *sp );
+	void setSortRichtung( bool absteigend );
+	bool tick( double tickVal );
+	void doMausEreignis( MausEreignis &me );
+	void render( int xOff, int yOff, int breite, Bild &zRObj );
+	// constant
+	int getHeight() const;
+	AccountSPListeEintragDaten *zDaten() const;
+	// Reference Counting
+	AccountSPListeEintrag *getThis();
+	AccountSPListeEintrag *release();
+};
+
+class AccountSPListe : public Zeichnung
+{
+private:
+	Schrift *schrift;
+	LRahmen *ram;
+	VScrollBar *scroll;
+	RCArray< AccountSPListeEintrag > *skp;
+	RCArray< AccountSPListeEintrag > *spk;
+	RCArray< AccountSPListeEintrag > *psk;
+	Text *gruppierung;
+	Text *sortSpalte;
+	bool sortAbsteigend;
+	bool rend;
+	int ref;
+
+	// privat
+	int getReihenfolge( int *arr );
+
+public:
+	// Konstruktor
+	AccountSPListe( Schrift *zSchrift );
+	// Destruktor
+	~AccountSPListe();
+	// nicht constant
+	void reset();
+	void ladeDaten( int accId );
+	void setGruppierung( char *gp );
+	void setSortSpalte( char *sp );
+	void setSortRichtung( bool absteigend );
+	bool tick( double tickVal ) override;
+	void doMausEreignis( MausEreignis &me ) override;
+	void render( Bild &zRObj ) override;
+	// constant
+
+	// Reference Counting
+	AccountSPListe *getThis();
+	AccountSPListe *release();
+};
+
+class AccountSpielPartner : public Thread
+{
+private:
+	Fenster *spielPartnerF;
+	AuswahlBox *gruppAusw;
+	AuswahlBox *sortSpalte;
+	AuswahlBox *sortRichtung;
+	AccountSPListe *liste;
+	int status;
+	int accId;
+	int animation;
+	unsigned char alpha;
+	double tickVal;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	AccountSpielPartner( Schrift *zSchrift );
+	// Destruktor
+	~AccountSpielPartner();
+	// nicht constant
+	void reset();
+	void ladeStatistik( int accId );
+	virtual void thread();
+	void setSichtbar( bool sichtbar, bool nachRechts );
+	bool tick( double zeit );
+	void doMausEreignis( MausEreignis &me );
+	void render( Bild &zRObj );
+	// constant
+	int getStatus() const;
+	// Reference Counting
+	AccountSpielPartner *getThis();
+	AccountSpielPartner *release();
+};
+
+#endif;

+ 921 - 0
KSGClient/NachLogin/Account/Spiele_Karten/AccountSpieleUndKarten.cpp

@@ -0,0 +1,921 @@
+#include "AccountSpieleUndKarten.h"
+#include "../../../Global/Initialisierung.h"
+#include "../../../Global/Variablen.h"
+#include <Rahmen.h>
+#include <DateiSystem.h>
+#include <Punkt.h>
+#include <ToolTip.h>
+
+// Inhalt der AccountSUKListeKarte Klasse aus AccountSpieleUndKarten.h
+// Konstruktor
+AccountSUKListeKarte::AccountSUKListeKarte( Schrift *zSchrift, int id, int account )
+: ram( new LRahmen() ),
+  name( initTextFeld( 5, 0, 150, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Karte: " ) ),
+  spiele( initTextFeld( 165, 0, 150, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Spiele: " ) ),
+  gewonnen( initTextFeld( 325, 0, 150, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Gewonnen: " ) ),
+  status( initTextFeld( 485, 0, 150, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Status: " ) ),
+  st( new Text() ),
+  karteId( id ),
+  rend( 0 ),
+  ref( 1 )
+{
+	na = infoKlient->getKarteName( id );
+	if( na )
+		name->zText()->append( na->getText() );
+	sp = infoKlient->getAccountKarteSpiele( account, id );
+	spiele->zText()->append( sp );
+	gw = infoKlient->getAccountKarteSpieleGewonnen( account, id );
+	gewonnen->zText()->append( gw );
+	if( infoKlient->hatAccountKarte( account, id ) )
+		st->setText( "Im Besitz" );
+	else
+		st->setText( "Nicht im Besitz" );
+	status->zText()->append( st->getText() );
+	ram->setFarbe( 0xFFFFFFFF );
+	ram->setSize( 715, 20 );
+	ram->setRamenBreite( 1 );
+}
+
+// Destruktor
+AccountSUKListeKarte::~AccountSUKListeKarte()
+{
+	ram->release();
+	name->release();
+	spiele->release();
+	gewonnen->release();
+	status->release();
+	if( na )
+		na->release();
+	st->release();
+}
+
+// nicht constant
+void AccountSUKListeKarte::render( int yOff, Bild &zRObj )
+{
+	if( !zRObj.setDrawOptions( 5, yOff, ram->getBreite(), ram->getHeight() ) )
+		return;
+	name->render( zRObj );
+	spiele->render( zRObj );
+	gewonnen->render( zRObj );
+	status->render( zRObj );
+	ram->render( zRObj );
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+Text *AccountSUKListeKarte::zName() const
+{
+	return na;
+}
+
+int AccountSUKListeKarte::getSpiele() const
+{
+	return sp;
+}
+
+int AccountSUKListeKarte::getGewonnen() const
+{
+	return gw;
+}
+
+Text *AccountSUKListeKarte::zStatus() const
+{
+	return st;
+}
+
+// Reference Counting
+AccountSUKListeKarte *AccountSUKListeKarte::getThis()
+{
+	ref++;
+	return this;
+}
+
+AccountSUKListeKarte *AccountSUKListeKarte::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der AccountSUKListeSpiel Klasse aus AccountSpieleUndKarten.h
+// Konstruktor
+AccountSUKListeSpiel::AccountSUKListeSpiel( Schrift *zSchrift, int id, int account )
+: ram( new LRahmen() ),
+  nameTF( initTextFeld( 5, 0, 150, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Name: " ) ),
+  spieleTF( initTextFeld( 165, 0, 150, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Spiele: " ) ),
+  gewonnenTF( initTextFeld( 325, 0, 100, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Gewonnen: " ) ),
+  punkteTF( initTextFeld( 435, 0, 100, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Punkte: " ) ),
+  statusTF( initTextFeld( 545, 0, 150, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Status: " ) ),
+  details( initKnopf( 705, 0, 20, 20, 0, 0, "" ) ),
+  karten( new RCArray< AccountSUKListeKarte >() ),
+  einklappen( bilder->get( "account.ltdb/einklappen.png" ) ),
+  ausklappen( bilder->get( "account.ltdb/ausklappen.png" ) ),
+  status( new Text() ),
+  statusFilter( new Text( "Alle" ) ),
+  sortSpalte( new Text( "Name" ) ),
+  sortAbsteigend( 0 ),
+  spielId( id ),
+  tickVal( 0 ),
+  rend( 0 ),
+  ref( 1 )
+{
+	if( !einklappen )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/account.ltdb" ) );
+		datei->leseDaten( 0 );
+		einklappen = datei->laden( 0, new Text( "einklappen.png" ) );
+		datei->release();
+		bilder->add( "account.ltdb/einklappen.png", einklappen->getThis() );
+	}
+	if( !ausklappen )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/account.ltdb" ) );
+		datei->leseDaten( 0 );
+		ausklappen = datei->laden( 0, new Text( "ausklappen.png" ) );
+		datei->release();
+		bilder->add( "account.ltdb/ausklappen.png", ausklappen->getThis() );
+	}
+	ram->setFarbe( 0xFFFFFFFF );
+	ram->setRamenBreite( 1 );
+	ram->setSize( 725, 20 );
+	details->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	details->setHintergrundBildZ( ausklappen->getThis() );
+	initToolTip( details, "Karten anzeigen.", zSchrift->getThis(), hauptScreen );
+	name = infoKlient->getSpielName( id );
+	if( name )
+		nameTF->zText()->append( name->getText() );
+	Array< int > *stat = new Array< int >();
+	if( infoKlient->getSpielStatistik( account, id, stat ) )
+	{
+		spiele = stat->get( 0 );
+		gewonnen = stat->get( 1 );
+		punkte = stat->get( 3 );
+	}
+	stat->release();
+	spieleTF->zText()->append( spiele );
+	gewonnenTF->zText()->append( gewonnen );
+	punkteTF->zText()->append( punkte );
+	if( infoKlient->hatAccountSpiel( account, id ) )
+		status->setText( "Im Besitz" );
+	else
+		status->setText( "Nicht im Besitz" );
+	statusTF->zText()->append( status->getText() );
+	Array< int > *maps = infoKlient->getAccountKarteGespieltListe( account, id );
+	if( maps )
+	{
+		int anz = maps->getEintragAnzahl();
+		for( int i = 0; i < anz; i++ )
+			karten->set( new AccountSUKListeKarte( zSchrift, maps->get( i ), account ), i );
+		maps->release();
+	}
+}
+
+// Destruktor
+AccountSUKListeSpiel::~AccountSUKListeSpiel()
+{
+	ram->release();
+	nameTF->release();
+	spieleTF->release();
+	gewonnenTF->release();
+	punkteTF->release();
+	statusTF->release();
+	details->release();
+	karten->release();
+	einklappen->release();
+	ausklappen->release();
+	if( name )
+		name->release();
+	status->release();
+	statusFilter->release();
+	sortSpalte->release();
+}
+
+// privat
+int AccountSUKListeSpiel::getReihenfolge( int *arr )
+{
+	int anz = karten->getEintragAnzahl();
+	if( !anz )
+		return 0;
+	int ret = 0;
+	bool *fertig = new bool[ anz ];
+	ZeroMemory( fertig, anz );
+	for( int i = 0; i < anz; i++ )
+	{
+		int index = -1;
+		int minMax = 0;
+		Text minMaxT;
+		for( int j = 0; j < anz; j++ )
+		{
+			AccountSUKListeKarte *tmp = karten->z( j );
+			if( !statusFilter->istGleich( "Alle" ) && !tmp->zStatus()->istGleich( statusFilter->getText() ) )
+				continue;
+			if( sortSpalte->istGleich( "Name" ) && !fertig[ j ] && ( index < 0 ||
+				( sortAbsteigend && *tmp->zName() > minMaxT ) || ( !sortAbsteigend && *tmp->zName() < minMaxT ) ) )
+			{
+				minMaxT = tmp->zName()->getText();
+				index = j;
+			}
+			else if( sortSpalte->istGleich( "Spiele" ) && !fertig[ j ] && ( index < 0 ||
+				( sortAbsteigend && tmp->getSpiele() > minMax ) || ( !sortAbsteigend && tmp->getSpiele() < minMax ) ) )
+			{
+				minMax = tmp->getSpiele();
+				index = j;
+			}
+			else if( sortSpalte->istGleich( "Gewonnen" ) && !fertig[ j ] && ( index < 0 ||
+				( sortAbsteigend && tmp->getGewonnen() > minMax ) || ( !sortAbsteigend && tmp->getGewonnen() < minMax ) ) )
+			{
+				minMax = tmp->getGewonnen();
+				index = j;
+			}
+			else if( sortSpalte->istGleich( "Status" ) && !fertig[ j ] && ( index < 0 ||
+				( sortAbsteigend && *tmp->zStatus() > minMaxT ) || ( !sortAbsteigend && *tmp->zStatus() < minMaxT ) ) )
+			{
+				minMaxT = tmp->zStatus()->getText();
+				index = j;
+			}
+			else if( sortSpalte->istGleich( "Punkte" ) && !fertig[ j ] )
+			{
+				index = j;
+				break;
+			}
+		}
+		if( index < 0 )
+			break;
+		fertig[ index ] = 1;
+		arr[ ret ] = index;
+		ret++;
+	}
+	delete[] fertig;
+	return ret;
+}
+
+// nicht constant
+void AccountSUKListeSpiel::setStatusAusw( char *status )
+{
+	statusFilter->setText( status );
+	rend = 1;
+}
+
+void AccountSUKListeSpiel::setSortSpalte( char *spalte )
+{
+	sortSpalte->setText( spalte );
+	rend = 1;
+}
+
+void AccountSUKListeSpiel::setSortRichtung( bool absteigend )
+{
+	sortAbsteigend = absteigend;
+	rend = 1;
+}
+
+bool AccountSUKListeSpiel::tick( double tickVal )
+{
+	rend |= details->tick( tickVal );
+	this->tickVal += tickVal * 150;
+	int val = ( int )this->tickVal;
+	this->tickVal -= val;
+	if( val )
+	{
+		if( details->zHintergrundBild() == ausklappen && ram->getHeight() != 20 )
+		{
+			if( ram->getHeight() - val < 20 )
+				ram->setSize( ram->getBreite(), 20 );
+			else
+				ram->setSize( ram->getBreite(), ram->getHeight() - val );
+			rend = 1;
+		}
+		if( details->zHintergrundBild() == einklappen )
+		{
+			int maxHö = 20;
+			int anz = karten->getEintragAnzahl();
+			for( int i = 0; i < anz; i++ )
+			{
+				AccountSUKListeKarte *tmp = karten->z( i );
+				if( !statusFilter->istGleich( "Alle" ) && !tmp->zStatus()->istGleich( statusFilter->getText() ) )
+					continue;
+				maxHö += 25;
+			}
+			if( maxHö > 20 )
+				maxHö += 5;
+			if( ram->getHeight() > maxHö )
+			{
+				if( ram->getHeight() - val < maxHö )
+					ram->setSize( ram->getBreite(), maxHö );
+				else
+					ram->setSize( ram->getBreite(), ram->getHeight() - val );
+				rend = 1;
+			}
+			if( ram->getHeight() < maxHö )
+			{
+				if( ram->getHeight() + val > maxHö )
+					ram->setSize( ram->getBreite(), maxHö );
+				else
+					ram->setSize( ram->getBreite(), ram->getHeight() + val );
+				rend = 1;
+			}
+		}
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void AccountSUKListeSpiel::doMausEreignis( MausEreignis &me )
+{
+	bool vera = me.verarbeitet;
+	details->doMausEreignis( me );
+	if( !vera && me.verarbeitet && me.id == ME_RLinks )
+	{
+		if( details->zHintergrundBild() == ausklappen )
+		{
+			details->setHintergrundBildZ( einklappen->getThis() );
+			details->zToolTip()->setText( "Karten verbergen." );
+		}
+		else
+		{
+			details->setHintergrundBildZ( ausklappen->getThis() );
+			details->zToolTip()->setText( "Karten anzeigen." );
+		}
+	}
+}
+
+void AccountSUKListeSpiel::render( int yOff, Bild &zRObj )
+{
+	if( !zRObj.setDrawOptions( 10, yOff, ram->getBreite(), ram->getHeight() ) )
+		return;
+	nameTF->render( zRObj );
+	spieleTF->render( zRObj );
+	gewonnenTF->render( zRObj );
+	punkteTF->render( zRObj );
+	statusTF->render( zRObj );
+	details->render( zRObj );
+	ram->render( zRObj );
+	if( ram->getHeight() > 20 )
+	{
+		zRObj.drawLinieH( 0, 20, ram->getBreite(), ram->getFarbe() );
+		if( !zRObj.setDrawOptions( 1, 25, ram->getBreite() - 2, ram->getHeight() - 2 ) )
+		{
+			zRObj.releaseDrawOptions();
+			return;
+		}
+		int anz = karten->getEintragAnzahl();
+		int *arr = new int[ anz ];
+		anz = getReihenfolge( arr );
+		yOff = 0;
+		for( int i = 0; i < anz; i++ )
+		{
+			karten->z( arr[ i ] )->render( yOff, zRObj );
+			yOff += 25;
+		}
+		delete[]arr;
+		zRObj.releaseDrawOptions();
+	}
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+int AccountSUKListeSpiel::getHeight() const
+{
+	return ram->getHeight();
+}
+
+Text *AccountSUKListeSpiel::zName() const
+{
+	return name;
+}
+
+int AccountSUKListeSpiel::getSpiele() const
+{
+	return spiele;
+}
+
+int AccountSUKListeSpiel::getGewonnen() const
+{
+	return gewonnen;
+}
+
+int AccountSUKListeSpiel::getPunkte() const
+{
+	return punkte;
+}
+
+Text *AccountSUKListeSpiel::zStatus() const
+{
+	return status;
+}
+
+// Reference Counting
+AccountSUKListeSpiel *AccountSUKListeSpiel::getThis()
+{
+	ref++;
+	return this;
+}
+
+AccountSUKListeSpiel *AccountSUKListeSpiel::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der AccountSUKListe Klasse aus AccountSpieleUndKarten.h
+// Konstruktor
+AccountSUKListe::AccountSUKListe()
+: Zeichnung(),
+  ram( new LRahmen() ),
+  scroll( new VScrollBar() ),
+  spiele( new RCArray< AccountSUKListeSpiel >() ),
+  status( new Text() ),
+  statusFilter( new Text( "Alle" ) ),
+  sortSpalte( new Text( "Name" ) ),
+  sortAbsteigend( 0 ),
+  rend( 0 ),
+  ref( 1 )
+{
+	pos = Punkt( 10, 40 );
+	ram->setSize( 760, 380 );
+	ram->setFarbe( 0xFFFFFFFF );
+	ram->setRamenBreite( 1 );
+}
+
+// Destruktor
+AccountSUKListe::~AccountSUKListe()
+{
+	ram->release();
+	scroll->release();
+	spiele->release();
+	status->release();
+	statusFilter->release();
+	sortSpalte->release();
+}
+
+// privat
+int AccountSUKListe::getReihenfolge( int *arr )
+{
+	int anz = spiele->getEintragAnzahl();
+	if( !anz )
+		return 0;
+	int ret = 0;
+	bool *fertig = new bool[ anz ];
+	ZeroMemory( fertig, anz );
+	for( int i = 0; i < anz; i++ )
+	{
+		int index = -1;
+		int minMax = 0;
+		Text minMaxT;
+		for( int j = 0; j < anz; j++ )
+		{
+			AccountSUKListeSpiel *tmp = spiele->z( j );
+			if( !statusFilter->istGleich( "Alle" ) && !tmp->zStatus()->istGleich( statusFilter->getText() ) )
+				continue;
+			if( sortSpalte->istGleich( "Name" ) && !fertig[ j ] && ( index < 0 ||
+				( sortAbsteigend && *tmp->zName() > minMaxT ) || ( !sortAbsteigend && *tmp->zName() < minMaxT ) ) )
+			{
+				minMaxT = tmp->zName()->getText();
+				index = j;
+			}
+			else if( sortSpalte->istGleich( "Spiele" ) && !fertig[ j ] && ( index < 0 ||
+				( sortAbsteigend && tmp->getSpiele() > minMax ) || ( !sortAbsteigend && tmp->getSpiele() < minMax ) ) )
+			{
+				minMax = tmp->getSpiele();
+				index = j;
+			}
+			else if( sortSpalte->istGleich( "Gewonnen" ) && !fertig[ j ] && ( index < 0 ||
+				( sortAbsteigend && tmp->getGewonnen() > minMax ) || ( !sortAbsteigend && tmp->getGewonnen() < minMax ) ) )
+			{
+				minMax = tmp->getGewonnen();
+				index = j;
+			}
+			else if( sortSpalte->istGleich( "Punkte" ) && !fertig[ j ] && ( index < 0 ||
+				( sortAbsteigend && tmp->getPunkte() > minMax ) || ( !sortAbsteigend && tmp->getPunkte() < minMax ) ) )
+			{
+				minMax = tmp->getPunkte();
+				index = j;
+			}
+			else if( sortSpalte->istGleich( "Status" ) && !fertig[ j ] && ( index < 0 ||
+				( sortAbsteigend && *tmp->zStatus() > minMaxT ) || ( !sortAbsteigend && *tmp->zStatus() < minMaxT ) ) )
+			{
+				minMaxT = tmp->zStatus()->getText();
+				index = j;
+			}
+		}
+		if( index < 0 )
+			break;
+		fertig[ index ] = 1;
+		arr[ ret ] = index;
+		ret++;
+	}
+	delete[] fertig;
+	return ret;
+}
+
+// nicht constant
+void AccountSUKListe::reset()
+{
+	lockZeichnung();
+	spiele->leeren();
+	unlockZeichnung();
+}
+
+void AccountSUKListe::addSpiel( AccountSUKListeSpiel *spiel )
+{
+	lockZeichnung();
+	spiel->setSortRichtung( sortAbsteigend );
+	spiel->setSortSpalte( sortSpalte->getText() );
+	spiel->setStatusAusw( statusFilter->getText() );
+	spiele->add( spiel );
+	unlockZeichnung();
+}
+
+void AccountSUKListe::setStatusAusw( char *status )
+{
+	lockZeichnung();
+	this->statusFilter->setText( status );
+	int anz = spiele->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+		spiele->z( i )->setStatusAusw( status );
+	unlockZeichnung();
+	rend = 1;
+}
+
+void AccountSUKListe::setSortSpalte( char *spalte )
+{
+	lockZeichnung();
+	this->sortSpalte->setText( spalte );
+	int anz = spiele->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+		spiele->z( i )->setSortSpalte( spalte );
+	unlockZeichnung();
+	rend = 1;
+}
+
+void AccountSUKListe::setSortRichtung( bool absteigend )
+{
+	lockZeichnung();
+	sortAbsteigend = absteigend;
+	int anz = spiele->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+		spiele->z( i )->setSortRichtung( absteigend );
+	unlockZeichnung();
+	rend = 1;
+}
+
+bool AccountSUKListe::tick( double tickVal )
+{
+	lockZeichnung();
+    int anz = spiele->getEintragAnzahl();
+    if( anz > 0 )
+    {
+        int *rf = new int[ anz ];
+        int rfAnz = getReihenfolge( rf );
+        for( int i = 0; i < rfAnz; i++ )
+            rend |= spiele->z( rf[ i ] )->tick( tickVal );
+        delete[] rf;
+    }
+	unlockZeichnung();
+	rend |= scroll->getRend();
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void AccountSUKListe::doMausEreignis( MausEreignis &me )
+{
+	bool vera = 0;
+	if( me.mx - pos.x <= 0 || me.mx - pos.x >= ram->getBreite() || me.my - pos.y <= 0 || me.my - pos.y >= ram->getHeight() )
+	{
+		vera = 1;
+		me.verarbeitet = 1;
+	}
+	int mx = me.mx, my = me.my;
+	me.mx -= pos.x;
+	me.my -= pos.y;
+	scroll->doMausMessage( ram->getBreite() - 16, 1, 15, ram->getHeight() - 2, me );
+	me.mx -= 10;
+	me.my -= 10 - scroll->getScroll();
+	lockZeichnung();
+	int anz = spiele->getEintragAnzahl();
+	int *rf = new int[ anz ];
+	int rfAnz = getReihenfolge( rf );
+	for( int i = 0; i < rfAnz; i++ )
+	{
+		spiele->z( rf[ i ] )->doMausEreignis( me );
+		me.my -= spiele->z( rf[ i ] )->getHeight() + 10;
+	}
+	delete[] rf;
+	unlockZeichnung();
+	me.mx = mx, me.my = my;
+	if( vera )
+		me.verarbeitet = 0;
+}
+
+void AccountSUKListe::render( Bild &zRObj )
+{
+	if( !zRObj.setDrawOptions( pos.x, pos.y, ram->getBreite(), ram->getBreite() ) )
+		return;
+	ram->render( zRObj );
+	scroll->render( ram->getBreite() - 16, 1, 15, ram->getHeight() - 2, zRObj );
+	if( !zRObj.setDrawOptions( 1, 1, ram->getBreite() - 15, ram->getHeight() - 2 ) )
+	{
+		zRObj.releaseDrawOptions();
+		return;
+	}
+	int y = -scroll->getScroll();
+	int anzHö = 10;
+	lockZeichnung();
+	int anz = spiele->getEintragAnzahl();
+	int *rf = new int[ anz ];
+	int rfAnz = getReihenfolge( rf );
+	for( int i = 0; i < rfAnz; i++ )
+	{
+		spiele->z( rf[ i ] )->render( anzHö, zRObj );
+		anzHö += spiele->z( rf[ i ] )->getHeight() + 10;
+	}
+	delete[] rf;
+	unlockZeichnung();
+	scroll->update( anzHö, ram->getHeight() - 2 );
+	zRObj.releaseDrawOptions();
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+
+// Reference Counting
+AccountSUKListe *AccountSUKListe::getThis()
+{
+	ref++;
+	return this;
+}
+
+AccountSUKListe *AccountSUKListe::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+#define ABSTYLE AuswahlBox::Style::Sichtbar | AuswahlBox::Style::Erlaubt | AuswahlBox::Style::Rahmen | AuswahlBox::Style::AuswahlBuffer | AuswahlBox::Style::MausBuffer | AuswahlBox::Style::MaxHeight | AuswahlBox::Style::Hintergrund | AuswahlBox::Style::VScroll
+
+// Inhalt der AccountSpieleUndKarten Klasse aus AccountSpieleUndKarten.h
+// Konstruktor
+AccountSpieleUndKarten::AccountSpieleUndKarten( Schrift *zSchrift )
+: Thread(),
+  schrift( zSchrift->getThis() ),
+  spieleUndKartenF( initFenster( 810, 40, 780, 450, zSchrift, Fenster::Style::Sichtbar | Fenster::Style::Titel | Fenster::Style::TitelBuffered | Fenster::Style::Rahmen | Fenster::Style::Erlaubt, "Spiele und Karten von " ) ),
+  statusAusw( initAuswahlBox( 10, 10, 150, 20, zSchrift, ABSTYLE, { "Alle", "Im Besitz", "Nicht im Besitz" } ) ),
+  sortSpalte( initAuswahlBox( 170, 10, 150, 20, zSchrift, ABSTYLE, { "Name", "Spiele", "Gewonnen", "Punkte", "Status" } ) ),
+  sortRichtung( initAuswahlBox( 330, 10, 150, 20, zSchrift, ABSTYLE, { "Aufwärts", "Abwärts" } ) ),
+  liste( new AccountSUKListe() ),
+  status( 0 ),
+  accId( 0 ),
+  animation( 0 ),
+  alpha( 255 ),
+  tickVal( 0 ),
+  rend( 0 ),
+  ref( 1 )
+{
+	initToolTip( statusAusw, "Wähle den Status der anzuzeigenden Spiele und Karten aus.", zSchrift->getThis(), hauptScreen );
+	initToolTip( sortSpalte, "Wähle aus, nach welcher Spalte die\nTabelle sortiert werden soll.", zSchrift->getThis(), hauptScreen );
+	initToolTip( sortRichtung, "Wähle aus, Ob Aufwärts oder Abwärts sortiert werden soll.", zSchrift->getThis(), hauptScreen );
+	spieleUndKartenF->addMember( liste );
+	spieleUndKartenF->addMember( statusAusw );
+	spieleUndKartenF->addMember( sortSpalte );
+	spieleUndKartenF->addMember( sortRichtung );
+	spieleUndKartenF->setMausEreignis( _ret1ME );
+}
+
+// Destruktor
+AccountSpieleUndKarten::~AccountSpieleUndKarten()
+{
+	schrift->release();
+	spieleUndKartenF->release();
+	statusAusw->release();
+	sortSpalte->release();
+	sortRichtung->release();
+	liste->release();
+}
+
+// nicht constant
+void AccountSpieleUndKarten::reset()
+{
+	liste->reset();
+}
+
+void AccountSpieleUndKarten::ladeStatistik( int accId )
+{
+	if( this->accId == accId )
+		return;
+	this->status = 0;
+	if( run )
+	{
+		warteAufThread( 1000 );
+		ende();
+	}
+	if( ( animation | 0x1 ) == animation )
+	{
+		animation |= 0x4;
+		this->accId = accId;
+		this->status = 1;
+		return;
+	}
+	if( this->accId )
+		reset();
+	this->accId = accId;
+	start();
+	this->status = 1;
+}
+
+void AccountSpieleUndKarten::thread()
+{
+	Text *name = infoKlient->getSpielerName( accId );
+	if( name )
+	{
+		name->insert( 0, "Spiele und Karten von " );
+		spieleUndKartenF->setTitel( *name );
+		name->release();
+	}
+	Array< int > *spiele = infoKlient->getAccountSpielGespieltListe( accId );
+	if( spiele )
+	{
+		int anz = spiele->getEintragAnzahl();
+		for( int i = 0; i < anz; i++ )
+		{
+			AccountSUKListeSpiel *s = new AccountSUKListeSpiel( schrift, spiele->get( i ), accId );
+			liste->addSpiel( s );
+		}
+		spiele->release();
+	}
+	else
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Fehler beim laden der Daten." ), new Text( "Ok" ) );
+	animation &= ~0x4;
+	status = 2;
+	run = 0;
+}
+
+void AccountSpieleUndKarten::setSichtbar( bool sichtbar, bool nachRechts )
+{
+	if( sichtbar )
+	{
+		if( ( animation | 0x1 ) != animation || ( ( nachRechts && ( animation | 0x2 ) != animation ) || !nachRechts && ( animation | 0x2 ) == animation ) )
+		{
+			if( nachRechts )
+				spieleUndKartenF->setPosition( -810, 40 );
+			else
+				spieleUndKartenF->setPosition( 810, 40 );
+		}
+		animation |= 0x1;
+	}
+	else
+		animation &= ~0x1;
+	if( nachRechts )
+		animation |= 0x2;
+	else
+		animation &= ~0x2;
+}
+
+bool AccountSpieleUndKarten::tick( double zeit )
+{
+	rend |= spieleUndKartenF->tick( zeit );
+	tickVal += zeit;
+	int valA = (int)( tickVal * 150 );
+	int valB = (int)( tickVal * 500 );
+	tickVal -= valA / 150.0;
+	if( valA )
+	{
+		if( ( animation | 0x4 ) == animation && alpha )
+		{
+			if( alpha - valA <= 0 )
+				alpha = 0;
+			else
+				alpha -= valA;
+			rend = 1;
+			if( !alpha )
+			{
+				reset();
+				start();
+			}
+		}
+		if( ( animation | 0x4 ) != animation && alpha != 255 )
+		{
+			if( alpha + valA >= 255 )
+				alpha = 255;
+			else
+				alpha += valA;
+			rend = 1;
+		}
+	}
+	if( valB )
+	{
+		if( ( animation | 0x1 ) == animation )
+		{ // Sichtbar
+			if( ( animation | 0x2 ) == animation )
+			{ // Nach Rechts
+				if( spieleUndKartenF->getX() != 10 )
+				{
+					if( spieleUndKartenF->getX() + valB > 10 )
+						spieleUndKartenF->setPosition( 10, spieleUndKartenF->getY() );
+					else
+						spieleUndKartenF->setPosition( spieleUndKartenF->getX() + valB, spieleUndKartenF->getY() );
+					rend = 1;
+				}
+			}
+			else
+			{ // Nach Links
+				if( spieleUndKartenF->getX() != 10 )
+				{
+					if( spieleUndKartenF->getX() - valB < 10 )
+						spieleUndKartenF->setPosition( 10, spieleUndKartenF->getY() );
+					else
+						spieleUndKartenF->setPosition( spieleUndKartenF->getX() - valB, spieleUndKartenF->getY() );
+					rend = 1;
+				}
+			}
+		}
+		else
+		{ // Unsichtbar
+			if( ( animation | 0x2 ) == animation )
+			{ // Nach Rechts
+				if( spieleUndKartenF->getX() != 810 )
+				{
+					if( spieleUndKartenF->getX() + valB > 810 )
+						spieleUndKartenF->setPosition( 810, spieleUndKartenF->getY() );
+					else
+						spieleUndKartenF->setPosition( spieleUndKartenF->getX() + valB, spieleUndKartenF->getY() );
+					rend = 1;
+				}
+			}
+			else
+			{ // Nach Links
+				if( spieleUndKartenF->getX() != -810 )
+				{
+					if( spieleUndKartenF->getX() - valB < -810 )
+						spieleUndKartenF->setPosition( -810, spieleUndKartenF->getY() );
+					else
+						spieleUndKartenF->setPosition( spieleUndKartenF->getX() - valB, spieleUndKartenF->getY() );
+					rend = 1;
+				}
+			}
+		}
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void AccountSpieleUndKarten::doMausEreignis( MausEreignis &me )
+{
+	int statusAuswS = statusAusw->getAuswahl();
+	int sortSpalteS = sortSpalte->getAuswahl();
+	int sortRichtungS = sortRichtung->getAuswahl();
+	spieleUndKartenF->doMausEreignis( me );
+	if( statusAusw->getAuswahl() != statusAuswS )
+	{
+		liste->setStatusAusw( statusAusw->zEintrag( statusAusw->getAuswahl() )->zText()->getText() );
+		statusAusw->einklappen();
+	}
+	if( sortSpalte->getAuswahl() != sortSpalteS )
+	{
+		liste->setSortSpalte( sortSpalte->zEintrag( sortSpalte->getAuswahl() )->zText()->getText() );
+		sortSpalte->einklappen();
+	}
+	if( sortRichtung->getAuswahl() != sortRichtungS )
+	{
+		liste->setSortRichtung( sortRichtung->getAuswahl() != 0 );
+		sortRichtung->einklappen();
+	}
+}
+
+void AccountSpieleUndKarten::render( Bild &zRObj )
+{
+	zRObj.setAlpha( alpha );
+	spieleUndKartenF->render( zRObj );
+	zRObj.releaseAlpha();
+}
+
+// constant
+int AccountSpieleUndKarten::getStatus() const
+{
+	return status;
+}
+
+// Reference Counting
+AccountSpieleUndKarten *AccountSpieleUndKarten::getThis()
+{
+	ref++;
+	return this;
+}
+
+AccountSpieleUndKarten *AccountSpieleUndKarten::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 171 - 0
KSGClient/NachLogin/Account/Spiele_Karten/AccountSpieleUndKarten.h

@@ -0,0 +1,171 @@
+#ifndef AccountSpieleUndKarten_H
+#define AccountSpieleUndKarten_H
+
+#include <Schrift.h>
+#include <Fenster.h>
+#include <Thread.h>
+#include <AuswahlBox.h>
+
+using namespace Framework;
+
+class AccountSUKListeKarte
+{
+private:
+	LRahmen *ram;
+	TextFeld *name;
+	TextFeld *spiele;
+	TextFeld *gewonnen;
+	TextFeld *status;
+	Text *na;
+	int sp;
+	int gw;
+	Text *st;
+	int karteId;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	AccountSUKListeKarte( Schrift *zSchrift, int id, int account );
+	// Destruktor
+	~AccountSUKListeKarte();
+	// nicht constant
+	void render( int yOff, Bild &zRObj );
+	// constant
+	Text *zName() const;
+	int getSpiele() const;
+	int getGewonnen() const;
+	Text *zStatus() const;
+	// Reference Counting
+	AccountSUKListeKarte *getThis();
+	AccountSUKListeKarte *release();
+};
+
+class AccountSUKListeSpiel
+{
+private:
+	LRahmen *ram;
+	TextFeld *nameTF;
+	TextFeld *spieleTF;
+	TextFeld *gewonnenTF;
+	TextFeld *punkteTF;
+	TextFeld *statusTF;
+	Knopf *details;
+	RCArray< AccountSUKListeKarte > *karten;
+	Bild *einklappen;
+	Bild *ausklappen;
+	Text *name;
+	int spiele;
+	int gewonnen;
+	int punkte;
+	Text *status;
+	Text *statusFilter;
+	Text *sortSpalte;
+	bool sortAbsteigend;
+	int spielId;
+	double tickVal;
+	bool rend;
+	int ref;
+
+	// privat
+	int getReihenfolge( int *arr );
+
+public:
+	// Konstruktor
+	AccountSUKListeSpiel( Schrift *zSchrift, int id, int account );
+	// Destruktor
+	~AccountSUKListeSpiel();
+	// nicht constant
+	void setStatusAusw( char *status );
+	void setSortSpalte( char *spalte );
+	void setSortRichtung( bool absteigend );
+	bool tick( double tickVal );
+	void doMausEreignis( MausEreignis &me );
+	void render( int yOff, Bild &zRObj );
+	// constant
+	int getHeight() const;
+	Text *zName() const;
+	int getSpiele() const;
+	int getGewonnen() const;
+	int getPunkte() const;
+	Text *zStatus() const;
+	// Reference Counting
+	AccountSUKListeSpiel *getThis();
+	AccountSUKListeSpiel *release();
+};
+
+class AccountSUKListe : public Zeichnung
+{
+private:
+	LRahmen *ram;
+	VScrollBar *scroll;
+	RCArray< AccountSUKListeSpiel > *spiele;
+	Text *status;
+	Text *statusFilter;
+	Text *sortSpalte;
+	bool sortAbsteigend;
+	bool rend;
+	int ref;
+
+	// privat
+	int getReihenfolge( int *arr );
+
+public:
+	// Konstruktor
+	AccountSUKListe();
+	// Destruktor
+	~AccountSUKListe();
+	// nicht constant
+	void reset();
+	void addSpiel( AccountSUKListeSpiel *spiel );
+	void setStatusAusw( char *status );
+	void setSortSpalte( char *spalte );
+	void setSortRichtung( bool absteigend );
+	bool tick( double tickVal ) override;
+	void doMausEreignis( MausEreignis &me ) override;
+	void render( Bild &zRObj ) override;
+	// constant
+
+	// Reference Counting
+	AccountSUKListe *getThis();
+	AccountSUKListe *release();
+};
+
+class AccountSpieleUndKarten : public Thread
+{
+private:
+	Schrift *schrift;
+	Fenster *spieleUndKartenF;
+	AuswahlBox *statusAusw;
+	AuswahlBox *sortSpalte;
+	AuswahlBox *sortRichtung;
+	AccountSUKListe *liste;
+	int status;
+	int accId;
+	int animation;
+	unsigned char alpha;
+	double tickVal;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	AccountSpieleUndKarten( Schrift *zSchrift );
+	// Destruktor
+	~AccountSpieleUndKarten();
+	// nicht constant
+	void reset();
+	void ladeStatistik( int accId );
+	virtual void thread();
+	void setSichtbar( bool sichtbar, bool nachRechts );
+	bool tick( double zeit );
+	void doMausEreignis( MausEreignis &me );
+	void render( Bild &zRObj );
+	// constant
+	int getStatus() const;
+	// Reference Counting
+	AccountSpieleUndKarten *getThis();
+	AccountSpieleUndKarten *release();
+};
+
+#endif

+ 403 - 0
KSGClient/NachLogin/Account/Statistik/AccountStatistik.cpp

@@ -0,0 +1,403 @@
+#include "AccountStatistik.h"
+#include "../../../Global/Initialisierung.h"
+#include "../../../Global/Variablen.h"
+#include <DateiSystem.h>
+
+// Inhalt der AccountStatistik Klasse aus AccountStatistik.h
+// Konstruktor
+AccountStatistik::AccountStatistik( Schrift *zSchrift )
+: Thread(),
+  schrift( zSchrift->getThis() ),
+  statistikF( initFenster( 810, 40, 780, 450, zSchrift, Fenster::Style::Sichtbar | Fenster::Style::Titel | Fenster::Style::TitelBuffered | Fenster::Style::Rahmen | Fenster::Style::Erlaubt, "Statistik von " ) ),
+  sortSpalte( initAuswahlBox( 10, 10, 150, 20, zSchrift, ABSTYLE, { "Name", "Spiele", "Gewonnen", "Verloren", "Punkte", "BW0", "BW1", "BW2", "BW3", "BW4", "BW5" } ) ),
+  sortRichtung( initAuswahlBox( 170, 10, 150, 20, zSchrift, ABSTYLE, { "Aufwärts", "Abwärts" } ) ),
+  zurück( initKnopf( 590, 10, 20, 20, 0, 0, "" ) ),
+  vor( initKnopf( 750, 10, 20, 20, 0, 0, "" ) ),
+  seiteTF( initTextFeld( 620, 10, 120, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Seite 0 von 0" ) ),
+  tabelle( initObjTabelle( 10, 40, 760, 400, zSchrift, OTSTYLE, { { "Name", 108, 0, 0 }, { "Spiele", 70, 0, 0 }, { "Gewonnen", 70, 0, 0 },
+  { "Verloren", 70, 0, 0 }, { "Punkte", 70, 0, 0 }, { "BW0", 60, 0, 0 }, { "BW1", 60, 0, 0 }, { "BW2", 60, 0, 0 }, { "BW3", 60, 0, 0 },
+  { "BW4", 60, 0, 0 }, { "BW5", 60, 0, 0 } }, 20 ) ),
+  laden( (Animation2D*)ladeAnimation->dublizieren() ),
+  seite( 0 ),
+  maxSeite( 0 ),
+  status( 0 ),
+  accId( 0 ),
+  animation( 0 ),
+  alpha( 255 ),
+  tickVal( 0 ),
+  rend( 0 ),
+  ref( 1 )
+{
+	initToolTip( sortSpalte, "Wähle aus, nach welcher Spalte die\nTabelle sortiert werden soll.", zSchrift->getThis(), hauptScreen );
+	initToolTip( sortRichtung, "Wähle aus, ob Aufwärts oder Abwärts\nsortiert werden soll.", zSchrift->getThis(), hauptScreen );
+	Bild *zurückB = bilder->get( "shop.ltdb/zurück.png" );
+	if( !zurückB )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/shop.ltdb" ) );
+		datei->leseDaten( 0 );
+		zurückB = datei->laden( 0, new Text( "zurück.png" ) );
+		datei->release();
+		bilder->add( "shop.ltdb/zurück.png", zurückB->getThis() );
+	}
+	Bild *weiterB = bilder->get( "shop.ltdb/weiter.png" );
+	if( !weiterB )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/shop.ltdb" ) );
+		datei->leseDaten( 0 );
+		weiterB = datei->laden( 0, new Text( "weiter.png" ) );
+		datei->release();
+		bilder->add( "shop.ltdb/weiter.png", weiterB->getThis() );
+	}
+	laden->setSichtbar( 0 );
+	laden->setPosition( 365, 200 );
+	zurück->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	zurück->setHintergrundBildZ( zurückB );
+	initToolTip( zurück, "Eine Seite zurück blättern.", zSchrift->getThis(), hauptScreen );
+	vor->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	vor->setHintergrundBildZ( weiterB );
+	initToolTip( vor, "Eine Seite weiter blättern.", zSchrift->getThis(), hauptScreen );
+	statistikF->addMember( tabelle );
+	statistikF->addMember( zurück );
+	statistikF->addMember( seiteTF );
+	statistikF->addMember( vor );
+	statistikF->addMember( sortSpalte );
+	statistikF->addMember( sortRichtung );
+	statistikF->setMausEreignis( _ret1ME );
+	vor->setMausEreignis( accountStatistikVorME );
+	zurück->setMausEreignis( accountStatistikZurückME );
+}
+
+// Destruktor
+AccountStatistik::~AccountStatistik()
+{
+	reset( 1 );
+	statistikF->release();
+	sortSpalte->release();
+	sortRichtung->release();
+	zurück->release();
+	vor->release();
+	seiteTF->release();
+	tabelle->release();
+	laden->release();
+	schrift->release();
+}
+
+// nicht constant
+void AccountStatistik::reset( bool überschrift )
+{
+	statistikF->lockZeichnung();
+	int zAnz = tabelle->getZeilenAnzahl();
+	int sAnz = tabelle->getSpaltenAnzahl();
+	for( int i = !überschrift; i < zAnz; i++ )
+	{
+		for( int j = 0; j < sAnz; j++ )
+		{
+			if( !tabelle->zZeichnung( j, !überschrift ) )
+				continue;
+			( (TextFeld*)tabelle->zZeichnung( j, !überschrift ) )->release();
+		}
+		tabelle->removeZeile( !überschrift );
+	}
+	statistikF->unlockZeichnung();
+}
+
+void AccountStatistik::ladeStatistik( int accId )
+{
+	if( this->accId == accId )
+		return;
+	this->status = 0;
+	if( run )
+	{
+		warteAufThread( 1000 );
+		ende();
+	}
+	if( ( animation | 0x1 ) == animation )
+	{
+		animation |= 0x4;
+		this->accId = accId;
+		this->status = 1;
+		return;
+	}
+	this->accId = accId;
+	start();
+	this->status = 1;
+}
+
+void AccountStatistik::thread()
+{
+	laden->setSichtbar( 1 );
+	reset();
+	Text *name = infoKlient->getSpielerName( accId );
+	if( name )
+	{
+		name->insert( 0, "Statistik von " );
+		statistikF->setTitel( *name );
+		name->release();
+	}
+	RCArray< Array< int > > *values = new RCArray< Array< int > >();
+	RCArray< Text > *namen = new RCArray< Text >();
+	if( infoKlient->getStatistikListe( accId, &seite, &maxSeite, sortSpalte->getAuswahl(), sortRichtung->getAuswahl(), values, namen ) )
+	{
+		statistikF->lockZeichnung();
+		seiteTF->setText( "Seite " );
+		seiteTF->zText()->append( seite );
+		seiteTF->zText()->append( " von " );
+		seiteTF->zText()->append( maxSeite );
+		statistikF->unlockZeichnung();
+		zurück->setStyle( Knopf::Style::Erlaubt, seite > 1 );
+		vor->setStyle( Knopf::Style::Erlaubt, seite < maxSeite );
+		int zAnz = values->getEintragAnzahl();
+		if( zAnz )
+		{
+			int sAnz = values->z( 0 )->getEintragAnzahl();
+			for( int i = 0; i < zAnz; i++ )
+			{
+				if( sAnz )
+				{
+					tabelle->addZeile( Text() += values->z( i )->get( 0 ) );
+					Text *name = namen->z( i );
+					if( name )
+					{
+						TextFeld *tf = initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::Center, *name );
+						tabelle->setZeichnungZ( 0, i + 1, tf );
+					}
+				}
+				for( int j = 1; j < sAnz; j++ )
+				{
+					if( j < 1 )
+					{
+						TextFeld *tf = initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::Center, "" );
+						tf->zText()->append( values->z( i )->get( j ) );
+						tabelle->setZeichnungZ( j, i + 1, tf );
+					}
+					if( j > 1 )
+					{
+						TextFeld *tf = initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::Center, "" );
+						tf->zText()->append( values->z( i )->get( j ) );
+						tabelle->setZeichnungZ( j - 1, i + 1, tf );
+					}
+				}
+			}
+		}
+	}
+	else
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Die Statistiken dieses Spielers konnten nicht abgerufen werden." ), new Text( "Ok" ) );
+	values->release();
+	namen->release();
+	laden->setSichtbar( 0 );
+	animation &= ~0x4;
+	status = 2;
+	run = 0;
+}
+
+void AccountStatistik::setSichtbar( bool sichtbar, bool nachRechts )
+{
+	if( sichtbar )
+	{
+		if( ( animation | 0x1 ) != animation || ( ( nachRechts && ( animation | 0x2 ) != animation ) || !nachRechts && ( animation | 0x2 ) == animation ) )
+		{
+			if( nachRechts )
+				statistikF->setPosition( -810, 40 );
+			else
+				statistikF->setPosition( 810, 40 );
+		}
+		animation |= 0x1;
+	}
+	else
+		animation &= ~0x1;
+	if( nachRechts )
+		animation |= 0x2;
+	else
+		animation &= ~0x2;
+}
+
+bool AccountStatistik::vorME( MausEreignis &me )
+{
+	if( me.id == ME_RLinks )
+	{
+		seite++;
+		start();
+	}
+	return 1;
+}
+
+bool AccountStatistik::zurückME( MausEreignis &me )
+{
+	if( me.id == ME_RLinks )
+	{
+		seite--;
+		start();
+	}
+	return 1;
+}
+
+bool AccountStatistik::tick( double zeit )
+{
+	statistikF->lockZeichnung();
+	rend |= statistikF->tick( zeit );
+	statistikF->unlockZeichnung();
+	rend |= laden->tick( zeit );
+	tickVal += zeit;
+	int valA = (int)( tickVal * 150 );
+	int valB = (int)( tickVal * 500 );
+	tickVal -= valA / 150.0;
+	if( valA )
+	{
+		if( ( animation | 0x4 ) == animation && alpha )
+		{
+			if( alpha - valA <= 0 )
+				alpha = 0;
+			else
+				alpha -= valA;
+			rend = 1;
+			if( !alpha )
+			{
+				reset();
+				start();
+			}
+		}
+		if( ( animation | 0x4 ) != animation && alpha != 255 )
+		{
+			if( alpha + valA >= 255 )
+				alpha = 255;
+			else
+				alpha += valA;
+			rend = 1;
+		}
+	}
+	if( valB )
+	{
+		if( ( animation | 0x1 ) == animation )
+		{ // Sichtbar
+			if( ( animation | 0x2 ) == animation )
+			{ // Nach Rechts
+				if( statistikF->getX() != 10 )
+				{
+					if( statistikF->getX() + valB > 10 )
+						statistikF->setPosition( 10, statistikF->getY() );
+					else
+						statistikF->setPosition( statistikF->getX() + valB, statistikF->getY() );
+					rend = 1;
+				}
+			}
+			else
+			{ // Nach Links
+				if( statistikF->getX() != 10 )
+				{
+					if( statistikF->getX() - valB < 10 )
+						statistikF->setPosition( 10, statistikF->getY() );
+					else
+						statistikF->setPosition( statistikF->getX() - valB, statistikF->getY() );
+					rend = 1;
+				}
+			}
+		}
+		else
+		{ // Unsichtbar
+			if( ( animation | 0x2 ) == animation )
+			{ // Nach Rechts
+				if( statistikF->getX() != 810 )
+				{
+					if( statistikF->getX() + valB > 810 )
+						statistikF->setPosition( 810, statistikF->getY() );
+					else
+						statistikF->setPosition( statistikF->getX() + valB, statistikF->getY() );
+					rend = 1;
+				}
+			}
+			else
+			{ // Nach Links
+				if( statistikF->getX() != -810 )
+				{
+					if( statistikF->getX() - valB < -810 )
+						statistikF->setPosition( -810, statistikF->getY() );
+					else
+						statistikF->setPosition( statistikF->getX() - valB, statistikF->getY() );
+					rend = 1;
+				}
+			}
+		}
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void AccountStatistik::doMausEreignis( MausEreignis &me )
+{
+	if( run )
+		return;
+	bool starten = 0;
+	int sortSpalteS = sortSpalte->getAuswahl();
+	int sortRichtungS = sortRichtung->getAuswahl();
+	statistikF->lockZeichnung();
+	statistikF->doMausEreignis( me );
+	statistikF->unlockZeichnung();
+	if( sortSpalte->getAuswahl() != sortSpalteS )
+	{
+		sortSpalte->einklappen();
+		starten = 1;
+	}
+	if( sortRichtung->getAuswahl() != sortRichtungS )
+	{
+		sortRichtung->einklappen();
+		starten = 1;
+	}
+	if( starten )
+		start();
+}
+
+void AccountStatistik::render( Bild &zRObj )
+{
+	zRObj.setAlpha( alpha );
+	statistikF->lockZeichnung();
+	statistikF->render( zRObj );
+	statistikF->unlockZeichnung();
+	if( !zRObj.setDrawOptions( statistikF->getPosition(), statistikF->getSize() ) )
+	{
+		zRObj.releaseAlpha();
+		return;
+	}
+	laden->render( zRObj );
+	zRObj.releaseAlpha();
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+int AccountStatistik::getStatus() const
+{
+	return status;
+}
+
+// Reference Counting
+AccountStatistik *AccountStatistik::getThis()
+{
+	ref++;
+	return this;
+}
+
+AccountStatistik *AccountStatistik::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Ereignisse
+bool accountStatistikVorME( void *p, void *o, MausEreignis me )
+{
+	if( p )
+		return ( (AccountStatistik*)p )->vorME( me );
+	return 1;
+}
+
+bool accountStatistikZurückME( void *p, void *o, MausEreignis me )
+{
+	if( p )
+		return ( (AccountStatistik*)p )->zurückME( me );
+	return 1;
+}

+ 60 - 0
KSGClient/NachLogin/Account/Statistik/AccountStatistik.h

@@ -0,0 +1,60 @@
+#ifndef AccountStatistik_H
+#define AccountStatistik_H
+
+#include <Thread.h>
+#include <Tabelle.h>
+#include <Fenster.h>
+#include <AuswahlBox.h>
+#include <Animation.h>
+
+using namespace Framework;
+
+class AccountStatistik : public Thread
+{
+private:
+	Schrift *schrift;
+	Fenster *statistikF;
+	AuswahlBox *sortSpalte;
+	AuswahlBox *sortRichtung;
+	Knopf *zurück;
+	Knopf *vor;
+	TextFeld *seiteTF;
+	ObjTabelle *tabelle;
+	Animation2D *laden;
+	int seite;
+	int maxSeite;
+	int status;
+	int accId;
+	int animation;
+	unsigned char alpha;
+	double tickVal;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	AccountStatistik( Schrift *zSchrift );
+	// Destruktor
+	~AccountStatistik();
+	// nicht constant
+	void reset( bool überschrift = 0 );
+	void ladeStatistik( int accId );
+	virtual void thread();
+	void setSichtbar( bool sichtbar, bool nachRechts );
+	bool vorME( MausEreignis &me );
+	bool zurückME( MausEreignis &me );
+	bool tick( double zeit );
+	void doMausEreignis( MausEreignis &me );
+	void render( Bild &zRObj );
+	// constant
+	int getStatus() const;
+	// Reference Counting
+	AccountStatistik *getThis();
+	AccountStatistik *release();
+};
+
+// Ereignisse
+bool accountStatistikVorME( void *p, void *o, MausEreignis me );
+bool accountStatistikZurückME( void *p, void *o, MausEreignis me );
+
+#endif

+ 364 - 0
KSGClient/NachLogin/Account/Suchen/AccountSuchen.cpp

@@ -0,0 +1,364 @@
+#include "AccountSuchen.h"
+#include <Punkt.h>
+#include "../../../Global/Variablen.h"
+#include "../../../Global/Initialisierung.h"
+#include <DateiSystem.h>
+
+// Inhalt der AccountSuchen Klasse aud AccountSuchen.h
+// Konstruktor
+AccountSuchen::AccountSuchen( Schrift *schrift )
+	: Thread(),
+  schrift( schrift ),
+  pos( 810, 0 ),
+  gr( 800, 500 ),
+  laden( (Animation2D*)ladeAnimation->dublizieren() ),
+  accountName( initTextFeld( 10, 10, 200, 20, schrift, TextFeld::Style::TextFeld, "Spieler Suchen" ) ),
+  suchen( initKnopf( 220, 10, 100, 20, schrift, Knopf::Style::Sichtbar, "Suchen" ) ),
+  sortSpalte( initAuswahlBox( 330, 10, 150, 20, schrift, ABSTYLE, { "Name", "Zuletzt Online", "Letztes Spiel", "Letzte Karte", "Spielart Punkte" } ) ),
+  sortRichtung( initAuswahlBox( 490, 10, 120, 20, schrift, ABSTYLE, { "Aufwärts", "Abwärts" } ) ),
+  zurück( initKnopf( 620, 10, 20, 20, 0, 0, "" ) ),
+  seite( initTextFeld( 645, 10, 120, 20, schrift, TextFeld::Style::Text | TextFeld::Style::Center, "Seite 0 von 0" ) ),
+  vor( initKnopf( 770, 10, 20, 20, 0, 0, "" ) ),
+  liste( initObjTabelle( 10, 40, 780, 450, schrift, OTSTYLE, { { "Name", 158, 0, 0 }, { "Zuletzt Online", 150, 0, 0 }, { "Letztes Spiel", 145, 0, 0 }, { "Letzte Karte", 150, 0, 0 }, { "Spielart Punkte", 150, 0, 0 } }, 30 ) ),
+  auswahl( 0 ),
+  tickVal( 0 ),
+  sichtbar( 0 ),
+  jetztSeite( 0 ),
+  maxSeite( 0 ),
+  alpha( 255 ),
+  rend( 0 ),
+  ref( 1 )
+{
+	initToolTip( accountName, "Gebe den Namen eines Spielers ein.", schrift->getThis(), hauptScreen );
+	initToolTip( sortSpalte, "Wähle aus, nach welcher Spalte die\nTabelle sortiert werden soll.", schrift->getThis(), hauptScreen );
+	initToolTip( sortRichtung, "Wähle aus, ob Aufwärts oder Abwärts\nsortiert werden soll.", schrift->getThis(), hauptScreen );
+	Bild *zurückB = bilder->get( "shop.ltdb/zurück.png" );
+	if( !zurückB )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/shop.ltdb" ) );
+		datei->leseDaten( 0 );
+		zurückB = datei->laden( 0, new Text( "zurück.png" ) );
+		datei->release();
+		bilder->add( "shop.ltdb/zurück.png", zurückB->getThis() );
+	}
+	Bild *weiterB = bilder->get( "shop.ltdb/weiter.png" );
+	if( !weiterB )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/shop.ltdb" ) );
+		datei->leseDaten( 0 );
+		weiterB = datei->laden( 0, new Text( "weiter.png" ) );
+		datei->release();
+		bilder->add( "shop.ltdb/weiter.png", weiterB->getThis() );
+	}
+	laden->setSichtbar( 0 );
+	laden->setPosition( 375, 225 );
+	zurück->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	zurück->setHintergrundBildZ( zurückB );
+	initToolTip( zurück, "Eine Seite zurück blättern.", schrift->getThis(), hauptScreen );
+	vor->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	vor->setHintergrundBildZ( weiterB );
+	initToolTip( vor, "Eine Seite weiter blättern.", schrift->getThis(), hauptScreen );
+	liste->addSpalte( "Weiter" );
+	liste->setSpaltenBreite( "Weiter", 20 );
+}
+
+// Destruktor
+AccountSuchen::~AccountSuchen()
+{
+	if( run )
+		warteAufThread( 1000 );
+	if( run )
+		ende();
+	schrift->release();
+	laden->release();
+	accountName->release();
+	suchen->release();
+	sortSpalte->release();
+	sortRichtung->release();
+	zurück->release();
+	seite->release();
+	vor->release();
+	tabelleLehren( 1 );
+	liste->release();
+}
+
+// privat
+void AccountSuchen::lock()
+{
+    cs.lock();
+}
+
+void AccountSuchen::unlock()
+{
+    cs.unlock();
+}
+
+void AccountSuchen::tabelleLehren( bool überschrift )
+{
+	lock();
+	int zAnz = liste->getZeilenAnzahl();
+	int sAnz = liste->getSpaltenAnzahl();
+	for( int i = !überschrift; i < zAnz; i++ )
+	{
+		for( int j = 0; j < sAnz; j++ )
+		{
+			if( !liste->zZeichnung( j, !überschrift ) )
+				continue;
+			if( liste->zSpaltenName( j )->istGleich( "Weiter" ) )
+				( (Knopf*)liste->zZeichnung( j, !überschrift ) )->release();
+			else
+				( (TextFeld*)liste->zZeichnung( j, !überschrift ) )->release();
+		}
+		liste->removeZeile( !überschrift );
+	}
+	unlock();
+}
+
+// nicht constant
+void AccountSuchen::setSichtbar( bool sichtbar )
+{
+	this->sichtbar = sichtbar;
+}
+
+void AccountSuchen::thread()
+{
+	laden->setSichtbar( 1 );
+	tabelleLehren( 0 );
+	Array< int > *accounts = new Array< int >();
+	RCArray< Text > *namen = new RCArray< Text >();
+	RCArray< Text > *zuletztOnline = new RCArray< Text >();
+	RCArray< Text > *letztesSpiel = new RCArray< Text >();
+	RCArray< Text > *letzteKarte = new RCArray< Text >();
+	RCArray< Text > *punkte = new RCArray< Text >();
+	int anz = infoKlient->getSpielerListe( accountName->zText()->getText(), &jetztSeite, &maxSeite, sortSpalte->getAuswahl(),
+										   sortRichtung->getAuswahl(), accounts, namen, zuletztOnline, letztesSpiel, letzteKarte, punkte );
+	zurück->setStyle( Knopf::Style::Erlaubt, jetztSeite > 1 );
+	vor->setStyle( Knopf::Style::Erlaubt, jetztSeite < maxSeite );
+	lock();
+	seite->setText( "Seite " );
+	seite->zText()->append( jetztSeite );
+	seite->zText()->append( " von " );
+	seite->zText()->append( maxSeite );
+	unlock();
+	for( int i = 0; i < anz; i++ )
+	{
+		liste->addZeile( i + 1, Text() += accounts->get( i ) );
+		liste->setZeilenHeight( i + 1, 20 );
+		liste->setZeichnungZ( liste->getSpaltenNummer( "Name" ), i + 1, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, namen->z( i )->getText() ) );
+		if( zuletztOnline->z( i )->hat( '.' ) )
+			zuletztOnline->z( i )->setText( zuletztOnline->z( i )->getTeilText( 0, zuletztOnline->z( i )->positionVon( '.' ) ) );
+		liste->setZeichnungZ( liste->getSpaltenNummer( "Zuletzt Online" ), i + 1, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, zuletztOnline->z( i )->getText() ) );
+		liste->setZeichnungZ( liste->getSpaltenNummer( "Letztes Spiel" ), i + 1, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, letztesSpiel->z( i )->getText() ) );
+		liste->setZeichnungZ( liste->getSpaltenNummer( "Letzte Karte" ), i + 1, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, letzteKarte->z( i )->getText() ) );
+		liste->setZeichnungZ( liste->getSpaltenNummer( "Spielart Punkte" ), i + 1, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, punkte->z( i )->getText() ) );
+		Knopf *details = initKnopf( 0, 0, 20, 20, 0, 0, "" );
+		details->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::KlickBuffer | Knopf::Style::Erlaubt );
+		details->setMausEreignisParameter( this );
+		details->setMausEreignis( accountSuchenDetailsKlick );
+		details->setHintergrundBildZ( vor->getHintergrundBild() );
+		liste->setZeichnungZ( liste->getSpaltenNummer( "Weiter" ), i + 1, details );
+	}
+	accounts->release();
+	namen->release();
+	zuletztOnline->release();
+	letztesSpiel->release();
+	letzteKarte->release();
+	punkte->release();
+	laden->setSichtbar( 0 );
+	run = 0;
+}
+
+bool AccountSuchen::detailsKlick( Knopf *zKnopf, MausEreignis &me )
+{
+	if( me.id != ME_RLinks )
+		return 1;
+	int zAnz = liste->getZeilenAnzahl();
+	for( int i = 1; i < zAnz; i++ )
+	{
+		if( liste->zZeichnung( liste->getSpaltenNummer( "Weiter" ), i ) == zKnopf )
+		{
+			auswahl = *liste->zZeilenName( i );
+			break;
+		}
+	}
+	return 1;
+}
+
+void AccountSuchen::doMausEreignis( MausEreignis &me )
+{
+	if( run )
+		return;
+	bool starten = 0;
+	lock();
+	me.mx -= pos.x;
+	me.my -= pos.y;
+	int ausw = sortSpalte->getAuswahl();
+	sortSpalte->doMausEreignis( me );
+	if( ausw != sortSpalte->getAuswahl() )
+	{
+		sortSpalte->einklappen();
+		starten = 1;
+	}
+	ausw = sortRichtung->getAuswahl();
+	sortRichtung->doMausEreignis( me );
+	if( ausw != sortRichtung->getAuswahl() )
+	{
+		sortRichtung->einklappen();
+		starten = 1;
+	}
+	accountName->doMausEreignis( me );
+	bool vera = me.verarbeitet;
+	suchen->doMausEreignis( me );
+	if( !vera && me.verarbeitet && me.id == ME_RLinks )
+	{
+		jetztSeite = 1;
+		starten = 1;
+	}
+	vera = me.verarbeitet;
+	zurück->doMausEreignis( me );
+	if( !vera && me.verarbeitet )
+	{
+		seite--;
+		starten = 1;
+	}
+	vera = me.verarbeitet;
+	vor->doMausEreignis( me );
+	if( !vera && me.verarbeitet )
+	{
+		seite++;
+		starten = 1;
+	}
+	liste->doMausEreignis( me );
+	me.mx += pos.x;
+	me.my += pos.y;
+	unlock();
+	if( starten )
+		start();
+}
+
+void AccountSuchen::doTastaturEreignis( TastaturEreignis &te )
+{
+	if( run )
+		return;
+	lock();
+	bool vera = te.verarbeitet;
+	accountName->doTastaturEreignis( te );
+	if( !vera && te.verarbeitet && te.taste == T_Enter && te.id == TE_Release )
+	{
+		jetztSeite = 1;
+		start();
+	}
+	unlock();
+}
+
+bool AccountSuchen::tick( double tickVal )
+{
+	lock();
+	rend |= laden->tick( tickVal );
+	rend |= accountName->tick( tickVal );
+	rend |= suchen->tick( tickVal );
+	rend |= sortSpalte->tick( tickVal );
+	rend |= sortRichtung->tick( tickVal );
+	rend |= zurück->tick( tickVal );
+	rend |= seite->tick( tickVal );
+	rend |= vor->tick( tickVal );
+	rend |= liste->tick( tickVal );
+	this->tickVal += tickVal;
+	int valA = (int)( this->tickVal * 150 );
+	int valB = (int)( this->tickVal * 500 );
+	this->tickVal -= valA / 150.0;
+	if( valA )
+	{
+		if( laden->istSichtbar() && alpha != 100 )
+		{
+			if( alpha - valA < 100 )
+				alpha = 100;
+			else
+				alpha -= valA;
+			rend = 1;
+		}
+		if( !laden->istSichtbar() && alpha != 255 )
+		{
+			if( alpha + valA > 255 )
+				alpha = 255;
+			else
+				alpha += valA;
+			rend = 1;
+		}
+	}
+	if( valB )
+	{
+		if( sichtbar && pos.x != 0 )
+		{
+			if( pos.x + valB > 0 )
+				pos.x = 0;
+			else
+				pos.x += valB;
+			rend = 1;
+		}
+		else if( !sichtbar && pos.x != -810 )
+		{
+			if( pos.x - valB < -810 )
+				pos.x = -810;
+			else
+				pos.x -= valB;
+			rend = 1;
+		}
+	}
+	unlock();
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void AccountSuchen::render( Bild &zRObj )
+{
+	if( !zRObj.setDrawOptions( pos, gr ) )
+		return;
+	lock();
+	laden->render( zRObj );
+	accountName->render( zRObj );
+	suchen->render( zRObj );
+	zurück->render( zRObj );
+	seite->render( zRObj );
+	vor->render( zRObj );
+	liste->render( zRObj );
+	sortSpalte->render( zRObj );
+	sortRichtung->render( zRObj );
+	unlock();
+	zRObj.releaseDrawOptions();
+}
+
+int AccountSuchen::getAuswahlAccountId()
+{
+	int ret = auswahl;
+	auswahl = 0;
+	return ret;
+}
+
+// constant
+
+// Reference Counting
+AccountSuchen *AccountSuchen::getThis()
+{
+	ref++;
+	return this;
+}
+
+AccountSuchen *AccountSuchen::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Nachrichten
+bool accountSuchenDetailsKlick( void *p, void *obj, MausEreignis me )
+{
+	if( p )
+		return ( (AccountSuchen*)p )->detailsKlick( (Knopf*)obj, me );
+	return 1;
+}

+ 64 - 0
KSGClient/NachLogin/Account/Suchen/AccountSuchen.h

@@ -0,0 +1,64 @@
+#ifndef AccountSuchen_H
+#define AccountSuchen_H
+
+#include <Knopf.h>
+#include <Tabelle.h>
+#include <AuswahlBox.h>
+#include <Animation.h>
+#include <Thread.h>
+
+using namespace Framework;
+
+class AccountSuchen : private Thread
+{
+private:
+	Schrift *schrift;
+	Punkt pos;
+	Punkt gr;
+	Animation2D *laden;
+	TextFeld *accountName;
+	Knopf *suchen;
+	AuswahlBox *sortSpalte;
+	AuswahlBox *sortRichtung;
+	Knopf *zurück;
+	TextFeld *seite;
+	Knopf *vor;
+	ObjTabelle *liste;
+	Critical cs;
+	int auswahl;
+	double tickVal;
+	bool sichtbar;
+	int jetztSeite;
+	int maxSeite;
+	unsigned char alpha;
+	bool rend;
+	int ref;
+	// privat
+	void lock();
+	void unlock();
+	void tabelleLehren( bool überschrift );
+
+public:
+	// Konstruktor
+	AccountSuchen( Schrift *schrift );
+	// Destruktor
+	~AccountSuchen();
+	// nicht constant
+	void setSichtbar( bool sichtbar );
+	void thread();
+	bool detailsKlick( Knopf *zKnopf, MausEreignis &me );
+	void doMausEreignis( MausEreignis &me );
+	void doTastaturEreignis( TastaturEreignis &te );
+	bool tick( double tickVal );
+	void render( Bild &zRObj );
+	int getAuswahlAccountId();
+	// constant
+	// Reference Counting
+	AccountSuchen *getThis();
+	AccountSuchen *release();
+};
+
+// Nachrichten
+bool accountSuchenDetailsKlick( void *p, void *obj, MausEreignis me );
+
+#endif

+ 1421 - 0
KSGClient/NachLogin/Chat/ChatLeiste.cpp

@@ -0,0 +1,1421 @@
+#include "ChatLeiste.h"
+#include "..\..\Global\Initialisierung.h"
+#include <Bild.h>
+#include <Rahmen.h>
+#include <Punkt.h>
+#include "..\..\Global\Variablen.h"
+#include <DateiSystem.h>
+#include <ToolTip.h>
+#include <GSLDateiV.h>
+
+typedef GSL::GSLDateiV *( *GetGSLDatei )( );
+
+// Inhalt der Chat Klasse aus ChatLeiste.h
+// Konstruktor
+Chat::Chat( Schrift *zSchrift )
+{
+	Bild *minimierenBild = bilder->get( "chat.ltdb/minimieren.png" );
+	if( !minimierenBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		minimierenBild = datei->laden( 0, new Text( "minimieren.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/minimieren.png", minimierenBild->getThis() );
+	}
+	Bild *closeBild = bilder->get( "chat.ltdb/entfernen.png" );
+	if( !closeBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		closeBild = datei->laden( 0, new Text( "entfernen.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/entfernen.png", closeBild->getThis() );
+	}
+	rahmen = new LRahmen();
+	rahmen->setAlpha( 1 );
+	rahmen->setFarbe( 0xFFFFFFFF );
+	rahmen->setRamenBreite( 1 );
+	verlauf = initTextFeld( 7, 7, 184, 210, zSchrift, TextFeld::Style::TextGebiet, "" );
+	verlauf->removeStyle( TextFeld::Style::Erlaubt );
+	verlauf->updateVScroll();
+	nachricht = initTextFeld( 1, 220, 198, 20, zSchrift, TextFeld::Style::TextFeld, "" );
+	initToolTip( nachricht, "Nachricht senden.", zSchrift->getThis(), hauptScreen );
+	name = initTextFeld( 1, 250, 198, 29, zSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, "" );
+	minimieren = initKnopf( 159, 255, 20, 20, 0, 0, "" );
+	minimieren->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	minimieren->setHintergrundBildZ( minimierenBild );
+	initToolTip( minimieren, "Fenster einklappen.", zSchrift->getThis(), hauptScreen );
+	close = initKnopf( 179, 255, 20, 20, 0, 0, "" );
+	close->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	close->setHintergrundBildZ( closeBild );
+	initToolTip( close, "Fenster schließen.", zSchrift->getThis(), hauptScreen );
+	bildschirmGröße = BildschirmGröße();
+	admin = 0;
+	tickVal = 0;
+	sichtbar = 1;
+	breite = 0;
+	höhe = 30;
+	animation = 1;
+	rend = 0;
+	msgSound = 0;
+	HMODULE dll = dllDateien->ladeDLL( "GSL.dll", "data/bin/GSL.dll" );
+	if( dll )
+	{
+		GetGSLDatei getGSLDatei = (GetGSLDatei)GetProcAddress( dll, "getGSLDatei" );
+		if( getGSLDatei )
+		{
+			GSL::GSLDateiV *sDat = getGSLDatei();
+			sDat->setDatei( "data/sounds/popup.gsl" );
+			sDat->leseDaten();
+			msgSound = sDat->getSound( "chat.wav" );
+			sDat->release();
+			if( msgSound )
+				msgSound->setVolume( 0xFFFF, 0xFFFF );
+		}
+		if( !msgSound )
+			dllDateien->releaseDLL( "GSL.dll" );
+	}
+	ref = 1;
+}
+
+// Destruktor
+Chat::~Chat()
+{
+	if( msgSound )
+	{
+		msgSound->release();
+		dllDateien->releaseDLL( "GSL.dll" );
+	}
+	rahmen = rahmen->release();
+	verlauf = verlauf->release();
+	nachricht = nachricht->release();
+	name = name->release();
+	minimieren = minimieren->release();
+	close = close->release();
+}
+
+// nicht constant
+void Chat::setSichtbar( bool sichtbar )
+{
+	if( sichtbar )
+		animation = 2;
+	else
+		animation = 3;
+	this->sichtbar = sichtbar;
+}
+
+void Chat::entfernen()
+{
+	animation = 4;
+}
+
+void Chat::addNachricht( char *txt )
+{
+	if( msgSound )
+	    msgSound->playSound();
+	Text *n = new Text( txt );
+	if( txt[ 0 ] != '\r' )
+		n->append( "\r0xFFFFFFFF" );
+	verlauf->zSchrift()->textFormatieren( n, verlauf->getBreite() - 20, verlauf->getSchriftSize() );
+	if( n->getText()[ n->getLength() - 1 ] != '\n' )
+		n->append( "\n" );
+	verlauf->zText()->append( n );
+	if( animation != 4 )
+		animation = 2;
+	verlauf->updateVScroll();
+	rend = 1;
+}
+
+void Chat::setAdmin()
+{
+	admin = 1;
+	rend = 1;
+}
+
+void Chat::addSpieler( int accountId )
+{
+	// nur bei chatroom
+}
+
+void Chat::removeSpieler( int accountId )
+{
+	// nur bei chatroom
+}
+
+bool Chat::tick( double tickVal )
+{
+	// virtual
+	return 0;
+}
+
+void Chat::doMausEreignis( MausEreignis &me )
+{
+	// virtual
+}
+
+void Chat::doTastaturEreignis( TastaturEreignis &te )
+{
+	// virtual
+}
+
+void Chat::render( int x, Bild &zRObj )
+{
+	// virtual
+}
+
+// constant
+TextFeld *Chat::getName() const
+{
+	return name->getThis();
+}
+
+TextFeld *Chat::zName() const
+{
+	return name;
+}
+
+int Chat::getAccountId() const
+{
+	// nur bei chat
+	return 0;
+}
+
+int Chat::getChatroomId() const
+{
+	// nur bei chatroom
+	return 0;
+}
+
+int Chat::getBreite() const
+{
+	return breite;
+}
+
+bool Chat::istSichtbar() const
+{
+	return sichtbar;
+}
+
+// Reference Counting
+void *Chat::getThis()
+{
+	// virtual
+	return 0;
+}
+
+void *Chat::release()
+{
+	// virtual
+	return 0;
+}
+
+// Inhalt der ChatFenster Klasse aus ChatLeiste.h
+// Konstruktor
+ChatFenster::ChatFenster( Schrift *zSchrift, int accountId )
+	: Chat( zSchrift )
+{
+	this->accountId = accountId;
+	name->setTextZ( infoKlient->getSpielerName( accountId ) );
+}
+
+// Destruktor
+ChatFenster::~ChatFenster()
+{
+
+}
+
+// nicht constant
+bool ChatFenster::tick( double tickVal )
+{
+	rend |= close->tick( tickVal );
+	rend |= minimieren->tick( tickVal );
+	rend |= verlauf->tick( tickVal );
+	rend |= nachricht->tick( tickVal );
+	if( !animation )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	this->tickVal += tickVal * 300;
+	int val = ( int )this->tickVal;
+	if( val < 1 )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	if( val > 10 )
+		val = 10;
+	this->tickVal -= val;
+	switch( animation )
+	{
+	case 1: // erstellen
+	case 2: // ausfahren
+		if( breite == 200 )
+		{
+			höhe += val;
+			if( höhe > 280 )
+			{
+				höhe = 280;
+				animation = 0;
+			}
+		}
+		else
+		{
+			breite += val;
+			if( breite > 200 )
+				breite = 200;
+		}
+		rend = 1;
+		break;
+	case 3: // einfahren
+		if( höhe == 30 )
+		{
+			breite -= val;
+			if( breite < 100 )
+			{
+				breite = 100;
+				animation = 0;
+			}
+		}
+		else
+		{
+			höhe -= val;
+			if( höhe < 30 )
+				höhe = 30;
+		}
+		rend = 1;
+		break;
+	case 4: // close
+		if( höhe == 30 )
+		{
+			breite -= val;
+			if( breite < 0 )
+			{
+				nachLogin->zChatLeiste()->removeChat( this ); // delete this
+				return 1;
+			}
+		}
+		else
+		{
+			höhe -= val;
+			if( höhe < 30 )
+				höhe = 30;
+		}
+		rend = 1;
+		break;
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void ChatFenster::doMausEreignis( MausEreignis &me )
+{
+	bool tmp = me.verarbeitet;
+	if( me.mx < 0 || me.mx > breite || me.my < 280 - höhe || animation )
+		me.verarbeitet = 1;
+	verlauf->doMausEreignis( me );
+	bool vera = me.verarbeitet;
+	minimieren->doMausEreignis( me );
+	int aktion = me.verarbeitet && !vera ? 1 : 0;
+	close->doMausEreignis( me );
+	if( !aktion )
+		aktion = me.verarbeitet && !vera ? 2 : 0;
+	nachricht->doMausEreignis( me );
+	if( me.mx < 0 || me.mx > breite || me.my < 280 - höhe || animation )
+	{
+		me.verarbeitet = tmp;
+		return;
+	}
+	if( !aktion && !sichtbar && !vera )
+	{
+		if( me.mx < breite && me.mx > 0 && me.my > 250 && me.my < 280 )
+			aktion = 3;
+	}
+	switch( aktion )
+	{
+	case 1: // einfahren
+		if( me.id == ME_RLinks )
+			this->setSichtbar( 0 );
+		break;
+	case 2: // close
+		if( me.id == ME_RLinks )
+			animation = 4;
+		break;
+	case 3: // ausfahren
+		if( me.id == ME_RLinks )
+			this->setSichtbar( 1 );
+		break;
+	}
+}
+
+void ChatFenster::doTastaturEreignis( TastaturEreignis &te )
+{
+	bool tmp = te.verarbeitet;
+	if( animation )
+		te.verarbeitet = 1;
+	nachricht->doTastaturEreignis( te );
+	int aktion = te.verarbeitet && !tmp ? 1 : 0;
+	if( animation )
+	{
+		te.verarbeitet = tmp;
+		return;
+	}
+	switch( aktion )
+	{
+	case 1:
+		if( te.id == TE_Release && te.taste == T_Enter )
+		{
+			if( !nachricht->zText()->getLength() )
+				break;
+			nachricht->zText()->remove( "\n" );
+			if( chatKlient->chatNachricht( accountId, nachricht->zText()->getText() ) )
+			{
+				Text *n = new Text( nachricht->zText()->getText() );
+				n->insert( 0, "\r0xFF00FF00" );
+				n->append( "\r0xFFFFFFFF" );
+				verlauf->zSchrift()->textFormatieren( n, verlauf->getBreite() - 15, verlauf->getSchriftSize() );
+				if( n->getText()[ n->getLength() - 1 ] != '\n' )
+					n->append( "\n" );
+				verlauf->zText()->append( n->getText() );
+				n->release();
+				verlauf->updateVScroll();
+				nachricht->setText( "" );
+				nachricht->setAuswahl( 0, 0 );
+				rend = 1;
+			}
+		}
+		break;
+	}
+}
+
+void ChatFenster::render( int xPos, Bild &zRObj )
+{
+	int x = xPos;
+	int y = 280 - höhe;
+	int br = breite;
+	int hö = höhe;
+	if( !zRObj.setDrawOptions( x, y, br, hö ) )
+		return;
+	zRObj.alphaRegion( 0, 0, br, hö, 0xA0000000 );
+	rahmen->setSize( br, hö );
+	rahmen->render( zRObj );
+	zRObj.addScrollOffset( 0, 280 - höhe );
+	verlauf->render( zRObj );
+	nachricht->render( zRObj );
+	name->render( zRObj );
+	minimieren->render( zRObj );
+	close->render( zRObj );
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+int ChatFenster::getAccountId() const
+{
+	return accountId;
+}
+
+// Reference Counting
+void *ChatFenster::getThis()
+{
+	ref++;
+	return this;
+}
+
+void *ChatFenster::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Inhalt der ChatroomFenster Klasse aus ChatLeiste.h
+// Konstruktor
+ChatroomFenster::ChatroomFenster( Schrift *zSchrift, int chatroomId )
+	: Chat( zSchrift )
+{
+	Bild *maximierenBild = bilder->get( "chat.ltdb/maximieren.png" );
+	if( !maximierenBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		maximierenBild = datei->laden( 0, new Text( "maximieren.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/maximieren.png", maximierenBild->getThis() );
+	}
+	this->chatroomId = chatroomId;
+	spielerName = initTextFeld( 200, 5, 120, 0, zSchrift, TextFeld::Style::TextFeld, "" );
+	initToolTip( spielerName, "Name des Spielers der eingeladen werden soll.", zSchrift->getThis(), hauptScreen );
+	einladen = initKnopf( 325, 5, 20, 0, 0, 0, "" );
+	einladen->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	einladen->setHintergrundBildZ( maximierenBild );
+	initToolTip( einladen, "Spieler ins Chatroom einladen.", zSchrift->getThis(), hauptScreen );
+	spieler = new ObjTabelle();
+	spieler->setMausEreignis( _ret1ME );
+	spieler->setStyle( ObjTabelle::Style::Sichtbar | ObjTabelle::Style::Rahmen | ObjTabelle::Style::VScroll | ObjTabelle::Style::Erlaubt | ObjTabelle::Style::VScroll | ObjTabelle::Style::Raster );
+	spieler->setVertikalKlickScroll( 5 );
+	spieler->setPosition( 200, 1 );
+	spieler->setSize( 149, 240 );
+	spieler->setRasterFarbe( 0xFF555555 );
+	spieler->setLinienRahmenFarbe( 0xFFFFFFFF );
+	spieler->addSpalte( 0, "Name" );
+	spieler->addSpalte( 1, "Freund" );
+	spieler->addSpalte( 2, "Kick" );
+	spieler->setSpaltenBreite( 0, 110 );
+	spieler->setSpaltenBreite( 1, 20 );
+	spieler->setSpaltenBreite( 2, 0 );
+	schrift = zSchrift->getThis();
+	name->setTextZ( infoKlient->getChatroomName( chatroomId ) );
+	close->setPosition( close->getX() + 150, close->getY() );
+	minimieren->setPosition( minimieren->getX() + 150, minimieren->getY() );
+	neueSpieler = new Array< int >();
+	alteSpieler = new Array< int >();
+	neueSpielerAnzahl = 0;
+	alteSpielerAnzahl = 0;
+}
+
+// Destruktor
+ChatroomFenster::~ChatroomFenster()
+{
+	chatKlient->chatroomVerlassen( chatroomId );
+	schrift = schrift->release();
+	neueSpieler = neueSpieler->release();
+	alteSpieler = alteSpieler->release();
+	for( int i = 0; i < spieler->getZeilenAnzahl(); i++ )
+	{
+		TextFeld *name = (TextFeld*)spieler->zZeichnung( 0, 0 );
+		name = name->release();
+		Knopf *freund = (Knopf*)spieler->zZeichnung( 1, 0 );
+		freund = freund->release();
+		Knopf *entfernen = (Knopf*)spieler->zZeichnung( 2, 0 );
+		entfernen = entfernen->release();
+		spieler->removeZeile( 0 );
+	}
+	for( int i = 0; i < 3; i++ )
+		spieler->removeSpalte( 0 );
+	spieler = spieler->release();
+	spielerName = spielerName->release();
+	einladen = einladen->release();
+}
+
+// nicht constant
+void ChatroomFenster::addSpieler( int accountId )
+{
+	Text *zeile = new Text();
+	zeile->append( accountId );
+	if( spieler->getZeilenNummer( zeile->getText() ) >= 0 )
+		return;
+	Bild *einladenBild = bilder->get( "chat.ltdb/maximieren.png" );
+	if( !einladenBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		einladenBild = datei->laden( 0, new Text( "maximieren.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/maximieren.png", einladenBild->getThis() );
+	}
+	Bild *closeBild = bilder->get( "chat.ltdb/entfernen.png" );
+	if( !closeBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		closeBild = datei->laden( 0, new Text( "entfernen.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/entfernen.png", closeBild->getThis() );
+	}
+	spieler->addZeile( zeile->getText() );
+	spieler->setZeilenHeight( zeile->getText(), 0 );
+	Text *name = infoKlient->getSpielerName( accountId );
+	TextFeld *sName = initTextFeld( 0, 0, 110, 20, schrift, TextFeld::Style::Sichtbar | TextFeld::Style::Text | TextFeld::Style::Center, name->getText() );
+	name = name->release();
+	spieler->setZeichnungZ( "Name", zeile->getText(), sName );
+	Knopf *freund = initKnopf( 0, 0, 20, 20, 0, 0, "" );
+	freund->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	freund->setHintergrundBildZ( einladenBild->getThis() );
+	freund->setMausEreignisParameter( this );
+	freund->setMausEreignis( chatroomFensterFreundME );
+	initToolTip( freund, "Freundeseinladung an den Spieler schicken.", schrift->getThis(), hauptScreen );
+	spieler->setZeichnungZ( "Freund", zeile->getText(), freund );
+	Knopf *entfernen = initKnopf( 0, 0, 0, 20, 0, 0, "" );
+	entfernen->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	entfernen->setHintergrundBildZ( closeBild );
+	entfernen->setMausEreignisParameter( this );
+	entfernen->setMausEreignis( chatroomFensterEntfernenME );
+	initToolTip( entfernen, "Spieler aus Chatroom entfernen.", schrift->getThis(), hauptScreen );
+	spieler->setZeichnungZ( "Kick", zeile->getText(), entfernen );
+	neueSpieler->add( accountId, neueSpielerAnzahl );
+	neueSpielerAnzahl++;
+	zeile = zeile->release();
+	rend = 1;
+}
+
+void ChatroomFenster::removeSpieler( int accountId )
+{
+	Text *zeile = new Text();
+	zeile->append( accountId );
+	if( spieler->getZeilenNummer( zeile ) >= 0 )
+	{
+		alteSpieler->add( accountId, alteSpielerAnzahl );
+		alteSpielerAnzahl++;
+		rend = 1;
+	}
+}
+
+bool ChatroomFenster::tick( double tickVal )
+{
+	rend |= close->tick( tickVal );
+	rend |= minimieren->tick( tickVal );
+	rend |= einladen->tick( tickVal );
+	rend |= spieler->tick( tickVal );
+	rend |= spielerName->tick( tickVal );
+	rend |= verlauf->tick( tickVal );
+	rend |= nachricht->tick( tickVal );
+	this->tickVal += tickVal * 300;
+	int val = ( int )this->tickVal;
+	if( val < 1 )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	if( val > 10 )
+		val = 10;
+	this->tickVal -= val;
+	switch( animation )
+	{
+	case 1: // erstellen
+	case 2: // ausfahren
+		if( breite == 350 )
+		{
+			höhe += val;
+			if( höhe > 280 )
+			{
+				höhe = 280;
+				animation = 0;
+			}
+		}
+		else
+		{
+			breite += val;
+			if( breite > 350 )
+				breite = 350;
+		}
+		rend = 1;
+		break;
+	case 3: // einfahren
+		if( höhe == 30 )
+		{
+			breite -= val;
+			if( breite < 100 )
+			{
+				breite = 100;
+				animation = 0;
+			}
+		}
+		else
+		{
+			höhe -= val;
+			if( höhe < 30 )
+				höhe = 30;
+		}
+		rend = 1;
+		break;
+	case 4: // close
+		if( höhe == 30 )
+		{
+			breite -= val;
+			if( breite < 0 )
+			{
+				nachLogin->zChatLeiste()->removeChat( this ); // delete this
+				return 1;
+			}
+		}
+		else
+		{
+			höhe -= val;
+			if( höhe < 30 )
+				höhe = 30;
+		}
+		rend = 1;
+		break;
+	}
+	Text *zeile = new Text( "" );
+	for( int i = 0; i < neueSpielerAnzahl; i++ )
+	{
+		int id = neueSpieler->hat( i ) ? neueSpieler->get( i ) : 0;
+		zeile->append( id );
+		int z = spieler->getZeilenNummer( zeile->getText() );
+		spieler->setZeilenHeight( z, spieler->getZeilenHeight( z ) + val / 2 );
+		if( spieler->getZeilenHeight( z ) > 20 )
+		{
+			spieler->setZeilenHeight( z, 20 );
+			neueSpieler->remove( i );
+			neueSpielerAnzahl--;
+			i--;
+		}
+		zeile->setText( "" );
+		rend = 1;
+	}
+	for( int i = 0; i < alteSpielerAnzahl; i++ )
+	{
+		int id = alteSpieler->hat( i ) ? alteSpieler->get( i ) : 0;
+		zeile->append( id );
+		int z = spieler->getZeilenNummer( zeile->getText() );
+		spieler->setZeilenHeight( z, spieler->getZeilenHeight( z ) - val / 2 );
+		if( spieler->getZeilenHeight( z ) <= 0 )
+		{
+			TextFeld *name = (TextFeld*)spieler->zZeichnung( 0, z );
+			name = name->release();
+			Knopf *freund = (Knopf*)spieler->zZeichnung( 1, z );
+			freund = freund->release();
+			Knopf *entfernen = (Knopf*)spieler->zZeichnung( 2, z );
+			entfernen = entfernen->release();
+			spieler->removeZeile( z );
+			alteSpieler->remove( i );
+			alteSpielerAnzahl--;
+			i--;
+		}
+		zeile->setText( "" );
+		rend = 1;
+	}
+	zeile = zeile->release();
+	if( admin )
+	{
+		if( spielerName->getHeight() != 20 )
+		{
+			spielerName->setSize( spielerName->getBreite(), spielerName->getHeight() + val / 2 );
+			einladen->setSize( einladen->getBreite(), einladen->getHeight() + val / 2 );
+			spieler->setPosition( spieler->getX(), spieler->getY() + val / 2 );
+			spieler->setSize( spieler->getBreite(), spieler->getHeight() - val / 2 );
+			if( spielerName->getHeight() >= 20 )
+			{
+				spielerName->setSize( spielerName->getBreite(), 20 );
+				einladen->setSize( einladen->getBreite(), 20 );
+				spieler->setPosition( spieler->getX(), 30 );
+				spieler->setSize( spieler->getBreite(), 210 );
+			}
+			rend = 1;
+		}
+		if( spieler->getSpaltenBreite( 2 ) != 20 )
+		{
+			spieler->setSpaltenBreite( 2, spieler->getSpaltenBreite( 2 ) + val / 2 );
+			spieler->setSpaltenBreite( 0, spieler->getSpaltenBreite( 0 ) - val / 2 );
+			if( spieler->getSpaltenBreite( 2 ) > 20 )
+			{
+				spieler->setSpaltenBreite( 2, 20 );
+				spieler->setSpaltenBreite( 0, 90 );
+			}
+			rend = 1;
+		}
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void ChatroomFenster::doMausEreignis( MausEreignis &me )
+{
+	bool tmp = me.verarbeitet;
+	if( me.mx < 0 || me.mx > breite || me.my < 280 - höhe || animation )
+		me.verarbeitet = 1;
+	verlauf->doMausEreignis( me );
+	bool vera = me.verarbeitet;
+	minimieren->doMausEreignis( me );
+	int aktion = me.verarbeitet && !vera ? 1 : 0;
+	close->doMausEreignis( me );
+	if( !aktion )
+		aktion = me.verarbeitet && !vera ? 2 : 0;
+	einladen->doMausEreignis( me );
+	if( !aktion )
+		aktion = me.verarbeitet && !vera ? 4 : 0;
+	nachricht->doMausEreignis( me );
+	spielerName->doMausEreignis( me );
+	spieler->doMausEreignis( me );
+	if( me.mx < 0 || me.mx > breite || me.my < 280 - höhe || animation )
+	{
+		me.verarbeitet = tmp;
+		return;
+	}
+	if( !aktion && !sichtbar && !vera )
+	{
+		if( me.mx < breite && me.mx > 0 && me.my > 250 && me.my < 280 )
+			aktion = 3;
+	}
+	switch( aktion )
+	{
+	case 1: // einfahren
+		if( me.id == ME_RLinks )
+			this->setSichtbar( 0 );
+		break;
+	case 2: // close
+		if( me.id == ME_RLinks )
+			animation = 4;
+		break;
+	case 3: // ausfahren
+		if( me.id == ME_RLinks )
+			this->setSichtbar( 1 );
+		break;
+	case 4: // einladen
+		if( me.id != ME_RLinks )
+			break;
+		if( spielerName->zText()->getLength() )
+		{
+			int accountId = infoKlient->getAccountId( spielerName->zText()->getText() );
+			if( accountId )
+			{
+				if( chatKlient->chatroomEinladung( accountId, chatroomId ) )
+				{
+					nachLogin->zNachrichtenListe()->addNachricht( new Text( "Chatroom Einladung" ), new Text( "Es wurde eine Chatroom Einladung an den Spieler gesendet." ),
+																  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+					spielerName->setText( "" );
+					spielerName->setAuswahl( 0, 0 );
+					rend = 1;
+				}
+			}
+			else
+			{
+				nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Der Spieler wurde nicht gefunden." ),
+															  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+			}
+		}
+		break;
+	}
+}
+
+void ChatroomFenster::doTastaturEreignis( TastaturEreignis &te )
+{
+	bool tmp = te.verarbeitet;
+	if( animation )
+		te.verarbeitet = 1;
+	nachricht->doTastaturEreignis( te );
+	int aktion = te.verarbeitet && !tmp ? 1 : 0;
+	if( admin )
+	{
+		spielerName->doTastaturEreignis( te );
+		if( !aktion )
+			aktion = te.verarbeitet && !tmp ? 2 : 0;
+	}
+	if( animation )
+	{
+		te.verarbeitet = tmp;
+		return;
+	}
+	switch( aktion )
+	{
+	case 1:
+		if( te.id == TE_Release && te.taste == T_Enter )
+		{
+			nachricht->zText()->remove( "\n" );
+			chatKlient->chatroomNachricht( chatroomId, nachricht->zText()->getText() );
+			nachricht->setText( "" );
+			nachricht->setAuswahl( 0, 0 );
+			rend = 1;
+		}
+		break;
+	case 2:
+		if( te.id == TE_Release && te.taste == T_Enter )
+		{
+			if( !spielerName->zText()->getLength() )
+				break;
+			int accountId = infoKlient->getAccountId( spielerName->zText()->getText() );
+			if( accountId )
+			{
+				if( chatKlient->chatroomEinladung( accountId, chatroomId ) )
+				{
+					nachLogin->zNachrichtenListe()->addNachricht( new Text( "Chatroom Einladung" ), new Text( "Es wurde eine Chatroom Einladung an den Spieler gesendet." ),
+																  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+					spielerName->setText( "" );
+					spielerName->setAuswahl( 0, 0 );
+					rend = 1;
+				}
+			}
+			else
+			{
+				nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Der Spieler wurde nicht gefunden." ),
+															  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+			}
+		}
+		break;
+	}
+}
+
+void ChatroomFenster::render( int xPos, Bild &zRObj )
+{
+	int x = xPos;
+	int y = 280 - höhe;
+	int br = breite;
+	int hö = höhe;
+	if( !zRObj.setDrawOptions( x, y, br, hö ) )
+		return;
+	zRObj.alphaRegion( 0, 0, br, hö, 0x88000000 );
+	rahmen->setSize( br, hö );
+	rahmen->render( zRObj );
+	zRObj.addScrollOffset( 0, 280 - höhe );
+	verlauf->render( zRObj );
+	nachricht->render( zRObj );
+	spieler->render( zRObj );
+	name->render( zRObj );
+	minimieren->render( zRObj );
+	close->render( zRObj );
+	if( spielerName->getHeight() )
+	{
+		spielerName->render( zRObj );
+		einladen->render( zRObj );
+	}
+	zRObj.releaseDrawOptions();
+}
+
+bool ChatroomFenster::druckFreund( void *obj, MausEreignis &me )
+{
+	if( me.id == ME_RLinks )
+	{
+		Punkt p = spieler->getZeichnungPosition( (Zeichnung*)obj );
+		if( p.y >= 0 )
+		{
+			int accountId = TextZuInt( spieler->zZeilenName( p.y )->getText(), 10 );
+			if( chatKlient->freundesAnfrage( accountId ) )
+			{
+				nachLogin->zNachrichtenListe()->addNachricht( new Text( "Freundes Einladung" ), new Text( "Es wurde eine Freundesanfrage an den Spieler gesendet." ),
+															  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+			}
+		}
+		return 0;
+	}
+	return 1;
+}
+
+bool ChatroomFenster::druckEntfernen( void *obj, MausEreignis &me )
+{
+	if( me.id == ME_RLinks && admin )
+	{
+		Punkt p = spieler->getZeichnungPosition( (Zeichnung*)obj );
+		if( p.y >= 0 )
+		{
+			int accountId = TextZuInt( spieler->zZeilenName( p.y )->getText(), 10 );
+			if( chatKlient->chatroomKick( chatroomId, accountId ) )
+			{
+				nachLogin->zNachrichtenListe()->addNachricht( new Text( "Kick" ), new Text( "Der Spieler musste das Chatroom verlassen." ),
+															  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+			}
+		}
+		return 0;
+	}
+	return 1;
+}
+
+// constant
+int ChatroomFenster::getChatroomId() const
+{
+	return chatroomId;
+}
+
+// Reference Counting
+void *ChatroomFenster::getThis()
+{
+	ref++;
+	return this;
+}
+
+void *ChatroomFenster::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Inhalt der ChatLeisteObj Klasse aus ChatLeiste.h
+// Konstruktor
+ChatLeisteObj::ChatLeisteObj( Schrift *zSchrift )
+	: Zeichnung()
+{
+	schrift = zSchrift->getThis();
+	chats = new RCArray< Chat >();
+	hsb = new HScrollBar();
+	bildschirmGröße = BildschirmGröße();
+	anzahl = 0;
+	ref = 1;
+	nowME = -1;
+}
+
+// Destruktor
+ChatLeisteObj::~ChatLeisteObj()
+{
+	chats = chats->release();
+	hsb = (HScrollBar*)hsb->release();
+	schrift = schrift->release();
+}
+
+// nicht constant
+void ChatLeisteObj::chatNachricht( int vonAccount, char *txt )
+{
+	if( !vonAccount )
+		return;
+	lockZeichnung();
+	bool gefunden = 0;
+	for( int i = 0; i < anzahl; i++ )
+	{
+		Chat *tmp = chats->z( i );
+		if( tmp->getAccountId() == vonAccount )
+		{
+			tmp->addNachricht( txt );
+			gefunden = 1;
+			break;
+		}
+	}
+	if( !gefunden )
+	{
+		addChat( vonAccount, 0 );
+		chatNachricht( vonAccount, txt );
+	}
+	unlockZeichnung();
+}
+
+void ChatLeisteObj::chatroomNachricht( int chatroomId, char *txt )
+{
+	lockZeichnung();
+	bool gefunden = 0;
+	for( int i = 0; i < anzahl; i++ )
+	{
+		Chat *tmp = chats->z( i );
+		if( tmp->getChatroomId() == chatroomId )
+		{
+			tmp->addNachricht( txt );
+			gefunden = 1;
+			break;
+		}
+	}
+	if( !gefunden )
+	{
+		addChat( 0, chatroomId );
+		chatroomNachricht( chatroomId, txt );
+	}
+	unlockZeichnung();
+}
+
+void ChatLeisteObj::addChat( int accountId, int chatroomId )
+{
+	lockZeichnung();
+	bool gefunden = 0;
+	if( accountId )
+	{
+		for( int i = 0; i < anzahl; i++ )
+		{
+			Chat *tmp = chats->z( i );
+			if( tmp->getAccountId() == accountId )
+			{
+				tmp->setSichtbar( 1 );
+				gefunden = 1;
+				break;
+			}
+		}
+		if( !gefunden )
+		{
+			ChatFenster *neu = new ChatFenster( schrift, accountId );
+			chats->add( neu, anzahl );
+			anzahl++;
+			rend = 1;
+		}
+	}
+	else if( chatroomId )
+	{
+		for( int i = 0; i < anzahl; i++ )
+		{
+			Chat *tmp = chats->z( i );
+			if( tmp->getChatroomId() == chatroomId )
+			{
+				tmp->setSichtbar( 1 );
+				gefunden = 1;
+				break;
+			}
+		}
+		if( !gefunden )
+		{
+			ChatroomFenster *neu = new ChatroomFenster( schrift, chatroomId );
+			chats->add( neu, anzahl );
+			anzahl++;
+			rend = 1;
+		}
+	}
+	unlockZeichnung();
+}
+
+void ChatLeisteObj::removeChat( int accountId, int chatroomId )
+{
+	lockZeichnung();
+	if( accountId )
+	{
+		for( int i = 0; i < anzahl; i++ )
+		{
+			Chat *tmp = chats->z( i );
+			if( tmp->getAccountId() == accountId )
+				tmp->entfernen();
+		}
+	}
+	else if( chatroomId )
+	{
+		for( int i = 0; i < anzahl; i++ )
+		{
+			Chat *tmp = chats->z( i );
+			if( tmp->getChatroomId() == chatroomId )
+				tmp->entfernen();
+		}
+	}
+	rend = 1;
+	unlockZeichnung();
+}
+
+void ChatLeisteObj::removeChat( Chat *zChat )
+{
+	lockZeichnung();
+	for( int i = 0; i < anzahl; i++ )
+	{
+		if( chats->z( i ) == zChat )
+		{
+			chats->remove( i );
+			anzahl--;
+			rend = 1;
+			break;
+		}
+	}
+	unlockZeichnung();
+}
+
+void ChatLeisteObj::removeAll()
+{
+	lockZeichnung();
+	chats->leeren();
+	anzahl = 0;
+	rend = 1;
+	unlockZeichnung();
+}
+
+void ChatLeisteObj::addSpieler( int chatroomId, int accountId )
+{
+	if( !chatroomId || !accountId )
+		return;
+	lockZeichnung();
+	for( int i = 0; i < anzahl; i++ )
+	{
+		Chat *tmp = chats->z( i );
+		if( tmp->getChatroomId() == chatroomId )
+		{
+			tmp->addSpieler( accountId );
+			break;
+		}
+	}
+	unlockZeichnung();
+}
+
+void ChatLeisteObj::removeSpieler( int chatroomId, int accountId )
+{
+	lockZeichnung();
+	if( !chatroomId || !accountId )
+		return;
+	for( int i = 0; i < anzahl; i++ )
+	{
+		Chat *tmp = chats->z( i );
+		if( tmp->getChatroomId() == chatroomId )
+		{
+			tmp->removeSpieler( accountId );
+			break;
+		}
+	}
+	unlockZeichnung();
+}
+
+void ChatLeisteObj::setChatroomAdmin( int chatroomId )
+{
+	lockZeichnung();
+	for( int i = 0; i < anzahl; i++ )
+	{
+		Chat *tmp = chats->z( i );
+		if( tmp->getChatroomId() == chatroomId )
+		{
+			tmp->setAdmin();
+			break;
+		}
+	}
+	unlockZeichnung();
+}
+
+bool ChatLeisteObj::tick( double tickVal )
+{
+	rend |= hsb->getRend();
+	rend |= nachLogin->zChatLeiste()->tick( tickVal );
+	for( int i = 0; i < anzahl; i++ )
+		rend |= chats->z( i )->tick( tickVal );
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void ChatLeisteObj::doTastaturEreignis( TastaturEreignis &te )
+{
+	for( int i = 0; i < anzahl; i++ )
+		chats->z( i )->doTastaturEreignis( te );
+}
+
+void ChatLeisteObj::doMausEreignis( MausEreignis &me )
+{
+	int mx = me.mx;
+	int my = me.my;
+	me.my += 250;
+	me.mx += hsb->getScroll();
+	for( int i = 0; i < anzahl; i++ )
+	{
+		Chat *tmp = chats->z( i );
+		nowME = i;
+		tmp->doMausEreignis( me );
+		nowME = -1;
+		me.mx -= tmp->getBreite();
+	}
+	me.mx = mx;
+	me.my = my;
+	hsb->doMausMessage( 1, 30, bildschirmGröße.x - 20, 20, me );
+}
+
+void ChatLeisteObj::render( Bild &zRObj )
+{
+	int x = pos.x;
+	int y = pos.y;
+	int br = bildschirmGröße.x - 20;
+	int hö = 300;
+	if( !zRObj.setDrawOptionsErzwingen( x, y - 250, br, hö ) )
+		return;
+	int breite = 0;
+	for( int i = 0; i < anzahl; i++ )
+	{
+		Chat *tmp = chats->z( i );
+		tmp->render( breite - ( hsb ? hsb->getScroll() : 0 ), zRObj );
+		breite += tmp->getBreite();
+	}
+	if( hsb )
+	{
+		hsb->update( breite, bildschirmGröße.x - 22 );
+		hsb->render( 0, 280, bildschirmGröße.x - 22, 20, zRObj );
+	}
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+
+// Reference Counting
+ChatLeisteObj *ChatLeisteObj::getThis()
+{
+	ref++;
+	return this;
+}
+
+ChatLeisteObj *ChatLeisteObj::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Inhalt der ChatLeiste Klasse aus ChatLeiste.h
+// Konstruktor
+ChatLeiste::ChatLeiste( Schrift *zSchrift, Fenster *zNachLoginFenster )
+{
+	minimierenBild = bilder->get( "chat.ltdb/minimieren.png" );
+	if( !minimierenBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		minimierenBild = datei->laden( 0, new Text( "minimieren.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/minimieren.png", minimierenBild->getThis() );
+	}
+	maximierenBild = bilder->get( "chat.ltdb/maximieren.png" );
+	if( !maximierenBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		maximierenBild = datei->laden( 0, new Text( "maximieren.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/maximieren.png", maximierenBild->getThis() );
+	}
+	bildschirmGröße = BildschirmGröße();
+	fenster = initFenster( 20 - bildschirmGröße.x, bildschirmGröße.y - 50, bildschirmGröße.x, 50, 0, Fenster::Style::Sichtbar | Fenster::Style::Erlaubt | Fenster::Style::BodyHintergrund | Fenster::Style::Rahmen, "" );
+	fenster->setKBgFarbe( 0xFF000000 );
+	minMax = initKnopf( bildschirmGröße.x - 21, 1, 20, 20, 0, 0, "" );
+	minMax->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	minMax->setHintergrundBildZ( minimierenBild->getThis() );
+	minMax->setMausEreignisParameter( this );
+	minMax->setMausEreignis( chatLeisteMinMaxME );
+	initToolTip( minMax, "Chat Leiste minimieren.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( minMax );
+	chatLeiste = new ChatLeisteObj( zSchrift );
+	fenster->addMember( chatLeiste );
+	zNachLoginFenster->addMember( fenster );
+	tickVal = 0;
+	animation = 1;
+	ref = 1;
+	rend = 0;
+	chatKlient->chatNachrichtAnfrage();
+}
+
+// Destruktor
+ChatLeiste::~ChatLeiste()
+{
+	minimierenBild = minimierenBild->release();
+	maximierenBild = maximierenBild->release();
+	fenster = fenster->release();
+	minMax = minMax->release();
+	chatLeiste = chatLeiste->release();
+}
+
+// nicht constant
+void ChatLeiste::chatNachricht( int vonAccount, char *txt )
+{
+	chatLeiste->chatNachricht( vonAccount, txt );
+}
+
+void ChatLeiste::chatroomNachricht( int chatroomId, int vonAccount, char *txt )
+{
+	chatLeiste->chatroomNachricht( chatroomId, txt );
+}
+
+void ChatLeiste::addChat( int accountId, int chatroomId )
+{
+	chatLeiste->addChat( accountId, chatroomId );
+}
+
+void ChatLeiste::removeChat( int accountId, int chatroomId )
+{
+	chatLeiste->removeChat( accountId, chatroomId );
+}
+
+void ChatLeiste::removeChat( Chat *zChat )
+{
+	chatLeiste->removeChat( zChat );
+}
+
+void ChatLeiste::removeAll()
+{
+	chatLeiste->removeAll();
+}
+
+void ChatLeiste::addSpieler( int chatroomId, int accountId )
+{
+	chatLeiste->addSpieler( chatroomId, accountId );
+}
+
+void ChatLeiste::removeSpieler( int chatroomId, int accountId )
+{
+	chatLeiste->removeSpieler( chatroomId, accountId );
+}
+
+void ChatLeiste::setChatroomAdmin( int chatroomId )
+{
+	chatLeiste->setChatroomAdmin( chatroomId );
+}
+
+bool ChatLeiste::tick( double tickVal )
+{
+	this->tickVal += tickVal * 500;
+	int val = ( int )this->tickVal;
+	if( val < 1 )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	if( val > 16 )
+		val = 16;
+	this->tickVal -= val;
+	switch( animation )
+	{
+	case 1: // einfahren
+		if( fenster->getX() < 0 )
+			fenster->setPosition( fenster->getX() + val, fenster->getY() );
+		else
+		{
+			fenster->setPosition( 0, fenster->getY() );
+			animation = 0;
+		}
+		rend = 1;
+		break;
+	case 2: // ausfahren
+		if( fenster->getX() + fenster->getBreite() > 21 )
+			fenster->setPosition( fenster->getX() - val, fenster->getY() );
+		else
+		{
+			fenster->setPosition( 21 - fenster->getBreite(), fenster->getY() );
+			animation = 0;
+		}
+		rend = 1;
+		break;
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+bool ChatLeiste::druckMinMax( MausEreignis &me )
+{
+	if( animation )
+		return 1;
+	if( me.id == ME_RLinks )
+	{
+		if( minMax->zHintergrundBild() == minimierenBild )
+		{
+			animation = 2;
+			minMax->setHintergrundBildZ( maximierenBild->getThis() );
+			minMax->zToolTip()->setText( "Chat Leiste maximieren." );
+		}
+		else
+		{
+			animation = 1;
+			minMax->setHintergrundBildZ( minimierenBild->getThis() );
+			minMax->zToolTip()->setText( "Chat Leiste minimieren." );
+		}
+	}
+	return 1;
+}
+
+// constant
+
+// Reference Counting
+ChatLeiste *ChatLeiste::getThis()
+{
+	ref++;
+	return this;
+}
+
+ChatLeiste *ChatLeiste::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Nachrichten
+bool chatLeisteMinMaxME( void *p, void *obj, MausEreignis me )
+{
+	return ( (ChatLeiste*)p )->druckMinMax( me );
+}
+
+bool chatroomFensterFreundME( void *p, void *obj, MausEreignis me )
+{
+	return ( (ChatroomFenster*)p )->druckFreund( obj, me );
+}
+
+bool chatroomFensterEntfernenME( void *p, void *obj, MausEreignis me )
+{
+	return ( (ChatroomFenster*)p )->druckEntfernen( obj, me );
+}

+ 200 - 0
KSGClient/NachLogin/Chat/ChatLeiste.h

@@ -0,0 +1,200 @@
+#ifndef ChatLeiste_H
+#define ChatLeiste_H
+
+#include <Klient.h>
+#include <Zeichnung.h>
+#include <TextFeld.h>
+#include <Fenster.h>
+#include <Knopf.h>
+#include <Scroll.h>
+#include <Tabelle.h>
+#include <GSLSoundV.h>
+
+using namespace Framework;
+using namespace Network;
+
+class Chat
+{
+protected:
+	LRahmen *rahmen;
+	TextFeld *verlauf;
+	TextFeld *nachricht;
+	TextFeld *name;
+	Knopf *minimieren;
+	Knopf *close;
+	Punkt bildschirmGröße;
+	GSL::GSLSoundV *msgSound;
+	bool admin;
+	double tickVal;
+	bool sichtbar;
+	int animation;
+	int breite;
+	int höhe;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	Chat( Schrift *zSchrift );
+	// Destruktor
+	~Chat();
+	// nicht constant
+	void setSichtbar( bool sichtbar );
+	void entfernen();
+	void addNachricht( char *txt );
+	void setAdmin();
+	virtual void addSpieler( int accountId );
+	virtual void removeSpieler( int accountId );
+	virtual bool tick( double tickVal );
+	virtual void doMausEreignis( MausEreignis &me );
+	virtual void doTastaturEreignis( TastaturEreignis &te );
+	virtual void render( int x, Bild &zRObj );
+	// constant
+	TextFeld *getName() const;
+	TextFeld *zName() const;
+	virtual int getAccountId() const;
+	virtual int getChatroomId() const;
+	int getBreite() const;
+	bool istSichtbar() const;
+	// Reference Counting
+	virtual void *getThis();
+	virtual void *release();
+};
+
+class ChatFenster : public Chat
+{
+private:
+	int accountId;
+
+public:
+	// Konstruktor
+	ChatFenster( Schrift *zSchrift, int accountId );
+	// Destruktor
+	~ChatFenster();
+	// nicht constant
+	bool tick( double tickVal ) override;
+	void doMausEreignis( MausEreignis &me ) override;
+	void doTastaturEreignis( TastaturEreignis &te ) override;
+	void render( int x, Bild &zRObj ) override;
+	// constant
+	int getAccountId() const override;
+	// Reference Counting
+	void *getThis() override;
+	void *release() override;
+};
+
+class ChatroomFenster : public Chat
+{
+private:
+	int chatroomId;
+	ObjTabelle *spieler;
+	Schrift *schrift;
+	Array< int > *neueSpieler;
+	int neueSpielerAnzahl;
+	Array< int > *alteSpieler;
+	int alteSpielerAnzahl;
+	TextFeld *spielerName;
+	Knopf *einladen;
+
+public:
+	// Konstruktor
+	ChatroomFenster( Schrift *zSchrift, int chatroomId );
+	// Destruktor
+	~ChatroomFenster();
+	// nicht constant
+	void addSpieler( int accountId ) override;
+	void removeSpieler( int accountId ) override;
+	bool tick( double tickVal ) override;
+	void doMausEreignis( MausEreignis &me ) override;
+	void doTastaturEreignis( TastaturEreignis &te ) override;
+	void render( int x, Bild &zRObj ) override;
+	bool druckFreund( void *obj, MausEreignis &me );
+	bool druckEntfernen( void *obj, MausEreignis &me );
+	// constant
+	virtual int getChatroomId() const;
+	// Reference Counting
+	virtual void *getThis();
+	virtual void *release();
+};
+
+class ChatLeisteObj : public Zeichnung
+{
+private:
+	RCArray< Chat > *chats;
+	HScrollBar *hsb;
+	Schrift *schrift;
+	Punkt bildschirmGröße;
+	int anzahl;
+	int ref;
+	int nowME;
+
+public:
+	// Konstruktor
+	ChatLeisteObj( Schrift *zSchrift );
+	// Destruktor
+	~ChatLeisteObj();
+	// nicht constant
+	void chatNachricht( int vonAccount, char *txt );
+	void chatroomNachricht( int chatroomId, char *txt );
+	void addChat( int accountId, int chatroomId );
+	void removeChat( int accountId, int chatroomId );
+	void removeChat( Chat *zChat );
+	void removeAll();
+	void addSpieler( int chatroomId, int accountId );
+	void removeSpieler( int chatroomId, int accountId );
+	void setChatroomAdmin( int chatroomId );
+	bool tick( double tickVal ) override;
+	void doTastaturEreignis( TastaturEreignis &te ) override;
+	void doMausEreignis( MausEreignis &me ) override;
+	void render( Bild &zRObj ) override;
+	// constant
+
+	// Reference Counting
+	ChatLeisteObj *getThis();
+	ChatLeisteObj *release();
+};
+
+class ChatLeiste
+{
+private:
+	Fenster *fenster;
+	Knopf *minMax;
+	ChatLeisteObj *chatLeiste;
+	Punkt bildschirmGröße;
+	Bild *minimierenBild;
+	Bild *maximierenBild;
+	double tickVal;
+	int animation;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	ChatLeiste( Schrift *zSchrift, Fenster *zNachLoginFenster );
+	// Destruktor
+	~ChatLeiste();
+	// nicht constant
+	void chatNachricht( int vonAccount, char *txt );
+	void chatroomNachricht( int chatroomId, int vonAccount, char *txt );
+	void addChat( int accountId, int chatroomId );
+	void removeChat( int accountId, int chatroomId );
+	void removeChat( Chat *zChat );
+	void removeAll();
+	void addSpieler( int chatroomId, int accountId );
+	void removeSpieler( int chatroomId, int accountId );
+	void setChatroomAdmin( int chatroomId );
+	bool tick( double tickVal );
+	bool druckMinMax( MausEreignis &me );
+	// constant
+
+	// Reference Counting
+	ChatLeiste *getThis();
+	ChatLeiste *release();
+};
+
+// Nachrichten
+bool chatLeisteMinMaxME( void *p, void *obj, MausEreignis me );
+bool chatroomFensterFreundME( void *p, void *obj, MausEreignis me );
+bool chatroomFensterEntfernenME( void *p, void *obj, MausEreignis me );
+
+#endif

+ 1255 - 0
KSGClient/NachLogin/Chat/FreundesListe.cpp

@@ -0,0 +1,1255 @@
+#include "FreundesListe.h"
+#include "..\..\Global\Variablen.h"
+#include "..\..\Global\Initialisierung.h"
+#include <Rahmen.h>
+#include <AlphaFeld.h>
+#include <MausEreignis.h>
+#include <Scroll.h>
+#include <Punkt.h>
+#include <DateiSystem.h>
+#include <Tooltip.h>
+
+// Inhalt der FreundData Klasse aus FreundesListe.h
+// Konstruktor
+FreundData::FreundData( int accountId, LRahmen *rahmen, AlphaFeld *auswahlBuffer, Schrift *zSchrift )
+	: Thread()
+{
+	Bild *entfernenBild = bilder->get( "chat.ltdb/entfernen.png" );
+	if( !entfernenBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		entfernenBild = datei->laden( 0, new Text( "entfernen.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/entfernen.png", entfernenBild->getThis() );
+	}
+	Bild *ansehenBild = bilder->get( "chat.ltdb/ansehen.png" );
+	if( !ansehenBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		ansehenBild = datei->laden( 0, new Text( "ansehen.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/ansehen.png", ansehenBild->getThis() );
+	}
+	Bild *nachrichtBild = bilder->get( "chat.ltdb/nachricht.png" );
+	if( !nachrichtBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		nachrichtBild = datei->laden( 0, new Text( "nachricht.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/nachricht.png", nachrichtBild->getThis() );
+	}
+	Bild *einladenBild = bilder->get( "chat.ltdb/neuerfreund.png" );
+	if( !einladenBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		einladenBild = datei->laden( 0, new Text( "neuerfreund.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/neuerfreund.png", einladenBild->getThis() );
+	}
+	this->accountId = accountId;
+	this->rahmen = rahmen;
+	this->auswahlBuffer = auswahlBuffer;
+	name = new TextFeld();
+	name->setStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Center );
+	name->setSchriftZ( zSchrift->getThis() );
+	name->setSchriftFarbe( 0xFFFFFFFF );
+	name->setSchriftSize( 12 );
+	name->setText( "" );
+	name->setSize( 200, 20 );
+	name->setPosition( 25, 1 );
+	status = new TextFeld();
+	status->setStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Center );
+	status->setSchriftZ( zSchrift->getThis() );
+	status->setSchriftFarbe( 0xFFFF0000 );
+	status->setSchriftSize( 12 );
+	status->setText( "offline" );
+	status->setSize( 200, 20 );
+	status->setPosition( 25, 24 );
+	entfernen = initKnopf( 228, 49, 20, 20, 0, 0, "" );
+	entfernen->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	entfernen->setHintergrundBildZ( entfernenBild );
+    entfernen->setHintergrundFarbe( 0 );
+	initToolTip( entfernen, "Freund entfernen.", zSchrift->getThis(), hauptScreen );
+	ansehen = initKnopf( 208, 49, 20, 20, 0, 0, "" );
+	ansehen->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	ansehen->setHintergrundBildZ( ansehenBild );
+    ansehen->setHintergrundFarbe( 0 );
+	initToolTip( ansehen, "Account ansehen.", zSchrift->getThis(), hauptScreen );
+	nachricht = initKnopf( 188, 49, 20, 20, 0, 0, "" );
+	nachricht->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	nachricht->setHintergrundBildZ( nachrichtBild );
+    nachricht->setHintergrundFarbe( 0 );
+	initToolTip( nachricht, "Nachricht senden.", zSchrift->getThis(), hauptScreen );
+	einladen = initKnopf( 168, 49, 20, 20, 0, 0, "" );
+	einladen->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	einladen->setHintergrundBildZ( einladenBild );
+    einladen->setHintergrundFarbe( 0 );
+	initToolTip( einladen, "Spieler in Gruppe einladen.\nDies kann nur der Gruppen Administrator.", zSchrift->getThis(), hauptScreen );
+	online = 0;
+	einladenSichtbar = 0;
+	ausgewählt = 0;
+	höhe = 0;
+	animation = 1;
+	auswahlAlpha = 0;
+	tickVal = 0;
+	rend = 0;
+	ref = 1;
+	start();
+}
+
+// Destruktor
+FreundData::~FreundData()
+{
+	rahmen = rahmen->release();
+	auswahlBuffer = auswahlBuffer->release();
+	name = name->release();
+	status = status->release();
+	entfernen = entfernen->release();
+	ansehen = ansehen->release();
+	nachricht = nachricht->release();
+	einladen = einladen->release();
+}
+
+// nicht constant
+void FreundData::thread()
+{
+	if( infoKlient )
+	{
+		Text *n = infoKlient->getSpielerName( accountId );
+		name->setTextZ( n );
+	}
+	run = 0;
+}
+
+void FreundData::setName( char *txt )
+{
+	name->setText( txt );
+	rend = 1;
+}
+
+void FreundData::setStatus( char *txt )
+{
+	status->setText( txt );
+	rend = 1;
+}
+
+void FreundData::setOnline( bool online )
+{
+	this->online = online;
+	if( online )
+	{
+		status->setSchriftFarbe( 0xFF00FF00 );
+		status->setText( "online" );
+	}
+	else
+	{
+		status->setSchriftFarbe( 0xFFFF0000 );
+		status->setText( "offline" );
+	}
+	einladen->setStyle( Knopf::Style::Erlaubt, einladenSichtbar && online );
+	rend = 1;
+}
+
+void FreundData::setAusgewählt( bool ausw )
+{
+	if( animation != 3 )
+	{
+		ausgewählt = ausw;
+		if( ausw )
+			animation = 2;
+		else
+			animation = 1;
+	}
+}
+
+void FreundData::remove()
+{
+	animation = 3;
+}
+
+void FreundData::zeigeEinladeKnopf( bool zeigen )
+{
+	einladenSichtbar = zeigen;
+	einladen->setStyle( Knopf::Style::Erlaubt, einladenSichtbar && online );
+	rend = 1;
+}
+
+void FreundData::doMausEreignis( MausEreignis &me )
+{
+	if( animation != 3 )
+	{
+		bool tmp = 0;
+		if( me.my > höhe || !ausgewählt )
+		{
+			tmp = me.verarbeitet;
+			me.verarbeitet = 1;
+		}
+		char aktion = 0;
+		bool vera = me.verarbeitet;
+		nachricht->doMausEreignis( me );
+		aktion = me.verarbeitet && !vera ? 1 : 0;
+		ansehen->doMausEreignis( me );
+		if( !aktion )
+			aktion = me.verarbeitet && !vera ? 2 : 0;
+		entfernen->doMausEreignis( me );
+		if( !aktion )
+			aktion = me.verarbeitet && !vera ? 3 : 0;
+		einladen->doMausEreignis( me );
+		if( !aktion )
+			aktion = me.verarbeitet && !vera ? 4 : 0;
+		if( me.my > höhe || !ausgewählt )
+		{
+			me.verarbeitet = tmp;
+			return;
+		}
+		switch( aktion )
+		{
+		case 1:
+			// Nachricht senden
+			if( me.id == ME_RLinks )
+				nachLogin->zChatLeiste()->addChat( accountId, 0 );
+			break;
+		case 2:
+			// profil ansehen
+			if( me.id == ME_RLinks )
+			{
+				if( nachLogin->zAccountAnsehenFenster()->setSpielerDetails( accountId, 2 ) )
+				{
+					MausEreignis me = { ME_RLinks, 0, 0, 0, 0, 0 };
+					nachLogin->zTitelLeiste()->druckAccountAnsehen( me );
+				}
+			}
+			break;
+		case 3:
+			// freund entfernen
+			if( me.id == ME_RLinks )
+			{
+				int *id = new int;
+				*id = accountId;
+				Text *nachricht = new Text( "Möchtest du deine Freundschaft mit " );
+				nachricht->append( name->zText()->getText() );
+				nachricht->append( " wirklich beenden?" );
+				nachLogin->zNachrichtenListe()->addNachricht( new Text( "Bist du dir Sicher?" ), nachricht, new Text( "ja" ),
+															  new Text( "abbrechen" ), NachrichtType::freundEntfernen, id );
+			}
+			break;
+		case 4: // In Gruppe einladen
+			if( me.id == ME_RLinks )
+			{
+				if( !anmeldungKlient->gruppeSpielerEinladen( accountId, nachLogin->zSpielenFenster()->getGruppeId() ) )
+				{
+					nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( anmeldungKlient->getLetzterFehler() ),
+																  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+				}
+			}
+		default:
+			// nichts
+			break;
+		}
+	}
+}
+
+bool FreundData::tick( double tickVal )
+{
+	rend |= name->tick( tickVal );
+	rend |= status->tick( tickVal );
+	rend |= entfernen->tick( tickVal );
+	rend |= ansehen->tick( tickVal );
+	rend |= nachricht->tick( tickVal );
+	rend |= einladen->tick( tickVal );
+	this->tickVal += tickVal * 100;
+	int val = ( int )this->tickVal;
+	if( val < 1 )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	if( val > 4 )
+		val = 4;
+	this->tickVal -= val;
+	switch( animation )
+	{
+	case 1:
+		if( höhe != 50 )
+		{
+			if( höhe > 50 )
+			{
+				höhe -= val;
+				if( höhe < 50 )
+					höhe = 50;
+			}
+			else
+			{
+				höhe += val;
+				if( höhe > 50 )
+					höhe = 50;
+			}
+			rend = 1;
+		}
+		else
+			animation = 0;
+		break;
+	case 2:
+		if( höhe != 70 )
+		{
+			höhe += val;
+			if( höhe > 70 )
+				höhe = 70;
+			rend = 1;
+		}
+		else
+			animation = 0;
+		break;
+	case 3:
+		höhe -= val;
+		if( höhe <= 0 )
+		{
+			nachLogin->zFreundesListe()->removeMember( this ); // delete this
+			return 1;
+		}
+		rend = 1;
+		break;
+	}
+	if( ausgewählt && auswahlAlpha < 50 )
+	{
+		if( auswahlAlpha + val > 50 )
+			auswahlAlpha = 50;
+		else
+			auswahlAlpha += val;
+		rend = 1;
+	}
+	else if( !ausgewählt && auswahlAlpha > 0 )
+	{
+		if( auswahlAlpha - val < 0 )
+			auswahlAlpha = 0;
+		else
+			auswahlAlpha -= val;
+		rend = 1;
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void FreundData::render( int yPos, Bild &zRObj )
+{
+	int br = 250;
+	if( !zRObj.setDrawOptions( 0, yPos, br, höhe ) )
+		return;
+	rahmen->setSize( br, höhe );
+	rahmen->render( zRObj );
+	int rbr = rahmen->getRBreite();
+	if( !zRObj.setDrawOptions( rbr, rbr, br - rbr * 2, höhe - rbr * 2 ) )
+	{
+		zRObj.releaseDrawOptions();
+		return;
+	}
+	if( auswahlAlpha > 0 )
+	{
+		auswahlBuffer->setFarbe( 0x0000FF00 | ( ( (int)auswahlAlpha << 24 ) & 0xFF000000 ) );
+		auswahlBuffer->setSize( br - rbr * 2, höhe - rbr * 2 );
+		auswahlBuffer->render( zRObj );
+	}
+	name->render( zRObj );
+	status->render( zRObj );
+	einladen->render( zRObj );
+	nachricht->render( zRObj );
+	ansehen->render( zRObj );
+	entfernen->render( zRObj );
+	zRObj.releaseDrawOptions();
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+bool FreundData::istOnline() const
+{
+	return online;
+}
+
+bool FreundData::istAusgewählt() const
+{
+	return ausgewählt;
+}
+
+char *FreundData::zName() const
+{
+	return name->zText()->getText();
+}
+
+Text *FreundData::getName() const
+{
+	return name->getText();
+}
+
+char *FreundData::zStatus() const
+{
+	return status->zText()->getText();
+}
+
+Text *FreundData::getStatus() const
+{
+	return status->getText();
+}
+
+int FreundData::getAccountId() const
+{
+	return accountId;
+}
+
+int FreundData::getHeight() const
+{
+	return höhe;
+}
+
+// reference Counting
+FreundData *FreundData::getThis()
+{
+	ref++;
+	return this;
+}
+
+FreundData *FreundData::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Inhalt der FreundesListeObj Klasse aus FreundesListe.h
+// Konstruktor
+FreundesListeObj::FreundesListeObj( Schrift *zSchrift )
+	: Zeichnung()
+{
+	members = new RCArray< FreundData >();
+	schrift = zSchrift->getThis();
+	memberRahmen = new LRahmen();
+	memberRahmen->setFarbe( 0xFFFFFFFF );
+	memberRahmen->setRamenBreite( 1 );
+	auswahlBuffer = new AlphaFeld();
+	auswahlBuffer->setStrength( -2 );
+	auswahlBuffer->setPosition( 1, 1 );
+	vsb = new VScrollBar();
+	vsb->setKlickScroll( 10 );
+	bildschirmGröße = BildschirmGröße();
+	vsb->update( 0, bildschirmGröße.y - 200 );
+	memberNummer = 0;
+	einladenSichtbar = 0;
+	ref = 1;
+}
+
+// Destruktor
+FreundesListeObj::~FreundesListeObj()
+{
+	members = members->release();
+	schrift = schrift->release();
+	memberRahmen = memberRahmen->release();
+	auswahlBuffer = auswahlBuffer->release();
+	vsb = (VScrollBar*)vsb->release();
+}
+
+// nicht constant
+void FreundesListeObj::addMember( int accountId )
+{
+	FreundData *tmp = new FreundData( accountId, memberRahmen->getThis(), auswahlBuffer->getThis(), schrift );
+	members->add( tmp, memberNummer );
+	memberNummer++;
+	if( einladenSichtbar )
+		tmp->zeigeEinladeKnopf( 1 );
+	rend = 1;
+}
+
+void FreundesListeObj::removeMember( int accountId )
+{
+	for( int i = 0; i < memberNummer; i++ )
+	{
+		FreundData *tmp = members->z( i );
+		if( tmp->getAccountId() == accountId )
+		{
+			tmp->remove();
+			break;
+		}
+	}
+}
+
+void FreundesListeObj::removeMember( FreundData *member )
+{
+	for( int i = 0; i < memberNummer; i++ )
+	{
+		if( members->z( i ) == member )
+		{
+			members->remove( i );
+			memberNummer--;
+			rend = 1;
+			break;
+		}
+	}
+}
+
+void FreundesListeObj::removeAll()
+{
+	members->leeren();
+	memberNummer = 0;
+	rend = 1;
+}
+
+void FreundesListeObj::setName( int accountId, char *txt )
+{
+	for( int i = 0; i < memberNummer; i++ )
+	{
+		FreundData *tmp = members->z( i );
+		if( tmp->getAccountId() == accountId )
+		{
+			tmp->setName( txt );
+			break;
+		}
+	}
+}
+
+void FreundesListeObj::setStatus( int accountId, char *txt )
+{
+	for( int i = 0; i < memberNummer; i++ )
+	{
+		FreundData *tmp = members->z( i );
+		if( tmp->getAccountId() == accountId )
+		{
+			tmp->setStatus( txt );
+			break;
+		}
+	}
+}
+
+void FreundesListeObj::setOnline( int accountId, bool online )
+{
+	for( int i = 0; i < memberNummer; i++ )
+	{
+		FreundData *tmp = members->z( i );
+		if( tmp->getAccountId() == accountId )
+		{
+			tmp->setOnline( online );
+			break;
+		}
+	}
+}
+
+void FreundesListeObj::zeigeEinladeKnopf( bool zeigen )
+{
+	einladenSichtbar = zeigen;
+	for( int i = 0; i < memberNummer; i++ )
+	{
+		FreundData *tmp = members->z( i );
+		tmp->zeigeEinladeKnopf( zeigen );
+	}
+}
+
+bool FreundesListeObj::tick( double tickVal )
+{
+	rend |= vsb->getRend();
+	rend |= nachLogin->zFreundesListe()->tick( tickVal );
+	for( int i = 0; i < memberNummer; i++ )
+	{
+		FreundData *tmp = members->z( i );
+		if( tmp )
+			rend |= tmp->tick( tickVal );
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void FreundesListeObj::doMausEreignis( MausEreignis &me )
+{
+	int my = me.my;
+	me.my -= pos.y;
+	if( me.mx <= 250 && me.mx > 0 && me.my >= 0 )
+	{
+		me.my += vsb->getScroll();
+		for( int i = 0; i < memberNummer; i++ )
+		{
+			FreundData *tmp = members->z( i );
+			if( tmp )
+			{
+				if( me.my > 0 && me.my < tmp->getHeight() )
+					tmp->setAusgewählt( 1 );
+				else
+					tmp->setAusgewählt( 0 );
+				tmp->doMausEreignis( me );
+				me.my -= tmp->getHeight();
+			}
+		}
+		me.my -= vsb->getScroll();
+	}
+	else
+	{
+		me.my += vsb->getScroll();
+		for( int i = 0; i < memberNummer; i++ )
+		{
+			FreundData *tmp = members->z( i );
+			if( tmp )
+			{
+				tmp->setAusgewählt( 0 );
+				tmp->doMausEreignis( me );
+				me.my -= tmp->getHeight();
+			}
+		}
+		me.my -= vsb->getScroll();
+	}
+	me.my = my;
+	vsb->doMausMessage( 250, pos.y, 20, gr.y, me );
+}
+
+void FreundesListeObj::render( Bild &zrObj )
+{
+	if( !zrObj.setDrawOptions( pos.x, pos.y, gr.x, gr.y ) )
+		return;
+	int höhe = 0;
+	for( int i = 0; i < memberNummer; i++ )
+	{
+		FreundData *tmp = members->z( i );
+		tmp->render( höhe, zrObj );
+		höhe += tmp->getHeight();
+	}
+	vsb->update( höhe, gr.y );
+	vsb->render( 250, 0, 20, gr.y, zrObj );
+	zrObj.releaseDrawOptions();
+}
+
+// constant
+bool FreundesListeObj::istFreund( int accId ) const
+{
+	for( int i = 0; i < memberNummer; i++ )
+	{
+		FreundData *tmp = members->z( i );
+		if( tmp->getAccountId() == accId )
+			return 1;
+	}
+	return 0;
+}
+
+// reference Counting
+FreundesListeObj *FreundesListeObj::getThis()
+{
+	ref++;
+	return this;
+}
+
+FreundesListeObj *FreundesListeObj::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Inhalt der FreundesListe Klasse aus FreundesListe.h
+// Konstruktor
+FreundesListe::FreundesListe( Schrift *zSchrift, Fenster *zNachLoginFenster )
+	: Thread()
+{
+	minimierenBild = bilder->get( "chat.ltdb/minimieren.png" );
+	if( !minimierenBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		minimierenBild = datei->laden( 0, new Text( "minimieren.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/minimieren.png", minimierenBild->getThis() );
+	}
+	maximierenBild = bilder->get( "chat.ltdb/maximieren.png" );
+	if( !maximierenBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		maximierenBild = datei->laden( 0, new Text( "maximieren.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/maximieren.png", maximierenBild->getThis() );
+	}
+	Bild *neuerFreundBild = bilder->get( "chat.ltdb/neuerfreund.png" );
+	if( !neuerFreundBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		neuerFreundBild = datei->laden( 0, new Text( "neuerfreund.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/neuerfreund.png", neuerFreundBild->getThis() );
+	}
+
+	bildschirmGröße = BildschirmGröße();
+
+	fenster = new Fenster();
+	fenster->setStyle( Fenster::Style::Sichtbar | Fenster::Style::Erlaubt | Fenster::Style::Rahmen | Fenster::Style::BodyHintergrund );
+	fenster->setSize( 270, 20 );
+	fenster->setRFarbe( 0xFFFFFFFF );
+	fenster->setKBgFarbe( 0xFF000000 );
+	fenster->setPosition( -250, 100 );
+
+	minMax = initKnopf( 249, 1, 20, 20, 0, 0, "" );
+	minMax->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	minMax->setHintergrundBildZ( minimierenBild->getThis() );
+	minMax->setMausEreignisParameter( this );
+	minMax->setMausEreignis( freundesListeMinMaxME );
+	initToolTip( minMax, "Freundes Leiste minimieren.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( minMax );
+
+	überschrift = initTextFeld( 0, 5, 250, 25, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center | TextFeld::Style::Sichtbar, "Freunde" );
+	überschrift->setSchriftSize( 15 );
+	fenster->addMember( überschrift );
+
+	accountName = initTextFeld( 25, 40, 200, 20, zSchrift, TextFeld::Style::TextFeld | TextFeld::Style::Sichtbar, "" );
+	accountName->setTastaturEreignisParameter( this );
+	accountName->setTastaturEreignis( freundesListeNameTE );
+	initToolTip( accountName, "Mit diesem Namen bist du bei anderen Spielern sichtbar.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( accountName );
+
+	LTDBDatei *chatBilder = new LTDBDatei();
+	chatBilder->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+	chatBilder->leseDaten( 0 );
+	Bild *neuerChatBild = chatBilder->laden( 0, new Text( "neuerchat.png" ) );
+	chatBilder = chatBilder->release();
+
+	neuerFreund = initKnopf( 5, 75, 20, 20, 0, 0, "" );
+	neuerFreund->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::HAlpha | Knopf::Style::KlickBuffer );
+	neuerFreund->setHintergrundBildZ( neuerFreundBild );
+	neuerFreund->setMausEreignisParameter( this );
+	neuerFreund->setMausEreignis( freundesListeNeuerFreundME );
+	initToolTip( neuerFreund, "Freundesanfrage senden.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( neuerFreund );
+
+	neuerChat = initKnopf( 30, 75, 20, 20, 0, 0, "" );
+	neuerChat->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::HAlpha | Knopf::Style::KlickBuffer );
+	neuerChat->setHintergrundBildZ( neuerChatBild );
+	neuerChat->setMausEreignisParameter( this );
+	neuerChat->setMausEreignis( freundesListeNeuerChatME );
+	initToolTip( neuerChat, "Nachricht senden.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( neuerChat );
+
+	neuerFreundFenster = initFenster( 0, 100, 270, 0, 0, Fenster::Style::Erlaubt | Fenster::Style::Rahmen, 0 );
+	neuerFreundSpielerName = initTextFeld( 5, 5, 235, 20, zSchrift, TextFeld::Style::Sichtbar | TextFeld::Style::TextFeld, "Spieler Name" );
+	neuerFreundSpielerName->setTastaturEreignisParameter( this );
+	neuerFreundSpielerName->setTastaturEreignis( freundesListeNeuerFreundSpielerNameTE );
+	initToolTip( neuerFreundSpielerName, "Name des Spielers an den eine Freundesanfrage gesendet werden soll.", zSchrift->getThis(), hauptScreen );
+	neuerFreundFenster->addMember( neuerFreundSpielerName );
+	neuerFreundFertig = initKnopf( 245, 5, 20, 20, 0, 0, "" );
+	neuerFreundFertig->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::HAlpha | Knopf::Style::KlickBuffer );
+	neuerFreundFertig->setHintergrundBildZ( maximierenBild->getThis() );
+	neuerFreundFertig->setMausEreignisParameter( this );
+	neuerFreundFertig->setMausEreignis( freundesListeNeuerFreundFertigME );
+	initToolTip( neuerFreundFertig, "Diesem Spieler eine Freundesanfrage senden.", zSchrift->getThis(), hauptScreen );
+	neuerFreundFenster->addMember( neuerFreundFertig );
+	fenster->addMember( neuerFreundFenster );
+
+	neuerChatFenster = initFenster( 0, 100, 270, 0, 0, Fenster::Style::Erlaubt | Fenster::Style::Rahmen, 0 );
+	neuerChatName = initTextFeld( 5, 5, 235, 20, zSchrift, TextFeld::Style::Sichtbar | TextFeld::Style::TextFeld, "Spieler Name" );
+	neuerChatName->setTastaturEreignisParameter( this );
+	neuerChatName->setTastaturEreignis( freundesListeNeuerChatNameTE );
+	initToolTip( neuerChatName, "Name des Spielers an den eine Nachricht gesendet werden soll.", zSchrift->getThis(), hauptScreen );
+	neuerChatFenster->addMember( neuerChatName );
+	neuerChatFertig = initKnopf( 245, 5, 20, 20, 0, 0, "" );
+	neuerChatFertig->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::HAlpha | Knopf::Style::KlickBuffer );
+	neuerChatFertig->setHintergrundBildZ( maximierenBild->getThis() );
+	neuerChatFertig->setMausEreignisParameter( this );
+	neuerChatFertig->setMausEreignis( freundesListeNeuerChatFertigME );
+	initToolTip( neuerChatFertig, "Diesem Spieler eine Nachricht senden.", zSchrift->getThis(), hauptScreen );
+	neuerChatFenster->addMember( neuerChatFertig );
+	neuesChatroomName = initTextFeld( 5, 30, 235, 20, zSchrift, TextFeld::Style::Sichtbar | TextFeld::Style::TextFeld, "Chatroom Name" );
+	neuesChatroomName->setTastaturEreignisParameter( this );
+	neuesChatroomName->setTastaturEreignis( freundesListeNeuesChatroomNameTE );
+	initToolTip( neuesChatroomName, "Name des Chatroom dem du beitreten möchtest.", zSchrift->getThis(), hauptScreen );
+	neuerChatFenster->addMember( neuesChatroomName );
+	neuesChatroomFertig = initKnopf( 245, 30, 20, 20, 0, 0, "" );
+	neuesChatroomFertig->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::HAlpha | Knopf::Style::KlickBuffer );
+	neuesChatroomFertig->setHintergrundBildZ( maximierenBild->getThis() );
+	neuesChatroomFertig->setMausEreignisParameter( this );
+	neuesChatroomFertig->setMausEreignis( freundesListeNeuesChatroomFertigME );
+	initToolTip( neuesChatroomFertig, "Chatroom erstellen oder beitreten.", zSchrift->getThis(), hauptScreen );
+	neuerChatFenster->addMember( neuesChatroomFertig );
+	fenster->addMember( neuerChatFenster );
+
+	freundesListe = new FreundesListeObj( zSchrift );
+	freundesListe->setPosition( 0, 100 );
+	freundesListe->setSize( 270, bildschirmGröße.y - 200 );
+	fenster->addMember( freundesListe );
+
+	zNachLoginFenster->addMember( fenster );
+	animation = 1;
+	tickVal = 0;
+	ref = 1;
+	neuerFreundSichtbar = 0;
+	neuerChatSichtbar = 0;
+	rend = 0;
+
+	start();
+}
+
+// Destruktor
+FreundesListe::~FreundesListe()
+{
+	ende();
+	fenster = fenster->release();
+	minimierenBild = minimierenBild->release();
+	maximierenBild = maximierenBild->release();
+	minMax = minMax->release();
+	überschrift = überschrift->release();
+	accountName = accountName->release();
+	freundesListe = freundesListe->release();
+	neuerFreund = neuerFreund->release();
+	neuerChat = neuerChat->release();
+	neuerFreundFenster = neuerFreundFenster->release();
+	neuerFreundSpielerName = neuerFreundSpielerName->release();
+	neuerFreundFertig = neuerFreundFertig->release();
+	neuerChatFenster = neuerChatFenster->release();
+	neuerChatName = neuerChatName->release();
+	neuerChatFertig = neuerChatFertig->release();
+	neuesChatroomName = neuesChatroomName->release();
+	neuesChatroomFertig = neuesChatroomFertig->release();
+}
+
+// nicht constant
+void FreundesListe::addMember( int accountId )
+{
+	freundesListe->addMember( accountId );
+}
+
+void FreundesListe::removeMember( int accountId )
+{
+	freundesListe->removeMember( accountId );
+}
+
+void FreundesListe::removeMember( FreundData *member )
+{
+	freundesListe->removeMember( member );
+}
+
+void FreundesListe::removeAll()
+{
+	freundesListe->removeAll();
+}
+
+void FreundesListe::setName( int accountId, char *txt )
+{
+	freundesListe->setName( accountId, txt );
+}
+
+void FreundesListe::setStatus( int accountId, char *txt )
+{
+	freundesListe->setStatus( accountId, txt );
+}
+
+void FreundesListe::setOnline( int accountId, bool online )
+{
+	freundesListe->setOnline( accountId, online );
+}
+
+void FreundesListe::setAnimation( int animation )
+{
+	this->animation = animation;
+}
+
+void FreundesListe::thread()
+{
+	bool err = 1;
+	if( infoKlient && loginKlient )
+	{
+		Text *name = infoKlient->getSpielerName( loginKlient->getAccountId() );
+		if( name )
+		{
+			accountName->setText( name->getText() );
+			name->release();
+			err = 0;
+		}
+	}
+	if( err && nachLogin->zNachrichtenListe() )
+	{
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+													   new Text( "Dein Accountname konnte nicht ermittelt werden." ),
+													   new Text( "Ok" ),
+													   0,
+													   NachrichtType::nachricht,
+													   0 );
+	}
+	err = 0;
+	if( ( !chatKlient || !chatKlient->freundesListeAnfragen() ) && nachLogin->zNachrichtenListe() )
+	{
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+													   new Text( "Deine Freunde konnten nicht geladen werden." ),
+													   new Text( "Ok" ),
+													   0,
+													   NachrichtType::nachricht,
+													   0 );
+	}
+	run = 0;
+}
+
+void FreundesListe::zeigeEinladeKnopf( bool zeigen )
+{
+	freundesListe->zeigeEinladeKnopf( zeigen );
+}
+
+bool FreundesListe::tick( double tickVal )
+{
+	this->tickVal += tickVal * 400;
+	int val = ( int )this->tickVal;
+	if( val < 1 )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	if( val > 14 )
+		val = 14;
+	this->tickVal -= val;
+	switch( animation )
+	{
+	case 1:
+		if( fenster->getX() < 0 )
+		{
+			fenster->setPosition( fenster->getX() + val, fenster->getY() );
+			if( fenster->getX() > 0 )
+				fenster->setPosition( 0, fenster->getY() );
+		}
+		else if( fenster->getHeight() < bildschirmGröße.y - 100 )
+		{
+			fenster->setSize( fenster->getBreite(), fenster->getHeight() + val );
+			if( fenster->getHeight() > bildschirmGröße.y - 100 )
+				fenster->setSize( fenster->getBreite(), bildschirmGröße.y - 100 );
+		}
+		else
+			animation = 0;
+		rend = 1;
+		break;
+	case 2:
+		if( fenster->getHeight() > 20 )
+		{
+			fenster->setSize( fenster->getBreite(), fenster->getHeight() - val );
+			if( fenster->getHeight() < 20 )
+				fenster->setSize( fenster->getBreite(), 20 );
+		}
+		else if( fenster->getX() > -250 )
+		{
+			fenster->setPosition( fenster->getX() - val, fenster->getY() );
+			if( fenster->getX() < -250 )
+				fenster->setPosition( -250, fenster->getY() );
+		}
+		else
+			animation = 0;
+		rend = 1;
+		break;
+	}
+	if( neuerFreundSichtbar )
+	{
+		if( neuerFreundFenster->getHeight() != 30 && neuerChatFenster->hatStyleNicht( Fenster::Style::Sichtbar ) )
+		{
+			neuerFreundFenster->addStyle( Fenster::Style::Sichtbar );
+			neuerFreundFenster->setSize( neuerFreundFenster->getBreite(), neuerFreundFenster->getHeight() + val );
+			freundesListe->setPosition( freundesListe->getX(), freundesListe->getY() + val );
+			freundesListe->setSize( freundesListe->getBreite(), freundesListe->getHeight() - val );
+			if( neuerFreundFenster->getHeight() > 30 )
+			{
+				neuerFreundFenster->setSize( neuerFreundFenster->getBreite(), 30 );
+				freundesListe->setPosition( freundesListe->getX(), 130 );
+				freundesListe->setSize( freundesListe->getBreite(), bildschirmGröße.y - 230 );
+			}
+			rend = 1;
+		}
+	}
+	else
+	{
+		if( neuerFreundFenster->hatStyle( Fenster::Style::Sichtbar ) )
+		{
+			neuerFreundFenster->setSize( neuerFreundFenster->getBreite(), neuerFreundFenster->getHeight() - val );
+			freundesListe->setPosition( freundesListe->getX(), freundesListe->getY() - val );
+			freundesListe->setSize( freundesListe->getBreite(), freundesListe->getHeight() + val );
+			if( neuerFreundFenster->getHeight() < 0 )
+			{
+				neuerFreundFenster->setSize( neuerFreundFenster->getBreite(), 0 );
+				neuerFreundFenster->removeStyle( Fenster::Style::Sichtbar );
+				freundesListe->setPosition( freundesListe->getX(), 100 );
+				freundesListe->setSize( freundesListe->getBreite(), bildschirmGröße.y - 200 );
+			}
+			rend = 1;
+		}
+	}
+	if( neuerChatSichtbar )
+	{
+		if( neuerChatFenster->getHeight() != 55 && neuerFreundFenster->hatStyleNicht( Fenster::Style::Sichtbar ) )
+		{
+			neuerChatFenster->addStyle( Fenster::Style::Sichtbar );
+			neuerChatFenster->setSize( neuerChatFenster->getBreite(), neuerChatFenster->getHeight() + val );
+			freundesListe->setPosition( freundesListe->getX(), freundesListe->getY() + val );
+			freundesListe->setSize( freundesListe->getBreite(), freundesListe->getHeight() - val );
+			if( neuerChatFenster->getHeight() > 55 )
+			{
+				neuerChatFenster->setSize( neuerChatFenster->getBreite(), 55 );
+				freundesListe->setPosition( freundesListe->getX(), 155 );
+				freundesListe->setSize( freundesListe->getBreite(), bildschirmGröße.y - 255 );
+			}
+			rend = 1;
+		}
+	}
+	else
+	{
+		if( neuerChatFenster->hatStyle( Fenster::Style::Sichtbar ) )
+		{
+			neuerChatFenster->setSize( neuerChatFenster->getBreite(), neuerChatFenster->getHeight() - val );
+			freundesListe->setPosition( freundesListe->getX(), freundesListe->getY() - val );
+			freundesListe->setSize( freundesListe->getBreite(), freundesListe->getHeight() + val );
+			if( neuerChatFenster->getHeight() < 0 )
+			{
+				neuerChatFenster->setSize( neuerChatFenster->getBreite(), 0 );
+				neuerChatFenster->removeStyle( Fenster::Style::Sichtbar );
+				freundesListe->setPosition( freundesListe->getX(), 100 );
+				freundesListe->setSize( freundesListe->getBreite(), bildschirmGröße.y - 200 );
+			}
+			rend = 1;
+		}
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+bool FreundesListe::druckMinMax( MausEreignis &me )
+{
+	if( me.id == ME_RLinks )
+	{
+		if( minMax->zHintergrundBild() == minimierenBild )
+		{
+			animation = 2;
+			minMax->setHintergrundBildZ( maximierenBild->getThis() );
+			minMax->zToolTip()->setText( "Freundes Leiste maximieren." );
+		}
+		else
+		{
+			animation = 1;
+			minMax->setHintergrundBildZ( minimierenBild->getThis() );
+			minMax->zToolTip()->setText( "Freundes Leiste minimieren." );
+		}
+	}
+	return 1;
+}
+
+bool FreundesListe::druckName( TastaturEreignis &te )
+{
+	if( te.id == TE_Release && te.taste == T_Enter )
+		chatKlient->accountNameÄndern( accountName->zText()->getText() );
+	return 1;
+}
+
+bool FreundesListe::druckNeuerFreund( MausEreignis &me )
+{
+	if( me.id == ME_RLinks )
+	{
+		neuerChatSichtbar = 0;
+		neuerFreundSichtbar = !neuerFreundSichtbar;
+	}
+	return 1;
+}
+
+bool FreundesListe::druckNeuerChat( MausEreignis &me )
+{
+	if( me.id == ME_RLinks )
+	{
+		neuerFreundSichtbar = 0;
+		neuerChatSichtbar = !neuerChatSichtbar;
+	}
+	return 1;
+}
+
+bool FreundesListe::druckNeuerFreundSpielerName( TastaturEreignis &te )
+{
+	if( !neuerFreundSichtbar )
+		return 0;
+	if( te.id == TE_Release && te.taste == T_Enter )
+	{
+		MausEreignis me = { ME_RLinks, 0, 0, 0 };
+		druckNeuerFreundFertig( me );
+	}
+	return 1;
+}
+
+bool FreundesListe::druckNeuerFreundFertig( MausEreignis &me )
+{
+	if( !neuerFreundSichtbar )
+		return 0;
+	if( me.id == ME_RLinks )
+	{
+		if( neuerFreundSpielerName->zText()->getLength() )
+		{
+			int accountId = infoKlient->getAccountId( neuerFreundSpielerName->zText()->getText() );
+			if( accountId )
+			{
+				if( chatKlient->freundesAnfrage( accountId ) )
+				{
+					nachLogin->zNachrichtenListe()->addNachricht( new Text( "Freundesanfrage" ), new Text( "Es wurde eine Anfrage an den Spieler gesendet." ),
+																  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+					neuerFreundSichtbar = 0;
+				}
+			}
+			else
+				nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Der Spieler wurde nicht gefunden." ),
+				new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+		}
+	}
+	return 1;
+}
+
+bool FreundesListe::druckNeuerChatName( TastaturEreignis &te )
+{
+	if( !neuerChatSichtbar )
+		return 0;
+	if( te.id == TE_Release && te.taste == T_Enter )
+	{
+		MausEreignis me = { ME_RLinks, 0, 0, 0 };
+		druckNeuerChatFertig( me );
+	}
+	return 1;
+}
+
+bool FreundesListe::druckNeuerChatFertig( MausEreignis &me )
+{
+	if( !neuerChatSichtbar )
+		return 0;
+	if( me.id == ME_RLinks )
+	{
+		if( neuerChatName->zText()->getLength() )
+		{
+			int accountId = infoKlient->getAccountId( neuerChatName->zText()->getText() );
+			if( accountId )
+			{
+				nachLogin->zChatLeiste()->addChat( accountId, 0 );
+				neuerChatSichtbar = 0;
+			}
+			else
+				nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Der Spieler wurde nicht gefunden." ),
+				new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+		}
+	}
+	return 1;
+}
+
+bool FreundesListe::druckNeuesChatroomName( TastaturEreignis &te )
+{
+	if( !neuerChatSichtbar )
+		return 0;
+	if( te.id == TE_Release && te.taste == T_Enter )
+	{
+		MausEreignis me = { ME_RLinks, 0, 0, 0 };
+		druckNeuesChatroomFertig( me );
+	}
+	return 1;
+}
+
+bool FreundesListe::druckNeuesChatroomFertig( MausEreignis &me )
+{
+	if( !neuerChatSichtbar )
+		return 0;
+	if( me.id == ME_RLinks )
+	{
+		if( neuesChatroomName->zText()->getLength() )
+		{
+			int chatroomId = infoKlient->getChatroomId( neuesChatroomName->zText()->getText() );
+			if( chatroomId )
+			{
+				if( chatKlient->chatroomBetreten( chatroomId ) )
+				{
+					nachLogin->zChatLeiste()->addChat( 0, chatroomId );
+					neuerChatSichtbar = 0;
+				}
+			}
+			else
+			{
+				chatroomId = chatKlient->chatroomErstellen( neuesChatroomName->zText()->getText() );
+				if( chatroomId )
+				{
+					nachLogin->zChatLeiste()->addChat( 0, chatroomId );
+					neuerChatSichtbar = 0;
+				}
+			}
+		}
+	}
+	return 1;
+}
+
+// constant
+bool FreundesListe::istFreund( int accId ) const
+{
+	return freundesListe->istFreund( accId );
+}
+
+// reference Counting
+FreundesListe *FreundesListe::getThis()
+{
+	ref++;
+	return this;
+}
+
+FreundesListe *FreundesListe::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Nachrichten
+bool freundesListeMinMaxME( void *p, void *obj, MausEreignis me )
+{
+	return ( (FreundesListe*)p )->druckMinMax( me );
+}
+
+bool freundesListeNameTE( void *p, void *obj, TastaturEreignis te )
+{
+	return ( (FreundesListe*)p )->druckName( te );
+}
+
+bool freundesListeNeuerFreundME( void *p, void *obj, MausEreignis me )
+{
+	return ( (FreundesListe*)p )->druckNeuerFreund( me );
+}
+
+bool freundesListeNeuerChatME( void *p, void *obj, MausEreignis me )
+{
+	return ( (FreundesListe*)p )->druckNeuerChat( me );
+}
+
+bool freundesListeNeuerFreundSpielerNameTE( void *p, void *obj, TastaturEreignis te )
+{
+	return ( (FreundesListe*)p )->druckNeuerFreundSpielerName( te );
+}
+
+bool freundesListeNeuerFreundFertigME( void *p, void *obj, MausEreignis me )
+{
+	return ( (FreundesListe*)p )->druckNeuerFreundFertig( me );
+}
+
+bool freundesListeNeuerChatNameTE( void *p, void *obj, TastaturEreignis te )
+{
+	return ( (FreundesListe*)p )->druckNeuerChatName( te );
+}
+
+bool freundesListeNeuerChatFertigME( void *p, void *obj, MausEreignis me )
+{
+	return ( (FreundesListe*)p )->druckNeuerChatFertig( me );
+}
+
+bool freundesListeNeuesChatroomNameTE( void *p, void *obj, TastaturEreignis te )
+{
+	return ( (FreundesListe*)p )->druckNeuesChatroomName( te );
+}
+
+bool freundesListeNeuesChatroomFertigME( void *p, void *obj, MausEreignis me )
+{
+	return ( (FreundesListe*)p )->druckNeuesChatroomFertig( me );
+}

+ 176 - 0
KSGClient/NachLogin/Chat/FreundesListe.h

@@ -0,0 +1,176 @@
+#ifndef FreundesListe_H
+#define FreundesListe_H
+
+#include <Klient.h>
+#include <Zeichnung.h>
+#include <Fenster.h>
+#include <Array.h>
+#include <Knopf.h>
+#include <Thread.h>
+
+using namespace Framework;
+
+class FreundData : private Thread
+{
+private:
+	LRahmen *rahmen;
+	AlphaFeld *auswahlBuffer;
+	TextFeld *name;
+	TextFeld *status;
+	Knopf *entfernen;
+	Knopf *ansehen;
+	Knopf *nachricht;
+	Knopf *einladen;
+	int accountId;
+	bool einladenSichtbar;
+	bool online;
+	bool ausgewählt;
+	int höhe;
+	int animation;
+	unsigned char auswahlAlpha;
+	double tickVal;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	FreundData( int accountId, LRahmen *rahmen, AlphaFeld *auswahlBuffer, Schrift *zSchrift );
+	// Destruktor
+	~FreundData();
+	// nicht constant
+	void thread();
+	void setName( char *txt );
+	void setStatus( char *txt );
+	void setOnline( bool online );
+	void setAusgewählt( bool ausw );
+	void remove();
+	void zeigeEinladeKnopf( bool zeigen );
+	void doMausEreignis( MausEreignis &me );
+	bool tick( double tickVal );
+	void render( int yPos, Bild &zRObj );
+	// constant
+	bool istOnline() const;
+	bool istAusgewählt() const;
+	char *zName() const;
+	Text *getName() const;
+	char *zStatus() const;
+	Text *getStatus() const;
+	int getAccountId() const;
+	int getHeight() const;
+	// reference Counting
+	FreundData *getThis();
+	FreundData *release();
+};
+
+class FreundesListeObj : public Zeichnung
+{
+private:
+	RCArray< FreundData > *members;
+	LRahmen *memberRahmen;
+	AlphaFeld *auswahlBuffer;
+	Schrift *schrift;
+	VScrollBar *vsb;
+	Punkt bildschirmGröße;
+	bool einladenSichtbar;
+	int memberNummer;
+	int ref;
+
+public:
+	// Konstruktor
+	FreundesListeObj( Schrift *zSchrift );
+	// Destruktor
+	~FreundesListeObj();
+	// nicht constant
+	void addMember( int accountId );
+	void removeMember( int accountId );
+	void removeMember( FreundData *member );
+	void removeAll();
+	void setName( int accountId, char *txt );
+	void setStatus( int accountId, char *txt );
+	void setOnline( int accountId, bool online );
+	void zeigeEinladeKnopf( bool zeigen );
+	bool tick( double tickVal ) override;
+	void doMausEreignis( MausEreignis &me ) override;
+	void render( Bild &zRObj ) override;
+	// constant
+	bool istFreund( int accId ) const;
+	// reference Counting
+	FreundesListeObj *getThis();
+	FreundesListeObj *release();
+};
+
+class FreundesListe : private Thread
+{
+private:
+	Fenster *fenster;
+	TextFeld *überschrift;
+	TextFeld *accountName;
+	Knopf *minMax;
+	Knopf *neuerFreund;
+	Knopf *neuerChat;
+	FreundesListeObj *freundesListe;
+	Punkt bildschirmGröße;
+	Fenster *neuerFreundFenster;
+	TextFeld *neuerFreundSpielerName;
+	Knopf *neuerFreundFertig;
+	Fenster *neuerChatFenster;
+	TextFeld *neuerChatName;
+	Knopf *neuerChatFertig;
+	TextFeld *neuesChatroomName;
+	Knopf *neuesChatroomFertig;
+	Bild *minimierenBild;
+	Bild *maximierenBild;
+	int animation;
+	double tickVal;
+	bool neuerFreundSichtbar;
+	bool neuerChatSichtbar;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	FreundesListe( Schrift *zSchrift, Fenster *zNachLoginFenster );
+	// Destruktor
+	~FreundesListe();
+	// nicht constant
+	void addMember( int accountId );
+	void removeMember( int accountId );
+	void removeMember( FreundData *member );
+	void removeAll();
+	void setName( int accountId, char *txt );
+	void setStatus( int accountId, char *txt );
+	void setOnline( int accountId, bool online );
+	void setAnimation( int animation );
+	void thread();
+	void zeigeEinladeKnopf( bool zeigen );
+	bool tick( double tickVal );
+	bool druckMinMax( MausEreignis &me );
+	bool druckName( TastaturEreignis &te );
+	bool druckNeuerFreund( MausEreignis &me );
+	bool druckNeuerChat( MausEreignis &me );
+	bool druckNeuerFreundSpielerName( TastaturEreignis &te );
+	bool druckNeuerFreundFertig( MausEreignis &me );
+	bool druckNeuerChatName( TastaturEreignis &te );
+	bool druckNeuerChatFertig( MausEreignis &me );
+	bool druckNeuesChatroomName( TastaturEreignis &te );
+	bool druckNeuesChatroomFertig( MausEreignis &me );
+	// constant
+	bool istFreund( int accId ) const;
+	// reference Counting
+	FreundesListe *getThis();
+	FreundesListe *release();
+};
+
+// Nachrichten
+bool freundesListeMinMaxME( void *p, void *obj, MausEreignis me );
+bool freundesListeNameTE( void *p, void *obj, TastaturEreignis te );
+bool freundesListeNeuerFreundME( void *p, void *obj, MausEreignis me );
+bool freundesListeNeuerChatME( void *p, void *obj, MausEreignis me );
+bool freundesListeNeuerFreundSpielerNameTE( void *p, void *obj, TastaturEreignis te );
+bool freundesListeNeuerFreundFertigME( void *p, void *obj, MausEreignis me );
+bool freundesListeNeuerChatNameTE( void *p, void *obj, TastaturEreignis te );
+bool freundesListeNeuerChatFertigME( void *p, void *obj, MausEreignis me );
+bool freundesListeNeuesChatroomNameTE( void *p, void *obj, TastaturEreignis te );
+bool freundesListeNeuesChatroomFertigME( void *p, void *obj, MausEreignis me );
+
+#endif

+ 816 - 0
KSGClient/NachLogin/Chat/NachrichtenListe.cpp

@@ -0,0 +1,816 @@
+#include "NachrichtenListe.h"
+#include <Punkt.h>
+#include <MausEreignis.h>
+#include <Bild.h>
+#include "../../Global/Initialisierung.h"
+#include <Scroll.h>
+#include "../../Global/Variablen.h"
+#include <Rahmen.h>
+#include <DateiSystem.h>
+#include <KSGTDatei.h>
+#include <ToolTip.h>
+#include <GSLDateiV.h>
+
+typedef GSL::GSLDateiV *( *GetGSLDatei )( );
+
+// Inhalt der Nachricht Klasse aus NachrichtListe.h
+// Konstruktor
+Nachricht::Nachricht( Schrift *zSchrift, Text *titel, Text *nachricht, Text *positiv, Text *negativ, char type, void *param )
+{
+	rahmen = new LRahmen();
+	rahmen->setRamenBreite( 1 );
+	rahmen->setFarbe( 0xFFFFFFFF );
+	this->titel = initTextFeld( 1, 1, 208, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, titel->getText() );
+	titel = titel->release();
+	close = initKnopf( 208, 1, 20, 20, 0, 0, "" );
+	close->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::HAlpha | Knopf::Style::KlickBuffer );
+	Bild *closeBild = bilder->get( "chat.ltdb/entfernen.png" );
+	if( !closeBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		closeBild = datei->laden( 0, new Text( "entfernen.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/entfernen.png", closeBild->getThis() );
+	}
+	close->setHintergrundBildZ( closeBild );
+	initToolTip( close, "Nachricht ignorieren.", zSchrift->getThis(), hauptScreen );
+	Text *result = new Text( nachricht->getText() );
+	int län = nachricht->getLength();
+	char *txt = nachricht->getText();
+	int x = 0;
+	int y = 0;
+	zSchrift->lock();
+	zSchrift->setSchriftSize( 12 );
+	Alphabet *tmp = zSchrift->getAlphabet( 12 );
+	int zeilenHöhe = tmp->getZeilenHeight() + tmp->getZeilenAbstand();
+	int lastPos = -1;
+	for( int i = 0; i < län; i++ )
+	{
+		char c = txt[ i ];
+		if( c == ' ' )
+		{
+			lastPos = i;
+			x += 6;
+			continue;
+		}
+		if( c == '\n' )
+		{
+			x = 0;
+			y += zeilenHöhe;
+			lastPos = -1;
+			continue;
+		}
+		Buchstabe *b = tmp->getBuchstabe( (unsigned)c );
+		if( b )
+		{
+			x += b->getBreite();
+			if( x > 228 && lastPos > -1 )
+			{
+				result->ersetzen( lastPos, lastPos + 1, "\n" );
+				x = 0;
+				y += zeilenHöhe;
+				i = lastPos;
+				lastPos = -1;
+			}
+			b = b->release();
+		}
+	}
+	y += zeilenHöhe;
+	tmp = tmp->release();
+	zSchrift->unlock();
+	nachricht = nachricht->release();
+	text = initTextFeld( 1, 22, 228, y, zSchrift, TextFeld::Style::Text, result->getText() );
+	result = result->release();
+	if( positiv )
+	{
+		this->positiv = initKnopf( 10, 20 + y, 100, 20, zSchrift, Knopf::Style::Sichtbar, positiv->getText() );
+		positiv = positiv->release();
+	}
+	else
+		this->positiv = 0;
+	if( negativ )
+	{
+		this->negativ = initKnopf( 120, 20 + y, 100, 20, zSchrift, Knopf::Style::Sichtbar, negativ->getText() );
+		negativ = negativ->release();
+	}
+	else
+		this->negativ = 0;
+	typ = type;
+	this->param = param;
+	maxHöhe = 50 + y;
+	ref = 1;
+	animation = 1;
+	ausgewählt = 0;
+	tickVal = 0;
+	rend = 0;
+	höhe = 0;
+}
+
+// Destruktor
+Nachricht::~Nachricht()
+{
+	switch( typ )
+	{
+	case 1:
+		delete ( (int*)param );
+		break;
+	case 2:
+		delete ( (int*)param );
+		break;
+	case 3:
+		delete ( (SpielEinladungParam*)param );
+		break;
+	case 4:
+		delete ( (ChatroomEinladungParam*)param );
+		break;
+	}
+	titel = titel->release();
+	text = text->release();
+	close = close->release();
+	if( positiv )
+		positiv = positiv->release();
+	if( negativ )
+		negativ = negativ->release();
+	rahmen = rahmen->release();
+}
+
+// nicht constant
+void Nachricht::entfernen()
+{
+	animation = 3;
+}
+
+void Nachricht::setAusgewählt( bool ausw )
+{
+	if( animation != 3 )
+	{
+		ausgewählt = ausw;
+		if( ausw )
+			animation = 2;
+		else
+			animation = 1;
+	}
+}
+
+void Nachricht::doMausEreignis( MausEreignis &me )
+{
+	if( animation != 3 )
+	{
+		bool tmp = 0;
+		if( me.my > höhe || !ausgewählt )
+		{
+			tmp = me.verarbeitet;
+			me.verarbeitet = 1;
+		}
+		char aktion = 0;
+		if( positiv )
+			positiv->doMausEreignis( me );
+		aktion = me.verarbeitet ? 1 : 0;
+		if( negativ )
+			negativ->doMausEreignis( me );
+		if( !aktion )
+			aktion = me.verarbeitet ? 2 : 0;
+		close->doMausEreignis( me );
+		if( !aktion )
+			aktion = me.verarbeitet ? 3 : 0;
+		if( me.my > höhe || !ausgewählt )
+		{
+			me.verarbeitet = tmp;
+			return;
+		}
+		if( me.id != ME_RLinks )
+			return;
+		if( aktion )
+			animation = 3;
+		switch( aktion )
+		{
+		case 1:
+			// positiv
+			switch( typ )
+			{
+			case 1: // freund entfernen
+				chatKlient->freundschaftBeenden( *( (int*)param ) );
+				break;
+			case 2: // freund einladung
+				chatKlient->freundesAnfrageBeantworten( *( (int*)param ), 1 );
+				break;
+			case 3: // spiel einladung
+				if( 1 )
+				{
+					int karteId = infoKlient->getGruppenKarteId( ( (SpielEinladungParam*)param )->gruppeId );
+					int spielArt = infoKlient->getSpielId( karteId );
+					KSGTDatei *dgt = new KSGTDatei( "data/dg.ksgt" );
+					dgt->laden();
+					bool sak = 0;
+					int dgSId = infoKlient->getDateiGruppeIdVonSpiel( spielArt );
+					bool sgf = 0;
+					for( int i = 0; i < dgt->getZeilenAnzahl(); i++ )
+					{
+						if( dgt->zFeld( i, 0 ) && TextZuInt( dgt->zFeld( i, 0 )->getText(), 10 ) == dgSId )
+						{
+							sgf = 1;
+							int lv = dgt->zFeld( i, 2 ) ? TextZuInt( dgt->zFeld( i, 2 )->getText(), 10 ) : 0;
+							int ov = infoKlient->getSpielVersion( spielArt );
+                            if( lv == ov )
+                            {
+                                sak = 1;
+                                break;
+                            }
+						}
+					}
+					dgt->release();
+					if( !sak )
+					{
+						anmeldungKlient->gruppeEinladungAblehnen( ( (SpielEinladungParam*)param )->gruppeId );
+						nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Deine Spiel Version ist nicht aktuell. Sie wird beim nächsten Spielstart aktualisiert." ), new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+						if( !sgf )
+						{
+							Text *pfad = infoKlient->getDateiGruppePfad( dgSId );
+							Text *idT = new Text();
+							idT->append( dgSId );
+							if( pfad )
+							{
+								KSGTDatei *dg = new KSGTDatei( "data/dg.ksgt" );
+								dg->laden();
+								RCArray< Text > *zeile = new RCArray< Text >();
+								zeile->add( idT );
+								zeile->add( pfad );
+								zeile->add( new Text( "0" ) );
+								zeile->add( new Text( "0" ) );
+								dg->addZeile( 4, zeile );
+								zeile->release();
+								dg->speichern();
+								dg->release();
+							}
+							else
+								idT->release();
+						}
+					}
+                    else
+					{
+						MausEreignis me;
+						me.verarbeitet = 0;
+						me.id = ME_RLinks;
+						nachLogin->zTitelLeiste()->druckSpielen( me );
+						Array< int > *spieler = new Array< int >();
+						int anzahl = 0;
+						if( anmeldungKlient->gruppeBetreten( ( (SpielEinladungParam*)param )->gruppeId, spieler, &anzahl ) )
+						{
+							nachLogin->zSpielenFenster()->gruppeBetreten( ( (SpielEinladungParam*)param )->gruppeId );
+							for( int i = 0; i < anzahl; i++ )
+								nachLogin->zSpielenFenster()->spielerBetrittGruppe( ( (SpielEinladungParam*)param )->gruppeId, spieler->hat( i ) ? spieler->get( i ) : 0 );
+						}
+						else
+							nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( anmeldungKlient->getLetzterFehler() ), new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+					}
+				}
+				break;
+			case 4: // chatroom einladung
+				nachLogin->zChatLeiste()->addChat( 0, ( (ChatroomEinladungParam*)param )->chatroomId );
+				chatKlient->chatroomBetreten( ( (ChatroomEinladungParam*)param )->chatroomId );
+				break;
+			case 5: // logout
+				::aktion = 3;
+				break;
+			case 6: // close
+				nachLogin->zChatLeiste()->removeAll();
+				loginKlient->logout();
+				PostQuitMessage( 0 );
+				break;
+			}
+			break;
+		case 2:
+			// schließn
+		case 3:
+			// negativ
+			switch( typ )
+			{
+			case 2:
+				chatKlient->freundesAnfrageBeantworten( *( (int*)param ), 0 );
+				break;
+			case 3: // spiel einladung
+				anmeldungKlient->gruppeEinladungAblehnen( ( (SpielEinladungParam*)param )->gruppeId );
+				break;
+			case 4:
+				chatKlient->chatroomEinladungAblehnen( ( (ChatroomEinladungParam*)param )->vonAccount, ( (ChatroomEinladungParam*)param )->chatroomId );
+				break;
+			}
+			break;
+		}
+	}
+}
+
+bool Nachricht::tick( double tickVal )
+{
+	rend |= close->tick( tickVal );
+	rend |= positiv ? positiv->tick( tickVal ) : 0;
+	rend |= negativ ? negativ->tick( tickVal ) : 0;
+	rend |= text->tick( tickVal );
+	if( !animation )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	this->tickVal += tickVal * 100;
+	int val = ( int )this->tickVal;
+	if( val < 1 )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	if( val > 4 )
+		val = 4;
+	this->tickVal -= val;
+	switch( animation )
+	{
+	case 1:
+		if( höhe != 20 )
+		{
+			if( höhe > 20 )
+			{
+				höhe -= val;
+				if( höhe < 20 )
+					höhe = 20;
+			}
+			else
+			{
+				höhe += val;
+				if( höhe > 20 )
+					höhe = 20;
+			}
+			rend = 1;
+		}
+		else
+			animation = 0;
+		break;
+	case 2:
+		if( höhe != maxHöhe )
+		{
+			höhe += val;
+			if( höhe > maxHöhe )
+				höhe = maxHöhe;
+			rend = 1;
+		}
+		else
+			animation = 0;
+		break;
+	case 3:
+		höhe -= val;
+		if( höhe <= 0 )
+		{
+			nachLogin->zNachrichtenListe()->removeNachricht( this ); // delete this
+			return 1;
+		}
+		rend = 1;
+		break;
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void Nachricht::render( int yPos, Bild &zRObj )
+{
+	int y = yPos;
+	int br = 228;
+	int hö = höhe;
+	if( !zRObj.setDrawOptions( 0, y, br, hö ) )
+		return;
+	rahmen->setSize( br, hö );
+	rahmen->render( zRObj );
+	int rbr = rahmen->getRBreite();
+	if( !zRObj.setDrawOptions( rbr, rbr, br - rbr * 2, hö - rbr * 2 ) )
+	{
+		zRObj.releaseDrawOptions();
+		return;
+	}
+	titel->render( zRObj );
+	text->render( zRObj );
+	close->render( zRObj );
+	if( positiv )
+		positiv->render( zRObj );
+	if( negativ )
+		negativ->render( zRObj );
+	zRObj.releaseDrawOptions();
+	zRObj.releaseDrawOptions();
+}
+
+// contant
+bool Nachricht::istAusgewählt() const
+{
+	return ausgewählt;
+}
+
+int Nachricht::getHeight() const
+{
+	return höhe;
+}
+
+// Reference Counting
+Nachricht *Nachricht::getThis()
+{
+	ref++;
+	return this;
+}
+
+Nachricht *Nachricht::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Inhalt der NachrichtenListeObj Klasse aus NachrichtListe.h
+// Konstruktor
+NachrichtenListeObj::NachrichtenListeObj( Schrift *zSchrift )
+: Zeichnung()
+{
+	members = new RCArray< Nachricht >();
+	schrift = zSchrift->getThis();
+	vsb = new VScrollBar();
+	vsb->setKlickScroll( 10 );
+	bildschirmGröße = BildschirmGröße();
+	vsb->update( 0, bildschirmGröße.y - 122 );
+	anzahl = 0;
+	gr = Punkt( 250, bildschirmGröße.y - 122 );
+	ref = 1;
+}
+
+// Destruktor
+NachrichtenListeObj::~NachrichtenListeObj()
+{
+	schrift = schrift->release();
+	vsb = (VScrollBar*)vsb->release();
+	members = members->release();
+}
+
+// nicht constant
+void NachrichtenListeObj::addNachricht( Text *titel, Text *nachricht, Text *positiv, Text *negativ, char type, void *param )
+{
+	Nachricht *tmp = new Nachricht( schrift, titel, nachricht, positiv, negativ, type, param );
+	members->add( tmp, anzahl );
+	anzahl++;
+	rend = 1;
+}
+
+void NachrichtenListeObj::removeNachricht( Nachricht *zNachricht )
+{
+	for( int i = 0; i < anzahl; i++ )
+	{
+		if( members->z( i ) == zNachricht )
+		{
+			members->remove( i );
+			anzahl--;
+			rend = 1;
+			break;
+		}
+	}
+}
+
+void NachrichtenListeObj::removeAll()
+{
+	lockZeichnung();
+	members->leeren();
+	anzahl = 0;
+	rend = 1;
+	unlockZeichnung();
+}
+
+bool NachrichtenListeObj::tick( double tickVal )
+{
+	lockZeichnung();
+	rend |= vsb->getRend();
+	rend |= nachLogin->zNachrichtenListe()->tick( tickVal );
+	for( int i = 0; i < anzahl; i++ )
+	{
+		Nachricht *tmp = members->z( i );
+		if( tmp )
+			rend |= tmp->tick( tickVal );
+	}
+	unlockZeichnung();
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void NachrichtenListeObj::doMausEreignis( MausEreignis &me )
+{
+	lockZeichnung();
+	int my = me.my;
+	me.my -= 20;
+	if( me.mx <= 229 && me.mx > 0 && me.my >= 0 )
+	{
+		me.my += vsb->getScroll();
+		for( int i = 0; i < anzahl; i++ )
+		{
+			Nachricht *tmp = members->z( i );
+			if( tmp )
+			{
+				if( me.my > 0 && me.my < tmp->getHeight() )
+					tmp->setAusgewählt( 1 );
+				else
+					tmp->setAusgewählt( 0 );
+				tmp->doMausEreignis( me );
+				me.my -= tmp->getHeight();
+			}
+		}
+		me.my -= vsb->getScroll();
+	}
+	else
+	{
+		me.my += vsb->getScroll();
+		for( int i = 0; i < anzahl; i++ )
+		{
+			Nachricht *tmp = members->z( i );
+			if( tmp )
+			{
+				tmp->setAusgewählt( 0 );
+				tmp->doMausEreignis( me );
+				me.my -= tmp->getHeight();
+			}
+		}
+		me.my -= vsb->getScroll();
+	}
+	me.my = my;
+	vsb->doMausMessage( 229, 20, 20, bildschirmGröße.y - 122, me );
+	unlockZeichnung();
+}
+
+void NachrichtenListeObj::render( Bild &zrObj )
+{
+	lockZeichnung();
+	int x = pos.x;
+	int y = pos.y;
+	int br = gr.x;
+	int hö = gr.y;
+	if( !zrObj.setDrawOptions( x, y, br, hö ) )
+	{
+		unlockZeichnung();
+		return;
+	}
+	int höhe = 0;
+	for( int i = 0; i < anzahl; i++ )
+	{
+		Nachricht *tmp = members->z( i );
+		tmp->render( höhe - ( vsb ? vsb->getScroll() : 0 ), zrObj );
+		höhe += tmp->getHeight();
+	}
+	if( vsb )
+	{
+		vsb->update( höhe, bildschirmGröße.y - 122 );
+		vsb->render( 229, 0, 20, bildschirmGröße.y - 122, zrObj );
+	}
+	zrObj.releaseDrawOptions();
+	unlockZeichnung();
+}
+
+// contant
+
+// Reference Counting
+NachrichtenListeObj *NachrichtenListeObj::getThis()
+{
+	ref++;
+	return this;
+}
+
+NachrichtenListeObj *NachrichtenListeObj::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Inhalt der NachrichtenListe Klasse aus NachrichtListe.h
+// Konstruktor
+NachrichtenListe::NachrichtenListe( Schrift *zSchrift, Fenster *zNachLoginFenster )
+{
+	minimierenBild = bilder->get( "chat.ltdb/minimieren.png" );
+	if( !minimierenBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		minimierenBild = datei->laden( 0, new Text( "minimieren.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/minimieren.png", minimierenBild->getThis() );
+	}
+	maximierenBild = bilder->get( "chat.ltdb/maximieren.png" );
+	if( !maximierenBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		maximierenBild = datei->laden( 0, new Text( "maximieren.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/maximieren.png", maximierenBild->getThis() );
+	}
+	bildschirmGröße = BildschirmGröße();
+	fenster = initFenster( bildschirmGröße.x - 21, 100, 250, 22, zSchrift, Fenster::Style::Sichtbar | Fenster::Style::Erlaubt | Fenster::Style::Rahmen | Fenster::Style::BodyHintergrund, "" );
+	fenster->setKBgFarbe( 0xFF000000 );
+	überschrift = initTextFeld( 1, 1, 248, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center | TextFeld::Style::Sichtbar, "Nachrichten" );
+	überschrift->setSchriftSize( 15 );
+	fenster->addMember( überschrift );
+	minMax = initKnopf( 1, 1, 20, 20, 0, 0, "" );
+	minMax->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::HAlpha | Knopf::Style::KlickBuffer );
+	minMax->setMausEreignisParameter( this );
+	minMax->setMausEreignis( NachrichtenListeMinMaxME );
+	minMax->setHintergrundBildZ( minimierenBild->getThis() );
+	initToolTip( minMax, "Nachrichten Leiste minimieren.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( minMax );
+	nachrichtenListe = new NachrichtenListeObj( zSchrift );
+	nachrichtenListe->setPosition( 1, 21 );
+	nachrichtenListe->setSize( 248, bildschirmGröße.y - 122 );
+	fenster->addMember( nachrichtenListe );
+	zNachLoginFenster->addMember( fenster );
+	tickVal = 0;
+	animation = 1;
+	rend = 0;
+	msgSound = 0;
+	errSound = 0;
+	HMODULE dll = dllDateien->ladeDLL( "GSL.dll", "data/bin/GSL.dll" );
+	if( dll )
+	{
+		GetGSLDatei getGSLDatei = (GetGSLDatei)GetProcAddress( dll, "getGSLDatei" );
+		if( getGSLDatei )
+		{
+			GSL::GSLDateiV *sDat = getGSLDatei();
+			sDat->setDatei( "data/sounds/popup.gsl" );
+			sDat->leseDaten();
+			msgSound = sDat->getSound( "info.wav" );
+			errSound = sDat->getSound( "error.wav" );
+			sDat->release();
+			if( msgSound )
+				msgSound->setVolume( 0xFFFF, 0xFFFF );
+			if( errSound )
+				errSound->setVolume( 0xFFFF, 0xFFFF );
+		}
+		if( !msgSound && !errSound )
+			dllDateien->releaseDLL( "GSL.dll" );
+	}
+	ref = 1;
+}
+
+// Destruktor
+NachrichtenListe::~NachrichtenListe()
+{
+	if( msgSound || errSound )
+	{
+		if( msgSound )
+		{
+			msgSound->stopSound();
+			msgSound->release();
+		}
+		if( errSound )
+		{
+			errSound->stopSound();
+			errSound->release();
+		}
+		dllDateien->releaseDLL( "GSL.dll" );
+	}
+	überschrift = überschrift->release();
+	fenster = fenster->release();
+	minMax = minMax->release();
+	nachrichtenListe = nachrichtenListe->release();
+	minimierenBild = minimierenBild->release();
+	maximierenBild = maximierenBild->release();
+}
+
+// nicht constant
+void NachrichtenListe::addNachricht( Text *titel, Text *nachricht, Text *positiv, Text *negativ, char type, void *param )
+{
+	if( titel && titel->hat( "Fehler" ) && errSound )
+		errSound->playSound();
+	else if( msgSound )
+		msgSound->playSound();
+	nachrichtenListe->addNachricht( titel, nachricht, positiv, negativ, type, param );
+}
+
+void NachrichtenListe::removeNachricht( Nachricht *zNachricht )
+{
+	nachrichtenListe->removeNachricht( zNachricht );
+}
+
+void NachrichtenListe::removeAll()
+{
+	nachrichtenListe->removeAll();
+}
+
+bool NachrichtenListe::druckMinMax( MausEreignis &me )
+{
+	if( me.id == ME_RLinks )
+	{
+		if( minMax->zHintergrundBild() == minimierenBild )
+		{
+			animation = 2;
+			minMax->setHintergrundBildZ( maximierenBild->getThis() );
+			minMax->zToolTip()->setText( "Nachrichten Leiste maximieren." );
+		}
+		else
+		{
+			animation = 1;
+			minMax->setHintergrundBildZ( minimierenBild->getThis() );
+			minMax->zToolTip()->setText( "Nachrichten Leiste minimieren." );
+		}
+	}
+	return 1;
+}
+
+bool NachrichtenListe::tick( double tickVal )
+{
+	if( !animation )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	this->tickVal += tickVal * 400;
+	int val = ( int )this->tickVal;
+	if( val < 1 )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	if( val > 14 )
+		val = 14;
+	this->tickVal -= val;
+	switch( animation )
+	{
+	case 1: // maximieren
+		if( fenster->getX() > bildschirmGröße.x - 250 )
+		{
+			fenster->setPosition( fenster->getX() - val, fenster->getY() );
+			minMax->setPosition( minMax->getX() + val, minMax->getY() );
+			if( fenster->getX() < bildschirmGröße.x - 250 )
+			{
+				fenster->setPosition( bildschirmGröße.x - 250, fenster->getY() );
+				minMax->setPosition( 229, minMax->getY() );
+            }
+            rend = 1;
+		}
+		else if( fenster->getHeight() < bildschirmGröße.y - 100 )
+		{
+			fenster->setSize( fenster->getBreite(), fenster->getHeight() + val );
+			if( fenster->getHeight() >= bildschirmGröße.y - 100 )
+			{
+				fenster->setSize( fenster->getBreite(), bildschirmGröße.y - 100 );
+				animation = 0;
+            }
+            rend = 1;
+		}
+		break;
+	case 2: // minimieren
+		if( fenster->getHeight() > 22 )
+		{
+			fenster->setSize( fenster->getBreite(), fenster->getHeight() - val );
+			if( fenster->getHeight() < 22 )
+                fenster->setSize( fenster->getBreite(), 22 );
+            rend = 1;
+		}
+		else if( fenster->getX() < bildschirmGröße.x - 21 )
+		{
+			minMax->setPosition( minMax->getX() - val, minMax->getY() );
+			fenster->setPosition( fenster->getX() + val, fenster->getY() );
+			if( fenster->getX() >= bildschirmGröße.x - 21 )
+			{
+				minMax->setPosition( 1, minMax->getY() );
+				fenster->setPosition( bildschirmGröße.x - 21, fenster->getY() );
+				animation = 0;
+            }
+            rend = 1;
+		}
+		break;
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+// contant
+
+// Reference Counting
+NachrichtenListe *NachrichtenListe::getThis()
+{
+	ref++;
+	return this;
+}
+
+NachrichtenListe *NachrichtenListe::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Nachrichten
+bool NachrichtenListeMinMaxME( void *p, void *obj, MausEreignis me )
+{
+	return ( (NachrichtenListe*)p )->druckMinMax( me );
+}

+ 142 - 0
KSGClient/NachLogin/Chat/NachrichtenListe.h

@@ -0,0 +1,142 @@
+#ifndef NachrichtenListe_H
+#define NachrichtenListe_H
+
+#include <Klient.h>
+#include <Array.h>
+#include <Fenster.h>
+#include <Knopf.h>
+#include <GSLSoundV.h>
+#include "..\..\Aktionen\AktionsThread.h"
+
+using namespace Framework;
+using namespace Network;
+
+namespace NachrichtType
+{
+	const char nachricht         = 0;
+	const char freundEntfernen   = 1;
+	const char freundEinladung   = 2;
+	const char spielEinladung    = 3;
+	const char chatroomEinladung = 4;
+	const char logout            = 5;
+	const char close         = 6;
+}
+
+struct SpielEinladungParam
+{
+	int vonAccount;
+	int gruppeId;
+};
+
+struct ChatroomEinladungParam
+{
+	int vonAccount;
+	int chatroomId;
+};
+
+class Nachricht
+{
+private:
+	TextFeld *titel;
+	TextFeld *text;
+	Knopf *close;
+	Knopf *positiv;
+	Knopf *negativ;
+	LRahmen *rahmen;
+	int höhe;
+	int maxHöhe;
+	bool ausgewählt;
+	int animation;
+	double tickVal;
+	char typ;
+	void *param;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	Nachricht( Schrift *zSchrift, Text *titel, Text *nachricht, Text *positiv, Text *negativ, char type, void *param );
+	// Destruktor
+	~Nachricht();
+	// nicht constant
+	void entfernen();
+	void setAusgewählt( bool ausgewählt );
+	void doMausEreignis( MausEreignis &me );
+	bool tick( double tickVal );
+	void render( int y, Bild &zRObj );
+	// contant
+	bool istAusgewählt() const;
+	int getHeight() const;
+	// Reference Counting
+	Nachricht *getThis();
+	Nachricht *release();
+};
+
+class NachrichtenListeObj : public Zeichnung
+{
+private:
+	RCArray< Nachricht > *members;
+	VScrollBar *vsb;
+	Schrift *schrift;
+	Punkt bildschirmGröße;
+	int anzahl;
+	int ref;
+
+public:
+	// Konstruktor
+	NachrichtenListeObj( Schrift *zSchrift );
+	// Destruktor
+	~NachrichtenListeObj();
+	// nicht constant
+	void addNachricht( Text *titel, Text *nachricht, Text *positiv, Text *negativ, char type, void *param );
+	void removeNachricht( Nachricht *zNachricht );
+	void removeAll();
+	bool tick( double tickVal ) override;
+	void doMausEreignis( MausEreignis &me ) override;
+	void render( Bild &zRObj ) override;
+	// contant
+
+	// Reference Counting
+	NachrichtenListeObj *getThis();
+	NachrichtenListeObj *release();
+};
+
+class NachrichtenListe
+{
+private:
+	Fenster *fenster;
+	Knopf *minMax;
+	NachrichtenListeObj *nachrichtenListe;
+	Punkt bildschirmGröße;
+	TextFeld *überschrift;
+	Bild *minimierenBild;
+	Bild *maximierenBild;
+	GSL::GSLSoundV *msgSound;
+	GSL::GSLSoundV *errSound;
+	double tickVal;
+	int animation;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	NachrichtenListe( Schrift *zSchrift, Fenster *zNachLoginFenster );
+	// Destruktor
+	~NachrichtenListe();
+	// nicht constant
+	void addNachricht( Text *titel, Text *nachricht, Text *positiv = 0, Text *negativ = 0, char type = NachrichtType::nachricht, void *param = 0 );
+	void removeNachricht( Nachricht *zNachricht );
+	void removeAll();
+	bool druckMinMax( MausEreignis &me );
+	bool tick( double tickVal );
+	// contant
+
+	// Reference Counting
+	NachrichtenListe *getThis();
+	NachrichtenListe *release();
+};
+
+// Nachrichten
+bool NachrichtenListeMinMaxME( void *p, void *obj, MausEreignis me );
+
+#endif

+ 429 - 0
KSGClient/NachLogin/Editor/Auswahl/Auswahl.cpp

@@ -0,0 +1,429 @@
+#include "Auswahl.h"
+#include "../../../Global/Initialisierung.h"
+#include "../../../Global/Variablen.h"
+#include <DateiSystem.h>
+#include <KSGTDatei.h>
+
+// Inhalt der Auswahl Klasse aus Auswahl.h
+// Konstruktor
+Auswahl::Auswahl( Schrift *zSchrift, KartenEditor *kEditor )
+	: Thread()
+{
+	this->kEditor = kEditor;
+	alpha = 255;
+	sichtbar = 0;
+	suchFilterT = initTextFeld( 10, 10, 70, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, "Suchfilter:" );
+	suchFilter = initTextFeld( 90, 10, 210, 20, zSchrift, TextFeld::Style::TextFeld, "" );
+	initToolTip( suchFilter, "Gebe etwas vom Namen der Karte ein, nach der du suchst.", zSchrift->getThis(), hauptScreen );
+	suchen = initKnopf( 310, 10, 100, 20, zSchrift, Knopf::Style::Sichtbar, "suchen" );
+	sortSpalte = initAuswahlBox( 640, 10, 120, 20, zSchrift, ABSTYLE,
+	{ "Name", "Spielart", "Preis (Kupfer)", "Verkauft", "Spieleranzahl" } );
+	sortRichtung = initAuswahlBox( 770, 10, 120, 20, zSchrift, ABSTYLE, { "Aufsteigend", "Absteigend" } );
+	karten = initObjTabelle( 10, 40, 880, 520, zSchrift, OTSTYLE, { { "Name", 220, 220, 220 }, { "Spielart", 220, 220, 220 },
+	{ "Kupfer", 130, 130, 130 }, { "Verkauft", 125, 125, 125 }, { "Spieleranzahl", 140, 140, 140 },
+	{ "", 20, 20, 20 } }, 20 );
+	neuKarteName = initTextFeld( 10, 570, 195, 20, zSchrift, TextFeld::Style::TextFeld, "" );
+    initToolTip( neuKarteName, "Name einer neuen Karte", zSchrift->getThis(), hauptScreen );
+	neuKarteSpielArt = initAuswahlBox( 215, 570, 195, 20, zSchrift, ABSTYLE, {} );
+	neuKarte = initKnopf( 420, 570, 120, 20, zSchrift, Knopf::Style::Sichtbar, "Karte Erstellen" );
+	laden = ( Framework::Animation2D* )ladeAnimation->dublizieren();
+	laden->setPosition( 425, 275 );
+	laden->setSichtbar( 0 );
+	schrift = zSchrift->getThis();
+	aktion = 0;
+	tickVal = 0;
+	rend = 0;
+	ref = 1;
+}
+
+// Destruktor
+Auswahl::~Auswahl()
+{
+	if( run )
+		warteAufThread( 1000 );
+	if( run )
+		ende();
+	int anz = karten->getZeilenAnzahl();
+	for( int i = 0; i < anz; i++ )
+	{
+		( (TextFeld*)karten->zZeichnung( 0, i ) )->release();
+		( (TextFeld*)karten->zZeichnung( 1, i ) )->release();
+		( (TextFeld*)karten->zZeichnung( 2, i ) )->release();
+		( (TextFeld*)karten->zZeichnung( 3, i ) )->release();
+		( (TextFeld*)karten->zZeichnung( 4, i ) )->release();
+		if( !i )
+			( (TextFeld*)karten->zZeichnung( 5, i ) )->release();
+		else
+			( (Knopf*)karten->zZeichnung( 5, i ) )->release();
+	}
+	laden->release();
+	suchFilterT->release();
+	suchFilter->release();
+	suchen->release();
+	sortSpalte->release();
+	sortRichtung->release();
+	karten->release();
+	neuKarteName->release();
+	neuKarteSpielArt->release();
+	neuKarte->release();
+	schrift->release();
+	kEditor->release();
+}
+
+// nicht constant
+void Auswahl::setSichtbar( bool sicht )
+{
+	sichtbar = sicht;
+	if( sichtbar )
+	{
+		MausEreignis me;
+		me.id = ME_RLinks;
+		me.verarbeitet = 0;
+		me.mx = suchen->getX() + 1;
+		me.my = suchen->getY() + 1;
+		doMausEreignis( me );
+	}
+}
+
+void Auswahl::thread()
+{
+	laden->setSichtbar( 1 );
+    if( aktion < 0 )
+    {
+        int port = 0;
+        Text ip = "";
+        if( !infoKlient->getEditorServer( 0, &port, &ip ) )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( infoKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            aktion = 0;
+            laden->setSichtbar( 0 );
+            run = 0;
+            return;
+        }
+        bool ok = 0;
+        if( editorKlient->verbinde( port, ip ) )
+        {
+            if( editorKlient->karteErstellen( neuKarteName->zText(), infoKlient->getSpielId( neuKarteSpielArt->zEintrag( neuKarteSpielArt->getAuswahl() )->zText()->getText() ) ) )
+                ok = 1;
+            editorKlient->trenne();
+        }
+        if( !ok )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            aktion = 0;
+            laden->setSichtbar( 0 );
+            run = 0;
+            return;
+        }
+        aktion = 0;
+        laden->setSichtbar( 0 );
+        run = 0;
+        return;
+    }
+	if( aktion )
+	{
+        int port = 0;
+        Text ip = "";
+        if( !infoKlient->getEditorServer( aktion, &port, &ip ) )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( infoKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            aktion = 0;
+            laden->setSichtbar( 0 );
+            run = 0;
+            return;
+        }
+        bool ok = 0;
+        if( editorKlient->verbinde( port, ip ) )
+        {
+            if( editorKlient->ladeKarte( aktion ) )
+                ok = 1;
+        }
+        if( !ok )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            aktion = 0;
+            laden->setSichtbar( 0 );
+            run = 0;
+            return;
+        }
+		kEditor->setKarte( aktion );
+		aktion = 0;
+		setSichtbar( 0 );
+		while( alpha != 0 )
+			Sleep( 100 );
+		laden->setSichtbar( 0 );
+		run = 0;
+		return;
+	}
+	Array< int > *saList = infoKlient->getAccountSpielArtListe();
+	if( saList )
+	{
+		RCArray< Text > *saNamen = new RCArray< Text >();
+		int anz = saList->getEintragAnzahl();
+		for( int i = 0; i < anz; i++ )
+		{
+			if( !saList->hat( i ) )
+				continue;
+			Text *name = infoKlient->getSpielName( saList->hat( i ) ? saList->get( i ) : 0 );
+			if( name )
+				saNamen->add( name );
+		}
+		neuKarteSpielArt->lockZeichnung();
+		neuKarteSpielArt->setAuswahl( 0 );
+		anz = neuKarteSpielArt->getEintragAnzahl();
+		for( int i = 0; i < anz; i++ )
+			neuKarteSpielArt->removeEintrag( 0 );
+		anz = saNamen->getEintragAnzahl();
+		for( int i = 0; i < anz; i++ )
+		{
+			if( saNamen->z( i ) )
+				neuKarteSpielArt->addEintrag( saNamen->z( i )->getText() );
+		}
+		neuKarteSpielArt->unlockZeichnung();
+		saNamen->release();
+		saList->release();
+	}
+	karten->lockZeichnung();
+	int anz = karten->getZeilenAnzahl();
+	for( int i = 1; i < anz; i++ )
+	{
+		( (TextFeld*)karten->zZeichnung( 0, 1 ) )->release();
+		( (TextFeld*)karten->zZeichnung( 1, 1 ) )->release();
+		( (TextFeld*)karten->zZeichnung( 2, 1 ) )->release();
+		( (TextFeld*)karten->zZeichnung( 3, 1 ) )->release();
+		( (TextFeld*)karten->zZeichnung( 4, 1 ) )->release();
+		( (Knopf*)karten->zZeichnung( 5, 1 ) )->release();
+		karten->removeZeile( 1 );
+	}
+	karten->unlockZeichnung();
+	Bild *shopWeiter = bilder->get( "shop.ltdb/weiter.png" );
+	if( !shopWeiter )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/shop.ltdb" ) );
+		datei->leseDaten( 0 );
+		shopWeiter = datei->laden( 0, new Text( "weiter.png" ) );
+		datei->release();
+		bilder->add( "shop.ltdb/weiter.png", shopWeiter->getThis() );
+	}
+	Array< int > *kId = new Array< int >();
+	RCArray< Text > *kName = new RCArray< Text >();
+	RCArray< Text > *saName = new RCArray< Text >();
+	Array< int > *kupfer = new Array< int >();
+	Array< int > *verkauft = new Array< int >();
+	Array< int > *maxSpieler = new Array< int >();
+	int kAnz = infoKlient->getKartenListe( suchFilter->zText()->getText(), (char)sortSpalte->getAuswahl(), (char)sortRichtung->getAuswahl(),
+										   kId, kName, saName, kupfer, verkauft, maxSpieler );
+	for( int i = 0; i < kAnz; i++ )
+	{
+		Text zeile;
+		zeile = kId->get( i );
+		karten->addZeile( zeile );
+		karten->setZeichnungZ( 0, i + 1, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, kName->z( i )->getText() ) );
+		karten->setZeichnungZ( 1, i + 1, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, saName->z( i )->getText() ) );
+		karten->setZeichnungZ( 2, i + 1, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, Text() += kupfer->get( i ) ) );
+		karten->setZeichnungZ( 3, i + 1, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, Text() += verkauft->get( i ) ) );
+		karten->setZeichnungZ( 4, i + 1, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, Text() += maxSpieler->get( i ) ) );
+		Knopf *weiter = initKnopf( 0, 0, 0, 0, schrift, 0, "" );
+		weiter->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+		weiter->setHintergrundBildZ( shopWeiter->getThis() );
+		weiter->setMausEreignisParameter( this );
+		weiter->setMausEreignis( auswahlWeiterME );
+		karten->setZeichnungZ( 5, i + 1, weiter );
+	}
+	kId->release();
+	kName->release();
+	saName->release();
+	kupfer->release();
+	verkauft->release();
+	maxSpieler->release();
+	shopWeiter->release();
+	laden->setSichtbar( 0 );
+	run = 0;
+}
+
+bool Auswahl::weiterME( Zeichnung *obj, MausEreignis &me )
+{
+	if( me.id != ME_RLinks )
+		return 1;
+	karten->lockZeichnung();
+	int anz = karten->getZeilenAnzahl();
+	for( int i = 1; i < anz; i++ )
+	{
+		if( karten->zZeichnung( 5, i ) == obj )
+		{
+            aktion = *karten->zZeilenName( i );
+			start();
+		}
+	}
+	karten->unlockZeichnung();
+	return 1;
+}
+
+void Auswahl::doMausEreignis( MausEreignis &me )
+{
+	if( !sichtbar || run )
+		return;
+	suchFilter->doMausEreignis( me );
+	bool vera = me.verarbeitet;
+	suchen->doMausEreignis( me );
+	if( !vera && me.verarbeitet && me.id == ME_RLinks )
+	{
+		aktion = 0;
+		start();
+	}
+	int ausw = sortSpalte->getAuswahl();
+	sortSpalte->doMausEreignis( me );
+	if( ausw != sortSpalte->getAuswahl() )
+	{
+		aktion = 0;
+		start();
+        sortSpalte->einklappen();
+	}
+	ausw = sortRichtung->getAuswahl();
+	sortRichtung->doMausEreignis( me );
+	if( ausw != sortRichtung->getAuswahl() )
+	{
+		aktion = 0;
+		start();
+        sortRichtung->einklappen();
+	}
+	karten->doMausEreignis( me );
+	neuKarteName->doMausEreignis( me );
+	neuKarteSpielArt->doMausEreignis( me );
+    vera = me.verarbeitet;
+    neuKarte->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+    {
+        aktion = -1;
+        start();
+    }
+}
+
+void Auswahl::doTastaturEreignis( TastaturEreignis &te )
+{
+	if( !sichtbar || run )
+		return;
+	bool vera = te.verarbeitet;
+	suchFilter->doTastaturEreignis( te );
+	if( !vera && te.verarbeitet && te.taste == T_Enter && te.id == TE_Release )
+	{
+		MausEreignis me;
+		me.id = ME_RLinks;
+		me.verarbeitet = 0;
+		me.mx = suchen->getX() + 1;
+		me.my = suchen->getY() + 1;
+		doMausEreignis( me );
+	}
+	neuKarteName->doTastaturEreignis( te );
+}
+
+bool Auswahl::tick( double zeit )
+{
+	tickVal += zeit * 250;
+	int val = (int)tickVal;
+	if( val < 1 )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	if( val > 10 )
+		val = 10;
+	rend |= sortSpalte->tick( zeit );
+	rend |= sortRichtung->tick( zeit );
+	rend |= neuKarteSpielArt->tick( zeit );
+	rend |= laden->tick( zeit );
+	rend |= suchFilterT->tick( zeit );
+	rend |= suchFilter->tick( zeit );
+	rend |= suchen->tick( zeit );
+	rend |= karten->tick( zeit );
+	rend |= neuKarteName->tick( zeit );
+	rend |= neuKarte->tick( zeit );
+	if( sichtbar && alpha != 255 && !run )
+	{
+		if( alpha + val > 255 )
+			alpha = 255;
+		else
+			alpha += val;
+		rend = 1;
+	}
+	if( sichtbar && alpha != 125 && run )
+	{
+		if( alpha > 125 )
+		{
+			if( alpha - val < 125 )
+				alpha = 125;
+			else
+				alpha -= val;
+			rend = 1;
+		}
+		else
+		{
+			if( alpha + val > 125 )
+				alpha = 125;
+			else
+				alpha += 125;
+			rend = 1;
+		}
+	}
+	if( !sichtbar && alpha != 0 )
+	{
+		if( alpha - val < 0 )
+			alpha = 0;
+		else
+			alpha -= val;
+		rend = 1;
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void Auswahl::render( Bild &zRObj )
+{
+	if( !alpha )
+		return;
+	zRObj.setAlpha( alpha );
+	suchFilterT->render( zRObj );
+	suchFilter->render( zRObj );
+	suchen->render( zRObj );
+	karten->render( zRObj );
+	neuKarteName->render( zRObj );
+	neuKarte->render( zRObj );
+	neuKarteSpielArt->render( zRObj );
+	sortSpalte->render( zRObj );
+	sortRichtung->render( zRObj );
+	zRObj.releaseAlpha();
+	laden->render( zRObj );
+}
+
+// constant
+bool Auswahl::istSichtbar() const
+{
+	return sichtbar;
+}
+
+// Reference Counting
+Auswahl *Auswahl::getThis()
+{
+	ref++;
+	return this;
+}
+
+Auswahl *Auswahl::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Ereignisse
+bool auswahlWeiterME( void *p, void *obj, MausEreignis me )
+{
+	if( p )
+		return ( (Auswahl*)p )->weiterME( (Zeichnung*)obj, me );
+	return 1;
+}

+ 58 - 0
KSGClient/NachLogin/Editor/Auswahl/Auswahl.h

@@ -0,0 +1,58 @@
+#ifndef Auswahl_H
+#define Auswahl_H
+
+#include <Knopf.h>
+#include <Animation.h>
+#include <AuswahlBox.h>
+#include <Tabelle.h>
+#include <Thread.h>
+#include "../Karte/KartenEditor.h"
+
+using namespace Framework;
+
+class Auswahl : private Thread
+{
+private:
+	KartenEditor *kEditor;
+	Animation2D *laden;
+	TextFeld *suchFilterT;
+	TextFeld *suchFilter;
+	Knopf *suchen;
+	AuswahlBox *sortSpalte;
+	AuswahlBox *sortRichtung;
+	ObjTabelle *karten;
+	TextFeld *neuKarteName;
+	AuswahlBox *neuKarteSpielArt;
+	Knopf *neuKarte;
+	Schrift *schrift;
+	int aktion;
+	unsigned char alpha;
+	bool sichtbar;
+	double tickVal;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	Auswahl( Schrift *zSchrift, KartenEditor *kEditor );
+	// Destruktor
+	~Auswahl();
+	// nicht constant
+	void setSichtbar( bool sicht );
+	virtual void thread();
+	bool weiterME( Zeichnung *obj, MausEreignis &me );
+	void doMausEreignis( MausEreignis &me );
+	void doTastaturEreignis( TastaturEreignis &te );
+	bool tick( double zeit );
+	void render( Bild &zRObj );
+	// constant
+	bool istSichtbar() const;
+	// Reference Counting
+	Auswahl *getThis();
+	Auswahl *release();
+};
+
+// Ereignisse
+bool auswahlWeiterME( void *p, void *obj, MausEreignis me );
+
+#endif;

+ 216 - 0
KSGClient/NachLogin/Editor/Editor.cpp

@@ -0,0 +1,216 @@
+#include "Editor.h"
+#include <Rahmen.h>
+#include "../../Global/Variablen.h"
+
+// Inhalt der Editor Klasse aus Editor.h
+// Konstruktor
+Editor::Editor( Schrift *zSchrift, Fenster *zNachLoginFenster, int x )
+	: Zeichnung()
+{
+	schrift = zSchrift->getThis();
+	bildschirmGröße = BildschirmGröße();
+	pos = Punkt( x, 35 );
+	gr = Punkt( 102, 32 );
+	rahmen = new LRahmen();
+	rahmen->setFarbe( 0xFFFFFFFF );
+	rahmen->setSize( 102, 32 );
+	alpha = 0;
+	animation = 0;
+	sichtbar = 0;
+	tickVal = 0;
+	jetzt = 0;
+	prozent1 = 0;
+	prozent2 = 0;
+	begPos = Punkt( 0, 0 );
+	begGröße = Punkt( 0, 0 );
+	größe1 = Punkt( 102, 32 );
+	pos1 = Punkt( x, 35 );
+	größe2 = Punkt( 900, 600 );
+	pos2 = bildschirmGröße / 2 - größe2 / 2;
+	laden = (Animation2D*)ladeAnimation->dublizieren();
+	laden->setSichtbar( 0 );
+	laden->setPosition( 425, 275 );
+	zNachLoginFenster->addMember( this );
+	kEditor = new KartenEditor( schrift->getThis() );
+	karteAuswahl = new Auswahl( zSchrift, kEditor->getThis() );
+	ref = 1;
+}
+
+// Destruktor
+Editor::~Editor()
+{
+	rahmen->release();
+	laden->release();
+	karteAuswahl->release();
+	kEditor->release();
+	schrift->release();
+}
+
+// nicht constant
+void Editor::setSichtbar( bool sicht )
+{
+	begPos = pos;
+	begGröße = gr;
+	animation |= ( sicht ? 0x1 : 0x2 );
+	rend = 1;
+}
+
+void Editor::doMausEreignis( MausEreignis &me )
+{
+	if( animation || !sichtbar )
+		return;
+	me.mx -= pos.x;
+	me.my -= pos.y;
+	switch( jetzt )
+	{
+	case 1: // Karten Auswahl
+		karteAuswahl->doMausEreignis( me );
+		break;
+	case 2: // Karten Editor
+		kEditor->doMausEreignis( me );
+		break;
+	}
+	me.mx += pos.x;
+	me.my += pos.y;
+}
+
+void Editor::doTastaturEreignis( TastaturEreignis &te )
+{
+	if( animation || !sichtbar )
+		return;
+	switch( jetzt )
+	{
+	case 1: // Karten Auswahl
+		karteAuswahl->doTastaturEreignis( te );
+		break;
+	case 2: // Karten Editor
+		kEditor->doTastaturEreignis( te );
+		break;
+	}
+}
+
+bool Editor::tick( double z )
+{
+	rend |= laden->tick( z );
+	rend |= karteAuswahl->tick( z );
+	if( jetzt == 1 && !karteAuswahl->istSichtbar() )
+	{
+		kEditor->setSichtbar( 1 );
+		jetzt = 2;
+	}
+	if( jetzt == 2 && !kEditor->istSichtbar() )
+	{
+		karteAuswahl->setSichtbar( 1 );
+		jetzt = 1;
+	}
+	rend |= kEditor->tick( z );
+	tickVal += z * 150;
+	int val = (int)tickVal;
+	if( val < 1 )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	tickVal -= val;
+	if( ( animation | 0x1 ) == animation ) // Einblenden
+	{
+		if( prozent1 != 100 )
+		{
+			prozent1 += val;
+			if( prozent1 >= 100 )
+			{
+				if( !jetzt )
+				{
+					karteAuswahl->setSichtbar( 1 );
+					jetzt = 1;
+				}
+				prozent1 = 100;
+			}
+			pos = begPos + (Punkt)( ( ( Vec2< double > )( pos2 - begPos ) / 100.0 ) * prozent1 );
+			gr = begGröße + (Punkt)( ( ( Vec2< double > )( größe2 - begGröße ) / 100.0 ) * prozent1 );
+		}
+		else if( alpha != 255 )
+		{
+			alpha += val * 2;
+			if( alpha >= 255 || ( animation | 0x2 ) == animation )
+			{
+				alpha = 255;
+				animation &= ~0x1;
+				sichtbar = 1;
+				prozent1 = 0;
+			}
+		}
+		rend = 1;
+	}
+	if( ( animation | 0x2 ) == animation ) // ausblenden
+	{
+		if( alpha != 0 )
+		{
+			alpha -= val * 2;
+			if( alpha < 0 )
+				alpha = 0;
+		}
+		else
+		{
+			prozent2 += val;
+			if( prozent2 > 100 )
+				prozent2 = 100;
+			pos = begPos + (Punkt)( ( ( Vec2< double > )( pos1 - begPos ) / 100.0 ) * prozent2 );
+			gr = begGröße + (Punkt)( ( ( Vec2< double > )( größe1 - begGröße ) / 100.0 ) * prozent2 );
+			if( prozent2 == 100 )
+			{
+				prozent2 = 0;
+				animation &= ~0x2;
+				sichtbar = 0;
+			}
+		}
+		rend = 1;
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void Editor::render( Bild &zRObj )
+{
+	if( pos == pos1 )
+		return;
+	if( !zRObj.setDrawOptions( pos.x, pos.y, gr.x, gr.y ) )
+		return;
+	rahmen->setSize( gr );
+	rahmen->render( zRObj );
+	int rbr = rahmen->getRBreite();
+	zRObj.setAlpha( (unsigned char)alpha );
+	karteAuswahl->render( zRObj );
+	kEditor->render( zRObj );
+	laden->render( zRObj );
+	zRObj.releaseAlpha();
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+bool Editor::istAnimiert() const
+{
+	return animation != 0;
+}
+
+bool Editor::istSichtbar() const
+{
+	return sichtbar || prozent1 != 0;
+}
+
+// Reference Counting
+Editor *Editor::getThis()
+{
+	ref++;
+	return this;
+}
+
+Editor *Editor::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 55 - 0
KSGClient/NachLogin/Editor/Editor.h

@@ -0,0 +1,55 @@
+#ifndef Editor_H
+#define Editor_H
+
+#include <Animation.h>
+#include <Fenster.h>
+#include "Auswahl/Auswahl.h"
+#include "Karte/KartenEditor.h"
+
+using namespace Framework;
+
+class Editor : public Zeichnung
+{
+private:
+	Punkt begPos;
+	Punkt begGröße;
+	Punkt pos1;
+	Punkt größe1;
+	Punkt pos2;
+	Punkt größe2;
+	Punkt bildschirmGröße;
+	LRahmen *rahmen;
+	Animation2D *laden;
+	Schrift *schrift;
+	Auswahl *karteAuswahl;
+	KartenEditor *kEditor;
+	int dg;
+	int animation;
+	int alpha;
+	bool sichtbar;
+	int prozent1;
+	int prozent2;
+	double tickVal;
+	int jetzt;
+	int ref;
+
+public:
+	// Konstruktor
+	Editor( Schrift *zSchrift, Fenster *zNachLoginFenster, int x );
+	// Destruktor
+	~Editor();
+	// nicht constant
+	void setSichtbar( bool sicht );
+	void doMausEreignis( MausEreignis &me ) override;
+	void doTastaturEreignis( TastaturEreignis &te ) override;
+	bool tick( double z ) override;
+	void render( Bild &zRObj ) override;
+	// constant
+	bool istAnimiert() const;
+	bool istSichtbar() const;
+	// Reference Counting
+	Editor *getThis();
+	Editor *release();
+};
+
+#endif

+ 246 - 0
KSGClient/NachLogin/Editor/Karte/Beschreibung/KEBEditor.cpp

@@ -0,0 +1,246 @@
+#include "KEBeschreibung.h"
+#include <TextFeld.h>
+#include <Text.h>
+#include <MausEreignis.h>
+#include "../../../../Global/Initialisierung.h"
+#include "../../../../Global/Variablen.h"
+#include <DateiSystem.h>
+
+bool KEBKnopfPressME( void *p, void *obj, MausEreignis me );
+
+// Inhalt der KEBEditor Klasse aus KEBEditor.h
+// Konstruktor
+KEBEditor::KEBEditor( Schrift *zSchrift, KEBeschreibung *zKeb )
+{
+    beschreibung = initKnopf( 10, 10, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Beschreibung" );
+    initToolTip( beschreibung, "Beschreibung bei der Kartenauswahl", zSchrift->getThis(), hauptScreen );
+    beschreibung->setMausEreignisParameter( zKeb );
+    beschreibung->setMausEreignis( KEBKnopfPressME );
+    titelBild = initKnopf( 10, 40, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Titel Bild" );
+    initToolTip( titelBild, "Titelbild während der Kartenauswahl (200x100)", zSchrift->getThis(), hauptScreen );
+    titelBild->setMausEreignisParameter( zKeb );
+    titelBild->setMausEreignis( KEBKnopfPressME );
+    mapBild = initKnopf( 10, 70, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Minimap Bild" );
+    initToolTip( mapBild, "Kartenvorschau Bild währed des erstellens einer Gruppe (348x348)", zSchrift->getThis(), hauptScreen );
+    mapBild->setMausEreignisParameter( zKeb );
+    mapBild->setMausEreignis( KEBKnopfPressME );
+    ladenBild = initKnopf( 10, 100, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Laden Bild" );
+    initToolTip( ladenBild, "Hintergrundbild beim Laden der Karte", zSchrift->getThis(), hauptScreen );
+    ladenBild->setMausEreignisParameter( zKeb );
+    ladenBild->setMausEreignis( KEBKnopfPressME );
+    bild = initBildZ( 120, 10, 750, 510, ( BildZ::Style::normal | BildZ::Style::Alpha ) & ~BildZ::Style::Sichtbar, 0 );
+    LTDSDatei *sd = new LTDSDatei();
+    sd->setPfad( new Text( "data/schriften/ksgs.ltds" ) );
+    sd->leseDaten();
+    Schrift *ksgsS = sd->ladeSchrift();
+    sd->release();
+    text = initTextFeld( 120, 10, 750, 510, ksgsS ? ksgsS : zSchrift, ( TextFeld::Style::TextGebiet | TextFeld::Style::HScroll ) & ~TextFeld::Style::Sichtbar, "" );
+    if( ksgsS )
+        ksgsS->release();
+    speichern = initKnopf( 10, 500, 100, 20, zSchrift, 0, "Speichern" );
+    initToolTip( speichern, "Beschreibung speichern", zSchrift->getThis(), hauptScreen );
+    speichern->setMausEreignisParameter( zKeb );
+    speichern->setMausEreignis( KEBKnopfPressME );
+    importieren = initKnopf( 10, 500, 100, 20, zSchrift, 0, "Importieren" );
+    initToolTip( importieren, "Bild von Festplatte hochladen", zSchrift->getThis(), hauptScreen );
+    importieren->setMausEreignisParameter( zKeb );
+    importieren->setMausEreignis( KEBKnopfPressME );
+    vorschau = initKnopf( 10, 470, 100, 20, zSchrift, 0, "Script Testen" );
+    initToolTip( vorschau, "Die Beschreibung auf Scriptfehler testen", zSchrift->getThis(), hauptScreen );
+    vorschau->setMausEreignisParameter( zKeb );
+    vorschau->setMausEreignis( KEBKnopfPressME );
+    jetzt = 0;
+    sichtbar = 0;
+    alpha = 0;
+    tickVal = 0;
+    ref = 1;
+}
+
+// Destruktor
+KEBEditor::~KEBEditor()
+{
+    beschreibung->release();
+    titelBild->release();
+    mapBild->release();
+    ladenBild->release();
+    bild->release();
+    text->release();
+    speichern->release();
+    importieren->release();
+    vorschau->release();
+}
+
+// nicht constant
+void KEBEditor::setSichtbar( bool s )
+{
+    sichtbar = s;
+}
+
+void KEBEditor::setText( Text *zText )
+{
+    text->setText( zText->getText() );
+    bild->removeStyle( BildZ::Style::Sichtbar );
+    text->addStyle( TextFeld::Style::Sichtbar );
+    importieren->removeStyle( Knopf::Style::Sichtbar );
+    speichern->addStyle( Knopf::Style::Sichtbar );
+    vorschau->addStyle( Knopf::Style::Sichtbar );
+}
+
+void KEBEditor::setBild( Bild *zBild )
+{
+    bild->setBildZ( zBild->getThis() );
+    text->removeStyle( TextFeld::Style::Sichtbar );
+    bild->addStyle( BildZ::Style::Sichtbar );
+    speichern->removeStyle( Knopf::Style::Sichtbar );
+    importieren->addStyle( Knopf::Style::Sichtbar );
+    vorschau->removeStyle( Knopf::Style::Sichtbar );
+}
+
+bool KEBEditor::tick( double tv )
+{
+    bool ret = beschreibung->tick( tv );
+    ret |= titelBild->tick( tv );
+    ret |= mapBild->tick( tv );
+    ret |= ladenBild->tick( tv );
+    ret |= bild->tick( tv );
+    ret |= text->tick( tv );
+    ret |= speichern->tick( tv );
+    ret |= importieren->tick( tv );
+    ret |= vorschau->tick( tv );
+    tickVal += tv * 150;
+    int val = 0;
+    if( tickVal > 1 )
+        val = (int)tickVal;
+    else
+        return ret;
+    if( sichtbar && alpha != 255 )
+    {
+        if( alpha + val > 255 )
+            alpha = 255;
+        else
+            alpha += val;
+        ret = 1;
+    }
+    if( !sichtbar && alpha != 0 )
+    {
+        if( alpha - val < 0 )
+            alpha = 0;
+        else
+            alpha -= val;
+        ret = 1;
+    }
+    return ret;
+}
+
+void KEBEditor::doMausEreignis( MausEreignis &me )
+{
+    if( !sichtbar )
+        return;
+    beschreibung->setAlphaFeldFarbe( 0x5500FF00 );
+    titelBild->setAlphaFeldFarbe( 0x5500FF00 );
+    mapBild->setAlphaFeldFarbe( 0x5500FF00 );
+    ladenBild->setAlphaFeldFarbe( 0x5500FF00 );
+    bool mv = me.verarbeitet;
+    beschreibung->doMausEreignis( me );
+    if( !mv && me.verarbeitet && me.id == ME_RLinks )
+        jetzt = 1;
+    mv = me.verarbeitet;
+    titelBild->doMausEreignis( me );
+    if( !mv && me.verarbeitet && me.id == ME_RLinks )
+        jetzt = 2;
+    mv = me.verarbeitet;
+    mapBild->doMausEreignis( me );
+    if( !mv && me.verarbeitet && me.id == ME_RLinks )
+        jetzt = 3;
+    mv = me.verarbeitet;
+    ladenBild->doMausEreignis( me );
+    if( !mv && me.verarbeitet && me.id == ME_RLinks )
+        jetzt = 4;
+    if( jetzt == 1 )
+        beschreibung->setAlphaFeldFarbe( 0x0000FF00 );
+    if( jetzt == 2 )
+        titelBild->setAlphaFeldFarbe( 0x0000FF00 );
+    if( jetzt == 3 )
+        mapBild->setAlphaFeldFarbe( 0x0000FF00 );
+    if( jetzt == 4 )
+        ladenBild->setAlphaFeldFarbe( 0x0000FF00 );
+    bild->doMausEreignis( me );
+    text->doMausEreignis( me );
+    speichern->doMausEreignis( me );
+    importieren->doMausEreignis( me );
+    vorschau->doMausEreignis( me );
+}
+
+void KEBEditor::doTastaturEreignis( TastaturEreignis &te )
+{
+    if( !sichtbar )
+        return;
+    text->doTastaturEreignis( te );
+}
+
+void KEBEditor::render( Bild &zRObj )
+{
+    if( !alpha )
+        return;
+    zRObj.setAlpha( alpha );
+    beschreibung->render( zRObj );
+    titelBild->render( zRObj );
+    mapBild->render( zRObj );
+    ladenBild->render( zRObj );
+    text->render( zRObj );
+    bild->render( zRObj );
+    speichern->render( zRObj );
+    importieren->render( zRObj );
+    vorschau->render( zRObj );
+    zRObj.releaseAlpha();
+}
+
+// constant
+int KEBEditor::getKNum( Knopf *zK ) const
+{
+    if( zK == beschreibung )
+        return 1;
+    if( zK == titelBild )
+        return 2;
+    if( zK == mapBild )
+        return 3;
+    if( zK == ladenBild )
+        return 4;
+    if( zK == speichern )
+        return -1;
+    if( zK == importieren )
+        return -2;
+    if( zK == vorschau )
+        return -3;
+    return 0;
+}
+
+Text *KEBEditor::zBeschreibung() const
+{
+    return text->zText();
+}
+
+int KEBEditor::getJetzt() const
+{
+    return jetzt;
+}
+
+bool KEBEditor::istSichtbar() const
+{
+    return sichtbar;
+}
+
+// Reference Counting
+KEBEditor *KEBEditor::getThis()
+{
+    ref++;
+    return this;
+}
+
+KEBEditor *KEBEditor::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 48 - 0
KSGClient/NachLogin/Editor/Karte/Beschreibung/KEBEditor.h

@@ -0,0 +1,48 @@
+#pragma once
+
+#include <Knopf.h>
+#include <Bild.h>
+
+using namespace Framework;
+class KEBeschreibung;
+
+class KEBEditor : public Zeichnung
+{
+private:
+    Knopf *beschreibung;
+    Knopf *titelBild;
+    Knopf *mapBild;
+    Knopf *ladenBild;
+    BildZ *bild;
+    TextFeld *text;
+    Knopf *speichern;
+    Knopf *importieren;
+    Knopf *vorschau;
+    int jetzt;
+    bool sichtbar;
+    unsigned char alpha;
+    double tickVal;
+    int ref;
+
+public:
+    // Konstruktor
+    KEBEditor( Schrift *zSchrift, KEBeschreibung *zKeb );
+    // Destruktor
+    ~KEBEditor();
+    // nicht constant
+    void setSichtbar( bool s );
+    void setText( Text *zText );
+    void setBild( Bild *zBild );
+    bool tick( double tv ) override;
+    void doMausEreignis( MausEreignis &me ) override;
+    void doTastaturEreignis( TastaturEreignis &te ) override;
+    void render( Bild &zRObj ) override;
+    // constant
+    int getKNum( Knopf *zK ) const;
+    Text *zBeschreibung() const;
+    int getJetzt() const;
+    bool istSichtbar() const;
+    // Reference Counting
+    KEBEditor *getThis();
+    KEBEditor *release();
+};

+ 352 - 0
KSGClient/NachLogin/Editor/Karte/Beschreibung/KEBVorschau.cpp

@@ -0,0 +1,352 @@
+#include "KEBVorschau.h"
+#include "../../../../Global/Variablen.h"
+#include "../../../../Global/Initialisierung.h"
+#include <Datei.h>
+
+void kEBVorschauKSGSAktion( void *p, RCArray< KSGSVariable > *parameter, KSGSVariable **retVal )
+{
+    if( !p )
+        return;
+    ( (KEBVorschauKarteScript*)p )->ksgsAktion( parameter, retVal );
+}
+
+// Inhalt der KEBVorschauKarteScript Klasse aus KEBVorschau.h
+// Konstruktor
+KEBVorschauKarteScript::KEBVorschauKarteScript( Schrift *zSchrift, TextFeld *zLog )
+    : Thread()
+{
+    ksgs = dllDateien->ladeDLL( "KSGScript.dll", "data/bin/KSGScript.dll" );
+    if( ksgs )
+    {
+        KSGSGetZeichnung getKSGScript = (KSGSGetZeichnung)GetProcAddress( ksgs, KSGS_START_FUNKTION );
+        if( getKSGScript )
+        {
+            fenster = getKSGScript();
+            fenster->setSchriftZ( zSchrift->getThis() );
+            fenster->setSize( 578, 428 );
+            fenster->setRückrufParam( this );
+            fenster->setRückrufFunktion( kEBVorschauKSGSAktion );
+            fenster->setLog( zLog->getThis() );
+        }
+        else
+        {
+            fenster = 0;
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                          new Text( "Der Einstiegspunkt '" KSGS_START_FUNKTION "' in der DLL-Datei "
+                                                                    "'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+                                                          new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+        }
+    }
+    else
+    {
+        fenster = 0;
+        nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                      new Text( "Die DLL-Datei 'data/bin/KSGScript.dll' konnte nicht geladen werden." ),
+                                                      new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+    }
+    ram = new LRahmen();
+    ram->setSize( 578, 428 );
+    ram->setFarbe( 0xFFFFFFFF );
+    pos = Punkt( 120, 10 );
+    erlaubt = 1;
+    sichtbar = 0;
+    alpha = 0;
+    aktion = 0;
+    ak = 0;
+    ref = 1;
+}
+
+// Destruktor
+KEBVorschauKarteScript::~KEBVorschauKarteScript()
+{
+    if( fenster )
+    {
+        fenster->zurücksetzen();
+        fenster->release();
+    }
+    ram->release();
+    if( ksgs )
+        dllDateien->releaseDLL( "KSGScript.dll" );
+}
+
+// nicht constant
+void KEBVorschauKarteScript::thread()
+{
+    sichtbar = 0;
+    while( alpha )
+        Sleep( 100 );
+    if( ak == 1 )
+    {
+        pfad += "/seite.ksgs";
+        if( fenster )
+            fenster->setScriptDatei( pfad );
+    }
+    fenster->neuLaden();
+    KSGSGetVariable getKSGSVar = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
+    RCArray< KSGSVariable > *params = new RCArray< KSGSVariable >();
+    KSGSVariableDef p1;
+    p1.typId = KSGS_BOOL;
+    p1.wert = erlaubt;
+    params->add( getKSGSVar( fenster, &p1 ) );
+    KSGSVariable *var = fenster->startFunktion( fenster->getFunktionId( "_set_Erlaubt" ), params );
+    if( var )
+        var->release();
+    sichtbar = 1;
+    ak = 0;
+    run = 0;
+}
+
+void KEBVorschauKarteScript::setErlaubt( bool e )
+{
+    erlaubt = e;
+    KSGSGetVariable getKSGSVar = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
+    RCArray< KSGSVariable > *params = new RCArray< KSGSVariable >();
+    KSGSVariableDef p1;
+    p1.typId = KSGS_BOOL;
+    p1.wert = erlaubt;
+    params->add( getKSGSVar( fenster, &p1 ) );
+    KSGSVariable *var = fenster->startFunktion( fenster->getFunktionId( "_set_Erlaubt" ), params );
+    if( var )
+        var->release();
+}
+
+void KEBVorschauKarteScript::ladeKarteSeite( char *pfad )
+{
+    if( run )
+        warteAufThread( 5000 );
+    if( run )
+        ende();
+    this->pfad = pfad;
+    ak = 1;
+    start();
+}
+
+void KEBVorschauKarteScript::ksgsAktion( RCArray< KSGSVariable > *parameter, KSGSVariable **retVal )
+{
+}
+
+void KEBVorschauKarteScript::doMausEreignis( MausEreignis &me )
+{
+    me.mx -= pos.x;
+    me.my -= pos.y;
+    if( fenster )
+        fenster->doMausEreignis( me );
+    me.mx += pos.x;
+    me.my += pos.y;
+}
+
+void KEBVorschauKarteScript::doTastaturEreignis( TastaturEreignis &te )
+{
+    if( fenster )
+        fenster->doTastaturEreignis( te );
+}
+
+bool KEBVorschauKarteScript::tick( double zeit )
+{
+    bool rend = fenster ? fenster->tick( zeit ) : 0;
+    if( !sichtbar && alpha > 0 )
+    {
+        if( alpha - zeit * 150 < 0 )
+            alpha = 0;
+        else
+            alpha -= (unsigned char)( zeit * 150 );
+        rend = 1;
+    }
+    if( sichtbar && alpha < 255 )
+    {
+        if( alpha + zeit * 150 > 255 )
+            alpha = 255;
+        else
+            alpha += (unsigned char)( zeit * 150 );
+        rend = 1;
+    }
+    return rend;
+}
+
+void KEBVorschauKarteScript::render( Bild &zRObj )
+{
+    if( !zRObj.setDrawOptions( pos.x, pos.y, ram->getBreite(), ram->getHeight() ) )
+        return;
+    zRObj.setAlpha( alpha );
+    ram->render( zRObj );
+    if( fenster )
+        fenster->render( zRObj );
+    zRObj.releaseAlpha();
+    zRObj.releaseDrawOptions();
+}
+
+// Reference Counting
+KEBVorschauKarteScript *KEBVorschauKarteScript::getThis()
+{
+    ref++;
+    return this;
+}
+
+KEBVorschauKarteScript *KEBVorschauKarteScript::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+
+// Inhalt der KEBVorschau Klasse aus KEBVorschau.h
+// Konstruktor
+KEBVorschau::KEBVorschau( Schrift *zSchrift )
+{
+    this->schrift = zSchrift->getThis();
+    neu = initKnopf( 10, 10, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Neu starten" );
+    beenden = initKnopf( 10, 40, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Beenden" );
+    log = initTextFeld( 10, 445, 860, 75, zSchrift, ( TextFeld::Style::TextGebiet | TextFeld::Style::HScroll ) & ~TextFeld::Style::Erlaubt, "Log:\n" );
+    script = new KEBVorschauKarteScript( zSchrift, log );
+    erlaubt = initKontrollKnopf( 10, 70, 100, 20, zSchrift, KontrollKnopf::Style::Normal | KontrollKnopf::Style::Selected, "Erlaubt" );
+    alpha = 0;
+    sichtbar = 0;
+    tickVal = 0;
+    aktion = 0;
+    rend = 0;
+    ref = 1;
+}
+
+// Destruktor
+KEBVorschau::~KEBVorschau()
+{
+    schrift->release();
+    script->release();
+    neu->release();
+    beenden->release();
+    log->release();
+    erlaubt->release();
+}
+
+// nicht constant
+int KEBVorschau::getAktion()
+{
+    int ret = aktion;
+    aktion = 0;
+    return ret;
+}
+
+bool KEBVorschau::ladeKarte()
+{
+    Text *scr = editorKlient->beschreibungLaden();
+    if( !scr )
+    {
+        nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+        return 0;
+    }
+    else
+    {
+        Datei d;
+        d.setDatei( "data/tmp/ke/kbv/seite.ksgs" );
+        d.erstellen();
+        if( !d.open( Datei::Style::schreiben ) )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Fehler beim open der Datei 'data/tmp/ke/kbv/seite.ksgs'" ), new Text( "Ok" ) );
+            return 0;
+        }
+        d.schreibe( scr->getText(), scr->getLength() );
+        d.close();
+        scr->release();
+        script->ladeKarteSeite( "data/tmp/ke/kbv" );
+    }
+    return 1;
+}
+
+void KEBVorschau::setSichtbar( bool sicht )
+{
+    sichtbar = sicht;
+}
+
+void KEBVorschau::doMausEreignis( MausEreignis &me )
+{
+    if( !sichtbar )
+        return;
+    script->doMausEreignis( me );
+    bool mev = me.verarbeitet;
+    neu->doMausEreignis( me );
+    if( !mev && me.verarbeitet && me.id == ME_RLinks )
+        script->ladeKarteSeite( "data/tmp/ke/kbv" );
+    mev = me.verarbeitet;
+    beenden->doMausEreignis( me );
+    if( !mev && me.verarbeitet && me.id == ME_RLinks )
+        aktion = 1;
+    log->doMausEreignis( me );
+    bool eu = 0;
+    bool sel = erlaubt->hatStyle( KontrollKnopf::Style::Selected );
+    erlaubt->doMausEreignis( me );
+    if( sel != erlaubt->hatStyle( KontrollKnopf::Style::Selected ) )
+        script->setErlaubt( erlaubt->hatStyle( KontrollKnopf::Style::Selected ) );
+}
+
+void KEBVorschau::doTastaturEreignis( TastaturEreignis &te )
+{
+    if( !sichtbar )
+        return;
+    script->doTastaturEreignis( te );
+}
+
+bool KEBVorschau::tick( double zeit )
+{
+    bool ret = script->tick( zeit );
+    ret |= neu->tick( zeit );
+    ret |= beenden->tick( zeit );
+    ret |= log->tick( zeit );
+    ret |= erlaubt->tick( zeit );
+    tickVal += zeit * 150;
+    int val = 0;
+    if( tickVal > 1 )
+        val = (int)tickVal;
+    else
+        return ret;
+    if( sichtbar && alpha != 255 )
+    {
+        if( alpha + val > 255 )
+            alpha = 255;
+        else
+            alpha += val;
+        ret = 1;
+    }
+    if( !sichtbar && alpha != 0 )
+    {
+        if( alpha - val < 0 )
+            alpha = 0;
+        else
+            alpha -= val;
+        ret = 1;
+    }
+    return ret;
+}
+
+void KEBVorschau::render( Bild &zRObj )
+{
+    zRObj.setAlpha( alpha );
+    script->render( zRObj );
+    neu->render( zRObj );
+    beenden->render( zRObj );
+    log->render( zRObj );
+    erlaubt->render( zRObj );
+    zRObj.releaseAlpha();
+}
+
+// constant
+bool KEBVorschau::istSichtbar() const
+{
+    return sichtbar;
+}
+
+// Reference Counting
+KEBVorschau *KEBVorschau::getThis()
+{
+    ref++;
+    return this;
+}
+
+KEBVorschau *KEBVorschau::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 78 - 0
KSGClient/NachLogin/Editor/Karte/Beschreibung/KEBVorschau.h

@@ -0,0 +1,78 @@
+#pragma once
+#include <KSGScript.h>
+#include <AuswahlBox.h>
+#include <Thread.h>
+#include <Knopf.h>
+
+using namespace Framework;
+using namespace KSGScript;
+
+class KEBVorschauKarteScript : public Thread
+{
+private:
+    KSGScriptObj *fenster;
+    Punkt pos;
+    LRahmen *ram;
+    HINSTANCE ksgs;
+    Text pfad;
+    bool erlaubt;
+    bool sichtbar;
+    unsigned char alpha;
+    bool aktion;
+    int ak;
+    int ref;
+
+public:
+    // Konstruktor
+    KEBVorschauKarteScript( Schrift *zSchrift, TextFeld *zLog );
+    // Destruktor
+    ~KEBVorschauKarteScript();
+    // nicht constant
+    void thread() override;
+    void setErlaubt( bool e );
+    void ladeKarteSeite( char *pfad );
+    void ksgsAktion( RCArray< KSGSVariable > *parameter, KSGSVariable **retVal );
+    void doMausEreignis( MausEreignis &me );
+    void doTastaturEreignis( TastaturEreignis &te );
+    bool tick( double zeit );
+    void render( Bild &zRObj );
+    // Reference Counting
+    KEBVorschauKarteScript *getThis();
+    KEBVorschauKarteScript *release();
+};
+
+class KEBVorschau : public Zeichnung
+{
+private:
+    Schrift *schrift;
+    KEBVorschauKarteScript *script;
+    Knopf *neu;
+    Knopf *beenden;
+    TextFeld *log;
+    KontrollKnopf *erlaubt;
+    unsigned char alpha;
+    bool sichtbar;
+    double tickVal;
+    int aktion;
+    bool rend;
+    int ref;
+
+public:
+    // Konstruktor
+    KEBVorschau( Schrift *zSchrift );
+    // Destruktor
+    ~KEBVorschau();
+    // nicht constant
+    int getAktion();
+    bool ladeKarte();
+    void setSichtbar( bool sicht );
+    void doMausEreignis( MausEreignis &me );
+    void doTastaturEreignis( TastaturEreignis &te );
+    bool tick( double zeit );
+    void render( Bild &zRObj );
+    // constant
+    bool istSichtbar() const;
+    // Reference Counting
+    KEBVorschau *getThis();
+    KEBVorschau *release();
+};

+ 428 - 0
KSGClient/NachLogin/Editor/Karte/Beschreibung/KEBeschreibung.cpp

@@ -0,0 +1,428 @@
+#include "KEBeschreibung.h"
+#include "../../../../Global/Initialisierung.h"
+#include "../../../../Global/Variablen.h"
+
+bool KEBKnopfPressME( void *p, void *obj, MausEreignis me )
+{
+    if( p )
+        ( (KEBeschreibung*)p )->knopfPress( (Knopf*)obj, &me );
+    return 1;
+}
+
+// Inhalt der KEBeschreibung Klasse aus KEBeschreibung.h
+// Konstruktor
+KEBeschreibung::KEBeschreibung( int karte, Schrift *zSchrift )
+    : Thread()
+{
+    schrift = zSchrift->getThis();
+    Text *kName = infoKlient->getKarteName( karte );
+    Text titel = kName ? kName->getText() : "<Karte>";
+    titel += " - Beschreibung";
+    if( kName )
+        kName->release();
+    fenster = initFenster( 10, 40, 880, 550, zSchrift, Fenster::Style::Sichtbar | Fenster::Style::Titel | Fenster::Style::TitelBuffered | Fenster::Style::Erlaubt | Fenster::Style::Rahmen, titel );
+    editor = new KEBEditor( zSchrift, this );
+    vorschau = new KEBVorschau( zSchrift );
+    fenster->addMember( editor );
+    fenster->addMember( vorschau );
+    laden = (Animation2D*)ladeAnimation->dublizieren();
+    laden->setPosition( 425, 275 );
+    laden->setSichtbar( 0 );
+    importDialog = 0;
+    importPfad = 0;
+    animation = 0;
+    tickVal = 0;
+    sichtbar = 0;
+    rechts = 0;
+    xStart = 0;
+    breite = 0;
+    aktion = 0;
+    jetzt = 0;
+    this->karte = karte;
+    alpha = 255;
+    ref = 1;
+}
+
+// Destruktor
+KEBeschreibung::~KEBeschreibung()
+{
+    if( run )
+    {
+        warteAufThread( 5000 );
+        if( run )
+            ende();
+    }
+    fenster->release();
+    laden->release();
+    schrift->release();
+    editor->release();
+    vorschau->release();
+    if( importDialog )
+        importDialog->release();
+    if( importPfad )
+        importPfad->release();
+}
+
+// nicht constant
+void KEBeschreibung::setSichtbar( bool s, bool vr )
+{
+    animation = 1;
+    sichtbar = s;
+    rechts = vr;
+    if( sichtbar )
+    {
+        if( vr )
+        {
+            xStart = 900;
+            breite = 0;
+        }
+        else
+        {
+            xStart = 0;
+            breite = 0;
+        }
+        if( !run )
+        {
+            aktion = 0;
+            start();
+        }
+    }
+}
+
+void KEBeschreibung::thread()
+{
+    laden->setSichtbar( 1 );
+    if( aktion == 0 )
+    {
+        if( jetzt == 1 )
+        { // beschreibung laden
+            Text *t = editorKlient->beschreibungLaden();
+            t->ersetzen( "\r\n", "\n" );
+            hauptScreen->lock();
+            if( !t )
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            else
+                editor->setText( t );
+            hauptScreen->unlock();
+            t->release();
+        }
+        if( jetzt == 2 )
+        { // Titelbild laden
+            Bild *b = editorKlient->titelbildLaden();
+            hauptScreen->lock();
+            if( !b )
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            else
+                editor->setBild( b );
+            hauptScreen->unlock();
+            b->release();
+        }
+        if( jetzt == 3 )
+        { // Minimap Bild laden
+            Bild *b = editorKlient->minimapLaden();
+            hauptScreen->lock();
+            if( !b )
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            else
+                editor->setBild( b );
+            hauptScreen->unlock();
+            b->release();
+        }
+        if( jetzt == 4 )
+        { // Ladebild laden
+            Bild *b = editorKlient->ladebildLaden();
+            hauptScreen->lock();
+            if( !b )
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            else
+                editor->setBild( b );
+            hauptScreen->unlock();
+            b->release();
+        }
+        editor->setSichtbar( 1 );
+    }
+    if( aktion == 1 )
+    {
+        if( jetzt == 1 )
+        { // Beschreibung speichern
+            if( !editorKlient->beschreibungSpeichern( editor->zBeschreibung() ) )
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+        }
+        if( jetzt == 2 )
+        { // Titelbild hochladen
+            importPfad->ersetzen( "\\", "/" );
+            Text *n = importPfad->getTeilText( importPfad->positionVon( "/", importPfad->anzahlVon( "/" ) - 1 ) + 1 );
+            Text name = n->getText();
+            n->release();
+            Text *err = new Text();
+            Bild *b = ladeBild( importPfad->getText(), err );
+            if( !b )
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), err, new Text( "Ok" ) );
+            else
+            {
+                err->release();
+                if( !editorKlient->titelbildSpeichern( b ) )
+                    nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+                hauptScreen->lock();
+                editor->setBild( b );
+                hauptScreen->unlock();
+                b->release();
+            }
+        }
+        if( jetzt == 3 )
+        { // Minimap hochladen
+            importPfad->ersetzen( "\\", "/" );
+            Text *n = importPfad->getTeilText( importPfad->positionVon( "/", importPfad->anzahlVon( "/" ) - 1 ) + 1 );
+            Text name = n->getText();
+            n->release();
+            Text *err = new Text();
+            Bild *b = ladeBild( importPfad->getText(), err );
+            if( !b )
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), err, new Text( "Ok" ) );
+            else
+            {
+                err->release();
+                if( !editorKlient->minimapSpeichern( b ) )
+                    nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+                hauptScreen->lock();
+                editor->setBild( b );
+                hauptScreen->unlock();
+                b->release();
+            }
+        }
+        if( jetzt == 4 )
+        { // Ladebild hochladen
+            importPfad->ersetzen( "\\", "/" );
+            Text *n = importPfad->getTeilText( importPfad->positionVon( "/", importPfad->anzahlVon( "/" ) - 1 ) + 1 );
+            Text name = n->getText();
+            n->release();
+            Text *err = new Text();
+            Bild *b = ladeBild( importPfad->getText(), err );
+            if( !b )
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), err, new Text( "Ok" ) );
+            else
+            {
+                err->release();
+                if( !editorKlient->ladebildSpeichern( b ) )
+                    nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+                hauptScreen->lock();
+                editor->setBild( b );
+                hauptScreen->unlock();
+                b->release();
+            }
+        }
+    }
+    if( aktion == 2 )
+    { // Vorschau
+        if( vorschau->ladeKarte() )
+        {
+            editor->setSichtbar( 0 );
+            vorschau->setSichtbar( 1 );
+        }
+    }
+    run = 0;
+    laden->setSichtbar( 0 );
+    return;
+}
+
+void KEBeschreibung::knopfPress( Knopf *k, MausEreignis *me )
+{
+    if( run || me->id != ME_RLinks )
+        return;
+    if( editor->getKNum( k ) > 0 && jetzt != editor->getKNum( k ) )
+    {
+        jetzt = editor->getKNum( k );
+        aktion = 0;
+        start();
+    }
+    if( editor->getKNum( k ) == -1 )
+    {
+        aktion = 1;
+        start();
+    }
+    if( editor->getKNum( k ) == -2 )
+    {
+        if( !importDialog )
+        {
+            importDialog = new DateiDialogTh();
+            importDialog->setOpen( 1 );
+            importDialog->setDateiTypAuswahl( 4 );
+            importDialog->addDateiTyp( "JPEG-Bild", "*.jpg;*.jpeg;*.jpe" );
+            importDialog->addDateiTyp( "GIF-Bild", "*.gif" );
+            importDialog->addDateiTyp( "PNG-Bild", "*.png" );
+            importDialog->addDateiTyp( "Alle Dateien", "*.*" );
+            importDialog->start();
+        }
+    }
+    if( editor->getKNum( k ) == -3 )
+    {
+        aktion = 2;
+        start();
+    }
+}
+
+void KEBeschreibung::doMausEreignis( MausEreignis &me )
+{
+    if( !run )
+        fenster->doMausEreignis( me );
+}
+
+void KEBeschreibung::doTastaturEreignis( TastaturEreignis &te )
+{
+    if( !run )
+        fenster->doTastaturEreignis( te );
+}
+
+bool KEBeschreibung::tick( double z )
+{
+    if( importDialog )
+    {
+        if( !importDialog->isRunning() )
+        {
+            if( importPfad )
+                importPfad->release();
+            importPfad = importDialog->getPfad();
+            importDialog = importDialog->release();
+            if( sichtbar && importPfad )
+            {
+                aktion = 1;
+                start();
+            }
+        }
+    }
+    if( vorschau->istSichtbar() )
+    {
+        if( vorschau->getAktion() )
+        {
+            vorschau->setSichtbar( 0 );
+            editor->setSichtbar( 1 );
+        }
+    }
+    bool ret = laden->tick( z );
+    tickVal += z * 150;
+    int val = (int)tickVal;
+    tickVal -= val;
+    if( val )
+    {
+        if( run && alpha > 100 )
+        {
+            if( alpha - val < 100 )
+                alpha = 100;
+            else
+                alpha -= val;
+            ret = 1;
+        }
+        if( sichtbar && !run && alpha != 255 )
+        {
+            if( alpha + val > 255 )
+                alpha = 255;
+            else
+                alpha += val;
+            ret = 1;
+        }
+        val *= 3;
+        if( sichtbar )
+        {
+            if( alpha < 100 )
+            {
+                if( alpha + val > 100 )
+                    alpha = 100;
+                else
+                    alpha += val;
+                ret = 1;
+            }
+            if( xStart != 0 || breite != 900 )
+            {
+                if( rechts )
+                {
+                    if( xStart - val <= 0 )
+                    {
+                        xStart = 0;
+                        breite = 900;
+                        animation = 0;
+                    }
+                    else
+                    {
+                        xStart -= val;
+                        breite += val;
+                    }
+                }
+                else
+                {
+                    if( breite + val >= 900 )
+                    {
+                        breite = 900;
+                        animation = 0;
+                    }
+                    else
+                        breite += val;
+                }
+                ret = 1;
+            }
+        }
+        else
+        {
+            if( breite != 0 )
+            {
+                if( rechts )
+                {
+                    if( breite - val <= 0 )
+                    {
+                        breite = 0;
+                        animation = 0;
+                    }
+                    else
+                        breite -= val;
+                }
+                else
+                {
+                    if( breite - val <= 0 )
+                    {
+                        breite = 0;
+                        xStart = 900;
+                        animation = 0;
+                    }
+                    else
+                    {
+                        breite -= val;
+                        xStart += val;
+                    }
+                }
+                ret = 1;
+            }
+        }
+    }
+    return ret || fenster->tick( z );
+}
+
+void KEBeschreibung::render( Bild &zRObj )
+{
+    if( !zRObj.setDrawOptions( xStart, 0, breite, 600 ) )
+        return;
+    zRObj.setAlpha( alpha );
+    fenster->render( zRObj );
+    zRObj.releaseAlpha();
+    laden->render( zRObj );
+    zRObj.releaseDrawOptions();
+}
+
+// constant
+bool KEBeschreibung::istSichtbar() const
+{
+    return sichtbar || animation;
+}
+
+// Reference Counting
+KEBeschreibung *KEBeschreibung::getThis()
+{
+    ref++;
+    return this;
+}
+
+KEBeschreibung *KEBeschreibung::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 52 - 0
KSGClient/NachLogin/Editor/Karte/Beschreibung/KEBeschreibung.h

@@ -0,0 +1,52 @@
+#pragma once
+
+#include <Fenster.h>
+#include <Thread.h>
+#include <Animation.h>
+#include <DateiDialog.h>
+#include "KEBEditor.h"
+#include "KEBVorschau.h"
+
+using namespace Framework;
+
+class KEBeschreibung : private Thread
+{
+private:
+    Fenster *fenster;
+    Animation2D *laden;
+    Schrift *schrift;
+    DateiDialogTh *importDialog;
+    Text *importPfad;
+    KEBEditor *editor;
+    KEBVorschau *vorschau;
+    int jetzt;
+    int aktion;
+    bool animation;
+    double tickVal;
+    bool sichtbar;
+    bool rechts;
+    int xStart;
+    int breite;
+    int karte;
+    unsigned char alpha;
+    int ref;
+
+public:
+    // Konstruktor
+    KEBeschreibung( int karte, Schrift *zSchrift );
+    // Destruktor
+    ~KEBeschreibung();
+    // nicht constant
+    void setSichtbar( bool s, bool vr );
+    void thread() override;
+    void knopfPress( Knopf *k, MausEreignis *me );
+    void doMausEreignis( MausEreignis &me );
+    void doTastaturEreignis( TastaturEreignis &te );
+    bool tick( double z );
+    void render( Bild &zRObj );
+    // constant
+    bool istSichtbar() const;
+    // Reference Counting
+    KEBeschreibung *getThis();
+    KEBeschreibung *release();
+};

+ 1212 - 0
KSGClient/NachLogin/Editor/Karte/Dateien/KEDEditor.cpp

@@ -0,0 +1,1212 @@
+#include "KEDEditor.h"
+#include "../../../../Global/Initialisierung.h"
+#include <MausEreignis.h>
+#include "../../../../Global/Variablen.h"
+#include <Model2D.h>
+
+// Inhalt der KEDBildSeite Klasse aus KEDEditor.h
+// Konstruktor
+KEDBildSeite::KEDBildSeite( Schrift *zSchrift, Knopf *zNeueDatei, Knopf *zDateiRemove )
+{
+    bilder = initAuswahlListe( 220, 10, 200, 510, zSchrift, AuswahlListe::Style::Normal, {} );
+    bildObj = initBildZ( 430, 10, 440, 440, BildZ::Style::normal | BildZ::Style::Alpha, 0 );
+    bildLöschen = initKnopf( 430, 460, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Bild Löschen" );
+    importieren = initKnopf( 430, 490, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Importieren" );
+    dateiLöschen = zDateiRemove->getThis();
+    neueDatei = zNeueDatei->getThis();
+    importDialog = 0;
+    importPfad = 0;
+    aktion = 0;
+    sichtbar = 0;
+    alpha = 0;
+    alpha2 = 0;
+    tickVal = 0;
+    ref = 1;
+}
+
+// Destruktor
+KEDBildSeite::~KEDBildSeite()
+{
+    bilder->release();
+    bildObj->release();
+    bildLöschen->release();
+    importieren->release();
+    dateiLöschen->release();
+    neueDatei->release();
+    if( importDialog )
+        importDialog->release();
+    if( importPfad )
+        importPfad->release();
+}
+
+// nicht constant
+int KEDBildSeite::getAktion()
+{
+    int ret = aktion;
+    aktion = 0;
+    return ret;
+}
+
+void KEDBildSeite::setBildListe( RCArray< Text > *list )
+{
+    hauptScreen->lock();
+    Text txt = bilder->zEintrag( bilder->getAuswahl() ) ? bilder->zEintrag( bilder->getAuswahl() )->zText()->getText() : "";
+    while( bilder->getEintragAnzahl() )
+        bilder->removeEintrag( 0 );
+    int anz = list->getEintragAnzahl();
+    int ausw = -1;
+    for( int i = 0; i < anz; i++ )
+    {
+        if( list->z( i )->istGleich( txt ) )
+            ausw = i;
+        bilder->addEintrag( list->get( i ) );
+    }
+    if( ausw >= 0 )
+        bilder->setAuswahl( ausw );
+    else
+        bilder->deSelect();
+    list->release();
+    hauptScreen->unlock();
+}
+
+void KEDBildSeite::setBild( Bild *b )
+{
+    hauptScreen->lock();
+    bildObj->setBild( b );
+    hauptScreen->unlock();
+}
+
+void KEDBildSeite::setSichtbar( bool s )
+{
+    sichtbar = s;
+}
+
+bool KEDBildSeite::tick( double tv )
+{
+    if( importDialog )
+    {
+        if( !importDialog->isRunning() )
+        {
+            if( importPfad )
+                importPfad->release();
+            importPfad = importDialog->getPfad();
+            importDialog = importDialog->release();
+            if( sichtbar && importPfad )
+                aktion = 3;
+        }
+    }
+    bool ret = bilder->tick( tv );
+    ret |= bildObj->tick( tv );
+    ret |= bildLöschen->tick( tv );
+    ret |= importieren->tick( tv );
+    ret |= dateiLöschen->tick( tv );
+    ret |= neueDatei->tick( tv );
+    tickVal += tv * 150;
+    int val = 0;
+    if( tickVal > 1 )
+        val = (int)tickVal;
+    else
+        return ret;
+    if( sichtbar && alpha != 255 )
+    {
+        if( alpha + val > 255 )
+            alpha = 255;
+        else
+            alpha += val;
+        ret = 1;
+    }
+    if( !sichtbar && alpha != 0 )
+    {
+        if( alpha - val < 0 )
+            alpha = 0;
+        else
+            alpha -= val;
+        ret = 1;
+    }
+    if( sichtbar && bilder->getAuswahl() >= 0 && alpha2 != 255 )
+    {
+        if( alpha2 + val > 255 )
+            alpha2 = 255;
+        else
+            alpha2 += val;
+        ret = 1;
+    }
+    if( ( !sichtbar || bilder->getAuswahl() < 0 ) && alpha2 != 0 )
+    {
+        if( alpha2 - val < 0 )
+            alpha2 = 0;
+        else
+            alpha2 -= val;
+        ret = 1;
+    }
+    return ret;
+}
+
+void KEDBildSeite::doMausEreignis( MausEreignis &me )
+{
+    if( !sichtbar )
+        return;
+    int ausw = bilder->getAuswahl();
+    bilder->doMausEreignis( me );
+    if( ausw != bilder->getAuswahl() && me.id == ME_RLinks )
+    {
+        if( bilder->getAuswahl() >= 0 )
+            aktion = 1;
+        else
+            bilder->setAuswahl( ausw );
+    }
+    bool vera = me.verarbeitet;
+    dateiLöschen->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+        aktion = 4;
+    vera = me.verarbeitet;
+    neueDatei->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+        aktion = 5;
+    vera = me.verarbeitet;
+    importieren->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+    {
+        if( !importDialog )
+        {
+            importDialog = new DateiDialogTh();
+            importDialog->setOpen( 1 );
+            importDialog->setDateiTypAuswahl( 4 );
+            importDialog->addDateiTyp( "JPEG-Bild", "*.jpg;*.jpeg;*.jpe" );
+            importDialog->addDateiTyp( "GIF-Bild", "*.gif" );
+            importDialog->addDateiTyp( "PNG-Bild", "*.png" );
+            importDialog->addDateiTyp( "Alle Dateien", "*.*" );
+            importDialog->start();
+        }
+    }
+    if( bilder->getAuswahl() < 0 )
+        return;
+    bildObj->doMausEreignis( me );
+    vera = me.verarbeitet;
+    bildLöschen->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+        aktion = 2;
+}
+
+void KEDBildSeite::render( Bild &zRObj )
+{
+    if( !alpha )
+        return;
+    zRObj.setAlpha( alpha );
+    bilder->render( zRObj );
+    neueDatei->setPosition( 540, 490 );
+    neueDatei->render( zRObj );
+    dateiLöschen->setPosition( 540, 460 );
+    dateiLöschen->render( zRObj );
+    importieren->render( zRObj );
+    zRObj.setAlpha( alpha2 );
+    bildObj->render( zRObj );
+    bildLöschen->render( zRObj );
+    zRObj.releaseAlpha();
+    zRObj.releaseAlpha();
+}
+
+// constant
+Text *KEDBildSeite::zBildImportPfad() const
+{
+    return importPfad;
+}
+
+Text *KEDBildSeite::zBildAuswahl() const
+{
+    if( !bilder->zEintrag( bilder->getAuswahl() ) )
+        return 0;
+    return bilder->zEintrag( bilder->getAuswahl() )->zText();
+}
+
+// Reference Counting
+KEDBildSeite *KEDBildSeite::getThis()
+{
+    ref++;
+    return this;
+}
+
+KEDBildSeite *KEDBildSeite::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+
+bool kEDEditorNeuModelOkME( void *p, void *obj, MausEreignis me )
+{
+    if( p )
+        return ( (KEDModellSeite*)p )->neuModelOkME( me );
+    else if( me.id == ME_RLinks )
+        ( (Fenster*)obj )->removeStyle( Fenster::Style::Sichtbar );
+    return 1;
+}
+
+
+// Inhalt der KEDModellSeite Klasse aus KEDEditor.h
+// Konstruktor
+KEDModellSeite::KEDModellSeite( Schrift *zSchrift, Knopf *zNeueDatei, Knopf *zDateiRemove, AuswahlListe *datL )
+{
+    dateien = datL;
+    modelle = initAuswahlListe( 220, 10, 200, 510, zSchrift, AuswahlListe::Style::Normal, {} );
+    modelObj = new M2DVorschau();
+    modelObj->setPosition( 430, 10 );
+    modelObj->setSize( 440, 440 );
+    modelObj->setStyle( M2DVorschau::Style::Rahmen | M2DVorschau::Style::Erlaubt | M2DVorschau::Style::Sichtbar | M2DVorschau::Style::UsrMove | M2DVorschau::Style::UsrRot | M2DVorschau::Style::UsrScale );
+    modelObj->setLinienRahmenFarbe( 0xFFFFFFFF );
+    modelObj->setMausEreignis( _ret1ME );
+    modelObj->setModel2DZ( new Model2D() );
+    modelObj->zModel()->setStyle( Model2D::Style::Erlaubt | Model2D::Style::Mesh | Model2D::Style::Sichtbar );
+    modelObj->zModel()->setFarbe( 0xFFFFFFFF );
+    modelLöschen = initKnopf( 430, 460, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Modell2D Löschen" );
+    neuesModel = initKnopf( 430, 490, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Neues Modell2D" );
+    bearbeiten = initKnopf( 550, 490, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Bearbeiten" );
+    dateiLöschen = zDateiRemove->getThis();
+    neueDatei = zNeueDatei->getThis();
+    editor = new Model2DEditor::GUI( zSchrift );
+    neuModelF = initFenster( 365, 160, 150, 90, zSchrift, Fenster::Style::Erlaubt | Fenster::Style::BodyHintergrund | Fenster::Style::BodyHAlpha |
+                                                                          Fenster::Style::Rahmen | Fenster::Style::Closable | Fenster::Style::ClosingKlickBuffer | Fenster::Style::ClosingHintergrund |
+                                                                          Fenster::Style::ClosingHAlpha | Fenster::Style::Titel | Fenster::Style::TitelHintergrund | Fenster::Style::TitelHAlpha | Fenster::Style::TitelBuffered, "Neues Modell" );
+    neuModelF->setKBgFarbe( 0xC0000000 );
+    neuModelF->setSBgFarbe( 0xC0000000 );
+    neuModelF->setTBgFarbe( 0xC0000000 );
+    neuModelF->setClosingMe( kEDEditorNeuModelOkME );
+    neuModelName = initTextFeld( 10, 10, 130, 20, zSchrift, TextFeld::Style::TextFeld, "Name" );
+    neuModelOk = initKnopf( 25, 40, 100, 20, zSchrift, Knopf::Style::Normal | Knopf::Style::Sichtbar, "Erstellen" );
+    neuModelOk->setMausEreignisParameter( this );
+    neuModelOk->setMausEreignis( kEDEditorNeuModelOkME );
+    neuModelF->addMember( neuModelName );
+    neuModelF->addMember( neuModelOk );
+    aktion = 0;
+    sichtbar = 0;
+    alpha = 0;
+    alpha2 = 0;
+    alpha3 = 0;
+    tickVal = 0;
+    ref = 1;
+}
+
+// Destruktor
+KEDModellSeite::~KEDModellSeite()
+{
+    dateien->release();
+    modelle->release();
+    modelObj->release();
+    modelLöschen->release();
+    neuesModel->release();
+    dateiLöschen->release();
+    neueDatei->release();
+    bearbeiten->release();
+    editor->release();
+    neuModelF->release();
+    neuModelName->release();
+    neuModelOk->release();
+}
+
+// nicht constant
+int KEDModellSeite::getAktion()
+{
+    int ret = aktion;
+    aktion = 0;
+    return ret;
+}
+
+bool KEDModellSeite::neuModelOkME( MausEreignis &me )
+{
+    if( me.id == ME_RLinks )
+    {
+        neuModelF->removeStyle( Fenster::Style::Sichtbar );
+        aktion = 4;
+    }
+    return 1;
+}
+
+void KEDModellSeite::setModelListe( RCArray< Text > *list )
+{
+    hauptScreen->lock();
+    Text txt = modelle->zEintrag( modelle->getAuswahl() ) ? modelle->zEintrag( modelle->getAuswahl() )->zText()->getText() : "";
+    while( modelle->getEintragAnzahl() )
+        modelle->removeEintrag( 0 );
+    int anz = list->getEintragAnzahl();
+    int ausw = -1;
+    for( int i = 0; i < anz; i++ )
+    {
+        if( list->z( i )->istGleich( txt ) )
+            ausw = i;
+        modelle->addEintrag( list->get( i ) );
+    }
+    if( ausw >= 0 )
+        modelle->setAuswahl( ausw );
+    else
+        modelle->deSelect();
+    list->release();
+    hauptScreen->unlock();
+}
+
+void KEDModellSeite::setModel( Model2DData *mdl )
+{
+    modelObj->setModel2D( mdl->getThis() );
+    editor->setModel( mdl );
+}
+
+void KEDModellSeite::setSichtbar( bool s )
+{
+    sichtbar = s;
+}
+
+bool KEDModellSeite::tick( double tv )
+{
+    bool ret = modelle->tick( tv );
+    ret |= modelObj->tick( tv );
+    ret |= modelLöschen->tick( tv );
+    ret |= neuesModel->tick( tv );
+    ret |= dateiLöschen->tick( tv );
+    ret |= neueDatei->tick( tv );
+    ret |= bearbeiten->tick( tv );
+    ret |= editor->tick( tv );
+    ret |= neuModelF->tick( tv );
+    int a = editor->getAktion();
+    if( a == 1 || a == 2 )
+    {
+        editor->setSichtbar( 0 );
+        modelObj->addStyle( Model2D::Style::Sichtbar );
+        modelle->addStyle( Model2D::Style::Sichtbar );
+        dateien->addStyle( AuswahlListe::Style::Sichtbar );
+        dateiLöschen->addStyle( Knopf::Style::Sichtbar );
+        neueDatei->addStyle( Knopf::Style::Sichtbar );
+        neuesModel->addStyle( Knopf::Style::Sichtbar );
+        modelLöschen->addStyle( Knopf::Style::Sichtbar );
+        bearbeiten->addStyle( Knopf::Style::Sichtbar );
+    }
+    if( a == 1 )
+        aktion = 3;
+    tickVal += tv * 150;
+    int val = 0;
+    if( tickVal > 1 )
+        val = (int)tickVal;
+    else
+        return ret;
+    if( sichtbar && alpha != 255 )
+    {
+        if( alpha + val > 255 )
+            alpha = 255;
+        else
+            alpha += val;
+        ret = 1;
+    }
+    if( !sichtbar && alpha != 0 )
+    {
+        if( alpha - val < 0 )
+            alpha = 0;
+        else
+            alpha -= val;
+        ret = 1;
+    }
+    if( sichtbar && modelle->getAuswahl() >= 0 && alpha2 != 255 )
+    {
+        if( alpha2 + val > 255 )
+            alpha2 = 255;
+        else
+            alpha2 += val;
+        ret = 1;
+    }
+    if( ( !sichtbar || modelle->getAuswahl() < 0 ) && alpha2 != 0 )
+    {
+        if( alpha2 - val < 0 )
+            alpha2 = 0;
+        else
+            alpha2 -= val;
+        ret = 1;
+    }
+    if( sichtbar && neuModelF->hatStyle( Fenster::Style::Sichtbar ) && alpha3 > 100 )
+    {
+        if( alpha3 - val < 100 )
+            alpha3 = 100;
+        else
+            alpha3 -= val;
+        ret = 1;
+    }
+    if( sichtbar && neuModelF->hatStyleNicht( Fenster::Style::Sichtbar ) && alpha3 < 255 )
+    {
+        if( alpha3 + val > 255 )
+            alpha3 = 255;
+        else
+            alpha3 += val;
+        ret = 1;
+    }
+    return ret;
+}
+
+void KEDModellSeite::doMausEreignis( MausEreignis &me )
+{
+    if( !sichtbar )
+        return;
+    if( neuModelF->hatStyle( Fenster::Style::Sichtbar ) )
+    {
+        neuModelF->doMausEreignis( me );
+        return;
+    }
+    int ausw = modelle->getAuswahl();
+    modelle->doMausEreignis( me );
+    if( ausw != modelle->getAuswahl() && me.id == ME_RLinks )
+    {
+        if( modelle->getAuswahl() >= 0 )
+            aktion = 1;
+        else
+            modelle->setAuswahl( ausw );
+    }
+    bool vera = me.verarbeitet;
+    dateiLöschen->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+        aktion = 5;
+    vera = me.verarbeitet;
+    neueDatei->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+        aktion = 6;
+    vera = me.verarbeitet;
+    neuesModel->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+        neuModelF->addStyle( Fenster::Style::Sichtbar );
+    vera = me.verarbeitet;
+    if( modelle->getAuswahl() < 0 )
+        return;
+    bearbeiten->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+    {
+        editor->setSichtbar( 1 );
+        modelObj->removeStyle( Model2D::Style::Sichtbar );
+        modelle->removeStyle( Model2D::Style::Sichtbar );
+        dateien->removeStyle( AuswahlListe::Style::Sichtbar );
+        dateiLöschen->removeStyle( Knopf::Style::Sichtbar );
+        neueDatei->removeStyle( Knopf::Style::Sichtbar );
+        neuesModel->removeStyle( Knopf::Style::Sichtbar );
+        bearbeiten->removeStyle( Knopf::Style::Sichtbar );
+        modelLöschen->removeStyle( Knopf::Style::Sichtbar );
+    }
+    modelObj->doMausEreignis( me );
+    editor->doMausEreignis( me );
+    vera = me.verarbeitet;
+    modelLöschen->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+        aktion = 2;
+}
+
+void KEDModellSeite::doTastaturEreignis( TastaturEreignis &te )
+{
+    if( neuModelF->hatStyle( Fenster::Style::Sichtbar ) )
+    {
+        neuModelF->doTastaturEreignis( te );
+        return;
+    }
+    editor->doTastaturEreignis( te );
+}
+
+void KEDModellSeite::render( Bild &zRObj )
+{
+    if( !alpha )
+        return;
+    zRObj.setAlpha( alpha );
+    zRObj.setAlpha( alpha3 );
+    modelle->render( zRObj );
+    neuesModel->render( zRObj );
+    neueDatei->setPosition( 670, 490 );
+    neueDatei->render( zRObj );
+    dateiLöschen->setPosition( 670, 460 );
+    dateiLöschen->render( zRObj );
+    if( modelle->getAuswahl() >= 0 )
+    {
+        bearbeiten->render( zRObj );
+        modelLöschen->render( zRObj );
+        zRObj.setAlpha( alpha2 );
+        modelObj->render( zRObj );
+        editor->render( zRObj );
+        zRObj.releaseAlpha();
+    }
+    zRObj.releaseAlpha();
+    neuModelF->render( zRObj );
+    zRObj.releaseAlpha();
+}
+
+// constant
+Text *KEDModellSeite::zModelAuswahl() const
+{
+    if( !modelle->zEintrag( modelle->getAuswahl() ) )
+        return 0;
+    return modelle->zEintrag( modelle->getAuswahl() )->zText();
+}
+
+Text *KEDModellSeite::zNeuModelName() const
+{
+    return neuModelName->zText();
+}
+
+Model2DData *KEDModellSeite::getModelData() const
+{
+    return editor->getM2Data();
+}
+
+// Reference Counting
+KEDModellSeite *KEDModellSeite::getThis()
+{
+    ref++;
+    return this;
+}
+
+KEDModellSeite *KEDModellSeite::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+
+// Inhalt der KEDSoundSeite Klasse aus KEDEditor.h
+// Konstruktor
+KEDSoundSeite::KEDSoundSeite( Schrift *zSchrift, Knopf *zNeueDatei, Knopf *zDateiRemove )
+{
+    dllDateien->ladeDLL( "GSL.dll", "data/bin/GSL.dll" );
+    sounds = initAuswahlListe( 220, 10, 200, 510, zSchrift, AuswahlListe::Style::Normal, {} );
+    play = initKnopf( 430, 430, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Play" );
+    soundLöschen = initKnopf( 430, 460, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Bild Löschen" );
+    importieren = initKnopf( 430, 490, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Importieren" );
+    dateiLöschen = zDateiRemove->getThis();
+    neueDatei = zNeueDatei->getThis();
+    importDialog = 0;
+    importPfad = 0;
+    aktion = 0;
+    sichtbar = 0;
+    alpha = 0;
+    alpha2 = 0;
+    tickVal = 0;
+    sound = 0;
+    ref = 1;
+}
+
+// Destruktor
+KEDSoundSeite::~KEDSoundSeite()
+{
+    if( sound )
+    {
+        sound->stopSound();
+        sound->release();
+    }
+    dllDateien->releaseDLL( "GSL.dll" );
+    sounds->release();
+    play->release();
+    soundLöschen->release();
+    importieren->release();
+    dateiLöschen->release();
+    neueDatei->release();
+    if( importDialog )
+        importDialog->release();
+    if( importPfad )
+        importPfad->release();
+}
+
+// nicht constant
+int KEDSoundSeite::getAktion()
+{
+    int ret = aktion;
+    aktion = 0;
+    return ret;
+}
+
+void KEDSoundSeite::setSoundListe( RCArray< Text > *list )
+{
+    hauptScreen->lock();
+    Text txt = sounds->zEintrag( sounds->getAuswahl() ) ? sounds->zEintrag( sounds->getAuswahl() )->zText()->getText() : "";
+    while( sounds->getEintragAnzahl() )
+        sounds->removeEintrag( 0 );
+    int anz = list->getEintragAnzahl();
+    int ausw = -1;
+    for( int i = 0; i < anz; i++ )
+    {
+        if( list->z( i )->istGleich( txt ) )
+            ausw = i;
+        sounds->addEintrag( list->get( i ) );
+    }
+    if( ausw >= 0 )
+        sounds->setAuswahl( ausw );
+    else
+        sounds->deSelect();
+    list->release();
+    hauptScreen->unlock();
+}
+
+void KEDSoundSeite::setSound( GSL::GSLSoundV *b )
+{
+    if( sound )
+    {
+        sound->stopSound();
+        sound->release();
+    }
+    sound = b;
+    sound->playSound();
+}
+
+void KEDSoundSeite::setSichtbar( bool s )
+{
+    sichtbar = s;
+}
+
+bool KEDSoundSeite::tick( double tv )
+{
+    if( importDialog )
+    {
+        if( !importDialog->isRunning() )
+        {
+            if( importPfad )
+                importPfad->release();
+            importPfad = importDialog->getPfad();
+            importDialog = importDialog->release();
+            if( sichtbar && importPfad )
+                aktion = 3;
+        }
+    }
+    bool ret = sounds->tick( tv );
+    ret |= play->tick( tv );
+    ret |= soundLöschen->tick( tv );
+    ret |= importieren->tick( tv );
+    ret |= dateiLöschen->tick( tv );
+    ret |= neueDatei->tick( tv );
+    tickVal += tv * 150;
+    int val = 0;
+    if( tickVal > 1 )
+        val = (int)tickVal;
+    else
+        return ret;
+    if( sichtbar && alpha != 255 )
+    {
+        if( alpha + val > 255 )
+            alpha = 255;
+        else
+            alpha += val;
+        ret = 1;
+    }
+    if( !sichtbar && alpha != 0 )
+    {
+        if( alpha - val < 0 )
+            alpha = 0;
+        else
+            alpha -= val;
+        ret = 1;
+    }
+    if( sichtbar && sounds->getAuswahl() >= 0 && alpha2 != 255 )
+    {
+        if( alpha2 + val > 255 )
+            alpha2 = 255;
+        else
+            alpha2 += val;
+        ret = 1;
+    }
+    if( ( !sichtbar || sounds->getAuswahl() < 0 ) && alpha2 != 0 )
+    {
+        if( alpha2 - val < 0 )
+            alpha2 = 0;
+        else
+            alpha2 -= val;
+        ret = 1;
+    }
+    return ret;
+}
+
+void KEDSoundSeite::doMausEreignis( MausEreignis &me )
+{
+    if( !sichtbar )
+        return;
+    int ausw = sounds->getAuswahl();
+    sounds->doMausEreignis( me );
+    if( ausw != sounds->getAuswahl() && me.id == ME_RLinks )
+    {
+        if( sounds->getAuswahl() >= 0 )
+        {
+            if( sound )
+                sound->stopSound();
+        }
+        else
+            sounds->setAuswahl( ausw );
+    }
+    bool vera = me.verarbeitet;
+    dateiLöschen->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+        aktion = 4;
+    vera = me.verarbeitet;
+    neueDatei->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+        aktion = 5;
+    vera = me.verarbeitet;
+    importieren->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+    {
+        if( !importDialog )
+        {
+            importDialog = new DateiDialogTh();
+            importDialog->setOpen( 1 );
+            importDialog->setDateiTypAuswahl( 4 );
+            importDialog->addDateiTyp( "WAV-Sound", "*.wav" );
+            importDialog->addDateiTyp( "Alle Dateien", "*.*" );
+            importDialog->start();
+        }
+    }
+    if( sounds->getAuswahl() < 0 )
+        return;
+    vera = me.verarbeitet;
+    play->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+    {
+        if( sound )
+            sound->stopSound();
+        aktion = 1;
+    }
+    vera = me.verarbeitet;
+    soundLöschen->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+        aktion = 2;
+}
+
+void KEDSoundSeite::render( Bild &zRObj )
+{
+    if( !alpha )
+        return;
+    zRObj.setAlpha( alpha );
+    sounds->render( zRObj );
+    neueDatei->setPosition( 540, 490 );
+    neueDatei->render( zRObj );
+    dateiLöschen->setPosition( 540, 460 );
+    dateiLöschen->render( zRObj );
+    importieren->render( zRObj );
+    zRObj.setAlpha( alpha2 );
+    play->render( zRObj );
+    soundLöschen->render( zRObj );
+    zRObj.releaseAlpha();
+    zRObj.releaseAlpha();
+}
+
+// constant
+Text *KEDSoundSeite::zSoundImportPfad() const
+{
+    return importPfad;
+}
+
+Text *KEDSoundSeite::zSoundAuswahl() const
+{
+    if( !sounds->zEintrag( sounds->getAuswahl() ) )
+        return 0;
+    return sounds->zEintrag( sounds->getAuswahl() )->zText();
+}
+
+// Reference Counting
+KEDSoundSeite *KEDSoundSeite::getThis()
+{
+    ref++;
+    return this;
+}
+
+KEDSoundSeite *KEDSoundSeite::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+
+bool kEDEditorNeuDateiOkME( void *p, void *obj, MausEreignis me )
+{
+    if( p )
+        return ( (KEDEditor*)p )->neuDateiOkME( me );
+    else if( me.id == ME_RLinks )
+        ( (Fenster*)obj )->removeStyle( Fenster::Style::Sichtbar );
+    return 1;
+}
+
+
+// Inhalt der KEDEditor Klasse aus KEDEditor.h
+// Konstruktor
+KEDEditor::KEDEditor( Schrift *zSchrift )
+{
+    neueDatei = initKnopf( 0, 0, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Neue Datei" );
+    dateiLöschen = initKnopf( 0, 0, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Datei Löschen" );
+    dateien = initAuswahlListe( 10, 10, 200, 510, zSchrift, AuswahlListe::Style::Normal, {} );
+    bildSeite = new KEDBildSeite( zSchrift, neueDatei, dateiLöschen );
+    modelSeite = new KEDModellSeite( zSchrift, neueDatei, dateiLöschen, dateien->getThis() );
+    soundSeite = new KEDSoundSeite( zSchrift, neueDatei, dateiLöschen );
+    neuDateiF = initFenster( 365, 145, 150, 120, zSchrift, Fenster::Style::Erlaubt | Fenster::Style::BodyHintergrund | Fenster::Style::BodyHAlpha |
+                             Fenster::Style::Rahmen | Fenster::Style::Closable | Fenster::Style::ClosingKlickBuffer | Fenster::Style::ClosingHintergrund |
+                             Fenster::Style::ClosingHAlpha | Fenster::Style::Titel | Fenster::Style::TitelHintergrund | Fenster::Style::TitelHAlpha | Fenster::Style::TitelBuffered, "Neue Datei" );
+    neuDateiF->setKBgFarbe( 0xC0000000 );
+    neuDateiF->setSBgFarbe( 0xC0000000 );
+    neuDateiF->setTBgFarbe( 0xC0000000 );
+    neuDateiF->setClosingMe( kEDEditorNeuDateiOkME );
+    neuDateiTyp = initAuswahlBox( 10, 10, 130, 20, zSchrift, ABSTYLE, { "Ordner", "Bild (.ltdb)", "Modell 2D (.m2)", "Sound (.gsl)" } );
+    neuDateiName = initTextFeld( 10, 40, 130, 20, zSchrift, TextFeld::Style::TextFeld, "Datei Name" );
+    neuDateiOk = initKnopf( 25, 70, 100, 20, zSchrift, Knopf::Style::Normal | Knopf::Style::Sichtbar, "Erstellen" );
+    neuDateiOk->setMausEreignisParameter( this );
+    neuDateiOk->setMausEreignis( kEDEditorNeuDateiOkME );
+    neuDateiF->addMember( neuDateiName );
+    neuDateiF->addMember( neuDateiOk );
+    neuDateiF->addMember( neuDateiTyp );
+    aktion = 0;
+    sichtbar = 0;
+    alpha = 0;
+    alpha2 = 0;
+    tickVal = 0;
+    ref = 1;
+}
+
+// Destruktor
+KEDEditor::~KEDEditor()
+{
+    dateien->release();
+    bildSeite->release();
+    modelSeite->release();
+    soundSeite->release();
+    neuDateiF->release();
+    neuDateiTyp->release();
+    neuDateiName->release();
+    neuDateiOk->release();
+    neueDatei->release();
+    dateiLöschen->release();
+}
+
+// nicht constant
+int KEDEditor::getAktion()
+{
+    int ret = aktion;
+    aktion = 0;
+    return ret;
+}
+
+bool KEDEditor::neuDateiOkME( MausEreignis &me )
+{
+    if( me.id == ME_RLinks )
+    {
+        neuDateiF->removeStyle( Fenster::Style::Sichtbar );
+        aktion = 1;
+    }
+    return 1;
+}
+
+void KEDEditor::setDateiListe( RCArray< Text > *list )
+{
+    hauptScreen->lock();
+    dateien->deSelect();
+    while( dateien->getEintragAnzahl() )
+        dateien->removeEintrag( 0 );
+    int anz = list->getEintragAnzahl();
+    for( int i = 0; i < anz; i++ )
+        dateien->addEintrag( list->get( i ) );
+    bildSeite->setSichtbar( 0 );
+    soundSeite->setSichtbar( 0 );
+    modelSeite->setSichtbar( 0 );
+    neuDateiF->removeStyle( Fenster::Style::Sichtbar );
+    list->release();
+    hauptScreen->unlock();
+}
+
+void KEDEditor::setBildListe( RCArray< Text > *list )
+{
+    soundSeite->setSichtbar( 0 );
+    modelSeite->setSichtbar( 0 );
+    bildSeite->setBildListe( list );
+    bildSeite->setSichtbar( 1 );
+}
+
+void KEDEditor::setSoundListe( RCArray< Text > *list )
+{
+    modelSeite->setSichtbar( 0 );
+    bildSeite->setSichtbar( 0 );
+    soundSeite->setSoundListe( list );
+    soundSeite->setSichtbar( 1 );
+}
+
+void KEDEditor::setModel2dListe( RCArray< Text > *list )
+{
+    bildSeite->setSichtbar( 0 );
+    soundSeite->setSichtbar( 0 );
+    modelSeite->setModelListe( list );
+    modelSeite->setSichtbar( 1 );
+}
+
+void KEDEditor::setBild( Bild *b )
+{
+    bildSeite->setBild( b );
+}
+
+void KEDEditor::setSound( GSL::GSLSoundV *s )
+{
+    soundSeite->setSound( s );
+}
+
+void KEDEditor::setModel2d( Model2DData *d )
+{
+    modelSeite->setModel( d );
+}
+
+void KEDEditor::setSichtbar( bool s )
+{
+    sichtbar = s;
+}
+
+bool KEDEditor::tick( double tv )
+{
+    int ak = bildSeite->getAktion();
+    switch( ak )
+    {
+    case 1: // Bild Auswählen
+        aktion = 4;
+        break;
+    case 2: // Bild Löschen
+        aktion = 5;
+        break;
+    case 3: // Importieren
+        aktion = 6;
+        break;
+    case 4: // Datei Löschen
+        aktion = 3;
+        break;
+    case 5: // Neue Datei
+        neuDateiF->addStyle( Fenster::Style::Sichtbar );
+        break;
+    }
+    ak = modelSeite->getAktion();
+    switch( ak )
+    {
+    case 1: // Model Auswählen
+        aktion = 7;
+        break;
+    case 2: // Model Löschen
+        aktion = 8;
+        break;
+    case 3: // Model speichern
+        aktion = 9;
+        break;
+    case 4: // Neues Modell
+        aktion = 10;
+        break;
+    case 5: // Datei Löschen
+        aktion = 3;
+        break;
+    case 6: // Neue Datei
+        neuDateiF->addStyle( Fenster::Style::Sichtbar );
+        break;
+    }
+    ak = soundSeite->getAktion();
+    switch( ak )
+    {
+    case 1: // Sound Abspielen
+        aktion = 11;
+        break;
+    case 2: // Sound Löschen
+        aktion = 12;
+        break;
+    case 3: // Importieren
+        aktion = 13;
+        break;
+    case 4: // Datei Löschen
+        aktion = 3;
+        break;
+    case 5: // Neue Datei
+        neuDateiF->addStyle( Fenster::Style::Sichtbar );
+        break;
+    }
+    bool ret = dateien->tick( tv );
+    ret |= bildSeite->tick( tv );
+    ret |= soundSeite->tick( tv );
+    ret |= modelSeite->tick( tv );
+    ret |= neuDateiF->tick( tv );
+    if( dateien->getAuswahl() < 0 )
+    {
+        ret |= neueDatei->tick( tv );
+        if( dateien->getEintragAnzahl() > 0 && dateien->zEintrag( 0 )->zText()->istGleich( ".." ) )
+            ret |= dateiLöschen->tick( tv );
+    }
+    tickVal += tv * 150;
+    int val = 0;
+    if( tickVal > 1 )
+    {
+        val = (int)tickVal;
+        tickVal -= val;
+    }
+    else
+        return ret;
+    if( sichtbar && neuDateiF->hatStyle( Fenster::Style::Sichtbar ) && alpha2 > 100 )
+    {
+        if( alpha2 - val < 100 )
+            alpha2 = 100;
+        else
+            alpha2 -= val;
+        ret = 1;
+    }
+    if( sichtbar && neuDateiF->hatStyleNicht( Fenster::Style::Sichtbar ) && alpha2 < 255 )
+    {
+        if( alpha2 + val > 255 )
+            alpha2 = 255;
+        else
+            alpha2 += val;
+        ret = 1;
+    }
+    if( sichtbar && alpha != 255 )
+    {
+        if( alpha + val > 255 )
+            alpha = 255;
+        else
+            alpha += val;
+        ret = 1;
+    }
+    if( !sichtbar && alpha != 0 )
+    {
+        if( alpha - val < 0 )
+            alpha = 0;
+        else
+            alpha -= val;
+        ret = 1;
+    }
+    return ret;
+}
+
+void KEDEditor::doMausEreignis( MausEreignis &me )
+{
+    if( !sichtbar )
+        return;
+    if( neuDateiF->hatStyle( Fenster::Style::Sichtbar ) )
+    {
+        neuDateiF->doMausEreignis( me );
+        return;
+    }
+    int ausw = dateien->getAuswahl();
+    dateien->doMausEreignis( me );
+    if( ausw != dateien->getAuswahl() && me.id == ME_RLinks )
+    {
+        if( dateien->getAuswahl() >= 0 )
+            aktion = 2;
+        else
+            dateien->setAuswahl( ausw );
+    }
+    bildSeite->doMausEreignis( me );
+    soundSeite->doMausEreignis( me );
+    modelSeite->doMausEreignis( me );
+    if( dateien->getAuswahl() < 0 )
+    {
+        bool vera = me.verarbeitet;
+        neueDatei->doMausEreignis( me );
+        if( !vera && me.verarbeitet && me.id == ME_RLinks )
+            neuDateiF->addStyle( Fenster::Style::Sichtbar );
+        if( dateien->getEintragAnzahl() > 0 && dateien->zEintrag( 0 )->zText()->istGleich( ".." ) )
+        {
+            vera = me.verarbeitet;
+            dateiLöschen->doMausEreignis( me );
+            if( !vera && me.verarbeitet && me.id == ME_RLinks )
+                aktion = 3;
+        }
+    }
+}
+
+void KEDEditor::doTastaturEreignis( TastaturEreignis &te )
+{
+    if( neuDateiF->hatStyle( Fenster::Style::Sichtbar ) )
+    {
+        neuDateiF->doTastaturEreignis( te );
+        return;
+    }
+    modelSeite->doTastaturEreignis( te );
+}
+
+void KEDEditor::render( Bild &zRObj )
+{
+    zRObj.setAlpha( alpha );
+    zRObj.setAlpha( alpha2 );
+    dateien->render( zRObj );
+    bildSeite->render( zRObj );
+    modelSeite->render( zRObj );
+    soundSeite->render( zRObj );
+    if( dateien->getAuswahl() < 0 )
+    {
+        neueDatei->setPosition( 770, 440 );
+        neueDatei->render( zRObj );
+        if( dateien->getEintragAnzahl() > 0 && dateien->zEintrag( 0 )->zText()->istGleich( ".." ) )
+        {
+            dateiLöschen->setPosition( 770, 410 );
+            dateiLöschen->render( zRObj );
+        }
+    }
+    zRObj.releaseAlpha();
+    neuDateiF->render( zRObj );
+    zRObj.releaseAlpha();
+}
+
+// constant
+Text *KEDEditor::zBildImportPfad() const
+{
+    return bildSeite->zBildImportPfad();
+}
+
+Text *KEDEditor::zSoundImportPfad() const
+{
+    return soundSeite->zSoundImportPfad();
+}
+
+Text *KEDEditor::zDateiAuswahl() const
+{
+    if( !dateien->zEintrag( dateien->getAuswahl() ) )
+        return 0;
+    return dateien->zEintrag( dateien->getAuswahl() )->zText();
+}
+
+Text *KEDEditor::zSoundAuswahl() const
+{
+    return soundSeite->zSoundAuswahl();
+}
+
+Text *KEDEditor::zModel2dAuswahl() const
+{
+    return modelSeite->zModelAuswahl();
+}
+
+Model2DData *KEDEditor::getModelData() const
+{
+    return modelSeite->getModelData();
+}
+
+Text *KEDEditor::zNeuModelName() const
+{
+    return modelSeite->zNeuModelName();
+}
+
+Text *KEDEditor::zBildAuswahl() const
+{
+    return bildSeite->zBildAuswahl();
+}
+
+int KEDEditor::getNeuDateiTyp() const
+{
+    return neuDateiTyp->getAuswahl();
+}
+
+Text *KEDEditor::zNeuDateiName() const
+{
+    return neuDateiName->zText();
+}
+
+bool KEDEditor::istSichtbar() const
+{
+    return sichtbar;
+}
+
+// Reference Counting
+KEDEditor *KEDEditor::getThis()
+{
+    ref++;
+    return this;
+}
+
+KEDEditor *KEDEditor::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 196 - 0
KSGClient/NachLogin/Editor/Karte/Dateien/KEDEditor.h

@@ -0,0 +1,196 @@
+#pragma once
+
+#include <Liste.h>
+#include <Bild.h>
+#include <Knopf.h>
+#include <DateiDialog.h>
+#include <Fenster.h>
+#include <AuswahlBox.h>
+#include <M2DVorschau.h>
+#include "KEDModel2DEditor.h"
+#include <GSLSoundV.h>
+
+using namespace Framework;
+
+class KEDBildSeite
+{
+private:
+    AuswahlListe *bilder;
+    BildZ *bildObj;
+    Knopf *bildLöschen;
+    Knopf *importieren;
+    Knopf *dateiLöschen;
+    Knopf *neueDatei;
+    DateiDialogTh *importDialog;
+    Text *importPfad;
+    int aktion;
+    bool sichtbar;
+    unsigned char alpha;
+    unsigned char alpha2;
+    double tickVal;
+    int ref;
+
+public:
+    // Konstruktor
+    KEDBildSeite( Schrift *zSchrift, Knopf *zNeueDatei, Knopf *zDateiRemove );
+    // Destruktor
+    ~KEDBildSeite();
+    // nicht constant
+    int getAktion();
+    void setBildListe( RCArray< Text > *list );
+    void setBild( Bild *b );
+    void setSichtbar( bool s );
+    bool tick( double tv );
+    void doMausEreignis( MausEreignis &me );
+    void render( Bild &zRObj );
+    // constant
+    Text *zBildImportPfad() const;
+    Text *zBildAuswahl() const;
+    // Reference Counting
+    KEDBildSeite *getThis();
+    KEDBildSeite *release();
+};
+
+class KEDModellSeite
+{
+private:
+    AuswahlListe *modelle;
+    M2DVorschau *modelObj;
+    Knopf *modelLöschen;
+    Knopf *neuesModel;
+    Knopf *dateiLöschen;
+    Knopf *neueDatei;
+    Knopf *bearbeiten;
+    Model2DEditor::GUI *editor;
+    Fenster *neuModelF;
+    TextFeld *neuModelName;
+    Knopf *neuModelOk;
+    AuswahlListe *dateien;
+    int aktion;
+    bool sichtbar;
+    unsigned char alpha;
+    unsigned char alpha2;
+    unsigned char alpha3;
+    double tickVal;
+    int ref;
+
+public:
+    // Konstruktor
+    KEDModellSeite( Schrift *zSchrift, Knopf *zNeueDatei, Knopf *zDateiRemove, AuswahlListe *dateien );
+    // Destruktor
+    ~KEDModellSeite();
+    // nicht constant
+    int getAktion();
+    bool neuModelOkME( MausEreignis &me );
+    void setModelListe( RCArray< Text > *list );
+    void setModel( Model2DData *mdl );
+    void setSichtbar( bool s );
+    bool tick( double tv );
+    void doMausEreignis( MausEreignis &me );
+    void doTastaturEreignis( TastaturEreignis &me );
+    void render( Bild &zRObj );
+    // constant
+    Text *zModelAuswahl() const;
+    Text *zNeuModelName() const;
+    Model2DData *getModelData() const;
+    // Reference Counting
+    KEDModellSeite *getThis();
+    KEDModellSeite *release();
+};
+
+class KEDSoundSeite
+{
+private:
+    AuswahlListe *sounds;
+    GSL::GSLSoundV *sound;
+    Knopf *soundLöschen;
+    Knopf *importieren;
+    Knopf *dateiLöschen;
+    Knopf *neueDatei;
+    Knopf *play;
+    DateiDialogTh *importDialog;
+    Text *importPfad;
+    int aktion;
+    bool sichtbar;
+    unsigned char alpha;
+    unsigned char alpha2;
+    double tickVal;
+    int ref;
+
+public:
+    // Konstruktor
+    KEDSoundSeite( Schrift *zSchrift, Knopf *zNeueDatei, Knopf *zDateiRemove );
+    // Destruktor
+    ~KEDSoundSeite();
+    // nicht constant
+    int getAktion();
+    void setSoundListe( RCArray< Text > *list );
+    void setSound( GSL::GSLSoundV *b );
+    void setSichtbar( bool s );
+    bool tick( double tv );
+    void doMausEreignis( MausEreignis &me );
+    void render( Bild &zRObj );
+    // constant
+    Text *zSoundImportPfad() const;
+    Text *zSoundAuswahl() const;
+    // Reference Counting
+    KEDSoundSeite *getThis();
+    KEDSoundSeite *release();
+};
+
+class KEDEditor : public Zeichnung
+{
+private:
+    AuswahlListe *dateien;
+    KEDBildSeite *bildSeite;
+    KEDModellSeite *modelSeite;
+    KEDSoundSeite *soundSeite;
+    Fenster *neuDateiF;
+    AuswahlBox *neuDateiTyp;
+    TextFeld *neuDateiName;
+    Knopf *neuDateiOk;
+    Knopf *neueDatei;
+    Knopf *dateiLöschen;
+    int aktion;
+    bool sichtbar;
+    unsigned char alpha;
+    unsigned char alpha2;
+    double tickVal;
+    int ref;
+
+public:
+    // Konstruktor
+    KEDEditor( Schrift *zSchrift );
+    // Destruktor
+    ~KEDEditor();
+    // nicht constant
+    int getAktion();
+    bool neuDateiOkME( MausEreignis &me );
+    void setDateiListe( RCArray< Text > *list );
+    void setBildListe( RCArray< Text > *list );
+    void setSoundListe( RCArray< Text > *list );
+    void setModel2dListe( RCArray< Text > *list );
+    void setBild( Bild *b );
+    void setSound( GSL::GSLSoundV *s );
+    void setModel2d( Model2DData *d );
+    void setSichtbar( bool s );
+    bool tick( double tv ) override;
+    void doMausEreignis( MausEreignis &me ) override;
+    void doTastaturEreignis( TastaturEreignis &te ) override;
+    void render( Bild &zRObj ) override;
+    // constant
+    Text *zBildImportPfad() const;
+    Text *zSoundImportPfad() const;
+    Text *zDateiAuswahl() const;
+    Text *zBildAuswahl() const;
+    Text *zSoundAuswahl() const;
+    Text *zModel2dAuswahl() const;
+    Model2DData *getModelData() const;
+    Text *zNeuModelName() const;
+    int getNeuDateiTyp() const;
+    Text *zNeuDateiName() const;
+    bool istSichtbar() const;
+    // Reference Counting
+    KEDEditor *getThis();
+    KEDEditor *release();
+};

+ 1103 - 0
KSGClient/NachLogin/Editor/Karte/Dateien/KEDModel2DEditor.cpp

@@ -0,0 +1,1103 @@
+#include "KEDModel2DEditor.h"
+#include <Rahmen.h>
+#include <MausEreignis.h>
+#include <Text.h>
+#include <Schrift.h>
+#include <Scroll.h>
+#include <Globals.h>
+#include <TastaturEreignis.h>
+#include "../../../../Global/Initialisierung.h"
+#include "../../../../Global/Variablen.h"
+
+using namespace Model2DEditor;
+
+// Inhalt der VertexData Klasse aus KEDModel2DEditor.h
+// Konstruktor
+VertexData::VertexData( Vec2< float > v, Punkt t )
+{
+    vertex = v;
+    textur = t;
+    selected = 0;
+    sichtbar = 1;
+    ref = 1;
+}
+
+// nicht constant
+void VertexData::nachLinks( float num )
+{
+    if( selected )
+        vertex.x -= num;
+}
+
+void VertexData::nachOben( float num )
+{
+    if( selected )
+        vertex.y -= num;
+}
+
+void VertexData::saveTextur( Punkt tPos )
+{
+    textur = (Punkt)vertex - tPos;
+}
+
+void VertexData::select( Punkt p1, Punkt p2 )
+{
+    selected |= vertex.istInRegion( p1, p2 ) && sichtbar;
+}
+
+void VertexData::deSelect()
+{
+    selected = 0;
+}
+
+void VertexData::setAuswahl( bool ausw )
+{
+    selected = ausw;
+}
+
+void VertexData::setSichtbar( bool s )
+{
+    sichtbar = s;
+    selected &= sichtbar;
+}
+
+// constant
+bool VertexData::istSichtbar() const
+{
+    return sichtbar;
+}
+
+bool VertexData::istAusgewählt() const
+{
+    return selected;
+}
+
+Vec2< float > VertexData::getPos() const
+{
+    return vertex;
+}
+
+Punkt VertexData::getTPos() const
+{
+    return textur;
+}
+
+// Reference Counting
+VertexData *VertexData::getThis()
+{
+    ref++;
+    return this;
+}
+
+VertexData *VertexData::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+
+// Inhalt der PolygonData Klasse aus KEDModel2DEditor.h
+// Konstruktor
+PolygonData::PolygonData( Polygon2D &pg )
+{
+    vd = new RCArray< VertexData >();
+    sichtbar = 1;
+    ref = 1;
+    int anz = pg.vertex->getEintragAnzahl();
+    for( int i = 0; i < anz; i++ )
+    {
+        Vec2< float > v( 0, 0 );
+        Punkt t( 0, 0 );
+        if( pg.vertex->hat( i ) )
+            v = pg.vertex->get( i );
+        if( pg.tKordinaten && pg.tKordinaten->hat( i ) )
+            t = pg.tKordinaten->get( i );
+        vd->add( new VertexData( v, t ) );
+    }
+}
+
+// Destruktor
+PolygonData::~PolygonData()
+{
+    vd->release();
+}
+
+// nicht constant
+void PolygonData::addVertex( Vec2< float >v, Punkt t )
+{
+    vd->add( new VertexData( v, t ) );
+}
+
+void PolygonData::removeVertex( int num )
+{
+    vd->remove( num );
+}
+
+void PolygonData::nachLinks( float num )
+{
+    for( auto *i = &vd->getArray(); i && i->set; i = i->next )
+        i->var->nachLinks( num );
+}
+
+void PolygonData::nachOben( float num )
+{
+    for( auto *i = &vd->getArray(); i && i->set; i = i->next )
+        i->var->nachOben( num );
+}
+
+void PolygonData::saveTextur( Punkt tPos )
+{
+    for( auto *i = &vd->getArray(); i && i->set; i = i->next )
+        i->var->saveTextur( tPos );
+}
+
+void PolygonData::select( Punkt p1, Punkt p2 )
+{
+    for( auto *i = &vd->getArray(); i && i->set; i = i->next )
+        i->var->select( p1, p2 );
+}
+
+void PolygonData::deSelect()
+{
+    for( auto *i = &vd->getArray(); i && i->set; i = i->next )
+        i->var->deSelect();
+}
+
+void PolygonData::setSichtbar( bool s )
+{
+    sichtbar = s;
+}
+
+// constant
+bool PolygonData::istSichtbar() const
+{
+    return sichtbar;
+}
+
+VertexData *PolygonData::zVertex( int num ) const
+{
+    return vd->z( num );
+}
+
+int PolygonData::getVertexAnzahl() const
+{
+    return vd->getEintragAnzahl();
+}
+
+void PolygonData::getM2( Polygon2D &pd, bool textur ) const
+{
+    int anz = vd->getEintragAnzahl();
+    if( !pd.vertex )
+        pd.vertex = new Array< Vertex >();
+    if( !pd.tKordinaten )
+        pd.tKordinaten = new Array< Punkt >();
+    for( int i = 0; i < anz; i++ )
+    {
+        pd.vertex->add( this->vd->z( i )->getPos() );
+        if( textur )
+            pd.tKordinaten->add( this->vd->z( i )->getTPos() );
+    }
+}
+
+// Reference Counting
+PolygonData *PolygonData::getThis()
+{
+    ref++;
+    return this;
+}
+
+PolygonData *PolygonData::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+
+// Inhalt der Data Klasse aus KEDModel2DEditor.h
+// Konstruktor
+Data::Data( Model2DData *mdl )
+{
+    pd = new RCArray< PolygonData >();
+    tPos.x = 0;
+    tPos.y = 0;
+    textur = 0;
+    rTextur = 0;
+    sp = -1;
+    ref = 1;
+    int anz = ( mdl && mdl->polygons ) ? mdl->polygons->getEintragAnzahl() : 0;
+    for( int i = 0; i < anz; i++ )
+    {
+        if( mdl->polygons->hat( i ) )
+        {
+            pd->add( new PolygonData( mdl->polygons->get( i ) ) );
+            if( !tPos.x && !tPos.y )
+            {
+                if( mdl->polygons->get( i ).tKordinaten && mdl->polygons->get( i ).vertex
+                    && mdl->polygons->get( i ).tKordinaten->hat( 0 ) && mdl->polygons->get( i ).vertex->hat( 0 ) )
+                {
+                    Punkt p = (Punkt)mdl->polygons->get( i ).vertex->get( 0 );
+                    Punkt tp = mdl->polygons->get( i ).tKordinaten->get( 0 );
+                    tPos = p - tp;
+                }
+            }
+        }
+    }
+    if( mdl )
+        mdl->release();
+}
+
+// Destruktor
+Data::~Data()
+{
+    pd->release();
+    if( textur )
+        textur->release();
+}
+
+// nicht constant
+void Data::addPolygon()
+{
+    Polygon2D p;
+    p.vertex = new Array< Vertex >();
+    pd->add( new PolygonData( p ) );
+    p.vertex->release();
+}
+
+void Data::removePolygon( int num )
+{
+    pd->remove( num );
+    if( sp == num )
+        sp = -1;
+}
+
+void Data::selectPolygon( int num )
+{
+    sp = num;
+}
+
+void Data::nachLinks( float num )
+{
+    for( auto *i = &pd->getArray(); i && i->set; i = i->next )
+        i->var->nachLinks( num );
+}
+
+void Data::nachOben( float num )
+{
+    for( auto *i = &pd->getArray(); i && i->set; i = i->next )
+        i->var->nachOben( num );
+}
+
+void Data::tNachLinks( int num )
+{
+    if( !rTextur )
+        return;
+    tPos.x -= num;
+}
+
+void Data::tNachOben( int num )
+{
+    if( !rTextur )
+        return;
+    tPos.y -= num;
+}
+
+void Data::setRTextur( bool rt )
+{
+    rTextur = rt;
+    if( rt && !textur )
+    {
+        textur = new Bild();
+        textur->neuBild( 500, 500, 0xFF505000 );
+    }
+}
+
+void Data::saveTextur()
+{
+    if( !rTextur )
+        return;
+    for( auto *i = &pd->getArray(); i && i->set; i = i->next )
+        i->var->saveTextur( tPos );
+}
+
+void Data::setTextur( Bild *t )
+{
+    if( textur )
+        textur->release();
+    textur = t;
+}
+
+void Data::select( Punkt p1, Punkt p2 )
+{
+    for( auto *i = &pd->getArray(); i && i->set; i = i->next )
+        i->var->select( p1, p2 );
+}
+
+void Data::deSelect()
+{
+    for( auto *i = &pd->getArray(); i && i->set; i = i->next )
+        i->var->deSelect();
+}
+
+// constant
+PolygonData *Data::zPolygon( int num ) const
+{
+    return pd->z( num );
+}
+
+int Data::getPolygonAnzahl() const
+{
+    return pd->getEintragAnzahl();
+}
+
+int Data::getSelectedPolygon() const
+{
+    return sp;
+}
+
+Model2DData *Data::getM2() const
+{
+    int anz = pd->getEintragAnzahl();
+    Array< Polygon2D > *polygons = new Array< Polygon2D >();
+    for( int i = 0; i < anz; i++ )
+    {
+        Polygon2D pd = { 0, 0 };
+        this->pd->z( i )->getM2( pd, rTextur );
+        polygons->add( pd );
+    }
+    Model2DData *ret = new Model2DData();
+    ret->erstelleModell( polygons );
+    return ret;
+}
+
+Bild *Data::zTextur() const
+{
+    return rTextur ? textur : 0;
+}
+
+Punkt Data::getTPos() const
+{
+    return tPos;
+}
+
+// Reference Counting
+Data *Data::getThis()
+{
+    ref++;
+    return this;
+}
+
+Data *Data::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+
+// Inhalt der EditorListe Klasse aus KEDModel2DEditor.h
+// Konstruktor
+EditorListe::EditorListe( Schrift *zSchrift )
+{
+    ram = new LRahmen();
+    ram->setRamenBreite( 1 );
+    ram->setFarbe( 0xFFFFFFFF );
+    ram->setSize( 150, 480 );
+    ram->setPosition( 720, 10 );
+    scroll = new VScrollBar();
+    schrift = zSchrift->getThis();
+    data = 0;
+    ref = 1;
+}
+
+// Destruktor
+EditorListe::~EditorListe()
+{
+    ram->release();
+    scroll->release();
+    if( data )
+        data->release();
+    schrift->release();
+}
+
+// nicht constant
+void EditorListe::setDataZ( Data *d )
+{
+    if( data )
+        data->release();
+    data = d;
+}
+
+void EditorListe::doMausEreignis( MausEreignis &me )
+{
+    me.mx -= ram->getX();
+    me.my -= ram->getY();
+    if( me.mx < 0 || me.my < 0 || me.mx > ram->getBreite() || me.my > ram->getHeight() )
+    {
+        me.mx += ram->getX();
+        me.my += ram->getY();
+        return;
+    }
+    scroll->doMausMessage( ram->getBreite() - 17, 1, 15, ram->getHeight() - 2, me );
+    rend |= scroll->getRend();
+    if( me.id == ME_RLinks )
+    {
+        int pAnz = data->getPolygonAnzahl();
+        int y = -scroll->getScroll();
+        for( int i = 0; i < pAnz; i++ )
+        {
+            if( me.mx > 0 && me.my > y && me.mx < 20 && me.my < y + 20 )
+            { // Ein und Ausklappen
+                if( !ausgeklappt.hat( i ) )
+                    ausgeklappt.set( 0, i );
+                ausgeklappt.set( !ausgeklappt.get( i ), i );
+                rend = 1;
+            }
+            else if( me.mx > 115 && me.my > y + 1 && me.mx < 132 && me.my < y + 19 )
+            { // Löschen
+                data->removePolygon( i );
+                rend = 1;
+                break;
+            }
+            else if( me.mx > 0 && me.my > y && me.mx < 133 && me.my < y + 20 )
+            { // Polygon Auswählen und Abwählen
+                if( data->getSelectedPolygon() != i )
+                    data->selectPolygon( i );
+                else
+                    data->selectPolygon( -1 );
+                rend = 1;
+            }
+            PolygonData *pd = data->zPolygon( i );
+            if( pd && ausgeklappt.hat( i ) && ausgeklappt.get( i ) )
+            {
+                int vAnz = pd->getVertexAnzahl();
+                for( int j = 0; j < vAnz; j++ )
+                {
+                    y += 20;
+                    if( me.mx > 115 && me.my > y + 1 && me.mx < 132 && me.my < y + 19 )
+                    { // Löschen
+                        pd->removeVertex( j );
+                        rend = 1;
+                    }
+                    else if( me.mx > 95 && me.my > y + 5 && me.mx < 105 && me.my < y + 15 )
+                    { // Sichtbar und Unsichtbar
+                        pd->zVertex( j )->setSichtbar( !pd->zVertex( j )->istSichtbar() );
+                        rend = 1;
+                    }
+                    else if( me.my > y && me.my < y + 20 && me.mx > 0 && me.mx < 133 )
+                    { // Auswählen und Abwählen
+                        pd->zVertex( j )->setAuswahl( !pd->zVertex( j )->istAusgewählt() );
+                        rend = 1;
+                    }
+                }
+            }
+            y += 20;
+        }
+    }
+    me.verarbeitet = 1;
+    me.mx += ram->getX();
+    me.my += ram->getY();
+}
+
+bool EditorListe::tick( double zeit )
+{
+    bool ret = rend;
+    rend = 0;
+    return ret;
+}
+
+void EditorListe::render( Bild &zRObj )
+{
+    ram->render( zRObj );
+    if( !zRObj.setDrawOptions( ram->getPosition() + Punkt( 1, 1 ), ram->getSize() - Punkt( 2, 2 ) ) )
+        return;
+    scroll->render( ram->getBreite() - 17, 1, 15, ram->getHeight() - 2, zRObj );
+    int pAnz = data->getPolygonAnzahl();
+    int y = -scroll->getScroll();
+    int maxH = 0;
+    schrift->lock();
+    schrift->setSchriftSize( 12 );
+    Text name;
+    for( int i = 0; i < pAnz; i++ )
+    {
+        if( data->getSelectedPolygon() == i )
+            zRObj.fillRegion( 0, y, 133, 20, 0xFF002000 );
+        name = "Polygon ";
+        name += i;
+        schrift->setDrawPosition( 20, y + 4 );
+        schrift->renderText( &name, zRObj, 0xFFFFFFFF );
+        zRObj.drawLinie( Punkt( 115, y + 1 ), Punkt( 132, y + 18 ), 0xFFFF0000 );
+        zRObj.drawLinie( Punkt( 132, y + 1 ), Punkt( 115, y + 18 ), 0xFFFF0000 );
+        if( ausgeklappt.hat( i ) && ausgeklappt.get( i ) )
+        {
+            zRObj.drawDreieck( Punkt( 10, 4 + y ), Punkt( 4, 16 + y ), Punkt( 16, 16 + y ), 0xFFFFFFFF );
+            PolygonData *pd = data->zPolygon( i );
+            if( pd )
+            {
+                int vAnz = pd->getVertexAnzahl();
+                for( int j = 0; j < vAnz; j++ )
+                {
+                    maxH += 20;
+                    y += 20;
+                    if( pd->zVertex( j )->istAusgewählt() )
+                        zRObj.fillRegion( 0, y, 133, 20, 0xFF101010 );
+                    name = "  Vertex ";
+                    name += j;
+                    schrift->setDrawPosition( 20, y + 4 );
+                    schrift->renderText( &name, zRObj, 0xFFFFFFFF );
+                    zRObj.drawLinie( Punkt( 115, y + 1 ), Punkt( 132, y + 18 ), 0xFFFF0000 );
+                    zRObj.drawLinie( Punkt( 132, y + 1 ), Punkt( 115, y + 18 ), 0xFFFF0000 );
+                    if( pd->zVertex( j )->istSichtbar() )
+                    {
+                        zRObj.drawKreis( 100, y + 10, 5, 0xFFFFFFFF );
+                        zRObj.drawKreis( 100, y + 10, 1, 0xFFFFFFFF );
+                    }
+                    else
+                    {
+                        zRObj.drawKreis( 100, y + 10, 5, 0xFF505050 );
+                        zRObj.drawKreis( 100, y + 10, 1, 0xFF505050 );
+                    }
+                }
+            }
+        }
+        else
+            zRObj.drawDreieck( Punkt( 10, 16 + y ), Punkt( 4, 4 + y ), Punkt( 16, 4 + y ), 0xFFFFFFFF );
+        maxH += 20;
+        y += 20;
+    }
+    schrift->unlock();
+    scroll->update( maxH, ram->getHeight() - 2 );
+    zRObj.releaseDrawOptions();
+}
+
+// Reference Counting
+EditorListe *EditorListe::getThis()
+{
+    ref++;
+    return this;
+}
+
+EditorListe *EditorListe::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+
+// Inhalt der Editor2D Klasse aus KEDModel2DEditor.h
+// Konstruktor
+Editor2D::Editor2D( Schrift *zSchrift )
+{
+    pos.x = 10;
+    pos.y = 10;
+    offs.x = -350;
+    offs.y = -250;
+    mausPos.x = 0;
+    mausPos.y = 0;
+    data = 0;
+    ram = new LRahmen();
+    ram->setFarbe( 0xFFFFFFFF );
+    ram->setRamenBreite( 1 );
+    ram->setSize( 700, 480 );
+    select = new LRahmen();
+    select->setFarbe( 0xFF5050FF );
+    select->setRamenBreite( 1 );
+    schrift = zSchrift->getThis();
+    addV = Vertex( 0, 0 );
+    mausIn = 0;
+    größe = 1;
+    ref = 1;
+}
+
+// Destruktor
+Editor2D::~Editor2D()
+{
+    ram->release();
+    select->release();
+    schrift->release();
+    if( data )
+        data->release();
+}
+
+// nicht constant
+void Editor2D::setDataZ( Data *d )
+{
+    if( data )
+        data->release();
+    data = d;
+}
+
+void Editor2D::doMausEreignis( MausEreignis &me )
+{
+    me.mx -= pos.x;
+    me.my -= pos.y;
+    if( me.mx < 0 || me.my < 0 || me.mx > ram->getBreite() || me.my > ram->getHeight() )
+    {
+        me.mx += pos.x;
+        me.my += pos.y;
+        mausIn = 0;
+        return;
+    }
+    mausIn = 1;
+    rend = 1;
+    addV = Vertex( (float)me.mx, (float)me.my ) / größe + offs;
+    if( me.id == ME_UScroll )
+        größe += 0.01f;
+    if( me.id == ME_DScroll )
+        größe -= 0.01f;
+    if( me.id == ME_PLinks )
+    {
+        select->setPosition( me.mx, me.my );
+        select->setSize( 0, 0 );
+    }
+    if( me.id == ME_PRechts || me.id == ME_PMitte )
+    {
+        mausPos.x = me.mx;
+        mausPos.y = me.my;
+    }
+    if( me.id == ME_Bewegung )
+    {
+        if( getMausStand( M_Links ) )
+        {
+            select->setSize( me.mx - select->getX(), me.my - select->getY() );
+        }
+        if( getMausStand( M_Rechts ) )
+        {
+            data->nachLinks( ( mausPos.x - me.mx ) / größe );
+            data->nachOben( ( mausPos.y - me.my ) / größe );
+            mausPos.x = me.mx;
+            mausPos.y = me.my;
+        }
+        if( getMausStand( M_Mitte ) )
+        {
+            data->tNachLinks( (int)( ( mausPos.x - me.mx ) / größe ) );
+            data->tNachOben( (int)( ( mausPos.y - me.my ) / größe ) );
+            mausPos.x = me.mx;
+            mausPos.y = me.my;
+        }
+    }
+    if( me.id == ME_RLinks )
+    {
+        if( !getTastenStand( T_Shift ) )
+            data->deSelect();
+        data->select( ( Vec2<float> )select->getPosition() / größe + offs, ( Vec2<float> )( select->getPosition() + select->getSize() ) / größe + offs );
+        select->setSize( 0, 0 );
+        select->setPosition( 0, 0 );
+    }
+    if( me.id == ME_RRechts )
+    {
+        mausPos.x = 0;
+        mausPos.y = 0;
+    }
+    me.verarbeitet = 1;
+    me.mx += pos.x;
+    me.my += pos.y;
+}
+
+void Editor2D::doTastaturEreignis( TastaturEreignis &te )
+{
+    if( te.id == TE_Release && te.taste == T_Enter && mausIn )
+    {
+        PolygonData *pd = data->zPolygon( data->getSelectedPolygon() );
+        if( pd )
+        {
+            pd->addVertex( addV, Punkt( 0, 0 ) );
+            rend = 1;
+        }
+    }
+    if( te.id == TE_Release && te.taste == T_Einfg )
+    {
+        data->addPolygon();
+        rend = 1;
+    }
+    if( te.id == T_Oben )
+        offs.y -= 2;
+    if( te.id == T_Links )
+        offs.x -= 2;
+    if( te.id == T_Unten )
+        offs.y += 2;
+    if( te.id == T_Rechts )
+        offs.x += 2;
+    if( te.id == T_Oben || te.id == T_Links || te.id == T_Unten || te.id == T_Rechts )
+        rend = 1;
+}
+
+bool Editor2D::tick( double zeit )
+{
+    if( mausIn )
+    {
+        if( getTastenStand( T_Links ) )
+        {
+            offs.x--;
+            rend = 1;
+        }
+        if( getTastenStand( T_Rechts ) )
+        {
+            offs.x++;
+            rend = 1;
+        }
+        if( getTastenStand( T_Oben ) )
+        {
+            offs.y--;
+            rend = 1;
+        }
+        if( getTastenStand( T_Unten ) )
+        {
+            offs.y++;
+            rend = 1;
+        }
+        if( getTastenStand( 'w' ) )
+        {
+            data->tNachOben( 1 );
+            rend = 1;
+        }
+        if( getTastenStand( 'a' ) )
+        {
+            data->tNachLinks( 1 );
+            rend = 1;
+        }
+        if( getTastenStand( 's' ) )
+        {
+            data->tNachOben( -1 );
+            rend = 1;
+        }
+        if( getTastenStand( 'd' ) )
+        {
+            data->tNachLinks( -1 );
+            rend = 1;
+        }
+    }
+    bool ret = rend;
+    rend = 0;
+    return ret;
+}
+
+void Editor2D::render( Bild &zRObj )
+{
+    if( !zRObj.setDrawOptions( pos, ram->getSize() ) )
+        return;
+    ram->render( zRObj );
+    if( !zRObj.setDrawOptions( 1, 1, ram->getBreite() - 2, ram->getHeight() - 2 ) )
+    {
+        zRObj.releaseDrawOptions();
+        return;
+    }
+    if( data->zTextur() )
+    {
+        Punkt tPos = data->getTPos();
+        zRObj.alphaBildSkall( (int)( ( tPos.x - offs.x ) * größe ), (int)( ( tPos.y - offs.y ) * größe ),
+                              (int)( data->zTextur()->getBreite() * größe ), (int)( data->zTextur()->getHeight() * größe ), *data->zTextur() );
+    }
+    // Raster mahlen
+    int xanz = (int)( ram->getBreite() / ( 50 * größe ) );
+    int yanz = (int)( ram->getHeight() / ( 50 * größe ) );
+    int xStart = ( 50 - abs( offs.x ) % 50 );
+    if( offs.x < 0 )
+        xStart = -offs.x % 50;
+    if( offs.x == 0 )
+        xStart = 0;
+    int yStart = ( 50 - abs( offs.y ) % 50 );
+    if( offs.y < 0 )
+        yStart = -offs.y % 50;
+    if( offs.y == 0 )
+        yStart = 0;
+    for( float x = xStart * größe, y = yStart * größe; !( x > ram->getBreite() && y > ram->getHeight() ); x += 50 * größe, y += 50 * größe )
+    {
+        zRObj.drawLinieH( 0, (int)y, ram->getBreite(), 0xFF505050 );
+        zRObj.drawLinieV( (int)x, 0, ram->getHeight() , 0xFF505050 );
+    }
+    Text xPos = "";
+    xPos = offs.x + (int)( xStart + 50 * ( xanz / 2 ) );
+    schrift->setDrawPosition( (int)( xStart * größe + 50 * größe * ( xanz / 2 ) ), 0 );
+    schrift->renderText( &xPos, zRObj, 0xFF505050 );
+    xPos = offs.y + (int)( yStart + 50 * ( yanz / 2 ) );
+    schrift->setDrawPosition( 0, (int)( yStart * größe + 50 * größe * ( yanz / 2 ) ) );
+    schrift->renderText( &xPos, zRObj, 0xFF505050 );
+    // Model mahlen
+    int pAnz = data->getPolygonAnzahl();
+    for( int i = 0; i < pAnz; i++ )
+    {
+        PolygonData *p = data->zPolygon( i );
+        if( !p->istSichtbar() )
+            continue;
+        if( data->getSelectedPolygon() == i && mausIn )
+        {
+            int vAnz = p->getVertexAnzahl();
+            VertexData tmp = VertexData( addV, Punkt() );
+            VertexData *l = p->zVertex( vAnz - 1 );
+            for( int j = -1; j < vAnz && vAnz > 0; j++ )
+            {
+                VertexData *v = j < 0 ? &tmp : p->zVertex( j );
+                if( l && v )
+                {
+                    if( l->istSichtbar() && v->istSichtbar() )
+                        zRObj.drawLinie( ( ( l->getPos() - offs ) * größe ), ( ( v->getPos() - offs ) * größe ), 0xFFA0A0A0 );
+                    else
+                        zRObj.drawLinie( ( ( l->getPos() - offs ) * größe ), ( ( v->getPos() - offs ) * größe ), 0xFF606060 );
+                }
+                if( !l->istSichtbar() )
+                {
+                    l = v;
+                    continue;
+                }
+                if( j == 0 )
+                    zRObj.fillRegion( (int)( ( l->getPos().x - offs.x ) * größe ) - 5, (int)( ( l->getPos().y - offs.y ) * größe ) - 5, 10, 10, 0xFF50FF50 );
+                else
+                {
+                    if( !l->istAusgewählt() )
+                        zRObj.fillRegion( (int)( ( l->getPos().x - offs.x ) * größe ) - 5, (int)( ( l->getPos().y - offs.y ) * größe ) - 5, 10, 10, 0xFF5050FF );
+                    else
+                        zRObj.fillRegion( (int)( ( l->getPos().x - offs.x ) * größe ) - 5, (int)( ( l->getPos().y - offs.y ) * größe ) - 5, 10, 10, 0xFFFF5050 );
+                }
+                l = v;
+            }
+        }
+        else
+        {
+            int vAnz = p->getVertexAnzahl();
+            VertexData *l = p->zVertex( vAnz - 1 );
+            for( int j = 0; j < vAnz; j++ )
+            {
+                VertexData *v = p->zVertex( j );
+                if( l && v )
+                {
+                    if( l->istSichtbar() && v->istSichtbar() )
+                        zRObj.drawLinie( ( ( l->getPos() - offs ) * größe ), ( ( v->getPos() - offs ) * größe ), 0xFFA0A0A0 );
+                    else
+                        zRObj.drawLinie( ( ( l->getPos() - offs ) * größe ), ( ( v->getPos() - offs ) * größe ), 0xFF606060 );
+                }
+                if( !l->istSichtbar() )
+                {
+                    l = v;
+                    continue;
+                }
+                if( !l->istAusgewählt() )
+                    zRObj.fillRegion( (int)( ( l->getPos().x - offs.x ) * größe ) - 5, (int)( ( l->getPos().y - offs.y ) * größe ) - 5, 10, 10, 0xFF5050FF );
+                else
+                    zRObj.fillRegion( (int)( ( l->getPos().x - offs.x ) * größe ) - 5, (int)( ( l->getPos().y - offs.y ) * größe ) - 5, 10, 10, 0xFFFF5050 );
+                l = v;
+            }
+        }
+    }
+    select->render( zRObj );
+    zRObj.releaseDrawOptions();
+    zRObj.releaseDrawOptions();
+}
+
+// Reference Counting
+Editor2D *Editor2D::getThis()
+{
+    ref++;
+    return this;
+}
+
+Editor2D *Editor2D::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+
+// Inhalt der GUI Klasse aus KEDModel2DEditor.h
+// Konstruktor
+GUI::GUI( Schrift *zSchrift )
+{
+    speichern = initKnopf( 660, 500, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Speichern" );
+    abbrechen = initKnopf( 770, 500, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Abbrehen" );
+    textur = initKontrollKnopf( 10, 500, 100, 20, zSchrift, KontrollKnopf::Style::Normal, "Textur" );
+    texturVerknüpfen = initKnopf( 120, 500, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Textur Speichern" );
+    texturLaden = initKnopf( 230, 500, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Textur Laden" );
+    data = new Data( 0 );
+    editor = new Editor2D( zSchrift );
+    editor->setDataZ( data->getThis() );
+    liste = new EditorListe( zSchrift );
+    liste->setDataZ( data->getThis() );
+    importDialog = 0;
+    aktion = 0;
+    alpha = 0;
+    sichtbar = 0;
+    ref = 1;
+}
+
+// Destruktor
+GUI::~GUI()
+{
+    editor->release();
+    liste->release();
+    speichern->release();
+    abbrechen->release();
+    data->release();
+    textur->release();
+    texturVerknüpfen->release();
+    texturLaden->release();
+    if( importDialog )
+        importDialog->release();
+}
+
+// nicht constant
+void GUI::setSichtbar( bool s )
+{
+    sichtbar = s;
+}
+
+void GUI::setModel( Model2DData *data )
+{
+    if( this->data )
+        this->data->release();
+    this->data = new Data( data );
+    editor->setDataZ( this->data->getThis() );
+    liste->setDataZ( this->data->getThis() );
+}
+
+void GUI::doMausEreignis( MausEreignis &me )
+{
+    if( !sichtbar )
+        return;
+    editor->doMausEreignis( me );
+    liste->doMausEreignis( me );
+    bool vera = me.verarbeitet;
+    speichern->doMausEreignis( me );
+    if( me.id == ME_RLinks && me.verarbeitet && !vera )
+    {
+        aktion = 1;
+    }
+    vera = me.verarbeitet;
+    abbrechen->doMausEreignis( me );
+    if( me.id == ME_RLinks && me.verarbeitet && !vera )
+    {
+        aktion = 2;
+    }
+    vera = me.verarbeitet;
+    textur->doMausEreignis( me );
+    data->setRTextur( textur->hatStyle( KontrollKnopf::Style::Selected ) );
+    vera = me.verarbeitet;
+    texturVerknüpfen->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+        data->saveTextur();
+    vera = me.verarbeitet;
+    texturLaden->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+    {
+        if( !importDialog )
+        {
+            importDialog = new DateiDialogTh();
+            importDialog->setOpen( 1 );
+            importDialog->setDateiTypAuswahl( 4 );
+            importDialog->addDateiTyp( "JPEG-Bild", "*.jpg;*.jpeg;*.jpe" );
+            importDialog->addDateiTyp( "GIF-Bild", "*.gif" );
+            importDialog->addDateiTyp( "PNG-Bild", "*.png" );
+            importDialog->addDateiTyp( "Alle Dateien", "*.*" );
+            importDialog->start();
+        }
+    }
+}
+
+void GUI::doTastaturEreignis( TastaturEreignis &te )
+{
+    if( !sichtbar )
+        return;
+    editor->doTastaturEreignis( te );
+}
+
+bool GUI::tick( double zeit )
+{
+    if( importDialog )
+    {
+        if( !importDialog->isRunning() )
+        {
+            Text *importPfad = importDialog->getPfad();
+            importDialog = importDialog->release();
+            if( sichtbar && importPfad )
+            {
+                importPfad->ersetzen( "\\", "/" );
+                Text *err = new Text();
+                Bild *b = ladeBild( importPfad->getText(), err );
+                if( !b )
+                    nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), err, new Text( "Ok" ) );
+                else
+                    data->setTextur( b );
+                err->release();
+            }
+            importPfad->release();
+        }
+    }
+    rend |= speichern->tick( zeit );
+    rend |= abbrechen->tick( zeit );
+    if( sichtbar && alpha != 255 )
+    {
+        if( alpha + zeit * 200 > 255 )
+            alpha = 255;
+        else
+            alpha += (unsigned char)(zeit * 200);
+        rend = 1;
+    }
+    else if( !sichtbar && alpha )
+    {
+        if( alpha - zeit * 200 < 0 )
+            alpha = 0;
+        else
+            alpha -= (unsigned char)( zeit * 200 );
+        rend = 1;
+    }
+    if( sichtbar )
+    {
+        rend |= editor->tick( zeit );
+        rend |= liste->tick( zeit );
+        rend |= speichern->tick( zeit );
+        rend |= textur->tick( zeit );
+        rend |= texturVerknüpfen->tick( zeit );
+        rend |= texturLaden->tick( zeit );
+    }
+    bool ret = rend;
+    rend = 0;
+    return ret;
+}
+
+void GUI::render( Bild &zRObj )
+{
+    zRObj.setAlpha( alpha );
+    editor->render( zRObj );
+    liste->render( zRObj );
+    speichern->render( zRObj );
+    abbrechen->render( zRObj );
+    textur->render( zRObj );
+    texturVerknüpfen->render( zRObj );
+    texturLaden->render( zRObj );
+    zRObj.releaseAlpha();
+}
+
+int GUI::getAktion()
+{
+    int ret = aktion;
+    aktion = 0;
+    return ret;
+}
+
+// const
+Model2DData *GUI::getM2Data() const
+{
+    return data->getM2();
+}
+
+// Reference Counting
+GUI *GUI::getThis()
+{
+    ref++;
+    return 0;
+}
+
+GUI *GUI::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 207 - 0
KSGClient/NachLogin/Editor/Karte/Dateien/KEDModel2DEditor.h

@@ -0,0 +1,207 @@
+#pragma once
+
+#include <Knopf.h>
+#include <Array.h>
+#include <Punkt.h>
+#include <Bild.h>
+#include <Model2D.h>
+#include <DateiDialog.h>
+
+using namespace Framework;
+
+namespace Model2DEditor
+{
+    class VertexData
+    {
+    private:
+        Vec2< float > vertex;
+        Punkt textur;
+        bool selected;
+        bool sichtbar;
+        int ref;
+
+    public:
+        // Konstruktor
+        VertexData( Vec2< float > v, Punkt t );
+        // nicht constant
+        void nachLinks( float num );
+        void nachOben( float num );
+        void saveTextur( Punkt tPos );
+        void select( Punkt p1, Punkt p2 );
+        void deSelect();
+        void setAuswahl( bool ausw );
+        void setSichtbar( bool s );
+        // constant
+        bool istSichtbar() const;
+        bool istAusgewählt() const;
+        Vec2< float > getPos() const;
+        Punkt getTPos() const;
+        // Reference Counting
+        VertexData *getThis();
+        VertexData *release();
+    };
+
+    class PolygonData
+    {
+    private:
+        RCArray< VertexData > *vd;
+        bool sichtbar;
+        int ref;
+
+    public:
+        // Konstruktor
+        PolygonData( Polygon2D &pg );
+        // Destruktor
+        ~PolygonData();
+        // nicht constant
+        void addVertex( Vec2< float >v, Punkt t );
+        void removeVertex( int num );
+        void nachLinks( float num );
+        void nachOben( float num );
+        void saveTextur( Punkt tPos );
+        void select( Punkt p1, Punkt p2 );
+        void deSelect();
+        void setSichtbar( bool s );
+        // constant
+        bool istSichtbar() const;
+        VertexData *zVertex( int num ) const;
+        int getVertexAnzahl() const;
+        void getM2( Polygon2D &pd, bool textur ) const;
+        // Reference Counting
+        PolygonData *getThis();
+        PolygonData *release();
+    };
+
+    class Data
+    {
+    private:
+        RCArray< PolygonData > *pd;
+        Bild *textur;
+        Punkt tPos;
+        bool rTextur;
+        int sp;
+        int ref;
+
+    public:
+        // Konstruktor
+        Data( Model2DData *mdl );
+        // Destruktor
+        ~Data();
+        // nicht constant
+        void addPolygon();
+        void removePolygon( int num );
+        void selectPolygon( int num );
+        void nachLinks( float num );
+        void nachOben( float num );
+        void tNachLinks( int num );
+        void tNachOben( int num );
+        void setRTextur( bool rt );
+        void saveTextur();
+        void setTextur( Bild *t );
+        void select( Punkt p1, Punkt p2 );
+        void deSelect();
+        // constant
+        PolygonData *zPolygon( int num ) const;
+        int getPolygonAnzahl() const;
+        int getSelectedPolygon() const;
+        Model2DData *getM2() const;
+        Bild *zTextur() const;
+        Punkt getTPos() const;
+        // Reference Counting
+        Data *getThis();
+        Data *release();
+    };
+
+    class EditorListe : public Zeichnung
+    {
+    private:
+        LRahmen *ram;
+        VScrollBar *scroll;
+        Data *data;
+        Array< bool > ausgeklappt;
+        Schrift *schrift;
+        int ref;
+
+    public:
+        // Konstruktor
+        EditorListe( Schrift *zSchrift );
+        // Destruktor
+        ~EditorListe();
+        // nicht constant
+        void setDataZ( Data *d );
+        void doMausEreignis( MausEreignis &me ) override;
+        bool tick( double zeit ) override;
+        void render( Bild &zRObj ) override;
+        // Reference Counting
+        EditorListe *getThis();
+        EditorListe *release();
+    };
+    
+    class Editor2D : public Zeichnung
+    {
+    private:
+        Punkt pos;
+        Punkt offs;
+        Data *data;
+        LRahmen *ram;
+        LRahmen *select;
+        Schrift *schrift;
+        Punkt mausPos;
+        Vertex addV;
+        bool mausIn;
+        float größe;
+        int ref;
+
+    public:
+        // Konstruktor
+        Editor2D( Schrift *zSchrift );
+        // Destruktor
+        ~Editor2D();
+        // nicht constant
+        void setDataZ( Data *d );
+        void doMausEreignis( MausEreignis &me ) override;
+        void doTastaturEreignis( TastaturEreignis &te ) override;
+        bool tick( double zeit ) override;
+        void render( Bild &zRObj ) override;
+        // Reference Counting
+        Editor2D *getThis();
+        Editor2D *release();
+    };
+
+    class GUI : public Zeichnung
+    {
+    private:
+        Knopf *speichern;
+        Knopf *abbrechen;
+        Editor2D *editor;
+        EditorListe *liste;
+        KontrollKnopf *textur;
+        Knopf *texturLaden;
+        Knopf *texturVerknüpfen;
+        DateiDialogTh *importDialog;
+        Data *data;
+        bool sichtbar;
+        unsigned char alpha;
+        int aktion;
+        int ref;
+
+    public:
+        // Konstruktor
+        GUI( Schrift *zSchrifto );
+        // Destruktor
+        ~GUI();
+        // nicht constant
+        void setSichtbar( bool s );
+        void setModel( Model2DData *data );
+        void doMausEreignis( MausEreignis &me ) override;
+        void doTastaturEreignis( TastaturEreignis &te ) override;
+        bool tick( double zeit ) override;
+        void render( Bild &zRObj ) override;
+        int getAktion();
+        // const
+        Model2DData *getM2Data() const;
+        // Reference Counting
+        GUI *getThis();
+        GUI *release();
+    };
+}

+ 537 - 0
KSGClient/NachLogin/Editor/Karte/Dateien/KEDateien.cpp

@@ -0,0 +1,537 @@
+#include "KEDateien.h"
+#include <Schrift.h>
+#include <Text.h>
+#include "../../../../Global/Variablen.h"
+#include "../../../../Global/Initialisierung.h"
+#include "KEDModel2DEditor.h"
+#include "WAVDatei.h"
+
+
+// Inahlt der KEDateien Klasse aus KEDateien.h
+// Konstruktor
+KEDateien::KEDateien( int karte, Schrift *zSchrift )
+{
+    schrift = zSchrift->getThis();
+    Text *kName = infoKlient->getKarteName( karte );
+    Text titel = kName ? kName->getText() : "<Karte>";
+    titel += " - Dateien";
+    if( kName )
+        kName->release();
+    fenster = initFenster( 10, 40, 880, 550, zSchrift, Fenster::Style::Sichtbar | Fenster::Style::Titel | Fenster::Style::TitelBuffered | Fenster::Style::Erlaubt | Fenster::Style::Rahmen, titel );
+    editor = new KEDEditor( zSchrift );
+    laden = (Animation2D*)ladeAnimation->dublizieren();
+    laden->setPosition( 425, 275 );
+    laden->setSichtbar( 0 );
+    fenster->addMember( editor );
+    fort = initFBalken( 375, 350, 150, 20, zSchrift, FBalken::Style::normal );
+    animation = 0;
+    tickVal = 0;
+    sichtbar = 0;
+    rechts = 0;
+    xStart = 0;
+    breite = 0;
+    aktion = 0;
+    this->karte = karte;
+    alpha = 255;
+    ref = 1;
+}
+
+// Destruktor
+KEDateien::~KEDateien()
+{
+    if( run )
+    {
+        warteAufThread( 5000 );
+        if( run )
+            ende();
+    }
+    fenster->release();
+    editor->release();
+    laden->release();
+    fort->release();
+    schrift->release();
+}
+
+// nicht constant
+void KEDateien::setSichtbar( bool s, bool vr )
+{
+    animation = 1;
+    sichtbar = s;
+    rechts = vr;
+    if( sichtbar )
+    {
+        if( vr )
+        {
+            xStart = 900;
+            breite = 0;
+        }
+        else
+        {
+            xStart = 0;
+            breite = 0;
+        }
+        if( !run )
+        {
+            aktion = 0;
+            start();
+        }
+    }
+    else
+        editor->setSichtbar( 0 );
+}
+
+void KEDateien::thread()
+{
+    laden->setSichtbar( 1 );
+    switch( aktion )
+    {
+    case 0: // Init
+    {
+        RCArray< Text > *list = new RCArray< Text >();
+        int anz = editorKlient->deGetDateiListe( list );
+        if( anz < 0 )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            list->release();
+            break;
+        }
+        editor->setDateiListe( list );
+        break;
+    }
+    case 1: // Neue Datei
+    {
+        if( !editorKlient->deNeueDatei( (char)editor->getNeuDateiTyp(), editor->zNeuDateiName() ) )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            break;
+        }
+        RCArray< Text > *list = new RCArray< Text >();
+        int anz = editorKlient->deGetDateiListe( list );
+        if( anz < 0 )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            list->release();
+            break;
+        }
+        editor->setDateiListe( list );
+        break;
+    }
+    case 2: // Datei Auswählen
+    {
+        Text *zName = editor->zDateiAuswahl();
+        if( zName->hat( ".ltdb" ) )
+        {
+            RCArray< Text > *list = new RCArray< Text >();
+            int anz = editorKlient->deGetBildListe( zName, list );
+            if( anz < 0 )
+            {
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+                list->release();
+                break;
+            }
+            editor->setBildListe( list );
+        }
+        else if( zName->hat( ".gsl" ) )
+        {
+            RCArray< Text > *list = new RCArray< Text >();
+            int anz = editorKlient->deGetSoundListe( zName, list );
+            if( anz < 0 )
+            {
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+                list->release();
+                break;
+            }
+            editor->setSoundListe( list );
+        }
+        else if( zName->hat( ".m2" ) )
+        {
+            RCArray< Text > *list = new RCArray< Text >();
+            int anz = editorKlient->deGetModelListe( zName, list );
+            if( anz < 0 )
+            {
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+                list->release();
+                break;
+            }
+            editor->setModel2dListe( list );
+        }
+        else
+        {
+            if( !editorKlient->deOrdnerÖffnen( zName ) )
+            {
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+                break;
+            }
+            RCArray< Text > *list = new RCArray< Text >();
+            int anz = editorKlient->deGetDateiListe( list );
+            if( anz < 0 )
+            {
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+                list->release();
+                break;
+            }
+            editor->setDateiListe( list );
+        }
+        break;;
+    }
+    case 3: // Datei Löschen
+    {
+        Text p( "." );
+        if( ( editor->zDateiAuswahl() && !editorKlient->deDateiLöschen( editor->zDateiAuswahl() ) ) || ( !editor->zDateiAuswahl() && !editorKlient->deDateiLöschen( &p ) ) )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            break;
+        }
+        RCArray< Text > *list = new RCArray< Text >();
+        int anz = editorKlient->deGetDateiListe( list );
+        if( anz < 0 )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            list->release();
+            break;
+        }
+        editor->setDateiListe( list );
+        break;
+    }
+    case 4: // Bild Auswählen
+    {
+        Bild *b = editorKlient->deBildLaden( editor->zDateiAuswahl(), editor->zBildAuswahl(), fort );
+        if( !b )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            break;
+        }
+        editor->setBild( b );
+        break;
+    }
+    case 5: // Bild Löschen
+    {
+        if( !editorKlient->deBildLöschen( editor->zDateiAuswahl(), editor->zBildAuswahl() ) )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            break;
+        }
+        RCArray< Text > *list = new RCArray< Text >();
+        int anz = editorKlient->deGetBildListe( editor->zDateiAuswahl(), list );
+        if( anz < 0 )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            list->release();
+            break;
+        }
+        editor->setBildListe( list );
+        break;
+    }
+    case 6: // Bild Importieren
+    {
+        Text *pfad = editor->zBildImportPfad();
+        pfad->ersetzen( "\\", "/" );
+        Text *n = pfad->getTeilText( pfad->positionVon( "/", pfad->anzahlVon( "/" ) - 1 ) + 1 );
+        Text name = n->getText();
+        n->release();
+        Text *err = new Text();
+        Bild *b = ladeBild( pfad->getText(), err );
+        if( !b )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), err, new Text( "Ok" ) );
+            break;
+        }
+        err->release();
+        if( !editorKlient->deBildSpeichern( editor->zDateiAuswahl(), &name, b, fort ) )
+        {
+            b->release();
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            break;
+        }
+        b->release();
+        RCArray< Text > *list = new RCArray< Text >();
+        int anz = editorKlient->deGetBildListe( editor->zDateiAuswahl(), list );
+        if( anz < 0 )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            list->release();
+            break;
+        }
+        editor->setBildListe( list );
+        break;
+    }
+    case 7: // Model Auswählen
+    {
+        Model2DData *d = editorKlient->deModelLaden( editor->zDateiAuswahl(), editor->zModel2dAuswahl(), fort );
+        if( !d )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            break;
+        }
+        editor->setModel2d( d );
+        break;
+    }
+    case 8: // Model Löschen
+    {
+        if( !editorKlient->deModelLöschen( editor->zDateiAuswahl(), editor->zModel2dAuswahl() ) )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            break;
+        }
+        RCArray< Text > *list = new RCArray< Text >();
+        int anz = editorKlient->deGetModelListe( editor->zDateiAuswahl(), list );
+        if( anz < 0 )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            list->release();
+            break;
+        }
+        editor->setModel2dListe( list );
+        break;
+    }
+    case 9: // Model speichern
+    {
+        Model2DData *m = editor->getModelData();
+        if( !editorKlient->deModelSpeichern( editor->zDateiAuswahl(), editor->zModel2dAuswahl(), m, fort ) )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            m->release();
+            break;
+        }
+        editor->setModel2d( m );
+        break;
+    }
+    case 10: // Neues Model
+    {
+        Model2DData *m = new Model2DData();
+        m->erstelleModell( new Array< Polygon2D >() );
+        if( !editorKlient->deModelSpeichern( editor->zDateiAuswahl(), editor->zNeuModelName(), m, fort ) )
+        {
+            m->release();
+            break;
+        }
+        m->release();
+        RCArray< Text > *list = new RCArray< Text >();
+        int anz = editorKlient->deGetModelListe( editor->zDateiAuswahl(), list );
+        if( anz < 0 )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            list->release();
+            break;
+        }
+        editor->setModel2dListe( list );
+        break;
+    }
+    case 11: // Sound Abspielen
+    {
+        GSL::GSLSoundV *s = editorKlient->deSoundLaden( editor->zDateiAuswahl(), editor->zSoundAuswahl(), fort );
+        if( !s )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            break;
+        }
+        editor->setSound( s );
+        break;
+    }
+    case 12: // Sound Löschen
+    {
+        if( !editorKlient->deSoundLöschen( editor->zDateiAuswahl(), editor->zSoundAuswahl() ) )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            break;
+        }
+        RCArray< Text > *list = new RCArray< Text >();
+        int anz = editorKlient->deGetSoundListe( editor->zDateiAuswahl(), list );
+        if( anz < 0 )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            list->release();
+            break;
+        }
+        editor->setSoundListe( list );
+        break;
+    }
+    case 13: // Sound Importieren
+    {
+        Text *pfad = editor->zSoundImportPfad();
+        pfad->ersetzen( "\\", "/" );
+        Text *n = pfad->getTeilText( pfad->positionVon( "/", pfad->anzahlVon( "/" ) - 1 ) + 1 );
+        Text name = n->getText();
+        name.remove( ".wav" );
+        n->release();
+        WAVDatei *s = new WAVDatei();
+        if( !s->lade( pfad->getText() ) )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Fehler beim Lesen der Ausgewählten Datei." ), new Text( "Ok" ) );
+            s->release();
+            break;
+        }
+        if( !editorKlient->deSoundSpeichern( editor->zDateiAuswahl(), &name, s, fort ) )
+        {
+            s->release();
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            break;
+        }
+        s->release();
+        RCArray< Text > *list = new RCArray< Text >();
+        int anz = editorKlient->deGetSoundListe( editor->zDateiAuswahl(), list );
+        if( anz < 0 )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            list->release();
+            break;
+        }
+        editor->setSoundListe( list );
+        break;
+    }
+    }
+    laden->setSichtbar( 0 );
+    run = 0;
+    fort->reset();
+}
+
+void KEDateien::doMausEreignis( MausEreignis &me )
+{
+    if( !run )
+        fenster->doMausEreignis( me );
+}
+
+void KEDateien::doTastaturEreignis( TastaturEreignis &te )
+{
+    if( !run )
+        fenster->doTastaturEreignis( te );
+}
+
+bool KEDateien::tick( double z )
+{
+    fort->tick( z );
+    aktion = editor->getAktion();
+    if( aktion && !run )
+        start();
+    bool ret = laden->tick( z );
+    tickVal += z * 150;
+    int val = (int)tickVal;
+    tickVal -= val;
+    if( val )
+    {
+        if( run && alpha > 100 )
+        {
+            if( alpha - val < 100 )
+                alpha = 100;
+            else
+                alpha -= val;
+            ret = 1;
+        }
+        if( sichtbar && !run && alpha != 255 )
+        {
+            if( alpha + val > 255 )
+                alpha = 255;
+            else
+                alpha += val;
+            ret = 1;
+        }
+        val *= 3;
+        if( sichtbar )
+        {
+            if( alpha < 100 )
+            {
+                if( alpha + val > 100 )
+                    alpha = 100;
+                else
+                    alpha += val;
+                ret = 1;
+            }
+            if( xStart != 0 || breite != 900 )
+            {
+                if( rechts )
+                {
+                    if( xStart - val <= 0 )
+                    {
+                        xStart = 0;
+                        breite = 900;
+                        animation = 0;
+                        editor->setSichtbar( 1 );
+                    }
+                    else
+                    {
+                        xStart -= val;
+                        breite += val;
+                    }
+                }
+                else
+                {
+                    if( breite + val >= 900 )
+                    {
+                        breite = 900;
+                        animation = 0;
+                        editor->setSichtbar( 1 );
+                    }
+                    else
+                        breite += val;
+                }
+                ret = 1;
+            }
+        }
+        else
+        {
+            if( breite != 0 )
+            {
+                if( rechts )
+                {
+                    if( breite - val <= 0 )
+                    {
+                        breite = 0;
+                        animation = 0;
+                    }
+                    else
+                        breite -= val;
+                }
+                else
+                {
+                    if( breite - val <= 0 )
+                    {
+                        breite = 0;
+                        xStart = 900;
+                        animation = 0;
+                    }
+                    else
+                    {
+                        breite -= val;
+                        xStart += val;
+                    }
+                }
+                ret = 1;
+            }
+        }
+    }
+    return ret || fenster->tick( z );
+}
+
+void KEDateien::render( Bild &zRObj )
+{
+    if( !zRObj.setDrawOptions( xStart, 0, breite, 600 ) )
+        return;
+    zRObj.setAlpha( alpha );
+    fenster->render( zRObj );
+    zRObj.releaseAlpha();
+    laden->render( zRObj );
+    if( fort->getAktionAnzahl() && run )
+        fort->render( zRObj );
+    zRObj.releaseDrawOptions();
+}
+
+// constant
+bool KEDateien::istSichtbar() const
+{
+    return sichtbar || animation;
+}
+
+// Reference Counting
+KEDateien *KEDateien::getThis()
+{
+    ref++;
+    return this;
+}
+
+KEDateien *KEDateien::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 50 - 0
KSGClient/NachLogin/Editor/Karte/Dateien/KEDateien.h

@@ -0,0 +1,50 @@
+#pragma once
+
+#include <Fenster.h>
+#include <Thread.h>
+#include <Animation.h>
+#include <Liste.h>
+#include <Knopf.h>
+#include <Bild.h>
+#include "KEDEditor.h"
+#include <Fortschritt.h>
+
+using namespace Framework;
+
+class KEDateien : private Thread
+{
+private:
+    Fenster *fenster;
+    Animation2D *laden;
+    Schrift *schrift;
+    KEDEditor *editor;
+    FBalken *fort;
+    int aktion;
+    bool animation;
+    double tickVal;
+    bool sichtbar;
+    bool rechts;
+    int xStart;
+    int breite;
+    int karte;
+    unsigned char alpha;
+    int ref;
+
+public:
+    // Konstruktor
+    KEDateien( int karte, Schrift *zSchrift );
+    // Destruktor
+    ~KEDateien();
+    // nicht constant
+    void setSichtbar( bool s, bool vr );
+    void thread() override;
+    void doMausEreignis( MausEreignis &me );
+    void doTastaturEreignis( TastaturEreignis &te );
+    bool tick( double z );
+    void render( Bild &zRObj );
+    // constant
+    bool istSichtbar() const;
+    // Reference Counting
+    KEDateien *getThis();
+    KEDateien *release();
+};

+ 99 - 0
KSGClient/NachLogin/Editor/Karte/Dateien/WAVDatei.cpp

@@ -0,0 +1,99 @@
+#include "WAVDatei.h"
+#include <Text.h>
+#include <mmsystem.h>
+#include <Bild.h>
+#include <DateiSystem.h>
+
+bool istGleich( char *a, char *b, int l )
+{
+    bool ret = 1;
+    for( ; l > 0; --l, ++a, ++b )
+        ret &= *a == *b;
+    return ret;
+}
+
+// Inhalt der WAVDatei Klasse aus WAVDatei.h
+// Konstruktor
+WAVDatei::WAVDatei()
+{}
+
+// nicht constant
+bool WAVDatei::lade( char *pfad )
+{
+    d.setDatei( pfad );
+    if( !d.open( Datei::Style::lesen ) )
+        return 0;
+    d.lese( (char*)&kpf, sizeof( kpf ) );
+    if( !istGleich( kpf.riff, "RIFF", 4 ) )
+        return 0;
+    if( !istGleich( kpf.wav, "WAVE", 4 ) )
+        return 0;
+    d.lese( (char*)&fmt, sizeof( fmt ) );
+    if( !istGleich( fmt.fmt, "fmt ", 4 ) )
+        return 0;
+    if( fmt.channels > 2 || fmt.channels < 1 )
+        return 0;
+    if( fmt.tag != 1 )
+        return 0;
+    if( fmt.bitsPerSample != 16 )
+        return 0;
+    if( fmt.blockAlign * fmt.sampleRate != fmt.bytesPerSec )
+        return 0;
+    d.lese( (char*)&dBeg, sizeof( dBeg ) );
+    while( !istGleich( dBeg.data, "data", 4 ) )
+    {
+        d.setLPosition( 1 + d.getLPosition() - sizeof( dBeg ), 0 );
+        d.lese( (char*)&dBeg, sizeof( dBeg ) );
+    }
+    pos = (int)d.getLPosition();
+    d.close();
+    return 1;
+}
+
+// zum Speichern
+void WAVDatei::open()
+{
+    d.open( Datei::Style::lesen );
+    d.setLPosition( pos, 0 );
+}
+
+int WAVDatei::getDaten( char *buffer, int län )
+{
+    if( d.getLPosition() + län > d.getSize() )
+        län = (int)( d.getSize() - d.getLPosition() );
+    if( !län )
+        return -1;
+    d.lese( buffer, län );
+    return län;
+}
+
+void WAVDatei::close()
+{
+    d.close();
+}
+
+bool WAVDatei::istMono() const
+{
+    return fmt.channels == 1;
+}
+
+int WAVDatei::getSampleRate() const
+{
+    return fmt.sampleRate;
+}
+
+__int64 WAVDatei::getDatLength() const
+{
+    return d.getSize() - pos;
+}
+
+// Reference Counting
+GSL::GSLSoundV *WAVDatei::getThis()
+{
+    return this;
+}
+
+GSL::GSLSoundV *WAVDatei::release()
+{
+    return 0;
+}

+ 69 - 0
KSGClient/NachLogin/Editor/Karte/Dateien/WAVDatei.h

@@ -0,0 +1,69 @@
+#pragma once
+
+#include <GSLDateiV.h>
+#include <Datei.h>
+
+using namespace Framework;
+
+struct WAVKopf
+{
+    char riff[ 4 ];
+    unsigned int datGr;
+    char wav[ 4 ];
+};
+
+struct WAVFormat
+{
+    char fmt[ 4 ];
+    int fmtLän;
+    short tag;
+    unsigned short channels;
+    unsigned int sampleRate;
+    unsigned int bytesPerSec;
+    unsigned short blockAlign;
+    unsigned short bitsPerSample;
+};
+
+struct WAVDBeg
+{
+    char data[ 4 ];
+    int län;
+};
+
+class WAVDatei : public GSL::GSLSoundV
+{
+private:
+    WAVKopf kpf;
+    WAVFormat fmt;
+    WAVDBeg dBeg;
+    int pos;
+    Datei d;
+
+public:
+    // Konstruktor
+    WAVDatei();
+    // nicht constant
+    bool lade( char *pfad );
+    // 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;
+    int getDaten( char *buffer, int län ) override;
+    void close() override;
+    bool istMono() const override;
+    int getSampleRate() const override;
+    __int64 getDatLength() const override;
+    // Reference Counting
+    GSL::GSLSoundV *getThis() override;
+    GSL::GSLSoundV *release() override;
+};

+ 606 - 0
KSGClient/NachLogin/Editor/Karte/KartenEditor.cpp

@@ -0,0 +1,606 @@
+#include "KartenEditor.h"
+#include "../../../Global/Initialisierung.h"
+#include "../../../Global/Variablen.h"
+#include <KSGTDatei.h>
+
+typedef EditorV*( *DllStart )( );
+
+// Inhalt der KartenEditor Klasse aus KartenEditor.h
+// Konstruktor
+KartenEditor::KartenEditor( Schrift *schrift )
+{
+    this->schrift = schrift;
+    karteRelease = initKnopf( 10, 10, 100, 20, schrift, Knopf::Style::Sichtbar, "Karte Release" );
+    shopSeite = initKnopf( 120, 10, 100, 20, schrift, Knopf::Style::Sichtbar, "Shop Seite" );
+    beschreibung = initKnopf( 230, 10, 100, 20, schrift, Knopf::Style::Sichtbar, "Beschreibung" );
+    teams = initKnopf( 340, 10, 100, 20, schrift, Knopf::Style::Sichtbar, "Teams" );
+    dateien = initKnopf( 450, 10, 100, 20, schrift, Knopf::Style::Sichtbar, "Dateien" );
+    editor = initKnopf( 560, 10, 100, 20, schrift, Knopf::Style::Sichtbar, "Editor" );
+    kaufHistorie = initKnopf( 670, 10, 100, 20, schrift, Knopf::Style::Sichtbar, "Kauf Historie" );
+    beenden = initKnopf( 790, 10, 100, 20, schrift, Knopf::Style::Sichtbar, "Beenden" );
+    laden = (Animation2D*)ladeAnimation->dublizieren();
+    laden->setPosition( 425, 275 );
+    laden->setSichtbar( 0 );
+    tickVal = 0;
+    jetzt = 0;
+    releaseF = 0;
+    shopSeiteF = 0;
+    beschreibungF = 0;
+    teamsF = 0;
+    dateienF = 0;
+    alpha = 0;
+    alpha2 = 0;
+    sichtbar = 0;
+    editorDll = 0;
+    editorF = 0;
+    dllName = "";
+    ref = 1;
+}
+
+// Destruktor
+KartenEditor::~KartenEditor()
+{
+    if( run )
+    {
+        warteAufThread( 5000 );
+        if( run )
+            ende();
+    }
+    schrift->release();
+    karteRelease->release();
+    shopSeite->release();
+    beschreibung->release();
+    teams->release();
+    dateien->release();
+    editor->release();
+    kaufHistorie->release();
+    beenden->release();
+    laden->release();
+    if( releaseF )
+        releaseF->release();
+    if( shopSeiteF )
+        shopSeiteF->release();
+    if( beschreibungF )
+        beschreibungF->release();
+    if( teamsF )
+        teamsF->release();
+    if( dateienF )
+        dateienF->release();
+    if( editorF )
+        editorF->release();
+    if( editorDll )
+        dllDateien->releaseDLL( dllName );
+}
+
+// nicht constant
+void KartenEditor::thread()
+{
+    laden->setSichtbar( 1 );
+    if( !editorKlient->initEditor() )
+    {
+        editor->setAlphaFeldFarbe( 0x5500FF00 );
+        editor->removeStyle( Knopf::Style::Erlaubt );
+        nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+        laden->setSichtbar( 0 );
+        run = 0;
+        return;
+    }
+    nachLogin->setEditor( editorF->getThis() );
+    aktion = 9;
+    laden->setSichtbar( 0 );
+}
+
+void KartenEditor::setKarte( int id )
+{
+    jetzt = 0;
+    hauptScreen->lock();
+    if( releaseF )
+        releaseF->release();
+    if( shopSeiteF )
+        shopSeiteF->release();
+    if( beschreibungF )
+        beschreibungF->release();
+    if( teamsF )
+        teamsF->release();
+    if( editorF )
+        editorF->release();
+    if( editorDll )
+        dllDateien->releaseDLL( dllName );
+    releaseF = new KERelease( id, schrift );
+    releaseF->setSichtbar( 1, 0 );
+    karteRelease->setAlphaFeldFarbe( 0x0000FF00 );
+    shopSeite->setAlphaFeldFarbe( 0x5500FF00 );
+    beschreibung->setAlphaFeldFarbe( 0x5500FF00 );
+    teams->setAlphaFeldFarbe( 0x5500FF00 );
+    dateien->setAlphaFeldFarbe( 0x5500FF00 );
+    editor->setAlphaFeldFarbe( 0x5500FF00 );
+    kaufHistorie->setAlphaFeldFarbe( 0x5500FF00 );
+    jetzt = 1;
+    shopSeiteF = new KEShopSeite( id, schrift );
+    beschreibungF = new KEBeschreibung( id, schrift );
+    teamsF = new KETeams( id, schrift );
+    dateienF = new KEDateien( id, schrift );
+    // Editor laden
+    int spielArt = infoKlient->getSpielId( id );
+    KSGTDatei *dgt = new KSGTDatei( "data/dg.ksgt" );
+    dgt->laden();
+    bool sak = 0;
+    int dgSId = infoKlient->getDateiGruppeIdVonSpiel( spielArt );
+    bool sgf = 0;
+    for( int i = 0; i < dgt->getZeilenAnzahl(); i++ )
+    {
+        if( dgt->zFeld( i, 0 ) && TextZuInt( dgt->zFeld( i, 0 )->getText(), 10 ) == dgSId )
+        {
+            sgf = 1;
+            int lv = dgt->zFeld( i, 2 ) ? TextZuInt( dgt->zFeld( i, 2 )->getText(), 10 ) : 0;
+            int ov = infoKlient->getSpielVersion( spielArt );
+            if( lv == ov )
+            {
+                sak = 1;
+                break;
+            }
+        }
+    }
+    dgt->release();
+    if( !sak )
+    {
+        nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Deine Spiel Version ist nicht aktuell. Sie wird beim nächsten Spielstart aktualisiert. Bis dahin sind nicht alle Editorfunktionen verfügbar." ), new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+        if( !sgf )
+        {
+            Text *pfad = infoKlient->getDateiGruppePfad( dgSId );
+            Text *idT = new Text();
+            idT->append( dgSId );
+            if( pfad )
+            {
+                KSGTDatei *dg = new KSGTDatei( "data/dg.ksgt" );
+                dg->laden();
+                RCArray< Text > *zeile = new RCArray< Text >();
+                zeile->add( idT );
+                zeile->add( pfad );
+                zeile->add( new Text( "0" ) );
+                zeile->add( new Text( "0" ) );
+                dg->addZeile( 4, zeile );
+                zeile->release();
+                dg->speichern();
+                dg->release();
+            }
+            else
+                idT->release();
+        }
+    }
+    else
+    {
+        Text pfad = "data/spiele/";
+        dllName = "";
+        dllName.append( infoKlient->getSpielName( spielArt ) );
+        pfad.append( dllName.getText() );
+        pfad.append( "/bin/" );
+        dllName.append( ".dll" );
+        pfad.append( dllName.getText() );
+        editorDll = dllDateien->ladeDLL( dllName, pfad );
+        if( !editorDll )
+        {
+            editor->removeStyle( Knopf::Style::Erlaubt );
+            Text *err = new Text( "Fehler beim laden der Dll Datei '" );
+            err->append( pfad.getText() );
+            err->append( "'. Es stehen nicht alle Editorfunktionen zur verfügung." );
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), err, new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+        }
+        else
+        {
+            DllStart getEditorKlasse = (DllStart)GetProcAddress( editorDll, "getEditor" );
+            if( !getEditorKlasse )
+            {
+                editor->removeStyle( Knopf::Style::Erlaubt );
+                Text *err = new Text( "Der Einstiegspunkt 'getEditor' wurde in der Dll Datei '" );
+                err->append( pfad.getText() );
+                err->append( "' nicht gefunden. Es stehen nicht alle Editorfunktionen zur verfügung." );
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), err, new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+            }
+            else
+            {
+                editor->addStyle( Knopf::Style::Erlaubt );
+                editorF = getEditorKlasse();
+                editorF->setSchrift( schrift->getThis() );
+                editorF->setKlient( editorKlient->getThis() );
+                editorF->setLadeAnimation( (Animation2D*)ladeAnimation->dublizieren() );
+                editor->addStyle( Knopf::Style::Sichtbar );
+            }
+        }
+    }
+    //-------------------------
+    hauptScreen->unlock();
+}
+
+void KartenEditor::setSichtbar( bool s )
+{
+    sichtbar = s;
+}
+
+void KartenEditor::doMausEreignis( MausEreignis &me )
+{
+    if( run )
+        return;
+    int aktion = 0;
+    bool vera = me.verarbeitet;
+    karteRelease->doMausEreignis( me );
+    if( !vera && me.verarbeitet )
+        aktion = 1;
+    vera = me.verarbeitet;
+    shopSeite->doMausEreignis( me );
+    if( !vera && me.verarbeitet )
+        aktion = 2;
+    vera = me.verarbeitet;
+    beschreibung->doMausEreignis( me );
+    if( !vera && me.verarbeitet )
+        aktion = 3;
+    vera = me.verarbeitet;
+    teams->doMausEreignis( me );
+    if( !vera && me.verarbeitet )
+        aktion = 4;
+    vera = me.verarbeitet;
+    dateien->doMausEreignis( me );
+    if( !vera && me.verarbeitet )
+        aktion = 5;
+    vera = me.verarbeitet;
+    editor->doMausEreignis( me );
+    if( !vera && me.verarbeitet )
+        aktion = 6;
+    vera = me.verarbeitet;
+    kaufHistorie->doMausEreignis( me );
+    if( !vera && me.verarbeitet )
+        aktion = 7;
+    vera = me.verarbeitet;
+    beenden->doMausEreignis( me );
+    if( !vera && me.verarbeitet )
+        aktion = 8;
+    if( me.id == ME_RLinks && aktion )
+    {
+        switch( aktion )
+        {
+        case 1: // Release
+            if( releaseF && !releaseF->istSichtbar() )
+            {
+                if( shopSeiteF && shopSeiteF->istSichtbar() )
+                {
+                    shopSeite->setAlphaFeldFarbe( 0x5500FF00 );
+                    releaseF->setSichtbar( 1, 0 );
+                    shopSeiteF->setSichtbar( 0, 0 );
+                }
+                if( beschreibungF && beschreibungF->istSichtbar() )
+                {
+                    beschreibung->setAlphaFeldFarbe( 0x5500FF00 );
+                    releaseF->setSichtbar( 1, 0 );
+                    beschreibungF->setSichtbar( 0, 0 );
+                }
+                if( teamsF && teamsF->istSichtbar() )
+                {
+                    teams->setAlphaFeldFarbe( 0x5500FF00 );
+                    releaseF->setSichtbar( 1, 0 );
+                    teamsF->setSichtbar( 0, 0 );
+                }
+                if( dateienF && dateienF->istSichtbar() )
+                {
+                    dateien->setAlphaFeldFarbe( 0x5500FF00 );
+                    releaseF->setSichtbar( 1, 0 );
+                    dateienF->setSichtbar( 0, 0 );
+                }
+                //-------------
+                karteRelease->setAlphaFeldFarbe( 0x0000FF00 );
+                jetzt = 1;
+            }
+            break;
+        case 2: // Shop Seite
+            if( shopSeiteF && !shopSeiteF->istSichtbar() )
+            {
+                if( releaseF && releaseF->istSichtbar() )
+                {
+                    karteRelease->setAlphaFeldFarbe( 0x5500FF00 );
+                    shopSeiteF->setSichtbar( 1, 1 );
+                    releaseF->setSichtbar( 0, 1 );
+                }
+                if( beschreibungF && beschreibungF->istSichtbar() )
+                {
+                    beschreibung->setAlphaFeldFarbe( 0x5500FF00 );
+                    shopSeiteF->setSichtbar( 1, 0 );
+                    beschreibungF->setSichtbar( 0, 0 );
+                }
+                if( teamsF && teamsF->istSichtbar() )
+                {
+                    teams->setAlphaFeldFarbe( 0x5500FF00 );
+                    shopSeiteF->setSichtbar( 1, 0 );
+                    teamsF->setSichtbar( 0, 0 );
+                }
+                if( dateienF && dateienF->istSichtbar() )
+                {
+                    dateien->setAlphaFeldFarbe( 0x5500FF00 );
+                    shopSeiteF->setSichtbar( 1, 0 );
+                    dateienF->setSichtbar( 0, 0 );
+                }
+                //---------------
+                shopSeite->setAlphaFeldFarbe( 0x0000FF00 );
+                jetzt = 2;
+            }
+            break;
+        case 3: // Beschreibung
+            if( beschreibungF && !beschreibungF->istSichtbar() )
+            {
+                if( releaseF && releaseF->istSichtbar() )
+                {
+                    karteRelease->setAlphaFeldFarbe( 0x5500FF00 );
+                    beschreibungF->setSichtbar( 1, 1 );
+                    releaseF->setSichtbar( 0, 1 );
+                }
+                if( shopSeiteF && shopSeiteF->istSichtbar() )
+                {
+                    shopSeite->setAlphaFeldFarbe( 0x5500FF00 );
+                    beschreibungF->setSichtbar( 1, 1 );
+                    shopSeiteF->setSichtbar( 0, 1 );
+                }
+                if( teamsF && teamsF->istSichtbar() )
+                {
+                    teams->setAlphaFeldFarbe( 0x5500FF00 );
+                    beschreibungF->setSichtbar( 1, 0 );
+                    teamsF->setSichtbar( 0, 0 );
+                }
+                if( dateienF && dateienF->istSichtbar() )
+                {
+                    dateien->setAlphaFeldFarbe( 0x5500FF00 );
+                    beschreibungF->setSichtbar( 1, 0 );
+                    dateienF->setSichtbar( 0, 0 );
+                }
+                //---------------
+                beschreibung->setAlphaFeldFarbe( 0x0000FF00 );
+                jetzt = 3;
+            }
+            break;
+        case 4: // Teams
+            if( teamsF && !teamsF->istSichtbar() )
+            {
+                if( releaseF && releaseF->istSichtbar() )
+                {
+                    karteRelease->setAlphaFeldFarbe( 0x5500FF00 );
+                    teamsF->setSichtbar( 1, 1 );
+                    releaseF->setSichtbar( 0, 1 );
+                }
+                if( shopSeiteF && shopSeiteF->istSichtbar() )
+                {
+                    shopSeite->setAlphaFeldFarbe( 0x5500FF00 );
+                    teamsF->setSichtbar( 1, 1 );
+                    shopSeiteF->setSichtbar( 0, 1 );
+                }
+                if( beschreibungF && beschreibungF->istSichtbar() )
+                {
+                    beschreibung->setAlphaFeldFarbe( 0x5500FF00 );
+                    teamsF->setSichtbar( 1, 1 );
+                    beschreibungF->setSichtbar( 0, 1 );
+                }
+                if( dateienF && dateienF->istSichtbar() )
+                {
+                    dateien->setAlphaFeldFarbe( 0x5500FF00 );
+                    teamsF->setSichtbar( 1, 0 );
+                    dateienF->setSichtbar( 0, 0 );
+                }
+                //---------------
+                teams->setAlphaFeldFarbe( 0x0000FF00 );
+                jetzt = 4;
+            }
+            break;
+        case 5: // Dateien
+            if( dateienF && !dateienF->istSichtbar() )
+            {
+                if( releaseF && releaseF->istSichtbar() )
+                {
+                    karteRelease->setAlphaFeldFarbe( 0x5500FF00 );
+                    dateienF->setSichtbar( 1, 1 );
+                    releaseF->setSichtbar( 0, 1 );
+                }
+                if( shopSeiteF && shopSeiteF->istSichtbar() )
+                {
+                    shopSeite->setAlphaFeldFarbe( 0x5500FF00 );
+                    dateienF->setSichtbar( 1, 1 );
+                    shopSeiteF->setSichtbar( 0, 1 );
+                }
+                if( beschreibungF && beschreibungF->istSichtbar() )
+                {
+                    beschreibung->setAlphaFeldFarbe( 0x5500FF00 );
+                    dateienF->setSichtbar( 1, 1 );
+                    beschreibungF->setSichtbar( 0, 1 );
+                }
+                if( teamsF && teamsF->istSichtbar() )
+                {
+                    teams->setAlphaFeldFarbe( 0x5500FF00 );
+                    dateienF->setSichtbar( 1, 1 );
+                    teamsF->setSichtbar( 0, 1 );
+                }
+                //---------------
+                dateien->setAlphaFeldFarbe( 0x0000FF00 );
+                jetzt = 5;
+            }
+            break;
+        case 6: // Editor
+            if( editor )
+                start();
+            break;
+        case 7:
+            //---------------
+            break;
+        case 8:
+            setSichtbar( 0 );
+            break;
+        }
+    }
+    switch( jetzt )
+    {
+    case 1:
+        releaseF->doMausEreignis( me );
+        break;
+    case 2:
+        shopSeiteF->doMausEreignis( me );
+        break;
+    case 3:
+        beschreibungF->doMausEreignis( me );
+        break;
+    case 4:
+        teamsF->doMausEreignis( me );
+        break;
+    case 5:
+        dateienF->doMausEreignis( me );
+        break;
+        //---------------
+    }
+}
+
+void KartenEditor::doTastaturEreignis( TastaturEreignis &te )
+{
+    if( run )
+        return;
+    switch( jetzt )
+    {
+    case 1:
+        releaseF->doTastaturEreignis( te );
+        break;
+    case 2:
+        shopSeiteF->doTastaturEreignis( te );
+        break;
+    case 3:
+        beschreibungF->doTastaturEreignis( te );
+        break;
+    case 4:
+        teamsF->doTastaturEreignis( te );
+        break;
+    case 5:
+        dateienF->doTastaturEreignis( te );
+        break;
+        //---------------
+    }
+}
+
+bool KartenEditor::tick( double zeit )
+{
+    bool ret = karteRelease->tick( zeit );
+    ret |= laden->tick( zeit );
+    ret |= shopSeite->tick( zeit );
+    ret |= beschreibung->tick( zeit );
+    ret |= teams->tick( zeit );
+    ret |= dateien->tick( zeit );
+    ret |= editor->tick( zeit );
+    ret |= kaufHistorie->tick( zeit );
+    ret |= beenden->tick( zeit );
+    if( releaseF && releaseF->istSichtbar() )
+        ret |= releaseF->tick( zeit );
+    if( shopSeiteF && shopSeiteF->istSichtbar() )
+        ret |= shopSeiteF->tick( zeit );
+    if( beschreibungF && beschreibungF->istSichtbar() )
+        ret |= beschreibungF->tick( zeit );
+    if( teamsF && teamsF->istSichtbar() )
+        ret |= teamsF->tick( zeit );
+    if( dateienF && dateienF->istSichtbar() )
+        ret |= dateienF->tick( zeit );
+    tickVal += zeit * 150;
+    int val = (int)tickVal;
+    if( val < 1 )
+        return ret;
+    if( sichtbar && run )
+    {
+        if( alpha != 100 )
+        {
+            if( alpha > 100 )
+            {
+                if( alpha - val <= 100 )
+                    alpha = 100;
+                else
+                    alpha -= val;
+            }
+            if( alpha < 100 )
+            {
+                if( alpha + val >= 100 )
+                    alpha = 100;
+                else
+                    alpha += val;
+            }
+        }
+        if( alpha2 != 255 )
+        {
+            if( alpha2 + val >= 255 )
+                alpha2 = 255;
+            else
+                alpha2 += val;
+        }
+    }
+    else
+    {
+        if( sichtbar && alpha != 255 )
+        {
+            if( alpha + val >= 255 )
+                alpha = 255;
+            else
+                alpha += val;
+        }
+        if( !sichtbar && alpha )
+        {
+            if( alpha - val <= 0 )
+                alpha = 0;
+            else
+                alpha -= val;
+        }
+        if( alpha2 )
+        {
+            if( alpha2 - val <= 0 )
+                alpha2 = 0;
+            else
+                alpha2 -= val;
+        }
+    }
+    return ret;
+}
+
+void KartenEditor::render( Bild &zRObj )
+{
+    if( !alpha )
+        return;
+    zRObj.setAlpha( alpha2 );
+    laden->render( zRObj );
+    zRObj.releaseAlpha();
+    zRObj.setAlpha( alpha );
+    karteRelease->render( zRObj );
+    shopSeite->render( zRObj );
+    beschreibung->render( zRObj );
+    teams->render( zRObj );
+    dateien->render( zRObj );
+    editor->render( zRObj );
+    kaufHistorie->render( zRObj );
+    beenden->render( zRObj );
+    if( releaseF )
+        releaseF->render( zRObj );
+    if( shopSeiteF )
+        shopSeiteF->render( zRObj );
+    if( beschreibungF )
+        beschreibungF->render( zRObj );
+    if( teamsF )
+        teamsF->render( zRObj );
+    if( dateienF )
+        dateienF->render( zRObj );
+    zRObj.releaseAlpha();
+}
+
+// constant
+bool KartenEditor::istSichtbar() const
+{
+    return sichtbar;
+}
+
+// Reference Counting
+KartenEditor *KartenEditor::getThis()
+{
+    ref++;
+    return this;
+}
+
+KartenEditor *KartenEditor::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 64 - 0
KSGClient/NachLogin/Editor/Karte/KartenEditor.h

@@ -0,0 +1,64 @@
+#ifndef KartenEditor_H
+#define KartenEditor_H
+
+#include <EditorV.h>
+#include "Release/KERelease.h"
+#include "ShopSeite/KEShopSeite.h"
+#include "Beschreibung\KEBeschreibung.h"
+#include "Teams/KETeams.h"
+#include "Dateien/KEDateien.h"
+#include <Schrift.h>
+#include <MausEreignis.h>
+#include <Knopf.h>
+
+using namespace Framework;
+
+class KartenEditor : private Thread
+{
+private:
+	Schrift *schrift;
+	Knopf *karteRelease;
+	Knopf *shopSeite;
+	Knopf *beschreibung;
+	Knopf *teams;
+	Knopf *dateien;
+	Knopf *editor;
+	Knopf *kaufHistorie;
+	Knopf *beenden;
+	KERelease *releaseF;
+    KEShopSeite *shopSeiteF;
+    KEBeschreibung *beschreibungF;
+    KETeams *teamsF;
+    KEDateien *dateienF;
+    EditorV *editorF;
+    HINSTANCE editorDll;
+    Text dllName;
+    Animation2D *laden;
+	double tickVal;
+	int jetzt;
+	unsigned char alpha;
+    unsigned char alpha2;
+	bool sichtbar;
+	int ref;
+
+public:
+	// Konstruktor
+	KartenEditor( Schrift *schrift );
+	// Destruktor
+	~KartenEditor();
+	// nicht constant
+    void thread() override;
+	void setKarte( int id );
+	void setSichtbar( bool s );
+	void doMausEreignis( MausEreignis &me );
+	void doTastaturEreignis( TastaturEreignis &te );
+	bool tick( double zeit );
+	void render( Bild &zRObj );
+	// constant
+	bool istSichtbar() const;
+	// Reference Counting
+	KartenEditor *getThis();
+	KartenEditor *release();
+};
+
+#endif;

+ 721 - 0
KSGClient/NachLogin/Editor/Karte/ShopSeite/KESSEditor.cpp

@@ -0,0 +1,721 @@
+#include "KESSEditor.h"
+#include "KEShopSeite.h"
+#include "../../../../Global/Initialisierung.h"
+#include <MausEreignis.h>
+#include <Text.h>
+#include "../../../../Global/Variablen.h"
+#include <DateiSystem.h>
+
+// Inhalt der KESSTextSeite Klasse aus KESSEditor.h
+// Konstruktor
+KESSTextSeite::KESSTextSeite( Schrift *zSchrift, Knopf *zNeueDatei, Knopf *zDateiRemove )
+{
+    LTDSDatei *sd = new LTDSDatei();
+    sd->setPfad( new Text( "data/schriften/ksgs.ltds" ) );
+    sd->leseDaten();
+    Schrift *ksgsS = sd->ladeSchrift();
+    sd->release();
+    text = initTextFeld( 220, 10, 540, 510, ksgsS ? ksgsS : zSchrift, TextFeld::Style::TextGebiet | TextFeld::Style::HScroll, "" );
+    if( ksgsS )
+        ksgsS->release();
+    speichern = initKnopf( 770, 10, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Speichern" );
+    dateiLöschen = zDateiRemove->getThis();
+    neueDatei = zNeueDatei->getThis();
+    aktion = 0;
+    sichtbar = 0;
+    alpha = 0;
+    tickVal = 0;
+    ref = 1;
+}
+
+// Destruktor
+KESSTextSeite::~KESSTextSeite()
+{
+    text->release();
+    speichern->release();
+    dateiLöschen->release();
+    neueDatei->release();
+}
+
+// nicht constant
+int KESSTextSeite::getAktion()
+{
+    int ret = aktion;
+    aktion = 0;
+    return ret;
+}
+
+void KESSTextSeite::setDateiText( Text *txt )
+{
+    text->setText( txt );
+}
+
+void KESSTextSeite::setSichtbar( bool s )
+{
+    sichtbar = s;
+}
+
+bool KESSTextSeite::tick( double tv )
+{
+    bool ret = text->tick( tv );
+    ret |= speichern->tick( tv );
+    ret |= dateiLöschen->tick( tv );
+    ret |= neueDatei->tick( tv );
+    tickVal += tv * 150;
+    int val = 0;
+    if( tickVal > 1 )
+        val = (int)tickVal;
+    else
+        return ret;
+    if( sichtbar && alpha != 255 )
+    {
+        if( alpha + val > 255 )
+            alpha = 255;
+        else
+            alpha += val;
+        ret = 1;
+    }
+    if( !sichtbar && alpha != 0 )
+    {
+        if( alpha - val < 0 )
+            alpha = 0;
+        else
+            alpha -= val;
+        ret = 1;
+    }
+    return ret;
+}
+
+void KESSTextSeite::doMausEreignis( MausEreignis &me )
+{
+    if( !sichtbar )
+        return;
+    text->doMausEreignis( me );
+    bool vera = me.verarbeitet;
+    speichern->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+        aktion = 1;
+    vera = me.verarbeitet;
+    dateiLöschen->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+        aktion = 2;
+    vera = me.verarbeitet;
+    neueDatei->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+        aktion = 3;
+}
+
+void KESSTextSeite::doTastaturEreignis( TastaturEreignis &te )
+{
+    if( !sichtbar )
+        return;
+    text->doTastaturEreignis( te );
+}
+
+void KESSTextSeite::render( Bild &zRObj )
+{
+    if( !alpha )
+        return;
+    zRObj.setAlpha( alpha );
+    text->render( zRObj );
+    speichern->render( zRObj );
+    neueDatei->setPosition( 770, 70 );
+    neueDatei->render( zRObj );
+    dateiLöschen->setPosition( 770, 40 );
+    dateiLöschen->render( zRObj );
+    zRObj.releaseAlpha();
+}
+
+// constant
+Text *KESSTextSeite::zDateiText() const
+{
+    return text->zText();
+}
+
+// Reference Counting 
+KESSTextSeite *KESSTextSeite::getThis()
+{
+    ref++;
+    return this;
+}
+
+KESSTextSeite *KESSTextSeite::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+
+// Inhalt der KESSBildSeite Klasse aus KESSEditor.h
+// Konstruktor
+KESSBildSeite::KESSBildSeite( Schrift *zSchrift, Knopf *zNeueDatei, Knopf *zDateiRemove )
+{
+    bilder = initAuswahlListe( 220, 10, 200, 510, zSchrift, AuswahlListe::Style::Normal, {} );
+    bildObj = initBildZ( 430, 10, 440, 440, BildZ::Style::normal | BildZ::Style::Alpha, 0 );
+    bildLöschen = initKnopf( 430, 460, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Bild Löschen" );
+    importieren = initKnopf( 430, 490, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Importieren" );
+    dateiLöschen = zDateiRemove->getThis();
+    neueDatei = zNeueDatei->getThis();
+    importDialog = 0;
+    importPfad = 0;
+    aktion = 0;
+    sichtbar = 0;
+    alpha = 0;
+    alpha2 = 0;
+    tickVal = 0;
+    ref = 1;
+}
+
+// Destruktor
+KESSBildSeite::~KESSBildSeite()
+{
+    bilder->release();
+    bildObj->release();
+    bildLöschen->release();
+    importieren->release();
+    dateiLöschen->release();
+    neueDatei->release();
+    if( importDialog )
+        importDialog->release();
+    if( importPfad )
+        importPfad->release();
+}
+
+// nicht constant
+int KESSBildSeite::getAktion()
+{
+    int ret = aktion;
+    aktion = 0;
+    return ret;
+}
+
+void KESSBildSeite::setBildListe( RCArray< Text > *list )
+{
+    hauptScreen->lock();
+    Text txt = bilder->zEintrag( bilder->getAuswahl() ) ? bilder->zEintrag( bilder->getAuswahl() )->zText()->getText() : "";
+    while( bilder->getEintragAnzahl() )
+        bilder->removeEintrag( 0 );
+    int anz = list->getEintragAnzahl();
+    int ausw = -1;
+    for( int i = 0; i < anz; i++ )
+    {
+        if( list->z( i )->istGleich( txt ) )
+            ausw = i;
+        bilder->addEintrag( list->get( i ) );
+    }
+    if( ausw >= 0 )
+        bilder->setAuswahl( ausw );
+    else
+        bilder->deSelect();
+    list->release();
+    hauptScreen->unlock();
+}
+
+void KESSBildSeite::setBild( Bild *b )
+{
+    hauptScreen->lock();
+    bildObj->setBild( b );
+    hauptScreen->unlock();
+}
+
+void KESSBildSeite::setSichtbar( bool s )
+{
+    sichtbar = s;
+}
+
+bool KESSBildSeite::tick( double tv )
+{
+    if( importDialog )
+    {
+        if( !importDialog->isRunning() )
+        {
+            if( importPfad )
+                importPfad->release();
+            importPfad = importDialog->getPfad();
+            importDialog = importDialog->release();
+            if( sichtbar && importPfad )
+                aktion = 3;
+        }
+    }
+    bool ret = bilder->tick( tv );
+    ret |= bildObj->tick( tv );
+    ret |= bildLöschen->tick( tv );
+    ret |= importieren->tick( tv );
+    ret |= dateiLöschen->tick( tv );
+    ret |= neueDatei->tick( tv );
+    tickVal += tv * 150;
+    int val = 0;
+    if( tickVal > 1 )
+        val = (int)tickVal;
+    else
+        return ret;
+    if( sichtbar && alpha != 255 )
+    {
+        if( alpha + val > 255 )
+            alpha = 255;
+        else
+            alpha += val;
+        ret = 1;
+    }
+    if( !sichtbar && alpha != 0 )
+    {
+        if( alpha - val < 0 )
+            alpha = 0;
+        else
+            alpha -= val;
+        ret = 1;
+    }
+    if( sichtbar && bilder->getAuswahl() >= 0 && alpha2 != 255 )
+    {
+        if( alpha2 + val > 255 )
+            alpha2 = 255;
+        else
+            alpha2 += val;
+        ret = 1;
+    }
+    if( ( !sichtbar || bilder->getAuswahl() < 0 ) && alpha2 != 0 )
+    {
+        if( alpha2 - val < 0 )
+            alpha2 = 0;
+        else
+            alpha2 -= val;
+        ret = 1;
+    }
+    return ret;
+}
+
+void KESSBildSeite::doMausEreignis( MausEreignis &me )
+{
+    if( !sichtbar )
+        return;
+    int ausw = bilder->getAuswahl();
+    bilder->doMausEreignis( me );
+    if( ausw != bilder->getAuswahl() && me.id == ME_RLinks )
+    {
+        if( bilder->getAuswahl() >= 0 )
+            aktion = 1;
+        else
+            bilder->setAuswahl( ausw );
+    }
+    bool vera = me.verarbeitet;
+    dateiLöschen->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+        aktion = 4;
+    vera = me.verarbeitet;
+    neueDatei->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+        aktion = 5;
+    vera = me.verarbeitet;
+    importieren->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+    {
+        if( !importDialog )
+        {
+            importDialog = new DateiDialogTh();
+            importDialog->setOpen( 1 );
+            importDialog->setDateiTypAuswahl( 4 );
+            importDialog->addDateiTyp( "JPEG-Bild", "*.jpg;*.jpeg;*.jpe" );
+            importDialog->addDateiTyp( "GIF-Bild", "*.gif" );
+            importDialog->addDateiTyp( "PNG-Bild", "*.png" );
+            importDialog->addDateiTyp( "Alle Dateien", "*.*" );
+            importDialog->start();
+        }
+    }
+    if( bilder->getAuswahl() < 0 )
+        return;
+    bildObj->doMausEreignis( me );
+    vera = me.verarbeitet;
+    bildLöschen->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+        aktion = 2;
+}
+
+void KESSBildSeite::render( Bild &zRObj )
+{
+    if( !alpha )
+        return;
+    zRObj.setAlpha( alpha );
+    bilder->render( zRObj );
+    neueDatei->setPosition( 540, 490 );
+    neueDatei->render( zRObj );
+    dateiLöschen->setPosition( 540, 460 );
+    dateiLöschen->render( zRObj );
+    importieren->render( zRObj );
+    zRObj.setAlpha( alpha2 );
+    bildObj->render( zRObj );
+    bildLöschen->render( zRObj );
+    zRObj.releaseAlpha();
+    zRObj.releaseAlpha();
+}
+
+// constant
+Text *KESSBildSeite::zBildImportPfad() const
+{
+    return importPfad;
+}
+
+Text *KESSBildSeite::zBildAuswahl() const
+{
+    if( !bilder->zEintrag( bilder->getAuswahl() ) )
+        return 0;
+    return bilder->zEintrag( bilder->getAuswahl() )->zText();
+}
+
+// Reference Counting
+KESSBildSeite *KESSBildSeite::getThis()
+{
+    ref++;
+    return this;
+}
+
+KESSBildSeite *KESSBildSeite::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+
+bool kESSEditorNeuDateiOkME( void *p, void *obj, MausEreignis me )
+{
+    if( p )
+        return ( (KESSEditor*)p )->neuDateiOkME( me );
+    else if( me.id == ME_RLinks )
+        ( (Fenster*)obj )->removeStyle( Fenster::Style::Sichtbar );
+    return 1;
+}
+
+
+// Inhalt der KESSEditor Klasse aus KESSEditor.h
+// Konstruktor
+KESSEditor::KESSEditor( Schrift *zSchrift )
+    : Zeichnung()
+{
+    neueDatei = initKnopf( 0, 0, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Neue Datei" );
+    dateiLöschen = initKnopf( 0, 0, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Datei Löschen" );
+    dateien = initAuswahlListe( 10, 10, 200, 510, zSchrift, AuswahlListe::Style::Normal, {} );
+    textSeite = new KESSTextSeite( zSchrift, neueDatei, dateiLöschen );
+    bildSeite = new KESSBildSeite( zSchrift, neueDatei, dateiLöschen );
+    vorschau = initKnopf( 770, 470, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Vorschau" );
+    veröffentlichen = initKnopf( 770, 500, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Fertig" );
+    initToolTip( veröffentlichen, "Veröffentlicht die geänderte Version der Shop-Seite.", zSchrift->getThis(), hauptScreen );
+    neuDateiF = initFenster( 365, 145, 150, 120, zSchrift, Fenster::Style::Erlaubt | Fenster::Style::BodyHintergrund | Fenster::Style::BodyHAlpha |
+                             Fenster::Style::Rahmen | Fenster::Style::Closable | Fenster::Style::ClosingKlickBuffer | Fenster::Style::ClosingHintergrund |
+                             Fenster::Style::ClosingHAlpha | Fenster::Style::Titel | Fenster::Style::TitelHintergrund | Fenster::Style::TitelHAlpha | Fenster::Style::TitelBuffered, "Neue Datei" );
+    neuDateiF->setKBgFarbe( 0xC0000000 );
+    neuDateiF->setSBgFarbe( 0xC0000000 );
+    neuDateiF->setTBgFarbe( 0xC0000000 );
+    neuDateiF->setClosingMe( kESSEditorNeuDateiOkME );
+    neuDateiTyp = initAuswahlBox( 10, 10, 130, 20, zSchrift, ABSTYLE, { "Ordner", "Bild (.ltdb)", "Script (.ksgs)" } );
+    neuDateiName = initTextFeld( 10, 40, 130, 20, zSchrift, TextFeld::Style::TextFeld, "Datei Name" );
+    neuDateiOk = initKnopf( 25, 70, 100, 20, zSchrift, Knopf::Style::Normal | Knopf::Style::Sichtbar, "Erstellen" );
+    neuDateiOk->setMausEreignisParameter( this );
+    neuDateiOk->setMausEreignis( kESSEditorNeuDateiOkME );
+    neuDateiF->addMember( neuDateiName );
+    neuDateiF->addMember( neuDateiOk );
+    neuDateiF->addMember( neuDateiTyp );
+    aktion = 0;
+    sichtbar = 0;
+    alpha = 0;
+    alpha2 = 0;
+    tickVal = 0;
+    ref = 1;
+}
+
+// Destruktor
+KESSEditor::~KESSEditor()
+{
+    dateien->release();
+    textSeite->release();
+    bildSeite->release();
+    vorschau->release();
+    veröffentlichen->release();
+    neuDateiF->release();
+    neuDateiTyp->release();
+    neuDateiName->release();
+    neuDateiOk->release();
+    neueDatei->release();
+    dateiLöschen->release();
+}
+
+// nicht constant
+int KESSEditor::getAktion()
+{
+    int ret = aktion;
+    aktion = 0;
+    return ret;
+}
+
+bool KESSEditor::neuDateiOkME( MausEreignis &me )
+{
+    if( me.id == ME_RLinks )
+    {
+        neuDateiF->removeStyle( Fenster::Style::Sichtbar );
+        aktion = 1;
+    }
+    return 1;
+}
+
+void KESSEditor::setDateiListe( RCArray< Text > *list )
+{
+    hauptScreen->lock();
+    dateien->deSelect();
+    while( dateien->getEintragAnzahl() )
+        dateien->removeEintrag( 0 );
+    int anz = list->getEintragAnzahl();
+    for( int i = 0; i < anz; i++ )
+        dateien->addEintrag( list->get( i ) );
+    bildSeite->setSichtbar( 0 );
+    textSeite->setSichtbar( 0 );
+    neuDateiF->removeStyle( Fenster::Style::Sichtbar );
+    list->release();
+    hauptScreen->unlock();
+}
+
+void KESSEditor::setBildListe( RCArray< Text > *list )
+{
+    textSeite->setSichtbar( 0 );
+    bildSeite->setBildListe( list );
+    bildSeite->setSichtbar( 1 );
+}
+
+void KESSEditor::setDateiText( Text *txt )
+{
+    bildSeite->setSichtbar( 0 );
+    textSeite->setDateiText( txt );
+    textSeite->setSichtbar( 1 );
+}
+
+void KESSEditor::setBild( Bild *b )
+{
+    bildSeite->setBild( b );
+}
+
+void KESSEditor::setSichtbar( bool s )
+{
+    sichtbar = s;
+}
+
+bool KESSEditor::tick( double tv )
+{
+    int ak = textSeite->getAktion();
+    switch( ak )
+    {
+    case 1: // Text Speichern
+        aktion = 5;
+        break;
+    case 2: // Datei Löschen
+        aktion = 4;
+        break;
+    case 3: // Neue Datei
+        neuDateiF->addStyle( Fenster::Style::Sichtbar );
+        break;
+    }
+    ak = bildSeite->getAktion();
+    switch( ak )
+    {
+    case 1: // Bild Auswählen
+        aktion = 3;
+        break;
+    case 2: // Bild Löschen
+        aktion = 6;
+        break;
+    case 3: // Importieren
+        aktion = 7;
+        break;
+    case 4: // Datei Löschen
+        aktion = 4;
+        break;
+    case 5: // Neue Datei
+        neuDateiF->addStyle( Fenster::Style::Sichtbar );
+        break;
+    }
+    bool ret = dateien->tick( tv );
+    ret |= textSeite->tick( tv );
+    ret |= bildSeite->tick( tv );
+    ret |= vorschau->tick( tv );
+    ret |= veröffentlichen->tick( tv );
+    ret |= neuDateiF->tick( tv );
+    if( dateien->getAuswahl() < 0 )
+    {
+        ret |= neueDatei->tick( tv );
+        if( dateien->getEintragAnzahl() > 0 && dateien->zEintrag( 0 )->zText()->istGleich( ".." ) )
+            ret |= dateiLöschen->tick( tv );
+    }
+    tickVal += tv * 150;
+    int val = 0;
+    if( tickVal > 1 )
+    {
+        val = (int)tickVal;
+        tickVal -= val;
+    }
+    else
+        return ret;
+    if( sichtbar && neuDateiF->hatStyle( Fenster::Style::Sichtbar ) && alpha2 > 100 )
+    {
+        if( alpha2 - val < 100 )
+            alpha2 = 100;
+        else
+            alpha2 -= val;
+        ret = 1;
+    }
+    if( sichtbar && neuDateiF->hatStyleNicht( Fenster::Style::Sichtbar ) && alpha2 < 255 )
+    {
+        if( alpha2 + val > 255 )
+            alpha2 = 255;
+        else
+            alpha2 += val;
+        ret = 1;
+    }
+    if( sichtbar && alpha != 255 )
+    {
+        if( alpha + val > 255 )
+            alpha = 255;
+        else
+            alpha += val;
+        ret = 1;
+    }
+    if( !sichtbar && alpha != 0 )
+    {
+        if( alpha - val < 0 )
+            alpha = 0;
+        else
+            alpha -= val;
+        ret = 1;
+    }
+    return ret;
+}
+
+void KESSEditor::doMausEreignis( MausEreignis &me )
+{
+    if( !sichtbar )
+        return;
+    if( neuDateiF->hatStyle( Fenster::Style::Sichtbar ) )
+    {
+        neuDateiF->doMausEreignis( me );
+        return;
+    }
+    int ausw = dateien->getAuswahl();
+    dateien->doMausEreignis( me );
+    if( ausw != dateien->getAuswahl() && me.id == ME_RLinks )
+    {
+        if( dateien->getAuswahl() >= 0 )
+            aktion = 2;
+        else
+            dateien->setAuswahl( ausw );
+    }
+    textSeite->doMausEreignis( me );
+    bildSeite->doMausEreignis( me );
+    if( dateien->getAuswahl() < 0 )
+    {
+        bool vera = me.verarbeitet;
+        neueDatei->doMausEreignis( me );
+        if( !vera && me.verarbeitet && me.id == ME_RLinks )
+            neuDateiF->addStyle( Fenster::Style::Sichtbar );
+        if( dateien->getEintragAnzahl() > 0 && dateien->zEintrag( 0 )->zText()->istGleich( ".." ) )
+        {
+            vera = me.verarbeitet;
+            dateiLöschen->doMausEreignis( me );
+            if( !vera && me.verarbeitet && me.id == ME_RLinks )
+                aktion = 4;
+        }
+    }
+    bool vera = me.verarbeitet;
+    vorschau->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+        aktion = 8;
+    vera = me.verarbeitet;
+    veröffentlichen->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+        aktion = 9;
+}
+
+void KESSEditor::doTastaturEreignis( TastaturEreignis &te )
+{
+    if( neuDateiF->hatStyle( Fenster::Style::Sichtbar ) )
+    {
+        neuDateiF->doTastaturEreignis( te );
+        return;
+    }
+    textSeite->doTastaturEreignis( te );
+}
+
+void KESSEditor::render( Bild &zRObj )
+{
+    zRObj.setAlpha( alpha );
+    zRObj.setAlpha( alpha2 );
+    dateien->render( zRObj );
+    textSeite->render( zRObj );
+    bildSeite->render( zRObj );
+    vorschau->render( zRObj );
+    veröffentlichen->render( zRObj );
+    if( dateien->getAuswahl() < 0 )
+    {
+        neueDatei->setPosition( 770, 440 );
+        neueDatei->render( zRObj );
+        if( dateien->getEintragAnzahl() > 0 && dateien->zEintrag( 0 )->zText()->istGleich( ".." ) )
+        {
+            dateiLöschen->setPosition( 770, 410 );
+            dateiLöschen->render( zRObj );
+        }
+    }
+    zRObj.releaseAlpha();
+    neuDateiF->render( zRObj );
+    zRObj.releaseAlpha();
+}
+
+// constant
+Text *KESSEditor::zDateiText() const
+{
+    return textSeite->zDateiText();
+}
+
+Text *KESSEditor::zBildImportPfad() const
+{
+    return bildSeite->zBildImportPfad();
+}
+
+Text *KESSEditor::zDateiAuswahl() const
+{
+    if( !dateien->zEintrag( dateien->getAuswahl() ) )
+        return 0;
+    return dateien->zEintrag( dateien->getAuswahl() )->zText();
+}
+
+Text *KESSEditor::zBildAuswahl() const
+{
+    return bildSeite->zBildAuswahl();
+}
+
+int KESSEditor::getNeuDateiTyp() const
+{
+    return neuDateiTyp->getAuswahl();
+}
+
+Text *KESSEditor::zNeuDateiName() const
+{
+    return neuDateiName->zText();
+}
+
+bool KESSEditor::istSichtbar() const
+{
+    return sichtbar;
+}
+
+// Reference Counting
+KESSEditor *KESSEditor::getThis()
+{
+    ref++;
+    return this;
+}
+
+KESSEditor *KESSEditor::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 138 - 0
KSGClient/NachLogin/Editor/Karte/ShopSeite/KESSEditor.h

@@ -0,0 +1,138 @@
+#ifndef KESSEditor_H
+#define KESSEditor_H
+
+#include <Knopf.h>
+#include <Liste.h>
+#include <Bild.h>
+#include <DateiDialog.h>
+#include <Fenster.h>
+#include <AuswahlBox.h>
+
+using namespace Framework;
+
+class KEShopSeite;
+
+class KESSTextSeite
+{
+private:
+    TextFeld *text;
+    Knopf *speichern;
+    Knopf *dateiLöschen;
+    Knopf *neueDatei;
+    int aktion;
+    bool sichtbar;
+    unsigned char alpha;
+    double tickVal;
+    int ref;
+
+public:
+    // Konstruktor
+    KESSTextSeite( Schrift *zSchrift, Knopf *zNeueDatei, Knopf *zDateiRemove );
+    // Destruktor
+    ~KESSTextSeite();
+    // nicht constant
+    int getAktion();
+    void setDateiText( Text *txt );
+    void setSichtbar( bool s );
+    bool tick( double tv );
+    void doMausEreignis( MausEreignis &me );
+    void doTastaturEreignis( TastaturEreignis &te );
+    void render( Bild &zRObj );
+    // constant
+    Text *zDateiText() const;
+    // Reference Counting 
+    KESSTextSeite *getThis();
+    KESSTextSeite *release();
+};
+
+class KESSBildSeite
+{
+private:
+    AuswahlListe *bilder;
+    BildZ *bildObj;
+    Knopf *bildLöschen;
+    Knopf *importieren;
+    Knopf *dateiLöschen;
+    Knopf *neueDatei;
+    DateiDialogTh *importDialog;
+    Text *importPfad;
+    int aktion;
+    bool sichtbar;
+    unsigned char alpha;
+    unsigned char alpha2;
+    double tickVal;
+    int ref;
+
+public:
+    // Konstruktor
+    KESSBildSeite( Schrift *zSchrift, Knopf *zNeueDatei, Knopf *zDateiRemove );
+    // Destruktor
+    ~KESSBildSeite();
+    // nicht constant
+    int getAktion();
+    void setBildListe( RCArray< Text > *list );
+    void setBild( Bild *b );
+    void setSichtbar( bool s );
+    bool tick( double tv );
+    void doMausEreignis( MausEreignis &me );
+    void render( Bild &zRObj );
+    // constant
+    Text *zBildImportPfad() const;
+    Text *zBildAuswahl() const;
+    // Reference Counting
+    KESSBildSeite *getThis();
+    KESSBildSeite *release();
+};
+
+class KESSEditor : public Zeichnung
+{
+private:
+    AuswahlListe *dateien;
+    KESSTextSeite *textSeite;
+    KESSBildSeite *bildSeite;
+    Knopf *vorschau;
+    Knopf *veröffentlichen;
+    Fenster *neuDateiF;
+    AuswahlBox *neuDateiTyp;
+    TextFeld *neuDateiName;
+    Knopf *neuDateiOk;
+    Knopf *neueDatei;
+    Knopf *dateiLöschen;
+    int aktion;
+    bool sichtbar;
+    unsigned char alpha;
+    unsigned char alpha2;
+    double tickVal;
+    int ref;
+
+public:
+    // Konstruktor
+    KESSEditor( Schrift *zSchrift );
+    // Destruktor
+    ~KESSEditor();
+    // nicht constant
+    int getAktion();
+    bool neuDateiOkME( MausEreignis &me );
+    void setDateiListe( RCArray< Text > *list );
+    void setBildListe( RCArray< Text > *list );
+    void setDateiText( Text *txt );
+    void setBild( Bild *b );
+    void setSichtbar( bool s );
+    bool tick( double tv ) override;
+    void doMausEreignis( MausEreignis &me ) override;
+    void doTastaturEreignis( TastaturEreignis &te ) override;
+    void render( Bild &zRObj ) override;
+    // constant
+    Text *zDateiText() const;
+    Text *zBildImportPfad() const;
+    Text *zDateiAuswahl() const;
+    Text *zBildAuswahl() const;
+    int getNeuDateiTyp() const;
+    Text *zNeuDateiName() const;
+    bool istSichtbar() const;
+    // Reference Counting
+    KESSEditor *getThis();
+    KESSEditor *release();
+};
+
+#endif

+ 727 - 0
KSGClient/NachLogin/Editor/Karte/ShopSeite/KESSVorschau.cpp

@@ -0,0 +1,727 @@
+#include "KESSVorschau.h"
+#include "../../../../Global/Variablen.h"
+#include "../../../../Global/Initialisierung.h"
+#include <DateiSystem.h>
+
+void kESSVorschauKSGSAktion( void *p, RCArray< KSGSVariable > *parameter, KSGSVariable **retVal )
+{
+    if( !p )
+        return;
+    ( (KESSVorschauKarteScript*)p )->ksgsAktion( parameter, retVal );
+}
+
+// Inhalt der KESSVorschauKarteScript Klasse aus KESSVorschau.h
+// Konstruktor
+KESSVorschauKarteScript::KESSVorschauKarteScript( Schrift *zSchrift, TextFeld *zLog )
+    : Thread()
+{
+    ksgs = dllDateien->ladeDLL( "KSGScript.dll", "data/bin/KSGScript.dll" );
+    if( ksgs )
+    {
+        KSGSGetZeichnung getKSGScript = (KSGSGetZeichnung)GetProcAddress( ksgs, KSGS_START_FUNKTION );
+        if( getKSGScript )
+        {
+            fenster = getKSGScript();
+            fenster->setSchriftZ( zSchrift->getThis() );
+            fenster->setSize( 555, 380 );
+            fenster->setRückrufParam( this );
+            fenster->setRückrufFunktion( kESSVorschauKSGSAktion );
+            fenster->setLog( zLog->getThis() );
+        }
+        else
+        {
+            fenster = 0;
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                          new Text( "Der Einstiegspunkt '" KSGS_START_FUNKTION "' in der DLL-Datei "
+                                                          "'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+                                                          new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+        }
+    }
+    else
+    {
+        fenster = 0;
+        nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                      new Text( "Die DLL-Datei 'data/bin/KSGScript.dll' konnte nicht geladen werden." ),
+                                                      new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+    }
+    ram = new LRahmen();
+    ram->setSize( 555, 380 );
+    ram->setFarbe( 0xFFFFFFFF );
+    pos = Punkt( 220, 10 );
+    sichtbar = 0;
+    besitztTestVersion = 0;
+    verbleibend = 0;
+    vollversionErwerbbar = 1;
+    testversionErwerbbar = 1;
+    vvPreis = 0;
+    tvPreis = 0;
+    kupfer = 0;
+    alpha = 0;
+    aktion = 0;
+    ak = 0;
+    ref = 1;
+}
+
+// Destruktor
+KESSVorschauKarteScript::~KESSVorschauKarteScript()
+{
+    if( fenster )
+    {
+        fenster->zurücksetzen();
+        fenster->release();
+    }
+    ram->release();
+    if( ksgs )
+        dllDateien->releaseDLL( "KSGScript.dll" );
+}
+
+// nicht constant
+void KESSVorschauKarteScript::thread()
+{
+    sichtbar = 0;
+    while( alpha )
+        Sleep( 100 );
+    if( ak == 1 )
+    {
+        pfad += "/seite/seite.ksgs";
+        if( fenster )
+            fenster->setScriptDatei( pfad );
+    }
+    fenster->neuLaden();
+    sichtbar = 1;
+    ak = 0;
+    run = 0;
+}
+
+void KESSVorschauKarteScript::setScriptParams( bool hatTV, int tvVerb, bool vvEn, bool tvEn, int vvK, int tvK, int k )
+{
+    besitztTestVersion = hatTV;
+    verbleibend = tvVerb;
+    vollversionErwerbbar = vvEn;
+    testversionErwerbbar = tvEn;
+    vvPreis = vvK;
+    tvPreis = tvK;
+    kupfer = k;
+    if( sichtbar )
+    {
+        ak = 2;
+        start();
+    }
+}
+
+void KESSVorschauKarteScript::ladeKarteSeite( char *pfad )
+{
+    if( run )
+        warteAufThread( 5000 );
+    if( run )
+        ende();
+    this->pfad = pfad;
+    ak = 1;
+    start();
+}
+
+void KESSVorschauKarteScript::ksgsAktion( RCArray< KSGSVariable > *parameter, KSGSVariable **retVal )
+{
+    KSGSVariable *befehl = parameter->z( 0 );
+    if( !befehl )
+        return;
+    Text *b = befehl->getText();
+    if( !b )
+        return;
+    if( b->istGleich( "GetBesitzStatus" ) )
+    {
+        int besitz = (int)besitztTestVersion;
+        KSGSGetVariable getKSGSVariable = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
+        if( getKSGSVariable )
+        {
+            KSGSVariableDef def = { KSGS_INT, 0, 3, ( Text() += besitz ).getText() };
+            *retVal = getKSGSVariable( fenster, &def );
+        }
+        else
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                          new Text( "Der Einstiegspunkt '" KSGS_VARIABLE_FUNKTION "' in der DLL-Datei "
+                                                          "'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+                                                          new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+        }
+        b->release();
+        return;
+    }
+    if( b->istGleich( "GetPreis" ) )
+    {
+        KSGSVariable *version = parameter->z( 1 );
+        if( !version )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                          new Text( "Auf dieser Seite befindet sich ein Fehler im KSG-Script. "
+                                                          "Sie könnte eventuell nicht richtig funktionieren." ),
+                                                          new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+        }
+        else
+        {
+            bool testVersion = !version->getInt();
+            int k = testVersion ? tvPreis : vvPreis;
+            KSGSGetVariable getKSGSVariable = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
+            if( getKSGSVariable )
+            {
+                KSGSVariableDef def = { KSGS_INT, 0, 3, ( Text() += k ).getText() };
+                *retVal = getKSGSVariable( fenster, &def );
+            }
+            else
+            {
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                              new Text( "Der Einstiegspunkt '" KSGS_VARIABLE_FUNKTION "' in der DLL-Datei "
+                                                              "'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+                                                              new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+            }
+        }
+        b->release();
+        return;
+    }
+    if( b->istGleich( "GetTestVersionVerbleibend" ) )
+    {
+        KSGSGetVariable getKSGSVariable = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
+        if( getKSGSVariable )
+        {
+            KSGSVariableDef def = { KSGS_INT, 0, 3, ( Text() += verbleibend ).getText() };
+            *retVal = getKSGSVariable( fenster, &def );
+        }
+        else
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                          new Text( "Der Einstiegspunkt '" KSGS_VARIABLE_FUNKTION "' in der DLL-Datei "
+                                                          "'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+                                                          new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+        }
+        b->release();
+        return;
+    }
+    if( b->istGleich( "GetErwerbbarStatus" ) )
+    {
+        int erwerbbar = ( (int)testversionErwerbbar & 0x1 ) | ( ( (int)vollversionErwerbbar << 1 ) & 0x2 );
+        KSGSGetVariable getKSGSVariable = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
+        if( getKSGSVariable )
+        {
+            KSGSVariableDef def = { KSGS_INT, 0, 3, ( Text() += erwerbbar ).getText() };
+            *retVal = getKSGSVariable( fenster, &def );
+        }
+        else
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                          new Text( "Der Einstiegspunkt '" KSGS_VARIABLE_FUNKTION "' in der DLL-Datei "
+                                                          "'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+                                                          new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+        }
+        b->release();
+        return;
+    }
+    if( b->istGleich( "GetKupfer" ) )
+    {
+        KSGSGetVariable getKSGSVariable = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
+        if( getKSGSVariable )
+        {
+            KSGSVariableDef def = { KSGS_INT, 0, 3, ( Text() += kupfer ).getText() };
+            *retVal = getKSGSVariable( fenster, &def );
+        }
+        else
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                          new Text( "Der Einstiegspunkt '" KSGS_VARIABLE_FUNKTION "' in der DLL-Datei "
+                                                          "'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+                                                          new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+        }
+        b->release();
+        return;
+    }
+    if( b->istGleich( "Kaufen" ) )
+    {
+        KSGSVariable *version = parameter->z( 1 );
+        if( !version )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                          new Text( "Auf dieser Seite befindet sich ein Fehler im KSG-Script. "
+                                                          "Sie könnte eventuell nicht richtig funktionieren." ),
+                                                          new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+        }
+        b->release();
+        return;
+    }
+    if( b->istGleich( "GetBild" ) )
+    {
+        KSGSVariable *pfad = parameter->z( 1 );
+        KSGSVariable *name = parameter->z( 2 );
+        if( !pfad || !name )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                          new Text( "Auf dieser Seite befindet sich ein Fehler im KSG-Script. "
+                                                          "Sie könnte eventuell nicht richtig funktionieren." ),
+                                                          new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+        }
+        else
+        {
+            Text *pf = pfad->getText();
+            Text *n = name->getText();
+            if( !pf || !n )
+            {
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                              new Text( "Auf dieser Seite befindet sich ein Fehler im KSG-Script. "
+                                                              "Sie könnte eventuell nicht richtig funktionieren." ),
+                                                              new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+            }
+            else
+            {
+                KSGSGetVariable getKSGSVariable = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
+                if( getKSGSVariable )
+                {
+                    int p = n->positionVon( ".ltdb/" );
+                    if( p < 0 )
+                        p = 0;
+                    else
+                        p += 6;
+                    Bild *b = bilder->get( *n );
+                    if( !b )
+                    {
+                        LTDBDatei *dat = new LTDBDatei();
+                        dat->setDatei( pf->getThis() );
+                        dat->leseDaten( 0 );
+                        b = dat->laden( 0, n->getTeilText( p, n->getLength() ) );
+                        dat->release();
+                        if( b )
+                            bilder->add( *n, b->getThis() );
+                    }
+                    if( b )
+                    {
+                        KSGSVariableDef def = { KSGS_BILD, 0, 3, "" };
+                        KSGSVariable *ret = getKSGSVariable( fenster, &def );
+                        KSGSSetBild setKSGSBild = (KSGSSetBild)GetProcAddress( ksgs, KSGS_SET_BILD_FUNKTION );
+                        if( !setKSGSBild )
+                        {
+                            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                                          new Text( "Der Einstiegspunkt '" KSGS_SET_BILD_FUNKTION "' in der DLL-Datei "
+                                                                          "'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+                                                                          new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+                            b->release();
+                        }
+                        else
+                            setKSGSBild( ret, b );
+                        *retVal = ret;
+                    }
+                }
+                else
+                {
+                    nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                                  new Text( "Der Einstiegspunkt '" KSGS_VARIABLE_FUNKTION "' in der DLL-Datei "
+                                                                  "'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+                                                                  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+                }
+            }
+            if( pf )
+                pf->release();
+            if( n )
+                n->release();
+        }
+        b->release();
+        return;
+    }
+}
+
+void KESSVorschauKarteScript::doMausEreignis( MausEreignis &me )
+{
+    me.mx -= pos.x;
+    me.my -= pos.y;
+    if( fenster )
+        fenster->doMausEreignis( me );
+    me.mx += pos.x;
+    me.my += pos.y;
+}
+
+void KESSVorschauKarteScript::doTastaturEreignis( TastaturEreignis &te )
+{
+    if( fenster )
+        fenster->doTastaturEreignis( te );
+}
+
+bool KESSVorschauKarteScript::tick( double zeit )
+{
+    bool rend = fenster ? fenster->tick( zeit ) : 0;
+    if( !sichtbar && alpha > 0 )
+    {
+        if( alpha - zeit * 150 < 0 )
+            alpha = 0;
+        else
+            alpha -= (unsigned char)( zeit * 150 );
+        rend = 1;
+    }
+    if( sichtbar && alpha < 255 )
+    {
+        if( alpha + zeit * 150 > 255 )
+            alpha = 255;
+        else
+            alpha += (unsigned char)( zeit * 150 );
+        rend = 1;
+    }
+    return rend;
+}
+
+void KESSVorschauKarteScript::render( Bild &zRObj )
+{
+    if( !zRObj.setDrawOptions( pos.x, pos.y, ram->getBreite(), ram->getHeight() ) )
+        return;
+    zRObj.setAlpha( alpha );
+    ram->render( zRObj );
+    if( fenster )
+        fenster->render( zRObj );
+    zRObj.releaseAlpha();
+    zRObj.releaseDrawOptions();
+}
+
+// Reference Counting
+KESSVorschauKarteScript *KESSVorschauKarteScript::getThis()
+{
+    ref++;
+    return this;
+}
+
+KESSVorschauKarteScript *KESSVorschauKarteScript::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+
+// Inhalt der KESSVorschauKarte Klasse aus KESSVorschau.h
+// Konstruktor
+KESSVorschauKarte::KESSVorschauKarte( Schrift *schrift )
+{
+    auswählen = initKnopf( 173, 73, 22, 22, 0, 0, "" );
+    auswählen->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Rahmen | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+    auswählen->setHintergrundBildZ( bilder->get( "shop.ltdb/weiter.png" ) );
+    initToolTip( auswählen, "Karte auswählen.", schrift, hauptScreen );
+    auswählen->setLinienRahmenBreite( 1 );
+    hintergrund = 0;
+    ausgewählt = new AlphaFeld();
+    ausgewählt->setPosition( 1, 1 );
+    ausgewählt->setSize( 198, 98 );
+    ausgewählt->setFarbe( 0x0000FF00 );
+    ausgewählt->setStrength( 10 );
+    ram = new LRahmen();
+    ram->setPosition( 10, 10 );
+    ram->setSize( 200, 100 );
+    ram->setFarbe( 0xFFFFFFFF );
+    ausw = 0;
+    rend = 0;
+    ref = 1;
+}
+
+// Destruktor
+KESSVorschauKarte::~KESSVorschauKarte()
+{
+    auswählen->release();
+    if( hintergrund )
+        hintergrund->release();
+    ausgewählt->release();
+    ram->release();
+}
+
+// nicht constant
+void KESSVorschauKarte::ladeKarte( char *pfad )
+{
+    LTDBDatei *datei = new LTDBDatei();
+    Text *bdpf = new Text( pfad );
+    bdpf->append( "/titelbg.ltdb" );
+    datei->setDatei( bdpf );
+    hintergrund = datei->laden( 0, new Text( "auswbg.jpg" ) );
+    datei->release();
+}
+
+bool KESSVorschauKarte::doMausEreignis( MausEreignis &me )
+{
+    bool vera = me.verarbeitet;
+    auswählen->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+    {
+        ausw = 1;
+        return 1;
+    }
+    return 0;
+}
+
+bool KESSVorschauKarte::tick( double zeit )
+{
+    rend |= ausgewählt->tick( zeit );
+    rend |= auswählen->tick( zeit );
+    int a = ( ausgewählt->getFarbe() >> 24 ) & 0xFF;
+    if( ausw && a < 255 )
+    {
+        if( a + 150 * zeit > 255 )
+            a = 255;
+        else
+            a += (int)( zeit * 150 );
+        ausgewählt->setFarbe( ( ( a << 24 ) & 0xFF000000 ) | ( ausgewählt->getFarbe() & 0xFFFFFF ) );
+        rend = 1;
+    }
+    if( !ausw && a > 0 )
+    {
+        if( a - 150 * zeit < 0 )
+            a = 0;
+        else
+            a += (int)( zeit * 150 );
+        ausgewählt->setFarbe( ( ( a << 24 ) & 0xFF000000 ) | ( ausgewählt->getFarbe() & 0xFFFFFF ) );
+        rend = 1;
+    }
+    bool ret = rend;
+    rend = 0;
+    return ret;
+}
+
+void KESSVorschauKarte::render( Bild &zRObj )
+{
+    ram->render( zRObj );
+    if( !zRObj.setDrawOptions( ram->getX(), ram->getY(), 200, 100 ) )
+        return;
+    if( hintergrund )
+        zRObj.drawBild( 1, 1, 198, 98, *hintergrund );
+    ausgewählt->render( zRObj );
+    auswählen->render( zRObj );
+    zRObj.releaseDrawOptions();
+}
+
+// Reference Counting
+KESSVorschauKarte *KESSVorschauKarte::getThis()
+{
+    ref++;
+    return this;
+}
+
+KESSVorschauKarte *KESSVorschauKarte::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+
+// Inhalt der KESSVorschau Klasse aus KESSVorschau.h
+// Konstruktor
+KESSVorschau::KESSVorschau( Schrift *zSchrift )
+{
+    schrift = zSchrift->getThis();
+    log = initTextFeld( 10, 400, 860, 90, zSchrift, TextFeld::Style::TextGebiet & ~TextFeld::Style::Erlaubt, "Log:\n" );
+    script = new KESSVorschauKarteScript( zSchrift, log );
+    karte = new KESSVorschauKarte( zSchrift->getThis() );
+    beenden = initKnopf( 10, 500, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Zurück" );
+    besitztTestVersion = initAuswahlBox( 10, 120, 200, 20, zSchrift, ABSTYLE, { "Besitzt Testversion nicht", "Besitzt Testversion" } );
+    spieleVerbleibend = initTextFeld( 110, 150, 100, 20, zSchrift, TextFeld::Style::TextFeld, "0" );
+    spieleVerbleibend->setTastaturEreignis( _nurNummernTE );
+    vvErwerbbar = initAuswahlBox( 10, 180, 200, 20, zSchrift, ABSTYLE, { "Vollversion erwerbbar", "Vollversion nicht erwerbbar" } );
+    tvErwerbbar = initAuswahlBox( 10, 210, 200, 20, zSchrift, ABSTYLE, { "Testversion erwerbbar", "Testversion nicht erwerbbar" } );
+    vvPreis = initTextFeld( 110, 240, 100, 20, zSchrift, TextFeld::Style::TextFeld, "0" );
+    vvPreis->setTastaturEreignis( _nurNummernTE );
+    tvPreis = initTextFeld( 110, 270, 100, 20, zSchrift, TextFeld::Style::TextFeld, "0" );
+    tvPreis->setTastaturEreignis( _nurNummernTE );
+    kupfer = initTextFeld( 110, 300, 100, 20, zSchrift, TextFeld::Style::TextFeld, "0" );
+    pfad = "";
+    alpha = 0;
+    sichtbar = 0;
+    tickVal = 0;
+    aktion = 0;
+    rend = 0;
+    ref = 1;
+}
+
+// Destruktor
+KESSVorschau::~KESSVorschau()
+{
+    schrift->release();
+    script->release();
+    karte->release();
+    beenden->release();
+    besitztTestVersion->release();
+    spieleVerbleibend->release();
+    vvErwerbbar->release();
+    tvErwerbbar->release();
+    vvPreis->release();
+    tvPreis->release();
+    kupfer->release();
+    log->release();
+}
+
+// nicht constant
+int KESSVorschau::getAktion()
+{
+    int ret = aktion;
+    aktion = 0;
+    return ret;
+}
+
+void KESSVorschau::ladeKarte( char *pfad )
+{
+    karte->ladeKarte( pfad );
+    this->pfad = pfad;
+}
+
+void KESSVorschau::setSichtbar( bool sicht )
+{
+    sichtbar = sicht;
+}
+
+void KESSVorschau::doMausEreignis( MausEreignis &me )
+{
+    if( !sichtbar )
+        return;
+    bool paramUpdate = 0;
+    int ausw = vvErwerbbar->getAuswahl();
+    vvErwerbbar->doMausEreignis( me );
+    if( ausw != vvErwerbbar->getAuswahl() && me.id == ME_RLinks )
+    {
+        vvErwerbbar->einklappen();
+        paramUpdate = 1;
+    }
+    ausw = tvErwerbbar->getAuswahl();
+    tvErwerbbar->doMausEreignis( me );
+    if( ausw != tvErwerbbar->getAuswahl() && me.id == ME_RLinks )
+    {
+        tvErwerbbar->einklappen();
+        paramUpdate = 1;
+    }
+    ausw = besitztTestVersion->getAuswahl();
+    besitztTestVersion->doMausEreignis( me );
+    if( ausw != besitztTestVersion->getAuswahl() && me.id == ME_RLinks )
+    {
+        besitztTestVersion->einklappen();
+        paramUpdate = 1;
+    }
+    script->doMausEreignis( me );
+    if( karte->doMausEreignis( me ) )
+        script->ladeKarteSeite( pfad );
+    bool vera = me.verarbeitet;
+    beenden->doMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+        aktion = 1;
+    vvPreis->doMausEreignis( me );
+    tvPreis->doMausEreignis( me );
+    kupfer->doMausEreignis( me );
+    spieleVerbleibend->doMausEreignis( me );
+    log->doMausEreignis( me );
+    if( paramUpdate )
+    {
+        script->setScriptParams( besitztTestVersion->getAuswahl() == 1, (int)*spieleVerbleibend->zText(), vvErwerbbar->getAuswahl() == 0,
+                                 tvErwerbbar->getAuswahl() == 0, (int)*vvPreis->zText(), (int)*tvPreis->zText(), (int)*kupfer->zText() );
+    }
+}
+
+void KESSVorschau::doTastaturEreignis( TastaturEreignis &te )
+{
+    if( !sichtbar )
+        return;
+    if( !te.verarbeitet && te.id == TE_Release && te.taste == T_Enter )
+    {
+        if( spieleVerbleibend->hatStyle( TextFeld::Style::Fokus ) || vvPreis->hatStyle( TextFeld::Style::Fokus ) || tvPreis->hatStyle( TextFeld::Style::Fokus ) || kupfer->hatStyle( TextFeld::Style::Fokus ) )
+        {
+            script->setScriptParams( besitztTestVersion->getAuswahl() == 1, (int)*spieleVerbleibend->zText(), vvErwerbbar->getAuswahl() == 0,
+                                     tvErwerbbar->getAuswahl() == 0, (int)*vvPreis->zText(), (int)*tvPreis->zText(), (int)*kupfer->zText() );
+        }
+    }
+    script->doTastaturEreignis( te );
+    spieleVerbleibend->doTastaturEreignis( te );
+    vvPreis->doTastaturEreignis( te );
+    tvPreis->doTastaturEreignis( te );
+    kupfer->doTastaturEreignis( te );
+}
+
+bool KESSVorschau::tick( double zeit )
+{
+    bool ret = script->tick( zeit );
+    ret |= karte->tick( zeit );
+    ret |= beenden->tick( zeit );
+    ret |= spieleVerbleibend->tick( zeit );
+    ret |= vvPreis->tick( zeit );
+    ret |= tvPreis->tick( zeit );
+    ret |= kupfer->tick( zeit );
+    ret |= log->tick( zeit );
+    ret |= tvErwerbbar->tick( zeit );
+    ret |= vvErwerbbar->tick( zeit );
+    ret |= besitztTestVersion->tick( zeit );
+    tickVal += zeit * 150;
+    int val = 0;
+    if( tickVal > 1 )
+        val = (int)tickVal;
+    else
+        return ret;
+    if( sichtbar && alpha != 255 )
+    {
+        if( alpha + val > 255 )
+            alpha = 255;
+        else
+            alpha += val;
+        ret = 1;
+    }
+    if( !sichtbar && alpha != 0 )
+    {
+        if( alpha - val < 0 )
+            alpha = 0;
+        else
+            alpha -= val;
+        ret = 1;
+    }
+    return ret;
+}
+
+void KESSVorschau::render( Bild &zRObj )
+{
+    zRObj.setAlpha( alpha );
+    script->render( zRObj );
+    karte->render( zRObj );
+    beenden->render( zRObj );
+    spieleVerbleibend->render( zRObj );
+    log->render( zRObj );
+    vvPreis->render( zRObj );
+    tvPreis->render( zRObj );
+    kupfer->render( zRObj );
+    schrift->lock();
+    schrift->setSchriftSize( 12 );
+    Text txt = "Test Spiele:";
+    schrift->setDrawPosition( 10, 154 );
+    schrift->renderText( &txt, zRObj, 0xFFFFFFFF );
+    txt = "Voll Preis:";
+    schrift->setDrawPosition( 10, 244 );
+    schrift->renderText( &txt, zRObj, 0xFFFFFFFF );
+    txt = "Test Preis:";
+    schrift->setDrawPosition( 10, 274 );
+    schrift->renderText( &txt, zRObj, 0xFFFFFFFF );
+    txt = "Kupfer Besitz:";
+    schrift->setDrawPosition( 10, 304 );
+    schrift->renderText( &txt, zRObj, 0xFFFFFFFF );
+    txt = "Diese Werte sind nur zum\nTesten und haben keinerlei\nEinfluss auf den Shop.";
+    schrift->setDrawPosition( 10, 334 );
+    schrift->renderText( &txt, zRObj, 0xFFFFFFFF );
+    schrift->unlock();
+    tvErwerbbar->render( zRObj );
+    vvErwerbbar->render( zRObj );
+    besitztTestVersion->render( zRObj );
+    zRObj.releaseAlpha();
+}
+
+// constant
+bool KESSVorschau::istSichtbar() const
+{
+    return sichtbar;
+}
+
+// Reference Counting
+KESSVorschau *KESSVorschau::getThis()
+{
+    ref++;
+    return this;
+}
+
+KESSVorschau *KESSVorschau::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 120 - 0
KSGClient/NachLogin/Editor/Karte/ShopSeite/KESSVorschau.h

@@ -0,0 +1,120 @@
+#ifndef KESSVorschau_H
+#define KESSVorschau_H
+
+#include <KSGScript.h>
+#include <AuswahlBox.h>
+#include <Thread.h>
+
+using namespace Framework;
+using namespace KSGScript;
+
+class KESSVorschauKarteScript : public Thread
+{
+private:
+    KSGScriptObj *fenster;
+    Punkt pos;
+    LRahmen *ram;
+    HINSTANCE ksgs;
+    Text pfad;
+    bool sichtbar;
+    bool besitztTestVersion;
+    int verbleibend;
+    bool vollversionErwerbbar;
+    bool testversionErwerbbar;
+    int vvPreis;
+    int tvPreis;
+    int kupfer;
+    unsigned char alpha;
+    bool aktion;
+    int ak;
+    int ref;
+
+public:
+    // Konstruktor
+    KESSVorschauKarteScript( Schrift *zSchrift, TextFeld *zLog );
+    // Destruktor
+    ~KESSVorschauKarteScript();
+    // nicht constant
+    void thread() override;
+    void setScriptParams( bool hatTV, int tvVerb, bool vvEn, bool tvEn, int vvK, int tvK, int k );
+    void ladeKarteSeite( char *pfad );
+    void ksgsAktion( RCArray< KSGSVariable > *parameter, KSGSVariable **retVal );
+    void doMausEreignis( MausEreignis &me );
+    void doTastaturEreignis( TastaturEreignis &te );
+    bool tick( double zeit );
+    void render( Bild &zRObj );
+    // Reference Counting
+    KESSVorschauKarteScript *getThis();
+    KESSVorschauKarteScript *release();
+};
+
+class KESSVorschauKarte
+{
+private:
+    Knopf *auswählen;
+    Bild *hintergrund;
+    AlphaFeld *ausgewählt;
+    LRahmen *ram;
+    bool ausw;
+    bool rend;
+    int ref;
+
+public:
+    // Konstruktor
+    KESSVorschauKarte( Schrift *schrift );
+    // Destruktor
+    ~KESSVorschauKarte();
+    // nicht constant
+    void ladeKarte( char *pfad );
+    bool doMausEreignis( MausEreignis &me );
+    bool tick( double zeit );
+    void render( Bild &zRObj );
+    // Reference Counting
+    KESSVorschauKarte *getThis();
+    KESSVorschauKarte *release();
+};
+
+class KESSVorschau : public Zeichnung
+{
+private:
+    Schrift *schrift;
+    KESSVorschauKarteScript *script;
+    KESSVorschauKarte *karte;
+    Knopf *beenden;
+    AuswahlBox *besitztTestVersion;
+    TextFeld *spieleVerbleibend;
+    AuswahlBox *vvErwerbbar;
+    AuswahlBox *tvErwerbbar;
+    TextFeld *vvPreis;
+    TextFeld *tvPreis;
+    TextFeld *kupfer;
+    Text pfad;
+    TextFeld *log;
+    unsigned char alpha;
+    bool sichtbar;
+    double tickVal;
+    int aktion;
+    bool rend;
+    int ref;
+
+public:
+    // Konstruktor
+    KESSVorschau( Schrift *zSchrift );
+    // Destruktor
+    ~KESSVorschau();
+    // nicht constant
+    int getAktion();
+    void ladeKarte( char *pfad );
+    void setSichtbar( bool sicht );
+    void doMausEreignis( MausEreignis &me );
+    void doTastaturEreignis( TastaturEreignis &te );
+    bool tick( double zeit );
+    void render( Bild &zRObj );
+    // constant
+    bool istSichtbar() const;
+    // Reference Counting
+    KESSVorschau *getThis();
+    KESSVorschau *release();
+};
+
+#endif

+ 431 - 0
KSGClient/NachLogin/Editor/Karte/ShopSeite/KEShopSeite.cpp

@@ -0,0 +1,431 @@
+#include "KEShopSeite.h"
+#include <Schrift.h>
+#include <Datei.h>
+#include "../../../../Global/Variablen.h"
+#include "../../../../Global/Initialisierung.h"
+#include <Bild.h>
+
+// Inhalt der KEShopSeite Klasse aus KEShopSeite.h
+// Konstruktor
+KEShopSeite::KEShopSeite( int karte, Schrift *zSchrift )
+    : Thread()
+{
+    schrift = zSchrift->getThis();
+    Text *kName = infoKlient->getKarteName( karte );
+    Text titel = kName ? kName->getText() : "<Karte>";
+    titel += " - Shop Seite";
+    if( kName )
+        kName->release();
+    fenster = initFenster( 10, 40, 880, 550, zSchrift, Fenster::Style::Sichtbar | Fenster::Style::Titel | Fenster::Style::TitelBuffered | Fenster::Style::Erlaubt | Fenster::Style::Rahmen, titel );
+    editor = new KESSEditor( zSchrift );
+    vorschau = new KESSVorschau( zSchrift );
+    laden = (Animation2D*)ladeAnimation->dublizieren();
+    laden->setPosition( 425, 275 );
+    laden->setSichtbar( 0 );
+    fenster->addMember( editor );
+    fenster->addMember( vorschau );
+    animation = 0;
+    tickVal = 0;
+    sichtbar = 0;
+    rechts = 0;
+    xStart = 0;
+    breite = 0;
+    aktion = 0;
+    zeile = 0;
+    this->karte = karte;
+    alpha = 255;
+    ref = 1;
+}
+
+// Destruktor
+KEShopSeite::~KEShopSeite()
+{
+    if( run )
+    {
+        warteAufThread( 5000 );
+        if( run )
+            ende();
+    }
+    fenster->release();
+    editor->release();
+    vorschau->release();
+    laden->release();
+    schrift->release();
+}
+
+// nicht constant
+void KEShopSeite::setSichtbar( bool s, bool vr )
+{
+    animation = 1;
+    sichtbar = s;
+    rechts = vr;
+    if( sichtbar )
+    {
+        if( vr )
+        {
+            xStart = 900;
+            breite = 0;
+        }
+        else
+        {
+            xStart = 0;
+            breite = 0;
+        }
+        if( !run )
+        {
+            aktion = 0;
+            start();
+        }
+    }
+}
+
+void KEShopSeite::thread()
+{
+    laden->setSichtbar( 1 );
+    switch( aktion )
+    {
+    case 0: // Init
+    {
+        RCArray< Text > *list = new RCArray< Text >();
+        int anz = editorKlient->ssGetDateiListe( list );
+        if( anz < 0 )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            list->release();
+            break;
+        }
+        editor->setDateiListe( list );
+        break;
+    }
+    case 1: // Neue Datei
+    {
+        if( !editorKlient->ssDateiErstellen( editor->zNeuDateiName()->getText(), editor->getNeuDateiTyp() ) )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            break;
+        }
+        RCArray< Text > *list = new RCArray< Text >();
+        int anz = editorKlient->ssGetDateiListe( list );
+        if( anz < 0 )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            list->release();
+            break;
+        }
+        editor->setDateiListe( list );
+        break;
+    }
+    case 2: // Datei Auswählen
+    {
+        Text *zName = editor->zDateiAuswahl();
+        if( zName->hat( ".ltdb" ) )
+        {
+            RCArray< Text > *list = new RCArray< Text >();
+            int anz = editorKlient->ssGetBildListe( zName->getText(), list );
+            if( anz < 0 )
+            {
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+                list->release();
+                break;
+            }
+            editor->setBildListe( list );
+        }
+        else if( zName->hat( ".ksgs" ) )
+        {
+            Text *txt = editorKlient->ssTextLaden( zName->getText() );
+            if( !txt )
+            {
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+                break;
+            }
+            editor->setDateiText( txt );
+        }
+        else
+        {
+            if( !editorKlient->ssOrdnerÖffnen(zName->getText() ) )
+            {
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+                break;
+            }
+            RCArray< Text > *list = new RCArray< Text >();
+            int anz = editorKlient->ssGetDateiListe( list );
+            if( anz < 0 )
+            {
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+                list->release();
+                break;
+            }
+            editor->setDateiListe( list );
+        }
+        break;
+    }
+    case 3: // Bild Auswählen
+    {
+        Bild *b = editorKlient->ssBildLaden( editor->zDateiAuswahl()->getText(), editor->zBildAuswahl()->getText() );
+        if( !b )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            break;
+        }
+        editor->setBild( b );
+        break;
+    }
+    case 4: // Datei Löschen
+    {
+        if( ( editor->zDateiAuswahl() && !editorKlient->ssDateiLöschen( editor->zDateiAuswahl()->getText() ) ) || ( !editor->zDateiAuswahl() && !editorKlient->ssDateiLöschen( "." ) ) )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            break;
+        }
+        RCArray< Text > *list = new RCArray< Text >();
+        int anz = editorKlient->ssGetDateiListe( list );
+        if( anz < 0 )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            list->release();
+            break;
+        }
+        editor->setDateiListe( list );
+        break;
+    }
+    case 5: // Text Speichern
+    {
+        if( !editorKlient->ssTextSpeichern( editor->zDateiAuswahl()->getText(), editor->zDateiText() ) )
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+        break;
+    }
+    case 6: // Bild Löschen
+    {
+        if( !editorKlient->ssBildLöschen( editor->zDateiAuswahl()->getText(), editor->zBildAuswahl()->getText() ) )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            break;
+        }
+        RCArray< Text > *list = new RCArray< Text >();
+        int anz = editorKlient->ssGetBildListe( editor->zDateiAuswahl()->getText(), list );
+        if( anz < 0 )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            list->release();
+            break;
+        }
+        editor->setBildListe( list );
+        break;
+    }
+    case 7: // Importieren
+    {
+        Text *pfad = editor->zBildImportPfad();
+        pfad->ersetzen( "\\", "/" );
+        Text *n = pfad->getTeilText( pfad->positionVon( "/", pfad->anzahlVon( "/" ) - 1 ) + 1 );
+        Text name = n->getText();
+        n->release();
+        Text *err = new Text();
+        Bild *b = ladeBild( pfad->getText(), err );
+        if( !b )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), err, new Text( "Ok" ) );
+            break;
+        }
+        err->release();
+        if( !editorKlient->ssBildSpeichern( editor->zDateiAuswahl()->getText(), name, b ) )
+        {
+            b->release();
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            break;
+        }
+        b->release();
+        RCArray< Text > *list = new RCArray< Text >();
+        int anz = editorKlient->ssGetBildListe( editor->zDateiAuswahl()->getText(), list );
+        if( anz < 0 )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            list->release();
+            break;
+        }
+        editor->setBildListe( list );
+        break;
+    }
+    case 8: // Vorschau
+    {
+        editor->setSichtbar( 0 );
+        if( !editorKlient->ladeShopSeiteVorschau() )
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+            editor->setSichtbar( 1 );
+            break;
+        }
+        vorschau->ladeKarte( "data/tmp/ke/ssv" );
+        vorschau->setSichtbar( 1 );
+        break;
+    }
+    case 9: // Veröffentlichen
+    {
+        if( !editorKlient->shopSeiteVeröffentlichen() )
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+        break;
+    }
+    case 10: // Vorschau Beenden
+    {
+        vorschau->setSichtbar( 0 );
+        DateiRemove( "data/tmp/ke/ssv" );
+        editor->setSichtbar( 1 );
+        break;
+    }
+    }
+    laden->setSichtbar( 0 );
+    run = 0;
+}
+
+void KEShopSeite::doMausEreignis( MausEreignis &me )
+{
+    if( !run )
+        fenster->doMausEreignis( me );
+}
+
+void KEShopSeite::doTastaturEreignis( TastaturEreignis &te )
+{
+    if( !run )
+        fenster->doTastaturEreignis( te );
+}
+
+bool KEShopSeite::tick( double z )
+{
+    aktion = vorschau->getAktion();
+    if( aktion )
+        aktion += 9;
+    else
+        aktion = editor->getAktion();
+    if( aktion && !run )
+        start();
+    bool ret = laden->tick( z );
+    tickVal += z * 150;
+    int val = (int)tickVal;
+    tickVal -= val;
+    if( val )
+    {
+        if( run && alpha > 100 )
+        {
+            if( alpha - val < 100 )
+                alpha = 100;
+            else
+                alpha -= val;
+            ret = 1;
+        }
+        if( sichtbar && !run && alpha != 255 )
+        {
+            if( alpha + val > 255 )
+                alpha = 255;
+            else
+                alpha += val;
+            ret = 1;
+        }
+        val *= 3;
+        if( sichtbar )
+        {
+            if( alpha < 100 )
+            {
+                if( alpha + val > 100 )
+                    alpha = 100;
+                else
+                    alpha += val;
+                ret = 1;
+            }
+            if( xStart != 0 || breite != 900 )
+            {
+                if( rechts )
+                {
+                    if( xStart - val <= 0 )
+                    {
+                        xStart = 0;
+                        breite = 900;
+                        animation = 0;
+                        if( !editor->istSichtbar() && !vorschau->istSichtbar() )
+                            editor->setSichtbar( 1 );
+                    }
+                    else
+                    {
+                        xStart -= val;
+                        breite += val;
+                    }
+                }
+                else
+                {
+                    if( breite + val >= 900 )
+                    {
+                        breite = 900;
+                        animation = 0;
+                        if( !editor->istSichtbar() && !vorschau->istSichtbar() )
+                            editor->setSichtbar( 1 );
+                    }
+                    else
+                        breite += val;
+                }
+                ret = 1;
+            }
+        }
+        else
+        {
+            if( breite != 0 )
+            {
+                if( rechts )
+                {
+                    if( breite - val <= 0 )
+                    {
+                        breite = 0;
+                        animation = 0;
+                    }
+                    else
+                        breite -= val;
+                }
+                else
+                {
+                    if( breite - val <= 0 )
+                    {
+                        breite = 0;
+                        xStart = 900;
+                        animation = 0;
+                    }
+                    else
+                    {
+                        breite -= val;
+                        xStart += val;
+                    }
+                }
+                ret = 1;
+            }
+        }
+    }
+    return ret || fenster->tick( z );
+}
+
+void KEShopSeite::render( Bild &zRObj )
+{
+    if( !zRObj.setDrawOptions( xStart, 0, breite, 600 ) )
+        return;
+    zRObj.setAlpha( alpha );
+    fenster->render( zRObj );
+    zRObj.releaseAlpha();
+    laden->render( zRObj );
+    zRObj.releaseDrawOptions();
+}
+
+// constant
+bool KEShopSeite::istSichtbar() const
+{
+    return sichtbar || animation;
+}
+
+// Reference Counting
+KEShopSeite *KEShopSeite::getThis()
+{
+    ref++;
+    return this;
+}
+
+KEShopSeite *KEShopSeite::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 51 - 0
KSGClient/NachLogin/Editor/Karte/ShopSeite/KEShopSeite.h

@@ -0,0 +1,51 @@
+#ifndef KEShopSeite_H
+#define KEShopSeite_H
+
+#include <Fenster.h>
+#include <Thread.h>
+#include <Animation.h>
+#include "KESSEditor.h"
+#include "KESSVorschau.h"
+
+using namespace Framework;
+
+class KEShopSeite : private Thread
+{
+private:
+    Fenster *fenster;
+    Animation2D *laden;
+    Schrift *schrift;
+    KESSEditor *editor;
+    KESSVorschau *vorschau;
+    int aktion;
+    int zeile;
+    bool animation;
+    double tickVal;
+    bool sichtbar;
+    bool rechts;
+    int xStart;
+    int breite;
+    int karte;
+    unsigned char alpha;
+    int ref;
+
+public:
+    // Konstruktor
+    KEShopSeite( int karte, Schrift *zSchrift );
+    // Destruktor
+    ~KEShopSeite();
+    // nicht constant
+    void setSichtbar( bool s, bool vr );
+    void thread() override;
+    void doMausEreignis( MausEreignis &me );
+    void doTastaturEreignis( TastaturEreignis &te );
+    bool tick( double z );
+    void render( Bild &zRObj );
+    // constant
+    bool istSichtbar() const;
+    // Reference Counting
+    KEShopSeite *getThis();
+    KEShopSeite *release();
+};
+
+#endif

+ 478 - 0
KSGClient/NachLogin/Editor/Karte/Teams/KETeams.cpp

@@ -0,0 +1,478 @@
+#include "KETeams.h"
+#include "../../../../Global/Initialisierung.h"
+#include "../../../../Global/Variablen.h"
+
+bool KETNachME( void *p, void *obj, MausEreignis me )
+{
+    if( p )
+        ( (KETeams*)p )->nachME( obj, me );
+    return 1;
+}
+
+bool KETNachTE( void *p, void *obj, TastaturEreignis te )
+{
+    if( p )
+        ( (KETeams*)p )->nachTE( obj, te );
+    return 1;
+}
+
+// Inhalt der KETeams Klasse aus KETeams.h
+// Konstruktor
+KETeams::KETeams( int karte, Schrift *zSchrift )
+    : Thread()
+{
+    schrift = zSchrift->getThis();
+    Text *kName = infoKlient->getKarteName( karte );
+    Text titel = kName ? kName->getText() : "<Karte>";
+    titel += " - Teams";
+    if( kName )
+        kName->release();
+    fenster = initFenster( 10, 40, 880, 550, zSchrift, Fenster::Style::Sichtbar | Fenster::Style::Titel | Fenster::Style::TitelBuffered | Fenster::Style::Erlaubt | Fenster::Style::Rahmen, titel );
+    teams = initAuswahlListe( 10, 10, 265, 510, zSchrift, AuswahlListe::Style::Normal, {} );
+    teams->setNMausEreignisParameter( this );
+    teams->setNMausEreignis( KETNachME );
+    tName = initTextFeld( 285, 10, 150, 20, zSchrift, TextFeld::Style::TextFeld & ~TextFeld::Style::Erlaubt, "Team Name" );
+    initToolTip( tName, "Name des Teams ändern", zSchrift->getThis(), hauptScreen );
+    tName->setNTastaturEreignisParameter( this );
+    tName->setNTastaturEreignis( KETNachTE );
+    tFarbe = initTextFeld( 285, 40, 150, 20, zSchrift, TextFeld::Style::TextFeld & ~TextFeld::Style::Erlaubt, "Team Farbe" );
+    initToolTip( tFarbe, "Farbe des Teams ändern", zSchrift->getThis(), hauptScreen );
+    tFarbe->setTastaturEreignis( _nurHexTE );
+    tFarbe->setNTastaturEreignisParameter( this );
+    tFarbe->setNTastaturEreignis( KETNachTE );
+    tFarbeV = initZeichnungHintergrund( 285, 70, 150, 20, ZeichnungHintergrund::Style::Sichtbar | ZeichnungHintergrund::Style::Hintergrund, 0 );
+    tNeu = initKnopf( 285, 100, 150, 20, zSchrift, Knopf::Style::Sichtbar, "Neues Team" );
+    tNeu->setNMausEreignisParameter( this );
+    tNeu->setNMausEreignis( KETNachME );
+    tLöschen = initKnopf( 285, 130, 150, 20, zSchrift, Knopf::Style::Sichtbar, "Team remove" );
+    tLöschen->removeStyle( Knopf::Style::Erlaubt );
+    tLöschen->setNMausEreignisParameter( this );
+    tLöschen->setNMausEreignis( KETNachME );
+    spieler = initAuswahlListe( 445, 10, 265, 510, zSchrift, AuswahlListe::Style::Normal & ~AuswahlListe::Style::Erlaubt, {} );
+    spieler->setNMausEreignisParameter( this );
+    spieler->setNMausEreignis( KETNachME );
+    sFarbe = initTextFeld( 720, 10, 150, 20, zSchrift, TextFeld::Style::TextFeld & ~TextFeld::Style::Erlaubt, "Spieler Farbe" );
+    initToolTip( sFarbe, "Farbe des Spielers ändern", zSchrift->getThis(), hauptScreen );
+    sFarbe->setTastaturEreignis( _nurHexTE );
+    sFarbe->setNTastaturEreignisParameter( this );
+    sFarbe->setNTastaturEreignis( KETNachTE );
+    sFarbeV = initZeichnungHintergrund( 720, 40, 150, 20, ZeichnungHintergrund::Style::Sichtbar | ZeichnungHintergrund::Style::Hintergrund, 0 );
+    sNeu = initKnopf( 720, 70, 150, 20, zSchrift, Knopf::Style::Sichtbar, "Neuer Spieler" );
+    sNeu->removeStyle( Knopf::Style::Erlaubt );
+    sNeu->setNMausEreignisParameter( this );
+    sNeu->setNMausEreignis( KETNachME );
+    sLöschen = initKnopf( 720, 100, 150, 20, zSchrift, Knopf::Style::Sichtbar, "Spieler remove" );
+    sLöschen->removeStyle( Knopf::Style::Erlaubt );
+    sLöschen->setNMausEreignisParameter( this );
+    sLöschen->setNMausEreignis( KETNachME );
+    abbrechen = initKnopf( 720, 470, 150, 20, zSchrift, Knopf::Style::Sichtbar, "Abbrechen" );
+    initToolTip( abbrechen, "Verwirft alle änderungen an den Team Einstellungen", zSchrift->getThis(), hauptScreen );
+    abbrechen->setNMausEreignisParameter( this );
+    abbrechen->setNMausEreignis( KETNachME );
+    speichern = initKnopf( 720, 500, 150, 20, zSchrift, Knopf::Style::Sichtbar, "Speichern" );
+    initToolTip( speichern, "Speichert alle Änderungen an den Team Einstellungen", zSchrift->getThis(), hauptScreen );
+    speichern->setNMausEreignisParameter( this );
+    speichern->setNMausEreignis( KETNachME );
+    fenster->addMember( teams );
+    fenster->addMember( tName );
+    fenster->addMember( tFarbe );
+    fenster->addMember( tFarbeV );
+    fenster->addMember( tNeu );
+    fenster->addMember( tLöschen );
+    fenster->addMember( spieler );
+    fenster->addMember( sFarbe );
+    fenster->addMember( sFarbeV );
+    fenster->addMember( sNeu );
+    fenster->addMember( sLöschen );
+    fenster->addMember( abbrechen );
+    fenster->addMember( speichern );
+    laden = (Animation2D*)ladeAnimation->dublizieren();
+    laden->setPosition( 425, 275 );
+    laden->setSichtbar( 0 );
+    sts = new SpielerTeamStruktur();
+    animation = 0;
+    tickVal = 0;
+    sichtbar = 0;
+    rechts = 0;
+    xStart = 0;
+    breite = 0;
+    aktion = 0;
+    this->karte = karte;
+    alpha = 255;
+    ref = 1;
+}
+
+// Destruktor
+KETeams::~KETeams()
+{
+    if( run )
+    {
+        warteAufThread( 5000 );
+        if( run )
+            ende();
+    }
+    fenster->release();
+    laden->release();
+    schrift->release();
+    teams->release();
+    tName->release();
+    tFarbe->release();
+    delete tFarbeV;
+    tNeu->release();
+    tLöschen->release();
+    spieler->release();
+    sFarbe->release();
+    delete sFarbeV;
+    sNeu->release();
+    sLöschen->release();
+    abbrechen->release();
+    speichern->release();
+    sts->release();
+}
+
+// privat
+void KETeams::updateGUI()
+{
+    Text *teamAusw = teams->zEintrag( teams->getAuswahl() ) ? teams->zEintrag( teams->getAuswahl() )->getText() : 0;
+    Text *spielerAusw = spieler->zEintrag( spieler->getAuswahl() ) ? spieler->zEintrag( spieler->getAuswahl() )->getText() : 0;
+    hauptScreen->lock();
+    teams->deSelect();
+    spieler->deSelect();
+    while( teams->getEintragAnzahl() )
+        teams->removeEintrag( 0 );
+    while( spieler->getEintragAnzahl() )
+        spieler->removeEintrag( 0 );
+    for( int i = 0; i < sts->teamAnzahl; i++ )
+    {
+        teams->addEintrag( sts->teamName->z( i )->getText() );
+        if( teamAusw && teamAusw->istGleich( sts->teamName->z( i )->getText() ) )
+        {
+            teams->setAuswahl( i );
+            tName->setText( sts->teamName->z( i )->getText() );
+            Text f = "";
+            f.appendHex( sts->teamFarbe->get( i ) );
+            tFarbe->setText( f );
+            tFarbeV->setHintergrundFarbe( sts->teamFarbe->get( i ) );
+        }
+    }
+    int start = 0;
+    for( int i = 0; i < teams->getAuswahl(); i++ )
+        start += sts->teamGröße->get( i );
+    bool tausw = teams->zEintrag( teams->getAuswahl() ) != 0;
+    if( tausw )
+    {
+        for( int i = 0; i < sts->teamGröße->get( teams->getAuswahl() ); i++ )
+        {
+            Text n = "Spieler ";
+            n += i + 1;
+            spieler->addEintrag( n );
+            if( spielerAusw && spielerAusw->istGleich( n ) )
+            {
+                spieler->setAuswahl( i );
+                Text f = "";
+                f.appendHex( sts->spielerFarbe->get( start + i ) );
+                sFarbe->setText( f );
+                sFarbeV->setHintergrundFarbe( sts->spielerFarbe->get( start + i ) );
+            }
+        }
+    }
+    sts->spielerAnzahl = 0;
+    for( int i = 0; i < sts->teamAnzahl; i++ )
+        sts->spielerAnzahl += sts->teamGröße->get( i );
+    hauptScreen->unlock();
+    bool sAusw = spieler->zEintrag( spieler->getAuswahl() ) != 0;
+    tName->setStyle( TextFeld::Style::Erlaubt, tausw );
+    tFarbe->setStyle( TextFeld::Style::Erlaubt, tausw );
+    tLöschen->setStyle( Knopf::Style::Erlaubt, tausw );
+    spieler->setStyle( AuswahlListe::Style::Erlaubt, tausw );
+    sNeu->setStyle( Knopf::Style::Erlaubt, tausw );
+    sFarbe->setStyle( TextFeld::Style::Erlaubt, sAusw );
+    sLöschen->setStyle( Knopf::Style::Erlaubt, sAusw );
+    if( teamAusw )
+        teamAusw->release();
+    if( spielerAusw )
+        spielerAusw->release();
+}
+
+// nicht constant
+void KETeams::nachME( void *obj, MausEreignis &me )
+{
+    if( me.id != ME_RLinks )
+        return;
+    if( obj == speichern )
+    {
+        aktion = 1;
+        start();
+    }
+    if( obj == abbrechen )
+    {
+        aktion = 0;
+        start();
+    }
+    if( obj == tNeu )
+    {
+        sts->teamGröße->set( 0, sts->teamAnzahl );
+        sts->teamFarbe->set( 0, sts->teamAnzahl );
+        Text tn = "";
+        bool ex = 1;
+        for( int i = 1; ex; i++ )
+        {
+            tn = "Team ";
+            tn += i;
+            ex = 0;
+            for( int j = 0; j < sts->teamAnzahl; j++ )
+            {
+                if( sts->teamName->z( j )->istGleich( tn ) )
+                {
+                    ex = 1;
+                    break;
+                }
+            }
+        }
+        sts->teamName->set( new Text( (char*)tn ), sts->teamAnzahl );
+        sts->teamAnzahl++;
+        updateGUI();
+    }
+    if( obj == tLöschen )
+    {
+        sts->teamGröße->remove( teams->getAuswahl() );
+        sts->teamFarbe->remove( teams->getAuswahl() );
+        sts->teamName->remove( teams->getAuswahl() );
+        sts->teamAnzahl--;
+        updateGUI();
+    }
+    if( obj == sNeu )
+    {
+        int start = 0;
+        for( int i = 0; i < teams->getAuswahl(); i++ )
+            start += sts->teamGröße->get( i );
+        sts->spielerFarbe->add( 0, start + sts->teamGröße->get( teams->getAuswahl() ) );
+        sts->teamGröße->set( sts->teamGröße->get( teams->getAuswahl() ) + 1, teams->getAuswahl() );
+        updateGUI();
+    }
+    if( obj == sLöschen )
+    {
+        int start = 0;
+        for( int i = 0; i < teams->getAuswahl(); i++ )
+            start += sts->teamGröße->get( i );
+        sts->spielerFarbe->remove( start + spieler->getAuswahl() );
+        sts->teamGröße->set( sts->teamGröße->get( teams->getAuswahl() ) - 1, teams->getAuswahl() );
+        updateGUI();
+    }
+    if( obj == teams )
+        updateGUI();
+    if( obj == spieler )
+        updateGUI();
+}
+
+void KETeams::nachTE( void *obj, TastaturEreignis &te )
+{
+    if( te.id != TE_Release )
+        return;
+    if( obj == tName )
+    {
+        sts->teamName->set( new Text( tName->zText()->getText() ), teams->getAuswahl() );
+        teams->zEintrag( teams->getAuswahl() )->setText( sts->teamName->z( teams->getAuswahl() )->getText() );
+    }
+    if( obj == tFarbe )
+    {
+        sts->teamFarbe->set( TextZuInt( tFarbe->zText()->getText(), 16 ), teams->getAuswahl() );
+        tFarbeV->setHintergrundFarbe( sts->teamFarbe->get( teams->getAuswahl() ) );
+    }
+    if( obj == sFarbe )
+    {
+        int start = 0;
+        for( int i = 0; i < teams->getAuswahl(); i++ )
+            start += sts->teamGröße->get( i );
+        sts->spielerFarbe->set( TextZuInt( sFarbe->zText()->getText(), 16 ), start + spieler->getAuswahl() );
+        sFarbeV->setHintergrundFarbe( sts->spielerFarbe->get( start + spieler->getAuswahl() ) );
+    }
+}
+
+void KETeams::setSichtbar( bool s, bool vr )
+{
+    animation = 1;
+    sichtbar = s;
+    rechts = vr;
+    if( sichtbar )
+    {
+        if( vr )
+        {
+            xStart = 900;
+            breite = 0;
+        }
+        else
+        {
+            xStart = 0;
+            breite = 0;
+        }
+        if( !run )
+        {
+            aktion = 0;
+            start();
+        }
+    }
+}
+
+void KETeams::thread()
+{
+    laden->setSichtbar( 1 );
+    if( aktion == 0 )
+    { // Laden
+        if( !editorKlient->ladeTeamDaten( sts ) )
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+        else
+            updateGUI();
+    }
+    if( aktion == 1 )
+    { // Speichern
+        if( !editorKlient->speicherTeamDaten( sts ) )
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
+    }
+    run = 0;
+    laden->setSichtbar( 0 );
+    return;
+}
+
+void KETeams::doMausEreignis( MausEreignis &me )
+{
+    if( !run )
+        fenster->doMausEreignis( me );
+}
+
+void KETeams::doTastaturEreignis( TastaturEreignis &te )
+{
+    if( !run )
+        fenster->doTastaturEreignis( te );
+}
+
+bool KETeams::tick( double z )
+{
+    bool ret = laden->tick( z );
+    tickVal += z * 150;
+    int val = (int)tickVal;
+    tickVal -= val;
+    if( val )
+    {
+        if( run && alpha > 100 )
+        {
+            if( alpha - val < 100 )
+                alpha = 100;
+            else
+                alpha -= val;
+            ret = 1;
+        }
+        if( sichtbar && !run && alpha != 255 )
+        {
+            if( alpha + val > 255 )
+                alpha = 255;
+            else
+                alpha += val;
+            ret = 1;
+        }
+        val *= 3;
+        if( sichtbar )
+        {
+            if( alpha < 100 )
+            {
+                if( alpha + val > 100 )
+                    alpha = 100;
+                else
+                    alpha += val;
+                ret = 1;
+            }
+            if( xStart != 0 || breite != 900 )
+            {
+                if( rechts )
+                {
+                    if( xStart - val <= 0 )
+                    {
+                        xStart = 0;
+                        breite = 900;
+                        animation = 0;
+                    }
+                    else
+                    {
+                        xStart -= val;
+                        breite += val;
+                    }
+                }
+                else
+                {
+                    if( breite + val >= 900 )
+                    {
+                        breite = 900;
+                        animation = 0;
+                    }
+                    else
+                        breite += val;
+                }
+                ret = 1;
+            }
+        }
+        else
+        {
+            if( breite != 0 )
+            {
+                if( rechts )
+                {
+                    if( breite - val <= 0 )
+                    {
+                        breite = 0;
+                        animation = 0;
+                    }
+                    else
+                        breite -= val;
+                }
+                else
+                {
+                    if( breite - val <= 0 )
+                    {
+                        breite = 0;
+                        xStart = 900;
+                        animation = 0;
+                    }
+                    else
+                    {
+                        breite -= val;
+                        xStart += val;
+                    }
+                }
+                ret = 1;
+            }
+        }
+    }
+    return ret || fenster->tick( z );
+}
+
+void KETeams::render( Bild &zRObj )
+{
+    if( !zRObj.setDrawOptions( xStart, 0, breite, 600 ) )
+        return;
+    zRObj.setAlpha( alpha );
+    fenster->render( zRObj );
+    zRObj.releaseAlpha();
+    laden->render( zRObj );
+    zRObj.releaseDrawOptions();
+}
+
+// constant
+bool KETeams::istSichtbar() const
+{
+    return sichtbar || animation;
+}
+
+// Reference Counting
+KETeams *KETeams::getThis()
+{
+    ref++;
+    return this;
+}
+
+KETeams *KETeams::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 65 - 0
KSGClient/NachLogin/Editor/Karte/Teams/KETeams.h

@@ -0,0 +1,65 @@
+#pragma once
+
+#include "../../../../Strukturen/Strukturen.h"
+#include <Fenster.h>
+#include <Thread.h>
+#include <Animation.h>
+#include <Liste.h>
+#include <Knopf.h>
+
+using namespace Framework;
+
+class KETeams : private Thread
+{
+private:
+    Fenster *fenster;
+    Animation2D *laden;
+    Schrift *schrift;
+    AuswahlListe *teams;
+    TextFeld *tName;
+    TextFeld *tFarbe;
+    ZeichnungHintergrund *tFarbeV;
+    Knopf *tNeu;
+    Knopf *tLöschen;
+    AuswahlListe *spieler;
+    TextFeld *sFarbe;
+    ZeichnungHintergrund *sFarbeV;
+    Knopf *sNeu;
+    Knopf *sLöschen;
+    Knopf *abbrechen;
+    Knopf *speichern;
+    SpielerTeamStruktur *sts;
+    int aktion;
+    bool animation;
+    double tickVal;
+    bool sichtbar;
+    bool rechts;
+    int xStart;
+    int breite;
+    int karte;
+    unsigned char alpha;
+    int ref;
+
+    // privat
+    void updateGUI();
+
+public:
+    // Konstruktor
+    KETeams( int karte, Schrift *zSchrift );
+    // Destruktor
+    ~KETeams();
+    // nicht constant
+    void nachME( void *obj, MausEreignis &me );
+    void nachTE( void *obj, TastaturEreignis &te );
+    void setSichtbar( bool s, bool vr );
+    void thread() override;
+    void doMausEreignis( MausEreignis &me );
+    void doTastaturEreignis( TastaturEreignis &te );
+    bool tick( double z );
+    void render( Bild &zRObj );
+    // constant
+    bool istSichtbar() const;
+    // Reference Counting
+    KETeams *getThis();
+    KETeams *release();
+};

+ 86 - 0
KSGClient/NachLogin/Einstellungen/Einstellungen.cpp

@@ -0,0 +1,86 @@
+#include "Einstellungen.h"
+#include <MausEreignis.h>
+#include "../../Global/Initialisierung.h"
+
+// Inhalt der Einstellungen Klasse aus Einstellungen.h
+// Konstruktor
+Einstellungen::Einstellungen( Schrift *zSchrift, Fenster *zF )
+{
+	f = initFenster( zF->getBreite() / 2 - 250, zF->getHeight() / 2 - 250, 500, 500, zSchrift, 
+					 Fenster::Style::normal | Fenster::Style::BodyHAlpha | Fenster::Style::BodyHintergrund | 
+					 Fenster::Style::TitelHintergrund | Fenster::Style::TitelHAlpha, "Einstellungen" );
+	f->removeStyle( Fenster::Style::Sichtbar );
+	f->setKBgFarbe( 0xe0000000 );
+	f->setTBgFarbe( 0xe0000000 );
+	f->setSBgFarbe( 0xF0000000 );
+	f->setClosingMeParam( this );
+	f->setClosingMe( einstellungenSchließenME );
+	ok = initKnopf( 390, 450, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Ok" );
+	ok->setMausEreignisParameter( this );
+	ok->setMausEreignis( einstellungenOkME );
+	f->addMember( ok );
+	zF->addMember( f );
+	ref = 1;
+}
+
+// Destruktor
+Einstellungen::~Einstellungen()
+{
+	f->release();
+	ok->release();
+}
+
+// nicht constant
+void Einstellungen::setSichtbar()
+{
+	//-------------------
+	f->setStyle( Fenster::Style::Sichtbar, f->hatStyleNicht( Fenster::Style::Sichtbar ) );
+}
+
+bool Einstellungen::closeME( MausEreignis &me )
+{
+	if( me.id == ME_RLinks )
+		f->removeStyle( Fenster::Style::Sichtbar );
+	return 1;
+}
+
+bool Einstellungen::okME( MausEreignis &me )
+{
+	if( me.id == ME_RLinks )
+	{
+		f->removeStyle( Fenster::Style::Sichtbar );
+		//-----------------------------
+	}
+	return 1;
+}
+
+// Reference Counting
+Einstellungen *Einstellungen::getThis()
+{
+	ref++;
+	return this;
+}
+
+Einstellungen *Einstellungen::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Ereignisse
+bool einstellungenSchließenME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 1;
+	return ( (Einstellungen*)p )->closeME( me );
+}
+
+bool einstellungenOkME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 1;
+	return ( (Einstellungen*)p )->okME( me );
+}

+ 34 - 0
KSGClient/NachLogin/Einstellungen/Einstellungen.h

@@ -0,0 +1,34 @@
+#ifndef Einstellungen_H
+#define Einstellungen_H
+
+#include <Fenster.h>
+#include <Knopf.h>
+
+using namespace Framework;
+
+class Einstellungen
+{
+private:
+	Fenster *f;
+	Knopf *ok;
+	int ref;
+
+public:
+	// Konstruktor
+	Einstellungen( Schrift *zSchrift, Fenster *zF );
+	// Destruktor
+	~Einstellungen();
+	// nicht constant
+	void setSichtbar();
+	bool closeME( MausEreignis &me );
+	bool okME( MausEreignis &me );
+	// Reference Counting
+	Einstellungen *getThis();
+	Einstellungen *release();
+};
+
+// Ereignisse
+bool einstellungenSchließenME( void *p, void *obj, MausEreignis me );
+bool einstellungenOkME( void *p, void *obj, MausEreignis me );
+
+#endif

+ 242 - 0
KSGClient/NachLogin/ImSpiel/ImSpiel.cpp

@@ -0,0 +1,242 @@
+#include "ImSpiel.h"
+#include <Fenster.h>
+#include <Schrift.h>
+#include "..\..\Leser\KartenLeser.h"
+#include "..\..\Global\Variablen.h"
+
+typedef SpielV* ( *DllStart )( void );
+
+// Inhalt der ImSpielObj Klasse aus ImSpiel.h
+// Konstruktor
+ImSpiel::ImSpiel( Schrift *zSchrift )
+	: Thread()
+{
+	sichtbar = 0;
+	ladenFenster = 0;
+	spielFenster = 0;
+	schrift = zSchrift->getThis();
+	ladenStatus = 0;
+	karteId = 0;
+	mainDll = 0;
+	dllName = 0;
+	rend = 0;
+	ref = 1;
+}
+
+// Destruktor
+ImSpiel::~ImSpiel()
+{
+	if( sichtbar )
+		setSichtbar( 0 );
+	schrift->release();
+}
+
+// nicht constant
+void ImSpiel::setSichtbar( bool sichtbar )
+{
+	if( sichtbar && !this->sichtbar )
+	{
+		ladenFenster = new SpielLaden( schrift );
+		spielFenster = 0;
+		ladenStatus = 0;
+		karteId = 0;
+		mainDll = 0;
+		dllName = new Text( "" );
+		this->sichtbar = 1;
+	}
+	else if( !sichtbar && this->sichtbar )
+	{
+		if( ladenFenster )
+			ladenFenster->release();
+		if( spielFenster )
+			spielFenster->release();
+		if( mainDll )
+			dllDateien->releaseDLL( *dllName );
+		dllName->release();
+		this->sichtbar = 0;
+	}
+}
+void ImSpiel::beginnLaden( int karteId, SpielerTeamStruktur *sts )
+{
+	if( !sichtbar )
+		return;
+	ladenFenster->setSpielerTeamStruktur( sts );
+	ladenFenster->setKarte( karteId );
+	ladenFenster->setSichtbar( 1 );
+	this->karteId = karteId;
+	spielKlient->bereitZumLaden();
+	rend = 1;
+	start();
+}
+
+void ImSpiel::lBAddSpieler( int accountId, int spielerNummer )
+{
+	if( !sichtbar )
+		return;
+	ladenFenster->addSpieler( accountId, spielerNummer );
+	rend = 1;
+}
+
+void ImSpiel::lBSetSpielerProzent( int accountId, int prozent )
+{
+	if( !sichtbar )
+		return;
+	ladenFenster->setSpielerFortschritt( accountId, prozent );
+	rend = 1;
+}
+
+void ImSpiel::lBSetSpielerPing( int accountId, int ping )
+{
+	if( !sichtbar )
+		return;
+	ladenFenster->setSpielerPing( accountId, ping );
+	rend = 1;
+}
+
+void ImSpiel::spielNachricht( int län, char *bytes )
+{
+	if( !sichtbar )
+		return;
+	if( ladenStatus > 1 )
+		spielFenster->nachricht( län, bytes );
+}
+
+void ImSpiel::endLaden()
+{
+	if( !sichtbar )
+		return;
+	ladenFenster->setSichtbar( 0 );
+}
+
+void ImSpiel::thread()
+{
+	KartenLeser *reader = new KartenLeser();
+	reader->setKarteId( karteId );
+	Text *pfad = reader->getSpielPfad();
+	pfad->append( "bin/" );
+	pfad->append( reader->getSpielName() );
+	pfad->append( ".dll" );
+	dllName->setText( "Spiele/" );
+	dllName->append( reader->getSpielName() );
+	reader->release();
+	dllName->append( ".dll" );
+	mainDll = dllDateien->ladeDLL( *dllName, *pfad );
+	if( !mainDll )
+	{
+		Text *nachricht = new Text( "Die Spiel DLL " );
+		nachricht->append( pfad->getText() );
+		nachricht->append( " konnte nicht geladen werden.\n" );
+		nachricht->append( "Wenn sie nicht existiert dann installiere das Spiel neu." );
+		WMessageBox( 0, new Text( "Unerwarteter Fehler" ), nachricht, MB_ICONERROR );
+		//------------------------------
+		exit( 0 );
+	}
+	pfad->release();
+	DllStart getSpielKlasse = (DllStart)GetProcAddress( mainDll, "getSpielKlasse" );
+	if( !getSpielKlasse )
+	{
+		Text *nachricht = new Text( "Die Spiel DLL " );
+		nachricht->append( pfad->getText() );
+		nachricht->append( " konnte nicht geladen werden.\n" );
+		nachricht->append( "Die Einstiegsfunktion getSpielKlasse() wurde nicht gefunden." );
+		WMessageBox( 0, new Text( "Unerwarteter Fehler" ), nachricht, MB_ICONERROR );
+		//------------------------------
+		exit( 0 );
+	}
+    int port = 0;
+    Text ip;
+    infoKlient->getKartenServer( karteId, &port, &ip );
+    if( kartenKlient->verbinde( port, ip ) )
+        kartenKlient->downloadKarte( karteId );
+	spielFenster = getSpielKlasse();
+	ladenStatus = 1;
+	spielFenster->setKarteId( karteId );
+	spielFenster->setKlients( infoKlient->getThis(), spielKlient->getThis() );
+	spielFenster->setBildschirm( hauptScreen->getThis() );
+	spielFenster->setSchrift( schrift->getThis() );
+	spielFenster->ladeDaten();
+	ladenStatus = 2;
+	run = 0;
+}
+
+bool ImSpiel::tick( double tickVal )
+{
+	if( !sichtbar )
+		return 0;
+	if( ladenStatus < 3 ) // Vor dem Spiel
+		rend |= ladenFenster->tick( tickVal );
+	if( ladenStatus == 2 ) // Im spiel
+	{
+		rend |= spielFenster->tick( tickVal );
+		if( spielFenster->läuft() == 1 )
+		{
+			ladenStatus = 3;
+			rend = 1;
+		}
+	}
+	if( ladenStatus == 3 ) // Ende des Spiels
+	{
+		rend |= spielFenster->tick( tickVal );
+		if( !spielFenster->läuft() )
+		{
+			ladenStatus = 4;
+			aktion = 6; // Spiel Statistik laden (Render => new AktionsThread( 20, 0, 0, 0, 0, 0 ))
+			rend = 1;
+		}
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void ImSpiel::doMausEreignis( MausEreignis &me )
+{
+	if( !sichtbar )
+		return;
+	if( ladenStatus > 1 )
+		spielFenster->doMausEreignis( me );
+}
+
+void ImSpiel::doTastaturEreignis( TastaturEreignis &te )
+{
+	if( !sichtbar )
+		return;
+	if( ladenStatus > 1 )
+		spielFenster->doTastaturEreignis( te );
+}
+
+void ImSpiel::render( Bild &zRObj )
+{
+	if( !sichtbar )
+		return;
+	if( ladenStatus < 3 && ( !spielFenster || spielFenster->läuft() == 3 ) )
+		ladenFenster->render( zRObj );
+	if( ladenStatus == 3 || ladenStatus == 2 )
+		spielFenster->render( zRObj );
+}
+
+// constant
+int ImSpiel::getKarteId() const
+{
+	return karteId;
+}
+
+bool ImSpiel::istSichtbar() const
+{
+	return sichtbar;
+}
+
+// Reference Counting
+ImSpiel *ImSpiel::getThis()
+{
+	ref++;
+	return this;
+}
+
+ImSpiel *ImSpiel::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 48 - 0
KSGClient/NachLogin/ImSpiel/ImSpiel.h

@@ -0,0 +1,48 @@
+#ifndef ImSpiel_H
+#define ImSpiel_H
+
+#include "Laden\SpielLaden.h"
+#include <SpielV.h>
+#include <Bildschirm.h>
+
+class ImSpiel : private Thread
+{
+private:
+	SpielLaden *ladenFenster;
+	SpielV *spielFenster;
+	Schrift *schrift;
+	int ladenStatus;
+	int karteId;
+	HINSTANCE mainDll;
+	Text *dllName;
+	bool sichtbar;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	ImSpiel( Schrift *zSchrift );
+	// Destruktor
+	~ImSpiel();
+	// nicht constant
+	void setSichtbar( bool sichtbar );
+	void beginnLaden( int karteId, SpielerTeamStruktur *sts );
+	void lBAddSpieler( int accountId, int spielerNummer );
+	void lBSetSpielerProzent( int accountId, int prozent );
+	void lBSetSpielerPing( int accountId, int ping );
+	void spielNachricht( int län, char *bytes );
+	void endLaden();
+	void thread() override;
+	bool tick( double tickVal );
+	void doMausEreignis( MausEreignis &me );
+	void doTastaturEreignis( TastaturEreignis &te );
+	void render( Bild &zRObj );
+	// constant
+	int getKarteId() const;
+	bool istSichtbar() const;
+	// Reference Counting
+	ImSpiel *getThis();
+	ImSpiel *release();
+};
+
+#endif

+ 603 - 0
KSGClient/NachLogin/ImSpiel/Laden/SpielLaden.cpp

@@ -0,0 +1,603 @@
+#include "SpielLaden.h"
+#include "..\..\..\Global\Variablen.h"
+#include "..\..\..\Global\Initialisierung.h"
+#include "..\..\..\Leser\KartenLeser.h"
+#include <DateiSystem.h>
+#include <Rahmen.h>
+#include <AlphaFeld.h>
+#include <Punkt.h>
+
+// Inhalt der SpielLadenListeSpieler Klasse aus SpielLaden.h
+// Konstruktor
+SpielLadenListeSpieler::SpielLadenListeSpieler( int accountId, Schrift *zSchrift )
+{
+	rahmen = new LRahmen();
+	rahmen->setSize( 862, 22 );
+	rahmen->setRamenBreite( 1 );
+	rahmen->setFarbe( 0xFFFFFFFF );
+	this->accountId = accountId;
+	Text *n = infoKlient->getSpielerName( accountId );
+	name = initTextFeld( 1, 1, 149, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, n->getText() );
+	n->release();
+	team = initTextFeld( 230, 1, 100, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "0" );
+	ping = initTextFeld( 410, 1, 50, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "0" );
+	fortschritt = new FBalken();
+	fortschritt->setStyle( FBalken::Style::Hintergrund | FBalken::Style::HBild | FBalken::Style::L_R | FBalken::Style::FBild | FBalken::Style::Prozent | FBalken::Style::Sichtbar );
+	fortschritt->setSchriftZ( zSchrift->getThis() );
+	fortschritt->setSFarbe( 0xFFFFFFFF );
+	fortschritt->setSSize( 12 );
+	fortschritt->setPosition( 461, 1 );
+	fortschritt->setSize( 400, 20 );
+	fortschritt->reset();
+	fortschritt->setAktionAnzahl( 100 );
+	Bild *fbhb = bilder->get( "system.ltdb/fortschritt lehr.png" );
+	if( !fbhb )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/bilder/system.ltdb" ) );
+		datei->leseDaten( 0 );
+		fbhb = datei->laden( 0, new Text( "fortschrittleh" ) );
+		datei->release();
+		bilder->add( "system.ltdb/fortschritt lehr.png", fbhb->getThis() );
+	}
+	Bild *fbfhb = bilder->get( "system.ltdb/fortschritt voll.png" );
+	if( !fbfhb )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/bilder/system.ltdb" ) );
+		datei->leseDaten( 0 );
+		fbfhb = datei->laden( 0, new Text( "fortschrittvol" ) );
+		datei->release();
+		bilder->add( "system.ltdb/fortschritt voll.png", fbfhb->getThis() );
+	}
+	fortschritt->setHintergrundBildZ( fbhb );
+	fortschritt->setFBgBildZ( fbfhb );
+	spielerFarbe = 0;
+	teamFarbe = 0;
+	p = 0;
+	teamName = new Text( "" );
+	rend = 0;
+	ref = 1;
+}
+
+// Destruktor
+SpielLadenListeSpieler::~SpielLadenListeSpieler()
+{
+	rahmen->release();
+	name->release();
+	team->release();
+	ping->release();
+	fortschritt->release();
+	teamName->release();
+}
+
+// nicht constant
+void SpielLadenListeSpieler::setFortschritt( int prozent )
+{
+	fortschritt->aktionPlus( prozent - fortschritt->getAktion() );
+	rend = 1;
+}
+
+void SpielLadenListeSpieler::setPing( int ping )
+{
+	p = ping;
+	rend = 1;
+}
+
+void SpielLadenListeSpieler::setTeamName( Text *zName )
+{
+	teamName->setText( zName->getText() );
+	rend = 1;
+}
+
+void SpielLadenListeSpieler::setSpielerFarbe( int farbe )
+{
+	spielerFarbe = farbe;
+	rend = 1;
+}
+
+void SpielLadenListeSpieler::setTeamFarbe( int farbe )
+{
+	teamFarbe = farbe;
+	rend = 1;
+}
+
+bool SpielLadenListeSpieler::tick( double tickVal )
+{
+	if( !team->zText()->istGleich( teamName->getText() ) )
+	{
+		team->setText( teamName->getText() );
+		rend = 1;
+	}
+	if( TextZuInt( ping->zText()->getText(), 10 ) != p )
+	{
+		ping->setText( "" );
+		ping->zText()->append( p );
+		rend = 1;
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void SpielLadenListeSpieler::render( int y, Bild &zRObj )
+{
+	if( !zRObj.setDrawOptions( 0, y, 862, 22 ) )
+		return;
+	rahmen->render( zRObj );
+	name->render( zRObj );
+	zRObj.alphaRegion( 170, 1, 40, 20, spielerFarbe );
+	team->render( zRObj );
+	zRObj.alphaRegion( 350, 1, 40, 20, teamFarbe );
+	ping->render( zRObj );
+	fortschritt->render( zRObj );
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+int SpielLadenListeSpieler::getAccountId() const
+{
+	return accountId;
+}
+
+// Reference Counting
+SpielLadenListeSpieler *SpielLadenListeSpieler::getThis()
+{
+	ref++;
+	return this;
+}
+
+SpielLadenListeSpieler *SpielLadenListeSpieler::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Inhalt der SpielLadenListe Klasse aus SpielLaden.h
+// Konstruktor
+SpielLadenListe::SpielLadenListe( Schrift *zSchrift )
+{
+	bildschirmGröße = BildschirmGröße();
+	spielerAnzahl = 0;
+	höhe = 0;
+	breite = 0;
+	tickVal = 0;
+	spielerName = initTextFeld( 1, 1, 149, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Spieler Name" );
+	spielerFarbe = initTextFeld( 150, 1, 90, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Spieler Farbe" );
+	teamName = initTextFeld( 230, 1, 100, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Team Name" );
+	teamFarbe = initTextFeld( 330, 1, 80, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Team Farbe" );
+	ping = initTextFeld( 410, 1, 50, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Ping" );
+	fortschritt = initTextFeld( 460, 1, 400, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Fortschritt" );
+	rahmen = new LRahmen();
+	rahmen->setFarbe( 0xFFFFFFFF );
+	rahmen->setRamenBreite( 1 );
+	titel = new AlphaFeld();
+	titel->setFarbe( 0x1000FF00 );
+	titel->setStrength( -15 );
+	spieler = new RCArray < SpielLadenListeSpieler >();
+	sts = 0;
+	schrift = zSchrift->getThis();
+	alpha = 0;
+	animation = 0;
+	rend = 0;
+	ref = 1;
+}
+
+// Destruktor
+SpielLadenListe::~SpielLadenListe()
+{
+	spielerName->release();
+	spielerFarbe->release();
+	teamName->release();
+	teamFarbe->release();
+	ping->release();
+	fortschritt->release();
+	rahmen->release();
+	titel->release();
+	spieler->release();
+	schrift->release();
+	if( sts )
+		sts->release();
+}
+
+// nicht constant
+void SpielLadenListe::setSTS( SpielerTeamStruktur *sts )
+{
+	if( this->sts )
+		this->sts->release();
+	this->sts = sts;
+	rend = 1;
+}
+
+void SpielLadenListe::setSichtbar( bool sichtbar )
+{
+	animation = sichtbar ? 1 : 3;
+}
+
+void SpielLadenListe::addSpieler( int accountId, int spielerNummer )
+{
+	SpielLadenListeSpieler *tmp = new SpielLadenListeSpieler( accountId, schrift );
+	int team = 0;
+	int max = 0;
+	int min = 0;
+	for( int i = 0; i < sts->teamAnzahl; i++ )
+	{
+		min = max;
+		max += sts->teamGröße->get( i );
+		if( spielerNummer >= min && spielerNummer < max )
+		{
+			team = i;
+			break;
+		}
+	}
+	tmp->setSpielerFarbe( sts->spielerFarbe->hat( spielerNummer ) ? sts->spielerFarbe->get( spielerNummer ) : 0 );
+	tmp->setTeamFarbe( sts->teamFarbe->hat( team ) ? sts->teamFarbe->get( team ) : 0 );
+	tmp->setTeamName( sts->teamName->z( team ) );
+	spieler->set( tmp, spielerAnzahl );
+	spielerAnzahl++;
+	rend = 1;
+}
+
+void SpielLadenListe::setSpielerFortschritt( int accountId, int prozent )
+{
+	for( int i = 0; i < spielerAnzahl; i++ )
+	{
+		if( spieler->z( i )->getAccountId() == accountId )
+		{
+			spieler->z( i )->setFortschritt( prozent );
+			break;
+		}
+	}
+}
+
+void SpielLadenListe::setSpielerPing( int accountId, int ping )
+{
+	for( int i = 0; i < spielerAnzahl; i++ )
+	{
+		if( spieler->z( i )->getAccountId() == accountId )
+		{
+			spieler->z( i )->setPing( ping );
+			break;
+		}
+	}
+}
+
+bool SpielLadenListe::tick( double tickVal )
+{
+	for( int i = 0; i < spielerAnzahl; i++ )
+		rend |= spieler->z( i )->tick( tickVal );
+	this->tickVal += tickVal * 500;
+	int val = ( int )this->tickVal;
+	if( !val )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	this->tickVal -= val;
+	if( breite && animation != 4 && höhe != spielerAnzahl * 22 + 23 )
+	{
+		höhe += val / 2;
+		if( höhe > spielerAnzahl * 22 + 23 )
+			höhe = spielerAnzahl * 22 + 23;
+		rend = 1;
+	}
+	switch( animation )
+	{
+	case 1: // größe ++
+		breite += val;
+		if( breite >= 864 )
+		{
+			breite = 864;
+			animation = 2;
+		}
+		rend = 1;
+		break;
+	case 2: // alpha ++
+		if( alpha + val > 255 )
+		{
+			alpha = 255;
+			animation = 0;
+		}
+		else
+			alpha += val;
+		rend = 1;
+		break;
+	case 3: // alpha --
+		if( alpha - val < 0 )
+		{
+			alpha = 0;
+			animation = 4;
+		}
+		else
+			alpha -= val;
+		rend = 1;
+		break;
+	case 4: // größe --
+		breite -= val;
+		if( breite <= 0 )
+		{
+			breite = 0;
+			höhe = 0;
+			animation = 0;
+		}
+		else if( breite < spielerAnzahl * 22 + 23 )
+			höhe = breite;
+		rend = 1;
+		break;
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void SpielLadenListe::render( Bild &zRObj )
+{
+	if( !breite )
+		return;
+	int x = bildschirmGröße.x / 2 - breite / 2;
+	int y = bildschirmGröße.y / 2 - höhe / 2;
+	if( !zRObj.setDrawOptions( x, y, breite, höhe ) )
+		return;
+	rahmen->setSize( breite, höhe );
+	rahmen->render( zRObj );
+	zRObj.setAlpha( alpha );
+	titel->setPosition( 1, 1 );
+	titel->setSize( breite - 2, 20 );
+	titel->render( zRObj );
+	spielerName->render( zRObj );
+	spielerFarbe->render( zRObj );
+	spielerName->render( zRObj );
+	teamFarbe->render( zRObj );
+	ping->render( zRObj );
+	fortschritt->render( zRObj );
+	zRObj.releaseAlpha();
+	zRObj.drawLinieH( 1, 21, breite - 2, 0xFFFFFFFF );
+	if( höhe > 22 )
+	{
+		if( !zRObj.setDrawOptions( 1, 22, breite - 2, höhe - 2 ) )
+		{
+			zRObj.releaseDrawOptions();
+			return;
+		}
+		zRObj.alphaRegion( 0, 0, breite - 2, höhe - 23, 0x50000000 );
+		zRObj.setAlpha( alpha );
+		for( int i = 0; i < spielerAnzahl; i++ )
+			spieler->z( i )->render( i * 22, zRObj );
+		zRObj.releaseAlpha();
+		zRObj.releaseDrawOptions();
+	}
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+int SpielLadenListe::getHeight() const
+{
+	return höhe;
+}
+
+int SpielLadenListe::getAlpha() const
+{
+	return (int)alpha;
+}
+
+// Reference Counting
+SpielLadenListe *SpielLadenListe::getThis()
+{
+	ref++;
+	return this;
+}
+
+SpielLadenListe *SpielLadenListe::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Inhalt der SpielLaden Klasse aus SpielLaden.h
+// Konstruktor
+SpielLaden::SpielLaden( Schrift *zSchrift )
+	: Thread()
+{
+	karteId = 0;
+	bildschirmGröße = BildschirmGröße();
+	hintergrundBild = 0;
+	ladenAlpha = 0;
+	hintergrundAlpha = 0;
+	ladenBild = 0;
+	tickVal = 0;
+	geladen = 0;
+	liste = new SpielLadenListe( zSchrift );
+	animation = 0;
+	ende = 0;
+	rend = 0;
+	ref = 1;
+}
+
+// Destruktor
+SpielLaden::~SpielLaden()
+{
+	warteAufThread( 1000 );
+	if( geladen )
+		hintergrundBild->release();
+	liste->release();
+}
+
+// nicht constant
+void SpielLaden::setSpielerTeamStruktur( SpielerTeamStruktur *sts )
+{
+	liste->setSTS( sts );
+	rend = 1;
+}
+
+void SpielLaden::setKarte( int karteId )
+{
+	this->karteId = karteId;
+	start();
+	rend = 1;
+}
+
+void SpielLaden::setSichtbar( bool sichtbar )
+{
+	animation = sichtbar ? 1 : 4;
+}
+
+void SpielLaden::thread()
+{
+	KartenLeser *reader = new KartenLeser();
+	reader->setKarteId( karteId );
+	hintergrundBild = reader->getLadeBild();
+	reader->release();
+	if( hintergrundBild )
+		geladen = 1;
+	else
+		run = 0;
+}
+
+void SpielLaden::addSpieler( int accountId, int spielerNummer )
+{
+	liste->addSpieler( accountId, spielerNummer );
+}
+
+void SpielLaden::setSpielerFortschritt( int accountId, int prozent )
+{
+	liste->setSpielerFortschritt( accountId, prozent );
+}
+
+void SpielLaden::setSpielerPing( int accountId, int ping )
+{
+	liste->setSpielerPing( accountId, ping );
+}
+
+bool SpielLaden::tick( double tickVal )
+{
+	if( ende )
+		return 0;
+	rend |= liste->tick( tickVal );
+	if( ladenAlpha )
+		rend = 1;
+	ladenBild++;
+	if( ladenBild >= ladeAnimation->zAnimationData()->getBildAnzahl() )
+		ladenBild = 0;
+	if( !animation && geladen && ladenAlpha && !ende )
+		animation = 2;
+	this->tickVal += tickVal * 150;
+	int val = ( int )this->tickVal;
+	if( !val )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	this->tickVal -= val;
+	switch( animation )
+	{ // ------- Beginne zu laden -------
+	case 1: // Sichtbar machen der Ladeanimation
+		if( ladenAlpha + val >= 255 )
+		{
+			ladenAlpha = 255;
+			animation = 0;
+			if( geladen )
+				animation = 2;
+		}
+		else
+			ladenAlpha += val;
+		rend = 1;
+		break;
+	case 2: // Sichtbar machen des Hintergrund Bildes
+		if( hintergrundAlpha + val > 255 )
+		{
+			hintergrundAlpha = 255;
+			animation = 3;
+		}
+		else
+			hintergrundAlpha += val;
+		rend = 1;
+		break;
+	case 3: // Unsichtbar machen der Lade Animation
+		if( ladenAlpha == 255 )
+			liste->setSichtbar( 1 ); // während dessen die Liste sichtbar machen
+		if( ladenAlpha - val < 0 )
+		{
+			ladenAlpha = 0;
+			animation = 0;
+		}
+		else
+			ladenAlpha -= val;
+		rend = 1;
+		break;
+		// ------- Laden beenden -------
+	case 4: // Ladeanimation sichtbar machen
+		if( !ladenAlpha && liste->getAlpha() == 255 )
+			liste->setSichtbar( 0 ); // während dessen die Liste unsichtbar machen
+		if( ladenAlpha + val > 255 )
+		{
+			ladenAlpha = 255;
+			animation = 5;
+		}
+		else
+			ladenAlpha += val;
+		rend = 1;
+		break;
+	case 5: // Hintergrund Bild mit Lade Animation unsichtbar machen
+		if( hintergrundAlpha - val < 0 )
+		{
+			hintergrundAlpha = 0;
+			ladenAlpha = 0;
+			ende = 1;
+			animation = 0;
+			spielKlient->bereitZumSpiel();
+		}
+		else
+		{
+			hintergrundAlpha -= val;
+			ladenAlpha -= val;
+		}
+		rend = 1;
+		break;
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void SpielLaden::render( Bild &zRObj )
+{
+	zRObj.setAlpha( hintergrundAlpha );
+	if( hintergrundBild )
+	{
+		zRObj.drawBild( bildschirmGröße.x / 2 - hintergrundBild->getBreite() / 2, bildschirmGröße.y / 2 - hintergrundBild->getHeight() / 2,
+						hintergrundBild->getBreite(), hintergrundBild->getHeight(), *hintergrundBild );
+	}
+	zRObj.releaseAlpha();
+	liste->render( zRObj );
+	zRObj.setAlpha( ladenAlpha );
+	Bild *zLadenBild = ladeAnimation->zAnimationData()->zBild( ladenBild );
+	zRObj.drawBild( bildschirmGröße.x / 2 - 25, bildschirmGröße.y / 2 - 25, zLadenBild->getBreite(), zLadenBild->getHeight(), *zLadenBild );
+	zRObj.releaseAlpha();
+}
+
+// constant
+int SpielLaden::getAlpha() const
+{
+	return hintergrundAlpha;
+}
+
+// Reference Counting 
+SpielLaden *SpielLaden::getThis()
+{
+	ref++;
+	return this;
+}
+
+SpielLaden *SpielLaden::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 133 - 0
KSGClient/NachLogin/ImSpiel/Laden/SpielLaden.h

@@ -0,0 +1,133 @@
+#ifndef SpielLaden_H
+#define SpielLaden_H
+
+#include <Klient.h>
+#include <Thread.h>
+#include <Bild.h>
+#include <TextFeld.h>
+#include <Fortschritt.h>
+#include "..\..\..\Strukturen\Strukturen.h"
+
+using namespace Framework;
+
+class SpielLadenListeSpieler
+{
+private:
+	int accountId;
+	TextFeld *name;
+	TextFeld *team;
+	TextFeld *ping;
+	FBalken *fortschritt;
+	LRahmen *rahmen;
+	Text *teamName;
+	int p;
+	int spielerFarbe;
+	int teamFarbe;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	SpielLadenListeSpieler( int accountId, Schrift *zSchrift );
+	// Destruktor
+	~SpielLadenListeSpieler();
+	// nicht constant
+	void setFortschritt( int prozent );
+	void setPing( int ping );
+	void setTeamName( Text *zName );
+	void setSpielerFarbe( int farbe );
+	void setTeamFarbe( int farbe );
+	bool tick( double tickVal );
+	void render( int y, Bild &zRObj );
+	// constant
+	int getAccountId() const;
+	// Reference Counting
+	SpielLadenListeSpieler *getThis();
+	SpielLadenListeSpieler *release();
+};
+
+class SpielLadenListe
+{
+private:
+	int spielerAnzahl;
+	int höhe;
+	int breite;
+	double tickVal;
+	TextFeld *spielerName;
+	TextFeld *spielerFarbe;
+	TextFeld *teamName;
+	TextFeld *teamFarbe;
+	TextFeld *ping;
+	TextFeld *fortschritt;
+	LRahmen *rahmen;
+	AlphaFeld *titel;
+	RCArray < SpielLadenListeSpieler > *spieler;
+	SpielerTeamStruktur *sts;
+	Schrift *schrift;
+	Punkt bildschirmGröße;
+	unsigned char alpha;
+	int animation;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	SpielLadenListe( Schrift *zSchrift );
+	// Destruktor
+	~SpielLadenListe();
+	// nicht constant
+	void setSTS( SpielerTeamStruktur *sts );
+	void setSichtbar( bool sichtbar );
+	void addSpieler( int accountId, int spielerNummer );
+	void setSpielerFortschritt( int accountId, int prozent );
+	void setSpielerPing( int accountId, int ping );
+	bool tick( double tickval );
+	void render( Bild &zRObj );
+	// constant
+	int getHeight() const;
+	int getAlpha() const;
+	// Reference Counting
+	SpielLadenListe *getThis();
+	SpielLadenListe *release();
+};
+
+class SpielLaden : private Thread
+{
+private:
+	int karteId;
+	Punkt bildschirmGröße;
+	Bild *hintergrundBild;
+	unsigned char ladenAlpha;
+	unsigned char hintergrundAlpha;
+	int ladenBild;
+	double tickVal;
+	bool geladen;
+	SpielLadenListe *liste;
+	int animation;
+	bool ende;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	SpielLaden( Schrift *zSchrift );
+	// Destruktor
+	~SpielLaden();
+	// nicht constant
+	void setSpielerTeamStruktur( SpielerTeamStruktur *sts );
+	void setKarte( int karteId );
+	void setSichtbar( bool sichtbar );
+	void thread() override;
+	void addSpieler( int accountId, int spielerNummer );
+	void setSpielerFortschritt( int accountId, int prozent );
+	void setSpielerPing( int accountId, int ping );
+	bool tick( double tickVal );
+	void render( Bild &zRObj );
+	// constant
+	int getAlpha() const;
+	// Reference Counting 
+	SpielLaden *getThis();
+	SpielLaden *release();
+};
+
+#endif

+ 289 - 0
KSGClient/NachLogin/MiniGames/MiniGame.cpp

@@ -0,0 +1,289 @@
+#include "MiniGame.h"
+#include <Rahmen.h>
+#include <Datei.h>
+#include <InitDatei.h>
+#include <DateiSystem.h>
+#include <MausEreignis.h>
+
+// Inhalt der Minigame Klasse aus MiniGame.h
+// Konstruktor
+MiniGame::MiniGame( char *name )
+{
+	xPos = 0;
+	yPos = 0;
+	xAbs = 0;
+	yAbs = 0;
+	zXPos = 0;
+	zYPos = 0;
+	xSpeed = 0;
+	ySpeed = 0;
+	this->name = new Text( name );
+	bgBild = 0;
+	mausAlpha = new AlphaFeld();
+	mausAlpha->setSize( 248, 98 );
+	mausAlpha->setFarbe( 0xFF00FF00 );
+	mausAlpha->setStrength( 50 );
+	rahmen = new LRahmen();
+	rahmen->setSize( 250, 100 );
+	rahmen->setFarbe( 0xFFFFFFFF );
+	rahmen->setRamenBreite( 1 );
+	sichtbar = 1;
+	alpha = 0;
+	mausIn = 0;
+	ok = 1;
+	rend = 0;
+	ref = 1;
+	Text *pfad = new Text( "data/Minigames/" );
+	pfad->append( name );
+	if( !DateiExistiert( pfad->getThis() ) )
+	{
+		ok = 0;
+		pfad->release();
+		return;
+	}
+	pfad->append( "/mg.ini" );
+	if( !DateiExistiert( pfad->getThis() ) )
+	{
+		ok = 0;
+		pfad->release();
+		return;
+	}
+	InitDatei *mgIni = new InitDatei( pfad );
+	if( !mgIni->laden() )
+	{
+		ok = 0;
+		mgIni->release();
+		return;
+	}
+	if( !mgIni->wertExistiert( "TitelBild" ) || !mgIni->wertExistiert( "TitelBildPfad" ) || !mgIni->wertExistiert( "DllPfad" ) )
+	{
+		ok = 0;
+		mgIni->release();
+		return;
+	}
+	Text *bPfad = new Text( "data/Minigames/" );
+	bPfad->append( name );
+	bPfad->append( "/" );
+	bPfad->append( mgIni->zWert( "TitelBildPfad" )->getText() );
+	if( !DateiExistiert( bPfad->getThis() ) )
+	{
+		ok = 0;
+		bPfad->release();
+		mgIni->release();
+		return;
+	}
+	LTDBDatei *bDat = new LTDBDatei();
+	bDat->setDatei( bPfad );
+	bDat->leseDaten( 0 );
+	bgBild = bDat->laden( 0, mgIni->getWert( "TitelBild" ) );
+	bDat->release();
+	mgIni->release();
+	if( !bgBild )
+		ok = 0;
+}
+
+// Destruktor
+MiniGame::~MiniGame()
+{
+	name->release();
+	if( bgBild )
+		bgBild->release();
+	mausAlpha->release();
+	rahmen->release();
+}
+
+// nicht constant
+void MiniGame::setPosition( int x, int y )
+{
+	if( !xPos && !yPos )
+	{
+		xPos = x;
+		yPos = y;
+	}
+	zXPos = x;
+	zYPos = y;
+	xAbs = (int)( zXPos - xPos );
+	yAbs = (int)( zYPos - yPos );
+}
+
+void MiniGame::setSichtbar( bool sichtbar )
+{
+	this->sichtbar = sichtbar;
+}
+
+void MiniGame::doMausEreignis( MausEreignis &me )
+{
+	if( !this->sichtbar )
+		return;
+	if( me.mx > xPos && me.mx < xPos + 250 && me.my > yPos && me.my < yPos + 100 )
+	{
+		if( !mausIn )
+		{
+			rend = 1;
+			rahmen->setFarbe( 0xFF00FF00 );
+		}
+		mausIn = 1;
+	}
+	else
+	{
+		if( mausIn )
+		{
+			rend = 1;
+			rahmen->setFarbe( 0xFFFFFFFF );
+		}
+		mausIn = 0;
+	}
+	me.verarbeitet |= mausIn;
+}
+
+bool MiniGame::tick( double z )
+{
+	bool ret = rend;
+	rend = 0;
+	int val = (int)( z * 150 );
+	if( sichtbar && alpha != 255 )
+	{
+		if( alpha + val > 255 )
+			alpha = 255;
+		else
+			alpha += val;
+		ret = 1;
+	}
+	if( !sichtbar && alpha )
+	{
+		if( alpha - val < 0 )
+			alpha = 0;
+		else
+			alpha -= val;
+		ret = 1;
+	}
+	if( xPos != zXPos || yPos != zYPos )
+	{
+		if( xPos != zXPos )
+		{
+			if( xAbs > 0 )
+			{
+				if( zXPos - xPos >= xAbs / 2 )
+					xSpeed += xAbs * z;
+				else
+				{
+					xSpeed -= xAbs * z;
+					if( xSpeed < zXPos - xPos )
+						xSpeed += xAbs * z;
+				}
+			}
+			else
+			{
+				if( zXPos - xPos <= xAbs / 2 )
+					xSpeed += xAbs * z;
+				else
+				{
+					xSpeed -= xAbs * z;
+					if( xSpeed > zXPos - xPos )
+						xSpeed += xAbs * z;
+				}
+			}
+		}
+		if( yPos != zYPos )
+		{
+			if( yAbs > 0 )
+			{
+				if( zYPos - yPos >= yAbs / 2 )
+					ySpeed += yAbs * z;
+				else
+				{
+					ySpeed -= yAbs * z;
+					if( ySpeed < zYPos - yPos )
+						ySpeed += yAbs * z;
+				}
+			}
+			else
+			{
+				if( zYPos - yPos <= yAbs / 2 )
+					ySpeed += yAbs * z;
+				else
+				{
+					ySpeed -= yAbs * z;
+					if( ySpeed > zYPos - yPos )
+						ySpeed += yAbs * z;
+				}
+			}
+		}
+		xPos += xSpeed * z;
+		yPos += ySpeed * z;
+		if( xAbs > 0 )
+		{
+			if( xPos >= zXPos )
+			{
+				xPos = zXPos;
+				xSpeed = 0;
+			}
+		}
+		else
+		{
+			if( xPos <= zXPos )
+			{
+				xPos = zXPos;
+				xSpeed = 0;
+			}
+		}
+		if( yAbs > 0 )
+		{
+			if( yPos >= zYPos )
+			{
+				yPos = zYPos;
+				ySpeed = 0;
+			}
+		}
+		else
+		{
+			if( yPos <= zYPos )
+			{
+				yPos = zYPos;
+				ySpeed = 0;
+			}
+		}
+		ret = 1;
+	}
+	return ret;
+}
+
+void MiniGame::render( Bild &zRObj )
+{
+	zRObj.setAlpha( alpha );
+	zRObj.drawBild( (int)( xPos ), (int)( yPos ), 250, 100, *bgBild );
+	rahmen->setPosition( (int)xPos, (int)yPos );
+	rahmen->render( zRObj );
+	if( mausIn )
+	{
+		mausAlpha->setPosition( (int)xPos + 1, (int)yPos + 1 );
+		mausAlpha->render( zRObj );
+	}
+	zRObj.releaseAlpha();
+}
+
+// constant
+Text *MiniGame::zName()
+{
+	return name;
+}
+
+bool MiniGame::istOk() const
+{
+	return ok;
+}
+
+// Reference Counting
+MiniGame *MiniGame::getThis()
+{
+	ref++;
+	return this;
+}
+
+MiniGame *MiniGame::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 51 - 0
KSGClient/NachLogin/MiniGames/MiniGame.h

@@ -0,0 +1,51 @@
+#ifndef MiniGame_H
+#define MiniGame_H
+
+#include <Bild.h>
+#include <Text.h>
+#include <AlphaFeld.h>
+
+using namespace Framework;
+
+class MiniGame
+{
+private:
+	double xPos;
+	double yPos;
+	int xAbs;
+	int yAbs;
+	int zXPos;
+	int zYPos;
+	double xSpeed;
+	double ySpeed;
+	Text *name;
+	Bild *bgBild;
+	AlphaFeld *mausAlpha;
+	LRahmen *rahmen;
+	bool sichtbar;
+	unsigned char alpha;
+	bool mausIn;
+	bool ok;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	MiniGame( char *name );
+	// Destruktor
+	~MiniGame();
+	// nicht constant
+	void setPosition( int x, int y );
+	void setSichtbar( bool sichtbar );
+	void doMausEreignis( MausEreignis &me );
+	bool tick( double z );
+	void render( Bild &zRObj );
+	// constant
+	Text *zName();
+	bool istOk() const;
+	// Reference Counting
+	MiniGame *getThis();
+	MiniGame *release();
+};
+
+#endif

+ 540 - 0
KSGClient/NachLogin/MiniGames/Minigames.cpp

@@ -0,0 +1,540 @@
+#include "MiniGames.h"
+#include <Punkt.h>
+#include <Rahmen.h>
+#include "../../Global/Variablen.h"
+#include <Datei.h>
+#include "../../Global/Initialisierung.h"
+#include <InitDatei.h>
+#include <KSGTDatei.h>
+
+typedef MiniGameV *( *GetMiniGame )( );
+
+// Inhalt der MGLaden Klasse aus MiniGames.h
+// Konstruktor
+MGSuchen::MGSuchen( MiniGames *mGames )
+{
+	this->mGames = mGames;
+	start();
+}
+
+// Destruktor
+MGSuchen::~MGSuchen()
+{
+	mGames->release();
+}
+
+// nicht constant
+void MGSuchen::thread()
+{
+	KSGTDatei *dgt = new KSGTDatei( "data/dg.ksgt" );
+	dgt->laden();
+	bool ak = 0;
+	int dgId = infoKlient->getDateiGruppeIdVonPfad( "data/Minigames" );
+	for( int i = 0; i < dgt->getZeilenAnzahl(); i++ )
+	{
+		if( dgt->zFeld( i, 0 ) && TextZuInt( dgt->zFeld( i, 0 )->getText(), 10 ) == dgId )
+		{
+			int lv = dgt->zFeld( i, 2 ) ? TextZuInt( dgt->zFeld( i, 2 )->getText(), 10 ) : 0;
+			int ov = infoKlient->getDateiGruppeVersion( dgId );
+			if( lv == ov )
+				ak = 1;
+			break;
+		}
+	}
+	dgt->release();
+	if( !ak )
+	{
+		mGames->setAktuell( 0, dgId );
+		delete this;
+		return;
+	}
+	Datei *d = new Datei();
+	d->setDatei( "data/Minigames" );
+	if( !d->existiert() )
+		DateiPfadErstellen( "data/MiniGames/" );
+	RCArray< Text > *list = d->getDateiListe();
+	if( list )
+	{
+		for( int i = 0; i < list->getEintragAnzahl(); i++ )
+		{
+			MiniGame *mg = new MiniGame( list->z( i )->getText() );
+			if( !mg->istOk() )
+			{
+				mg->release();
+				continue;
+			}
+			mGames->addMiniGame( mg );
+		}
+		list->release();
+	}
+	d->release();
+	delete this;
+}
+
+
+// Inhalt der MGLaden Klasse aus MiniGameV.h
+// Konstruktor
+MGLaden::MGLaden( char *name )
+{
+	this->name = new Text( name );
+	game = 0;
+	ref = 1;
+	start();
+}
+
+// Destruktor
+MGLaden::~MGLaden()
+{
+	if( game )
+	{
+		game->release();
+		dllDateien->releaseDLL( name->getText() );
+	}
+	name->release();
+}
+
+// nicht constant
+void MGLaden::thread()
+{
+	Text *pfad = new Text( "data/Minigames/" );
+	pfad->append( name->getText() );
+	if( !DateiExistiert( pfad->getThis() ) )
+	{
+		pfad->release();
+		run = 0;
+		return;
+	}
+	pfad->append( "/mg.ini" );
+	if( !DateiExistiert( pfad->getThis() ) )
+	{
+		pfad->release();
+		run = 0;
+		return;
+	}
+	InitDatei *mgIni = new InitDatei( pfad );
+	if( !mgIni->laden() )
+	{
+		mgIni->release();
+		run = 0;
+		return;
+	}
+	if( !mgIni->wertExistiert( "DllPfad" ) )
+	{
+		mgIni->release();
+		run = 0;
+		return;
+	}
+	Text *dllPfad = new Text( "data/Minigames/" );
+	dllPfad->append( name->getText() );
+	dllPfad->append( "/" );
+	dllPfad->append( mgIni->zWert( "DllPfad" )->getText() );
+	mgIni->release();
+	if( !DateiExistiert( dllPfad->getThis() ) )
+	{
+		dllPfad->release();
+		run = 0;
+		return;
+	}
+	HMODULE dll = dllDateien->ladeDLL( name->getText(), dllPfad->getText() );
+	dllPfad->release();
+	if( !dll )
+	{
+		run = 0;
+		return;
+	}
+	GetMiniGame getMiniGame = (GetMiniGame)GetProcAddress( dll, "GetMiniGame" );
+	if( !getMiniGame )
+	{
+		dllDateien->releaseDLL( name->getText() );
+		run = 0;
+		return;
+	}
+	game = getMiniGame();
+	if( !game )
+	{
+		dllDateien->releaseDLL( name->getText() );
+		run = 0;
+		return;
+	}
+	if( !game->laden() )
+	{
+		game = game->release();
+		dllDateien->releaseDLL( name->getText() );
+	}
+	run = 0;
+}
+
+// constant
+bool MGLaden::fertig() const
+{
+	return !isRunning();
+}
+
+MiniGameV *MGLaden::zGame() const
+{
+	return game;
+}
+
+// Reference Counting
+MGLaden *MGLaden::getThis()
+{
+	ref++;
+	return this;
+}
+
+MGLaden *MGLaden::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der MiniGames Klasse aus MiniGames.h
+// Konstruktor
+MiniGames::MiniGames( Schrift *zSchrift, Fenster *zNachLoginFenster, int x )
+	: Zeichnung()
+{
+	schrift = zSchrift->getThis();
+	bildschirmGröße = BildschirmGröße();
+	pos = Punkt( x, 67 );
+	gr = Punkt( 102, 32 );
+	rahmen = new LRahmen();
+	rahmen->setFarbe( 0xFFFFFFFF );
+	rahmen->setSize( 102, 32 );
+	alpha = 0;
+	alpha2 = 0;
+	animation = 0;
+	sichtbar = 0;
+	tickVal = 0;
+	prozent1 = 0;
+	prozent2 = 0;
+	begPos = Punkt( 0, 0 );
+	begGröße = Punkt( 0, 0 );
+	größe1 = Punkt( 102, 32 );
+	pos1 = Punkt( x, 67 );
+	größe2 = Punkt( 800, 500 );
+	pos2 = bildschirmGröße / 2 - größe2 / 2;
+	laden = (Animation2D*)ladeAnimation->dublizieren();
+	laden->setSichtbar( 0 );
+	laden->setPosition( 375, 225 );
+	games = new RCArray< MiniGame >();
+	suchFilter = initTextFeld( 10, 10, 100, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, "Suchfilter:" );
+	zSchrift->setSchriftSize( 12 );
+	suchFilter->setSize( zSchrift->getTextBreite( suchFilter->zText() ), 20 );
+	suchName = initTextFeld( 20 + suchFilter->getBreite(), 10, 200, 20, zSchrift, TextFeld::Style::TextFeld, "" );
+	suchen = initKnopf( 230 + suchFilter->getBreite(), 10, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Suchen" );
+	gefiltert = 0;
+	zNachLoginFenster->addMember( this );
+	dg = 0;
+	mgl = 0;
+	ref = 1;
+	new MGSuchen( getThis() );
+}
+
+// Destruktor
+MiniGames::~MiniGames()
+{
+	if( schrift )
+		schrift->release();
+	rahmen->release();
+	suchName->release();
+	suchFilter->release();
+	suchen->release();
+	laden->release();
+	games->release();
+	if( mgl )
+		mgl->release();
+}
+
+// nicht constant
+void MiniGames::setSichtbar( bool sicht )
+{
+	begPos = pos;
+	begGröße = gr;
+	animation |= ( sicht ? 0x1 : 0x2 );
+	rend = 1;
+}
+
+void MiniGames::addMiniGame( MiniGame *mg )
+{
+	games->add( mg );
+	if( gefiltert )
+		filter();
+	else
+	{
+		int i = games->getEintragAnzahl() - 1;
+		games->z( i )->setPosition( 10 + 10 * ( i % 3 ) + 250 * ( i % 3 ), 50 + 10 * ( i / 3 ) + 100 * ( i / 3 ) );
+	}
+	if( dg && updateH->hat( 0, dg ) )
+		updateH->remove( 0, dg );
+}
+
+void MiniGames::setAktuell( bool aktuell, int dg )
+{
+	this->aktuell = aktuell;
+	if( aktuell )
+		new MGSuchen( getThis() );
+	if( !this->dg )
+		this->dg = dg;
+	if( !aktuell && !updateH->hat( 0, this->dg ) )
+		updateH->erstellen( schrift, 0, this->dg );
+	if( !aktuell )
+		updateH->setSichtbar( 0, 1, this->dg );
+}
+
+void MiniGames::filter()
+{
+	Text filter = suchName->zText()->getText();
+	bool notF = 0;
+	if( !filter.getLength() )
+		notF = 1;
+	int anz = games->getEintragAnzahl();
+	bool *fertig = new bool[ anz ];
+	for( int i = 0; i < anz; i++ )
+		fertig[ i ] = 0;
+	for( int i = 0; i < anz; i++ )
+	{
+		int pos = -1;
+		int p = -1;
+		for( int j = 0; j < anz; j++ )
+		{
+			if( ( notF || ( games->z( j )->zName()->hat( filter ) && ( pos == -1 || games->z( j )->zName()->positionVon( filter ) < pos ) ) ) && !fertig[ j ] )
+			{
+				p = j;
+				pos = games->z( j )->zName()->positionVon( filter );
+				games->z( j )->setSichtbar( 1 );
+			}
+		}
+		if( p < 0 )
+			break;
+		fertig[ p ] = 1;
+		games->z( p )->setPosition( 10 + 10 * ( i % 3 ) + 250 * ( i % 3 ), 50 + 10 * ( i / 3 ) + 100 * ( i / 3 ) );
+	}
+	for( int i = 0; i < anz; i++ )
+	{
+		if( !fertig[ i ] )
+			games->z( i )->setSichtbar( 0 );
+	}
+	delete[] fertig;
+}
+
+void MiniGames::doMausEreignis( MausEreignis &me )
+{
+	if( laden->istSichtbar() || !sichtbar )
+		return;
+	me.mx -= pos.x;
+	me.my -= pos.y;
+	if( !aktuell )
+	{
+		me.mx -= 200;
+		me.my -= 400;
+		updateH->doMausEreignis( 0, me, dg );
+		me.mx += 200;
+		me.my += 400;
+	}
+	if( alpha2 )
+	{
+		suchName->doMausEreignis( me );
+		bool vera = me.verarbeitet;
+		suchen->doMausEreignis( me );
+		if( !vera && me.verarbeitet && me.id == ME_RLinks )
+			filter();
+		int anz = games->getEintragAnzahl();
+		for( int i = 0; i < anz; i++ )
+		{
+			bool vera = me.verarbeitet;
+			games->z( i )->doMausEreignis( me );
+			if( !vera && me.verarbeitet && me.id == ME_RLinks )
+			{ // spiel starten
+				laden->setSichtbar( 1 );
+				if( mgl )
+					mgl = mgl->release();
+				mgl = new MGLaden( games->z( i )->zName()->getText() );
+			}
+		}
+	}
+	if( mgl && mgl->zGame() )
+		mgl->zGame()->doMausEreignis( me );
+	me.mx += pos.x;
+	me.my += pos.y;
+}
+
+void MiniGames::doTastaturEreignis( TastaturEreignis &te )
+{
+	if( laden->istSichtbar() || !sichtbar )
+		return;
+	if( alpha2 )
+	{
+		bool vera = te.verarbeitet;
+		suchName->doTastaturEreignis( te );
+		if( !vera && te.verarbeitet && te.taste == T_Enter && te.id == TE_Release )
+			filter();
+	}
+	if( mgl && mgl->zGame() )
+		mgl->zGame()->doTastaturEreignis( te );
+}
+
+bool MiniGames::tick( double z )
+{
+	if( !aktuell )
+		rend |= updateH->tick( 0, z, dg );
+	if( laden->istSichtbar() && mgl && mgl->fertig() )
+	{
+		if( !mgl->zGame() )
+		{
+			mgl = mgl->release();
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Das Minigame konnte nicht geladen werden." ), new Text( "Ok" ) );
+		}
+		else
+		{
+			mgl->zGame()->setSchriftZ( schrift->getThis() );
+			mgl->zGame()->setBildschirmZ( hauptScreen->getThis() );
+		}
+		laden->setSichtbar( 0 );
+	}
+	if( mgl && mgl->zGame() && !alpha2 )
+	{
+		if( sichtbar && !animation )
+			rend |= mgl->zGame()->tick( z );
+		if( mgl->zGame()->istEnde() )
+			mgl = mgl->release();
+	}
+	rend |= laden->tick( z );
+	if( alpha2 )
+	{
+		rend |= suchName->tick( z );
+		rend |= suchen->tick( z );
+		int anz = games->getEintragAnzahl();
+		for( int i = 0; i < anz; i++ )
+			rend |= games->z( i )->tick( z );
+	}
+	tickVal += z * 150;
+	int val = (int)tickVal;
+	if( val < 1 )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	tickVal -= val;
+	if( ( animation | 0x1 ) == animation ) // Einblenden
+	{
+		if( prozent1 != 100 )
+		{
+			prozent1 += val;
+			if( prozent1 >= 100 )
+				prozent1 = 100;
+			pos = begPos + (Punkt)( ( ( Vec2< double > )( pos2 - begPos ) / 100.0 ) * prozent1 );
+			gr = begGröße + (Punkt)( ( ( Vec2< double > )( größe2 - begGröße ) / 100.0 ) * prozent1 );
+		}
+		else if( alpha != 255 )
+		{
+			alpha += val * 2;
+			if( alpha >= 255 || ( animation | 0x2 ) == animation )
+			{
+				alpha = 255;
+				animation &= ~0x1;
+				sichtbar = 1;
+				prozent1 = 0;
+			}
+		}
+		rend = 1;
+	}
+	if( ( animation | 0x2 ) == animation ) // ausblenden
+	{
+		if( alpha != 0 )
+		{
+			alpha -= val * 2;
+			if( alpha < 0 )
+				alpha = 0;
+		}
+		else
+		{
+			prozent2 += val;
+			if( prozent2 > 100 )
+				prozent2 = 100;
+			pos = begPos + (Punkt)( ( ( Vec2< double > )( pos1 - begPos ) / 100.0 ) * prozent2 );
+			gr = begGröße + (Punkt)( ( ( Vec2< double > )( größe1 - begGröße ) / 100.0 ) * prozent2 );
+			if( prozent2 == 100 )
+			{
+				prozent2 = 0;
+				animation &= ~0x2;
+				sichtbar = 0;
+			}
+		}
+		rend = 1;
+	}
+	if( mgl && alpha2 )
+	{
+		alpha2 -= val;
+		if( alpha2 < 0 )
+			alpha2 = 0;
+		rend = 1;
+	}
+	if( !mgl && alpha2 != 255 )
+	{
+		alpha2 += val;
+		if( alpha2 > 255 )
+			alpha2 = 255;
+		rend = 1;
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void MiniGames::render( Bild &zRObj )
+{
+	if( pos == pos1 )
+		return;
+	rahmen->setPosition( pos );
+	rahmen->setSize( gr );
+	rahmen->render( zRObj );
+	if( !zRObj.setDrawOptions( pos.x + 1, pos.y + 1, gr.x - 2, gr.y - 2 ) )
+		return;
+	int rbr = rahmen->getRBreite();
+	zRObj.setAlpha( (unsigned char)alpha );
+	zRObj.setAlpha( (unsigned char)alpha2 );
+	suchFilter->render( zRObj );
+	suchName->render( zRObj );
+	suchen->render( zRObj );
+	int anz = games->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+		games->z( i )->render( zRObj );
+	if( !aktuell )
+		updateH->render( 0, 200, 400, zRObj, dg );
+	zRObj.releaseAlpha();
+	laden->render( zRObj );
+	if( mgl && mgl->fertig() && mgl->zGame() )
+		mgl->zGame()->render( zRObj );
+	zRObj.releaseAlpha();
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+bool MiniGames::istAnimiert() const
+{
+	return animation != 0;
+}
+
+bool MiniGames::istSichtbar() const
+{
+	return sichtbar || prozent1 != 0;
+}
+
+// Reference Counting
+MiniGames *MiniGames::getThis()
+{
+	ref++;
+	return this;
+}
+
+MiniGames *MiniGames::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 102 - 0
KSGClient/NachLogin/MiniGames/Minigames.h

@@ -0,0 +1,102 @@
+#ifndef MiniGames_H
+#define MiniGames_H
+
+#include <Fenster.h>
+#include <Animation.h>
+#include "MiniGame.h"
+#include <Thread.h>
+#include <Knopf.h>
+#include <MiniGameV.h>
+
+using namespace Framework;
+
+class MiniGames; // aus dieser Datei
+
+class MGSuchen : private Thread
+{
+private:
+	MiniGames *mGames;
+public:
+	// Konstruktor
+	MGSuchen( MiniGames *mGames );
+	// Destruktor
+	~MGSuchen();
+	// nicht constant
+	void thread() override;
+};
+
+class MGLaden : private Thread
+{
+private:
+	Text *name;
+	MiniGameV *game;
+	int ref;
+
+public:
+	// Konstruktor
+	MGLaden( char *name );
+	// Destruktor
+	~MGLaden();
+	// nicht constant
+	void thread();
+	// constant
+	bool fertig() const;
+	MiniGameV *zGame() const;
+	// Reference Counting
+	MGLaden *getThis();
+	MGLaden *release();
+};
+
+class MiniGames : public Zeichnung
+{
+private:
+	Punkt begPos;
+	Punkt begGröße;
+	Punkt pos1;
+	Punkt größe1;
+	Punkt pos2;
+	Punkt größe2;
+	Punkt bildschirmGröße;
+	LRahmen *rahmen;
+	Animation2D *laden;
+	TextFeld *suchFilter;
+	TextFeld *suchName;
+	Knopf *suchen;
+	RCArray< MiniGame > *games;
+	MGLaden *mgl;
+	Schrift *schrift;
+	int dg;
+	bool aktuell;
+	bool gefiltert;
+	int animation;
+	int alpha;
+	bool sichtbar;
+	int prozent1;
+	int prozent2;
+	double tickVal;
+	int alpha2;
+	int ref;
+
+public:
+	// Konstruktor
+	MiniGames( Schrift *zSchrift, Fenster *zNachLoginFenster, int x );
+	// Destruktor
+	~MiniGames();
+	// nicht constant
+	void setSichtbar( bool sicht );
+	void addMiniGame( MiniGame *mg );
+	void setAktuell( bool aktuell, int dg = 0 );
+	void filter();
+	void doMausEreignis( MausEreignis &me ) override;
+	void doTastaturEreignis( TastaturEreignis &te ) override;
+	bool tick( double z ) override;
+	void render( Bild &zRObj ) override;
+	// constant
+	bool istAnimiert() const;
+	bool istSichtbar() const;
+	// Reference Counting
+	MiniGames *getThis();
+	MiniGames *release();
+};
+
+#endif

+ 482 - 0
KSGClient/NachLogin/NachLogin.cpp

@@ -0,0 +1,482 @@
+#include "NachLogin.h"
+#include <Schrift.h>
+#include <Bildschirm.h>
+#include <DateiSystem.h>
+#include <Text.h>
+#include "../Global/Variablen.h"
+
+// Inhalt der NachLogin Klasse aus NachLogin.h
+// Konstruktor
+NachLogin::NachLogin( Schrift *zSchrift, Bildschirm *zBildschirm )
+	: Zeichnung()
+{
+	if( zSchrift )
+		schrift = zSchrift->getThis();
+	if( zBildschirm )
+		bildschirm = zBildschirm->getThis();
+	fenster = 0;
+	titel = 0;
+	freunde = 0;
+	chatLeiste = 0;
+	nachrichtenListe = 0;
+	spielenFenster = 0;
+	shopFenster = 0;
+	accountAnsehenFenster = 0;
+	mgFenster = 0;
+	newsFenster = 0;
+	editorFenster = 0;
+	spielAufzeichnung = 0;
+    editor = 0;
+	op = 0;
+	status = NLALogin;
+	ref = 1;
+}
+
+// Destruktor
+NachLogin::~NachLogin()
+{
+	if( fenster )
+		setAnzeige( NLALogin );
+	if( schrift )
+		schrift = schrift->release();
+	if( bildschirm )
+		bildschirm = bildschirm->release();
+}
+
+// nicht constant
+void NachLogin::login() // Initialisiert die Oberfläche
+{
+	lockZeichnung();
+	if( fenster )
+		logout();
+	fenster = new Fenster();
+	fenster->setStyle( Fenster::Style::Erlaubt | Fenster::Style::Sichtbar );
+	fenster->setSize( bildschirm->getBackBufferSize() );
+	leistenFenster = new Fenster();
+	leistenFenster->setStyle( Fenster::Style::Erlaubt | Fenster::Style::Sichtbar | Fenster::Style::METransparenz );
+	leistenFenster->setSize( bildschirm->getBackBufferSize() );
+	titel = new TitelLeiste( leistenFenster, schrift );
+	spielenFenster = new Spiele( schrift, fenster, titel->getSpielenX() );
+	shopFenster = new Shop( schrift, fenster, titel->getSpielenX() + 101 );
+	accountAnsehenFenster = new AccountAnsehen( schrift, fenster, titel->getSpielenX() + 202 );
+	mgFenster = new MiniGames( schrift, fenster, titel->getSpielenX() + 303 );
+	newsFenster = new Neuigkeiten( schrift, fenster, titel->getSpielenX() + 404 );
+	editorFenster = new Editor( schrift, fenster, titel->getSpielenX() );
+	nachrichtenListe = new NachrichtenListe( schrift, leistenFenster );
+	freunde = new FreundesListe( schrift, leistenFenster );
+	chatLeiste = new ChatLeiste( schrift, leistenFenster );
+	op = new Einstellungen( schrift, leistenFenster );
+	imSpiel = new ImSpiel( schrift );
+	fenster->addMember( leistenFenster );
+	bildschirm->addMember( this );
+	MausEreignis me;
+	me.id = ME_RLinks;
+	bildschirm->lock();
+	titel->druckSpielen( me );
+	bildschirm->unlock();
+	status = NLANormal;
+	unlockZeichnung();
+}
+
+void NachLogin::logout() // Setzt die Oberfläche zurück
+{
+	lockZeichnung();
+	status = NLALogin;
+	if( bildschirm )
+		bildschirm->removeMember( this );
+	if( spielenFenster )
+		spielenFenster = spielenFenster->release();
+	if( shopFenster )
+		shopFenster = shopFenster->release();
+	if( accountAnsehenFenster )
+		accountAnsehenFenster = accountAnsehenFenster->release();
+	if( mgFenster )
+		mgFenster = mgFenster->release();
+	if( newsFenster )
+		newsFenster = newsFenster->release();
+	if( editorFenster )
+		editorFenster = editorFenster->release();
+	if( titel )
+		titel = titel->release();
+	if( freunde )
+		freunde = freunde->release();
+	if( chatLeiste )
+		chatLeiste = chatLeiste->release();
+	if( nachrichtenListe )
+		nachrichtenListe = nachrichtenListe->release();
+	if( leistenFenster )
+		leistenFenster = leistenFenster->release();
+	if( fenster )
+		fenster = fenster->release();
+	if( imSpiel )
+		imSpiel = imSpiel->release();
+	if( op )
+		op->release();
+	unlockZeichnung();
+}
+
+void NachLogin::setSpielAufzeichnung( AufzeichnungV *video ) // Setzt die Spiel Aufzeichnung
+{
+	spielAufzeichnung = video;
+}
+
+void NachLogin::setEditor( EditorV *editor ) // Setzt die Spiel Aufzeichnung
+{
+    this->editor = editor;
+}
+
+void NachLogin::setAnzeige( NachLoginAnzeige s ) // Setzt den Status des Programms
+{
+	lockZeichnung();
+	if( s == NLAImSpiel )
+	{
+		imSpiel->setSichtbar( 1 );
+		MausEreignis me = { ME_Bewegung, -1, -1, -1, -1, 0 };
+		leistenFenster->doMausEreignis( me );
+		leistenFenster->removeStyle( Fenster::Style::Sichtbar );
+		fenster->removeMember( leistenFenster );
+		bildschirm->addMember( leistenFenster );
+		titel->setImSpiel( 1 );
+	}
+	else if( status == NLAImSpiel )
+	{
+		imSpiel->setSichtbar( 0 );
+		fenster->addMember( leistenFenster );
+		bildschirm->removeMember( leistenFenster );
+		leistenFenster->addStyle( Fenster::Style::Sichtbar );
+		titel->setImSpiel( 0 );
+	}
+	if( s == NLASpielVideo )
+	{
+		MausEreignis me = { ME_Bewegung, -1, -1, -1, -1, 0 };
+		leistenFenster->doMausEreignis( me );
+		leistenFenster->removeStyle( Fenster::Style::Sichtbar );
+		fenster->removeMember( leistenFenster );
+		bildschirm->addMember( leistenFenster );
+		titel->setImVideo( 1 );
+	}
+	else if( status == NLASpielVideo )
+	{
+		fenster->addMember( leistenFenster );
+		bildschirm->removeMember( leistenFenster );
+		leistenFenster->addStyle( Fenster::Style::Sichtbar );
+		spielAufzeichnung = spielAufzeichnung->release();
+		titel->setImVideo( 0 );
+	}
+    if( s == NLAEditor )
+    {
+        MausEreignis me = { ME_Bewegung, -1, -1, -1, -1, 0 };
+        leistenFenster->doMausEreignis( me );
+        leistenFenster->removeStyle( Fenster::Style::Sichtbar );
+        fenster->removeMember( leistenFenster );
+        bildschirm->addMember( leistenFenster );
+        titel->setImSpiel( 1 );
+    }
+    else if( status == NLAEditor )
+    {
+        fenster->addMember( leistenFenster );
+        bildschirm->removeMember( leistenFenster );
+        leistenFenster->addStyle( Fenster::Style::Sichtbar );
+        editor = editor->release();
+        titel->setImSpiel( 0 );
+    }
+	if( s == NLALogin )
+		logout();
+	else
+	{
+		if( !fenster )
+			login();
+		else
+			status = s;
+	}
+	unlockZeichnung();
+}
+
+void NachLogin::doMausEreignis( MausEreignis &me )
+{
+	if( status == NLASpielVideo )
+	{
+		lockZeichnung();
+		if( leistenFenster->hatStyle( Fenster::Style::Sichtbar ) )
+			leistenFenster->doMausEreignis( me );
+		else
+		{
+			spielAufzeichnung->doMausEreignis( me );
+			if( spielAufzeichnung->hatVerlassen( 1 ) )
+			{
+				MausEreignis me = { ME_Bewegung, -1, -1, -1, -1, 0 };
+				spielAufzeichnung->doMausEreignis( me );
+				aktion = 8; // Aufzeichnung verlassen
+			}
+		}
+		unlockZeichnung();
+		return;
+	}
+    if( status == NLAEditor )
+    {
+        lockZeichnung();
+        if( leistenFenster->hatStyle( Fenster::Style::Sichtbar ) )
+            leistenFenster->doMausEreignis( me );
+        else
+        {
+            editor->doMausEreignis( me );
+            if( editor->hatVerlassen( 1 ) )
+            {
+                MausEreignis me = { ME_Bewegung, -1, -1, -1, -1, 0 };
+                editor->doMausEreignis( me );
+                aktion = 8; // Editor verlassen
+            }
+        }
+        unlockZeichnung();
+        return;
+    }
+	if( status == NLAImSpiel )
+	{
+		lockZeichnung();
+		if( leistenFenster->hatStyle( Fenster::Style::Sichtbar ) )
+			leistenFenster->doMausEreignis( me );
+		else
+			imSpiel->doMausEreignis( me );
+		unlockZeichnung();
+		return;
+	}
+	if( status != NLANormal )
+		return;
+	lockZeichnung();
+	if( fenster )
+		fenster->doMausEreignis( me );
+	unlockZeichnung();
+}
+
+void NachLogin::doTastaturEreignis( TastaturEreignis &te )
+{
+	if( status == NLASpielVideo )
+	{
+		lockZeichnung();
+		if( te.taste == T_F2 && te.id == TE_Release )
+		{
+			leistenFenster->setStyle( Fenster::Style::Sichtbar, !leistenFenster->hatStyle( Fenster::Style::Sichtbar ) );
+			MausEreignis me = { ME_Bewegung, -1, -1, -1, -1, 0 };
+			leistenFenster->doMausEreignis( me );
+		}
+		else
+		{
+			if( leistenFenster->hatStyle( Fenster::Style::Sichtbar ) )
+				leistenFenster->doTastaturEreignis( te );
+			else
+				spielAufzeichnung->doTastaturEreignis( te );
+		}
+		unlockZeichnung();
+		return;
+	}
+    if( status == NLAEditor )
+    {
+        lockZeichnung();
+        if( te.taste == T_F2 && te.id == TE_Release )
+        {
+            leistenFenster->setStyle( Fenster::Style::Sichtbar, !leistenFenster->hatStyle( Fenster::Style::Sichtbar ) );
+            MausEreignis me = { ME_Bewegung, -1, -1, -1, -1, 0 };
+            leistenFenster->doMausEreignis( me );
+        }
+        else
+        {
+            if( leistenFenster->hatStyle( Fenster::Style::Sichtbar ) )
+                leistenFenster->doTastaturEreignis( te );
+            else
+                editor->doTastaturEreignis( te );
+        }
+        unlockZeichnung();
+        return;
+    }
+	if( status == NLAImSpiel )
+	{
+		lockZeichnung();
+		if( te.taste == T_F2 && te.id == TE_Release )
+		{
+			leistenFenster->setStyle( Fenster::Style::Sichtbar, !leistenFenster->hatStyle( Fenster::Style::Sichtbar ) );
+			MausEreignis me = { ME_Bewegung, -1, -1, -1, -1, 0 };
+			leistenFenster->doMausEreignis( me );
+		}
+		else
+		{
+			if( leistenFenster->hatStyle( Fenster::Style::Sichtbar ) )
+				leistenFenster->doTastaturEreignis( te );
+			else
+				imSpiel->doTastaturEreignis( te );
+		}
+		unlockZeichnung();
+		return;
+	}
+	if( status != NLANormal )
+		return;
+	lockZeichnung();
+	if( fenster )
+		fenster->doTastaturEreignis( te );
+	unlockZeichnung();
+}
+
+bool NachLogin::tick( double tickVal )
+{
+	if( status == NLASpielVideo )
+	{
+		lockZeichnung();
+		bool ret = 0;
+		if( leistenFenster->hatStyle( Fenster::Style::Sichtbar ) )
+			ret |= leistenFenster->tick( tickVal );
+		ret |= spielAufzeichnung->tick( tickVal );
+		unlockZeichnung();
+		return ret;
+	}
+    if( status == NLAEditor )
+    {
+        lockZeichnung();
+        bool ret = 0;
+        if( leistenFenster->hatStyle( Fenster::Style::Sichtbar ) )
+            ret |= leistenFenster->tick( tickVal );
+        ret |= editor->tick( tickVal );
+        unlockZeichnung();
+        return ret;
+    }
+	if( status == NLAImSpiel )
+	{
+		lockZeichnung();
+		bool ret = 0;
+		if( leistenFenster->hatStyle( Fenster::Style::Sichtbar ) )
+			ret |= leistenFenster->tick( tickVal );
+		ret |= imSpiel->tick( tickVal );
+		unlockZeichnung();
+		return ret;
+	}
+	if( status != NLANormal )
+		return 0;
+	lockZeichnung();
+	bool ret = 0;
+	if( titel )
+		ret |= titel->tick();
+	if( fenster )
+		ret |= fenster->tick( tickVal );
+	unlockZeichnung();
+	return ret;
+}
+
+void NachLogin::render( Bild &zRObj )
+{
+	if( status == NLASpielVideo )
+	{
+		lockZeichnung();
+		spielAufzeichnung->render( zRObj );
+		if( leistenFenster->hatStyle( Fenster::Style::Sichtbar ) )
+		    leistenFenster->render( zRObj );
+		unlockZeichnung();
+		return;
+	}
+    if( status == NLASpielVideo )
+    {
+        lockZeichnung();
+        editor->render( zRObj );
+        if( leistenFenster->hatStyle( Fenster::Style::Sichtbar ) )
+            leistenFenster->render( zRObj );
+        unlockZeichnung();
+        return;
+    }
+    if( status == NLAEditor )
+    {
+        lockZeichnung();
+        editor->render( zRObj );
+        if( leistenFenster->hatStyle( Fenster::Style::Sichtbar ) )
+            leistenFenster->render( zRObj );
+        unlockZeichnung();
+        return;
+    }
+	if( status == NLAImSpiel )
+	{
+		lockZeichnung();
+		imSpiel->render( zRObj );
+		if( leistenFenster->hatStyle( Fenster::Style::Sichtbar ) )
+			leistenFenster->render( zRObj );
+		unlockZeichnung();
+		return;
+	}
+	if( status != NLANormal )
+		return;
+	lockZeichnung();
+	if( fenster )
+		fenster->render( zRObj );
+	unlockZeichnung();
+}
+
+// constant
+TitelLeiste *NachLogin::zTitelLeiste() const // gibt die Titelleiste zurück
+{
+	return titel;
+}
+
+FreundesListe *NachLogin::zFreundesListe() const // gibt die FreundesListe zurück
+{
+	return freunde;
+}
+
+ChatLeiste *NachLogin::zChatLeiste() const // gibt die ChatLeiste zurück
+{
+	return chatLeiste;
+}
+
+NachrichtenListe *NachLogin::zNachrichtenListe() const // gibt die NachrichtenListe zurück
+{
+	return nachrichtenListe;
+}
+
+Spiele *NachLogin::zSpielenFenster() const // gibt das Spiele Fenster zurück
+{
+	return spielenFenster;
+}
+
+Shop *NachLogin::zShopFenster() const // gibt das Shop Fenster zurück
+{
+	return shopFenster;
+}
+
+AccountAnsehen *NachLogin::zAccountAnsehenFenster() const // gibt das Account Ansehen Fenster zurück
+{
+	return accountAnsehenFenster;
+}
+
+MiniGames *NachLogin::zMGFenster() const // gibt das MiniGames Fenster zurück
+{
+	return mgFenster;
+}
+
+Neuigkeiten *NachLogin::zNewsFenster() const // gibt das News Fenster zurück
+{
+	return newsFenster;
+}
+
+Editor *NachLogin::zEditorFenster() const // gibt das News Fenster zurück
+{
+	return editorFenster;
+}
+
+ImSpiel *NachLogin::zImSpiel() const // Gibt das Im Spiel Zeichnung zurück
+{
+	return imSpiel;
+}
+
+Einstellungen *NachLogin::zEinstellungen() const // Gibt das Einstellungen Zeichnung zurück
+{
+	return op;
+}
+
+// Reference Counting
+NachLogin *NachLogin::getThis()
+{
+	ref++;
+	return this;
+}
+
+NachLogin *NachLogin::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 86 - 0
KSGClient/NachLogin/NachLogin.h

@@ -0,0 +1,86 @@
+#ifndef NachLogin_H
+#define NachLogin_H
+
+#include "Titel/TitelLeiste.h"
+#include "Chat/FreundesListe.h"
+#include "Chat/ChatLeiste.h"
+#include "Chat/NachrichtenListe.h"
+#include "Spiele/Spiele.h"
+#include "Shop/Shop.h"
+#include "Account/AccountAnsehen.h"
+#include "ImSpiel/ImSpiel.h"
+#include <AufzeichnungV.h>
+#include "Neuigkeiten/Neuigkeiten.h"
+#include "Einstellungen/Einstellungen.h"
+#include "MiniGames/MiniGames.h"
+#include "Editor/Editor.h"
+
+using namespace Framework;
+
+enum NachLoginAnzeige
+{
+	NLALogin,
+	NLANormal,
+	NLAImSpiel,
+	NLASpielVideo,
+    NLAEditor
+};
+
+class NachLogin : public Zeichnung
+{
+private:
+	int	ref;
+	Fenster *fenster;
+	Fenster *leistenFenster;
+	Schrift *schrift;
+	Bildschirm *bildschirm;
+	TitelLeiste *titel;
+	FreundesListe *freunde;
+	ChatLeiste *chatLeiste;
+	NachrichtenListe *nachrichtenListe;
+	Spiele *spielenFenster;
+	Shop *shopFenster;
+	AccountAnsehen *accountAnsehenFenster;
+	MiniGames *mgFenster;
+	Neuigkeiten *newsFenster;
+	Editor *editorFenster;
+	ImSpiel *imSpiel;
+	AufzeichnungV *spielAufzeichnung;
+	Einstellungen *op;
+	NachLoginAnzeige status;
+    EditorV *editor;
+
+public:
+	// Konstruktor
+	NachLogin( Schrift *zSchrift, Bildschirm *zBildschirm );
+	// Destruktor
+	~NachLogin();
+	// nicht constant
+	void login(); // Initialisiert die Oberfläche
+	void logout(); // Setzt die Oberfläche zurück
+	void setSpielAufzeichnung( AufzeichnungV *video ); // Setzt die Spiel Aufzeichnung
+	void setEditor( EditorV *editor ); // Setzt den Editor
+	void setAnzeige( NachLoginAnzeige s ); // Setzt den Status des Programms
+	void doMausEreignis( MausEreignis &me ) override;
+	void doTastaturEreignis( TastaturEreignis &te ) override;
+	bool tick( double tickVal ) override;
+	void render( Bild &zRObj ) override;
+	// constant
+	TitelLeiste *zTitelLeiste() const;// gibt die Titelleiste zurück
+	FreundesListe *zFreundesListe() const; // gibt die FreundesListe zurück
+	ChatLeiste *zChatLeiste() const; // gibt die ChatLeiste zurück
+	NachrichtenListe *zNachrichtenListe() const; // gibt die NachrichtenListe zurück
+	Spiele *zSpielenFenster() const; // gibt das Spiele Fenster zurück
+	Shop *zShopFenster() const; // gibt das Shop Fenster zurück
+	AccountAnsehen *zAccountAnsehenFenster() const; // gibt das Account Ansehen Fenster zurück
+	MiniGames *zMGFenster() const; // gibt das MiniGames Fenster zurück
+	Neuigkeiten *zNewsFenster() const; // gibt das News Fenster zurück
+	Editor *zEditorFenster() const; // Gibt das Editor Fenster zurück
+	ImSpiel *zImSpiel() const; // Gibt das Im Spiel Zeichnung zurück
+	Einstellungen *zEinstellungen() const; // Gibt das Einstellungen Zeichnung zurück
+	// Reference Counting
+	NachLogin *getThis();
+	NachLogin *release();
+};
+
+#endif;

+ 326 - 0
KSGClient/NachLogin/Neuigkeiten/Neuigkeiten.cpp

@@ -0,0 +1,326 @@
+#include "Neuigkeiten.h"
+#include "../../Global/Variablen.h"
+#include "../../Global/Initialisierung.h"
+#include <Punkt.h>
+
+// Inhalt der NewsThread Klasse aus Neuigkeiten.h
+// Konstruktor
+NewsThread::NewsThread( char *name, KSGScriptObj *obj, Neuigkeiten *n )
+{
+	scriptName = new Text( name );
+	this->obj = obj;
+	news = n;
+	start();
+}
+
+// Destruktor
+NewsThread::~NewsThread()
+{
+	scriptName->release();
+	obj->release();
+	news->release();
+}
+
+// nicht constant
+void NewsThread::thread()
+{
+	bool trenn = 0;
+	if( !newsKlient->istVerbunden() )
+	{
+		trenn = 1;
+		if( !newsKlient->verbinde() )
+		{
+			news->endLaden( "Fehler beim Verbinden mit dem News-Server." );
+			run = 0;
+			delete this;
+			return;
+		}
+	}
+	if( !newsKlient->ladeSeite( scriptName->getText() ) )
+	{
+		news->endLaden( "Fehler beim herrunterladen der Seite." );
+		run = 0;
+		delete this;
+		return;
+	}
+	if( trenn )
+		newsKlient->trenne();
+	Text *pfad = new Text( "data/tmp/news/" );
+	pfad->append( scriptName->getText() );
+	pfad->append( "/seite.ksgs" );
+	obj->setScriptDatei( pfad );
+	if( !obj->neuLaden() )
+	{
+		news->endLaden( "Fehler beim laden der Seite." );
+		run = 0;
+		delete this;
+		return;
+	}
+	news->endLaden( 0 );
+	run = 0;
+	delete this;
+}
+
+
+void KSGSRückruf( void *p, RCArray< KSGSVariable > *parameter, KSGSVariable **ret )
+{
+	if( !p )
+		return;
+	( (Neuigkeiten*)p )->rückruf( parameter, ret );
+}
+
+// Inhalt der Neuigkeiten Klasse aus Neuigkeiten.h
+// Konstruktor
+Neuigkeiten::Neuigkeiten( Schrift *zSchrift, Fenster *zNachLoginFenster, int x )
+{
+	bildschirmGröße = BildschirmGröße();
+	pos = Punkt( x, 67 );
+	gr = Punkt( 102, 32 );
+	rahmen = new LRahmen();
+	rahmen->setFarbe( 0xFFFFFFFF );
+	rahmen->setSize( 102, 32 );
+	alpha = 0;
+	animation = 0;
+	wirdGeladen = 0;
+	sichtbar = 0;
+	tickVal = 0;
+	prozent1 = 0;
+	prozent2 = 0;
+	begPos = Punkt( 0, 0 );
+	begGröße = Punkt( 0, 0 );
+	größe1 = Punkt( 102, 32 );
+	pos1 = Punkt( x, 67 );
+	größe2 = Punkt( 800, 500 );
+	pos2 = bildschirmGröße / 2 - größe2 / 2;
+	fehler = initTextFeld( 5, 5, 790, 490, zSchrift, TextFeld::Style::Text & ~TextFeld::Style::Sichtbar, "" );
+	laden = (Animation2D*)ladeAnimation->dublizieren();
+	laden->setSichtbar( 0 );
+	laden->setPosition( 375, 225 );
+	zNachLoginFenster->addMember( this );
+	ref = 1;
+	ksgsDLL = dllDateien->ladeDLL( "KSGScript.dll", "data/bin/KSGScript.dll" );
+	if( !ksgsDLL )
+	{
+		fehler->setText( "Die DLL Datei 'data/bin/KSGScript.dll' konnte nicht geladen werden." );
+		fehler->addStyle( TextFeld::Style::Sichtbar );
+		script = 0;
+	}
+	else
+	{
+		KSGSGetZeichnung getKSGSZeichnung = (KSGSGetZeichnung)GetProcAddress( ksgsDLL, KSGS_START_FUNKTION );
+		if( !getKSGSZeichnung )
+		{
+			fehler->setText( "Die Funktion '" KSGS_START_FUNKTION "' konnte in der DLL Datei 'data/bin/KSGScript.dll'\nnicht gefunden werden." );
+			fehler->addStyle( TextFeld::Style::Sichtbar );
+			script = 0;
+		}
+		else
+		{
+			script = getKSGSZeichnung();
+			script->setSize( 800, 500 );
+			script->setBildschirmZ( hauptScreen->getThis() );
+			script->setSchriftZ( zSchrift->getThis() );
+			script->setRückrufParam( this );
+			script->setRückrufFunktion( KSGSRückruf );
+			wirdGeladen = 1;
+			laden->setSichtbar( 1 );
+			new NewsThread( "Client/Start", script->getThis(), getThis() );
+		}
+	}
+}
+
+// Destruktor
+Neuigkeiten::~Neuigkeiten()
+{
+	rahmen->release();
+	if( script )
+	{
+		script->zurücksetzen();
+		script->release();
+	}
+	if( ksgsDLL )
+		dllDateien->releaseDLL( "KSGScript.dll" );
+	fehler->release();
+	laden->release();
+}
+
+// nicht constant
+void Neuigkeiten::setSichtbar( bool sicht )
+{
+	begPos = pos;
+	begGröße = gr;
+	animation |= ( sicht ? 0x1 : 0x2 );
+	rend = 1;
+}
+
+void Neuigkeiten::endLaden( char *err )
+{
+	laden->setSichtbar( 0 );
+	wirdGeladen = 0;
+	if( err )
+	{
+		fehler->setText( err );
+		fehler->addStyle( TextFeld::Style::Sichtbar );
+	}
+	else
+	{
+		fehler->setText( "" );
+		fehler->removeStyle( TextFeld::Style::Sichtbar );
+	}
+}
+
+void Neuigkeiten::rückruf( RCArray< KSGSVariable > *parameter, KSGSVariable **ret )
+{
+	if( wirdGeladen )
+		return;
+	KSGSVariable *befehl = parameter->z( 0 );
+	if( !befehl )
+		return;
+	Text *b = befehl->getText();
+	if( !b || !b->getLength() )
+	{
+		if( b )
+			b->release();
+		return;
+	}
+	wirdGeladen = 1;
+	laden->setSichtbar( 1 );
+	new NewsThread( b->getText(), script->getThis(), getThis() );
+}
+
+void Neuigkeiten::doMausEreignis( MausEreignis &me )
+{
+	if( wirdGeladen )
+		return;
+	me.mx -= pos.x;
+	me.my -= pos.y;
+	if( script && sichtbar )
+		script->doMausEreignis( me );
+	me.mx += pos.x;
+	me.my += pos.y;
+}
+
+void Neuigkeiten::doTastaturEreignis( TastaturEreignis &te )
+{
+	if( wirdGeladen )
+		return;
+	if( script && sichtbar )
+		script->doTastaturEreignis( te );
+}
+
+bool Neuigkeiten::tick( double z )
+{
+	rend |= laden->tick( z );
+	rend |= fehler->tick( z );
+	if( wirdGeladen )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	if( script && sichtbar )
+		rend |= script->tick( z );
+	tickVal += z * 150;
+	int val = (int)tickVal;
+	if( val < 1 )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	tickVal -= val;
+	if( ( animation | 0x1 ) == animation ) // Einblenden
+	{
+		if( prozent1 != 100 )
+		{
+			prozent1 += val;
+			if( prozent1 >= 100 )
+				prozent1 = 100;
+			pos = begPos + (Punkt)( ( ( Vec2< double > )( pos2 - begPos ) / 100.0 ) * prozent1 );
+			gr = begGröße + (Punkt)( ( ( Vec2< double > )( größe2 - begGröße ) / 100.0 ) * prozent1 );
+		}
+		else if( alpha != 255 )
+		{
+			alpha += val * 2;
+			if( alpha >= 255 || ( animation | 0x2 ) == animation )
+			{
+				alpha = 255;
+				animation &= ~0x1;
+				sichtbar = 1;
+				prozent1 = 0;
+			}
+		}
+		rend = 1;
+	}
+	if( ( animation | 0x2 ) == animation ) // ausblenden
+	{
+		if( alpha != 0 )
+		{
+			alpha -= val * 2;
+			if( alpha < 0 )
+				alpha = 0;
+		}
+		else
+		{
+			prozent2 += val;
+			if( prozent2 > 100 )
+				prozent2 = 100;
+			pos = begPos + (Punkt)( ( ( Vec2< double > )( pos1 - begPos ) / 100.0 ) * prozent2 );
+			gr = begGröße + (Punkt)( ( ( Vec2< double > )( größe1 - begGröße ) / 100.0 ) * prozent2 );
+			if( prozent2 == 100 )
+			{
+				prozent2 = 0;
+				animation &= ~0x2;
+				sichtbar = 0;
+			}
+		}
+		rend = 1;
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void Neuigkeiten::render( Bild &zRObj )
+{
+	if( pos == pos1 )
+		return;
+	if( !zRObj.setDrawOptions( pos.x, pos.y, gr.x, gr.y ) )
+		return;
+	rahmen->setSize( gr );
+	rahmen->render( zRObj );
+	int rbr = rahmen->getRBreite();
+	zRObj.setAlpha( (unsigned char)alpha );
+	fehler->render( zRObj );
+	if( script )
+		script->render( zRObj );
+	laden->render( zRObj );
+	zRObj.releaseAlpha();
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+bool Neuigkeiten::istAnimiert() const
+{
+	return animation != 0;
+}
+
+bool Neuigkeiten::istSichtbar() const
+{
+	return sichtbar || prozent1 != 0;
+}
+
+// Reference Counting
+Neuigkeiten *Neuigkeiten::getThis()
+{
+	ref++;
+	return this;
+}
+
+Neuigkeiten *Neuigkeiten::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 74 - 0
KSGClient/NachLogin/Neuigkeiten/Neuigkeiten.h

@@ -0,0 +1,74 @@
+#ifndef Neuigkeiten_H
+#define Neuigkeiten_H
+
+#include <KSGScript.h>
+#include <Rahmen.h>
+#include <Thread.h>
+
+using namespace KSGScript;
+using namespace Framework;
+
+class Neuigkeiten; // Aus dieser Datei
+
+class NewsThread : private Thread
+{
+private:
+	Text *scriptName;
+	KSGScriptObj *obj;
+	Neuigkeiten *news;
+	
+public:
+	// Konstruktor
+	NewsThread( char *name, KSGScriptObj *obj, Neuigkeiten *n );
+	// Destruktor
+	~NewsThread();
+	// nicht constant
+	void thread();
+};
+
+class Neuigkeiten : public Zeichnung
+{
+private:
+	Punkt begPos;
+	Punkt begGröße;
+	Punkt pos1;
+	Punkt größe1;
+	Punkt pos2;
+	Punkt größe2;
+	Punkt bildschirmGröße;
+	LRahmen *rahmen;
+	HMODULE ksgsDLL;
+	KSGScriptObj *script;
+	TextFeld *fehler;
+	Animation2D *laden;
+	int animation;
+	bool wirdGeladen;
+	int alpha;
+	bool sichtbar;
+	int prozent1;
+	int prozent2;
+	double tickVal;
+	int ref;
+
+public:
+	// Konstruktor
+	Neuigkeiten( Schrift *zSchrift, Fenster *zNachLoginFenster, int x );
+	// Destruktor
+	~Neuigkeiten();
+	// nicht constant
+	void setSichtbar( bool sicht );
+	void endLaden( char *err );
+	void rückruf( RCArray< KSGSVariable > *parameter, KSGSVariable **ret );
+	void doMausEreignis( MausEreignis &me ) override;
+	void doTastaturEreignis( TastaturEreignis &te ) override;
+	bool tick( double z ) override;
+	void render( Bild &zRObj ) override;
+	// constant
+	bool istAnimiert() const;
+	bool istSichtbar() const;
+	// Reference Counting
+	Neuigkeiten *getThis();
+	Neuigkeiten *release();
+};
+
+#endif

+ 1055 - 0
KSGClient/NachLogin/Shop/Karten/KartenKaufen.cpp

@@ -0,0 +1,1055 @@
+#include "KartenKaufen.h"
+#include <Rahmen.h>
+#include <Punkt.h>
+#include "../../../Global/Initialisierung.h"
+#include "../../../Global/Variablen.h"
+#include <DateiSystem.h>
+#include <AlphaFeld.h>
+#include <KSGTDatei.h>
+
+void KarteKaufenKSGSAktion( void *p, RCArray< KSGSVariable > *parameter, KSGSVariable **retVal )
+{
+	if( !p )
+		return;
+	( (KartenKaufenAuswahl*)p )->ksgsAktion( parameter, retVal );
+}
+
+// Inhalt der KartenKaufenAuswahl Klasse aus KartenKaufen.h
+// Konstruktor
+KartenKaufenAuswahl::KartenKaufenAuswahl( Schrift *zSchrift )
+{
+	karteId = 0;
+	alpha = 0;
+	ksgs = dllDateien->ladeDLL( "KSGScript.dll", "data/bin/KSGScript.dll" );
+	if( ksgs )
+	{
+		KSGSGetZeichnung getKSGScript = (KSGSGetZeichnung)GetProcAddress( ksgs, KSGS_START_FUNKTION );
+		if( getKSGScript )
+		{
+			fenster = getKSGScript();
+			fenster->setSchriftZ( zSchrift->getThis() );
+			fenster->setSize( 555, 380 );
+			fenster->setRückrufParam( this );
+			fenster->setRückrufFunktion( KarteKaufenKSGSAktion );
+		}
+		else
+		{
+			fenster = 0;
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+														  new Text( "Der Einstiegspunkt '" KSGS_START_FUNKTION "' in der DLL-Datei "
+																	"'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+														  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+		}
+	}
+	else
+	{
+		fenster = 0;
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+													  new Text( "Die DLL-Datei 'data/bin/KSGScript.dll' konnte nicht geladen werden." ),
+													  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+	}
+	ram = new LRahmen();
+	ram->setSize( 555, 380 );
+	ram->setFarbe( 0xFFFFFFFF );
+	laden = ( Framework::Animation2D* )ladeAnimation->dublizieren();
+	laden->setPosition( 252, 165 );
+	laden->setSichtbar( 0 );
+	pos = Punkt( 220, 10 );
+	aktion = 0;
+	ref = 1;
+}
+
+// Destruktor
+KartenKaufenAuswahl::~KartenKaufenAuswahl()
+{
+	if( run )
+		warteAufThread( 2000 );
+	if( run )
+		ende();
+	if( fenster )
+	{
+		fenster->zurücksetzen();
+		fenster->release();
+	}
+	ram->release();
+	laden->release();
+	if( ksgs )
+		dllDateien->releaseDLL( "KSGScript.dll" );
+}
+
+// nicht constant
+void KartenKaufenAuswahl::ladeKarteSeite( int id )
+{
+	if( run )
+		warteAufThread( 2000 );
+	if( run )
+		return;
+	karteId = id;
+	aktion = 1;
+	start();
+}
+
+void KartenKaufenAuswahl::reset()
+{
+	if( run )
+		warteAufThread( 2000 );
+	if( run )
+		return;
+	aktion = 0;
+	start();
+}
+
+void KartenKaufenAuswahl::thread()
+{
+	laden->setSichtbar( 1 );
+	if( !aktion || karteId )
+	{
+		while( alpha )
+			Sleep( 100 );
+		if( !aktion )
+			karteId = 0;
+		if( fenster )
+			fenster->zurücksetzen();
+	}
+	if( aktion )
+	{
+		while( alpha )
+			Sleep( 100 );
+		shopKlient->ladeKarteSeite( karteId );
+		Text *pfad = new Text( "data/tmp/shop/kaufen/karten/" );
+		pfad->append( karteId );
+		pfad->append( "/seite.ksgs" );
+		if( fenster )
+		{
+			fenster->setScriptDatei( pfad );
+			fenster->neuLaden();
+		}
+	}
+	laden->setSichtbar( 0 );
+	run = 0;
+}
+
+void KartenKaufenAuswahl::ksgsAktion( RCArray< KSGSVariable > *parameter, KSGSVariable **retVal )
+{
+	KSGSVariable *befehl = parameter->z( 0 );
+	if( !befehl )
+		return;
+	Text *b = befehl->getText();
+	if( !b )
+		return;
+	if( b->istGleich( "GetBesitzStatus" ) )
+	{
+		int besitz = shopKlient->getKarteBesitzStatus( karteId );
+		KSGSGetVariable getKSGSVariable = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
+		if( getKSGSVariable )
+		{
+			KSGSVariableDef def = { KSGS_INT, 0, 3, ( Text() += besitz ).getText() };
+			*retVal = getKSGSVariable( fenster, &def );
+		}
+		else
+		{
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+														  new Text( "Der Einstiegspunkt '" KSGS_VARIABLE_FUNKTION "' in der DLL-Datei "
+																	"'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+														  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+		}
+		b->release();
+		return;
+	}
+	if( b->istGleich( "GetPreis" ) )
+	{
+		KSGSVariable *version = parameter->z( 1 );
+		if( !version )
+		{
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+														  new Text( "Auf dieser Seite befindet sich ein Fehler im KSG-Script. "
+																	"Sie könnte eventuell nicht richtig funktionieren." ),
+														  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+		}
+		else
+		{
+			bool testVersion = !version->getInt();
+			int preis = shopKlient->getKartePreis( karteId, testVersion );
+			KSGSGetVariable getKSGSVariable = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
+			if( getKSGSVariable )
+			{
+				KSGSVariableDef def = { KSGS_INT, 0, 3, ( Text() += preis ).getText() };
+				*retVal = getKSGSVariable( fenster, &def );
+			}
+			else
+			{
+				nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+															  new Text( "Der Einstiegspunkt '" KSGS_VARIABLE_FUNKTION "' in der DLL-Datei "
+																		"'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+															  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+			}
+		}
+		b->release();
+		return;
+	}
+	if( b->istGleich( "GetTestVersionVerbleibend" ) )
+	{
+		int verbleibend = shopKlient->getKarteTestversion( karteId );
+		KSGSGetVariable getKSGSVariable = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
+		if( getKSGSVariable )
+		{
+			KSGSVariableDef def = { KSGS_INT, 0, 3, ( Text() += verbleibend ).getText() };
+			*retVal = getKSGSVariable( fenster, &def );
+		}
+		else
+		{
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+														  new Text( "Der Einstiegspunkt '" KSGS_VARIABLE_FUNKTION "' in der DLL-Datei "
+																	"'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+														  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+		}
+		b->release();
+		return;
+	}
+	if( b->istGleich( "GetErwerbbarStatus" ) )
+	{
+		int erwerbbar = shopKlient->istKarteErwerbbar( karteId );
+		KSGSGetVariable getKSGSVariable = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
+		if( getKSGSVariable )
+		{
+			KSGSVariableDef def = { KSGS_INT, 0, 3, ( Text() += erwerbbar ).getText() };
+			*retVal = getKSGSVariable( fenster, &def );
+		}
+		else
+		{
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+														  new Text( "Der Einstiegspunkt '" KSGS_VARIABLE_FUNKTION "' in der DLL-Datei "
+																	"'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+														  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+		}
+		b->release();
+		return;
+	}
+	if( b->istGleich( "GetKupfer" ) )
+	{
+		int kupfer = infoKlient->getKupfer();
+		KSGSGetVariable getKSGSVariable = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
+		if( getKSGSVariable )
+		{
+			KSGSVariableDef def = { KSGS_INT, 0, 3, ( Text() += kupfer ).getText() };
+			*retVal = getKSGSVariable( fenster, &def );
+		}
+		else
+		{
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+														  new Text( "Der Einstiegspunkt '" KSGS_VARIABLE_FUNKTION "' in der DLL-Datei "
+																	"'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+														  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+		}
+		b->release();
+		return;
+	}
+	if( b->istGleich( "Kaufen" ) )
+	{
+		KSGSVariable *version = parameter->z( 1 );
+		if( !version )
+		{
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+														  new Text( "Auf dieser Seite befindet sich ein Fehler im KSG-Script. "
+																	"Sie könnte eventuell nicht richtig funktionieren." ),
+														  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+		}
+		else
+		{
+			bool testVersion = !version->getInt();
+			if( !shopKlient->karteErwerben( karteId, testVersion ) )
+			{
+				nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+															  new Text( "Die Karte konnte nicht erworben werden." ),
+															  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+			}
+			if( run )
+				warteAufThread( 2000 );
+			if( run )
+			{
+				b->release();
+				return;
+			}
+			aktion = 1;
+			start();
+		}
+		b->release();
+		return;
+	}
+	if( b->istGleich( "GetBild" ) )
+	{
+		KSGSVariable *pfad = parameter->z( 1 );
+		KSGSVariable *name = parameter->z( 2 );
+		if( !pfad || !name )
+		{
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+														  new Text( "Auf dieser Seite befindet sich ein Fehler im KSG-Script. "
+														  "Sie könnte eventuell nicht richtig funktionieren." ),
+														  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+		}
+		else
+		{
+			Text *pf = pfad->getText();
+			Text *n = name->getText();
+			if( !pf || !n )
+			{
+				nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+															  new Text( "Auf dieser Seite befindet sich ein Fehler im KSG-Script. "
+															  "Sie könnte eventuell nicht richtig funktionieren." ),
+															  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+			}
+			else
+			{
+				KSGSGetVariable getKSGSVariable = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
+				if( getKSGSVariable )
+				{
+					int p = n->positionVon( ".ltdb/" );
+					if( p < 0 )
+						p = 0;
+					else
+						p += 6;
+					Bild *b = bilder->get( *n );
+					if( !b )
+					{
+						LTDBDatei *dat = new LTDBDatei();
+						dat->setDatei( pf->getThis() );
+						dat->leseDaten( 0 );
+						b = dat->laden( 0, n->getTeilText( p, n->getLength() ) );
+						dat->release();
+						if( b )
+							bilder->add( *n, b->getThis() );
+					}
+					if( b )
+					{
+						KSGSVariableDef def = { KSGS_BILD, 0, 3, "" };
+						KSGSVariable *ret = getKSGSVariable( fenster, &def );
+						KSGSSetBild setKSGSBild = (KSGSSetBild)GetProcAddress( ksgs, KSGS_SET_BILD_FUNKTION );
+						if( !setKSGSBild )
+						{
+							nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+																		  new Text( "Der Einstiegspunkt '" KSGS_SET_BILD_FUNKTION "' in der DLL-Datei "
+																		  "'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+																		  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+							b->release();
+						}
+						else
+							setKSGSBild( ret, b );
+						*retVal = ret;
+					}
+				}
+				else
+				{
+					nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+																  new Text( "Der Einstiegspunkt '" KSGS_VARIABLE_FUNKTION "' in der DLL-Datei "
+																  "'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+																  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+				}
+			}
+			if( pf )
+				pf->release();
+			if( n )
+				n->release();
+		}
+		b->release();
+		return;
+	}
+}
+
+void KartenKaufenAuswahl::doMausEreignis( MausEreignis &me )
+{
+	if( run )
+		return;
+	me.mx -= pos.x;
+	me.my -= pos.y;
+	if( fenster )
+		fenster->doMausEreignis( me );
+	me.mx += pos.x;
+	me.my += pos.y;
+}
+
+void KartenKaufenAuswahl::doTastaturEreignis( TastaturEreignis &te )
+{
+	if( run )
+		return;
+	if( fenster )
+		fenster->doTastaturEreignis( te );
+}
+
+bool KartenKaufenAuswahl::tick( double zeit )
+{
+	bool rend = ( fenster && !run ) ? fenster->tick( zeit ) : 0;
+	rend |= laden->tick( zeit );
+	if( ( run || !karteId ) && alpha > 0 )
+	{
+		if( alpha - zeit * 150 < 0 )
+			alpha = 0;
+		else
+			alpha -= (unsigned char)( zeit * 150 );
+		rend = 1;
+	}
+	if( !run && karteId && alpha < 255 )
+	{
+		if( alpha + zeit * 150 > 255 )
+			alpha = 255;
+		else
+			alpha += (unsigned char)( zeit * 150 );
+		rend = 1;
+	}
+	return rend;
+}
+
+void KartenKaufenAuswahl::render( Bild &zRObj )
+{
+	if( !zRObj.setDrawOptions( pos.x, pos.y, ram->getBreite(), ram->getHeight() ) )
+		return;
+	zRObj.setAlpha( alpha );
+	ram->render( zRObj );
+	if( fenster )
+		fenster->render( zRObj );
+	zRObj.releaseAlpha();
+	laden->render( zRObj );
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+
+// Reference Counting
+KartenKaufenAuswahl *KartenKaufenAuswahl::getThis()
+{
+	ref++;
+	return this;
+}
+
+KartenKaufenAuswahl *KartenKaufenAuswahl::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der KartenKaufenListeEintrag Klasse aus KartenKaufen.h
+// Konstruktor
+KartenKaufenListeEintrag::KartenKaufenListeEintrag( int id, Schrift *schrift )
+{
+	karteId = id;
+	auswählen = initKnopf( 173, 73, 22, 22, 0, 0, "" );
+	auswählen->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Rahmen | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	auswählen->setHintergrundBildZ( bilder->get( "shop.ltdb/weiter.png" ) );
+	initToolTip( auswählen, "Karte auswählen.", schrift, hauptScreen );
+	auswählen->setLinienRahmenBreite( 1 );
+	LTDBDatei *datei = new LTDBDatei();
+	Text *bdpf = new Text( "data/tmp/shop/kaufen/karten/" );
+	bdpf->append( id );
+	bdpf->append( "/titelbg.ltdb" );
+	datei->setDatei( bdpf );
+	hintergrund = datei->laden( 0, new Text( "auswbg.jpg" ) );
+	datei->release();
+	ausgewählt = new AlphaFeld();
+	ausgewählt->setPosition( 1, 1 );
+	ausgewählt->setSize( 198, 98 );
+	ausgewählt->setFarbe( 0x0000FF00 );
+	ausgewählt->setStrength( 10 );
+	ram = new LRahmen();
+	ram->setSize( 200, 100 );
+	ram->setFarbe( 0xFFFFFFFF );
+	ausw = 0;
+	rend = 0;
+	ref = 1;
+}
+
+// Destruktor
+KartenKaufenListeEintrag::~KartenKaufenListeEintrag()
+{
+	auswählen->release();
+	if( hintergrund )
+		hintergrund->release();
+	ausgewählt->release();
+	ram->release();
+}
+
+// nicht constant
+void KartenKaufenListeEintrag::resetAuswahl()
+{
+	ausw = 0;
+}
+
+bool KartenKaufenListeEintrag::doMausEreignis( MausEreignis &me )
+{
+	bool vera = me.verarbeitet;
+	auswählen->doMausEreignis( me );
+	if( !vera && me.verarbeitet && me.id == ME_RLinks )
+	{
+		ausw = 1;
+		return 1;
+	}
+	return 0;
+}
+
+bool KartenKaufenListeEintrag::tick( double zeit )
+{
+	rend |= ausgewählt->tick( zeit );
+	rend |= auswählen->tick( zeit );
+	int a = ( ausgewählt->getFarbe() >> 24 ) & 0xFF;
+	if( ausw && a < 255 )
+	{
+		if( a + 150 * zeit > 255 )
+			a = 255;
+		else
+			a += (int)( zeit * 150 );
+		ausgewählt->setFarbe( ( ( a << 24 ) & 0xFF000000 ) | ( ausgewählt->getFarbe() & 0xFFFFFF ) );
+		rend = 1;
+	}
+	if( !ausw && a > 0 )
+	{
+		if( a - 150 * zeit < 0 )
+			a = 0;
+		else
+			a += (int)( zeit * 150 );
+		ausgewählt->setFarbe( ( ( a << 24 ) & 0xFF000000 ) | ( ausgewählt->getFarbe() & 0xFFFFFF ) );
+		rend = 1;
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void KartenKaufenListeEintrag::render( int yOff, Bild &zRObj )
+{
+	if( !zRObj.setDrawOptions( 0, yOff, 200, 100 ) )
+		return;
+	ram->render( zRObj );
+	if( hintergrund )
+		zRObj.drawBild( 1, 1, 198, 98, *hintergrund );
+	ausgewählt->render( zRObj );
+	auswählen->render( zRObj );
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+int KartenKaufenListeEintrag::getKarteId() const
+{
+	return karteId;
+}
+
+// Reference Counting
+KartenKaufenListeEintrag *KartenKaufenListeEintrag::getThis()
+{
+	ref++;
+	return this;
+}
+
+KartenKaufenListeEintrag *KartenKaufenListeEintrag::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der KartenKaufenListe Klasse aus KartenKaufen.h
+// Konstruktor
+KartenKaufenListe::KartenKaufenListe( Schrift *schrift )
+{
+	s = schrift;
+	pos = Punkt( 5, 55 );
+	ram = new LRahmen();
+	ram->setSize( 215, 380 );
+	ram->setFarbe( 0xFFFFFFFF );
+	einträge = new RCArray< KartenKaufenListeEintrag >();
+	vScroll = new VScrollBar();
+	vScroll->setKlickScroll( 10 );
+	vScroll->update( 0, 380 );
+	rend = 0;
+	ref = 1;
+}
+
+// Destruktor
+KartenKaufenListe::~KartenKaufenListe()
+{
+	s->release();
+	ram->release();
+	einträge->release();
+	vScroll->release();
+}
+
+// nicht constant
+void KartenKaufenListe::ladeKarten( Array< int > *karten )
+{
+	leeren();
+	int anz = karten->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+	{
+		if( shopKlient->ladeKarteTitel( karten->hat( i ) ? karten->get( i ) : 0 ) )
+			einträge->add( new KartenKaufenListeEintrag( karten->hat( i ) ? karten->get( i ) : 0, s->getThis() ) );
+	}
+	vScroll->update( anz * 100, 380 );
+	rend = 1;
+}
+
+void KartenKaufenListe::leeren()
+{
+    cs.lock();
+	einträge->leeren();
+    cs.unlock();
+	vScroll->update( 0, 380 );
+	rend = 1;
+}
+
+int KartenKaufenListe::doMausEreignis( MausEreignis &me )
+{
+	int mx = me.mx;
+	int my = me.my;
+	me.mx -= pos.x;
+	me.my -= pos.y;
+	vScroll->doMausMessage( 200, 0, 15, 380, me );
+	me.my += vScroll->getScroll();
+	int ret = 0;
+    cs.lock();
+	int anz = einträge->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+	{
+		if( einträge->z( i )->doMausEreignis( me ) )
+			ret = einträge->z( i )->getKarteId();
+		me.my += 100;
+	}
+	if( ret )
+	{
+		for( int i = 0; i < anz; i++ )
+		{
+			if( einträge->z( i )->getKarteId() != ret )
+				einträge->z( i )->resetAuswahl();
+		}
+	}
+    cs.unlock();
+	me.mx = mx;
+	me.my = my;
+	return ret;
+}
+
+bool KartenKaufenListe::tick( double zeit )
+{
+	rend |= vScroll->getRend();
+    cs.lock();
+	int anz = einträge->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+		rend |= einträge->z( i )->tick( zeit );
+    cs.unlock();
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void KartenKaufenListe::render( Bild &zRObj )
+{
+	int br = ram->getBreite();
+	int hö = ram->getHeight();
+	if( !zRObj.setDrawOptions( pos.x, pos.y, br, hö ) )
+		return;
+	ram->render( zRObj );
+    cs.lock();
+	int anz = einträge->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+		einträge->z( i )->render( i * 100 - vScroll->getScroll(), zRObj );
+    cs.unlock();
+	vScroll->render( 200, 0, 15, 380, zRObj );
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+int KartenKaufenListe::getEintragAnzahl()
+{
+	return einträge->getEintragAnzahl();
+}
+
+// Reference Counting
+KartenKaufenListe *KartenKaufenListe::getThis()
+{
+	ref++;
+	return this;
+}
+
+KartenKaufenListe *KartenKaufenListe::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der KartenKaufen Klasse aus KartenKaufen.h
+// Konstruktor
+KartenKaufen::KartenKaufen( Schrift *zSchrift )
+	: Thread()
+{
+	Bild *shopZurück = bilder->get( "shop.ltdb/zurück.png" );
+	if( !shopZurück )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/shop.ltdb" ) );
+		datei->leseDaten( 0 );
+		shopZurück = datei->laden( 0, new Text( "zurück.png" ) );
+		datei->release();
+		bilder->add( "shop.ltdb/zurück.png", shopZurück->getThis() );
+	}
+	Bild *shopWeiter = bilder->get( "shop.ltdb/weiter.png" );
+	if( !shopWeiter )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/shop.ltdb" ) );
+		datei->leseDaten( 0 );
+		shopWeiter = datei->laden( 0, new Text( "weiter.png" ) );
+		datei->release();
+		bilder->add( "shop.ltdb/weiter.png", shopWeiter->getThis() );
+	}
+	alpha = 255;
+	sichtbar = 0;
+	suchText = new Text( "" );
+	ram = new LRahmen();
+	ram->setSize( 780, 440 );
+	ram->setFarbe( 0xFFFFFFFF );
+	pos = Punkt( 10, 50 );
+	spielArt = new AuswahlBox();
+	spielArt->setStyle( AuswahlBox::Style::AuswahlBuffer | AuswahlBox::Style::MausBuffer | AuswahlBox::Style::Erlaubt | AuswahlBox::Style::Hintergrund |
+                        AuswahlBox::Style::Rahmen | AuswahlBox::Style::Sichtbar | AuswahlBox::Style::VScroll | AuswahlBox::Style::MaxHeight );
+	spielArt->setSize( 200, 20 );
+	spielArt->setPosition( 5, 5 );
+	spielArt->setLinienRahmenFarbe( 0xFFFFFFFF );
+	spielArt->setLinienRahmenBreite( 1 );
+	spielArt->setMaxAuskappHeight( 100 );
+	spielArt->setSchriftZ( zSchrift->getThis() );
+	spielArt->setHintergrundFarbe( 0xFF000000 );
+	spielArt->setMausEreignis( _ret1ME );
+	spielArt->setAuswAlphaFeldFarbe( 0x5000FF00 );
+	spielArt->setAuswAlphaFeldStrength( -10 );
+	spielArt->setMausAlphaFeldFarbe( 0x1000FF00 );
+	spielArt->setMausAlphaFeldStrength( -10 );
+	spielArt->setEintragHeight( 20 );
+	spielArt->addEintrag( "Spiel Art wählen" );
+	suchFilterT = initTextFeld( 210, 5, 70, 20, zSchrift, TextFeld::Style::Text, "Suchfilter:" );
+	suchFilter = initTextFeld( 285, 5, 225, 20, zSchrift, TextFeld::Style::TextFeld, "" );
+	initToolTip( suchFilter, "Gebe etwas vom Namen der Karte ein, nach der du suchst.", zSchrift->getThis(), hauptScreen );
+	suchen = initKnopf( 515, 5, 100, 20, zSchrift, Knopf::Style::Sichtbar, "suchen" );
+	seiten = initTextFeld( 55, 30, 250, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, "Seite 0 von 0, 0 Funde." );
+	zurück = initKnopf( 5, 30, 20, 20, 0, 0, "" );
+	zurück->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	zurück->setHintergrundBildZ( shopZurück );
+	initToolTip( zurück, "Seite zurück blättern.", zSchrift->getThis(), hauptScreen );
+	weiter = initKnopf( 30, 30, 20, 20, 0, 0, "" );
+	weiter->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	weiter->setHintergrundBildZ( shopWeiter );
+	initToolTip( weiter, "Seite weiter blättern.", zSchrift->getThis(), hauptScreen );
+	liste = new KartenKaufenListe( zSchrift->getThis() );
+	auswahl = new KartenKaufenAuswahl( zSchrift );
+	laden = ( Framework::Animation2D* )ladeAnimation->dublizieren();
+	laden->setPosition( 365, 195 );
+	laden->setSichtbar( 0 );
+	tickVal = 0;
+	seite = 0;
+	maxSeite = 0;
+	rend = 0;
+	aktion = 0;
+	ref = 1;
+	start();
+}
+
+// Destruktor
+KartenKaufen::~KartenKaufen()
+{
+	if( run )
+		warteAufThread( 1000 );
+	if( run )
+		ende();
+	spielArt->release();
+	suchText->release();
+	ram->release();
+	suchFilterT->release();
+	suchFilter->release();
+	suchen->release();
+	seiten->release();
+	weiter->release();
+	zurück->release();
+	liste->release();
+	auswahl->release();
+	laden->release();
+}
+
+// nicht constant
+void KartenKaufen::setSichtbar( bool sicht )
+{
+	sichtbar = sicht;
+	if( !run && sichtbar )
+	{
+		aktion = 0;
+		start();
+	}
+}
+
+void KartenKaufen::thread()
+{
+	laden->setSichtbar( 1 );
+	if( !aktion )
+	{
+		Array< int > *saList = infoKlient->getAccountSpielArtListe();
+		if( saList )
+		{
+			RCArray< Text > *saNamen = new RCArray< Text >();
+			int anz = saList->getEintragAnzahl();
+			for( int i = 0; i < anz; i++ )
+			{
+				if( !saList->hat( i ) )
+					continue;
+				Text *name = infoKlient->getSpielName( saList->hat( i ) ? saList->get( i ) : 0 );
+				if( name )
+					saNamen->add( name );
+			}
+			spielArt->lockZeichnung();
+			spielArt->setAuswahl( 0 );
+			anz = spielArt->getEintragAnzahl();
+			for( int i = 1; i < anz; i++ )
+				spielArt->removeEintrag( 1 );
+			anz = saNamen->getEintragAnzahl();
+			for( int i = 0; i < anz; i++ )
+			{
+				if( saNamen->z( i ) )
+					spielArt->addEintrag( saNamen->z( i )->getText() );
+			}
+			spielArt->unlockZeichnung();
+			saNamen->release();
+			saList->release();
+		}
+		if( !liste->getEintragAnzahl() )
+		{
+			hauptScreen->lock();
+            suchText->setText( suchFilter->zText()->getText() );
+            seite = 1;
+            maxSeite = 1;
+            aktion = 1;
+			hauptScreen->unlock();
+		}
+        if( !aktion )
+        {
+            laden->setSichtbar( 0 );
+            return;
+        }
+	}
+	int spielArtId = 0;
+	if( spielArt->getAuswahl() > 0 )
+		spielArtId = infoKlient->getSpielId( spielArt->zEintrag( spielArt->getAuswahl() )->zText()->getText() );
+	Array< int > *list = shopKlient->suchKarten( suchText->getText(), spielArtId );
+	if( !list )
+	{
+		laden->setSichtbar( 0 );
+		run = 0;
+		return;
+	}
+	Array< int > *slist = new Array< int >();
+	int anz = list->getEintragAnzahl();
+	maxSeite = anz / 10 + 1;
+	if( !( anz % 10 ) )
+		maxSeite--;
+	while( anz <= seite * 10 && seite > 0 )
+		seite--;
+	for( int i = seite * 10; i < anz && i < seite * 10 + 10; i++ )
+		slist->add( list->hat( i ) ? list->get( i ) : 0 );
+	list->release();
+	auswahl->reset();
+	liste->ladeKarten( slist );
+	slist->release();
+	Text *t = new Text( "Seite " );
+	t->append( maxSeite ? seite + 1 : 0 );
+	t->append( " von " );
+	t->append( maxSeite );
+	t->append( ", " );
+	t->append( anz );
+	if( anz == 1 )
+		t->append( " Fund." );
+	else
+		t->append( " Funde." );
+	seiten->setText( t );
+	zurück->setStyle( TextFeld::Style::Erlaubt, seite > 0 );
+	weiter->setStyle( TextFeld::Style::Erlaubt, seite + 1 < maxSeite );
+	laden->setSichtbar( 0 );
+}
+
+void KartenKaufen::doMausEreignis( MausEreignis &me )
+{
+	if( !sichtbar || run )
+		return;
+	int mx = me.mx;
+	int my = me.my;
+	me.mx -= pos.x;
+	me.my -= pos.y;
+	spielArt->doMausEreignis( me );
+	suchFilter->doMausEreignis( me );
+	int auswId = liste->doMausEreignis( me );
+	if( auswId )
+		auswahl->ladeKarteSeite( auswId );
+	auswahl->doMausEreignis( me );
+	int ak = 0;
+	bool tmp = me.verarbeitet;
+	suchen->doMausEreignis( me );
+	ak = me.verarbeitet ? 1 : 0;
+	zurück->doMausEreignis( me );
+	ak = me.verarbeitet && !ak ? 2 : ak;
+	weiter->doMausEreignis( me );
+	ak = me.verarbeitet && !ak ? 3 : ak;
+	if( tmp )
+		ak = 0;
+	if( me.id == ME_RLinks )
+	{
+		switch( ak )
+		{
+		case 1: // Suchen
+			suchText->setText( suchFilter->zText()->getText() );
+			seite = 1;
+			maxSeite = 1;
+			aktion = 1;
+			start();
+			break;
+		case 2: // Seite zurück blättern
+			seite--;
+			if( seite < 1 )
+				seite = 1;
+			aktion = 1;
+			start();
+			break;
+		case 3: // Seite vorwärts blättern
+			seite++;
+			if( seite > maxSeite )
+				seite = maxSeite;
+			aktion = 1;
+			start();
+			break;
+		}
+	}
+	me.mx = mx;
+	me.my = my;
+}
+
+void KartenKaufen::doTastaturEreignis( TastaturEreignis &te )
+{
+	if( !sichtbar || run )
+		return;
+	bool vera = te.verarbeitet;
+	suchFilter->doTastaturEreignis( te );
+	if( !vera && te.verarbeitet && te.taste == T_Enter && te.id == TE_Release )
+	{
+		MausEreignis me;
+		me.id = ME_RLinks;
+		me.verarbeitet = 0;
+		me.mx = suchen->getX() + 1 + pos.x;
+		me.my = suchen->getY() + 1 + pos.y;
+		doMausEreignis( me );
+	}
+	auswahl->doTastaturEreignis( te );
+}
+
+bool KartenKaufen::tick( double zeit )
+{
+	rend |= spielArt->tick( zeit );
+	rend |= suchFilter->tick( zeit );
+	rend |= suchen->tick( zeit );
+	rend |= weiter->tick( zeit );
+	rend |= zurück->tick( zeit );
+	rend |= liste->tick( zeit );
+	rend |= auswahl->tick( zeit );
+	rend |= laden->tick( zeit );
+	tickVal += zeit * 250;
+	int val = (int)tickVal;
+	if( val < 1 )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	if( val > 10 )
+		val = 10;
+	tickVal -= val;
+	if( sichtbar && alpha != 255 && !run )
+	{
+		if( alpha + val > 255 )
+			alpha = 255;
+		else
+			alpha += val;
+		rend = 1;
+	}
+	if( sichtbar && alpha != 125 && run )
+	{
+		if( alpha > 125 )
+		{
+			if( alpha - val < 125 )
+				alpha = 125;
+			else
+				alpha -= val;
+			rend = 1;
+		}
+		else
+		{
+			if( alpha + val > 125 )
+				alpha = 125;
+			else
+				alpha += 125;
+			rend = 1;
+		}
+	}
+	if( !sichtbar && alpha != 0 )
+	{
+		if( alpha - val < 0 )
+			alpha = 0;
+		else
+			alpha -= val;
+		rend = 1;
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void KartenKaufen::render( Bild &zRObj )
+{
+	if( !alpha )
+		return;
+	int br = ram->getBreite();
+	int hö = ram->getHeight();
+	if( !zRObj.setDrawOptions( pos.x, pos.y, br, hö ) )
+		return;
+	zRObj.setAlpha( alpha );
+	ram->render( zRObj );
+	suchFilterT->render( zRObj );
+	suchFilter->render( zRObj );
+	suchen->render( zRObj );
+	seiten->render( zRObj );
+	weiter->render( zRObj );
+	zurück->render( zRObj );
+	liste->render( zRObj );
+	auswahl->render( zRObj );
+	spielArt->render( zRObj );
+	zRObj.releaseAlpha();
+	laden->render( zRObj );
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+bool KartenKaufen::istSichtbar() const
+{
+	return sichtbar;
+}
+
+// Reference Counting
+KartenKaufen *KartenKaufen::getThis()
+{
+	ref++;
+	return this;
+}
+
+KartenKaufen *KartenKaufen::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 153 - 0
KSGClient/NachLogin/Shop/Karten/KartenKaufen.h

@@ -0,0 +1,153 @@
+#ifndef KartenKaufen_H
+#define KartenKaufen_H
+
+#include <Schrift.h>
+#include <Knopf.h>
+#include <KSGScript.h>
+#include <Array.h>
+#include <Scroll.h>
+#include <Animation.h>
+#include <Thread.h>
+#include <AuswahlBox.h>
+
+using namespace Framework;
+using namespace KSGScript;
+
+class KartenKaufenAuswahl : private Thread
+{
+private:
+	int karteId;
+	unsigned char alpha;
+	KSGScriptObj *fenster;
+	Framework::Animation2D *laden;
+	Punkt pos;
+	LRahmen *ram;
+	HINSTANCE ksgs;
+	bool aktion;
+	int ref;
+
+public:
+	// Konstruktor
+	KartenKaufenAuswahl( Schrift *zSchrift );
+	// Destruktor
+	~KartenKaufenAuswahl();
+	// nicht constant
+	void ladeKarteSeite( int id );
+	void reset();
+	virtual void thread();
+	void ksgsAktion( RCArray< KSGSVariable > *parameter, KSGSVariable **retVal );
+	void doMausEreignis( MausEreignis &me );
+	void doTastaturEreignis( TastaturEreignis &te );
+	bool tick( double zeit );
+	void render( Bild &zRObj );
+	// constant
+
+	// Reference Counting
+	KartenKaufenAuswahl *getThis();
+	KartenKaufenAuswahl *release();
+};
+
+class KartenKaufenListeEintrag
+{
+private:
+	int karteId;
+	Knopf *auswählen;
+	Bild *hintergrund;
+	AlphaFeld *ausgewählt;
+	LRahmen *ram;
+	bool ausw;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	KartenKaufenListeEintrag( int id, Schrift *schrift );
+	// Destruktor
+	~KartenKaufenListeEintrag();
+	// nicht constant
+	void resetAuswahl();
+	bool doMausEreignis( MausEreignis &me );
+	bool tick( double zeit );
+	void render( int yOff, Bild &zRObj );
+	// constant
+	int getKarteId() const;
+	// Reference Counting
+	KartenKaufenListeEintrag *getThis();
+	KartenKaufenListeEintrag *release();
+};
+
+class KartenKaufenListe
+{
+private:
+	Schrift *s;
+	LRahmen *ram;
+	Punkt pos;
+	RCArray< KartenKaufenListeEintrag > *einträge;
+	VScrollBar *vScroll;
+	bool rend;
+	int ref;
+	Critical cs;
+
+public:
+	// Konstruktor
+	KartenKaufenListe( Schrift *schrift );
+	// Destruktor
+	~KartenKaufenListe();
+	// nicht constant
+	void ladeKarten( Array< int > *karten );
+	void leeren();
+	int doMausEreignis( MausEreignis &me );
+	bool tick( double zeit );
+	void render( Bild &zRObj );
+	// constant
+	int getEintragAnzahl();
+	// Reference Counting
+	KartenKaufenListe *getThis();
+	KartenKaufenListe *release();
+};
+
+class KartenKaufen : private Thread
+{
+private:
+	unsigned char alpha;
+	bool sichtbar;
+	Text *suchText;
+	LRahmen *ram;
+	AuswahlBox *spielArt;
+	TextFeld *suchFilterT;
+	TextFeld *suchFilter;
+	Knopf *suchen;
+	TextFeld *seiten;
+	Knopf *weiter;
+	Knopf *zurück;
+	Punkt pos;
+	KartenKaufenListe *liste;
+	KartenKaufenAuswahl *auswahl;
+	Framework::Animation2D *laden;
+	double tickVal;
+	int seite;
+	int maxSeite;
+	int aktion;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	KartenKaufen( Schrift *zSchrift );
+	// Destruktor
+	~KartenKaufen();
+	// nicht constant
+	void setSichtbar( bool sicht );
+	virtual void thread();
+	void doMausEreignis( MausEreignis &me );
+	void doTastaturEreignis( TastaturEreignis &te );
+	bool tick( double zeit );
+	void render( Bild &zRObj );
+	// constant
+	bool istSichtbar() const;
+	// Reference Counting
+	KartenKaufen *getThis();
+	KartenKaufen *release();
+};
+
+#endif

+ 257 - 0
KSGClient/NachLogin/Shop/Shop.cpp

@@ -0,0 +1,257 @@
+#include "Shop.h"
+#include "../../Global/Variablen.h"
+#include "../../Global/Initialisierung.h"
+#include <Punkt.h>
+#include <Rahmen.h>
+
+// Inhalt der Shop Klasse aus Shop.h
+// Konstruktor
+Shop::Shop( Schrift *zSchrift, Fenster *zNachLoginFenster, int x )
+	: Zeichnung()
+{
+	bildschirmGröße = BildschirmGröße();
+	pos = Punkt( x, 67 );
+	gr = Punkt( 102, 32 );
+	rahmen = new LRahmen();
+	rahmen->setFarbe( 0xFFFFFFFF );
+	rahmen->setSize( 102, 32 );
+	spiele = initKnopf( 10, 10, 100, 30, zSchrift, Knopf::Style::Sichtbar, "Spiele" );
+	spiele->setLinienRahmenBreite( 2 );
+	spiele->setAlphaFeldFarbe( 0xFF000000 );
+	spiele->setAlphaFeldStrength( 20 );
+	initToolTip( spiele, "Shop nach Spielen durchsuchen.", zSchrift->getThis(), hauptScreen );
+	karten = initKnopf( 120, 10, 100, 30, zSchrift, Knopf::Style::Sichtbar, "Karten" );
+	initToolTip( karten, "Shop nach Karten durchsuchen.", zSchrift->getThis(), hauptScreen );
+	alpha = 0;
+	animation = 0;
+	sichtbar = 0;
+	tickVal = 0;
+	jetzt = 0;
+	prozent1 = 0;
+	prozent2 = 0;
+	begPos = Punkt( 0, 0 );
+	begGröße = Punkt( 0, 0 );
+	größe1 = Punkt( 102, 32 );
+	pos1 = Punkt( x, 67 );
+	größe2 = Punkt( 800, 500 );
+	pos2 = bildschirmGröße / 2 - größe2 / 2;
+	zNachLoginFenster->addMember( this );
+	spielKaufen = new SpieleKaufen( zSchrift );
+	karteKaufen = new KartenKaufen( zSchrift );
+	ref = 1;
+}
+
+// Destruktor
+Shop::~Shop()
+{
+	rahmen->release();
+	spiele->release();
+	karten->release();
+	spielKaufen->release();
+	karteKaufen->release();
+}
+
+// nicht constant
+void Shop::setSichtbar( bool sicht )
+{
+	begPos = pos;
+	begGröße = gr;
+	animation |= ( sicht ? 0x1 : 0x2 );
+	rend = 1;
+}
+
+bool Shop::tick( double tickVal )
+{
+	rend |= spiele->tick( tickVal );
+	rend |= karten->tick( tickVal );
+	rend |= spielKaufen->tick( tickVal );
+	rend |= karteKaufen->tick( tickVal );
+	this->tickVal += tickVal * 150;
+	int val = ( int )this->tickVal;
+	if( val < 1 )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	this->tickVal -= val;
+	if( ( animation | 0x1 ) == animation ) // Einblenden
+	{
+		if( prozent1 != 100 )
+		{
+			prozent1 += val;
+			if( prozent1 >= 100 )
+			{
+				prozent1 = 100;
+				if( !jetzt )
+				{
+					spielKaufen->setSichtbar( 1 );
+					jetzt = 1;
+				}
+			}
+			pos = begPos + (Punkt)( ( ( Vec2< double > )( pos2 - begPos ) / 100.0 ) * prozent1 );
+			gr = begGröße + (Punkt)( ( ( Vec2< double > )( größe2 - begGröße ) / 100.0 ) * prozent1 );
+		}
+		else if( alpha != 255 )
+		{
+			alpha += val * 2;
+			if( alpha >= 255 || ( animation | 0x2 ) == animation )
+			{
+				alpha = 255;
+				animation &= ~0x1;
+				sichtbar = 1;
+				prozent1 = 0;
+			}
+		}
+		rend = 1;
+	}
+	if( ( animation | 0x2 ) == animation ) // ausblenden
+	{
+		if( alpha != 0 )
+		{
+			alpha -= val * 2;
+			if( alpha < 0 )
+				alpha = 0;
+		}
+		else
+		{
+			prozent2 += val;
+			if( prozent2 > 100 )
+				prozent2 = 100;
+			pos = begPos + (Punkt)( ( ( Vec2< double > )( pos1 - begPos ) / 100.0 ) * prozent2 );
+			gr = begGröße + (Punkt)( ( ( Vec2< double > )( größe1 - begGröße ) / 100.0 ) * prozent2 );
+			if( prozent2 == 100 )
+			{
+				prozent2 = 0;
+				animation &= ~0x2;
+				sichtbar = 0;
+			}
+		}
+		rend = 1;
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void Shop::doMausEreignis( MausEreignis &me )
+{
+	if( !sichtbar )
+		return;
+	if( animation )
+		return;
+	int mx = me.mx;
+	int my = me.my;
+	me.mx -= pos.x;
+	me.my -= pos.y;
+	int ak = 0;
+	bool tmp = me.verarbeitet;
+	spiele->doMausEreignis( me );
+	ak = me.verarbeitet ? 1 : 0;
+	karten->doMausEreignis( me );
+	ak = me.verarbeitet && !ak ? 2 : ak;
+	if( tmp )
+		ak = 0;
+	if( me.id == ME_RLinks )
+	{
+		switch( ak )
+		{
+		case 1: // spiele Klick
+			if( jetzt == 1 )
+				break;
+			karten->setLinienRahmenBreite( 1 );
+			karten->setAlphaFeldFarbe( 0x5500FF00 );
+			karten->setAlphaFeldStrength( -5 );
+			spiele->setLinienRahmenBreite( 2 );
+			spiele->setAlphaFeldFarbe( 0xFF000000 );
+			spiele->setAlphaFeldStrength( 20 );
+			karteKaufen->setSichtbar( 0 );
+			spielKaufen->setSichtbar( 1 );
+			jetzt = 1;
+			break;
+		case 2: // karten Klick
+			if( jetzt == 2 || jetzt == 3 )
+				break;
+			spiele->setLinienRahmenBreite( 1 );
+			spiele->setAlphaFeldFarbe( 0x5500FF00 );
+			spiele->setAlphaFeldStrength( -5 );
+			karten->setLinienRahmenBreite( 2 );
+			karten->setAlphaFeldFarbe( 0xFF000000 );
+			karten->setAlphaFeldStrength( 20 );
+			spielKaufen->setSichtbar( 0 );
+			karteKaufen->setSichtbar( 1 );
+			jetzt = 2;
+			break;
+		}
+	}
+	switch( jetzt )
+	{
+	case 1: // Spiel kaufen
+		spielKaufen->doMausEreignis( me );
+		break;
+	case 2: // Karten kaufen
+		karteKaufen->doMausEreignis( me );
+		break;
+	}
+	me.mx = mx;
+	me.my = my;
+}
+
+void Shop::doTastaturEreignis( TastaturEreignis &te )
+{
+	if( !sichtbar )
+		return;
+	switch( jetzt )
+	{
+	case 1: // Spiel kaufen
+		spielKaufen->doTastaturEreignis( te );
+		break;
+	case 2: // Karten kaufen
+		karteKaufen->doTastaturEreignis( te );
+		break;
+	}
+}
+
+void Shop::render( Bild &zRObj )
+{
+	if( pos == pos1 )
+		return;
+	if( !zRObj.setDrawOptions( pos, gr ) )
+		return;
+	rahmen->setSize( gr );
+	rahmen->render( zRObj );
+	int rbr = rahmen->getRBreite();
+	zRObj.setAlpha( (unsigned char)alpha );
+	spiele->render( zRObj );
+	karten->render( zRObj );
+	spielKaufen->render( zRObj );
+	karteKaufen->render( zRObj );
+	zRObj.releaseAlpha();
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+bool Shop::istAnimiert() const
+{
+	return animation != 0;
+}
+
+bool Shop::istSichtbar() const
+{
+	return sichtbar || prozent1 != 0;
+}
+
+// Reference Counting
+Shop *Shop::getThis()
+{
+	ref++;
+	return this;
+}
+
+Shop *Shop::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 56 - 0
KSGClient/NachLogin/Shop/Shop.h

@@ -0,0 +1,56 @@
+#ifndef Shop_H
+#define Shop_H
+
+#include <Klient.h>
+#include <Fenster.h>
+#include <Knopf.h>
+#include <Animation.h>
+#include "Spiele/SpieleKaufen.h"
+#include "Karten/KartenKaufen.h"
+
+using namespace Framework;
+
+class Shop : public Zeichnung
+{
+private:
+	int animation;
+	Punkt begPos;
+	Punkt begGröße;
+	Punkt pos1;
+	Punkt größe1;
+	Punkt pos2;
+	Punkt größe2;
+	Punkt bildschirmGröße;
+	LRahmen *rahmen;
+	Knopf *spiele;
+	Knopf *karten;
+	SpieleKaufen *spielKaufen;
+	KartenKaufen *karteKaufen;
+	int alpha;
+	bool sichtbar;
+	int jetzt;
+	int prozent1;
+	int prozent2;
+	double tickVal;
+	int ref;
+
+public:
+	// Konstruktor
+	Shop( Schrift *zSchrift, Fenster *zNachLoginFenster, int x );
+	// Destruktor
+	~Shop();
+	// nicht constant
+	void setSichtbar( bool sicht );
+	bool tick( double tickVal ) override;
+	void doMausEreignis( MausEreignis &me ) override;
+	void doTastaturEreignis( TastaturEreignis &te ) override;
+	void render( Bild &zRObj ) override;
+	// constant
+	bool istAnimiert() const;
+	bool istSichtbar() const;
+	// Reference Counting
+	Shop *getThis();
+	Shop *release();
+};
+
+#endif

+ 1035 - 0
KSGClient/NachLogin/Shop/Spiele/SpieleKaufen.cpp

@@ -0,0 +1,1035 @@
+#include "SpieleKaufen.h"
+#include <Rahmen.h>
+#include <Punkt.h>
+#include "../../../Global/Initialisierung.h"
+#include "../../../Global/Variablen.h"
+#include <DateiSystem.h>
+#include <AlphaFeld.h>
+#include <KSGTDatei.h>
+
+void SpielKaufenKSGSAktion( void *p, RCArray< KSGSVariable > *parameter, KSGSVariable **retVal )
+{
+	if( !p )
+		return;
+	( (SpieleKaufenAuswahl*)p )->ksgsAktion( parameter, retVal );
+}
+
+// Inhalt der SpieleKaufenAuswahl Klasse aus SpieleKaufen.h
+// Konstruktor
+SpieleKaufenAuswahl::SpieleKaufenAuswahl( Schrift *zSchrift )
+{
+	spielId = 0;
+	alpha = 0;
+	ksgs = dllDateien->ladeDLL( "KSGScript.dll", "data/bin/KSGScript.dll" );
+	if( ksgs )
+	{
+		KSGSGetZeichnung getKSGScript = (KSGSGetZeichnung)GetProcAddress( ksgs, KSGS_START_FUNKTION );
+		if( getKSGScript )
+		{
+			fenster = getKSGScript();
+			fenster->setBildschirmZ( hauptScreen->getThis() );
+			fenster->setSchriftZ( zSchrift->getThis() );
+			fenster->setSize( 555, 380 );
+			fenster->setRückrufParam( this );
+			fenster->setRückrufFunktion( SpielKaufenKSGSAktion );
+		}
+		else
+		{
+			fenster = 0;
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+														  new Text( "Der Einstiegspunkt '" KSGS_START_FUNKTION "' in der DLL-Datei "
+																	"'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+														  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+		}
+	}
+	else
+	{
+		fenster = 0;
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+													  new Text( "Die DLL-Datei 'data/bin/KSGScript.dll' konnte nicht geladen werden." ),
+													  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+	}
+	ram = new LRahmen();
+	ram->setSize( 555, 380 );
+	ram->setFarbe( 0xFFFFFFFF );
+	laden = ( Framework::Animation2D* )ladeAnimation->dublizieren();
+	laden->setPosition( 252, 165 );
+	laden->setSichtbar( 0 );
+	pos = Punkt( 220, 55 );
+	aktion = 0;
+	ref = 1;
+}
+
+// Destruktor
+SpieleKaufenAuswahl::~SpieleKaufenAuswahl()
+{
+	if( run )
+		warteAufThread( 2000 );
+	if( run )
+		ende();
+	if( fenster )
+	{
+		fenster->zurücksetzen();
+		fenster->release();
+	}
+	ram->release();
+	laden->release();
+	if( ksgs )
+		dllDateien->releaseDLL( "KSGScript.dll" );
+}
+
+// nicht constant
+void SpieleKaufenAuswahl::ladeSpielSeite( int id )
+{
+	if( run )
+		warteAufThread( 2000 );
+	if( run )
+		return;
+	spielId = id;
+	aktion = 1;
+	start();
+}
+
+void SpieleKaufenAuswahl::reset()
+{
+	if( run )
+		warteAufThread( 2000 );
+	if( run )
+		return;
+	aktion = 0;
+	start();
+}
+
+void SpieleKaufenAuswahl::thread()
+{
+	laden->setSichtbar( 1 );
+	if( !aktion || spielId )
+	{
+		while( alpha )
+			Sleep( 100 );
+		if( !aktion )
+			spielId = 0;
+		if( fenster )
+			fenster->zurücksetzen();
+	}
+	if( aktion )
+	{
+		while( alpha )
+			Sleep( 100 );
+		shopKlient->ladeSpielSeite( spielId );
+		Text *pfad = new Text( "data/tmp/shop/kaufen/spiele/" );
+		pfad->append( spielId );
+		pfad->append( "/seite.ksgs" );
+		if( fenster )
+		{
+			fenster->setScriptDatei( pfad );
+			fenster->neuLaden();
+		}
+	}
+	laden->setSichtbar( 0 );
+	run = 0;
+}
+
+void SpieleKaufenAuswahl::ksgsAktion( RCArray< KSGSVariable > *parameter, KSGSVariable **retVal )
+{
+	KSGSVariable *befehl = parameter->z( 0 );
+	if( !befehl )
+		return;
+	Text *b = befehl->getText();
+	if( !b )
+		return;
+	if( b->istGleich( "GetBesitzStatus" ) )
+	{
+		int besitz = shopKlient->getSpielBesitzStatus( spielId );
+		KSGSGetVariable getKSGSVariable = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
+		if( getKSGSVariable )
+		{
+			KSGSVariableDef def = { KSGS_INT, 0, 3, ( Text() += besitz ).getText() };
+			*retVal = getKSGSVariable( fenster, &def );
+		}
+		else
+		{
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+														  new Text( "Der Einstiegspunkt '" KSGS_VARIABLE_FUNKTION "' in der DLL-Datei "
+																	"'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+														  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+		}
+		b->release();
+		return;
+	}
+	if( b->istGleich( "GetPreis" ) )
+	{
+		KSGSVariable *version = parameter->z( 1 );
+		if( !version )
+		{
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+														  new Text( "Auf dieser Seite befindet sich ein Fehler im KSG-Script. "
+																	"Sie könnte eventuell nicht richtig funktionieren." ),
+														  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+		}
+		else
+		{
+			bool testVersion = !version->getInt();
+			int preis = shopKlient->getSpielPreis( spielId, testVersion );
+			KSGSGetVariable getKSGSVariable = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
+			if( getKSGSVariable )
+			{
+				KSGSVariableDef def = { KSGS_INT, 0, 3, ( Text() += preis ).getText() };
+				*retVal = getKSGSVariable( fenster, &def );
+			}
+			else
+			{
+				nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+															  new Text( "Der Einstiegspunkt '" KSGS_VARIABLE_FUNKTION "' in der DLL-Datei "
+																		"'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+															  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+			}
+		}
+		b->release();
+		return;
+	}
+	if( b->istGleich( "GetTestVersionVerbleibend" ) )
+	{
+		int verbleibend = shopKlient->getSpielTestversion( spielId );
+		KSGSGetVariable getKSGSVariable = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
+		if( getKSGSVariable )
+		{
+			KSGSVariableDef def = { KSGS_INT, 0, 3, ( Text() += verbleibend ).getText() };
+			*retVal = getKSGSVariable( fenster, &def );
+		}
+		else
+		{
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+														  new Text( "Der Einstiegspunkt '" KSGS_VARIABLE_FUNKTION "' in der DLL-Datei "
+																	"'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+														  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+		}
+		b->release();
+		return;
+	}
+	if( b->istGleich( "GetErwerbbarStatus" ) )
+	{
+		int erwerbbar = shopKlient->istSpielErwerbbar( spielId );
+		KSGSGetVariable getKSGSVariable = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
+		if( getKSGSVariable )
+		{
+			KSGSVariableDef def = { KSGS_INT, 0, 3, ( Text() += erwerbbar ).getText() };
+			*retVal = getKSGSVariable( fenster, &def );
+		}
+		else
+		{
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+														  new Text( "Der Einstiegspunkt '" KSGS_VARIABLE_FUNKTION "' in der DLL-Datei "
+																	"'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+														  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+		}
+		b->release();
+		return;
+	}
+	if( b->istGleich( "GetKupfer" ) )
+	{
+		int kupfer = infoKlient->getKupfer();
+		KSGSGetVariable getKSGSVariable = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
+		if( getKSGSVariable )
+		{
+			KSGSVariableDef def = { KSGS_INT, 0, 3, ( Text() += kupfer ).getText() };
+			*retVal = getKSGSVariable( fenster, &def );
+		}
+		else
+		{
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+														  new Text( "Der Einstiegspunkt '" KSGS_VARIABLE_FUNKTION "' in der DLL-Datei "
+																	"'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+														  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+		}
+		b->release();
+		return;
+	}
+	if( b->istGleich( "Kaufen" ) )
+	{
+		KSGSVariable *version = parameter->z( 1 );
+		if( !version )
+		{
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+														  new Text( "Auf dieser Seite befindet sich ein Fehler im KSG-Script. "
+																	"Sie könnte eventuell nicht richtig funktionieren." ),
+														  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+		}
+		else
+		{
+			bool testVersion = !version->getInt();
+			if( !shopKlient->spielErwerben( spielId, testVersion ) )
+			{
+				nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+															  new Text( "Das Spiel konnte nicht erworben werden." ),
+															  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+			}
+			else
+			{
+				int dgId = infoKlient->getDateiGruppeIdVonSpiel( spielId );
+				if( dgId )
+				{
+					KSGTDatei *dg = new KSGTDatei( "data/dg.ksgt" );
+					dg->laden();
+					bool gefunden = 0;
+					for( int i = 0; i < dg->getZeilenAnzahl(); i++ )
+					{
+						if( dg->zFeld( i, 0 ) && TextZuInt( dg->zFeld( i, 0 )->getText(), 10 ) == dgId )
+						{
+							gefunden = 1;
+							break;
+						}
+					}
+					if( !gefunden )
+					{
+						for( int i = 0; i < dg->getZeilenAnzahl(); i++ )
+						{
+							if( dg->zFeld( i, 3 ) && !dg->zFeld( i, 3 )->istGleich( "SOFORT" ) && !dg->zFeld( i, 3 )->istGleich( "NICHT" ) )
+							{
+								int platz = TextZuInt( dg->zFeld( i, 3 )->getText(), 10 ) + 1;
+								Text *plT = new Text();
+								plT->append( platz );
+								dg->zFeld( i, 3 )->setText( plT );
+							}
+						}
+						Text *idT = new Text();
+						idT->append( dgId );
+						Text *pfad = infoKlient->getDateiGruppePfad( dgId );
+						if( pfad )
+						{
+							RCArray< Text > *zeile = new RCArray< Text >();
+							zeile->add( idT );
+							zeile->add( pfad );
+							zeile->add( new Text( "0" ) );
+							zeile->add( new Text( "0" ) );
+							dg->addZeile( 4, zeile );
+						}
+						else
+							idT->release();
+					}
+					dg->speichern();
+					dg->release();
+				}
+			}
+			if( run )
+				warteAufThread( 2000 );
+			if( run )
+			{
+				b->release();
+				return;
+			}
+			aktion = 1;
+			start();
+		}
+		b->release();
+		return;
+	}
+	if( b->istGleich( "GetBild" ) )
+	{
+		KSGSVariable *pfad = parameter->z( 1 );
+		KSGSVariable *name = parameter->z( 2 );
+		if( !pfad || !name )
+		{
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+														  new Text( "Auf dieser Seite befindet sich ein Fehler im KSG-Script. "
+																	"Sie könnte eventuell nicht richtig funktionieren." ),
+														  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+		}
+		else
+		{
+			Text *pf = pfad->getText();
+			Text *n = name->getText();
+			if( !pf || !n )
+			{
+				nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+															  new Text( "Auf dieser Seite befindet sich ein Fehler im KSG-Script. "
+																		"Sie könnte eventuell nicht richtig funktionieren." ),
+															  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+			}
+			else
+			{
+				KSGSGetVariable getKSGSVariable = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
+				if( getKSGSVariable )
+				{
+					int p = n->positionVon( ".ltdb/" );
+					if( p < 0 )
+						p = 0;
+					else
+						p += 6;
+					Bild *b = bilder->get( *n );
+					if( !b )
+					{
+						LTDBDatei *dat = new LTDBDatei();
+						dat->setDatei( pf->getThis() );
+						dat->leseDaten( 0 );
+						b = dat->laden( 0, n->getTeilText( p, n->getLength() ) );
+						dat->release();
+						if( b )
+							bilder->add( *n, b->getThis() );
+					}
+					if( b )
+					{
+						KSGSVariableDef def = { KSGS_BILD, 0, 3, "" };
+						KSGSVariable *ret = getKSGSVariable( fenster, &def );
+						KSGSSetBild setKSGSBild = (KSGSSetBild)GetProcAddress( ksgs, KSGS_SET_BILD_FUNKTION );
+						if( !setKSGSBild )
+						{
+							nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+																		  new Text( "Der Einstiegspunkt '" KSGS_SET_BILD_FUNKTION "' in der DLL-Datei "
+																		  "'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+																		  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+							b->release();
+						}
+						else
+							setKSGSBild( ret, b );
+						*retVal = ret;
+					}
+				}
+				else
+				{
+					nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+																  new Text( "Der Einstiegspunkt '" KSGS_VARIABLE_FUNKTION "' in der DLL-Datei "
+																			"'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+																  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+				}
+			}
+			if( pf )
+				pf->release();
+			if( n )
+				n->release();
+		}
+		b->release();
+		return;
+	}
+}
+
+void SpieleKaufenAuswahl::doMausEreignis( MausEreignis &me )
+{
+	if( run )
+		return;
+	me.mx -= pos.x;
+	me.my -= pos.y;
+	if( fenster )
+		fenster->doMausEreignis( me );
+	me.mx += pos.x;
+	me.my += pos.y;
+}
+
+void SpieleKaufenAuswahl::doTastaturEreignis( TastaturEreignis &te )
+{
+	if( run )
+		return;
+	if( fenster )
+		fenster->doTastaturEreignis( te );
+}
+
+bool SpieleKaufenAuswahl::tick( double zeit )
+{
+	bool rend = ( fenster && !run ) ? fenster->tick( zeit ) : 0;
+	rend |= laden->tick( zeit );
+	if( ( run || !spielId ) && alpha > 0 )
+	{
+		if( alpha - zeit * 150 < 0 )
+			alpha = 0;
+		else
+			alpha -= (unsigned char)( zeit * 150 );
+		rend = 1;
+	}
+	if( !run && spielId && alpha < 255 )
+	{
+		if( alpha + zeit * 150 > 255 )
+			alpha = 255;
+		else
+			alpha += (unsigned char)( zeit * 150 );
+		rend = 1;
+	}
+	return rend;
+}
+
+void SpieleKaufenAuswahl::render( Bild &zRObj )
+{
+	if( !zRObj.setDrawOptions( pos.x, pos.y, ram->getBreite(), ram->getHeight() ) )
+		return;
+	zRObj.setAlpha( alpha );
+	ram->render( zRObj );
+	if( fenster )
+		fenster->render( zRObj );
+	zRObj.releaseAlpha();
+	laden->render( zRObj );
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+
+// Reference Counting
+SpieleKaufenAuswahl *SpieleKaufenAuswahl::getThis()
+{
+	ref++;
+	return this;
+}
+
+SpieleKaufenAuswahl *SpieleKaufenAuswahl::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der SpieleKaufenListeEintrag Klasse aus SpieleKaufen.h
+// Konstruktor
+SpieleKaufenListeEintrag::SpieleKaufenListeEintrag( int id, Schrift *schrift )
+{
+	spielId = id;
+	auswählen = initKnopf( 173, 73, 22, 22, 0, 0, "" );
+	auswählen->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Rahmen | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	auswählen->setHintergrundBildZ( bilder->get( "shop.ltdb/weiter.png" ) );
+	initToolTip( auswählen, "Spiel auswählen.", schrift, hauptScreen );
+	auswählen->setLinienRahmenBreite( 1 );
+	LTDBDatei *datei = new LTDBDatei();
+	Text *bdpf = new Text( "data/tmp/shop/kaufen/spiele/" );
+	bdpf->append( id );
+	bdpf->append( "/titelbg.ltdb" );
+	datei->setDatei( bdpf );
+	hintergrund = datei->laden( 0, new Text( "auswbg.jpg" ) );
+	datei->release();
+	ausgewählt = new AlphaFeld();
+	ausgewählt->setPosition( 1, 1 );
+	ausgewählt->setSize( 198, 98 );
+	ausgewählt->setFarbe( 0x0000FF00 );
+	ausgewählt->setStrength( 10 );
+	ram = new LRahmen();
+	ram->setSize( 200, 100 );
+	ram->setFarbe( 0xFFFFFFFF );
+	ausw = 0;
+	rend = 0;
+	ref = 1;
+}
+
+// Destruktor
+SpieleKaufenListeEintrag::~SpieleKaufenListeEintrag()
+{
+	auswählen->release();
+	if( hintergrund )
+		hintergrund->release();
+	ausgewählt->release();
+	ram->release();
+}
+
+// nicht constant
+void SpieleKaufenListeEintrag::resetAuswahl()
+{
+	ausw = 0;
+}
+
+bool SpieleKaufenListeEintrag::doMausEreignis( MausEreignis &me )
+{
+	bool vera = me.verarbeitet;
+	auswählen->doMausEreignis( me );
+	if( !vera && me.verarbeitet && me.id == ME_RLinks )
+	{
+		ausw = 1;
+		return 1;
+	}
+	return 0;
+}
+
+bool SpieleKaufenListeEintrag::tick( double zeit )
+{
+	rend |= ausgewählt->tick( zeit );
+	rend |= auswählen->tick( zeit );
+	int a = ( ausgewählt->getFarbe() >> 24 ) & 0xFF;
+	if( ausw && a < 255 )
+	{
+		if( a + 150 * zeit > 255 )
+			a = 255;
+		else
+			a += (int)( 150 * zeit );
+		ausgewählt->setFarbe( ( ( a << 24 ) & 0xFF000000 ) | ( ausgewählt->getFarbe() & 0xFFFFFF ) );
+		rend = 1;
+	}
+	if( !ausw && a > 0 )
+	{
+		if( a - 150 * zeit < 0 )
+			a = 0;
+		else
+			a -= (int)( 150 * zeit );
+		ausgewählt->setFarbe( ( ( a << 24 ) & 0xFF000000 ) | ( ausgewählt->getFarbe() & 0xFFFFFF ) );
+		rend = 1;
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void SpieleKaufenListeEintrag::render( int yOff, Bild &zRObj )
+{
+	if( !zRObj.setDrawOptions( 0, yOff, 200, 100 ) )
+		return;
+	ram->render( zRObj );
+	if( hintergrund )
+		zRObj.drawBild( 1, 1, 198, 98, *hintergrund );
+	ausgewählt->render( zRObj );
+	auswählen->render( zRObj );
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+int SpieleKaufenListeEintrag::getSpielId() const
+{
+	return spielId;
+}
+
+// Reference Counting
+SpieleKaufenListeEintrag *SpieleKaufenListeEintrag::getThis()
+{
+	ref++;
+	return this;
+}
+
+SpieleKaufenListeEintrag *SpieleKaufenListeEintrag::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der SpieleKaufenListe Klasse aus SpieleKaufen.h
+// Konstruktor
+SpieleKaufenListe::SpieleKaufenListe( Schrift *schrift )
+{
+	s = schrift;
+	pos = Punkt( 5, 55 );
+	ram = new LRahmen();
+	ram->setSize( 215, 380 );
+	ram->setFarbe( 0xFFFFFFFF );
+	einträge = new RCArray< SpieleKaufenListeEintrag >();
+	vScroll = new VScrollBar();
+	vScroll->setKlickScroll( 10 );
+	vScroll->update( 0, 380 );
+	rend = 0;
+	ref = 1;
+}
+
+// Destruktor
+SpieleKaufenListe::~SpieleKaufenListe()
+{
+	s->release();
+	ram->release();
+	einträge->release();
+	vScroll->release();
+}
+
+// nicht constant
+void SpieleKaufenListe::ladeSpiele( Array< int > *spiele )
+{
+	leeren();
+	int anz = spiele->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+	{
+		if( shopKlient->ladeSpielTitel( spiele->hat( i ) ? spiele->get( i ) : 0 ) )
+			einträge->add( new SpieleKaufenListeEintrag( spiele->hat( i ) ? spiele->get( i ) : 0, s->getThis() ) );
+	}
+	vScroll->update( anz * 100, 380 );
+	rend = 1;
+}
+
+void SpieleKaufenListe::leeren()
+{
+    cs.lock();
+	einträge->leeren();
+    cs.unlock();
+	vScroll->update( 0, 380 );
+	rend = 1;
+}
+
+int SpieleKaufenListe::doMausEreignis( MausEreignis &me )
+{
+	int mx = me.mx;
+	int my = me.my;
+	me.mx -= pos.x;
+	me.my -= pos.y;
+	vScroll->doMausMessage( 200, 0, 15, 380, me );
+	me.my += vScroll->getScroll();
+	int ret = 0;
+    cs.lock();
+	int anz = einträge->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+	{
+		if( einträge->z( i )->doMausEreignis( me ) )
+			ret = einträge->z( i )->getSpielId();
+		me.my += 100;
+	}
+	if( ret )
+	{
+		for( int i = 0; i < anz; i++ )
+		{
+			if( einträge->z( i )->getSpielId() != ret )
+				einträge->z( i )->resetAuswahl();
+		}
+	}
+    cs.unlock();
+	me.mx = mx;
+	me.my = my;
+	return ret;
+}
+
+bool SpieleKaufenListe::tick( double zeit )
+{
+	rend |= vScroll->getRend();
+    cs.lock();
+	int anz = einträge->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+		rend |= einträge->z( i )->tick( zeit );
+    cs.unlock();
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void SpieleKaufenListe::render( Bild &zRObj )
+{
+	int br = ram->getBreite();
+	int hö = ram->getHeight();
+	if( !zRObj.setDrawOptions( pos.x, pos.y, br, hö ) )
+		return;
+	ram->render( zRObj );
+    cs.lock();
+	int anz = einträge->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+		einträge->z( i )->render( i * 100 - vScroll->getScroll(), zRObj );
+    cs.unlock();
+	vScroll->render( 200, 0, 15, 380, zRObj );
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+int SpieleKaufenListe::getEintragAnzahl()
+{
+	return einträge->getEintragAnzahl();
+}
+
+// Reference Counting
+SpieleKaufenListe *SpieleKaufenListe::getThis()
+{
+	ref++;
+	return this;
+}
+
+SpieleKaufenListe *SpieleKaufenListe::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der SpieleKaufen Klasse aus SpieleKaufen.h
+// Konstruktor
+SpieleKaufen::SpieleKaufen( Schrift *zSchrift )
+	: Thread()
+{
+	Bild *shopZurück = bilder->get( "shop.ltdb/zurück.png" );
+	if( !shopZurück )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/shop.ltdb" ) );
+		datei->leseDaten( 0 );
+		shopZurück = datei->laden( 0, new Text( "zurück.png" ) );
+		datei->release();
+		bilder->add( "shop.ltdb/zurück.png", shopZurück->getThis() );
+	}
+	Bild *shopWeiter = bilder->get( "shop.ltdb/weiter.png" );
+	if( !shopWeiter )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/shop.ltdb" ) );
+		datei->leseDaten( 0 );
+		shopWeiter = datei->laden( 0, new Text( "weiter.png" ) );
+		datei->release();
+		bilder->add( "shop.ltdb/weiter.png", shopWeiter->getThis() );
+	}
+	alpha = 255;
+	sichtbar = 0;
+	suchText = new Text( "" );
+	ram = new LRahmen();
+	ram->setSize( 780, 440 );
+	ram->setFarbe( 0xFFFFFFFF );
+	pos = Punkt( 10, 50 );
+	suchFilterT = initTextFeld( 5, 5, 70, 20, zSchrift, TextFeld::Style::Text, "Suchfilter:" );
+	suchFilter = initTextFeld( 80, 5, 225, 20, zSchrift, TextFeld::Style::TextFeld, "" );
+	initToolTip( suchFilter, "Gebe etwas vom Namen des Spieles ein, nach dem du suchst.", zSchrift->getThis(), hauptScreen );
+	suchen = initKnopf( 310, 5, 100, 20, zSchrift, Knopf::Style::Sichtbar, "suchen" );
+	seiten = initTextFeld( 55, 30, 250, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, "Seite 0 von 0, 0 Funde." );
+	zurück = initKnopf( 5, 30, 20, 20, 0, 0, "" );
+	zurück->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	zurück->setHintergrundBildZ( shopZurück );
+	initToolTip( zurück, "Seite zurück blättern.", zSchrift->getThis(), hauptScreen );
+	weiter = initKnopf( 30, 30, 20, 20, 0, 0, "" );
+	weiter->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	weiter->setHintergrundBildZ( shopWeiter );
+	initToolTip( weiter, "Seite weiter blättern.", zSchrift->getThis(), hauptScreen );
+	liste = new SpieleKaufenListe( zSchrift->getThis() );
+	auswahl = new SpieleKaufenAuswahl( zSchrift );
+	laden = ( Framework::Animation2D* )ladeAnimation->dublizieren();
+	laden->setPosition( 365, 195 );
+	laden->setSichtbar( 0 );
+	tickVal = 0;
+	seite = 0;
+	maxSeite = 0;
+	rend = 0;
+	ref = 1;
+}
+
+// Destruktor
+SpieleKaufen::~SpieleKaufen()
+{
+	if( run )
+		warteAufThread( 1000 );
+	if( run )
+		ende();
+	suchText->release();
+	ram->release();
+	suchFilter->release();
+	suchFilterT->release();
+	suchen->release();
+	seiten->release();
+	weiter->release();
+	zurück->release();
+	liste->release();
+	auswahl->release();
+	laden->release();
+}
+
+// nicht constant
+void SpieleKaufen::setSichtbar( bool sicht )
+{
+	sichtbar = sicht;
+	if( sichtbar && !liste->getEintragAnzahl() )
+	{
+		MausEreignis me;
+		me.id = ME_RLinks;
+		me.verarbeitet = 0;
+		me.mx = suchen->getX() + 1 + pos.x;
+		me.my = suchen->getY() + 1 + pos.y;
+		doMausEreignis( me );
+	}
+}
+
+void SpieleKaufen::thread()
+{
+	laden->setSichtbar( 1 );
+	Array< int > *list = shopKlient->suchSpiele( suchText->getText() );
+	if( !list )
+	{
+		laden->setSichtbar( 0 );
+		run = 0;
+		return;
+	}
+	Array< int > *slist = new Array< int >();
+	int anz = list->getEintragAnzahl();
+	maxSeite = anz / 10 + 1;
+	if( !( anz % 10 ) )
+		maxSeite--;
+	while( anz <= seite * 10 && seite > 0 )
+		seite--;
+	for( int i = seite * 10; i < anz && i < seite * 10 + 10; i++ )
+		slist->add( list->hat( i ) ? list->get( i ) : 0 );
+	list->release();
+	auswahl->reset();
+	liste->ladeSpiele( slist );
+	slist->release();
+	Text *t = new Text( "Seite " );
+	t->append( maxSeite ? seite + 1 : 0 );
+	t->append( " von " );
+	t->append( maxSeite );
+	t->append( ", " );
+	t->append( anz );
+	if( anz == 1 )
+		t->append( " Fund." );
+	else
+		t->append( " Funde." );
+	seiten->setText( t );
+	zurück->setStyle( TextFeld::Style::Erlaubt, seite > 0 );
+	weiter->setStyle( TextFeld::Style::Erlaubt, seite + 1 < maxSeite );
+	laden->setSichtbar( 0 );
+	run = 0;
+}
+
+void SpieleKaufen::doMausEreignis( MausEreignis &me )
+{
+	if( !sichtbar || run )
+		return;
+	int mx = me.mx;
+	int my = me.my;
+	me.mx -= pos.x;
+	me.my -= pos.y;
+	suchFilter->doMausEreignis( me );
+	int auswId = liste->doMausEreignis( me );
+	if( auswId )
+		auswahl->ladeSpielSeite( auswId );
+	auswahl->doMausEreignis( me );
+	int ak = 0;
+	bool tmp = me.verarbeitet;
+	suchen->doMausEreignis( me );
+	ak = me.verarbeitet ? 1 : 0;
+	zurück->doMausEreignis( me );
+	ak = me.verarbeitet && !ak ? 2 : ak;
+	weiter->doMausEreignis( me );
+	ak = me.verarbeitet && !ak ? 3 : ak;
+	if( tmp )
+		ak = 0;
+	if( me.id == ME_RLinks )
+	{
+		switch( ak )
+		{
+		case 1: // Suchen
+			suchText->setText( suchFilter->zText()->getText() );
+			seite = 1;
+			maxSeite = 1;
+			start();
+			break;
+		case 2: // Seite zurück blättern
+			seite--;
+			if( seite < 1 )
+				seite = 1;
+			start();
+			break;
+		case 3: // Seite vorwärts blättern
+			seite++;
+			if( seite > maxSeite )
+				seite = maxSeite;
+			start();
+			break;
+		}
+	}
+	me.mx = mx;
+	me.my = my;
+}
+
+void SpieleKaufen::doTastaturEreignis( TastaturEreignis &te )
+{
+	if( !sichtbar || run )
+		return;
+	bool vera = te.verarbeitet;
+	suchFilter->doTastaturEreignis( te );
+	if( !vera && te.verarbeitet && te.taste == T_Enter && te.id == TE_Release )
+	{
+		MausEreignis me;
+		me.id = ME_RLinks;
+		me.verarbeitet = 0;
+		me.mx = suchen->getX() + 1 + pos.x;
+		me.my = suchen->getY() + 1 + pos.y;
+		doMausEreignis( me );
+	}
+	auswahl->doTastaturEreignis( te );
+}
+
+bool SpieleKaufen::tick( double zeit )
+{
+	rend |= suchFilter->tick( zeit );
+	rend |= suchFilterT->tick( zeit );
+	rend |= suchen->tick( zeit );
+	rend |= weiter->tick( zeit );
+	rend |= zurück->tick( zeit );
+	rend |= liste->tick( zeit );
+	rend |= auswahl->tick( zeit );
+	rend |= laden->tick( zeit );
+	tickVal += zeit * 250;
+	int val = (int)tickVal;
+	if( val < 1 )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	if( val > 10 )
+		val = 10;
+	tickVal -= val;
+	if( sichtbar && alpha != 255 && !run )
+	{
+		if( alpha + val > 255 )
+			alpha = 255;
+		else
+			alpha += val;
+		rend = 1;
+	}
+	if( sichtbar && alpha != 125 && run )
+	{
+		if( alpha > 125 )
+		{
+			if( alpha - val < 125 )
+				alpha = 125;
+			else
+				alpha -= val;
+			rend = 1;
+		}
+		else
+		{
+			if( alpha + val > 125 )
+				alpha = 125;
+			else
+				alpha += 125;
+			rend = 1;
+		}
+	}
+	if( !sichtbar && alpha != 0 )
+	{
+		if( alpha - val < 0 )
+			alpha = 0;
+		else
+			alpha -= val;
+		rend = 1;
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void SpieleKaufen::render( Bild &zRObj )
+{
+	if( !alpha )
+		return;
+	int br = ram->getBreite();
+	int hö = ram->getHeight();
+	if( !zRObj.setDrawOptions( pos.x, pos.y, br, hö ) )
+		return;
+	zRObj.setAlpha( alpha );
+	ram->render( zRObj );
+	suchFilterT->render( zRObj );
+	suchFilter->render( zRObj );
+	suchen->render( zRObj );
+	seiten->render( zRObj );
+	weiter->render( zRObj );
+	zurück->render( zRObj );
+	liste->render( zRObj );
+	auswahl->render( zRObj );
+	zRObj.releaseAlpha();
+	laden->render( zRObj );
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+bool SpieleKaufen::istSichtbar() const
+{
+	return sichtbar;
+}
+
+// Reference Counting
+SpieleKaufen *SpieleKaufen::getThis()
+{
+	ref++;
+	return this;
+}
+
+SpieleKaufen *SpieleKaufen::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 150 - 0
KSGClient/NachLogin/Shop/Spiele/SpieleKaufen.h

@@ -0,0 +1,150 @@
+#ifndef SpieleKaufen_H
+#define SpieleKaufen_H
+
+#include <Schrift.h>
+#include <Knopf.h>
+#include <KSGScript.h>
+#include <Array.h>
+#include <Scroll.h>
+#include <Animation.h>
+#include <Thread.h>
+
+using namespace Framework;
+using namespace KSGScript;
+
+class SpieleKaufenAuswahl : private Thread
+{
+private:
+	int spielId;
+	unsigned char alpha;
+	KSGScriptObj *fenster;
+	Framework::Animation2D *laden;
+	Punkt pos;
+	LRahmen *ram;
+	HINSTANCE ksgs;
+	bool aktion;
+	int ref;
+
+public:
+	// Konstruktor
+	SpieleKaufenAuswahl( Schrift *zSchrift );
+	// Destruktor
+	~SpieleKaufenAuswahl();
+	// nicht constant
+	void ladeSpielSeite( int id );
+	void reset();
+	virtual void thread();
+	void ksgsAktion( RCArray< KSGSVariable > *parameter, KSGSVariable **ret );
+	void doMausEreignis( MausEreignis &me );
+	void doTastaturEreignis( TastaturEreignis &te );
+	bool tick( double zeit );
+	void render( Bild &zRObj );
+	// constant
+
+	// Reference Counting
+	SpieleKaufenAuswahl *getThis();
+	SpieleKaufenAuswahl *release();
+};
+
+class SpieleKaufenListeEintrag
+{
+private:
+	int spielId;
+	Knopf *auswählen;
+	Bild *hintergrund;
+	AlphaFeld *ausgewählt;
+	LRahmen *ram;
+	bool ausw;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	SpieleKaufenListeEintrag( int id, Schrift *schrift );
+	// Destruktor
+	~SpieleKaufenListeEintrag();
+	// nicht constant
+	void resetAuswahl();
+	bool doMausEreignis( MausEreignis &me );
+	bool tick( double zeit );
+	void render( int yOff, Bild &zRObj );
+	// constant
+	int getSpielId() const;
+	// Reference Counting
+	SpieleKaufenListeEintrag *getThis();
+	SpieleKaufenListeEintrag *release();
+};
+
+class SpieleKaufenListe
+{
+private:
+	Schrift *s;
+	LRahmen *ram;
+	Punkt pos;
+	RCArray< SpieleKaufenListeEintrag > *einträge;
+	VScrollBar *vScroll;
+	bool rend;
+	int ref;
+	Critical cs;
+
+public:
+	// Konstruktor
+	SpieleKaufenListe( Schrift *schrift );
+	// Destruktor
+	~SpieleKaufenListe();
+	// nicht constant
+	void ladeSpiele( Array< int > *spiele );
+	void leeren();
+	int doMausEreignis( MausEreignis &me );
+	bool tick( double zeit );
+	void render( Bild &zRObj );
+	// constant
+	int getEintragAnzahl();
+	// Reference Counting
+	SpieleKaufenListe *getThis();
+	SpieleKaufenListe *release();
+};
+
+class SpieleKaufen : private Thread
+{
+private:
+	unsigned char alpha;
+	bool sichtbar;
+	Text *suchText;
+	LRahmen *ram;
+	TextFeld *suchFilter;
+	TextFeld *suchFilterT;
+	Knopf *suchen;
+	TextFeld *seiten;
+	Knopf *weiter;
+	Knopf *zurück;
+	Punkt pos;
+	SpieleKaufenListe *liste;
+	SpieleKaufenAuswahl *auswahl;
+	Animation2D *laden;
+	double tickVal;
+	int seite;
+	int maxSeite;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	SpieleKaufen( Schrift *zSchrift );
+	// Destruktor
+	~SpieleKaufen();
+	// nicht constant
+	void setSichtbar( bool sicht );
+	virtual void thread();
+	void doMausEreignis( MausEreignis &me );
+	void doTastaturEreignis( TastaturEreignis &te );
+	bool tick( double zeit );
+	void render( Bild &zRObj );
+	// constant
+	bool istSichtbar() const;
+	// Reference Counting
+	SpieleKaufen *getThis();
+	SpieleKaufen *release();
+};
+
+#endif

+ 397 - 0
KSGClient/NachLogin/Spiele/Angemeldet/Angemeldet.cpp

@@ -0,0 +1,397 @@
+#include "Angemeldet.h"
+#include <Punkt.h>
+#include <Rahmen.h>
+#include "..\..\..\Global\Initialisierung.h"
+#include "..\..\..\Global\Variablen.h"
+
+// Inhalt der AngemeldetFenster Klasse aus Angemeldet.h
+// Konstruktor
+AngemeldetFenster::AngemeldetFenster( Schrift *zSchrift )
+{
+    pos = Punkt( 10, 10 );
+    gr = Punkt( 780, 480 );
+    rahmen = new LRahmen();
+    rahmen->setRamenBreite( 1 );
+    rahmen->setFarbe( 0xFFFFFFFF );
+    rahmen->setSize( 780, 480 );
+    spielName = initTextFeld( 290, 165, 200, 20, zSchrift, TextFeld::Style::Text, "" );
+    karteName = initTextFeld( 290, 190, 200, 20, zSchrift, TextFeld::Style::Text, "" );
+    zeit = initTextFeld( 290, 215, 200, 20, zSchrift, TextFeld::Style::Text, "Zeit in Warteschlange: " );
+    abbrechen = initKnopf( 340, 240, 100, 20, zSchrift, Knopf::Style::Normal, "abbrechen" );
+    spielGefunden = initTextFeld( 340, 140, 100, 20, zSchrift, TextFeld::Style::Text & ~TextFeld::Style::Sichtbar, "Spiel gefunden" );
+    warten = initTextFeld( 290, 240, 200, 20, zSchrift, TextFeld::Style::Text & ~TextFeld::Style::Sichtbar, "Warte auf andere Spieler" );
+    beitreten = initKnopf( 340, 240, 100, 20, zSchrift, Knopf::Style::Normal & ~Knopf::Style::Sichtbar, "beitreten" );
+    kick = initTextFeld( 190, 215, 400, 20, zSchrift, TextFeld::Style::Text & ~Knopf::Style::Sichtbar, "Du wurdest wegen Abwesenheit aus der Warteschlange entfernt." );
+    ok = initKnopf( 340, 240, 100, 20, zSchrift, Knopf::Style::Normal & ~Knopf::Style::Sichtbar, "Zurück" );
+    karteId = 0;
+    gameId = 0;
+    animation = 0;
+    alpha = 0;
+    aAlpha = 0;
+    tickVal = 0;
+    time = 0;
+    status = 0;
+    rend = 0;
+    ref = 1;
+}
+
+// Destruktor
+AngemeldetFenster::~AngemeldetFenster()
+{
+    if( karteId && anmeldungKlient )
+        anmeldungKlient->abmelden();
+    rahmen->release();
+    spielName->release();
+    karteName->release();
+    zeit->release();
+    abbrechen->release();
+    spielGefunden->release();
+    warten->release();
+    beitreten->release();
+    kick->release();
+    ok->release();
+}
+
+// nicht constant
+bool AngemeldetFenster::setKarteId( int karteId )
+{
+    if( !anmeldungKlient )
+        return 0;
+    if( !karteId )
+    {
+        if( anmeldungKlient->abmelden() )
+        {
+            this->karteId = 0;
+            return 1;
+        }
+        else
+            return 0;
+    }
+    if( !anmeldungKlient->anmelden( karteId ) )
+    {
+        if( nachLogin && nachLogin->zNachrichtenListe() )
+        {
+            if( anmeldungKlient->getLetzterFehler() )
+            {
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                              new Text( anmeldungKlient->getLetzterFehler() ),
+                                                              new Text( "Ok" ),
+                                                              0,
+                                                              NachrichtType::nachricht,
+                                                              0
+                                                              );
+            }
+            else
+            {
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                              new Text( "Fehler beim anmelden." ),
+                                                              new Text( "Ok" ),
+                                                              0,
+                                                              NachrichtType::nachricht,
+                                                              0
+                                                              );
+            }
+        }
+        return 0;
+    }
+    else
+    {
+        time = 0;
+        this->karteId = karteId;
+        if( infoKlient )
+        {
+            Text *sN = infoKlient->getSpielName( infoKlient->getSpielId( karteId ) );
+            Text *kN = infoKlient->getKarteName( karteId );
+            if( sN )
+            {
+                spielName->setText( "Spiel: " );
+                spielName->zText()->append( sN );
+            }
+            if( kN )
+            {
+                karteName->setText( "Karte: " );
+                karteName->zText()->append( kN );
+            }
+        }
+        rend = 1;
+        return 1;
+    }
+}
+
+void AngemeldetFenster::setSichtbar( bool sichtbar )
+{
+    if( sichtbar )
+    {
+        status = 1;
+        spielName->addStyle( TextFeld::Style::Sichtbar );
+        karteName->addStyle( TextFeld::Style::Sichtbar );
+        zeit->addStyle( TextFeld::Style::Sichtbar );
+        abbrechen->addStyle( Knopf::Style::Sichtbar );
+        spielGefunden->removeStyle( TextFeld::Style::Sichtbar );
+        warten->removeStyle( TextFeld::Style::Sichtbar );
+        beitreten->removeStyle( Knopf::Style::Sichtbar );
+        kick->removeStyle( TextFeld::Style::Sichtbar );
+        ok->removeStyle( Knopf::Style::Sichtbar );
+        animation |= 0x1 | 0x4;
+    }
+    else
+    {
+        animation &= ~( 0x1 | 0x4 | 0x8 );
+        status = 0;
+    }
+    rend = 1;
+}
+
+void AngemeldetFenster::setSpielGefunden()
+{
+    status = 2;
+    spielName->addStyle( TextFeld::Style::Sichtbar );
+    karteName->addStyle( TextFeld::Style::Sichtbar );
+    zeit->addStyle( TextFeld::Style::Sichtbar );
+    abbrechen->removeStyle( Knopf::Style::Sichtbar );
+    spielGefunden->addStyle( TextFeld::Style::Sichtbar );
+    warten->removeStyle( TextFeld::Style::Sichtbar );
+    beitreten->addStyle( Knopf::Style::Sichtbar );
+    kick->removeStyle( TextFeld::Style::Sichtbar );
+    ok->removeStyle( Knopf::Style::Sichtbar );
+    rend = 1;
+}
+
+void AngemeldetFenster::setVerbleibendeZeit( int sekunden )
+{
+    if( time != sekunden )
+    {
+        time = sekunden;
+        rend = 1;
+    }
+}
+
+void AngemeldetFenster::spielGefundenAbbruch()
+{
+    status = 4;
+    spielName->removeStyle( TextFeld::Style::Sichtbar );
+    karteName->removeStyle( TextFeld::Style::Sichtbar );
+    zeit->removeStyle( TextFeld::Style::Sichtbar );
+    abbrechen->removeStyle( Knopf::Style::Sichtbar );
+    spielGefunden->removeStyle( TextFeld::Style::Sichtbar );
+    warten->removeStyle( TextFeld::Style::Sichtbar );
+    beitreten->removeStyle( Knopf::Style::Sichtbar );
+    kick->addStyle( TextFeld::Style::Sichtbar );
+    ok->addStyle( Knopf::Style::Sichtbar );
+    rend = 1;
+}
+
+void AngemeldetFenster::zurückInWarteschlange( int stunden, int minuten, int sekunden )
+{
+    time = sekunden + minuten * 60 + stunden * 60 * 60;
+    status = 1;
+    spielName->addStyle( TextFeld::Style::Sichtbar );
+    karteName->addStyle( TextFeld::Style::Sichtbar );
+    zeit->addStyle( TextFeld::Style::Sichtbar );
+    abbrechen->addStyle( Knopf::Style::Sichtbar );
+    spielGefunden->removeStyle( TextFeld::Style::Sichtbar );
+    warten->removeStyle( TextFeld::Style::Sichtbar );
+    beitreten->removeStyle( Knopf::Style::Sichtbar );
+    kick->removeStyle( TextFeld::Style::Sichtbar );
+    ok->removeStyle( Knopf::Style::Sichtbar );
+    rend = 1;
+}
+
+bool AngemeldetFenster::tick( double tickVal )
+{
+    rend |= spielName->tick( tickVal );
+    rend |= karteName->tick( tickVal );
+    rend |= zeit->tick( tickVal );
+    rend |= abbrechen->tick( tickVal );
+    rend |= spielGefunden->tick( tickVal );
+    rend |= warten->tick( tickVal );
+    rend |= beitreten->tick( tickVal );
+    rend |= kick->tick( tickVal );
+    rend |= ok->tick( tickVal );
+    if( status == 2 || status == 3 )
+    {
+        Text txt = "Verbleibende Zeit: ";
+        txt += (int)( time / 60 / 60 );
+        txt += ":";
+        txt += ( (int)( time / 60 ) % 60 );
+        txt += ":";
+        txt += (int)time % 60;
+        if( !zeit->zText()->istGleich( txt ) )
+            zeit->setText( txt );
+    }
+    if( status == 1 )
+        time += tickVal;
+    this->tickVal += tickVal * 750;
+    int val = ( int )this->tickVal;
+    if( val < 1 )
+    {
+        bool ret = rend;
+        rend = 0;
+        return ret;
+    }
+    if( val > 25 )
+        val = 25;
+    this->tickVal -= val;
+    if( val )
+    {
+        if( ( animation | 0x4 ) == animation )
+        {
+            if( status == 1 )
+            {
+                if( !alpha )
+                    time = 0;
+                Text txt = "Zeit in Warteschlange: ";
+                txt += (int)( time / 60 / 60 );
+                txt += ":";
+                txt += ( (int)( time / 60 ) % 60 );
+                txt += ":";
+                txt += (int)time % 60;
+                if( !zeit->zText()->istGleich( txt ) )
+                    zeit->setText( txt );
+            }
+            if( alpha + ( val / 3 ) > 255 )
+                alpha = 255;
+            else
+            {
+                alpha += ( val / 3 );
+                rend = 1;
+            }
+        }
+        else
+        {
+            if( alpha - ( val / 2 ) < 0 )
+                alpha = 0;
+            else
+            {
+                alpha -= ( val / 2 );
+                rend = 1;
+            }
+        }
+        if( ( animation | 0x1 ) == animation ) // sichtbar
+        {
+            if( aAlpha != 255 )
+            {
+                if( aAlpha + val > 255 )
+                    aAlpha = 255;
+                else
+                    aAlpha += val;
+                rend = 1;
+            }
+        }
+        else // unsichtbar
+        {
+            if( aAlpha != 0 )
+            {
+                if( aAlpha - val < 0 )
+                    aAlpha = 0;
+                else
+                    aAlpha -= val;
+                rend = 1;
+            }
+        }
+    }
+    bool ret = rend;
+    rend = 0;
+    return ret;
+}
+
+void AngemeldetFenster::doMausEreignis( MausEreignis &me )
+{
+    me.mx -= pos.x;
+    me.my -= pos.y;
+    bool ak = !me.verarbeitet;
+    abbrechen->doMausEreignis( me );
+    int aktion = ( abbrechen->hatStyle( Knopf::Style::Sichtbar ) && ak && me.verarbeitet ) ? 1 : 0;
+    beitreten->doMausEreignis( me );
+    aktion = ( beitreten->hatStyle( Knopf::Style::Sichtbar ) && ak && me.verarbeitet && !aktion ) ? 2 : aktion;
+    ok->doMausEreignis( me );
+    aktion = ( ok->hatStyle( Knopf::Style::Sichtbar ) && ak && me.verarbeitet && !aktion ) ? 3 : aktion;
+    if( me.id == ME_RLinks )
+    {
+        switch( aktion )
+        {
+        case 1: // abbrechen
+            if( anmeldungKlient && anmeldungKlient->abmelden() )
+                if( nachLogin && nachLogin->zSpielenFenster() )
+                    nachLogin->zSpielenFenster()->anmeldungAbbrechen();
+            break;
+        case 2: // beitreten
+            if( spielKlient->spielErstelltAnnehmen() )
+            {
+                status = 3;
+                spielName->addStyle( TextFeld::Style::Sichtbar );
+                karteName->addStyle( TextFeld::Style::Sichtbar );
+                zeit->addStyle( TextFeld::Style::Sichtbar );
+                abbrechen->removeStyle( Knopf::Style::Sichtbar );
+                spielGefunden->addStyle( TextFeld::Style::Sichtbar );
+                warten->addStyle( TextFeld::Style::Sichtbar );
+                beitreten->removeStyle( Knopf::Style::Sichtbar );
+                kick->removeStyle( TextFeld::Style::Sichtbar );
+                ok->removeStyle( Knopf::Style::Sichtbar );
+                rend = 1;
+            }
+            else if( nachLogin && nachLogin->zSpielenFenster() )
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( spielKlient->getLetzterFehler() ), new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+            break;
+        case 3: // Zurück
+            if( nachLogin && nachLogin->zSpielenFenster() )
+                nachLogin->zSpielenFenster()->anmeldungAbbrechen();
+            break;
+        }
+    }
+    me.mx += pos.x;
+    me.my += pos.y;
+}
+
+void AngemeldetFenster::render( Bild &zrObj )
+{
+    int x = pos.x;
+    int y = pos.y;
+    int br = gr.x;
+    int hö = gr.y;
+    if( !zrObj.setDrawOptions( x, y, br, br ) )
+        return;
+    zrObj.setAlpha( aAlpha );
+    rahmen->render( zrObj );
+    zrObj.setAlpha( alpha );
+    spielName->render( zrObj );
+    karteName->render( zrObj );
+    zeit->render( zrObj );
+    abbrechen->render( zrObj );
+    spielGefunden->render( zrObj );
+    warten->render( zrObj );
+    beitreten->render( zrObj );
+    kick->render( zrObj );
+    ok->render( zrObj );
+    zrObj.releaseAlpha();
+    zrObj.releaseDrawOptions();
+    zrObj.releaseAlpha();
+}
+
+int AngemeldetFenster::getAktion()
+{
+    int ret = aktion;
+    aktion = 0;
+    return ret;
+}
+
+// constant
+int AngemeldetFenster::getKarteId() const
+{
+    return karteId;
+}
+
+// Reference Countong
+AngemeldetFenster *AngemeldetFenster::getThis()
+{
+    ref++;
+    return this;
+}
+
+AngemeldetFenster *AngemeldetFenster::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 60 - 0
KSGClient/NachLogin/Spiele/Angemeldet/Angemeldet.h

@@ -0,0 +1,60 @@
+#ifndef Angemeldet_H
+#define Angemeldet_H
+
+#include <Klient.h>
+#include <Bild.h>
+#include <Knopf.h>
+
+using namespace Framework;
+
+class AngemeldetFenster
+{
+private:
+	Punkt pos;
+	Punkt gr;
+	LRahmen *rahmen;
+	TextFeld *spielName;
+	TextFeld *karteName;
+	TextFeld *zeit;
+	Knopf *abbrechen;
+	TextFeld *spielGefunden;
+	TextFeld *warten;
+	Knopf *beitreten;
+	TextFeld *kick;
+	Knopf *ok;
+	int karteId;
+	int gameId;
+	int animation;
+    unsigned char aAlpha;
+	unsigned char alpha;
+	double tickVal;
+	double time;
+	int status;
+	int aktion;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	AngemeldetFenster( Schrift *zSchrift );
+	// Destruktor
+	~AngemeldetFenster();
+	// nicht constant
+	bool setKarteId( int karteId );
+	void setSichtbar( bool sichtbar );
+	void setSpielGefunden();
+	void setVerbleibendeZeit( int sekunden );
+	void spielGefundenAbbruch();
+	void zurückInWarteschlange( int stunden, int minuten, int sekunden );
+	bool tick( double tickVal );
+	void doMausEreignis( MausEreignis &me );
+	void render( Bild &zrObj );
+	int getAktion();
+	// constant
+	int getKarteId() const;
+	// Reference Countong
+	AngemeldetFenster *getThis();
+	AngemeldetFenster *release();
+};
+
+#endif

+ 2461 - 0
KSGClient/NachLogin/Spiele/Gruppe/Gruppe.cpp

@@ -0,0 +1,2461 @@
+#include "Gruppe.h"
+#include <Punkt.h>
+#include <Rahmen.h>
+#include "..\..\..\Global\Variablen.h"
+#include "..\..\..\Global\Initialisierung.h"
+#include "..\..\..\Leser\KartenLeser.h"
+#include <DateiSystem.h>
+#include <AlphaFeld.h>
+#include <ToolTip.h>
+
+// Inhalt der GruppeEinladungAccount Klasse aus Gruppe.h
+// Konstruktor
+GruppeEinladungAccount::GruppeEinladungAccount( Schrift *zSchrift )
+{
+	Bild *nachrichtBild = bilder->get( "chat.ltdb/nachricht.png" );
+	if( !nachrichtBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		nachrichtBild = datei->laden( 0, new Text( "nachricht.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/nachricht.png", nachrichtBild->getThis() );
+	}
+	Bild *neuSendenBild = bilder->get( "chat.ltdb/neusenden.png" );
+	if( !neuSendenBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		neuSendenBild = datei->laden( 0, new Text( "neusenden.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/neusenden.png", neuSendenBild->getThis() );
+	}
+	Bild *entfernenBild = bilder->get( "chat.ltdb/entfernen.png" );
+	if( !entfernenBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		entfernenBild = datei->laden( 0, new Text( "entfernen.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/entfernen.png", entfernenBild->getThis() );
+	}
+	rahmen = new LRahmen();
+	rahmen->setFarbe( 0xFFFFFFFF );
+	rahmen->setRamenBreite( 1 );
+	auswahl = new AlphaFeld();
+	auswahl->setFarbe( 0x0000FF00 );
+	auswahl->setStrength( -2 );
+	auswahl->setPosition( 1, 1 );
+	name = initTextFeld( 0, 5, 100, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "" );
+	nachrichtSenden = initKnopf( 0, 30, 20, 20, 0, 0, "" );
+	nachrichtSenden->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	nachrichtSenden->setHintergrundBildZ( nachrichtBild );
+	initToolTip( nachrichtSenden, "Nachricht senden.", zSchrift->getThis(), hauptScreen );
+	erneutSenden = initKnopf( 0, 30, 20, 20, 0, 0, "" );
+	erneutSenden->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	erneutSenden->setHintergrundBildZ( neuSendenBild );
+	initToolTip( erneutSenden, "Einladung erneut senden.", zSchrift->getThis(), hauptScreen );
+	einladungAbbrechen = initKnopf( 0, 30, 20, 20, 0, 0, "" );
+	einladungAbbrechen->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	einladungAbbrechen->setHintergrundBildZ( entfernenBild );
+	initToolTip( einladungAbbrechen, "Einladung abbrechen.", zSchrift->getThis(), hauptScreen );
+	status = 0;
+	knopfX = 500;
+	tickVal = 0;
+	mausIn = 0;
+	remove = 0;
+	gruppeId = 0;
+	accountId = 0;
+	admin = 0;
+	höhe = 0;
+	animation = 0x1;
+	rend = 0;
+	ref = 1;
+}
+
+// Destruktor
+GruppeEinladungAccount::~GruppeEinladungAccount()
+{
+	rahmen->release();
+	auswahl->release();
+	name->release();
+	nachrichtSenden->release();
+	erneutSenden->release();
+	einladungAbbrechen->release();
+}
+
+// nicht constant
+void GruppeEinladungAccount::setGruppeId( int gruppeId )
+{
+	this->gruppeId = gruppeId;
+}
+
+void GruppeEinladungAccount::setAccountId( int id )
+{
+	this->accountId = id;
+	name->setText( infoKlient->getSpielerName( id ) );
+	rend = 1;
+}
+
+void GruppeEinladungAccount::setSize( int br )
+{
+	if( this->br != br )
+		rend = 1;
+	this->br = br;
+	if( knopfX == 500 )
+	{
+		knopfX = br;
+		rend = 1;
+	}
+}
+
+void GruppeEinladungAccount::setAbgelehnt()
+{
+	status = 1;
+}
+
+void GruppeEinladungAccount::setAngenommen()
+{
+	status = 2;
+}
+
+void GruppeEinladungAccount::setRemove()
+{
+	animation &= ~0x1;
+}
+
+void GruppeEinladungAccount::setAdmin( int admin )
+{
+	this->admin = admin;
+}
+
+bool GruppeEinladungAccount::tick( double tickVal )
+{
+	rend |= name->tick( tickVal );
+	rend |= nachrichtSenden->tick( tickVal );
+	rend |= erneutSenden->tick( tickVal );
+	rend |= einladungAbbrechen->tick( tickVal );
+	this->tickVal += tickVal * 100;
+	int val = ( int )this->tickVal;
+	if( val < 1 )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	if( val > 4 )
+		val = 4;
+	this->tickVal -= val;
+	if( ( animation | 0x1 ) == animation )
+	{
+		if( höhe < 30 )
+		{
+			höhe += val;
+			if( höhe > 30 )
+				höhe = 30;
+			rend = 1;
+		}
+	}
+	else
+	{
+		if( höhe > 0 )
+		{
+			höhe -= val;
+			if( höhe < 0 )
+				höhe = 0;
+			rend = 1;
+		}
+	}
+	if( mausIn )
+	{
+		if( admin == loginKlient->getAccountId() && !status )
+		{
+			if( knopfX > br - 60 )
+			{
+				knopfX -= val;
+				if( knopfX < br - 60 )
+					knopfX = br - 60;
+				rend = 1;
+			}
+		}
+		else if( admin == loginKlient->getAccountId() && status != 2 )
+		{
+			if( knopfX > br - 40 )
+			{
+				knopfX -= val;
+				if( knopfX < br - 40 )
+					knopfX = br - 40;
+				rend = 1;
+			}
+		}
+		else
+		{
+			if( knopfX > br - 20 )
+			{
+				knopfX -= val;
+				if( knopfX < br - 20 )
+					knopfX = br - 20;
+				rend = 1;
+			}
+		}
+	}
+	else
+	{
+		if( knopfX < br )
+		{
+			knopfX += val;
+			if( knopfX > br )
+				knopfX = br;
+			rend = 1;
+		}
+	}
+	switch( status )
+	{
+	case 1:
+		if( 1 )
+		{
+			int r = ( rahmen->getFarbe() >> 16 ) & 0xFF;
+			int g = ( rahmen->getFarbe() >> 8 ) & 0xFF;
+			int b = rahmen->getFarbe() & 0xFF;
+			if( r < 255 )
+			{
+				r += val;
+				if( r > 255 )
+					r = 255;
+				rend = 1;
+			}
+			if( g > 0 )
+			{
+				g -= val;
+				if( g < 0 )
+					g = 0;
+				rend = 1;
+			}
+			if( b > 0 )
+			{
+				b -= val;
+				if( b < 0 )
+					b = 0;
+				rend = 1;
+			}
+			int f = ( ( r << 16 ) & 0xFF0000 ) | ( ( g << 8 ) & 0xFF00 ) | ( b & 0xFF );
+			rahmen->setFarbe( ( rahmen->getFarbe() & 0xFF000000 ) | f );
+			auswahl->setFarbe( ( auswahl->getFarbe() & 0xFF000000 ) | f );
+		}
+		break;
+	case 2:
+		if( 1 )
+		{
+			int r = ( rahmen->getFarbe() >> 16 ) & 0xFF;
+			int g = ( rahmen->getFarbe() >> 8 ) & 0xFF;
+			int b = rahmen->getFarbe() & 0xFF;
+			if( r > 0 )
+			{
+				r -= val;
+				if( r < 0 )
+					r = 0;
+				rend = 1;
+			}
+			if( g < 255 )
+			{
+				g += val;
+				if( g > 255 )
+					g = 255;
+				rend = 1;
+			}
+			if( b > 0 )
+			{
+				b -= val;
+				if( b < 0 )
+					b = 0;
+				rend = 1;
+			}
+			int f = ( ( r << 16 ) & 0xFF0000 ) | ( ( g << 8 ) & 0xFF00 ) | ( b & 0xFF );
+			rahmen->setFarbe( ( rahmen->getFarbe() & 0xFF000000 ) | f );
+			auswahl->setFarbe( ( auswahl->getFarbe() & 0xFF000000 ) | f );
+		}
+		break;
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void GruppeEinladungAccount::doMausEreignis( MausEreignis &me )
+{
+	if( me.mx < 0 || me.my < 0 || me.mx > br || me.my > höhe )
+		mausIn = 0;
+	else
+		mausIn = 1;
+	bool ak = !me.verarbeitet;
+	nachrichtSenden->doMausEreignis( me );
+	int aktion = ( me.verarbeitet && ak ) ? 1 : 0;
+	erneutSenden->doMausEreignis( me );
+	aktion = ( me.verarbeitet && ak && !aktion ) ? 2 : aktion;
+	einladungAbbrechen->doMausEreignis( me );
+	aktion = ( me.verarbeitet && ak && !status && !aktion ) ? 3 : aktion;
+	if( me.id != ME_RLinks || !mausIn )
+		return;
+	switch( aktion )
+	{
+	case 1:
+		nachLogin->zChatLeiste()->addChat( accountId, 0 );
+		break;
+	case 2:
+		if( !anmeldungKlient->gruppeSpielerEinladen( accountId, gruppeId ) )
+		{
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( anmeldungKlient->getLetzterFehler() ),
+														  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+		}
+		break;
+	case 3:
+		if( !anmeldungKlient->gruppeEinladungAbbrechen( accountId, gruppeId ) )
+		{
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( anmeldungKlient->getLetzterFehler() ),
+														  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+		}
+		break;
+	}
+}
+
+void GruppeEinladungAccount::render( int y, Bild &zrObj )
+{
+	if( !zrObj.setDrawOptions( 0, y, br, höhe ) )
+		return;
+	rahmen->setSize( br, höhe );
+	rahmen->render( zrObj );
+	int rbr = rahmen->getRBreite();
+	if( !zrObj.setDrawOptions( rbr, rbr, br - rbr * 2, höhe - rbr * 2 ) )
+	{
+		zrObj.releaseDrawOptions();
+		return;
+	}
+	auswahl->setSize( br - rbr * 2, höhe - rbr * 2 );
+	auswahl->render( zrObj );
+	nachrichtSenden->setPosition( knopfX, 5 );
+	nachrichtSenden->render( zrObj );
+	erneutSenden->setPosition( knopfX + 20, 5 );
+	erneutSenden->render( zrObj );
+	einladungAbbrechen->setPosition( knopfX + 40, 5 );
+	einladungAbbrechen->render( zrObj );
+	name->render( zrObj );
+	zrObj.releaseDrawOptions();
+	zrObj.releaseDrawOptions();
+}
+
+// constant
+bool GruppeEinladungAccount::getRemove() const
+{
+	return remove;
+}
+
+int GruppeEinladungAccount::getAccountId() const
+{
+	return accountId;
+}
+
+int GruppeEinladungAccount::getHeight() const
+{
+	return höhe;
+}
+
+// Reference Counting
+GruppeEinladungAccount *GruppeEinladungAccount::getThis()
+{
+	ref++;
+	return this;
+}
+
+GruppeEinladungAccount *GruppeEinladungAccount::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Inhalt der GruppeEinladungListe Klasse aus Gruppe.h
+// Konstruktor
+GruppeEinladungListe::GruppeEinladungListe( Schrift *zSchrift )
+{
+	schrift = zSchrift->getThis();
+	Bild *maximierenBild = bilder->get( "chat.ltdb/maximieren.png" );
+	if( !maximierenBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		maximierenBild = datei->laden( 0, new Text( "maximieren.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/maximieren.png", maximierenBild->getThis() );
+	}
+	pos = Punkt( 200, 0 );
+	gr = Punkt( 150, 350 );
+	rahmen = new LRahmen();
+	rahmen->setRamenBreite( 1 );
+	rahmen->setFarbe( 0xFFFFFFFF );
+	rahmen->setSize( 150, 350 );
+	einladenName = initTextFeld( 5, 5, 115, 20, zSchrift, TextFeld::Style::TextFeld, "" );
+	initToolTip( einladenName, "Name des Spielers den du einladen möchtest.", zSchrift->getThis(), hauptScreen );
+	einladen = initKnopf( 125, 5, 20, 20, 0, 0, "" );
+	einladen->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	einladen->setHintergrundBildZ( maximierenBild );
+	initToolTip( einladen, "Diesen Spieler einladen.", zSchrift->getThis(), hauptScreen );
+	scroll = new VScrollBar();
+	accounts = new RCArray< GruppeEinladungAccount >();
+	einladungHöhe = 0;
+	tickVal = 0;
+	anzahl = 0;
+	gruppeId = 0;
+	admin = 0;
+	rend = 0;
+	ref = 1;
+}
+
+// Destruktor
+GruppeEinladungListe::~GruppeEinladungListe()
+{
+	rahmen->release();
+	einladenName->release();
+	einladen->release();
+	scroll->release();
+	accounts->release();
+	schrift->release();
+}
+
+// nicht constant
+void GruppeEinladungListe::reset()
+{
+	einladenName->setText( "" );
+	scroll->update( 0, 0 );
+	einladungHöhe = 0;
+	tickVal = 0;
+	accounts->leeren();
+	anzahl = 0;
+	gruppeId = 0;
+	admin = 0;
+	rend = 1;
+}
+
+void GruppeEinladungListe::setGruppeId( int gruppeId )
+{
+	this->gruppeId = gruppeId;
+	for( int i = 0; i < anzahl; i++ )
+		accounts->z( i )->setGruppeId( gruppeId );
+}
+
+void GruppeEinladungListe::addAccount( int id )
+{
+	for( int i = 0; i < anzahl; i++ )
+	{
+		GruppeEinladungAccount *tmp = accounts->z( i );
+		if( tmp->getAccountId() == id )
+			tmp->setRemove();
+	}
+	GruppeEinladungAccount *tmp = new GruppeEinladungAccount( schrift );
+	tmp->setGruppeId( gruppeId );
+	tmp->setAccountId( id );
+	tmp->setAdmin( admin );
+	accounts->add( tmp, anzahl );
+	anzahl++;
+	rend = 1;
+}
+
+void GruppeEinladungListe::setAbgelehnt( int id )
+{
+	for( int i = 0; i < anzahl; i++ )
+	{
+		GruppeEinladungAccount *tmp = accounts->z( i );
+		if( tmp && tmp->getAccountId() == id )
+		{
+			tmp->setAbgelehnt();
+			break;
+		}
+	}
+}
+
+void GruppeEinladungListe::setAngenommen( int id )
+{
+	for( int i = 0; i < anzahl; i++ )
+	{
+		GruppeEinladungAccount *tmp = accounts->z( i );
+		if( tmp && tmp->getAccountId() == id )
+		{
+			tmp->setAngenommen();
+			break;
+		}
+	}
+}
+
+void GruppeEinladungListe::remove( int id )
+{
+	for( int i = 0; i < anzahl; i++ )
+	{
+		GruppeEinladungAccount *tmp = accounts->z( i );
+		if( tmp && tmp->getAccountId() == id )
+		{
+			tmp->setRemove();
+			break;
+		}
+	}
+}
+
+void GruppeEinladungListe::setAdmin( int admin )
+{
+	this->admin = admin;
+	for( int i = 0; i < anzahl; i++ )
+	{
+		GruppeEinladungAccount *tmp = accounts->z( i );
+		if( tmp )
+			tmp->setAdmin( admin );
+	}
+}
+
+bool GruppeEinladungListe::tick( double tickVal )
+{
+	rend |= einladenName->tick( tickVal );
+	rend |= einladen->tick( tickVal );
+	rend |= scroll->getRend();
+	this->tickVal += tickVal * 100;
+	int val = ( int )this->tickVal;
+	if( val < 1 )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	if( val > 4 )
+		val = 4;
+	this->tickVal -= val;
+	if( admin == loginKlient->getAccountId() )
+	{
+		if( einladungHöhe < 30 )
+		{
+			einladungHöhe += val;
+			if( einladungHöhe > 30 )
+				einladungHöhe = 30;
+			rend = 1;
+		}
+	}
+	else
+	{
+		if( einladungHöhe > 0 )
+		{
+			einladungHöhe -= val;
+			if( einladungHöhe < 0 )
+				einladungHöhe = 0;
+			rend = 1;
+		}
+	}
+	for( int i = 0; i < anzahl; i++ )
+	{
+		GruppeEinladungAccount *tmp = accounts->z( i );
+		if( tmp )
+			rend |= tmp->tick( tickVal );
+	}
+	for( int i = 0; i < anzahl; i++ )
+	{
+		GruppeEinladungAccount *tmp = accounts->z( i );
+		if( !tmp->getHeight() )
+		{
+			accounts->remove( i );
+			anzahl--;
+			rend = 1;
+		}
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void GruppeEinladungListe::doMausEreignis( MausEreignis &me )
+{
+	int tmpX = me.mx;
+	int tmpY = me.my;
+	me.mx -= pos.x;
+	me.my -= pos.y;
+	if( einladungHöhe == 30 )
+	{
+		einladenName->doMausEreignis( me );
+		bool ak = !me.verarbeitet;
+		einladen->doMausEreignis( me );
+		if( me.verarbeitet && ak )
+		{
+			if( me.id == ME_RLinks )
+			{
+				if( einladenName->zText()->getLength() )
+				{
+					int accountId = infoKlient->getAccountId( einladenName->zText()->getText() );
+					if( accountId )
+					{
+						if( !anmeldungKlient->gruppeSpielerEinladen( accountId, gruppeId ) )
+						{
+							nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( anmeldungKlient->getLetzterFehler() ),
+																		  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+						}
+						else
+						{
+							einladenName->setText( "" );
+							einladenName->setAuswahl( 0, 0 );
+							rend = 1;
+						}
+					}
+					else
+					{
+						nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Der Account wurde nicht gefunden." ),
+																	  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+					}
+				}
+			}
+			return;
+		}
+	}
+	scroll->doMausMessage( 134, 1 + einladungHöhe, 15, 348 - einladungHöhe, me );
+	me.my -= einladungHöhe + 1;
+	for( int i = 0; i < anzahl; i++ )
+	{
+		GruppeEinladungAccount *tmp = accounts->z( i );
+		if( tmp )
+		{
+			tmp->doMausEreignis( me );
+			if( tmp->getRemove() )
+			{
+				accounts->remove( i );
+				anzahl--;
+				rend = 1;
+			}
+			me.my -= tmp->getHeight();
+		}
+	}
+	me.mx = tmpX;
+	me.my = tmpY;
+}
+
+void GruppeEinladungListe::doTastaturEreignis( TastaturEreignis &te )
+{
+	bool b = !te.verarbeitet;
+	einladenName->doTastaturEreignis( te );
+	if( te.verarbeitet && b && te.id == TE_Release && te.taste == T_Enter )
+	{
+		if( einladenName->zText()->getLength() )
+		{
+			int accountId = infoKlient->getAccountId( einladenName->zText()->getText() );
+			if( accountId )
+			{
+				if( !anmeldungKlient->gruppeSpielerEinladen( accountId, gruppeId ) )
+				{
+					nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( anmeldungKlient->getLetzterFehler() ),
+																  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+				}
+				else
+				{
+					einladenName->setText( "" );
+					einladenName->setAuswahl( 0, 0 );
+					rend = 1;
+				}
+			}
+			else
+			{
+				nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Der Account wurde nicht gefunden." ),
+															  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+			}
+		}
+	}
+}
+
+void GruppeEinladungListe::render( Bild &zRObj )
+{
+	if( !zRObj.setDrawOptions( pos, gr ) )
+		return;
+	rahmen->render( zRObj );
+	int rbr = rahmen->getRBreite();
+	if( einladungHöhe )
+	{
+		if( zRObj.setDrawOptions( rbr, rbr, gr.x - rbr * 2, einladungHöhe - rbr * 2 ) )
+		{
+			einladenName->render( zRObj );
+			einladen->render( zRObj );
+			zRObj.releaseDrawOptions();
+		}
+	}
+	if( !zRObj.setDrawOptions( rbr, einladungHöhe + rbr, gr.x - rbr * 2, gr.y - rbr * 2 ) )
+	{
+		zRObj.releaseDrawOptions();
+		return;
+	}
+	scroll->render( 134, 0, 15, 348 - einladungHöhe, zRObj );
+	int höhe = 0;
+	for( int i = 0; i < anzahl; i++ )
+	{
+		GruppeEinladungAccount *tmp = accounts->z( i );
+		if( tmp )
+		{
+			tmp->setSize( gr.x - 15 - rbr * 2 );
+			tmp->render( höhe - scroll->getScroll(), zRObj );
+			höhe += tmp->getHeight();
+		}
+	}
+	scroll->update( höhe, gr.y - rbr * 2 - einladungHöhe );
+	zRObj.releaseDrawOptions();
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+
+// Reference Counting
+GruppeEinladungListe *GruppeEinladungListe::getThis()
+{
+	ref++;
+	return this;
+}
+
+GruppeEinladungListe *GruppeEinladungListe::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Inhalt der GruppeAccountDaten Klasse aus Gruppe.h
+// Konstruktor
+GruppeAccountDaten::GruppeAccountDaten( Schrift *zSchrift )
+{
+	Bild *nachrichtBild = bilder->get( "chat.ltdb/nachricht.png" );
+	if( !nachrichtBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		nachrichtBild = datei->laden( 0, new Text( "nachricht.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/nachricht.png", nachrichtBild->getThis() );
+	}
+	Bild *einladungBild = bilder->get( "chat.ltdb/neuerfreund.png" );
+	if( !nachrichtBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		einladungBild = datei->laden( 0, new Text( "neuerfreund.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/neuerfreund.png", einladungBild->getThis() );
+	}
+	Bild *ansehenBild = bilder->get( "chat.ltdb/ansehen.png" );
+	if( !ansehenBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		ansehenBild = datei->laden( 0, new Text( "ansehen.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/ansehen.png", ansehenBild->getThis() );
+	}
+	Bild *entfernenBild = bilder->get( "chat.ltdb/entfernen.png" );
+	if( !entfernenBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		entfernenBild = datei->laden( 0, new Text( "entfernen.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/entfernen.png", entfernenBild->getThis() );
+	}
+	rahmen = new LRahmen();
+	rahmen->setFarbe( 0xFFFFFFFF );
+	rahmen->setRamenBreite( 1 );
+	auswahl = new AlphaFeld();
+	auswahl->setFarbe( 0x0000FF00 );
+	auswahl->setStrength( -2 );
+	auswahl->setPosition( 1, 1 );
+	name = initTextFeld( 1, 6, 100, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "" );
+	punkte = initTextFeld( 101, 6, 100, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "0p" );
+	nachrichtSenden = initKnopf( 0, 30, 20, 20, 0, 0, "" );
+	nachrichtSenden->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	nachrichtSenden->setHintergrundBildZ( nachrichtBild );
+	initToolTip( nachrichtSenden, "Nachricht senden.", zSchrift->getThis(), hauptScreen );
+	freundEinladung = initKnopf( 0, 30, 20, 20, 0, 0, "" );
+	freundEinladung->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	freundEinladung->setHintergrundBildZ( einladungBild );
+	initToolTip( freundEinladung, "Freundeseinladung senden.", zSchrift->getThis(), hauptScreen );
+	accountAnsehen = initKnopf( 0, 30, 20, 20, 0, 0, "" );
+	accountAnsehen->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	accountAnsehen->setHintergrundBildZ( ansehenBild );
+	initToolTip( accountAnsehen, "Account ansehen.", zSchrift->getThis(), hauptScreen );
+	kick = initKnopf( 0, 30, 20, 20, 0, 0, "" );
+	kick->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	kick->setHintergrundBildZ( entfernenBild );
+	initToolTip( kick, "Diesen Spieler kicken.", zSchrift->getThis(), hauptScreen );
+	tickVal = 0;
+	mausIn = 0;
+	remove = 0;
+	gruppeId = 0;
+	accountId = 0;
+	admin = 0;
+	höhe = 0;
+	animation = 0x1;
+	rend = 0;
+	ref = 1;
+}
+
+// Destruktor
+GruppeAccountDaten::~GruppeAccountDaten()
+{
+	rahmen->release();
+	auswahl->release();
+	name->release();
+	punkte->release();
+	nachrichtSenden->release();
+	freundEinladung->release();
+	accountAnsehen->release();
+	kick->release();
+}
+
+// nicht constant
+void GruppeAccountDaten::setGruppeId( int gruppeId )
+{
+	this->gruppeId = gruppeId;
+}
+
+void GruppeAccountDaten::setAccountId( int id )
+{
+	accountId = id;
+	name->setText( infoKlient->getSpielerName( id ) );
+	punkte->setText( "" );
+	punkte->zText()->append( infoKlient->getSpielerPunkte( id, infoKlient->getSpielId( infoKlient->getGruppenKarteId( gruppeId ) ) ) );
+	punkte->zText()->append( "p" );
+	rend = 1;
+}
+
+void GruppeAccountDaten::setSize( int x )
+{
+	if( br != x )
+	{
+		br = x;
+		rend = 1;
+	}
+}
+
+void GruppeAccountDaten::entfernen()
+{
+	animation &= ~0x1;
+}
+
+void GruppeAccountDaten::setAdmin( int admin )
+{
+	this->admin = admin;
+	rend = 1;
+}
+
+bool GruppeAccountDaten::tick( double tickVal )
+{
+	rend |= name->tick( tickVal );
+	rend |= punkte->tick( tickVal );
+	rend |= nachrichtSenden->tick( tickVal );
+	rend |= accountAnsehen->tick( tickVal );
+	rend |= freundEinladung->tick( tickVal );
+	rend |= kick->tick( tickVal );
+	this->tickVal += tickVal * 100;
+	int val = ( int )this->tickVal;
+	if( val < 1 )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	if( val > 4 )
+		val = 4;
+	this->tickVal -= val;
+	if( admin == accountId )
+	{
+		int r = ( auswahl->getFarbe() >> 16 ) & 0xFF;
+		if( r < 200 )
+		{
+			r += val;
+			if( r > 200 )
+				r = 200;
+			auswahl->setFarbe( ( auswahl->getFarbe() & 0xFF00FFFF ) | ( ( r << 16 ) & 0xFF0000 ) );
+			rend = 1;
+		}
+	}
+	else
+	{
+		int r = ( auswahl->getFarbe() >> 16 ) & 0xFF;
+		if( r > 0 )
+		{
+			if( r - val < 0 )
+				r = 0;
+			else
+				r -= val;
+			auswahl->setFarbe( ( auswahl->getFarbe() & 0xFF00FFFF ) | ( ( r << 16 ) & 0xFF0000 ) );
+			rend = 1;
+		}
+	}
+	if( ( animation | 0x1 ) == animation )
+	{
+		if( höhe < 30 )
+		{
+			höhe += val;
+			if( höhe > 30 )
+				höhe = 30;
+			rend = 1;
+		}
+		if( mausIn )
+		{
+			if( höhe < 50 )
+			{
+				höhe += val;
+				if( höhe > 50 )
+					höhe = 50;
+				rend = 1;
+			}
+			int a = ( auswahl->getFarbe() >> 24 ) & 0xFF;
+			if( a < 50 )
+			{
+				a += val;
+				if( a > 50 )
+					a = 50;
+				auswahl->setFarbe( ( ( a << 24 ) & 0xFF000000 ) | ( auswahl->getFarbe() & 0xFFFFFF ) );
+				rend = 1;
+			}
+		}
+		else
+		{
+			if( höhe > 30 )
+			{
+				höhe -= val;
+				if( höhe < 30 )
+					höhe = 30;
+				rend = 1;
+			}
+			int a = ( auswahl->getFarbe() >> 24 ) & 0xFF;
+			if( a > 0 )
+			{
+				if( a - val < 0 )
+					a = 0;
+				else
+					a -= val;
+				auswahl->setFarbe( ( ( a << 24 ) & 0xFF000000 ) | ( auswahl->getFarbe() & 0xFFFFFF ) );
+				rend = 1;
+			}
+		}
+		if( accountId != loginKlient->getAccountId() )
+		{
+			if( nachrichtSenden->getBreite() < 20 )
+			{
+				nachrichtSenden->setSize( nachrichtSenden->getBreite() + val, nachrichtSenden->getHeight() );
+				if( nachrichtSenden->getBreite() > 20 )
+					nachrichtSenden->setSize( 20, nachrichtSenden->getHeight() );
+				rend = 1;
+			}
+		}
+		else
+		{
+			if( nachrichtSenden->getBreite() > 0 )
+			{
+				nachrichtSenden->setSize( nachrichtSenden->getBreite() - val, nachrichtSenden->getHeight() );
+				if( nachrichtSenden->getBreite() < 0 )
+					nachrichtSenden->setSize( 0, nachrichtSenden->getHeight() );
+				rend = 1;
+			}
+		}
+		if( accountAnsehen->getBreite() < 20 )
+		{
+			accountAnsehen->setSize( accountAnsehen->getBreite() + val, accountAnsehen->getHeight() );
+			if( accountAnsehen->getBreite() > 20 )
+				accountAnsehen->setSize( 20, accountAnsehen->getHeight() );
+			rend = 1;
+		}
+		if( accountId == loginKlient->getAccountId() || nachLogin->zFreundesListe()->istFreund( accountId ) )
+		{
+			if( freundEinladung->getBreite() > 0 )
+			{
+				freundEinladung->setSize( freundEinladung->getBreite() - val, freundEinladung->getHeight() );
+				if( freundEinladung->getBreite() < 0 )
+					freundEinladung->setSize( 0, freundEinladung->getHeight() );
+				rend = 1;
+			}
+		}
+		else
+		{
+			if( freundEinladung->getBreite() < 20 )
+			{
+				freundEinladung->setSize( freundEinladung->getBreite() + val, freundEinladung->getHeight() );
+				if( freundEinladung->getBreite() > 20 )
+					freundEinladung->setSize( 20, freundEinladung->getHeight() );
+				rend = 1;
+			}
+		}
+		if( accountId == loginKlient->getAccountId() || admin != loginKlient->getAccountId() )
+		{
+			if( kick->getBreite() > 0 )
+			{
+				kick->setSize( kick->getBreite() - val, kick->getHeight() );
+				if( kick->getBreite() < 0 )
+					kick->setSize( 0, kick->getHeight() );
+				rend = 1;
+			}
+		}
+		else
+		{
+			if( kick->getBreite() < 20 )
+			{
+				kick->setSize( kick->getBreite() + val, kick->getHeight() );
+				if( kick->getBreite() > 20 )
+					kick->setSize( 20, kick->getHeight() );
+				rend = 1;
+			}
+		}
+	}
+	else
+	{
+		if( höhe > 0 )
+		{
+			höhe -= val;
+			if( höhe <= 0 )
+			{
+				höhe = 0;
+				remove = 1;
+			}
+			rend = 1;
+		}
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void GruppeAccountDaten::doMausEreignis( MausEreignis &me )
+{
+	if( me.mx < 0 || me.my < 0 || me.mx > br || me.my > höhe )
+		mausIn = 0;
+	else
+		mausIn = 1;
+	bool ak = !me.verarbeitet;
+	nachrichtSenden->doMausEreignis( me );
+	int aktion = ( me.verarbeitet && ak ) ? 1 : 0;
+	accountAnsehen->doMausEreignis( me );
+	aktion = ( me.verarbeitet && ak && !aktion ) ? 2 : aktion;
+	freundEinladung->doMausEreignis( me );
+	aktion = ( me.verarbeitet && ak && !aktion ) ? 3 : aktion;
+	kick->doMausEreignis( me );
+	aktion = ( me.verarbeitet && ak && !aktion ) ? 4 : aktion;
+	if( me.id != ME_RLinks )
+		return;
+	switch( aktion )
+	{
+	case 1:
+		nachLogin->zChatLeiste()->addChat( accountId, 0 );
+		break;
+	case 2:
+		if( nachLogin->zAccountAnsehenFenster()->setSpielerDetails( accountId, 2 ) )
+		{
+			MausEreignis me = { ME_RLinks, 0, 0, 0, 0, 0 };
+			nachLogin->zTitelLeiste()->druckAccountAnsehen( me );
+		}
+		break;
+	case 3:
+		chatKlient->freundesAnfrage( accountId );
+		break;
+	case 4:
+		if( !anmeldungKlient->kickSpielerAusGruppe( accountId, gruppeId ) )
+		{
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( anmeldungKlient->getLetzterFehler() ),
+														  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+		}
+		break;
+	}
+}
+
+void GruppeAccountDaten::render( int y, Bild &zrObj )
+{
+	if( !zrObj.setDrawOptions( 0, y, br, höhe ) )
+		return;
+	rahmen->setSize( br, höhe );
+	rahmen->render( zrObj );
+	int rbr = rahmen->getRBreite();
+	auswahl->setPosition( rbr, rbr );
+	auswahl->setSize( br - rbr * 2, höhe - rbr * 2 );
+	auswahl->render( zrObj );
+	name->render( zrObj );
+	punkte->render( zrObj );
+	if( !zrObj.setDrawOptions( rbr, rbr, br - rbr * 2, höhe - rbr * 2 ) )
+	{
+		zrObj.releaseDrawOptions();
+		return;
+	}
+	int b = kick->getBreite();
+	kick->setPosition( br - rbr - b, 30 );
+	kick->render( zrObj );
+	b += freundEinladung->getBreite();
+	freundEinladung->setPosition( br - rbr - b, 30 );
+	freundEinladung->render( zrObj );
+	b += accountAnsehen->getBreite();
+	accountAnsehen->setPosition( br - rbr - b, 30 );
+	accountAnsehen->render( zrObj );
+	b += nachrichtSenden->getBreite();
+	nachrichtSenden->setPosition( br - rbr - b, 30 );
+	nachrichtSenden->render( zrObj );
+	zrObj.releaseDrawOptions();
+	zrObj.releaseDrawOptions();
+}
+
+// constant
+bool GruppeAccountDaten::getRemove() const
+{
+	return remove;
+}
+
+int GruppeAccountDaten::getAccountId() const
+{
+	return accountId;
+}
+
+int GruppeAccountDaten::getHeight() const
+{
+	return höhe;
+}
+
+// Reference Counting
+GruppeAccountDaten *GruppeAccountDaten::getThis()
+{
+	ref++;
+	return this;
+}
+
+GruppeAccountDaten *GruppeAccountDaten::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Inhalt der GruppeAccountListe Klasse aus Gruppe.h
+// Konstruktor
+GruppeAccountListe::GruppeAccountListe( Schrift *zSchrift )
+{
+	schrift = zSchrift->getThis();
+	pos = Punkt( 0, 0 );
+	gr = Punkt( 200, 350 );
+	rahmen = new LRahmen();
+	rahmen->setFarbe( 0xFFFFFFFF );
+	rahmen->setRamenBreite( 1 );
+	rahmen->setSize( 200, 350 );
+	scroll = new VScrollBar();
+	accounts = new RCArray< GruppeAccountDaten >();
+	anzahl = 0;
+	gruppeId = 0;
+	admin = 0;
+	rend = 0;
+	ref = 1;
+}
+
+// Destruktor
+GruppeAccountListe::~GruppeAccountListe()
+{
+	schrift->release();
+	rahmen->release();
+	scroll->release();
+	accounts->release();
+}
+
+// nicht constant
+void GruppeAccountListe::reset()
+{
+	accounts->leeren();
+	anzahl = 0;
+	gruppeId = 0;
+	admin = 0;
+	rend = 1;
+}
+
+void GruppeAccountListe::setGruppeId( int gruppeId )
+{
+	this->gruppeId = gruppeId;
+	for( int i = 0; i < anzahl; i++ )
+		accounts->z( i )->setGruppeId( gruppeId );
+}
+
+void GruppeAccountListe::addAccount( int id )
+{
+	GruppeAccountDaten *tmp = new GruppeAccountDaten( schrift );
+	tmp->setGruppeId( gruppeId );
+	tmp->setAccountId( id );
+	tmp->setAdmin( admin );
+	accounts->add( tmp, anzahl );
+	anzahl++;
+	rend = 1;
+}
+
+void GruppeAccountListe::removeAccount( int id )
+{
+	for( int i = 0; i < anzahl; i++ )
+	{
+		GruppeAccountDaten *tmp = accounts->z( i );
+		if( tmp && tmp->getAccountId() == id )
+		{
+			tmp->entfernen();
+			break;
+		}
+	}
+}
+
+void GruppeAccountListe::setAdmin( int admin )
+{
+	this->admin = admin;
+	for( int i = 0; i < anzahl; i++ )
+	{
+		GruppeAccountDaten *tmp = accounts->z( i );
+		if( tmp )
+			tmp->setAdmin( admin );
+	}
+}
+
+bool GruppeAccountListe::tick( double tickVal )
+{
+	rend |= scroll->getRend();
+	for( int i = 0; i < anzahl; i++ )
+	{
+		GruppeAccountDaten *tmp = accounts->z( i );
+		if( tmp )
+			rend |= tmp->tick( tickVal );
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void GruppeAccountListe::doMausEreignis( MausEreignis &me )
+{
+	int tmpX = me.mx;
+	int tmpY = me.my;
+	me.mx -= pos.x;
+	me.my -= pos.y;
+	scroll->doMausMessage( 184, 1, 15, 248, me );
+	for( int i = 0; i < anzahl; i++ )
+	{
+		GruppeAccountDaten *tmp = accounts->z( i );
+		if( tmp )
+		{
+			tmp->doMausEreignis( me );
+            me.my -= tmp->getHeight();
+			if( tmp->getRemove() )
+			{
+				accounts->remove( i );
+				anzahl--;
+                i--;
+				rend = 1;
+			}
+		}
+	}
+	me.mx = tmpX;
+	me.my = tmpY;
+}
+
+void GruppeAccountListe::render( Bild &zRObj )
+{
+	if( !zRObj.setDrawOptions( pos, gr ) )
+		return;
+	rahmen->render( zRObj );
+	int rbr = rahmen->getRBreite();
+	scroll->render( gr.x - 15 - rbr, 1, 15, gr.y - rbr * 2, zRObj );
+	if( !zRObj.setDrawOptions( rbr, rbr, gr.x - rbr * 2, gr.y - rbr * 2 ) )
+	{
+		zRObj.releaseDrawOptions();
+		return;
+	}
+	int höhe = 0;
+	for( int i = 0; i < anzahl; i++ )
+	{
+		GruppeAccountDaten *tmp = accounts->z( i );
+		if( tmp )
+		{
+			tmp->setSize( gr.x - 15 - rbr * 2 );
+			tmp->render( höhe - scroll->getScroll(), zRObj );
+			höhe += tmp->getHeight();
+		}
+	}
+	zRObj.releaseDrawOptions();
+	zRObj.releaseDrawOptions();
+	scroll->update( höhe, gr.y - rbr * 2 );
+}
+
+// constant
+
+// Reference Counting
+GruppeAccountListe *GruppeAccountListe::getThis()
+{
+	ref++;
+	return this;
+}
+
+GruppeAccountListe *GruppeAccountListe::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Inhalt der GruppeChat Klasse aus Gruppe.h
+// Konstruktor
+GruppeChat::GruppeChat( Schrift *zSchrift )
+{
+	Bild *sendenBild = bilder->get( "chat.ltdb/senden.png" );
+	if( !sendenBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		sendenBild = datei->laden( 0, new Text( "senden.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/senden.png", sendenBild->getThis() );
+	}
+	pos = Punkt( 0, 350 );
+	gr = Punkt( 750, 200 );
+	rahmen = new LRahmen();
+	rahmen->setFarbe( 0xFFFFFFFF );
+	rahmen->setRamenBreite( 1 );
+	rahmen->setSize( 750, 200 );
+	nachricht = initTextFeld( 2, 176, 724, 20, zSchrift, TextFeld::Style::TextFeld, "" );
+	initToolTip( nachricht, "Nachricht an die Gruppe senden.", zSchrift->getThis(), hauptScreen );
+	senden = initKnopf( 726, 176, 20, 20, 0, 0, "" );
+	senden->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	senden->setHintergrundBildZ( sendenBild );
+	initToolTip( senden, "Diese Nachricht an die Gruppe senden.", zSchrift->getThis(), hauptScreen );
+	verlauf = initTextFeld( 2, 2, 746, 174, zSchrift, TextFeld::Style::TextGebiet, "" );
+	verlauf->removeStyle( TextFeld::Style::Erlaubt );
+	verlauf->updateVScroll();
+	verlauf->setVertikalKlickScroll( 5 );
+	gruppeId = 0;
+	rend = 0;
+	ref = 1;
+}
+
+// Destruktor
+GruppeChat::~GruppeChat()
+{
+	rahmen->release();
+	nachricht->release();
+	senden->release();
+	verlauf->release();
+}
+
+// nicht constant
+void GruppeChat::reset()
+{
+	gruppeId = 0;
+	verlauf->setText( "" );
+	verlauf->updateVScroll();
+	nachricht->setText( "" );
+	rend = 1;
+}
+
+void GruppeChat::setGruppeId( int gruppeId )
+{
+	this->gruppeId = gruppeId;
+}
+
+void GruppeChat::gruppeNachricht( const char *nachricht )
+{
+	verlauf->addZeile( nachricht );
+	verlauf->updateVScroll();
+	rend = 1;
+}
+
+bool GruppeChat::tick( double tickVal )
+{
+	rend |= verlauf->tick( tickVal );
+	rend |= nachricht->tick( tickVal );
+	rend |= senden->tick( tickVal );
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void GruppeChat::doMausEreignis( MausEreignis &me )
+{
+	me.mx -= pos.x;
+	me.my -= pos.y;
+	verlauf->doMausEreignis( me );
+	nachricht->doMausEreignis( me );
+	bool ak = !me.verarbeitet;
+	senden->doMausEreignis( me );
+	int aktion = ( me.verarbeitet && ak ) ? 1 : 0;
+	if( me.id != ME_RLinks )
+	{
+		me.mx += pos.x;
+		me.my += pos.y;
+		return;
+	}
+	if( aktion )
+	{
+		if( anmeldungKlient->gruppeNachricht( gruppeId, nachricht->zText()->getText() ) )
+		{
+			nachricht->setText( "" );
+			nachricht->setAuswahl( 0, 0 );
+			rend = 1;
+		}
+		else
+		{
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( anmeldungKlient->getLetzterFehler() ),
+														  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+		}
+	}
+	me.mx += pos.x;
+	me.my += pos.y;
+}
+
+void GruppeChat::doTastaturEreignis( TastaturEreignis &te )
+{
+	bool b = te.verarbeitet;
+	nachricht->doTastaturEreignis( te );
+	if( te.verarbeitet && !b && te.id == TE_Release && te.taste == T_Enter )
+	{
+		if( anmeldungKlient->gruppeNachricht( gruppeId, nachricht->zText()->getText() ) )
+		{
+			nachricht->setText( "" );
+			nachricht->setAuswahl( 0, 0 );
+			rend = 1;
+		}
+		else
+		{
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( anmeldungKlient->getLetzterFehler() ),
+														  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+		}
+	}
+}
+
+void GruppeChat::render( Bild &zRObj )
+{
+	if( !zRObj.setDrawOptions( pos.x, pos.y, gr.x, gr.y ) )
+		return;
+	verlauf->render( zRObj );
+	nachricht->render( zRObj );
+	senden->render( zRObj );
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+
+// Reference Counting
+GruppeChat *GruppeChat::getThis()
+{
+	ref++;
+	return this;
+}
+
+GruppeChat *GruppeChat::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Inhalt der GruppeAnmeldung Klasse aus Gruppe.h
+// Konstruktor
+GruppeAnmeldung::GruppeAnmeldung( Schrift *zSchrift )
+{
+	pos = Punkt( 750, 350 );
+	gr = Punkt( 200, 200 );
+	rahmen = new LRahmen();
+	rahmen->setFarbe( 0xFFFFFFFF );
+	rahmen->setRamenBreite( 1 );
+	rahmen->setSize( 200, 200 );
+	spielerHinzufügen = initKontrollKnopf( 25, 45, 150, 20, zSchrift, KontrollKnopf::Style::Normal, "Spieler hinzufügen" );
+	spielerHinzufügen->removeStyle( KontrollKnopf::Style::Erlaubt );
+	spielerHinzufügen->setMausEreignis( _ret1ME );
+	initToolTip( spielerHinzufügen, "Es werden nur Spieler aus dieser Gruppe mit ins Spiel kommen.", zSchrift->getThis(), hauptScreen );
+	angemeldet = initKontrollKnopf( 25, 75, 150, 20, zSchrift, KontrollKnopf::Style::Normal, "in Warteschlange" );
+	angemeldet->removeStyle( KontrollKnopf::Style::Erlaubt );
+	angemeldet->setMausEreignis( _ret1ME );
+	initToolTip( angemeldet, "Die Gruppe befindet sich momentan nicht in der Warteschlange.", zSchrift->getThis(), hauptScreen );
+	zeit = initTextFeld( 0, 105, 200, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Zeit in Warteschlange: " );
+	gruppeVerlassen = initKnopf( 40, 135, 120, 20, zSchrift, Knopf::Style::Normal, "Gruppe verlassen" );
+	admin = 0;
+	time = 0;
+	gruppeId = 0;
+	rend = 0;
+	ref = 1;
+}
+
+// Destruktor
+GruppeAnmeldung::~GruppeAnmeldung()
+{
+	rahmen->release();
+	spielerHinzufügen->release();
+	angemeldet->release();
+	zeit->release();
+	gruppeVerlassen->release();
+}
+
+// nicht constant
+void GruppeAnmeldung::reset()
+{
+	spielerHinzufügen->removeStyle( KontrollKnopf::Style::Selected );
+	angemeldet->removeStyle( KontrollKnopf::Style::Selected );
+	admin = 0;
+	time = 0;
+	gruppeId = 0;
+	rend = 1;
+}
+
+void GruppeAnmeldung::setGruppeId( int gruppeId )
+{
+	this->gruppeId = gruppeId;
+	spielerHinzufügen->setStyle( KontrollKnopf::Style::Selected, infoKlient->getGruppeSpielerHinzufügen( gruppeId ) );
+	rend = 1;
+}
+
+void GruppeAnmeldung::setAdmin( int admin )
+{
+	this->admin = admin;
+	if( admin == loginKlient->getAccountId() )
+	{
+		spielerHinzufügen->addStyle( KontrollKnopf::Style::Erlaubt );
+		angemeldet->addStyle( KontrollKnopf::Style::Erlaubt );
+	}
+	else
+	{
+		spielerHinzufügen->removeStyle( KontrollKnopf::Style::Erlaubt );
+		angemeldet->removeStyle( KontrollKnopf::Style::Erlaubt );
+	}
+	rend = 1;
+}
+
+void GruppeAnmeldung::setSpielerHinzufügen( bool spielerHinzufügen )
+{
+	this->spielerHinzufügen->setStyle( KontrollKnopf::Style::Selected, spielerHinzufügen );
+	if( spielerHinzufügen )
+		this->spielerHinzufügen->zToolTip()->setText( "Es kommen auch andere Spieler mit ins Spiel,\ndie nicht in dieser Gruppe sind." );
+	else
+		this->spielerHinzufügen->zToolTip()->setText( "Es werden nur Spieler aus dieser Gruppe mit ins Spiel kommen." );
+	rend = 1;
+}
+
+void GruppeAnmeldung::setAngemeldet( bool angemeldet )
+{
+	this->angemeldet->setStyle( KontrollKnopf::Style::Selected, angemeldet );
+	if( angemeldet )
+		this->angemeldet->zToolTip()->setText( "Die Gruppe befindet sich in der Warteschlange." );
+	else
+		this->angemeldet->zToolTip()->setText( "Die Gruppe befindet sich momentan nicht in der Warteschlange." );
+	time = 0;
+	rend = 1;
+}
+
+void GruppeAnmeldung::zurückInWarteschlange( int stunden, int minuten, int sekunden )
+{
+	this->angemeldet->setStyle( KontrollKnopf::Style::Selected, 1 );
+	time = sekunden + minuten * 60 + stunden * 60 * 60;
+	rend = 1;
+}
+
+void GruppeAnmeldung::spielGefunden()
+{
+	this->angemeldet->setStyle( KontrollKnopf::Style::Selected, 0 );
+	time = 0;
+	rend = 1;
+}
+
+bool GruppeAnmeldung::tick( double tickVal )
+{
+	if( angemeldet->hatStyle( KontrollKnopf::Style::Selected ) )
+	{
+		if( (int)( time / 1 ) != (int)( ( time + tickVal ) / 1 ) )
+			rend = 1;
+		time += tickVal;
+	}
+	if( rend )
+	{
+		zeit->setText( "Zeit in Warteschlange: " );
+		zeit->zText()->append( (int)( time / 60 / 60 ) );
+		zeit->zText()->append( ":" );
+		zeit->zText()->append( (int)( time / 60 ) % 60 );
+		zeit->zText()->append( ":" );
+		zeit->zText()->append( (int)( time ) % 60 );
+	}
+	rend |= spielerHinzufügen->tick( tickVal );
+	rend |= angemeldet->tick( tickVal );
+	rend |= gruppeVerlassen->tick( tickVal );
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void GruppeAnmeldung::doMausEreignis( MausEreignis &me )
+{
+	me.mx -= pos.x;
+	me.my -= pos.y;
+	bool ak = !me.verarbeitet;
+	int aktion = 0;
+	if( admin == loginKlient->getAccountId() )
+	{
+		spielerHinzufügen->doMausEreignis( me );
+		aktion = ( me.verarbeitet && admin == loginKlient->getAccountId() && ak ) ? 1 : aktion;
+		angemeldet->doMausEreignis( me );
+		aktion = ( me.verarbeitet && admin == loginKlient->getAccountId() && ak && !aktion ) ? 2 : aktion;
+	}
+	gruppeVerlassen->doMausEreignis( me );
+	aktion = ( me.verarbeitet && ak && !aktion ) ? 3 : aktion;
+	if( me.id != ME_RLinks )
+	{
+		me.mx += pos.x;
+		me.my += pos.y;
+		return;
+	}
+	switch( aktion )
+	{
+	case 1:
+		if( !anmeldungKlient->gruppeSpielStarten( gruppeId, spielerHinzufügen->hatStyleNicht( KontrollKnopf::Style::Selected ) ) )
+		{
+			spielerHinzufügen->setStyle( KontrollKnopf::Style::Selected, spielerHinzufügen->hatStyleNicht( KontrollKnopf::Style::Selected ) );
+			rend = 1;
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( anmeldungKlient->getLetzterFehler() ),
+														  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+		}
+		break;
+	case 2:
+		if( angemeldet->hatStyle( KontrollKnopf::Style::Selected ) )
+		{
+			if( !anmeldungKlient->gruppeAnmelden( gruppeId ) )
+			{
+				angemeldet->setStyle( KontrollKnopf::Style::Selected, angemeldet->hatStyleNicht( KontrollKnopf::Style::Selected ) );
+				rend = 1;
+				nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( anmeldungKlient->getLetzterFehler() ),
+															  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+			}
+		}
+		else
+		{
+			if( !anmeldungKlient->gruppeAbmelden( gruppeId ) )
+			{
+				angemeldet->setStyle( KontrollKnopf::Style::Selected, angemeldet->hatStyleNicht( KontrollKnopf::Style::Selected ) );
+				rend = 1;
+				nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( anmeldungKlient->getLetzterFehler() ),
+															  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+			}
+		}
+		break;
+	case 3:
+		if( anmeldungKlient->gruppeVerlassen( gruppeId ) )
+			nachLogin->zSpielenFenster()->gruppeVerlassen();
+		else
+		{
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( anmeldungKlient->getLetzterFehler() ),
+														  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+		}
+		break;
+	}
+	me.mx += pos.x;
+	me.my += pos.y;
+}
+
+void GruppeAnmeldung::render( Bild &zRObj )
+{
+	if( !zRObj.setDrawOptions( pos.x, pos.y, gr.x, gr.y ) )
+		return;
+	rahmen->render( zRObj );
+	spielerHinzufügen->render( zRObj );
+	angemeldet->render( zRObj );
+	zeit->render( zRObj );
+	gruppeVerlassen->render( zRObj );
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+
+// Reference Counting
+GruppeAnmeldung *GruppeAnmeldung::getThis()
+{
+	ref++;
+	return this;
+}
+
+GruppeAnmeldung *GruppeAnmeldung::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+void GruppeKarteKSGSAktion( void *p, RCArray< KSGSVariable > *parameter, KSGSVariable **retVal )
+{
+    if( !p )
+        return;
+    ( (GruppeKarte*)p )->ksgsAktion( parameter, retVal );
+}
+
+// Inhalt der GruppeKarte Klasse aus Gruppe.h
+// Konstruktor
+GruppeKarte::GruppeKarte( Schrift *zSchrift )
+{
+	schrift = zSchrift;
+	pos = Punkt( 350, 0 );
+	gr = Punkt( 600, 350 );
+	rahmen = new LRahmen();
+	rahmen->setFarbe( 0xFFFFFFFF );
+	rahmen->setRamenBreite( 1 );
+	rahmen->setSize( 350, 350 );
+	rahmen->setPosition( 248, 0 );
+    info = 0;
+    ksgs = dllDateien->ladeDLL( "KSGScript.dll", "data/bin/KSGScript.dll" );
+    if( ksgs )
+    {
+        KSGSGetZeichnung getKSGScript = (KSGSGetZeichnung)GetProcAddress( ksgs, KSGS_START_FUNKTION );
+        if( getKSGScript )
+        {
+            info = getKSGScript();
+            info->setBildschirmZ( hauptScreen->getThis() );
+            info->setSchriftZ( schrift->getThis() );
+            info->setSize( 248, 350 );
+            info->setRückrufParam( this );
+            info->setRückrufFunktion( GruppeKarteKSGSAktion );
+        }
+        else
+        {
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                          new Text( "Der Einstiegspunkt '" KSGS_START_FUNKTION "' in der DLL-Datei "
+                                                          "'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+                                                          new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+        }
+    }
+    else
+    {
+        nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                      new Text( "Die DLL-Datei 'data/bin/KSGScript.dll' konnte nicht geladen werden." ),
+                                                      new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+    }
+	hintergrund = 0;
+	fehler = 0;
+	alpha1 = 0;
+	alpha2 = 0;
+	ladenZeit = 0;
+	tickVal = 0;
+	ladeBild = 0;
+	karteId = 0;
+	gruppeId = 0;
+	exit = 0;
+	geladen = 0;
+	rend = 0;
+	ref = 1;
+}
+
+// Destruktor
+GruppeKarte::~GruppeKarte()
+{
+	exit = 1;
+	warteAufThread( 5000 );
+	if( run )
+		ende();
+	rahmen->release();
+    if( info )
+    {
+        info->zurücksetzen();
+        info->release();
+    }
+	if( hintergrund )
+		hintergrund->release();
+	if( fehler )
+		fehler->release();
+	if( schrift )
+		schrift->release();
+    if( ksgs )
+        dllDateien->releaseDLL( "KSGScript.dll" );
+}
+
+// nicht constant
+void GruppeKarte::reset()
+{
+    if( info )
+        info->zurücksetzen();
+	if( hintergrund )
+		hintergrund = hintergrund->release();
+	if( fehler )
+		fehler = fehler->release();
+	if( run )
+	{
+		exit = 1;
+		warteAufThread( 5000 );
+		if( run )
+			ende();
+	}
+	geladen = 0;
+	alpha1 = 0;
+	alpha2 = 0;
+	ladenZeit = 0;
+	tickVal = 0;
+	ladeBild = 0;
+	karteId = 0;
+	gruppeId = 0;
+	exit = 0;
+	rend = 1;
+}
+
+void GruppeKarte::ksgsAktion( RCArray< KSGSVariable > *parameter, KSGSVariable **retVal )
+{
+
+}
+
+void GruppeKarte::setGruppeId( int gruppeId )
+{
+	this->gruppeId = gruppeId;
+	if( run )
+	{
+		exit = 1;
+		warteAufThread( 5000 );
+		if( run )
+			ende();
+		exit = 0;
+	}
+	geladen = 0;
+	rend = 1;
+	start();
+}
+
+bool GruppeKarte::tick( double tickVal )
+{
+    if( !gruppeId )
+        return 0;
+    if( info )
+        rend |= info->tick( tickVal );
+	ladenZeit += tickVal;
+	if( ladenZeit >= 1 / 30.0 )
+	{
+		ladenZeit -= 1 / 30.0;
+		if( ladeAnimation && ladeAnimation->zAnimationData() )
+		{
+			if( alpha1 )
+				rend = 1;
+			ladeBild++;
+			if( ladeBild >= ladeAnimation->zAnimationData()->getBildAnzahl() )
+				ladeBild = 0;
+		}
+	}
+	this->tickVal += tickVal * 300;
+	int val = ( int )this->tickVal;
+	if( val < 1 )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	if( val > 10 )
+		val = 10;
+	this->tickVal -= val;
+	if( !geladen && !fehler )
+	{
+		if( alpha1 != 255 || alpha2 != 0 )
+			rend = 1;
+		if( alpha1 + val > 255 )
+			alpha1 = 255;
+		else
+			alpha1 += val;
+		if( alpha2 - val < 0 )
+			alpha2 = 0;
+		else
+			alpha2 -= val;
+	}
+	else
+	{
+		if( alpha1 != 0 || alpha2 != 255 )
+			rend = 1;
+		if( alpha1 - val < 0 )
+			alpha1 = 0;
+		else
+			alpha1 -= val;
+		if( alpha2 + val > 255 )
+			alpha2 = 255;
+		else
+			alpha2 += val;
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void GruppeKarte::doMausEreignis( MausEreignis &me )
+{
+	me.mx -= pos.x;
+	me.my -= pos.y;
+    if( info )
+        info->doMausEreignis( me );
+	me.mx += pos.x;
+	me.my += pos.y;
+}
+
+void GruppeKarte::render( Bild &zrObj )
+{
+	int x = pos.x;
+	int y = pos.y;
+	if( !zrObj.setDrawOptions( x, y, gr.x, gr.y ) )
+		return;
+	if( alpha1 != 0 && ladeAnimation && ladeAnimation->zAnimationData() )
+	{
+		Bild *tmp = ladeAnimation->zAnimationData()->zBild( ladeBild );
+		if( tmp )
+		{
+			zrObj.setAlpha( alpha1 );
+			zrObj.drawBild( gr.x / 2 - tmp->getBreite() / 2, gr.y / 2 - tmp->getHeight() / 2, tmp->getBreite(), tmp->getHeight(), *tmp );
+			zrObj.releaseAlpha();
+		}
+	}
+	if( alpha2 != 0 )
+	{
+		zrObj.setAlpha( alpha2 );
+		if( geladen )
+        {
+            if( info )
+                info->render( zrObj );
+			rahmen->render( zrObj );
+			zrObj.drawBild( 248 + rahmen->getRBreite(), rahmen->getRBreite(),
+							 rahmen->getBreite() - rahmen->getRBreite() * 2, rahmen->getHeight() - rahmen->getRBreite() * 2, *hintergrund );
+		}
+		else if( fehler )
+			fehler->render( zrObj );
+		zrObj.releaseAlpha();
+	}
+	zrObj.releaseDrawOptions();
+}
+
+void GruppeKarte::thread()
+{
+    if( info )
+        info->zurücksetzen();
+	if( hintergrund )
+		hintergrund = hintergrund->release();
+	if( fehler )
+		fehler = fehler->release();
+	karteId = infoKlient->getGruppenKarteId( gruppeId );
+	if( !karteId )
+	{
+		run = 0;
+		return;
+	}
+	KartenLeser *karte = new KartenLeser();
+	karte->setKarteId( karteId );
+	hintergrund = karte->getKartenVorschauBild();
+	if( exit )
+	{
+		if( hintergrund )
+			hintergrund = hintergrund->release();
+		karte->release();
+		run = 0;
+		return;
+	}
+	if( !hintergrund )
+	{
+		Text *f = new Text( karte->getLetzterFehler() );
+		schrift->lock();
+		schrift->setSchriftSize( 12 );
+		int br = schrift->getTextBreite( f );
+		int hö = schrift->getTextHeight( f );
+		schrift->unlock();
+		fehler = initTextFeld( gr.x / 2 - ( br + 10 ) / 2, gr.y / 2 - ( hö + 4 ) / 2, br + 10, hö + 4,
+							   schrift, TextFeld::Style::Text | TextFeld::Style::Center, f->getText() );
+		f->release();
+		karte->release();
+		run = 0;
+		return;
+	}
+    bool ok = 0;
+    if( info )
+    {
+        if( !karte->getKartenBeschreibung() )
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Beschreibung nicht gefunden." ), new Text( "Ok" ) );
+        else
+        {
+            Text *pf = karte->getKartePfad();
+            *pf += "beschreibung.ksgs";
+            info->setScriptDatei( pf );
+            ok = info->neuLaden();
+            KSGSVariable *var = info->startFunktion( info->getFunktionId( "_in_gruppe" ), new RCArray< KSGSVariable >() );
+            if( var )
+                var->release();
+        }
+    }
+	if( !ok )
+	{
+		Text *f = new Text( karte->getLetzterFehler() );
+		schrift->lock();
+		schrift->setSchriftSize( 12 );
+		int br = schrift->getTextBreite( f );
+		int hö = schrift->getTextHeight( f );
+		schrift->unlock();
+		fehler = initTextFeld( gr.x / 2 - ( br + 10 ) / 2, gr.y / 2 - ( hö + 4 ) / 2, br + 10, hö + 4,
+							   schrift, TextFeld::Style::Text | TextFeld::Style::Center, f->getText() );
+		f->release();
+		karte->release();
+		run = 0;
+		return;
+	}
+	karte->release();
+	geladen = 1;
+	run = 0;
+	rend = 1;
+}
+
+// constant
+int GruppeKarte::getKarteId() const
+{
+	return karteId;
+}
+
+// Reference Counting
+GruppeKarte *GruppeKarte::getThis()
+{
+	ref++;
+	return this;
+}
+
+GruppeKarte *GruppeKarte::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Inhalt der GruppeSpielGefunden Klasse aus Gruppe.h
+// Konstruktor
+GruppeSpielGefunden::GruppeSpielGefunden( Schrift *zSchrift )
+{
+	pos = Punkt( 375, 235 );
+	gr = Punkt( 200, 90 );
+	spielGefunden = initFenster( 0, 0, 200, 90, zSchrift, Fenster::Style::Sichtbar | Fenster::Style::Rahmen | Fenster::Style::Titel, "Spiel gefunden" );
+	zeit = initTextFeld( 0, 30, 200, 20, zSchrift, TextFeld::Style::Text, "Verbleibende Zeit: 10" );
+	warte = initTextFeld( 0, 60, 200, 20, zSchrift, TextFeld::Style::Text & ~TextFeld::Style::Sichtbar, "Warte auf andere Spieler. . ." );
+	annehmen = initKnopf( 50, 60, 100, 20, zSchrift, Knopf::Style::Normal, "beitreten" );
+	alpha = 0;
+	time = 0;
+	sichtbar = 0;
+	tickVal = 0;
+	rend = 0;
+	ref = 1;
+}
+
+// Destruktor
+GruppeSpielGefunden::~GruppeSpielGefunden()
+{
+	spielGefunden->release();
+	zeit->release();
+	warte->release();
+	annehmen->release();
+}
+
+// nicht constant
+void GruppeSpielGefunden::reset()
+{
+	zeit->setText( "Verbleibende Zeit: 10" );
+	alpha = 0;
+	time = 0;
+	sichtbar = 0;
+	warte->removeStyle( TextFeld::Style::Sichtbar );
+	annehmen->addStyle( Knopf::Style::Sichtbar );
+	rend = 1;
+}
+
+void GruppeSpielGefunden::setSichtbar( bool sichtbar )
+{
+	warte->removeStyle( TextFeld::Style::Sichtbar );
+	annehmen->addStyle( Knopf::Style::Sichtbar );
+	this->sichtbar = sichtbar;
+	rend = 1;
+}
+
+void GruppeSpielGefunden::setVerbleibendeZeit( int sekunden )
+{
+	if( time != sekunden )
+		rend = 1;
+	time = sekunden;
+}
+
+bool GruppeSpielGefunden::tick( double tickVal )
+{
+	if( rend )
+	{
+		zeit->setText( "Verbleibende Zeit: " );
+		zeit->zText()->append( (int)time );
+	}
+	rend |= annehmen->tick( tickVal );
+	this->tickVal += tickVal * 300;
+	int val = ( int )this->tickVal;
+	if( val < 1 )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	if( val > 10 )
+		val = 10;
+	this->tickVal -= val;
+	if( sichtbar )
+	{
+		if( alpha < 255 )
+		{
+			if( alpha + val > 255 )
+				alpha = 255;
+			else
+				alpha += val;
+			rend = 1;
+		}
+	}
+	else
+	{
+		if( alpha )
+		{
+			if( alpha - val < 0 )
+				alpha = 0;
+			else
+				alpha -= val;
+			rend = 1;
+		}
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void GruppeSpielGefunden::doMausEreignis( MausEreignis &me )
+{
+	me.mx -= pos.x;
+	me.my -= pos.y;
+	bool ver = me.verarbeitet;
+	annehmen->doMausEreignis( me );
+	if( me.verarbeitet && !ver && me.id == ME_RLinks )
+	{
+		if( spielKlient->spielErstelltAnnehmen() )
+		{
+			annehmen->removeStyle( Knopf::Style::Sichtbar );
+			warte->addStyle( TextFeld::Style::Sichtbar );
+			rend = 1;
+		}
+		else if( nachLogin && nachLogin->zSpielenFenster() )
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( spielKlient->getLetzterFehler() ), new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+	}
+	me.mx += pos.x;
+	me.my += pos.y;
+}
+
+void GruppeSpielGefunden::render( Bild &zRObj )
+{
+	if( !zRObj.setDrawOptions( pos.x, pos.y, gr.x, gr.y ) )
+		return;
+	zRObj.setAlpha( alpha );
+	spielGefunden->render( zRObj );
+	zeit->render( zRObj );
+	warte->render( zRObj );
+	annehmen->render( zRObj );
+	zRObj.releaseAlpha();
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+bool GruppeSpielGefunden::istSichtbar() const
+{
+	return sichtbar;
+}
+
+// Reference Counting
+GruppeSpielGefunden *GruppeSpielGefunden::getThis()
+{
+	ref++;
+	return this;
+}
+
+GruppeSpielGefunden *GruppeSpielGefunden::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Inhalt der GruppeFenster Klasse aus Gruppe.h
+// Konstruktor
+GruppeFenster::GruppeFenster( Schrift *zSchrift )
+{
+	pos = Punkt( 0, 0 );
+	gr = Punkt( 950, 550 );
+	anmeldung = new GruppeAnmeldung( zSchrift );
+	chat = new GruppeChat( zSchrift );
+	accounts = new GruppeAccountListe( zSchrift );
+	einladungen = new GruppeEinladungListe( zSchrift );
+	karte = new GruppeKarte( zSchrift );
+	spiel = new GruppeSpielGefunden( zSchrift );
+	alpha = 0;
+	sichtbar = 0;
+	tickVal = 0;
+	rend = 0;
+	ref = 1;
+}
+
+// Destruktor
+GruppeFenster::~GruppeFenster()
+{
+	anmeldung->release();
+	chat->release();
+	accounts->release();
+	einladungen->release();
+	karte->release();
+	spiel->release();
+}
+
+// nicht constant
+void GruppeFenster::setGruppeId( int id )
+{
+	gruppeId = id;
+	anmeldung->setGruppeId( id );
+	chat->setGruppeId( id );
+	accounts->setGruppeId( id );
+	einladungen->setGruppeId( id );
+	karte->setGruppeId( id );
+	spiel->setSichtbar( 0 );
+	if( id )
+	{
+		int adminId = infoKlient->getGruppeAdminId( id );
+		nachLogin->zFreundesListe()->zeigeEinladeKnopf( adminId == loginKlient->getAccountId() );
+		setAdmin( adminId );
+	}
+	rend = 1;
+}
+
+void GruppeFenster::setSichtbar( bool sichtbar )
+{
+	this->sichtbar = sichtbar;
+	rend = 1;
+}
+
+void GruppeFenster::chatNachricht( const char *nachricht )
+{
+	chat->gruppeNachricht( nachricht );
+}
+
+void GruppeFenster::neuerSpieler( int accountId )
+{
+	einladungen->setAngenommen( accountId );
+	accounts->addAccount( accountId );
+}
+
+void GruppeFenster::spielerVerlässt( int accountId )
+{
+	accounts->removeAccount( accountId );
+	anmeldung->setAngemeldet( 0 );
+}
+
+void GruppeFenster::neueEinladung( int accountId )
+{
+	einladungen->addAccount( accountId );
+}
+
+void GruppeFenster::einladungEntfernt( int accountId )
+{
+	einladungen->remove( accountId );
+}
+
+void GruppeFenster::einladungAbgelehnt( int accountId )
+{
+	einladungen->setAbgelehnt( accountId );
+}
+
+void GruppeFenster::setSpielerHinzufügen( bool sh )
+{
+	anmeldung->setSpielerHinzufügen( sh );
+}
+
+void GruppeFenster::setAngemeldet( bool angemeldet )
+{
+	anmeldung->setAngemeldet( angemeldet );
+}
+
+void GruppeFenster::spielGefunden()
+{
+	anmeldung->spielGefunden();
+	spiel->setSichtbar( 1 );
+	rend = 1;
+}
+
+void GruppeFenster::verbleibendeZeit( int sekunden )
+{
+	spiel->setVerbleibendeZeit( sekunden );
+}
+
+void GruppeFenster::spielGefundenAbbruch()
+{
+	spiel->setSichtbar( 0 );
+}
+
+void GruppeFenster::zurückInWarteschlange( int stunden, int minuten, int sekunden )
+{
+	anmeldung->zurückInWarteschlange( stunden, minuten, sekunden );
+}
+
+void GruppeFenster::setAdmin( int accountId )
+{
+	anmeldung->setAdmin( accountId );
+	accounts->setAdmin( accountId );
+	einladungen->setAdmin( accountId );
+}
+
+void GruppeFenster::kick()
+{
+
+}
+
+void GruppeFenster::reset()
+{
+	accounts->reset();
+	einladungen->reset();
+	karte->reset();
+	chat->reset();
+	anmeldung->reset();
+	spiel->reset();
+}
+
+bool GruppeFenster::tick( double tickVal )
+{
+	if( !spiel->istSichtbar() )
+	{
+		rend |= anmeldung->tick( tickVal );
+		rend |= chat->tick( tickVal );
+		rend |= accounts->tick( tickVal );
+		rend |= einladungen->tick( tickVal );
+		rend |= karte->tick( tickVal );
+	}
+	rend |= spiel->tick( tickVal );
+	this->tickVal += tickVal * 300;
+	int val = ( int )this->tickVal;
+	if( val < 1 )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	if( val > 10 )
+		val = 10;
+	this->tickVal -= val;
+	if( sichtbar )
+	{
+		if( spiel->istSichtbar() )
+		{
+			if( alpha > 0x70 )
+			{
+				if( alpha - val < 0x70 )
+					alpha = 0x70;
+				else
+					alpha -= val;
+				rend = 1;
+			}
+			else if( alpha < 0x70 )
+			{
+				if( alpha + val > 0x70 )
+					alpha = 0x70;
+				else
+					alpha += val;
+				rend = 1;
+			}
+		}
+		else
+		{
+			if( alpha < 255 )
+			{
+				if( alpha + val > 255 )
+					alpha = 255;
+				else
+					alpha += val;
+				rend = 1;
+			}
+		}
+	}
+	else
+	{
+		if( alpha > 0 )
+		{
+			if( alpha - val < 0 )
+				alpha = 0;
+			else
+				alpha -= val;
+			rend = 1;
+			if( !alpha )
+				reset();
+		}
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void GruppeFenster::doMausEreignis( MausEreignis &me )
+{
+	if( !spiel->istSichtbar() )
+	{
+		anmeldung->doMausEreignis( me );
+		chat->doMausEreignis( me );
+		accounts->doMausEreignis( me );
+		einladungen->doMausEreignis( me );
+		karte->doMausEreignis( me );
+	}
+	spiel->doMausEreignis( me );
+}
+
+void GruppeFenster::doTastaturEreignis( TastaturEreignis &te )
+{
+	if( !spiel->istSichtbar() )
+	{
+		chat->doTastaturEreignis( te );
+		einladungen->doTastaturEreignis( te );
+	}
+}
+
+void GruppeFenster::render( Bild &zRObj )
+{
+	if( alpha )
+	{
+		int x = pos.x;
+		int y = pos.y;
+		if( !zRObj.setDrawOptions( x, y, gr.x, gr.y ) )
+			return;
+		unsigned char tmpAlpha = zRObj.getAlpha();
+		zRObj.setAlpha( alpha );
+		anmeldung->render( zRObj );
+		chat->render( zRObj );
+		accounts->render( zRObj );
+		einladungen->render( zRObj );
+		karte->render( zRObj );
+		zRObj.releaseAlpha();
+		spiel->render( zRObj );
+		zRObj.releaseDrawOptions();
+	}
+}
+
+// constant
+int GruppeFenster::getGruppeId() const
+{
+	return gruppeId;
+}
+
+int GruppeFenster::getKarteId() const
+{
+	return karte ? karte->getKarteId() : 0;
+}
+
+// Reference Counting
+GruppeFenster *GruppeFenster::getThis()
+{
+	ref++;
+	return this;
+}
+
+GruppeFenster *GruppeFenster::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 391 - 0
KSGClient/NachLogin/Spiele/Gruppe/Gruppe.h

@@ -0,0 +1,391 @@
+#ifndef Gruppe_H
+#define Gruppe_H
+
+#include <Klient.h>
+#include <Thread.h>
+#include <Array.h>
+#include <Knopf.h>
+#include <Scroll.h>
+#include <Fenster.h>
+#include <KSGScript.h>
+
+using namespace Framework;
+using namespace KSGScript;
+
+class GruppeEinladungAccount
+{
+private:
+	LRahmen *rahmen;
+	AlphaFeld *auswahl;
+	TextFeld *name;
+	Knopf *nachrichtSenden;
+	Knopf *erneutSenden;
+	Knopf *einladungAbbrechen;
+	int status;
+	int br;
+	int knopfX;
+	double tickVal;
+	bool mausIn;
+	bool remove;
+	int accountId;
+	int gruppeId;
+	int admin;
+	int höhe;
+	int animation;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	GruppeEinladungAccount( Schrift *zSchrift );
+	// Destruktor
+	~GruppeEinladungAccount();
+	// nicht constant
+	void setGruppeId( int gruppeId );
+	void setAccountId( int id );
+	void setSize( int br );
+	void setAbgelehnt();
+	void setAngenommen();
+	void setRemove();
+	void setAdmin( int admin );
+	bool tick( double tickVal );
+	void doMausEreignis( MausEreignis &me );
+	void render( int yOff, Bild &zrObj );
+	// constant
+	bool getRemove() const;
+	int getAccountId() const;
+	int getHeight() const;
+	// Reference Counting
+	GruppeEinladungAccount *getThis();
+	GruppeEinladungAccount *release();
+};
+
+class GruppeEinladungListe
+{
+private:
+	Punkt pos;
+	Punkt gr;
+	LRahmen *rahmen;
+	TextFeld *einladenName;
+	Knopf *einladen;
+	VScrollBar *scroll;
+	RCArray< GruppeEinladungAccount > *accounts;
+	Schrift *schrift;
+	int einladungHöhe;
+	double tickVal;
+	int anzahl;
+	int gruppeId;
+	int admin;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	GruppeEinladungListe( Schrift *zSchrift );
+	// Destruktor
+	~GruppeEinladungListe();
+	// nicht constant
+	void reset();
+	void setGruppeId( int gruppeId );
+	void addAccount( int id );
+	void setAbgelehnt( int id );
+	void setAngenommen( int id );
+	void remove( int id );
+	void setAdmin( int admin );
+	bool tick( double tickVal );
+	void doMausEreignis( MausEreignis &me );
+	void doTastaturEreignis( TastaturEreignis &te );
+	void render( Bild &zRObj );
+	// constant
+
+	// Reference Counting
+	GruppeEinladungListe *getThis();
+	GruppeEinladungListe *release();
+};
+
+class GruppeAccountDaten
+{
+private:
+	LRahmen *rahmen;
+	AlphaFeld *auswahl;
+	TextFeld *name;
+	TextFeld *punkte;
+	Knopf *nachrichtSenden;
+	Knopf *accountAnsehen;
+	Knopf *freundEinladung;
+	Knopf *kick;
+	int br;
+	double tickVal;
+	bool mausIn;
+	bool remove;
+	int gruppeId;
+	int accountId;
+	int admin;
+	int höhe;
+	int animation;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	GruppeAccountDaten( Schrift *zSchrift );
+	// Destruktor
+	~GruppeAccountDaten();
+	// nicht constant
+	void setGruppeId( int gruppeId );
+	void setAccountId( int id );
+	void setAdmin( int admin );
+	void setSize( int x );
+	void entfernen();
+	bool tick( double tickVal );
+	void doMausEreignis( MausEreignis &me );
+	void render( int y, Bild &zrObj );
+	// constant
+	bool getRemove() const;
+	int getAccountId() const;
+	int getHeight() const;
+	// Reference Counting
+	GruppeAccountDaten *getThis();
+	GruppeAccountDaten *release();
+};
+
+class GruppeAccountListe
+{
+private:
+	Punkt pos;
+	Punkt gr;
+	LRahmen *rahmen;
+	VScrollBar *scroll;
+	RCArray< GruppeAccountDaten > *accounts;
+	Schrift *schrift;
+	int anzahl;
+	int gruppeId;
+	int admin;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	GruppeAccountListe( Schrift *zSchrift );
+	// Destruktor
+	~GruppeAccountListe();
+	// nicht constant
+	void reset();
+	void setGruppeId( int gruppeId );
+	void addAccount( int id );
+	void removeAccount( int id );
+	void setAdmin( int admin );
+	bool tick( double tickVal );
+	void doMausEreignis( MausEreignis &me );
+	void render( Bild &zRObj );
+	// constant
+
+	// Reference Counting
+	GruppeAccountListe *getThis();
+	GruppeAccountListe *release();
+};
+
+class GruppeChat
+{
+private:
+	Punkt pos;
+	Punkt gr;
+	LRahmen *rahmen;
+	TextFeld *nachricht;
+	Knopf *senden;
+	TextFeld *verlauf;
+	int gruppeId;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	GruppeChat( Schrift *zSchrift );
+	// Destruktor
+	~GruppeChat();
+	// nicht constant
+	void reset();
+	void setGruppeId( int gruppeId );
+	void gruppeNachricht( const char *nachricht );
+	bool tick( double tickVal );
+	void doMausEreignis( MausEreignis &me );
+	void doTastaturEreignis( TastaturEreignis &te );
+	void render( Bild &zRObj );
+	// constant
+
+	// Reference Counting
+	GruppeChat *getThis();
+	GruppeChat *release();
+};
+
+class GruppeAnmeldung
+{
+private:
+	Punkt pos;
+	Punkt gr;
+	LRahmen *rahmen;
+	KontrollKnopf *spielerHinzufügen;
+	KontrollKnopf *angemeldet;
+	TextFeld *zeit;
+	Knopf *gruppeVerlassen;
+	int admin;
+	double time;
+	int gruppeId;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	GruppeAnmeldung( Schrift *zSchrift );
+	// Destruktor
+	~GruppeAnmeldung();
+	// nicht constant
+	void reset();
+	void setGruppeId( int gruppeId );
+	void setSpielerHinzufügen( bool spielerHinzufügen );
+	void setAngemeldet( bool angemeldet );
+	void zurückInWarteschlange( int stunden, int minuten, int sekunden );
+	void spielGefunden();
+	void setAdmin( int admin );
+	bool tick( double tickVal );
+	void doMausEreignis( MausEreignis &me );
+	void render( Bild &zRObj );
+	// constant
+
+	// Reference Counting
+	GruppeAnmeldung *getThis();
+	GruppeAnmeldung *release();
+};
+
+class GruppeKarte : public Thread
+{
+private:
+	Punkt pos;
+	Punkt gr;
+	LRahmen *rahmen;
+	Bild *hintergrund;
+	KSGScriptObj *info;
+    HINSTANCE ksgs;
+	TextFeld *fehler;
+	Schrift *schrift;
+	unsigned char alpha1;
+	unsigned char alpha2;
+	double tickVal;
+	double ladenZeit;
+	int ladeBild;
+	int karteId;
+	int gruppeId;
+	bool exit;
+	bool geladen;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	GruppeKarte( Schrift *zSchrift );
+	// Destruktor
+	~GruppeKarte();
+	// nicht constant
+    void reset();
+    void ksgsAktion( RCArray< KSGSVariable > *parameter, KSGSVariable **retVal );
+	void setGruppeId( int gruppeId );
+	bool tick( double tickVal );
+	void doMausEreignis( MausEreignis &me );
+	void render( Bild &zrObj );
+	virtual void thread();
+	// constant
+	int getKarteId() const;
+	// Reference Counting
+	GruppeKarte *getThis();
+	GruppeKarte *release();
+};
+
+class GruppeSpielGefunden
+{
+private:
+	Punkt pos;
+	Punkt gr;
+	Fenster *spielGefunden;
+	TextFeld *zeit;
+	TextFeld *warte;
+	Knopf *annehmen;
+	unsigned char alpha;
+	double time;
+	double tickVal;
+	bool sichtbar;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	GruppeSpielGefunden( Schrift *zSchrift );
+	// Destruktor
+	~GruppeSpielGefunden();
+	// nicht constant
+	void reset();
+	void setSichtbar( bool sichtbar );
+	void setVerbleibendeZeit( int sekunden );
+	bool tick( double tickVal );
+	void doMausEreignis( MausEreignis &me );
+	void render( Bild &zRObj );
+	// constant
+	bool istSichtbar() const;
+	// Reference Counting
+	GruppeSpielGefunden *getThis();
+	GruppeSpielGefunden *release();
+};
+
+class GruppeFenster
+{
+private:
+	Punkt pos;
+	Punkt gr;
+	GruppeAnmeldung *anmeldung;
+	GruppeChat *chat;
+	GruppeAccountListe *accounts;
+	GruppeEinladungListe *einladungen;
+	GruppeKarte *karte;
+	GruppeSpielGefunden *spiel;
+	bool sichtbar;
+	unsigned char alpha;
+	int gruppeId;
+	double tickVal;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	GruppeFenster( Schrift *zSchrift );
+	// Destruktor
+	~GruppeFenster();
+	// nicht constant
+	void setGruppeId( int id );
+	void setSichtbar( bool sichtbar );
+	void chatNachricht( const char *nachricht );
+	void neuerSpieler( int accountId );
+	void spielerVerlässt( int accountId );
+	void neueEinladung( int accountId );
+	void einladungEntfernt( int accountId );
+	void einladungAbgelehnt( int accountId );
+	void setSpielerHinzufügen( bool sh );
+	void setAngemeldet( bool angemeldet );
+	void spielGefunden();
+	void verbleibendeZeit( int sekunden );
+	void spielGefundenAbbruch();
+	void zurückInWarteschlange( int stunden, int minuten, int sekunden );
+	void setAdmin( int accountId );
+	void kick();
+	void reset();
+	bool tick( double tickVal );
+	void doMausEreignis( MausEreignis &me );
+	void doTastaturEreignis( TastaturEreignis &te );
+	void render( Bild &zRObj );
+	// constant
+	int getGruppeId() const;
+	int getKarteId() const;
+	// Reference ounting
+	GruppeFenster *getThis();
+	GruppeFenster *release();
+};
+
+#endif

+ 747 - 0
KSGClient/NachLogin/Spiele/Karte Auswahl/KarteAuswahl.cpp

@@ -0,0 +1,747 @@
+#include "KarteAuswahl.h"
+#include <Text.h>
+#include <Rahmen.h>
+#include <Punkt.h>
+#include <Schrift.h>
+#include <AlphaFeld.h>
+#include <TextFeld.h>
+#include <Datei.h>
+#include <DateiSystem.h>
+#include "..\..\..\Global\Initialisierung.h"
+#include <MausEreignis.h>
+#include "..\..\..\Global\Variablen.h"
+#include "..\..\..\Leser\KartenLeser.h"
+
+void KarteAuswahlKSGSAktion( void *p, RCArray< KSGSVariable > *parameter, KSGSVariable **retVal )
+{
+    if( !p )
+        return;
+    ( (KarteDaten*)p )->ksgsAktion( parameter, retVal );
+}
+
+// Inhalt der KarteDaten Klasse aus KarteAuswahl.h
+// Konstruktor
+KarteDaten::KarteDaten( Schrift *zSchrift, int id )
+{
+    hintergrund = 0;
+    beschreibung = 0;
+    ksgs = 0;
+    rahmen = new LRahmen();
+    rahmen->setFarbe( 0xFFFFFFFF );
+    rahmen->setRamenBreite( 1 );
+    tickVal = 0;
+    animation = 0;
+    ausgewählt = 0;
+    pos = Punkt( 0, 500 );
+    gr = Punkt( 200, 100 );
+    schrift = zSchrift->getThis();
+    karteId = id;
+    aktion = 1;
+    geladen = 0;
+    auswahl = new AlphaFeld();
+    auswahl->setFarbe( 0x0000FF00 );
+    auswahl->setStrength( 8 );
+    auswahl->setSize( 200, 100 );
+    auswAlpha = 0;
+    rend = 0;
+    erlaubt = 0;
+    tAlpha = 0;
+    alpha = 0;
+    ref = 1;
+    start();
+}
+
+// Destruktor
+KarteDaten::~KarteDaten()
+{
+    if( run )
+        this->warteAufThread( 5000 );
+    if( run )
+        ende();
+    if( schrift )
+        schrift->release();
+    if( hintergrund )
+        hintergrund->release();
+    if( beschreibung )
+    {
+        beschreibung->zurücksetzen();
+        beschreibung->release();
+    }
+    if( ksgs )
+    {
+        dllDateien->releaseDLL( "KSGScript.dll" );
+        ksgs = 0;
+    }
+    rahmen->release();
+    auswahl->release();
+}
+
+// nicht constant
+void KarteDaten::thread()
+{
+    if( !aktion )
+    {
+        geladen = 0;
+        if( hintergrund )
+            hintergrund = hintergrund->release();
+        if( beschreibung )
+        {
+            beschreibung->zurücksetzen();
+            beschreibung = beschreibung->release();
+        }
+        rend = 1;
+        if( ksgs )
+        {
+            dllDateien->releaseDLL( "KSGScript.dll" );
+            ksgs = 0;
+        }
+    }
+    else
+    {
+        KartenLeser *mapReader = new KartenLeser();
+        mapReader->setKarteId( karteId );
+        if( !hintergrund )
+            hintergrund = mapReader->getKartenTitelBild( schrift );
+        if( !geladen )
+            geladen = 1;
+        rend = 1;
+        if( aktion == 2 )
+        {
+            if( !mapReader->getKartenBeschreibung() )
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Beschreibung nicht gefunden." ), new Text( "Ok" ) );
+            if( beschreibung )
+            {
+                beschreibung->zurücksetzen();
+                beschreibung = beschreibung->release();
+            }
+            if( !ksgs )
+                ksgs = dllDateien->ladeDLL( "KSGScript.dll", "data/bin/KSGScript.dll" );
+            if( ksgs )
+            {
+                KSGSGetZeichnung getKSGScript = (KSGSGetZeichnung)GetProcAddress( ksgs, KSGS_START_FUNKTION );
+                if( getKSGScript )
+                {
+                    beschreibung = getKSGScript();
+                    beschreibung->setBildschirmZ( hauptScreen->getThis() );
+                    beschreibung->setSchriftZ( schrift->getThis() );
+                    beschreibung->setSize( 578, 428 );
+                    beschreibung->setRückrufParam( this );
+                    beschreibung->setRückrufFunktion( KarteAuswahlKSGSAktion );
+                    Text *pf = mapReader->getKartePfad();
+                    *pf += "beschreibung.ksgs";
+                    beschreibung->setScriptDatei( pf );
+                }
+                else
+                {
+                    nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                                  new Text( "Der Einstiegspunkt '" KSGS_START_FUNKTION "' in der DLL-Datei "
+                                                                  "'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+                                                                  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+                }
+            }
+            else
+            {
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                              new Text( "Die DLL-Datei 'data/bin/KSGScript.dll' konnte nicht geladen werden." ),
+                                                              new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+            }
+            if( beschreibung )
+                geladen = 2;
+            rend = 1;
+        }
+        mapReader->release();
+    }
+    aktion = 0;
+    if( !erlaubt )
+        updateErlaubt();
+    run = 0;
+    rend = 1;
+}
+
+void KarteDaten::updateErlaubt()
+{
+    if( geladen != 2 )
+        return;
+    bool update = erlaubt;
+    erlaubt = infoKlient->istKarteErlaubt( karteId );
+    if( update != erlaubt && beschreibung && ksgs )
+    {
+        KSGSGetVariable getKSGSVar = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
+        RCArray< KSGSVariable > *params = new RCArray< KSGSVariable >();
+        KSGSVariableDef p1;
+        p1.typId = KSGS_BOOL;
+        p1.wert = (int)erlaubt;
+        params->add( getKSGSVar( beschreibung, &p1 ) );
+        KSGSVariable *var = beschreibung->startFunktion( beschreibung->getFunktionId( "_set_Erlaubt" ), params );
+        if( var )
+            var->release();
+    }
+}
+
+void KarteDaten::ksgsAktion( RCArray< KSGSVariable > *parameter, KSGSVariable **retVal )
+{
+    if( parameter && parameter->getEintragAnzahl() > 0 )
+    {
+        Text *txt = parameter->z( 0 )->getText();
+        if( erlaubt && txt->istGleich( "anmelden" ) )
+        {
+            if( nachLogin && nachLogin->zSpielenFenster() )
+                nachLogin->zSpielenFenster()->anmelden( karteId );
+        }
+        if( erlaubt && txt->istGleich( "gruppeErstellen" ) )
+        {
+            int ret = anmeldungKlient->gruppeErstellen( karteId );
+            if( !ret )
+            {
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( anmeldungKlient->getLetzterFehler() ),
+                                                              new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+            }
+            else
+                nachLogin->zSpielenFenster()->gruppeBetreten( ret );
+        }
+        txt->release();
+    }
+}
+
+void KarteDaten::setSichtbar( bool sichtbar )
+{
+    if( sichtbar )
+        animation |= 0x1;
+    else
+    {
+        animation &= ~0x1;
+        setAuswahl( 0 );
+    }
+    if( sichtbar )
+    {
+        warteAufThread( 1000 );
+        aktion = 2;
+        start();
+    }
+    rend = 1;
+}
+
+void KarteDaten::setSichtbar()
+{
+    animation |= 0x1;
+    if( ausgewählt && geladen == 2 )
+    {
+        animation |= 0x4;
+        beschreibung->setPosition( beschreibung->getX(), 0 );
+    }
+    if( geladen != 2 )
+    {
+        warteAufThread( 1000 );
+        aktion = 2;
+        start();
+    }
+    rend = 1;
+}
+
+void KarteDaten::setAuswahl( bool auswahl )
+{
+    if( ausgewählt == auswahl )
+        return;
+    ausgewählt = auswahl;
+    if( auswahl )
+    {
+        animation |= 0x4;
+        if( beschreibung && ksgs )
+        {
+            beschreibung->neuLaden();
+            KSGSGetVariable getKSGSVar = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
+            RCArray< KSGSVariable > *params = new RCArray< KSGSVariable >();
+            KSGSVariableDef p1;
+            p1.typId = KSGS_BOOL;
+            p1.wert = (int)erlaubt;
+            params->add( getKSGSVar( beschreibung, &p1 ) );
+            KSGSVariable *var = beschreibung->startFunktion( beschreibung->getFunktionId( "_set_Erlaubt" ), params );
+            if( var )
+                var->release();
+        }
+    }
+    else
+        animation &= ~0x4;
+    rend = 1;
+}
+
+void KarteDaten::setPosition( int lPos )
+{
+    pos.y = lPos * 100;
+    rend = 1;
+}
+
+bool KarteDaten::tick( double tickVal )
+{
+    if( beschreibung )
+        rend |= beschreibung->tick( tickVal );
+    this->tickVal += tickVal * 500;
+    int val = ( int ) this->tickVal;
+    if( val < 1 )
+    {
+        bool ret = rend;
+        rend = 0;
+        return ret;
+    }
+    if( val > 17 )
+        val = 17;
+    this->tickVal -= val;
+    if( ausgewählt )
+    {
+        if( auswAlpha != 0xF0 )
+        {
+            auswAlpha += val;
+            if( auswAlpha > 0xF0 )
+                auswAlpha = 0xF0;
+            rend = 1;
+        }
+    }
+    else
+    {
+        if( auswAlpha != 0 )
+        {
+            auswAlpha -= val;
+            if( auswAlpha > 0xF0 )
+                auswAlpha = 0;
+            rend = 1;
+        }
+    }
+    if( ( animation | 0x1 ) == animation ) // sichtbar
+    {
+        if( tAlpha != 255 )
+        {
+            if( tAlpha + val > 255 )
+                tAlpha = 255;
+            else
+                tAlpha += val;
+            rend = 1;
+        }
+    }
+    else // unsichtbar
+    {
+        if( tAlpha != 0 )
+        {
+            if( tAlpha - val < 0 )
+                tAlpha = 0;
+            else
+                tAlpha -= val;
+            rend = 1;
+        }
+    }
+    if( ( animation | 0x4 ) == animation ) // auswählen
+    {
+        if( beschreibung )
+        {
+            if( alpha != 255 )
+            {
+                if( alpha + val < 255 )
+                    alpha += val;
+                else
+                    alpha = 255;
+                rend = 1;
+            }
+        }
+    }
+    else // abwählen
+    {
+        int a = ( auswahl->getFarbe() >> 24 ) & 0xFF;
+        if( a != 0 )
+        {
+            a -= val;
+            if( a < 0 )
+                a = 0;
+            auswahl->setFarbe( ( ( a << 24 ) & 0xFF000000 ) | ( auswahl->getFarbe() & 0xFFFFFF ) );
+            rend = 1;
+        }
+        if( beschreibung )
+        {
+            if( alpha != 0 )
+            {
+                if( alpha - val > 0 )
+                    alpha -= val;
+                else
+                    alpha = 0;
+                rend = 1;
+            }
+        }
+    }
+    bool ret = rend;
+    rend = 0;
+    return ret;
+}
+
+void KarteDaten::doMausEreignis( MausEreignis &me )
+{
+    me.mx -= gr.x;
+    if( beschreibung )
+        beschreibung->doMausEreignis( me );
+    me.mx += gr.x;
+}
+
+void KarteDaten::render( Bild &zRObj )
+{
+    int x = pos.x;
+    int y = pos.y;
+    int br = gr.x;
+    int hö = gr.y;
+    if( !zRObj.setDrawOptions( x, y, br, hö ) )
+        return;
+    zRObj.setAlpha( tAlpha );
+    rahmen->setSize( br, hö );
+    rahmen->render( zRObj );
+    int rbr = rahmen->getRBreite();
+    if( geladen && hintergrund )
+        zRObj.drawBild( rbr, rbr, br - rbr * 2, hö - rbr * 2, *hintergrund );
+    if( auswAlpha && auswahl )
+    {
+        auswahl->setFarbe( ( auswahl->getFarbe() & 0x00FFFFFF ) | ( auswAlpha << 24 ) );
+        auswahl->setPosition( rbr, rbr );
+        auswahl->setSize( br - rbr * 2, hö - rbr * 2 );
+        auswahl->render( zRObj );
+    }
+    zRObj.releaseDrawOptions();
+    x = br;
+    y = 0;
+    br = 580;
+    hö = 480;
+    if( !zRObj.setDrawOptions( x, y, br, hö ) )
+    {
+        zRObj.releaseAlpha();
+        return;
+    }
+    if( geladen == 2 )
+    {
+        zRObj.setAlpha( alpha );
+        if( beschreibung )
+            beschreibung->render( zRObj );
+        zRObj.releaseAlpha();
+    }
+    zRObj.releaseDrawOptions();
+    zRObj.releaseAlpha();
+}
+
+// constant
+int KarteDaten::getKarteId() const
+{
+    return karteId;
+}
+
+bool KarteDaten::istausgewählt() const
+{
+    return ausgewählt;
+}
+
+// Reference Counting
+KarteDaten *KarteDaten::getThis()
+{
+    ref++;
+    return this;
+}
+
+KarteDaten *KarteDaten::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+// Inhalt der KarteAuswahlFenster Klasse aus KarteAuswahl.h
+// Konstruktor
+KarteAuswahlFenster::KarteAuswahlFenster( Schrift *zSchrift )
+{
+    schrift = zSchrift->getThis();
+    rahmen = new LRahmen();
+    rahmen->setFarbe( 0xFFFFFFFF );
+    rahmen->setRamenBreite( 1 );
+    rahmen->setSize( 760, 500 );
+    members = new RCArray< KarteDaten >();
+    anzahl = 0;
+    animation = 0;
+    auswahl = -1;
+    tickVal = 0;
+    seite = 0;
+    pos = Punkt( 10, 10 );
+    gr = Punkt( 780, 430 );
+    spielId = 0;
+    rend = 0;
+    alpha = 0;
+    ref = 1;
+}
+
+// Destruktor
+KarteAuswahlFenster::~KarteAuswahlFenster()
+{
+    if( schrift )
+        schrift->release();
+    if( rahmen )
+        rahmen->release();
+    if( members )
+        members->release();
+}
+
+// nicht constant
+void KarteAuswahlFenster::setSpielId( int id )
+{
+    spielId = id;
+    members->leeren();
+    anzahl = 0;
+    start();
+}
+
+void KarteAuswahlFenster::setSichtbar( bool sichtbar )
+{
+    if( sichtbar )
+    {
+        animation |= 0x1;
+        start();
+    }
+    else
+    {
+        auswahl = -1;
+        for( int i = seite * 4; i >= 0 && i < anzahl && i < seite * 4 + 4; i++ )
+            members->z( i )->setSichtbar( 0 );
+        animation &= ~0x1;
+    }
+    rend = 1;
+}
+
+void KarteAuswahlFenster::blättern( bool oben )
+{
+    for( int i = seite * 4; i >= 0 && i < anzahl && i < seite * 4 + 4; i++ )
+        members->z( i )->setSichtbar( 0 );
+    seite += oben ? 1 : -1;
+    for( int i = seite * 4; i >= 0 && i < anzahl && i < seite * 4 + 4; i++ )
+    {
+        members->z( i )->setPosition( i % 4 );
+        members->z( i )->setSichtbar( 1 );
+    }
+    auswahl = -1;
+    rend = 1;
+}
+
+void KarteAuswahlFenster::updateListe()
+{
+    if( run )
+        return;
+    start();
+}
+
+void KarteAuswahlFenster::thread()
+{
+    Array< int > *liste = infoKlient->getAccountKarteListe( spielId );
+    if( !liste )
+    {
+        nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( infoKlient->getLetzterFehler() ),
+                                                      new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+        run = 0;
+        return;
+    }
+    int anz = liste->getEintragAnzahl();
+    for( int i = 0; i < anz; i++ )
+    {
+        bool gefunden = 0;
+        for( int j = 0; j < anzahl; j++ )
+        {
+            KarteDaten *tmp = members->z( j );
+            if( liste->hat( i ) && tmp->getKarteId() == liste->get( i ) )
+            {
+                gefunden = 1;
+                break;
+            }
+        }
+        if( !gefunden )
+        {
+            KarteDaten *tmp = new KarteDaten( schrift, liste->hat( i ) ? liste->get( i ) : 0 );
+            members->add( tmp, anzahl );
+            anzahl++;
+        }
+    }
+    if( liste )
+        liste->release();
+    for( int i = 0; i < anzahl; i++ )
+        members->z( i )->updateErlaubt();
+    for( int i = seite * 4; i < anzahl && i >= 0 && i < seite * 4 + 4; i++ )
+    {
+        members->z( i )->setPosition( i % 4 );
+        members->z( i )->setSichtbar();
+    }
+    rend = 1;
+    run = 0;
+}
+
+bool KarteAuswahlFenster::tick( double tickVal )
+{
+    for( int i = 0; i < anzahl; i++ )
+        rend |= members->z( i )->tick( tickVal );
+    this->tickVal += tickVal * 750;
+    int val = ( int )this->tickVal;
+    if( val < 1 )
+    {
+        bool ret = rend;
+        rend = 0;
+        return ret;
+    }
+    if( val > 25 )
+        val = 25;
+    this->tickVal -= val;
+    if( ( animation | 0x1 ) == animation ) // sichtbar
+    {
+        if( alpha < 255 )
+        {
+            if( alpha + val >= 255 )
+            {
+                alpha = 255;
+                for( int i = seite * 4; i < anzahl && i >= 0 && i < seite * 4 + 4; i++ )
+                {
+                    members->z( i )->setPosition( i % 4 );
+                    members->z( i )->setSichtbar( 1 );
+                }
+            }
+            else
+                alpha += val;
+            rend = 1;
+        }
+    }
+    else // unsichtbar
+    {
+        if( alpha > 0 )
+        {
+            if( alpha - val < 0 )
+                alpha = 0;
+            else
+                alpha -= val;
+            rend = 1;
+        }
+    }
+    bool ret = rend;
+    rend = 0;
+    return ret;
+}
+
+void KarteAuswahlFenster::doMausEreignis( MausEreignis &me )
+{
+    if( !members )
+        return;
+    if( pos.x != 10 )
+        return;
+    me.mx -= pos.x;
+    me.my -= pos.y;
+    for( int i = 0; i < anzahl; i++ )
+        members->z( i )->doMausEreignis( me );
+    if( me.mx < 0 || me.my < 0 )
+    {
+        me.mx += pos.x;
+        me.my += pos.y;
+        return;
+    }
+    if( me.mx > 200 || me.my > getAnzahlAufSeite() * 100 )
+    {
+        me.mx += pos.x;
+        me.my += pos.y;
+        return;
+    }
+    if( me.id == ME_RLinks )
+    {
+        int treffer = me.my / 100 + seite * 4;
+        if( treffer >= anzahl )
+        {
+            me.mx += pos.x;
+            me.my += pos.y;
+            return;
+        }
+        if( treffer == auswahl )
+        {
+            me.mx += pos.x;
+            me.my += pos.y;
+            return;
+        }
+        if( auswahl >= 0 )
+            members->z( auswahl )->setAuswahl( 0 );
+        members->z( treffer )->setAuswahl( 1 );
+        auswahl = treffer;
+        rend = 1;
+    }
+    me.mx += pos.x;
+    me.my += pos.y;
+}
+
+void KarteAuswahlFenster::render( Bild &zrObj )
+{
+    int x = pos.x;
+    int y = pos.y;
+    int br = gr.x;
+    int hö = gr.y;
+    if( !zrObj.setDrawOptions( x, y, br, hö ) )
+        return;
+    zrObj.setAlpha( alpha );
+    rahmen->setSize( br, hö );
+    rahmen->render( zrObj );
+    int rbr = rahmen->getRBreite();
+    if( !zrObj.setDrawOptions( rbr, rbr, br - rbr * 2, hö - rbr * 2 ) )
+    {
+        zrObj.releaseDrawOptions();
+        zrObj.releaseAlpha();
+        return;
+    }
+    for( int i = seite * 4; i >= 0 && i < anzahl && i < seite * 4 + 4; i++ )
+        members->z( i )->render( zrObj );
+    zrObj.releaseDrawOptions();
+    if( !anzahl )
+    {
+        Text t = "Dieser Account besitzt momentan noch keine Karten für dieses Spiel.\nBesuche den Shop um neue Karten zu erwerben!";
+        schrift->lock();
+        schrift->setDrawPosition( 10, 10 );
+        schrift->setSchriftSize( 12 );
+        schrift->renderText( &t, zrObj, 0xFFFFFFFF );
+        schrift->unlock();
+    }
+    zrObj.releaseDrawOptions();
+    zrObj.releaseAlpha();
+}
+
+// constant
+int KarteAuswahlFenster::getAnzahl() const
+{
+    return anzahl;
+}
+
+int KarteAuswahlFenster::getSeiteAnzahl() const
+{
+    return ( anzahl / 4.0 == anzahl / 4 ) ? ( anzahl / 4 ) : ( anzahl / 4 + 1 );
+}
+
+int KarteAuswahlFenster::getSeite() const
+{
+    return seite;
+}
+
+int KarteAuswahlFenster::getAnzahlAufSeite() const
+{
+    return ( anzahl < seite * 4 + 4 ) ? ( anzahl - seite * 4 ) : 4;
+}
+
+bool KarteAuswahlFenster::hatAuswahl() const
+{
+    return auswahl != -1;
+}
+
+KarteDaten *KarteAuswahlFenster::getAuswahl() const
+{
+    return members->get( auswahl );
+}
+
+// Reference Counting
+KarteAuswahlFenster *KarteAuswahlFenster::getThis()
+{
+    ref++;
+    return this;
+}
+
+KarteAuswahlFenster *KarteAuswahlFenster::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 105 - 0
KSGClient/NachLogin/Spiele/Karte Auswahl/KarteAuswahl.h

@@ -0,0 +1,105 @@
+#ifndef KarteAuswahl_H
+#define KarteAuswahl_H
+
+#include <Klient.h>
+#include <Bild.h>
+#include <Knopf.h>
+#include <Thread.h>
+#include <KSGScript.h>
+
+using namespace Framework;
+using namespace KSGScript;
+
+class KarteDaten : public Thread
+{
+private:
+	int karteId;
+	Schrift *schrift;
+	Bild *hintergrund;
+    HINSTANCE ksgs;
+	KSGScriptObj *beschreibung;
+	LRahmen *rahmen;
+	double tickVal;
+	int animation;
+	bool ausgewählt;
+	Punkt pos;
+	Punkt gr;
+	int geladen;
+	int aktion;
+	AlphaFeld *auswahl;
+	unsigned char auswAlpha;
+	bool erlaubt;
+	bool rend;
+    unsigned char tAlpha;
+    unsigned char alpha;
+	int ref;
+
+public:
+	// Konstruktor
+	KarteDaten( Schrift *zSchrift, int id );
+	// Destruktor
+	~KarteDaten();
+	// nicht constant
+	virtual void thread();
+	void updateErlaubt();
+    void ksgsAktion( RCArray< KSGSVariable > *parameter, KSGSVariable **retVal );
+	void setSichtbar( bool sichtbar );
+	void setSichtbar();
+	void setAuswahl( bool auswahl );
+	void setPosition( int lPos );
+	bool tick( double tickVal );
+	void doMausEreignis( MausEreignis &me );
+	void render( Bild &zRObj );
+	// constant
+	int getKarteId() const;
+	bool istausgewählt() const;
+	// Reference Counting
+	KarteDaten *getThis();
+	KarteDaten *release();
+};
+
+class KarteAuswahlFenster : private Thread
+{
+private:
+	int anzahl;
+	int auswahl;
+	RCArray< KarteDaten > *members;
+	LRahmen *rahmen;
+	Schrift *schrift;
+	double tickVal;
+	int animation;
+	Punkt pos;
+	Punkt gr;
+	int spielId;
+	int seite;
+	bool rend;
+    unsigned char alpha;
+	int ref;
+
+public:
+	// Konstruktor
+	KarteAuswahlFenster( Schrift *zSchrift );
+	// Destruktor
+	~KarteAuswahlFenster();
+	// nicht constant
+	void setSpielId( int spielId );
+	void setSichtbar( bool sichtbar );
+	void blättern( bool oben );
+	void updateListe();
+	virtual void thread();
+	bool tick( double tickVal );
+	void doMausEreignis( MausEreignis &me );
+	void render( Bild &zrObj );
+	// constant
+	int getAnzahl() const;
+	int getSeiteAnzahl() const;
+	int getSeite() const;
+	int getAnzahlAufSeite() const;
+	bool hatAuswahl() const;
+	KarteDaten *getAuswahl() const;
+	// Reference Counting
+	KarteAuswahlFenster *getThis();
+	KarteAuswahlFenster *release();
+};
+
+#endif

+ 1032 - 0
KSGClient/NachLogin/Spiele/Spiel Auswahl/SpielAuswahl.cpp

@@ -0,0 +1,1032 @@
+#include "SpielAuswahl.h"
+#include <Datei.h>
+#include <Text.h>
+#include <Schrift.h>
+#include <Rahmen.h>
+#include <Punkt.h>
+#include <DateiSystem.h>
+#include "..\..\..\Global\Initialisierung.h"
+#include <AlphaFeld.h>
+#include <MausEreignis.h>
+#include <KSGTDatei.h>
+#include "..\..\..\Global\Variablen.h"
+
+void SpielAuswahlKSGSAktion( void *p, RCArray< KSGSVariable > *parameter, KSGSVariable **retVal )
+{
+    if( !p )
+        return;
+    ( (SpielDaten*)p )->ksgsAktion( parameter, retVal );
+}
+
+// Inhalt der SpielDaten Klasse aus SpielAuswahl.h
+// Konstruktor
+SpielDaten::SpielDaten( Schrift *zSchrift, const char *name, int id )
+    : Thread()
+{
+    beenden = 0;
+    this->name = new Text( name );
+    hintergrund = 0;
+    aAnimation = 0;
+    beschreibung = 0;
+    ksgs = 0;
+    rahmen = new LRahmen();
+    rahmen->setFarbe( 0xFFFFFFFF );
+    rahmen->setRamenBreite( 1 );
+    tickVal = 0;
+    animation = 0;
+    ausgewählt = 0;
+    pos = Punkt( 0, 500 );
+    gr = Punkt( 200, 100 );
+    schrift = zSchrift->getThis();
+    spielId = id;
+    aktion = 1;
+    geladen = 0;
+    erlaubt = 0;
+    auswahl = new AlphaFeld();
+    auswahl->setFarbe( 0x0000FF00 );
+    auswahl->setStrength( 8 );
+    auswahl->setSize( 200, 100 );
+    ladenBild = 0;
+    rend = 0;
+    ref = 1;
+    alpha = 0;
+    tAlpha = 0;
+    start();
+}
+
+// Destruktor
+SpielDaten::~SpielDaten()
+{
+    beenden = 1;
+    if( run )
+        this->warteAufThread( 5000 );
+    if( run )
+        ende();
+    if( schrift )
+        schrift->release();
+    name->release();
+    if( hintergrund )
+        hintergrund->release();
+    if( aAnimation )
+        aAnimation->release();
+    if( beschreibung )
+    {
+        beschreibung->zurücksetzen();
+        beschreibung->release();
+    }
+    if( ksgs )
+    {
+        dllDateien->releaseDLL( "KSGScript.dll" );
+        ksgs = 0;
+    }
+    rahmen->release();
+    auswahl->release();
+}
+
+// nicht constant
+void SpielDaten::ksgsAktion( RCArray< KSGSVariable > *parameter, KSGSVariable **retVal )
+{}
+
+void SpielDaten::setSichtbar( bool sichtbar )
+{
+    if( sichtbar )
+        animation |= 0x1;
+    else
+    {
+        animation &= ~0x1;
+        setAuswahl( 0 );
+        auswahl->setFarbe( auswahl->getFarbe() & 0xFFFFFF );
+    }
+    if( !erlaubt && sichtbar && ausgewählt )
+        updateH->setSichtbar( spielId, 1 );
+    hauptScreen->lock();
+    if( run && aktion == (sichtbar ? 2 : 0) )
+    {
+        hauptScreen->unlock();
+        rend = 1;
+        return;
+    }
+    beenden = 1;
+    if( run )
+        this->warteAufThread( 1000 );
+    if( run )
+        ende();
+    beenden = 0;
+    aktion = sichtbar ? 2 : 0;
+    start();
+    hauptScreen->unlock();
+    rend = 1;
+}
+
+void SpielDaten::setSichtbar()
+{
+    animation |= 1;
+    if( ausgewählt && geladen == 2 )
+    {
+        animation |= 0x4;
+        beschreibung->setPosition( beschreibung->getX(), 0 );
+    }
+    if( !erlaubt && ausgewählt )
+        updateH->setSichtbar( spielId, 1 );
+    hauptScreen->lock();
+    if( geladen != 2 && !( aktion == 2 && run ) )
+    {
+        beenden = 1;
+        if( run )
+            this->warteAufThread( 1000 );
+        if( run )
+            ende();
+        beenden = 0;
+        aktion = 2;
+        start();
+    }
+    hauptScreen->unlock();
+    rend = 1;
+}
+
+void SpielDaten::setAuswahl( bool auswahl )
+{
+    if( ausgewählt == auswahl )
+        return;
+    ausgewählt = auswahl;
+    if( auswahl )
+    {
+        if( aAnimation )
+            aAnimation->setSichtbar( 1 );
+        if( beschreibung && ksgs )
+            beschreibung->neuLaden();
+        animation |= 0x4;
+    }
+    else
+        animation &= ~0x4;
+    if( !erlaubt && ausgewählt )
+        updateH->setSichtbar( spielId, 1 );
+    if( !erlaubt && !ausgewählt )
+        updateH->setSichtbar( spielId, 0 );
+    rend = 1;
+}
+
+void SpielDaten::thread()
+{
+    Text *pfad = new Text( "data/spiele/" );
+    pfad->append( name->getText() );
+    pfad->append( "/data/game.ini" );
+    if( !DateiExistiert( pfad->getThis() ) )
+    {
+        if( !aktion )
+        {
+            if( aAnimation )
+                aAnimation->setSichtbar( 0 );
+            geladen = 0;
+            ausgewählt = 0;
+            hauptScreen->lock();
+            if( aAnimation )
+                aAnimation = aAnimation->release();
+            hauptScreen->unlock();
+            if( hintergrund )
+                hintergrund = hintergrund->release();
+            if( beschreibung )
+            {
+                beschreibung->zurücksetzen();
+                beschreibung = beschreibung->release();
+            }
+            if( ksgs )
+            {
+                dllDateien->releaseDLL( "KSGScript.dll" );
+                ksgs = 0;
+            }
+        }
+        else
+        {
+            if( !hintergrund )
+                hintergrund = new Bild();
+            hintergrund->neuBild( 200, 100, 0xFF000000 );
+            schrift->lock();
+            schrift->setSchriftSize( 12 );
+            schrift->setDrawPosition( 10, 10 );
+            schrift->renderText( name, *hintergrund, 0xFFFFFFFF );
+            schrift->unlock();
+            if( !geladen )
+                geladen = 1;
+            rend = 1;
+            int dgId = infoKlient->getDateiGruppeIdVonSpiel( spielId );
+            if( dgId )
+            {
+                KSGTDatei *dg = new KSGTDatei( "data/dg.ksgt" );
+                dg->laden();
+                bool gefunden = 0;
+                for( int i = 0; i < dg->getZeilenAnzahl(); i++ )
+                {
+                    if( dg->zFeld( i, 0 ) && TextZuInt( dg->zFeld( i, 0 )->getText(), 10 ) == dgId )
+                    {
+                        gefunden = 1;
+                        break;
+                    }
+                }
+                if( !gefunden )
+                {
+                    for( int i = 0; i < dg->getZeilenAnzahl(); i++ )
+                    {
+                        if( dg->zFeld( i, 3 ) && !dg->zFeld( i, 3 )->istGleich( "SOFORT" ) && !dg->zFeld( i, 3 )->istGleich( "NICHT" ) )
+                        {
+                            int platz = TextZuInt( dg->zFeld( i, 3 )->getText(), 10 ) + 1;
+                            Text *plT = new Text();
+                            plT->append( platz );
+                            dg->zFeld( i, 3 )->setText( plT );
+                        }
+                    }
+                    Text *idT = new Text();
+                    idT->append( dgId );
+                    Text *pfad = infoKlient->getDateiGruppePfad( dgId );
+                    if( pfad )
+                    {
+                        RCArray< Text > *zeile = new RCArray< Text >();
+                        zeile->add( idT );
+                        zeile->add( pfad );
+                        zeile->add( new Text( "0" ) );
+                        zeile->add( new Text( "0" ) );
+                        dg->addZeile( 4, zeile );
+                        zeile->release();
+                    }
+                    else
+                        idT->release();
+                }
+                dg->speichern();
+                dg->release();
+            }
+            if( aktion == 2 && !beenden )
+            {
+                if( beschreibung )
+                {
+                    beschreibung->zurücksetzen();
+                    beschreibung = beschreibung->release();
+                }
+                if( !ksgs )
+                    ksgs = dllDateien->ladeDLL( "KSGScript.dll", "data/bin/KSGScript.dll" );
+                if( ksgs )
+                {
+                    KSGSGetZeichnung getKSGScript = (KSGSGetZeichnung)GetProcAddress( ksgs, KSGS_START_FUNKTION );
+                    if( getKSGScript )
+                    {
+                        beschreibung = getKSGScript();
+                        beschreibung->setBildschirmZ( hauptScreen->getThis() );
+                        beschreibung->setSchriftZ( schrift->getThis() );
+                        beschreibung->setSize( 578, 428 );
+                        beschreibung->setRückrufParam( this );
+                        beschreibung->setRückrufFunktion( SpielAuswahlKSGSAktion );
+                        beschreibung->setScriptDatei( "data/script/SpielNichtAktuell.ksgs" );
+                    }
+                    else
+                    {
+                        nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                                      new Text( "Der Einstiegspunkt '" KSGS_START_FUNKTION "' in der DLL-Datei "
+                                                                                "'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+                                                                      new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+                    }
+                }
+                else
+                {
+                    nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                                  new Text( "Die DLL-Datei 'data/bin/KSGScript.dll' konnte nicht geladen werden." ),
+                                                                  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+                }
+                if( beschreibung )
+                    geladen = 2;
+                if( beschreibung && ksgs && ausgewählt )
+                    beschreibung->neuLaden();
+            }
+        }
+        pfad->release();
+        rend = 1;
+        run = 0;
+        return;
+    }
+    Datei *ini = new Datei();
+    ini->setDatei( pfad->getText() );
+    ini->open( Datei::Style::lesen );
+    if( !aktion )
+    {
+        if( aAnimation )
+            aAnimation->setSichtbar( 0 );
+        geladen = 0;
+        ausgewählt = 0;
+        hauptScreen->lock();
+        if( aAnimation )
+            aAnimation = aAnimation->release();
+        hauptScreen->unlock();
+        if( hintergrund )
+            hintergrund = hintergrund->release();
+        if( beschreibung )
+        {
+            beschreibung->zurücksetzen();
+            beschreibung = beschreibung->release();
+        }
+        if( ksgs )
+        {
+            dllDateien->releaseDLL( "KSGScript.dll" );
+            ksgs = 0;
+        }
+        rend = 1;
+    }
+    else
+    {
+        Text *pf = ini->leseZeile();
+        pf->remove( pf->getLength() - 1 );
+        pf->insert( 0, "/bilder/" );
+        pf->insert( 0, name->getText() );
+        pf->insert( 0, "data/spiele/" );
+        if( pf->hat( ".ltdb/" ) )
+        {
+            if( !hintergrund )
+            {
+                LTDBDatei *bildDatei = new LTDBDatei();
+                bildDatei->setDatei( pf->getTeilText( 0, pf->positionVon( ".ltdb" ) + 5 ) );
+                bildDatei->leseDaten( 0 );
+                hintergrund = bildDatei->laden( 0, pf->getTeilText( pf->positionVon( ".ltdb" ) + 6 ) );
+                bildDatei->release();
+            }
+        }
+        else
+        {
+            if( !hintergrund )
+            {
+                LTDBDatei *bildDatei = new LTDBDatei();
+                bildDatei->setDatei( pf->getThis() );
+                bildDatei->leseDaten( 0 );
+                hintergrund = bildDatei->laden( 0, bildDatei->zBildListe()->get( 0 ) );
+                bildDatei->release();
+            }
+        }
+        pf->release();
+        pf = ini->leseZeile();
+        pf->release();
+        pf = ini->leseZeile();
+        pf->remove( pf->getLength() - 1 );
+        pf->insert( 0, "/data/" );
+        pf->insert( 0, name->getText() );
+        pf->insert( 0, "data/spiele/" );
+        Datei *idDatei = new Datei();
+        idDatei->setDatei( pf->getText() );
+        idDatei->open( Datei::Style::lesen );
+        idDatei->lese( (char*)&spielId, 4 );
+        idDatei->close();
+        idDatei->release();
+        pf->release();
+        if( !geladen )
+            geladen = 1;
+        rend = 1;
+        ini->setLPosition( 0, 0 );
+        if( aktion == 2 && !beenden )
+        {
+            pf = ini->leseZeile();
+            pf->remove( pf->getLength() - 1 );
+            pf->insert( 0, "/bilder/" );
+            pf->insert( 0, name->getText() );
+            pf->insert( 0, "data/spiele/" );
+            if( !pf->hat( ".ltdb/" ) )
+            {
+                hauptScreen->lock();
+                if( aAnimation )
+                    aAnimation = aAnimation->release();
+                hauptScreen->unlock();
+                LTDBDatei *add = new LTDBDatei();
+                add->setDatei( pf->getThis() );
+                add->leseDaten( 0 );
+                Animation2DData *ad = new Animation2DData();
+                ad->ladeAnimation( add );
+                ad->setWiederhohlend( 1 );
+                ad->setFPS( 30 );
+                aAnimation = new Animation2D();
+                aAnimation->setSize( 200, 100 );
+                aAnimation->setPosition( 0, 0 );
+                aAnimation->setAnimationDataZ( ad );
+            }
+            pf->release();
+            pf = ini->leseZeile();
+            pf->remove( pf->getLength() - 1 );
+            pf->insert( 0, "/data/" );
+            pf->insert( 0, name->getText() );
+            pf->insert( 0, "data/spiele/" );
+            if( beschreibung )
+            {
+                beschreibung->zurücksetzen();
+                beschreibung = beschreibung->release();
+            }
+            if( !ksgs )
+                ksgs = dllDateien->ladeDLL( "KSGScript.dll", "data/bin/KSGScript.dll" );
+            if( ksgs )
+            {
+                KSGSGetZeichnung getKSGScript = (KSGSGetZeichnung)GetProcAddress( ksgs, KSGS_START_FUNKTION );
+                if( getKSGScript )
+                {
+                    beschreibung = getKSGScript();
+                    beschreibung->setBildschirmZ( hauptScreen->getThis() );
+                    beschreibung->setSchriftZ( schrift->getThis() );
+                    beschreibung->setSize( 578, 428 );
+                    beschreibung->setRückrufParam( this );
+                    beschreibung->setRückrufFunktion( SpielAuswahlKSGSAktion );
+                    beschreibung->setScriptDatei( pf->getText() );
+                }
+                else
+                {
+                    nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                                  new Text( "Der Einstiegspunkt '" KSGS_START_FUNKTION "' in der DLL-Datei "
+                                                                            "'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
+                                                                  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+                }
+            }
+            else
+            {
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                              new Text( "Die DLL-Datei 'data/bin/KSGScript.dll' konnte nicht geladen werden." ),
+                                                              new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+            }
+            pf->release();
+            if( beschreibung )
+                geladen = 2;
+            if( beschreibung && ksgs && ausgewählt )
+                beschreibung->neuLaden();
+            rend = 1;
+        }
+    }
+    pfad->release();
+    ini->close();
+    ini->release();
+    if( !erlaubt )
+        updateErlaubt();
+    aktion = 0;
+    run = 0;
+    rend = 1;
+}
+
+void SpielDaten::updateErlaubt()
+{
+    bool update = erlaubt;
+    erlaubt = 0;
+    KSGTDatei *dgt = new KSGTDatei( "data/dg.ksgt" );
+    dgt->laden();
+    bool ak = 0;
+    int dgId = infoKlient->getDateiGruppeIdVonSpiel( spielId );
+    for( int i = 0; i < dgt->getZeilenAnzahl(); i++ )
+    {
+        if( dgt->zFeld( i, 0 ) && TextZuInt( dgt->zFeld( i, 0 )->getText(), 10 ) == dgId )
+        {
+            int lv = dgt->zFeld( i, 2 ) ? TextZuInt( dgt->zFeld( i, 2 )->getText(), 10 ) : 0;
+            int ov = infoKlient->getSpielVersion( spielId );
+            if( lv == ov )
+                ak = 1;
+            break;
+        }
+    }
+    dgt->release();
+    erlaubt = ak && infoKlient->istSpielErlaubt( spielId );
+    if( !erlaubt && !updateH->hat( spielId ) )
+    {
+        updateH->erstellen( schrift, spielId );
+        if( ausgewählt )
+            updateH->setSichtbar( spielId, 1 );
+    }
+    if( erlaubt && updateH->hat( spielId ) )
+        updateH->remove( spielId, 0 );
+}
+
+void SpielDaten::setPosition( int lPos )
+{
+    pos.y = lPos * 100;
+    rend = 1;
+}
+
+bool SpielDaten::tick( double tickVal )
+{
+    if( beschreibung )
+        rend |= beschreibung->tick( tickVal );
+    if( !erlaubt )
+        rend |= updateH->tick( spielId, tickVal );
+    this->tickVal += tickVal * 500;
+    int val = ( int ) this->tickVal;
+    if( val < 1 )
+    {
+        bool ret = rend;
+        rend = 0;
+        return ret;
+    }
+    if( val > 17 )
+        val = 17;
+    this->tickVal -= val;
+    if( aAnimation && geladen == 2 && aAnimation->istSichtbar() )
+    {
+        if( aAnimation->getJetzt() + 1 >= aAnimation->zAnimationData()->getBildAnzahl() )
+        {
+            rend |= aAnimation->tick( tickVal );
+            if( aAnimation->getJetzt() + 1 < aAnimation->zAnimationData()->getBildAnzahl() )
+                aAnimation->setSichtbar( 0 );
+        }
+        else
+            rend |= aAnimation->tick( tickVal );
+    }
+    if( ausgewählt )
+    {
+        int a = ( auswahl->getFarbe() >> 24 ) & 0xFF;
+        if( a != 150 )
+        {
+            if( a + val > 150 )
+                a = 150;
+            else
+                a += val;
+            auswahl->setFarbe( ( ( a << 24 ) & 0xFF000000 ) | ( auswahl->getFarbe() & 0xFFFFFF ) );
+            rend = 1;
+        }
+    }
+    else
+    {
+        int a = ( auswahl->getFarbe() >> 24 ) & 0xFF;
+        if( a != 0 )
+        {
+            if( a - val < 0 )
+                a = 0;
+            else
+                a -= val;
+            auswahl->setFarbe( ( ( a << 24 ) & 0xFF000000 ) | ( auswahl->getFarbe() & 0xFFFFFF ) );
+            rend = 1;
+        }
+    }
+    if( ( animation | 0x1 ) == animation ) // sichtbar
+    {
+        if( tAlpha != 255 )
+        {
+            if( tAlpha + val > 255 )
+                tAlpha = 255;
+            else
+                tAlpha += val;
+            rend = 1;
+        }
+    }
+    else // unsichtbar
+    {
+        if( tAlpha != 0 )
+        {
+            if( tAlpha - val < 0 )
+                tAlpha = 0;
+            else
+                tAlpha -= val;
+            rend = 1;
+        }
+    }
+    if( geladen == 2 )
+    {
+        if( ( animation | 0x4 ) == animation ) // auswählen
+        {
+            if( beschreibung )
+            {
+                if( alpha != 255 )
+                {
+                    if( alpha + val < 255 )
+                        alpha += val;
+                    else
+                        alpha = 255;
+                    rend = 1;
+                }
+            }
+        }
+        else // abwählen
+        {
+            int a = ( auswahl->getFarbe() >> 24 ) & 0xFF;
+            if( a != 0 )
+            {
+                a -= val;
+                if( a < 0 )
+                    a = 0;
+                auswahl->setFarbe( ( ( a << 24 ) & 0xFF000000 ) | ( auswahl->getFarbe() & 0xFFFFFF ) );
+                rend = 1;
+            }
+            if( beschreibung )
+            {
+                if( alpha != 0 )
+                {
+                    if( alpha - val > 0 )
+                        alpha -= val;
+                    else
+                        alpha = 0;
+                    rend = 1;
+                }
+            }
+        }
+    }
+    bool ret = rend;
+    rend = 0;
+    return ret;
+}
+
+void SpielDaten::doMausEreignis( MausEreignis &me )
+{
+    if( !erlaubt && ausgewählt )
+    {
+        me.mx -= gr.x + 90;
+        me.my -= 350;
+        updateH->doMausEreignis( spielId, me );
+        me.my += 350;
+        me.mx += 90;
+        if( beschreibung )
+            beschreibung->doMausEreignis( me );
+        me.mx += gr.x;
+    }
+}
+
+void SpielDaten::render( Bild &zRObj )
+{
+    int x = pos.x;
+    int y = pos.y;
+    int br = gr.x;
+    int hö = gr.y;
+    if( !zRObj.setDrawOptions( x, y, br, hö ) )
+        return;
+    zRObj.setAlpha( tAlpha );
+    rahmen->setSize( br, hö );
+    int rbr = rahmen->getRBreite();
+    if( geladen && hintergrund && ( !( ausgewählt && geladen == 2 && aAnimation ) || !aAnimation->istSichtbar() ) )
+        zRObj.drawBild( rbr, rbr, br - rbr * 2, hö - rbr * 2, *hintergrund );
+    if( aAnimation )
+        aAnimation->render( zRObj );
+    rahmen->render( zRObj );
+    if( auswahl && ( ( auswahl->getFarbe() >> 24 ) & 0xFF ) && ( !( ausgewählt && geladen == 2 && aAnimation ) || !aAnimation->istSichtbar() ) )
+    {
+        auswahl->setPosition( rbr, rbr );
+        auswahl->setSize( br - rbr * 2, hö - rbr * 2 );
+        auswahl->render( zRObj );
+    }
+    zRObj.releaseDrawOptions();
+    x = br;
+    y = 0;
+    br = 580;
+    hö = 480;
+    if( !zRObj.setDrawOptions( x, y, br, hö ) )
+    {
+        zRObj.releaseAlpha();
+        return;
+    }
+    if( geladen == 2 && beschreibung )
+    {
+        zRObj.setAlpha( alpha );
+        beschreibung->render( zRObj );
+        zRObj.releaseAlpha();
+    }
+    if( !erlaubt )
+        updateH->render( spielId, 90, 350, zRObj );
+    if( ausgewählt && geladen != 2 && ladeAnimation->zAnimationData() )
+    {
+        ladenBild++;
+        if( ladenBild >= ladeAnimation->zAnimationData()->getBildAnzahl() )
+            ladenBild = 0;
+        zRObj.drawBild( 275, 195, 50, 50, *ladeAnimation->zAnimationData()->zBild( ladenBild ) );
+        rend = 1;
+    }
+    zRObj.releaseDrawOptions();
+    zRObj.releaseAlpha();
+}
+
+// constant
+int SpielDaten::getSpielId() const
+{
+    return spielId;
+}
+
+bool SpielDaten::istausgewählt() const
+{
+    return ausgewählt;
+}
+
+Text *SpielDaten::zName() const
+{
+    return name;
+}
+
+bool SpielDaten::istErlaubt() const
+{
+    return erlaubt;
+}
+
+// Reference Counting
+SpielDaten *SpielDaten::getThis()
+{
+    ref++;
+    return this;
+}
+
+SpielDaten *SpielDaten::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}
+
+// Inhalt der SpielAuswahl Klasse aus SpielAuswahl.h
+// Konstruktor
+SpielAuswahlFenster::SpielAuswahlFenster( Schrift *zSchrift )
+    : Thread()
+{
+    schrift = zSchrift->getThis();
+    rahmen = new LRahmen();
+    rahmen->setFarbe( 0xFFFFFFFF );
+    rahmen->setRamenBreite( 1 );
+    rahmen->setSize( 760, 500 );
+    members = new RCArray< SpielDaten >();
+    anzahl = 0;
+    animation = 0;
+    auswahl = -1;
+    tickVal = 0;
+    seite = 0;
+    pos = Punkt( 10, 10 );
+    gr = Punkt( 780, 430 );
+    rend = 0;
+    ref = 1;
+    alpha = 0;
+    start();
+}
+
+// Destruktor
+SpielAuswahlFenster::~SpielAuswahlFenster()
+{
+    if( run )
+    {
+        warteAufThread( 5000 );
+        ende();
+    }
+    if( schrift )
+        schrift->release();
+    if( rahmen )
+        rahmen->release();
+    if( members )
+        members->release();
+}
+
+// nicht constant
+void SpielAuswahlFenster::setSichtbar( bool sichtbar )
+{
+    if( sichtbar )
+    {
+        animation |= 0x1;
+        start();
+    }
+    else
+    {
+        auswahl = -1;
+        for( int i = seite * 4; i >= 0 && i < anzahl && i < seite * 4 + 4; i++ )
+            members->z( i )->setSichtbar( 0 );
+        animation &= ~0x1;
+    }
+    rend = 1;
+}
+
+void SpielAuswahlFenster::blättern( bool oben )
+{
+    for( int i = seite * 4; i >= 0 && i < anzahl && i < seite * 4 + 4; i++ )
+        members->z( i )->setSichtbar( 0 );
+    seite += oben ? 1 : -1;
+    for( int i = seite * 4; i >= 0 && i < anzahl && i < seite * 4 + 4; i++ )
+    {
+        members->z( i )->setPosition( i % 4 );
+        members->z( i )->setSichtbar( 1 );
+    }
+    auswahl = -1;
+    rend = 1;
+}
+
+void SpielAuswahlFenster::updateListe()
+{
+    if( run )
+        return;
+    start();
+}
+
+void SpielAuswahlFenster::thread()
+{
+    Array< int > *liste = infoKlient->getAccountSpielArtListe();
+    if( !liste )
+    {
+        nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( infoKlient->getLetzterFehler() ),
+                                                      new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+        run = 0;
+        return;
+    }
+    int anz = liste->getEintragAnzahl();
+    for( int i = 0; i < anz; i++ )
+    {
+        Text *name = infoKlient->getSpielName( liste->hat( i ) ? liste->get( i ) : 0 );
+        if( name )
+        {
+            bool gefunden = 0;
+            for( int j = 0; j < anzahl; j++ )
+            {
+                SpielDaten *tmp = members->z( j );
+                if( liste->hat( i ) && tmp->getSpielId() == liste->get( i ) )
+                {
+                    gefunden = 1;
+                    break;
+                }
+            }
+            if( !gefunden )
+            {
+                SpielDaten *tmp = new SpielDaten( schrift, name->getText(), liste->hat( i ) ? liste->get( i ) : 0 );
+                members->add( tmp, anzahl );
+                anzahl++;
+            }
+            name->release();
+        }
+    }
+    if( liste )
+        liste->release();
+    for( int i = 0; i < anzahl; i++ )
+        members->z( i )->updateErlaubt();
+    for( int i = seite * 4; i < anzahl && i >= 0 && i < seite * 4 + 4; i++ )
+    {
+        members->z( i )->setPosition( i % 4 );
+        members->z( i )->setSichtbar();
+    }
+    rend = 1;
+    run = 0;
+}
+
+bool SpielAuswahlFenster::tick( double tickVal )
+{
+    for( int i = 0; i < anzahl; i++ )
+        rend |= members->z( i )->tick( tickVal );
+    this->tickVal += tickVal * 750;
+    int val = ( int )this->tickVal;
+    if( val < 1 )
+    {
+        bool ret = rend;
+        rend = 0;
+        return ret;
+    }
+    if( val > 25 )
+        val = 25;
+    this->tickVal -= val;
+    if( ( animation | 0x1 ) == animation ) // sichtbar
+    {
+        if( alpha < 255 )
+        {
+            if( alpha + val >= 255 )
+            {
+                alpha = 255;
+                for( int i = seite * 4; i < anzahl && i >= 0 && i < seite * 4 + 4; i++ )
+                {
+                    members->z( i )->setPosition( i % 4 );
+                    members->z( i )->setSichtbar( 1 );
+                }
+            }
+            else
+                alpha += val;
+            rend = 1;
+        }
+    }
+    else // unsichtbar
+    {
+        if( alpha > 0 )
+        {
+            if( alpha - val < 0 )
+                alpha = 0;
+            else
+                alpha -= val;
+            rend = 1;
+        }
+    }
+    bool ret = rend;
+    rend = 0;
+    return ret;
+}
+
+void SpielAuswahlFenster::doMausEreignis( MausEreignis &me )
+{
+    if( pos.x != 10 )
+        return;
+    me.mx -= pos.x;
+    me.my -= pos.y;
+    for( int i = 0; i < anzahl; i++ )
+        members->z( i )->doMausEreignis( me );
+    if( me.mx < 0 || me.my < 0 )
+    {
+        me.mx += pos.x;
+        me.my += pos.y;
+        return;
+    }
+    if( me.mx > 200 || me.my > getAnzahlAufSeite() * 100 )
+    {
+        me.mx += pos.x;
+        me.my += pos.y;
+        return;
+    }
+    if( me.id == ME_RLinks )
+    {
+        int treffer = me.my / 100 + seite * 4;
+        if( treffer >= anzahl )
+        {
+            me.mx += pos.x;
+            me.my += pos.y;
+            return;
+        }
+        if( treffer == auswahl )
+        {
+            me.mx += pos.x;
+            me.my += pos.y;
+            return;
+        }
+        if( auswahl >= 0 )
+            members->z( auswahl )->setAuswahl( 0 );
+        members->z( treffer )->setAuswahl( 1 );
+        auswahl = treffer;
+        rend = 1;
+    }
+    me.mx += pos.x;
+    me.my += pos.y;
+}
+
+void SpielAuswahlFenster::render( Bild &zrObj )
+{
+    int x = pos.x;
+    int y = pos.y;
+    int br = gr.x;
+    int hö = gr.y;
+    if( !zrObj.setDrawOptions( x, y, br, hö ) )
+        return;
+    zrObj.setAlpha( alpha );
+    rahmen->setSize( br, hö );
+    rahmen->render( zrObj );
+    int rbr = rahmen->getRBreite();
+    if( !zrObj.setDrawOptions( rbr, rbr, br - rbr * 2, hö - rbr * 2 ) )
+    {
+        zrObj.releaseDrawOptions();
+        zrObj.releaseAlpha();
+        return;
+    }
+    for( int i = seite * 4; i >= 0 && i < anzahl && i < seite * 4 + 4; i++ )
+        members->z( i )->render( zrObj );
+    zrObj.releaseDrawOptions();
+    if( !anzahl )
+    {
+        Text t = "Dieser Account besitzt momentan noch keine Spiele.\nBesuche den Shop um neue Spiele zu erwerben!";
+        schrift->lock();
+        schrift->setDrawPosition( 10, 10 );
+        schrift->setSchriftSize( 12 );
+        schrift->renderText( &t, zrObj, 0xFFFFFFFF );
+        schrift->unlock();
+    }
+    zrObj.releaseDrawOptions();
+    zrObj.releaseAlpha();
+}
+
+// constant
+int SpielAuswahlFenster::getAnzahl() const
+{
+    return anzahl;
+}
+
+int SpielAuswahlFenster::getSeiteAnzahl() const
+{
+    return ( anzahl / 4.0 == anzahl / 4 ) ? ( anzahl / 4 ) : ( anzahl / 4 + 1 );
+}
+
+int SpielAuswahlFenster::getSeite() const
+{
+    return seite;
+}
+
+int SpielAuswahlFenster::getAnzahlAufSeite() const
+{
+    return ( anzahl < seite * 4 + 4 ) ? ( anzahl - seite * 4 ) : 4;
+}
+
+bool SpielAuswahlFenster::hatAuswahl() const
+{
+    return auswahl != -1;
+}
+
+SpielDaten *SpielAuswahlFenster::getAuswahl() const
+{
+    return members->get( auswahl );
+}
+
+SpielDaten *SpielAuswahlFenster::zAuswahl() const
+{
+    return members->z( auswahl );
+}
+
+bool SpielAuswahlFenster::istAuswahlErlubt() const
+{
+    return auswahl != -1 && members->z( auswahl )->istErlaubt();
+}
+
+// Reference Counting
+SpielAuswahlFenster *SpielAuswahlFenster::getThis()
+{
+    ref++;
+    return this;
+}
+
+SpielAuswahlFenster *SpielAuswahlFenster::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 113 - 0
KSGClient/NachLogin/Spiele/Spiel Auswahl/SpielAuswahl.h

@@ -0,0 +1,113 @@
+#ifndef SpielAuswahl_H
+#define SpielAuswahl_H
+
+#include <Klient.h>
+#include <Bild.h>
+#include <Thread.h>
+#include <TextFeld.h>
+#include <Animation.h>
+#include <KSGScript.h>
+
+using namespace Framework;
+using namespace KSGScript;
+
+class SpielDaten; // aus dieser Datei
+
+class SpielDaten : public Thread
+{
+private:
+	int spielId;
+	Text *name;
+	Bild *hintergrund;
+	Animation2D *aAnimation;
+	Schrift *schrift;
+    KSGScriptObj *beschreibung;
+    HINSTANCE ksgs;
+	LRahmen *rahmen;
+	double tickVal;
+	int animation;
+	bool ausgewählt;
+	Punkt pos;
+	Punkt gr;
+	int geladen;
+	int aktion;
+	AlphaFeld *auswahl;
+	int ladenBild;
+	bool beenden;
+	bool rend;
+	bool erlaubt;
+    unsigned char tAlpha;
+    unsigned char alpha;
+	int ref;
+
+public:
+	// Konstruktor
+	SpielDaten( Schrift *zSchrift, const char *name, int id );
+	// Destruktor
+	~SpielDaten();
+	// nicht constant
+	virtual void thread();
+    void ksgsAktion( RCArray< KSGSVariable > *parameter, KSGSVariable **retVal );
+	void updateErlaubt();
+	void setSichtbar( bool sichtbar );
+	void setSichtbar();
+	void setAuswahl( bool auswahl );
+	void setPosition( int lPos );
+	bool tick( double tickVal );
+	void doMausEreignis( MausEreignis &me );
+	void render( Bild &zRObj );
+	// constant
+	int getSpielId() const;
+	bool istausgewählt() const;
+	Text *zName() const;
+	bool istErlaubt() const;
+	// Reference Counting
+	SpielDaten *getThis();
+	SpielDaten *release();
+};
+
+class SpielAuswahlFenster : private Thread
+{
+private:
+	int anzahl;
+	int auswahl;
+	RCArray< SpielDaten > *members;
+	LRahmen *rahmen;
+	Schrift *schrift;
+	double tickVal;
+	int animation;
+	Punkt pos;
+	Punkt gr;
+	int seite;
+	bool rend;
+    unsigned char alpha;
+	int ref;
+
+public:
+	// Konstruktor
+	SpielAuswahlFenster( Schrift *zSchrift );
+	// Destruktor
+	~SpielAuswahlFenster();
+	// nicht constant
+	void setSichtbar( bool sichtbar );
+	void blättern( bool oben );
+	void updateListe();
+	virtual void thread();
+	bool tick( double tickVal );
+	void doMausEreignis( MausEreignis &me );
+	void render( Bild &zrObj );
+	// constant
+	int getAnzahl() const;
+	int getSeiteAnzahl() const;
+	int getSeite() const;
+	int getAnzahlAufSeite() const;
+	bool hatAuswahl() const;
+	SpielDaten *getAuswahl() const;
+	SpielDaten *zAuswahl() const;
+	bool istAuswahlErlubt() const;
+	// Reference Counting
+	SpielAuswahlFenster *getThis();
+	SpielAuswahlFenster *release();
+};
+
+#endif

+ 842 - 0
KSGClient/NachLogin/Spiele/Spiele.cpp

@@ -0,0 +1,842 @@
+#include "Spiele.h"
+#include <Rahmen.h>
+#include <Punkt.h>
+#include <DateiSystem.h>
+#include <Text.h>
+#include "..\..\Global\Initialisierung.h"
+#include "..\..\Global\Variablen.h"
+
+// Inhalt der Spiele Klasse aus Spiele.h
+// Konstruktor
+Spiele::Spiele( Schrift *zSchrift, Fenster *zNachLoginFenster, int x )
+	: Zeichnung()
+{
+	bildschirmGröße = BildschirmGröße();
+	pos = Punkt( x, 67 );
+	gr = Punkt( 102, 32 );
+	LTDBDatei *spielenBilder = new LTDBDatei();
+	spielenBilder->setDatei( new Text( "data/client/bilder/spielen.ltdb" ) );
+	spielenBilder->leseDaten( 0 );
+	rahmen = new LRahmen();
+	rahmen->setFarbe( 0xFFFFFFFF );
+	rahmen->setSize( 102, 32 );
+	spielAuswahl = new SpielAuswahlFenster( zSchrift );
+	karteAuswahl = new KarteAuswahlFenster( zSchrift );
+	anmeldung = new AngemeldetFenster( zSchrift );
+	gruppe = new GruppeFenster( zSchrift );
+	teamAuswahl = new TeamAuswahl( zSchrift );
+	statistik = new SpielStatistik( zSchrift );
+	oben = initKnopf( 380, 450, 40, 15, 0, 0, "" );
+	oben->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	oben->setHintergrundBildZ( spielenBilder->laden( 0, new Text( "oben.png" ) ) );
+	initToolTip( oben, "Nach oben umblättern.", zSchrift->getThis(), hauptScreen );
+	links = initKnopf( 360, 450, 15, 40, 0, 0, "" );
+	links->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	links->setHintergrundBildZ( spielenBilder->laden( 0, new Text( "links.png" ) ) );
+	initToolTip( links, "Zurück.", zSchrift->getThis(), hauptScreen );
+	unten = initKnopf( 380, 475, 40, 15, 0, 0, "" );
+	unten->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	unten->setHintergrundBildZ( spielenBilder->laden( 0, new Text( "unten.png" ) ) );
+	initToolTip( unten, "Nach unten umblättern.", zSchrift->getThis(), hauptScreen );
+	rechts = initKnopf( 425, 450, 15, 40, 0, 0, "" );
+	rechts->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	rechts->setHintergrundBildZ( spielenBilder->laden( 0, new Text( "rechts.png" ) ) );
+	initToolTip( rechts, "Weiter.", zSchrift->getThis(), hauptScreen );
+	spielenBilder->release();
+	alpha = 0;
+	ladenAlpha = 0;
+	ladenJetzt = 0;
+	animation = 0;
+	sichtbar = 0;
+	tickVal = 0;
+	tickVal2 = 0;
+	jetzt = 0;
+	prozent1 = 0;
+	prozent2 = 0;
+	prozent3 = 0;
+	prozent4 = 0;
+	prozent5 = 0;
+	prozent6 = 0;
+	spielGefundenB = 0;
+	begPos = Punkt( 0, 0 );
+	begGröße = Punkt( 0, 0 );
+	größe1 = Punkt( 102, 32 );
+	pos1 = Punkt( x, 67 );
+	größe2 = Punkt( 800, 500 );
+	pos2 = bildschirmGröße / 2 - größe2 / 2;
+	größe3 = Punkt( 950, 550 );
+	pos3 = bildschirmGröße / 2 - größe3 / 2;
+	größe4 = Punkt( 700, 600 );
+	pos4 = bildschirmGröße / 2 - größe4 / 2;
+	zNachLoginFenster->addMember( this );
+	ref = 1;
+}
+
+// Destruktor
+Spiele::~Spiele()
+{
+	rahmen->release();
+	spielAuswahl->release();
+	karteAuswahl->release();
+	anmeldung->release();
+	gruppe->release();
+	teamAuswahl->release();
+	statistik->release();
+	oben->release();
+	links->release();
+	unten->release();
+	rechts->release();
+}
+
+// nicht constant
+void Spiele::setSichtbar( bool sicht )
+{
+	begPos = pos;
+	begGröße = gr;
+	animation |= ( sicht ? 0x1 : 0x2 );
+	updateErlaubt();
+	rend = 1;
+}
+
+void Spiele::updateErlaubt()
+{
+	if( sichtbar )
+	{
+		if( jetzt == 1 )
+			spielAuswahl->updateListe();
+		if( jetzt == 2 )
+			karteAuswahl->updateListe();
+	}
+}
+
+void Spiele::anmelden( int karteId )
+{
+	if( anmeldung->setKarteId( karteId ) )
+	{
+		karteAuswahl->setSichtbar( 0 );
+		anmeldung->setSichtbar( 1 );
+		jetzt = 3;
+	}
+}
+
+void Spiele::anmeldungAbbrechen()
+{
+	anmeldung->setSichtbar( 0 );
+	spielAuswahl->setSichtbar( 1 );
+	jetzt = 1;
+}
+
+void Spiele::gruppeBetreten( int gruppeId )
+{
+	begPos = pos;
+	begGröße = gr;
+	größe2 = größe3;
+	pos2 = pos3;
+	gruppe->setGruppeId( gruppeId );
+	gruppe->neuerSpieler( loginKlient->getAccountId() );
+	animation |= 0x4;
+	spielGefundenB = 0;
+}
+
+void Spiele::gruppeVerlassen()
+{
+	begPos = pos;
+	begGröße = gr;
+	größe2.x = 800;
+	größe2.y = 500;
+	pos2 = bildschirmGröße / 2 - größe2 / 2;
+	animation |= 0x8;
+}
+
+void Spiele::spielerBetrittGruppe( int gruppeId, int accountId )
+{
+	if( gruppe->getGruppeId() == gruppeId )
+		gruppe->neuerSpieler( accountId );
+}
+
+void Spiele::spielerVerlässtGruppe( int gruppeId, int accountId )
+{
+	if( gruppe->getGruppeId() == gruppeId )
+		gruppe->spielerVerlässt( accountId );
+}
+
+void Spiele::gruppeNachricht( int gruppeId, char *nachricht )
+{
+	if( gruppe->getGruppeId() == gruppeId )
+		gruppe->chatNachricht( nachricht );
+}
+
+void Spiele::gruppeAnmelden( int gruppeId )
+{
+	if( gruppe->getGruppeId() == gruppeId )
+		gruppe->setAngemeldet( 1 );
+}
+
+void Spiele::gruppeAbmelden( int gruppeId )
+{
+	if( gruppe->getGruppeId() == gruppeId )
+		gruppe->setAngemeldet( 0 );
+}
+
+void Spiele::setGruppeSpielStarten( int gruppeId, bool spielStarten )
+{
+	if( gruppe->getGruppeId() == gruppeId )
+		gruppe->setSpielerHinzufügen( !spielStarten );
+}
+
+void Spiele::setGruppeAdmin( int gruppeId, int admin )
+{
+	if( gruppe->getGruppeId() == gruppeId )
+		gruppe->setAdmin( admin );
+	nachLogin->zFreundesListe()->zeigeEinladeKnopf( admin == loginKlient->getAccountId() );
+}
+
+void Spiele::kickAusGruppe( int gruppeId )
+{
+	if( gruppe->getGruppeId() == gruppeId )
+	{
+		gruppe->kick();
+		gruppeVerlassen();
+	}
+}
+
+void Spiele::gruppeEinladungNeu( int gruppeId, int accountId )
+{
+	if( gruppe->getGruppeId() == gruppeId )
+		gruppe->neueEinladung( accountId );
+}
+
+void Spiele::gruppeEinladungAbgebrochen( int gruppeId, int accountId )
+{
+	if( gruppe->getGruppeId() == gruppeId )
+		gruppe->einladungEntfernt( accountId );
+}
+
+void Spiele::gruppeEinadungAbgelehnt( int gruppeId, int accountId )
+{
+	if( gruppe->getGruppeId() == gruppeId )
+		gruppe->einladungAbgelehnt( accountId );
+}
+
+void Spiele::spielGefunden( int karteId )
+{
+	MausEreignis me;
+	me.id = ME_RLinks;
+	hauptScreen->lock();
+	nachLogin->zTitelLeiste()->druckSpielen( me );
+	hauptScreen->unlock();
+	if( jetzt == 3 )
+		anmeldung->setSpielGefunden();
+	else if( jetzt == 4 )
+		gruppe->spielGefunden();
+	else
+		spielGefundenB = 1;
+}
+
+void Spiele::spielGefundenZeitVerbleibend( int sekunden )
+{
+	if( jetzt == 3 )
+		anmeldung->setVerbleibendeZeit( sekunden );
+	if( jetzt == 4 )
+		gruppe->verbleibendeZeit( sekunden );
+	if( jetzt == 5 )
+		teamAuswahl->verbleibendeZeit( sekunden );
+}
+
+void Spiele::spielGefundenAbbruch()
+{
+	if( jetzt == 3 )
+		anmeldung->spielGefundenAbbruch();
+	if( jetzt == 4 )
+		gruppe->spielGefundenAbbruch();
+}
+
+void Spiele::zurückInWarteschlange( int stunden, int minuten, int sekunden )
+{
+	if( jetzt == 3 )
+		anmeldung->zurückInWarteschlange( stunden, minuten, sekunden );
+	if( jetzt == 4 )
+		gruppe->zurückInWarteschlange( stunden, minuten, sekunden );
+}
+
+void Spiele::teamAuswahlBetreten()
+{
+	begPos = pos;
+	begGröße = gr;
+	größe2 = größe4;
+	pos2 = pos4;
+	animation |= 0x10;
+}
+
+void Spiele::teamAuswahlInit( SpielerTeamStruktur *sts )
+{
+	int karteId = 0;
+	if( jetzt == 3 )
+		karteId = anmeldung->getKarteId();
+	if( jetzt == 4 )
+		karteId = gruppe->getKarteId();
+	teamAuswahl->setKarteId( karteId );
+	teamAuswahl->initSTS( sts );
+}
+
+void Spiele::teamAuswahlAddSpieler( int accountId )
+{
+	teamAuswahl->addSpieler( accountId );
+}
+
+void Spiele::teamAuswahlRemoveSpieler( int accountId )
+{
+	teamAuswahl->removeSpieler( accountId );
+}
+
+void Spiele::teamAuswahlSpielerWehseltTeam( int accountId, int spielerNummer )
+{
+	teamAuswahl->setSpielerNummer( accountId, spielerNummer );
+}
+
+void Spiele::teamAuswahlChatNachricht( char *nachricht )
+{
+	teamAuswahl->addNachricht( nachricht );
+}
+
+void Spiele::teamAuswahlAbbrechen()
+{
+	begPos = pos;
+	begGröße = gr;
+	größe2.x = 800;
+	größe2.y = 500;
+	pos2 = bildschirmGröße / 2 - größe2 / 2;
+	animation |= 0x20;
+}
+
+void Spiele::statistikNachricht( int län, char *bytes )
+{
+	statistik->nachricht( län, bytes );
+}
+
+void Spiele::ladeSpielStatistik( int karteId )
+{
+	pos = pos1;
+	gr = größe1;
+	größe2 = Punkt( 800, 500 );
+	pos2 = bildschirmGröße / 2 - größe2 / 2;
+	teamAuswahl->setSichtbar( 0, 1 );
+	animation = 0;
+	sichtbar = 0;
+	alpha = 0;
+	jetzt = 6;
+	statistik->setSpielArt( infoKlient->getSpielId( karteId ) );
+	setSichtbar( 1 );
+}
+
+bool Spiele::tick( double tickVal )
+{
+	rend |= spielAuswahl->tick( tickVal );
+	rend |= karteAuswahl->tick( tickVal );
+	rend |= anmeldung->tick( tickVal );
+	rend |= gruppe->tick( tickVal );
+	rend |= teamAuswahl->tick( tickVal );
+	rend |= statistik->tick( tickVal );
+	rend |= oben->tick( tickVal );
+	rend |= rechts->tick( tickVal );
+	rend |= unten->tick( tickVal );
+	rend |= links->tick( tickVal );
+	if( jetzt == 6 && !statistik->istSichtbar() )
+	{
+		spielAuswahl->setSichtbar( 1 );
+		jetzt = 1;
+		statistik->reset();
+	}
+	tickVal2 += tickVal;
+	if( tickVal2 >= 1 / 60.0 )
+	{
+		tickVal2 -= 1 / 60.0;
+		if( ladenAlpha && ladeAnimation->zAnimationData() )
+		{
+			rend = 1;
+			ladenJetzt++;
+			if( ladenJetzt >= ladeAnimation->zAnimationData()->getBildAnzahl() )
+				ladenJetzt = 0;
+		}
+	}
+	this->tickVal += tickVal * 150;
+	int val = ( int )this->tickVal;
+	if( val < 1 )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	this->tickVal -= val;
+	if( ( animation | 0x1 ) == animation ) // Einblenden
+	{
+		if( prozent1 != 100 )
+		{
+			prozent1 += val;
+			if( prozent1 >= 100 )
+			{
+				prozent1 = 100;
+				if( !jetzt )
+				{
+					spielAuswahl->setSichtbar( 1 );
+					jetzt = 1;
+				}
+			}
+			pos = begPos + (Punkt)( ( ( Vec2< double > )( pos2 - begPos ) / 100.0 ) * prozent1 );
+			gr = begGröße + (Punkt)( ( ( Vec2< double > )( größe2 - begGröße ) / 100.0 ) * prozent1 );
+		}
+		else if( alpha != 255 )
+		{
+			alpha += val * 2;
+			if( alpha >= 255 || ( animation | 0x2 ) == animation )
+			{
+				alpha = 255;
+				animation &= ~0x1;
+				sichtbar = 1;
+				prozent1 = 0;
+			}
+		}
+		rend = 1;
+	}
+	if( ( animation | 0x2 ) == animation ) // ausblenden
+	{
+		if( alpha != 0 )
+		{
+			alpha -= val * 2;
+			if( alpha < 0 )
+				alpha = 0;
+		}
+		else
+		{
+			prozent2 += val;
+			if( prozent2 > 100 )
+				prozent2 = 100;
+			pos = begPos + (Punkt)( ( ( Vec2< double > )( pos1 - begPos ) / 100.0 ) * prozent2 );
+			gr = begGröße + (Punkt)( ( ( Vec2< double > )( größe1 - begGröße ) / 100.0 ) * prozent2 );
+			if( prozent2 == 100 )
+			{
+				prozent2 = 0;
+				animation &= ~0x2;
+				sichtbar = 0;
+			}
+		}
+		rend = 1;
+	}
+	if( ( animation | 0x4 ) == animation ) // Gruppe betreten
+	{
+		if( ladenAlpha < 255 && !prozent3 )
+		{
+			alpha -= val * 3;
+			if( alpha < 0 )
+				alpha = 0;
+			ladenAlpha += val * 3;
+			if( ladenAlpha >= 255 )
+			{
+				ladenAlpha = 255;
+				if( jetzt == 1 )
+					spielAuswahl->setSichtbar( 0 );
+				if( jetzt == 2 )
+					karteAuswahl->setSichtbar( 0 );
+				if( jetzt == 6 )
+					statistik->verlassen();
+			}
+		}
+		else if( ladenAlpha == 255 && prozent3 != 100 )
+		{
+			prozent3 += val;
+			if( prozent3 >= 100 )
+			{
+				prozent3 = 100;
+				gruppe->setSichtbar( 1 );
+				jetzt = 4;
+				if( spielGefundenB )
+				{
+					spielGefundenB = 0;
+					gruppe->spielGefunden();
+				}
+			}
+			pos = begPos + (Punkt)( ( ( Vec2< double > )( pos3 - begPos ) / 100.0 ) * prozent3 );
+			gr = begGröße + (Punkt)( ( ( Vec2< double > )( größe3 - begGröße ) / 100.0 ) * prozent3 );
+		}
+		else if( prozent3 == 100 )
+		{
+			alpha += val * 3;
+			if( alpha > 255 )
+				alpha = 255;
+			ladenAlpha -= val * 3;
+			if( ladenAlpha <= 0 )
+			{
+				ladenAlpha = 0;
+				animation &= ~0x4;
+				prozent3 = 0;
+			}
+		}
+		rend = 1;
+	}
+	if( ( animation | 0x8 ) == animation ) // Gruppe Verlassen
+	{
+		if( ladenAlpha < 255 && prozent4 == 0 )
+		{
+			alpha -= val * 3;
+			if( alpha < 0 )
+				alpha = 0;
+			ladenAlpha += val * 3;
+			if( ladenAlpha >= 255 )
+			{
+				ladenAlpha = 255;
+				gruppe->setSichtbar( 0 );
+			}
+		}
+		else if( ladenAlpha == 255 && prozent4 != 100 )
+		{
+			prozent4 += val;
+			if( prozent4 >= 100 )
+			{
+				prozent4 = 100;
+				spielAuswahl->setSichtbar( 1 );
+				jetzt = 1;
+			}
+			pos = begPos + (Punkt)( ( ( Vec2< double > )( pos2 - begPos ) / 100.0 ) * prozent4 );
+			gr = begGröße + (Punkt)( ( ( Vec2< double > )( größe2 - begGröße ) / 100.0 ) * prozent4 );
+		}
+		else if( prozent4 == 100 )
+		{
+			alpha += val * 3;
+			if( alpha > 255 )
+				alpha = 255;
+			ladenAlpha -= val * 3;
+			if( ladenAlpha <= 0 )
+			{
+				ladenAlpha = 0;
+				animation &= ~0x8;
+				prozent4 = 0;
+			}
+		}
+		rend = 1;
+	}
+	if( ( animation | 0x10 ) == animation ) // Team Auswahl betreten
+	{
+		if( ladenAlpha < 255 && !prozent5 )
+		{
+			alpha -= val * 3;
+			if( alpha < 0 )
+				alpha = 0;
+			ladenAlpha += val * 3;
+			if( ladenAlpha >= 255 )
+			{
+				ladenAlpha = 255;
+				if( jetzt == 1 )
+					spielAuswahl->setSichtbar( 0 );
+				if( jetzt == 2 )
+					karteAuswahl->setSichtbar( 0 );
+			}
+		}
+		else if( ladenAlpha == 255 && prozent5 != 100 )
+		{
+			prozent5 += val;
+			if( prozent5 >= 100 )
+			{
+				prozent5 = 100;
+				gruppe->setSichtbar( 0 );
+				anmeldung->setSichtbar( 0 );
+				teamAuswahl->setSichtbar( 1 );
+				jetzt = 5;
+			}
+			pos = begPos + (Punkt)( ( ( Vec2< double > )( pos4 - begPos ) / 100.0 ) * prozent5 );
+			gr = begGröße + (Punkt)( ( ( Vec2< double > )( größe4 - begGröße ) / 100.0 ) * prozent5 );
+		}
+		else if( prozent5 == 100 )
+		{
+			alpha += val * 3;
+			if( alpha > 255 )
+				alpha = 255;
+			ladenAlpha -= val * 3;
+			if( ladenAlpha <= 0 )
+			{
+				ladenAlpha = 0;
+				animation &= ~0x10;
+				prozent5 = 0;
+			}
+		}
+		rend = 1;
+	}
+	if( ( animation | 0x20 ) == animation ) // Team Auswahl Verlassen
+	{
+		if( ladenAlpha < 255 && prozent6 == 0 )
+		{
+			alpha -= val * 3;
+			if( alpha < 0 )
+				alpha = 0;
+			ladenAlpha += val * 3;
+			if( ladenAlpha >= 255 )
+			{
+				ladenAlpha = 255;
+				teamAuswahl->setSichtbar( 0 );
+			}
+		}
+		else if( ladenAlpha == 255 && prozent6 != 100 )
+		{
+			prozent6 += val;
+			if( prozent6 >= 100 )
+			{
+				prozent6 = 100;
+				spielAuswahl->setSichtbar( 1 );
+				jetzt = 1;
+			}
+			pos = begPos + (Punkt)( ( ( Vec2< double > )( pos2 - begPos ) / 100.0 ) * prozent6 );
+			gr = begGröße + (Punkt)( ( ( Vec2< double > )( größe2 - begGröße ) / 100.0 ) * prozent6 );
+		}
+		else if( prozent6 == 100 )
+		{
+			alpha += val * 3;
+			if( alpha > 255 )
+				alpha = 255;
+			ladenAlpha -= val * 3;
+			if( ladenAlpha <= 0 )
+			{
+				ladenAlpha = 0;
+				animation &= ~0x20;
+				prozent6 = 0;
+			}
+		}
+		rend = 1;
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void Spiele::doMausEreignis( MausEreignis &me )
+{
+	if( !sichtbar )
+		return;
+	if( animation )
+		return;
+	int mx = me.mx;
+	int my = me.my;
+	me.mx -= pos.x;
+	me.my -= pos.y;
+	int ak = 0;
+	bool tmp = me.verarbeitet;
+	oben->doMausEreignis( me );
+	ak = me.verarbeitet ? 1 : 0;
+	links->doMausEreignis( me );
+	ak = me.verarbeitet && !ak ? 2 : ak;
+	unten->doMausEreignis( me );
+	ak = me.verarbeitet && !ak ? 3 : ak;
+	rechts->doMausEreignis( me );
+	ak = me.verarbeitet && !ak ? 4 : ak;
+	if( tmp )
+		ak = 0;
+	switch( jetzt )
+	{
+	case 1: // Spiel Auswahl
+		if( spielAuswahl )
+		{
+			spielAuswahl->doMausEreignis( me );
+			if( spielAuswahl->hatAuswahl() && spielAuswahl->istAuswahlErlubt() )
+				rechts->addStyle( Knopf::Style::Erlaubt );
+			else
+				rechts->removeStyle( Knopf::Style::Erlaubt );
+			if( !spielAuswahl->getSeite() )
+				oben->removeStyle( Knopf::Style::Erlaubt );
+			else
+				oben->addStyle( Knopf::Style::Erlaubt );
+			if( spielAuswahl->getSeite() < spielAuswahl->getSeiteAnzahl() - 1 )
+				unten->addStyle( Knopf::Style::Erlaubt );
+			else
+				unten->removeStyle( Knopf::Style::Erlaubt );
+			links->removeStyle( Knopf::Style::Erlaubt );
+			if( me.id != ME_RLinks )
+				break;
+			switch( ak )
+			{
+			case 1: // oben Klick
+				spielAuswahl->blättern( 1 );
+				break;
+			case 3: // unten Klick
+				spielAuswahl->blättern( 0 );
+				break;
+			case 4: // rehts Klick
+				if( rechts->hatStyle( Knopf::Style::Erlaubt ) )
+				{
+					karteAuswahl->setSpielId( spielAuswahl->zAuswahl()->getSpielId() );
+					spielAuswahl->setSichtbar( 0 );
+					karteAuswahl->setSichtbar( 1 );
+					jetzt = 2;
+				}
+				break;
+			}
+		}
+		break;
+	case 2: // Karten Auswahl
+		if( karteAuswahl )
+		{
+			karteAuswahl->doMausEreignis( me );
+			rechts->removeStyle( Knopf::Style::Erlaubt );
+			if( !karteAuswahl->getSeite() )
+				oben->removeStyle( Knopf::Style::Erlaubt );
+			else
+				oben->addStyle( Knopf::Style::Erlaubt );
+			if( karteAuswahl->getSeite() < karteAuswahl->getSeiteAnzahl() - 1 )
+				unten->addStyle( Knopf::Style::Erlaubt );
+			else
+				unten->removeStyle( Knopf::Style::Erlaubt );
+			links->addStyle( Knopf::Style::Erlaubt );
+			if( me.id != ME_RLinks )
+				break;
+			switch( ak )
+			{
+			case 1: // oben Klick
+				karteAuswahl->blättern( 1 );
+				break;
+			case 2: // links Klick
+				karteAuswahl->setSichtbar( 0 );
+				spielAuswahl->setSichtbar( 1 );
+				jetzt = 1;
+				break;
+			case 3: // unten Klick
+				karteAuswahl->blättern( 0 );
+				break;
+			}
+		}
+		break;
+	case 3: // Anmeldung
+		anmeldung->doMausEreignis( me );
+		break;
+	case 4: // Gruppe
+		gruppe->doMausEreignis( me );
+		break;
+	case 5: // TeamAuswahl
+		teamAuswahl->doMausEreignis( me );
+		break;
+	case 6:
+		statistik->doMausEreignis( me );
+		break;
+	}
+	me.mx = mx;
+	me.my = my;
+}
+
+void Spiele::doTastaturEreignis( TastaturEreignis &te )
+{
+	if( !sichtbar )
+		return;
+	switch( jetzt )
+	{
+	case 1:
+
+		break;
+	case 2:
+
+		break;
+	case 3:
+
+		break;
+	case 4:
+		gruppe->doTastaturEreignis( te );
+		break;
+	case 5:
+		teamAuswahl->doTastaturEreignis( te );
+		break;
+	case 6:
+		statistik->doTastaturEreignis( te );
+	}
+}
+
+void Spiele::render( Bild &zRObj )
+{
+	if( pos == pos1 )
+		return;
+	int x = pos.x;
+	int y = pos.y;
+	int br = gr.x;
+	int hö = gr.y;
+	if( !zRObj.setDrawOptions( x, y, br, hö ) )
+		return;
+	rahmen->setSize( br, hö );
+	rahmen->render( zRObj );
+	int rbr = rahmen->getRBreite();
+	zRObj.setAlpha( (unsigned char)alpha );
+	if( jetzt == 1 || jetzt == 2 )
+	{
+		oben->render( zRObj );
+		links->render( zRObj );
+		unten->render( zRObj );
+		rechts->render( zRObj );
+	}
+	if( !zRObj.setDrawOptions( rbr, rbr, br - rbr * 2, hö - rbr * 2 ) )
+	{
+		zRObj.releaseDrawOptions();
+		zRObj.releaseAlpha();
+		return;
+	}
+	if( jetzt != 4 && jetzt != 5 )
+	{
+		spielAuswahl->render( zRObj );
+		karteAuswahl->render( zRObj );
+		anmeldung->render( zRObj );
+	}
+	if( jetzt != 5 )
+		gruppe->render( zRObj );
+	teamAuswahl->render( zRObj );
+	statistik->render( zRObj );
+	zRObj.releaseDrawOptions();
+	zRObj.releaseAlpha();
+	if( ladenAlpha && ladeAnimation->zAnimationData() )
+	{
+		zRObj.setAlpha( ladenAlpha );
+		zRObj.drawBild( br / 2 - 25, hö / 2 - 25, 50, 50, *ladeAnimation->zAnimationData()->zBild( ladenJetzt ) );
+		zRObj.releaseAlpha();
+	}
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+bool Spiele::istAnimiert() const
+{
+	return animation != 0;
+}
+
+bool Spiele::istSichtbar() const
+{
+	return sichtbar || prozent1 != 0;
+}
+
+int Spiele::getKarteId() const
+{
+	if( jetzt == 3 )
+		return anmeldung->getKarteId();
+	if( jetzt == 4 )
+		return gruppe->getKarteId();
+	if( jetzt == 5 )
+		return teamAuswahl->getKarteId();
+	return 0;
+}
+
+int Spiele::getGruppeId() const
+{
+	return gruppe->getGruppeId();
+}
+
+SpielerTeamStruktur *Spiele::getSTS() const
+{
+	if( jetzt == 5 )
+		return teamAuswahl->getSTS();
+	return 0;
+}
+
+// Reference Counting
+Spiele *Spiele::getThis()
+{
+	ref++;
+	return this;
+}
+
+Spiele *Spiele::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 115 - 0
KSGClient/NachLogin/Spiele/Spiele.h

@@ -0,0 +1,115 @@
+#ifndef Spiele_H
+#define Spiele_H
+
+#include <Klient.h>
+#include <Fenster.h>
+#include <Knopf.h>
+#include "Spiel Auswahl/SpielAuswahl.h"
+#include "Karte Auswahl/KarteAuswahl.h"
+#include "Angemeldet/Angemeldet.h"
+#include "Gruppe/Gruppe.h"
+#include "Team Auswahl/TeamAuswahl.h"
+#include "Statistik/SpielStatistik.h"
+
+using namespace Framework;
+
+namespace SpieleAnimation
+{
+	const int einfahren = 1;
+	const int ausblenden = 2;
+}
+
+class Spiele : public Zeichnung
+{
+private:
+	int animation;
+	Punkt begPos;
+	Punkt begGröße;
+	Punkt pos1;
+	Punkt größe1;
+	Punkt pos2;
+	Punkt größe2;
+	Punkt pos3;
+	Punkt größe3;
+	Punkt pos4;
+	Punkt größe4;
+	Punkt bildschirmGröße;
+	LRahmen *rahmen;
+	SpielAuswahlFenster *spielAuswahl;
+	KarteAuswahlFenster *karteAuswahl;
+	AngemeldetFenster *anmeldung;
+	GruppeFenster *gruppe;
+	TeamAuswahl *teamAuswahl;
+	SpielStatistik *statistik;
+	Knopf *oben;
+	Knopf *links;
+	Knopf *unten;
+	Knopf *rechts;
+	int alpha;
+	int ladenJetzt;
+	int ladenAlpha;
+	bool sichtbar;
+	int jetzt;
+	int prozent1;
+	int prozent2;
+	int prozent3;
+	int prozent4;
+	int prozent5;
+	int prozent6;
+	double tickVal;
+	double tickVal2;
+	bool spielGefundenB;
+	int ref;
+
+public:
+	// Konstruktor
+	Spiele( Schrift *zSchrift, Fenster *zNachLoginFenster, int x );
+	// Destruktor
+	~Spiele();
+	// nicht constant
+	void setSichtbar( bool sicht );
+	void updateErlaubt();
+	void anmelden( int karteId );
+	void anmeldungAbbrechen();
+	void gruppeBetreten( int gruppeId );
+	void gruppeVerlassen();
+	void spielerBetrittGruppe( int gruppeId, int accountId );
+	void spielerVerlässtGruppe( int gruppeId, int accountId );
+	void gruppeNachricht( int gruppeId, char *nachricht );
+	void gruppeAnmelden( int gruppeId );
+	void gruppeAbmelden( int gruppeId );
+	void setGruppeSpielStarten( int gruppeId, bool spielStarten );
+	void setGruppeAdmin( int gruppeId, int admin );
+	void kickAusGruppe( int gruppeId );
+	void gruppeEinladungNeu( int gruppeId, int accountId );
+	void gruppeEinadungAbgelehnt( int gruppeId, int accountId );
+	void gruppeEinladungAbgebrochen( int gruppeId, int accountId );
+	void spielGefunden( int karteId );
+	void spielGefundenZeitVerbleibend( int sekunden );
+	void spielGefundenAbbruch();
+	void zurückInWarteschlange( int stunden, int minuten, int sekunden );
+	void teamAuswahlBetreten();
+	void teamAuswahlInit( SpielerTeamStruktur *sts );
+	void teamAuswahlAddSpieler( int accountId );
+	void teamAuswahlRemoveSpieler( int accountId );
+	void teamAuswahlSpielerWehseltTeam( int accountId, int spielerNummer );
+	void teamAuswahlChatNachricht( char *nachricht );
+	void teamAuswahlAbbrechen();
+	void statistikNachricht( int län, char *bytes );
+	void ladeSpielStatistik( int karteId );
+	bool tick( double tickVal ) override;
+	void doMausEreignis( MausEreignis &me ) override;
+	void doTastaturEreignis( TastaturEreignis &te ) override;
+	void render( Bild &zRObj ) override;
+	// constant
+	bool istAnimiert() const;
+	bool istSichtbar() const;
+	int getKarteId() const;
+	int getGruppeId() const;
+	SpielerTeamStruktur *getSTS() const;
+	// Reference Counting
+	Spiele *getThis();
+	Spiele *release();
+};
+
+#endif

+ 269 - 0
KSGClient/NachLogin/Spiele/Statistik/SpielStatistik.cpp

@@ -0,0 +1,269 @@
+#include "SpielStatistik.h"
+#include <Punkt.h>
+#include "../../../Global/Variablen.h"
+
+typedef SpielStatistikV* ( *GetStatistikKlasse )( void );
+
+// Inhalt der SpielStatistik Klasse aus SpielStatistik.h
+// Konstruktor
+SpielStatistik::SpielStatistik( Schrift *zSchrift )
+	: pos( 10, 10 ),
+	  gr( 780, 480 )
+{
+	stat = 0;
+	spielDll = 0;
+	la = (Animation2D*)ladeAnimation->dublizieren();
+	la->setPosition( 365, 215 );
+	la->setSichtbar( 0 );
+	schrift = zSchrift->getThis();
+	tickVal = 0;
+	sichtbar = 0;
+	alpha = 0;
+	spielArt = 0;
+	rend = 0;
+	ref = 1;
+}
+
+// Destruktor
+SpielStatistik::~SpielStatistik()
+{
+	if( stat )
+		stat->release();
+	if( spielDll )
+		FreeLibrary( spielDll );
+	la->release();
+	schrift->release();
+}
+
+// nicht constant
+void SpielStatistik::setSpielArt( int spielArt )
+{
+	if( this->spielArt )
+		return;
+	this->spielArt = spielArt;
+	la->setSichtbar( 1 );
+	Text *name = infoKlient->getSpielName( spielArt );
+	if( !name )
+	{
+		this->spielArt = 0;
+		la->setSichtbar( 0 );
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Die Spiel Statistik konnte nicht geladen werden." ), new Text( "Ok" ) );
+		return;
+	}
+	Text *pfad = new Text( "data/spiele/" );
+	pfad->append( name->getText() );
+	pfad->append( "/bin/" );
+	pfad->append( name );
+	pfad->append( ".dll" );
+	spielDll = LoadLibrary( pfad->getText() );
+	pfad->release();
+	if( !spielDll )
+	{
+		this->spielArt = 0;
+		la->setSichtbar( 0 );
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Die Spiel Statistik konnte nicht geladen werden." ), new Text( "Ok" ) );
+		return;
+	}
+	GetStatistikKlasse gsk = (GetStatistikKlasse)GetProcAddress( spielDll, "GetStatistikKlasse" );
+	if( !gsk )
+	{
+		FreeLibrary( spielDll );
+		this->spielArt = 0;
+		la->setSichtbar( 0 );
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Die Spiel Statistik konnte nicht geladen werden." ), new Text( "Ok" ) );
+		return;
+	}
+	stat = gsk();
+	if( !stat )
+	{
+		FreeLibrary( spielDll );
+		this->spielArt = 0;
+		la->setSichtbar( 0 );
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Die Spiel Statistik konnte nicht geladen werden." ), new Text( "Ok" ) );
+		return;
+	}
+	stat->setAccountId( loginKlient->getAccountId() );
+	stat->setBilder( bilder );
+	stat->setRückrufFunktionen( spielStatistikAddNachrichtF, spielStatistikAddChatF, spielStatistikAddFreundF, spielStatistikAccountAnsehenF, spielStatistikIstFreundF, this );
+	stat->setSchrift( schrift->getThis() );
+	stat->setBildschirm( hauptScreen->getThis() );
+	stat->setKlients( infoKlient->getThis(), spielKlient->getThis() );
+	stat->bereit();
+}
+
+void SpielStatistik::nachricht( int län, char *bytes )
+{
+	if( stat )
+		stat->nachricht( län, bytes );
+}
+
+void SpielStatistik::reset()
+{
+	spielArt = 0;
+	la->setSichtbar( 0 );
+	sichtbar = 0;
+	alpha = 0;
+	stat = stat->release();
+	FreeLibrary( spielDll );
+	spielDll = 0;
+}
+
+void SpielStatistik::doMausEreignis( MausEreignis &me )
+{
+	me.mx -= pos.x;
+	me.my -= pos.y;
+	if( stat )
+		stat->doMausEreignis( me );
+	me.mx += pos.x;
+	me.my += pos.y;
+}
+
+void SpielStatistik::doTastaturEreignis( TastaturEreignis &te )
+{
+	if( stat )
+		stat->doTastaturEreignis( te );
+}
+
+bool SpielStatistik::tick( double zeit )
+{
+	if( stat && stat->getStatus() == 1 )
+	{
+		sichtbar = 1;
+		la->setSichtbar( 0 );
+	}
+	else
+		sichtbar = 0;
+	tickVal += zeit * 250;
+	int val = (int)tickVal;
+	if( val > 10 )
+		val = 10;
+	tickVal -= val;
+	if( val )
+	{
+		if( sichtbar && alpha != 255 )
+		{
+			if( alpha + val > 255 )
+				alpha = 255;
+			else
+				alpha += val;
+			rend = 1;
+		}
+		if( !sichtbar && alpha != 0 )
+		{
+			if( alpha - val < 0 )
+				alpha = 0;
+			else
+				alpha -= val;
+			rend = 1;
+		}
+	}
+	if( stat && sichtbar )
+		rend |= stat->tick( zeit );
+	rend |= la->tick( zeit );
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void SpielStatistik::render( Bild &zRObj )
+{
+	if( !zRObj.setDrawOptions( pos, gr ) )
+		return;
+	la->render( zRObj );
+	zRObj.setAlpha( alpha );
+	if( stat )
+		stat->render( zRObj );
+	zRObj.releaseAlpha();
+	zRObj.releaseDrawOptions();
+}
+
+void SpielStatistik::addNachrichtF( Text *t, Text *n, Text *rp, Text *rn, char a, void *ü )
+{
+	nachLogin->zNachrichtenListe()->addNachricht( t, n, rp, rn, a, ü );
+}
+
+void SpielStatistik::addChatF( int acc )
+{
+	nachLogin->zChatLeiste()->addChat( acc, 0 );
+}
+
+void SpielStatistik::addFreundF( int acc )
+{
+	if( !chatKlient->freundesAnfrage( acc ) )
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Die Freundesanfrage konnte nicht gesendet werden." ), new Text( "Ok" ) );
+	else
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Freundesanfrage" ), new Text( "Es wurde eine Freundesanfrage an den Spieler gesendet." ), new Text( "Ok" ) );
+}
+
+void SpielStatistik::accountAnsehenF( int acc )
+{
+	if( nachLogin->zAccountAnsehenFenster()->setSpielerDetails( acc, 2 ) )
+	{
+		MausEreignis me = { ME_RLinks, 0, 0, 0, 0, 0 };
+		nachLogin->zTitelLeiste()->druckAccountAnsehen( me );
+	}
+}
+
+bool SpielStatistik::istFreundF( int acc )
+{
+	return nachLogin->zFreundesListe()->istFreund( acc );
+}
+
+void SpielStatistik::verlassen()
+{
+	if( stat )
+	    stat->verlassen();
+}
+
+// constant
+bool SpielStatistik::istSichtbar()
+{
+	return sichtbar || alpha || la->istSichtbar();
+}
+
+// Reference Counting
+SpielStatistik *SpielStatistik::getThis()
+{
+	ref++;
+	return this;
+}
+
+SpielStatistik *SpielStatistik::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Rückruf Funktionen
+void spielStatistikAddNachrichtF( void *p, Text *t, Text *n, Text *rp, Text *rn, char a, void *ü )
+{
+	if( p )
+		( (SpielStatistik*)p )->addNachrichtF( t, n, rp, rn, a, ü );
+}
+
+void spielStatistikAddChatF( void *p, int acc )
+{
+	if( p )
+		( (SpielStatistik*)p )->addChatF( acc );
+}
+
+void spielStatistikAddFreundF( void *p, int acc )
+{
+	if( p )
+		( (SpielStatistik*)p )->addFreundF( acc );
+}
+
+void spielStatistikAccountAnsehenF( void *p, int acc )
+{
+	if( p )
+		( (SpielStatistik*)p )->accountAnsehenF( acc );
+}
+
+bool spielStatistikIstFreundF( void *p, int acc )
+{
+	if( p )
+		return ( (SpielStatistik*)p )->istFreundF( acc );
+	return 0;
+}

+ 56 - 0
KSGClient/NachLogin/Spiele/Statistik/SpielStatistik.h

@@ -0,0 +1,56 @@
+#ifndef SpielStatistik_H
+#define SpielStatistik_H
+
+#include <SpielStatistikV.h>
+#include <Animation.h>
+
+class SpielStatistik
+{
+private:
+	SpielStatistikV *stat;
+	Punkt pos;
+	Punkt gr;
+	HINSTANCE spielDll;
+	Animation2D *la;
+	Schrift *schrift;
+	double tickVal;
+	bool sichtbar;
+	unsigned char alpha;
+	int spielArt;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	SpielStatistik( Schrift *zSchrift );
+	// Destruktor
+	~SpielStatistik();
+	// nicht constant
+	void setSpielArt( int spielArt );
+	void nachricht( int län, char *bytes );
+	void reset();
+	void doMausEreignis( MausEreignis &me );
+	void doTastaturEreignis( TastaturEreignis &te );
+	bool tick( double zeit );
+	void render( Bild &zRObj );
+	void addNachrichtF( Text *t, Text *n, Text *rp, Text *rn, char a, void *ü );
+	void addChatF( int acc );
+	void addFreundF( int acc );
+	void accountAnsehenF( int acc );
+	bool istFreundF( int acc );
+	void verlassen();
+	// constant
+	bool istSichtbar();
+	// Reference Counting
+	SpielStatistik *getThis();
+	SpielStatistik *release();
+};
+
+// Rückruf Funktionen
+void spielStatistikAddNachrichtF( void *p, Text *t, Text *n, Text *rp, Text *rn, char a, void *ü );
+void spielStatistikAddChatF( void *p, int acc );
+void spielStatistikAddFreundF( void *p, int acc );
+void spielStatistikAccountAnsehenF( void *p, int acc );
+bool spielStatistikIstFreundF( void *p, int acc );
+
+#endif

+ 1133 - 0
KSGClient/NachLogin/Spiele/Team Auswahl/TeamAuswahl.cpp

@@ -0,0 +1,1133 @@
+#include "TeamAuswahl.h"
+#include "..\..\..\Global\Initialisierung.h"
+#include "..\..\..\Global\Variablen.h"
+#include <DateiSystem.h>
+#include <Rahmen.h>
+#include <AlphaFeld.h>
+#include <AuswahlBox.h>
+
+// Inhalt der TeamAuswahlListeSpieler Klasse aus TeamAuswahl.h
+// Konstruktor
+TeamAuswahlListeSpieler::TeamAuswahlListeSpieler( SpielerTeamStruktur *sts, Schrift *zSchrift, int accountId, int karteId )
+{
+	this->accountId = accountId;
+	Text *n = infoKlient->getSpielerName( accountId );
+	name = initTextFeld( 1, 1, 99, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, n->getText() );
+	n->release();
+	if( accountId == loginKlient->getAccountId() )
+	{
+		teamAuswahl = new AuswahlBox();
+		teamAuswahl->setStyle( AuswahlBox::Style::Sichtbar | AuswahlBox::Style::Erlaubt | AuswahlBox::Style::Rahmen | AuswahlBox::Style::MultiStyled | AuswahlBox::Style::MaxHeight | AuswahlBox::Style::VScroll | AuswahlBox::Style::Hintergrund );
+		teamAuswahl->setLinienRahmenFarbe( 0xFFFFFFFF );
+		teamAuswahl->setLinienRahmenBreite( 1 );
+		teamAuswahl->setPosition( 100, 1 );
+		teamAuswahl->setSize( 150, 20 );
+		teamAuswahl->setMaxAuskappHeight( 100 );
+		teamAuswahl->setSchriftZ( zSchrift->getThis() );
+		teamAuswahl->setHintergrundFarbe( 0xFF000000 );
+		teamAuswahl->setMausEreignis( _ret1ME );
+		teamAuswahl->setEventParam( this );
+		teamAuswahl->setEventAktion( TeamAuswahlListeSpielerTeamAuswahlE );
+	}
+	else
+		team = initTextFeld( 100, 1, 150, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "" );
+	Array< int > *statistik = new Array< int >();
+	infoKlient->getSpielStatistik( accountId, infoKlient->getSpielId( karteId ), statistik );
+	punkte = initTextFeld( 250, 1, 80, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Punkte: " );
+	punkte->zText()->append( statistik->hat( 3 ) ? statistik->get( 3 ) : 0 );
+	spiele = initTextFeld( 330, 1, 80, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Spiele: " );
+	spiele->zText()->append( statistik->hat( 0 ) ? statistik->get( 0 ) : 0 );
+	gewonnen = initTextFeld( 410, 1, 90, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Gewonnen: " );
+	gewonnen->zText()->append( statistik->hat( 1 ) ? statistik->get( 1 ) : 0 );
+	statistik->release();
+	farbe = initTextFeld( 500, 1, 50, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Farbe:" );
+	spielerFarbe = 0;
+	rahmen = new LRahmen();
+	rahmen->setSize( 581, 22 );
+	rahmen->setFarbe( 0xFFFFFFFF );
+	rahmen->setRamenBreite( 1 );
+	teamName = new Text( "" );
+	this->sts = sts;
+	rend = 0;
+	ref = 1;
+}
+
+// Destruktor
+TeamAuswahlListeSpieler::~TeamAuswahlListeSpieler()
+{
+	name->release();
+	if( accountId == loginKlient->getAccountId() )
+		teamAuswahl->release();
+	else
+		team->release();
+	punkte->release();
+	spiele->release();
+	gewonnen->release();
+	farbe->release();
+	rahmen->release();
+	teamName->release();
+	sts->release();
+}
+
+// nicht constant
+void TeamAuswahlListeSpieler::disable()
+{
+	if( accountId == loginKlient->getAccountId() )
+		teamAuswahl->removeStyle( AuswahlBox::Style::Erlaubt );
+}
+
+void TeamAuswahlListeSpieler::spielerTeamAuswahlE( AuswahlBox *obj, int p1, int p2 )
+{
+	Text *tmpTeamName = obj->zEintragText( p2 );
+	if( !tmpTeamName->istGleich( teamName->getText() ) )
+	{
+		if( tmpTeamName->istGleich( "Zufällig" ) )
+		{
+			if( !spielKlient->spielErstelltTeamWechseln( 0 ) )
+				obj->setAuswahl( obj->getEintragPos( teamName->getText() ) );
+		}
+		else
+		{
+			int neuTeam = 0;
+			for( int i = 0; i < sts->teamAnzahl; i++ )
+			{
+				if( sts->teamName->z( i )->istGleich( tmpTeamName->getText() ) )
+				{
+					neuTeam = i + 1;
+					break;
+				}
+			}
+			if( !spielKlient->spielErstelltTeamWechseln( neuTeam ) )
+				obj->setAuswahl( obj->getEintragPos( teamName->getText() ) );
+		}
+		obj->einklappen();
+	}
+}
+
+void TeamAuswahlListeSpieler::setFarbe( int farbe )
+{
+	this->spielerFarbe = farbe;
+	if( farbe )
+		rahmen->setFarbe( farbe );
+	else
+		rahmen->setFarbe( 0xFFFFFFFF );
+	rend = 1;
+}
+
+void TeamAuswahlListeSpieler::setTeam( Text *zName )
+{
+	teamName->setText( zName->getText() );
+	rend = 1;
+}
+
+void TeamAuswahlListeSpieler::setTeamErlaubt( Text *zName, bool erlaubt, int teamFarbe )
+{
+	if( accountId != loginKlient->getAccountId() )
+		return;
+	if( erlaubt )
+	{
+		if( teamAuswahl->getEintragPos( zName->getText() ) < 0 )
+		{
+			int p = teamAuswahl->getEintragAnzahl();
+			teamAuswahl->addEintrag( zName->getText() );
+			teamAuswahl->setMsStyle( p, AuswahlBox::Style::FeldRahmen | AuswahlBox::Style::MausBuffer | AuswahlBox::Style::AuswahlBuffer | AuswahlBox::Style::FeldBuffer );
+			if( teamFarbe )
+				teamAuswahl->zEintrag( p )->setLinienRahmenFarbe( teamFarbe );
+			teamAuswahl->setMsAuswAlphaFeldFarbe( p, 0x50000000 | ( teamFarbe & 0x00FFFFFF ) );
+			teamAuswahl->setMsAuswAlphaFeldStrength( p, -15 );
+			teamAuswahl->setMsMausAlphaFeldFarbe( p, 0x10000000 | ( teamFarbe & 0x00FFFFFF ) );
+			teamAuswahl->setMsMausAlphaFeldStrength( p, -15 );
+		}
+	}
+	else
+	{
+		if( zName->istGleich( teamName->getText() ) )
+			return;
+		if( teamAuswahl->getEintragPos( zName->getText() ) >= 0 )
+			teamAuswahl->removeEintrag( teamAuswahl->getEintragPos( zName->getText() ) );
+	}
+}
+
+bool TeamAuswahlListeSpieler::tick( double tickVal )
+{
+	if( accountId == loginKlient->getAccountId() )
+		rend |= teamAuswahl->tick( tickVal );
+	else if( !team->zText()->istGleich( teamName->getText() ) )
+	{
+		team->setText( "" );
+		team->zText()->append( teamName->getText() );
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void TeamAuswahlListeSpieler::doMausEreignis( MausEreignis &me )
+{
+	if( accountId == loginKlient->getAccountId() )
+		teamAuswahl->doMausEreignis( me );
+}
+
+void TeamAuswahlListeSpieler::render( int yOff, Bild &zRObj )
+{
+	if( !zRObj.setDrawOptions( 0, yOff, 581, 22 ) )
+		return;
+	rahmen->render( zRObj );
+	name->render( zRObj );
+	if( loginKlient->getAccountId() == accountId )
+		teamAuswahl->render( zRObj );
+	else
+		team->render( zRObj );
+	punkte->render( zRObj );
+	spiele->render( zRObj );
+	gewonnen->render( zRObj );
+	farbe->render( zRObj );
+	zRObj.alphaRegion( 550, 2, 18, 18, spielerFarbe );
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+int TeamAuswahlListeSpieler::getAccountId() const
+{
+	return accountId;
+}
+
+// Reference Counting
+TeamAuswahlListeSpieler *TeamAuswahlListeSpieler::getThis()
+{
+	ref++;
+	return this;
+}
+
+TeamAuswahlListeSpieler *TeamAuswahlListeSpieler::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Inhalt der TeamAuswahlListeTeam Klasse aus TeamAuswahl.h
+// Konstruktor
+TeamAuswahlListeTeam::TeamAuswahlListeTeam( Schrift *zSchrift )
+{
+	maxSpieler = 0;
+	jetztSpieler = 0;
+	team = 0;
+	name = initTextFeld( 0, 0, 300, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Team: " );
+	mjSpieler = initTextFeld( 300, 0, 150, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Spieler: 0/0" );
+	farbe = initTextFeld( 450, 0, 100, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Team Farbe:" );
+	teamFarbe = 0;
+	spieler = new RCArray< TeamAuswahlListeSpieler >();
+	rahmen = new LRahmen();
+	rahmen->setSize( 583, 22 );
+	rahmen->setFarbe( 0xFFFFFFFF );
+	rahmen->setRamenBreite( 1 );
+	titelAf = new AlphaFeld();
+	titelAf->setPosition( 1, 1 );
+	titelAf->setSize( 581, 20 );
+	titelAf->setFarbe( 0x1000FF00 );
+	titelAf->setStrength( -15 );
+	teamName = new Text( "" );
+	tickVal = 0;
+	höhe = 22;
+	rend = 0;
+	ref = 1;
+}
+
+// Destruktor
+TeamAuswahlListeTeam::~TeamAuswahlListeTeam()
+{
+	name->release();
+	mjSpieler->release();
+	farbe->release();
+	spieler->release();
+	rahmen->release();
+	titelAf->release();
+	teamName->release();
+}
+
+// nicht constant
+void TeamAuswahlListeTeam::disable()
+{
+	for( int i = 0; i < jetztSpieler; i++ )
+		spieler->z( i )->disable();
+}
+
+void TeamAuswahlListeTeam::setMaxSpieler( int maxSpieler )
+{
+	this->maxSpieler = maxSpieler;
+	rend = 1;
+}
+
+void TeamAuswahlListeTeam::setName( Text *name )
+{
+	teamName->setText( name->getText() );
+	name->release();
+	rend = 1;
+}
+
+void TeamAuswahlListeTeam::setFarbe( int farbe )
+{
+	teamFarbe = farbe;
+	rahmen->setFarbe( teamFarbe );
+	rend = 1;
+}
+
+void TeamAuswahlListeTeam::setTeam( int team )
+{
+	this->team = team;
+	rend = 1;
+}
+
+void TeamAuswahlListeTeam::addSpieler( TeamAuswahlListeSpieler *spieler )
+{
+	if( !jetztSpieler )
+		höhe++;
+	spieler->setTeam( teamName );
+	höhe += 22;
+	this->spieler->set( spieler, jetztSpieler );
+	jetztSpieler++;
+	rend = 1;
+}
+
+void TeamAuswahlListeTeam::removeSpieler( int accountId )
+{
+	höhe -= 22;
+	for( int i = 0; i < jetztSpieler; i++ )
+	{
+		if( spieler->z( i )->getAccountId() == accountId )
+		{
+			jetztSpieler--;
+			spieler->remove( i );
+			rend = 1;
+			break;
+		}
+	}
+	if( !jetztSpieler )
+		höhe = 22;
+}
+
+void TeamAuswahlListeTeam::setTeamErlaubt( Text *zName, bool erlaubt, int teamFarbe )
+{
+	for( int i = 0; i < jetztSpieler; i++ )
+		spieler->z( i )->setTeamErlaubt( zName, erlaubt, teamFarbe );
+}
+
+bool TeamAuswahlListeTeam::tick( double tickVal )
+{
+	this->tickVal += tickVal * 50;
+	int val = ( int )this->tickVal;
+	if( val > 2 )
+		val = 2;
+	this->tickVal -= val;
+	if( val )
+	{
+		if( rahmen->getHeight() > höhe )
+		{
+			rahmen->setSize( rahmen->getBreite(), rahmen->getHeight() - val );
+			if( rahmen->getHeight() < höhe )
+				rahmen->setSize( rahmen->getBreite(), höhe );
+			rend = 1;
+		}
+		if( rahmen->getHeight() < höhe )
+		{
+			rahmen->setSize( rahmen->getBreite(), rahmen->getHeight() + val );
+			if( rahmen->getHeight() > höhe )
+				rahmen->setSize( rahmen->getBreite(), höhe );
+			rend = 1;
+		}
+	}
+	name->setText( "Team: " );
+	name->zText()->append( teamName->getText() );
+	mjSpieler->setText( "Spieler: " );
+	mjSpieler->zText()->append( jetztSpieler );
+	mjSpieler->zText()->append( "/" );
+	mjSpieler->zText()->append( maxSpieler );
+	for( int i = 0; i < jetztSpieler; i++ )
+		rend |= spieler->z( i )->tick( tickVal );
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void TeamAuswahlListeTeam::doMausEreignis( MausEreignis &me )
+{
+	int tmpX = me.mx;
+	int tmpY = me.my;
+	me.mx--;
+	me.my -= 22;
+	for( int i = 0; i < jetztSpieler; i++ )
+	{
+		spieler->z( i )->doMausEreignis( me );
+		me.my -= 22;
+	}
+	me.mx = tmpX;
+	me.my = tmpY;
+}
+
+void TeamAuswahlListeTeam::render( int yOff, Bild &zRObj )
+{
+	if( !zRObj.setDrawOptions( 50, yOff, 583, rahmen->getHeight() + 1 ) )
+		return;
+	rahmen->render( zRObj );
+	titelAf->setPosition( 1, 1 );
+	titelAf->render( zRObj );
+	name->render( zRObj );
+	mjSpieler->render( zRObj );
+	farbe->render( zRObj );
+	zRObj.alphaRegion( 550, 2, 18, 18, teamFarbe );
+	zRObj.drawLinieH( 1, 21, 581, rahmen->getFarbe() );
+	if( !zRObj.setDrawOptions( 1, 22, 582, rahmen->getHeight() ) )
+	{
+		zRObj.releaseDrawOptions();
+		return;
+	}
+	int y = 22 * ( jetztSpieler - 1 );
+	for( int i = jetztSpieler - 1; i >= 0; i-- )
+	{
+		spieler->z( i )->render( y, zRObj );
+		y -= 22;
+	}
+	zRObj.releaseDrawOptions();
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+int TeamAuswahlListeTeam::getTeamNummer() const
+{
+	return team;
+}
+
+int TeamAuswahlListeTeam::getHeight() const
+{
+	return rahmen->getHeight() + 1;
+}
+
+bool TeamAuswahlListeTeam::istPlatzFrei() const
+{
+	return jetztSpieler < maxSpieler;
+}
+
+int TeamAuswahlListeTeam::getMaxSpieler() const
+{
+	return maxSpieler;
+}
+
+Text *TeamAuswahlListeTeam::zName() const
+{
+	return teamName;
+}
+
+TeamAuswahlListeSpieler *TeamAuswahlListeTeam::getSpielerDaten( int accountId ) const
+{
+	for( int i = 0; i < jetztSpieler; i++ )
+	{
+		if( spieler->z( i )->getAccountId() == accountId )
+			return spieler->get( i );
+	}
+	return 0;
+}
+
+TeamAuswahlListeSpieler *TeamAuswahlListeTeam::zSpielerDaten( int accountId ) const
+{
+	for( int i = 0; i < jetztSpieler; i++ )
+	{
+		if( spieler->z( i )->getAccountId() == accountId )
+			return spieler->z( i );
+	}
+	return 0;
+}
+
+// Reference Counting
+TeamAuswahlListeTeam *TeamAuswahlListeTeam::getThis()
+{
+	ref++;
+	return this;
+}
+
+TeamAuswahlListeTeam *TeamAuswahlListeTeam::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Inhalt der TeamAuswahlListe Klasse aus TeamAuswahl.h
+// Konstruktor
+TeamAuswahlListe::TeamAuswahlListe( Schrift *zSchrift, SpielerTeamStruktur *sts, int karteId )
+{
+	rahmen = new LRahmen();
+	rahmen->setSize( 698, 398 );
+	rahmen->setFarbe( 0xFFFFFFFF );
+	rahmen->setRamenBreite( 1 );
+	scroll = new VScrollBar();
+	scroll->update( 0, 396 );
+	scroll->setKlickScroll( 7 );
+	teams = new RCArray< TeamAuswahlListeTeam >();
+	TeamAuswahlListeTeam *zufall = new TeamAuswahlListeTeam( zSchrift );
+	zufall->setTeam( 0 );
+	zufall->setName( new Text( "Zufällig" ) );
+	zufall->setMaxSpieler( sts->spielerAnzahl );
+	teams->set( zufall, 0 );
+	for( int i = 0; i < sts->teamAnzahl; i++ )
+	{
+		TeamAuswahlListeTeam *tmp = new TeamAuswahlListeTeam( zSchrift );
+		tmp->setTeam( i );
+		tmp->setName( sts->teamName->get( i ) );
+		tmp->setFarbe( sts->teamFarbe->hat( i ) ? sts->teamFarbe->get( i ) : 0 );
+		tmp->setMaxSpieler( sts->teamGröße->hat( i ) ? sts->teamGröße->get( i ) : 0 );
+		teams->set( tmp, i + 1 );
+	}
+	teamAnzahl = 1 + sts->teamAnzahl;
+	schrift = zSchrift->getThis();
+	this->karteId = karteId;
+	this->sts = sts;
+	rend = 0;
+	ref = 1;
+}
+
+// Destruktor
+TeamAuswahlListe::~TeamAuswahlListe()
+{
+	rahmen->release();
+	scroll->release();
+	teams->release();
+	schrift->release();
+	sts->release();
+}
+
+// nicht constant
+void TeamAuswahlListe::disable()
+{
+	for( int i = 0; i < teamAnzahl; i++ )
+		teams->z( i )->disable();
+}
+
+void TeamAuswahlListe::setTeamVonSpieler( int accountId, int spielerNummer )
+{
+	if( spielerNummer == 0 )
+	{
+		int neuTeam = 0;
+		int altTeam = 0;
+		for( int j = 0; j < teamAnzahl; j++ )
+		{
+			if( teams->z( j )->zSpielerDaten( accountId ) )
+			{
+				altTeam = j;
+				break;
+			}
+		}
+		TeamAuswahlListeSpieler *tmp = teams->z( altTeam )->getSpielerDaten( accountId );
+		teams->z( altTeam )->removeSpieler( accountId );
+		tmp->setFarbe( 0 );
+		teams->z( neuTeam )->addSpieler( tmp );
+	}
+	else
+	{
+		int team = 0;
+		int max = 0;
+		int min = 0;
+		for( int i = 0; i < sts->teamAnzahl; i++ )
+		{
+			min = max;
+			max += sts->teamGröße->get( i );
+			if( spielerNummer - 1 >= min && spielerNummer - 1 < max )
+			{
+				int neuTeam = i + 1;
+				int altTeam = 0;
+				for( int j = 0; j < teamAnzahl; j++ )
+				{
+					if( teams->z( j )->zSpielerDaten( accountId ) )
+					{
+						altTeam = j;
+						break;
+					}
+				}
+				TeamAuswahlListeSpieler *tmp = teams->z( altTeam )->getSpielerDaten( accountId );
+				teams->z( altTeam )->removeSpieler( accountId );
+				tmp->setFarbe( sts->spielerFarbe->hat( spielerNummer - 1 ) ? sts->spielerFarbe->get( spielerNummer - 1 ) : 0 );
+				teams->z( neuTeam )->addSpieler( tmp );
+				break;
+			}
+		}
+	}
+	for( int i = 0; i < teamAnzahl; i++ )
+	{
+		for( int j = 0; j < teamAnzahl; j++ )
+		{
+			if( i == 0 )
+				teams->z( j )->setTeamErlaubt( teams->z( i )->zName(), teams->z( i )->istPlatzFrei(), 0 );
+			else
+				teams->z( j )->setTeamErlaubt( teams->z( i )->zName(), teams->z( i )->istPlatzFrei(), sts->teamFarbe->hat( i - 1 ) ? sts->teamFarbe->get( i - 1 ) : 0 );
+		}
+	}
+	rend = 1;
+}
+
+void TeamAuswahlListe::addSpieler( int accountId )
+{
+	TeamAuswahlListeSpieler *tmp = new TeamAuswahlListeSpieler( sts->getThis(), schrift, accountId, karteId );
+	for( int i = 0; i < teamAnzahl; i++ )
+	{
+		if( teams->z( i )->istPlatzFrei() )
+		{
+			if( i == 0 )
+				tmp->setTeamErlaubt( teams->z( i )->zName(), 1, 0 );
+			else
+				tmp->setTeamErlaubt( teams->z( i )->zName(), 1, sts->teamFarbe->hat( i - 1 ) ? sts->teamFarbe->get( i - 1 ) : 0 );
+		}
+	}
+	teams->z( 0 )->addSpieler( tmp );
+	for( int i = 0; i < teamAnzahl; i++ )
+		teams->z( i )->setTeamErlaubt( teams->z( 0 )->zName(), teams->z( 0 )->istPlatzFrei(), 0 );
+	rend = 1;
+}
+
+void TeamAuswahlListe::removeSpieler( int accountId )
+{
+	for( int i = 0; i < teamAnzahl; i++ )
+	{
+		if( teams->z( i )->zSpielerDaten( accountId ) )
+			teams->z( i )->removeSpieler( accountId );
+	}
+	for( int i = 0; i < teamAnzahl; i++ )
+	{
+		for( int j = 0; j < teamAnzahl; j++ )
+		{
+			if( i == 0 )
+				teams->z( j )->setTeamErlaubt( teams->z( i )->zName(), teams->z( i )->istPlatzFrei(), 0 );
+			else
+				teams->z( j )->setTeamErlaubt( teams->z( i )->zName(), teams->z( i )->istPlatzFrei(), sts->teamFarbe->hat( i - 1 ) ? sts->teamFarbe->get( i - 1 ) : 0 );
+		}
+	}
+	rend = 1;
+}
+
+bool TeamAuswahlListe::tick( double tickVal )
+{
+	for( int i = 0; i < teamAnzahl; i++ )
+		rend |= teams->z( i )->tick( tickVal );
+	rend |= scroll->getRend();
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void TeamAuswahlListe::doMausEreignis( MausEreignis &me )
+{
+	int tmpX = me.mx;
+	int tmpY = me.my;
+	me.mx -= 50;
+	me.my -= 50 - scroll->getScroll();
+	for( int i = 0; i < teamAnzahl; i++ )
+	{
+		teams->z( i )->doMausEreignis( me );
+		me.my -= 20 + teams->z( i )->getHeight();
+	}
+	me.mx = tmpX;
+	me.my = tmpY;
+	if( me.mx > 1 && me.mx < 698 && me.my > 1 && me.my < 397 )
+	{
+		scroll->doMausMessage( 683, 1, 15, 396, me );
+		me.verarbeitet = 1;
+	}
+}
+
+void TeamAuswahlListe::render( Bild &zRObj )
+{
+	if( !zRObj.setDrawOptions( 0, 0, 698, 398 ) )
+		return;
+	rahmen->render( zRObj );
+	int maxHöhe = 50;
+	for( int i = 0; i < teamAnzahl; i++ )
+		maxHöhe += 20 + teams->z( i )->getHeight();
+	maxHöhe += 30;
+	scroll->update( maxHöhe, 396 );
+	scroll->render( 683, 1, 15, 396, zRObj );
+	if( !zRObj.setDrawOptions( 1, 1, 682, 395 ) )
+	{
+		zRObj.releaseDrawOptions();
+		return;
+	}
+	int y = 50 - scroll->getScroll();
+	for( int i = 0; i < teamAnzahl - 1; i++ )
+		y += 20 + teams->z( i )->getHeight();
+	for( int i = teamAnzahl - 1; i >= 0; i-- )
+	{
+		teams->z( i )->render( y, zRObj );
+		if( i > 0 )
+			y -= 20 + teams->z( i - 1 )->getHeight();
+	}
+	zRObj.releaseDrawOptions();
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+
+// Reference Counting
+TeamAuswahlListe *TeamAuswahlListe::getThis()
+{
+	ref++;
+	return this;
+}
+
+TeamAuswahlListe *TeamAuswahlListe::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Inhalt der TeamAuswahlTimer Klasse aus TeamAuswahl.h
+// Konstruktor
+TeamAuswahlTimer::TeamAuswahlTimer( Schrift *zSchrift )
+{
+	zeit = initTextFeld( 0, 0, 200, 200, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "" );
+	bestätigen = initKnopf( 65, 170, 70, 20, zSchrift, Knopf::Style::Sichtbar, "Fertig" );
+	time = 0;
+	maxTime = 0;
+	grad = 0;
+	rend = 0;
+	ref = 1;
+}
+
+// Destruktor
+TeamAuswahlTimer::~TeamAuswahlTimer()
+{
+	zeit->release();
+	bestätigen->release();
+}
+
+// nicht constant
+void TeamAuswahlTimer::setVerbleibendeZeit( int sekunden )
+{
+	if( !maxTime )
+		maxTime = sekunden;
+	if( time != sekunden )
+		rend = 1;
+	time = sekunden;
+}
+
+bool TeamAuswahlTimer::doMausEreignis( MausEreignis &me )
+{
+	bool vera = me.verarbeitet;
+	bestätigen->doMausEreignis( me );
+	if( !vera && me.verarbeitet && me.id == ME_RLinks )
+	{
+		if( spielKlient->spielErstelltTeamFertig() )
+		{
+			bestätigen->removeStyle( Knopf::Style::Erlaubt );
+			return 1;
+		}
+	}
+	return 0;
+}
+
+bool TeamAuswahlTimer::tick( double tickVal )
+{
+	zeit->setText( "" );
+	zeit->zText()->append( time );
+	grad += ( tickVal * 2 );
+	rend = 1;
+	if( grad > 360 )
+		grad -= 360;
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void TeamAuswahlTimer::render( Bild &zRObj )
+{
+	if( !zRObj.setDrawOptions( 498, 398, 200, 200 ) )
+		return;
+	zeit->render( zRObj );
+	int r = ( maxTime && time ) ? 90 - (int)( 75.0 / ( (double)maxTime / ( maxTime - time ) ) + 0.5 ) : 15;
+	zRObj.drawKreis( 100, 100, 15, 0xFFFF0000 );
+	zRObj.drawKreis( 100, 100, r, 0xFF00FF00 );
+	int x1 = 100 + (int)( sin( grad ) * 15 );
+	int y1 = 100 + (int)( cos( grad ) * 15 );
+	int x2 = 100 + (int)( sin( grad ) * r );
+	int y2 = 100 + (int)( cos( grad ) * r );
+	zRObj.drawLinie( Punkt( x1, y1 ), Punkt( x2, y2 ), 0xFFFFFF00 );
+	bestätigen->render( zRObj );
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+int TeamAuswahlTimer::getZeit() const
+{
+	return time;
+}
+
+// Reference Counting
+TeamAuswahlTimer *TeamAuswahlTimer::getThis()
+{
+	ref++;
+	return this;
+}
+
+TeamAuswahlTimer *TeamAuswahlTimer::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Inhalt der TeamAuswahlChat Klasse aus TeamAuswahl.h
+// Konstruktor
+TeamAuswahlChat::TeamAuswahlChat( Schrift *zSchrift )
+{
+	nachricht = initTextFeld( 2, 178, 472, 20, zSchrift, TextFeld::Style::TextFeld, "" );
+	Bild *sendenBild = bilder->get( "chat.ltdb/senden.png" );
+	if( !sendenBild )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
+		datei->leseDaten( 0 );
+		sendenBild = datei->laden( 0, new Text( "senden.png" ) );
+		datei->release();
+		bilder->add( "chat.ltdb/senden.png", sendenBild->getThis() );
+	}
+	senden = initKnopf( 476, 178, 20, 20, 0, 0, "" );
+	senden->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
+	senden->setHintergrundBildZ( sendenBild );
+	verlauf = initTextFeld( 2, 2, 494, 174, zSchrift, TextFeld::Style::TextGebiet & ~TextFeld::Style::Erlaubt, "" );
+	verlauf->updateVScroll();
+	verlauf->setVertikalKlickScroll( 5 );
+	rahmen = new LRahmen();
+	rahmen->setSize( 498, 200 );
+	rahmen->setFarbe( 0xFFFFFFFF );
+	rahmen->setRamenBreite( 1 );
+	rend = 0;
+	ref = 1;
+}
+
+// Destruktor
+TeamAuswahlChat::~TeamAuswahlChat()
+{
+	nachricht->release();
+	senden->release();
+	verlauf->release();
+	rahmen->release();
+}
+
+// nicht constant
+void TeamAuswahlChat::addNachricht( char *nachricht )
+{
+	verlauf->addZeile( nachricht );
+	verlauf->updateVScroll();
+	rend = 1;
+}
+
+bool TeamAuswahlChat::tick( double tickVal )
+{
+	rend |= verlauf->tick( tickVal );
+	rend |= nachricht->tick( tickVal );
+	rend |= senden->tick( tickVal );
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void TeamAuswahlChat::doMausEreignis( MausEreignis &me )
+{
+	verlauf->doMausEreignis( me );
+	nachricht->doMausEreignis( me );
+	bool ver = !me.verarbeitet;
+	senden->doMausEreignis( me );
+	int aktion = ( ver && me.verarbeitet && me.id == ME_RLinks ) ? 1 : 0;
+	if( aktion == 1 )
+	{ // Nachricht senden
+		if( spielKlient->spielErstelltChatNachricht( nachricht->zText()->getText() ) )
+		{
+			nachricht->setText( "" );
+			nachricht->setAuswahl( 0, 0 );
+			rend = 1;
+		}
+		else
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( spielKlient->getLetzterFehler() ), new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+	}
+}
+
+void TeamAuswahlChat::doTastaturEreignis( TastaturEreignis &te )
+{
+	bool ver = !te.verarbeitet;
+	nachricht->doTastaturEreignis( te );
+	int aktion = ( ver && te.verarbeitet && te.id == TE_Release && te.taste == T_Enter ) ? 1 : 0;
+	if( aktion == 1 )
+	{ // Nachricht senden
+		if( spielKlient->spielErstelltChatNachricht( nachricht->zText()->getText() ) )
+		{
+			nachricht->setText( "" );
+			nachricht->setAuswahl( 0, 0 );
+			rend = 1;
+		}
+		else
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( spielKlient->getLetzterFehler() ), new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+	}
+}
+
+void TeamAuswahlChat::render( Bild &zRObj )
+{
+	if( !zRObj.setDrawOptions( 0, 398, 498, 200 ) )
+		return;
+	rahmen->render( zRObj );
+	verlauf->render( zRObj );
+	nachricht->render( zRObj );
+	senden->render( zRObj );
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+
+// Reference Counting
+TeamAuswahlChat *TeamAuswahlChat::getThis()
+{
+	ref++;
+	return this;
+}
+
+TeamAuswahlChat *TeamAuswahlChat::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Inhalt der TeamAuswahl Klasse aus TeamAuswahl.h
+// Konstruktor
+TeamAuswahl::TeamAuswahl( Schrift *zSchrift )
+{
+	tickVal = 0;
+	animation = 0;
+	sichtbar = 0;
+	alpha = 0;
+	karteId = 0;
+	sts = 0;
+	chat = 0;
+	timer = 0;
+	liste = 0;
+	schrift = zSchrift->getThis();
+	rend = 0;
+	ref = 1;
+}
+
+// Destruktor
+TeamAuswahl::~TeamAuswahl()
+{
+	if( sichtbar )
+		setSichtbar( 0 );
+	if( chat )
+		chat->release();
+	if( timer )
+		timer->release();
+	if( liste )
+		liste->release();
+	if( sts )
+		sts->release();
+}
+
+// nicht constant
+void TeamAuswahl::setKarteId( int karteId )
+{
+	this->karteId = karteId;
+}
+
+void TeamAuswahl::setSichtbar( bool sichtbar, bool sofort )
+{
+	this->sichtbar = sichtbar;
+	if( sichtbar )
+		animation |= 0x1;
+	else
+	{
+		if( sofort )
+			alpha = 0;
+		else
+			animation &= ~0x1;
+	}
+	rend = 1;
+}
+
+void TeamAuswahl::initSTS( SpielerTeamStruktur *sts )
+{
+	hauptScreen->lock();
+	if( this->sts )
+		this->sts->release();
+	this->sts = sts;
+	if( chat )
+		chat = chat->release();
+	if( timer )
+		timer = timer->release();
+	if( liste )
+		liste = liste->release();
+	chat = new TeamAuswahlChat( schrift );
+	timer = new TeamAuswahlTimer( schrift );
+	liste = new TeamAuswahlListe( schrift, sts->getThis(), karteId );
+	hauptScreen->unlock();
+	rend = 1;
+}
+
+void TeamAuswahl::addSpieler( int accountId )
+{
+	if( liste )
+		liste->addSpieler( accountId );
+}
+
+void TeamAuswahl::setSpielerNummer( int accountId, int sNummer )
+{
+	if( liste )
+		liste->setTeamVonSpieler( accountId, sNummer );
+}
+
+void TeamAuswahl::removeSpieler( int accountId )
+{
+	if( liste )
+		liste->removeSpieler( accountId );
+}
+
+void TeamAuswahl::verbleibendeZeit( int sekunden )
+{
+	if( timer )
+		timer->setVerbleibendeZeit( sekunden );
+}
+
+void TeamAuswahl::addNachricht( char *nachricht )
+{
+	if( chat )
+		chat->addNachricht( nachricht );
+}
+
+bool TeamAuswahl::tick( double tickVal )
+{
+	if( !sichtbar && !alpha )
+		return 0;
+	if( chat )
+		rend |= chat->tick( tickVal );
+	if( timer )
+		rend |= timer->tick( tickVal );
+	if( liste )
+		rend |= liste->tick( tickVal );
+	this->tickVal += tickVal * 150;
+	int val = ( int )this->tickVal;
+	if( !val )
+	{
+		bool ret = rend;
+		rend = 0;
+		return ret;
+	}
+	if( val > 5 )
+		val = 5;
+	this->tickVal -= val;
+	if( ( animation | 0x1 ) == animation ) // sichtbar werden
+	{
+		if( alpha != 255 )
+		{
+			if( alpha + val < 255 )
+				alpha += val;
+			else
+				alpha = 255;
+			rend = 1;
+		}
+	}
+	else // unsichtbar werden
+	{
+		if( alpha != 0 )
+		{
+			if( alpha - val >= 0 )
+				alpha -= val;
+			else
+				alpha = 0;
+			rend = 1;
+		}
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+void TeamAuswahl::doMausEreignis( MausEreignis &me )
+{
+	if( !alpha )
+		return;
+	if( liste )
+		liste->doMausEreignis( me );
+	if( chat )
+	{
+		me.my -= 398;
+		chat->doMausEreignis( me );
+		me.mx -= 498;
+		if( timer->doMausEreignis( me ) )
+			liste->disable();
+		me.my += 398;
+		me.mx += 498;
+	}
+}
+
+void TeamAuswahl::doTastaturEreignis( TastaturEreignis &te )
+{
+	if( !alpha )
+		return;
+	if( chat )
+		chat->doTastaturEreignis( te );
+}
+
+void TeamAuswahl::render( Bild &zRObj )
+{
+	if( !alpha )
+		return;
+	if( !zRObj.setDrawOptions( 0, 0, 700, 600 ) )
+		return;
+	zRObj.setAlpha( alpha );
+	if( timer )
+		timer->render( zRObj );
+	if( chat )
+		chat->render( zRObj );
+	if( liste )
+		liste->render( zRObj );
+	zRObj.releaseAlpha();
+	zRObj.releaseDrawOptions();
+}
+
+// constant
+bool TeamAuswahl::istSichtbar() const
+{
+	return sichtbar;
+}
+
+int TeamAuswahl::getKarteId() const
+{
+	return karteId;
+}
+
+SpielerTeamStruktur *TeamAuswahl::getSTS() const
+{
+	return sts->getThis();
+}
+
+// Reference Counting
+TeamAuswahl *TeamAuswahl::getThis()
+{
+	ref++;
+	return this;
+}
+
+TeamAuswahl *TeamAuswahl::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Event Aktionen
+void TeamAuswahlListeSpielerTeamAuswahlE( void *p, AuswahlBox *obj, int p1, int p2 )
+{
+	if( !p )
+		return;
+	( (TeamAuswahlListeSpieler*)p )->spielerTeamAuswahlE( obj, p1, p2 );
+}

+ 238 - 0
KSGClient/NachLogin/Spiele/Team Auswahl/TeamAuswahl.h

@@ -0,0 +1,238 @@
+#ifndef TeamAuswahl_H
+#define TeamAuswahl_H
+
+#include "..\..\..\Strukturen\Strukturen.h"
+#include <MausEreignis.h>
+#include <TastaturEreignis.h>
+#include <Bild.h>
+#include <TextFeld.h>
+#include <Knopf.h>
+#include <Tabelle.h>
+#include <AuswahlBox.h>
+
+using namespace Framework;
+
+class TeamAuswahlListeSpieler
+{
+private:
+	int accountId;
+	TextFeld *name;
+	AuswahlBox *teamAuswahl;
+	TextFeld *team;
+	TextFeld *punkte;
+	TextFeld *spiele;
+	TextFeld *gewonnen;
+	TextFeld *farbe;
+	int spielerFarbe;
+	LRahmen *rahmen;
+	Text *teamName;
+	SpielerTeamStruktur *sts;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	TeamAuswahlListeSpieler( SpielerTeamStruktur *sts, Schrift *zSchrift, int accountId, int karteId );
+	// Destruktor
+	~TeamAuswahlListeSpieler();
+	// nicht constant
+	void disable();
+	void spielerTeamAuswahlE( AuswahlBox *obj, int p1, int p2 );
+	void setFarbe( int farbe );
+	void setTeam( Text *zName );
+	void setTeamErlaubt( Text *zName, bool erlaubt, int teamFarbe );
+	bool tick( double tickVal );
+	void doMausEreignis( MausEreignis &me );
+	void render( int yOff, Bild &zRObj );
+	// constant
+	int getAccountId() const;
+	// Reference Counting
+	TeamAuswahlListeSpieler *getThis();
+	TeamAuswahlListeSpieler *release();
+};
+
+class TeamAuswahlListeTeam
+{
+private:
+	int maxSpieler;
+	int jetztSpieler;
+	int team;
+	TextFeld *name;
+	TextFeld *mjSpieler;
+	TextFeld *farbe;
+	int teamFarbe;
+	RCArray< TeamAuswahlListeSpieler > *spieler;
+	LRahmen *rahmen;
+	AlphaFeld *titelAf;
+	Text *teamName;
+	double tickVal;
+	int höhe;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	TeamAuswahlListeTeam( Schrift *zSchrift );
+	// Destruktor
+	~TeamAuswahlListeTeam();
+	// nicht constant
+	void disable();
+	void setMaxSpieler( int maxSpieler );
+	void setName( Text *name );
+	void setFarbe( int farbe );
+	void setTeam( int team );
+	void addSpieler( TeamAuswahlListeSpieler *spieler );
+	void removeSpieler( int accountId );
+	void setTeamErlaubt( Text *zName, bool erlaubt, int teamFarbe );
+	bool tick( double tickVal );
+	void doMausEreignis( MausEreignis &me );
+	void render( int yOff, Bild &zRObj );
+	// constant
+	int getTeamNummer() const;
+	int getHeight() const;
+	bool istPlatzFrei() const;
+	int getMaxSpieler() const;
+	Text *zName() const;
+	TeamAuswahlListeSpieler *getSpielerDaten( int accountId ) const;
+	TeamAuswahlListeSpieler *zSpielerDaten( int accountId ) const;
+	// Reference Counting
+	TeamAuswahlListeTeam *getThis();
+	TeamAuswahlListeTeam *release();
+};
+
+class TeamAuswahlListe
+{
+private:
+	LRahmen *rahmen;
+	VScrollBar *scroll;
+	RCArray< TeamAuswahlListeTeam > *teams;
+	Schrift *schrift;
+	SpielerTeamStruktur *sts;
+	int teamAnzahl;
+	int karteId;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	TeamAuswahlListe( Schrift *zSchrift, SpielerTeamStruktur *sts, int karteId );
+	// Destruktor
+	~TeamAuswahlListe();
+	// nicht constant
+	void disable();
+	void setTeamVonSpieler( int accountId, int spielerNummer );
+	void addSpieler( int accountId );
+	void removeSpieler( int accountId );
+	bool tick( double tickVal );
+	void doMausEreignis( MausEreignis &me );
+	void render( Bild &zRObj );
+	// constant
+
+	// Reference Counting
+	TeamAuswahlListe *getThis();
+	TeamAuswahlListe *release();
+};
+
+class TeamAuswahlTimer
+{
+private:
+	TextFeld *zeit;
+	Knopf *bestätigen;
+	int time;
+	int maxTime;
+	double grad;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	TeamAuswahlTimer( Schrift *zSchrift );
+	// Destruktor
+	~TeamAuswahlTimer();
+	// nicht constant
+	void setVerbleibendeZeit( int sekunden );
+	bool doMausEreignis( MausEreignis &me );
+	bool tick( double tickVal );
+	void render( Bild &zRObj );
+	// constant
+	int getZeit() const;
+	// Reference Counting
+	TeamAuswahlTimer *getThis();
+	TeamAuswahlTimer *release();
+};
+
+class TeamAuswahlChat
+{
+private:
+	TextFeld *nachricht;
+	Knopf *senden;
+	TextFeld *verlauf;
+	LRahmen *rahmen;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	TeamAuswahlChat( Schrift *zSchrift );
+	// Destruktor
+	~TeamAuswahlChat();
+	// nicht constant
+	void addNachricht( char *nachricht );
+	bool tick( double tickVal );
+	void doMausEreignis( MausEreignis &me );
+	void doTastaturEreignis( TastaturEreignis &te );
+	void render( Bild &zRObj );
+	// constant
+
+	// Reference Counting
+	TeamAuswahlChat *getThis();
+	TeamAuswahlChat *release();
+};
+
+class TeamAuswahl
+{
+private:
+	double tickVal;
+	int animation;
+	bool sichtbar;
+	int karteId;
+	unsigned char alpha;
+	SpielerTeamStruktur *sts;
+	TeamAuswahlChat *chat;
+	TeamAuswahlTimer *timer;
+	TeamAuswahlListe *liste;
+	Schrift *schrift;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	TeamAuswahl( Schrift *zSchrift );
+	// Destruktor
+	~TeamAuswahl();
+	// nicht constant
+	void setKarteId( int karteId );
+	void setSichtbar( bool sichtbar, bool sofort = 0 );
+	void initSTS( SpielerTeamStruktur *sts );
+	void addSpieler( int accountId );
+	void setSpielerNummer( int accountId, int sNummer );
+	void removeSpieler( int accountId );
+	void verbleibendeZeit( int sekunden );
+	void addNachricht( char *nachricht );
+	bool tick( double tickVal );
+	void doMausEreignis( MausEreignis &me );
+	void doTastaturEreignis( TastaturEreignis &te );
+	void render( Bild &zRObj );
+	// constant
+	bool istSichtbar() const;
+	int getKarteId() const;
+	SpielerTeamStruktur *getSTS() const;
+	// Reference Counting
+	TeamAuswahl *getThis();
+	TeamAuswahl *release();
+};
+
+// Event Aktionen
+void TeamAuswahlListeSpielerTeamAuswahlE( void *p, AuswahlBox *obj, int p1, int p2 );
+
+#endif

+ 742 - 0
KSGClient/NachLogin/Titel/TitelLeiste.cpp

@@ -0,0 +1,742 @@
+#include "..\..\Global\Variablen.h"
+#include "TitelLeiste.h"
+#include <DateiSystem.h>
+#include "..\..\Global\Initialisierung.h"
+#include <Punkt.h>
+#include <Datei.h>
+
+// Inhalt der TitelLeisten Klasse aus Titelleiste.h
+// Konstruktor
+TitelLeiste::TitelLeiste( Fenster *zNachLogin, Schrift *zSchrift )
+	: Thread()
+{
+	Bild *goldB = bilder->get( "system.ltdb/gold.jpg" );
+	if( !goldB )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/bilder/system.ltdb" ) );
+		datei->leseDaten( 0 );
+		goldB = datei->laden( 0, new Text( "gold.jpg" ) );
+		datei->release();
+		bilder->add( "system.ltdb/gold.jpg", goldB->getThis() );
+	}
+	Bild *silberB = bilder->get( "system.ltdb/silber.jpg" );
+	if( !silberB )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/bilder/system.ltdb" ) );
+		datei->leseDaten( 0 );
+		silberB = datei->laden( 0, new Text( "silber.jpg" ) );
+		datei->release();
+		bilder->add( "system.ltdb/silber.jpg", silberB->getThis() );
+	}
+	Bild *kupferB = bilder->get( "system.ltdb/kupfer.jpg" );
+	if( !kupferB )
+	{
+		LTDBDatei *datei = new LTDBDatei();
+		datei->setDatei( new Text( "data/bilder/system.ltdb" ) );
+		datei->leseDaten( 0 );
+		kupferB = datei->laden( 0, new Text( "kupfer.jpg" ) );
+		datei->release();
+		bilder->add( "system.ltdb/kupfer.jpg", kupferB->getThis() );
+	}
+	LTDBDatei *bilder = new LTDBDatei();
+	bilder->setDatei( new Text( "data/bilder/system.ltdb" ) );
+	bilder->leseDaten( 0 );
+	closeBild = bilder->laden( 0, new Text( "schließen.png" ) );
+	einstellungenBild = bilder->laden( 0, new Text( "optionen.png" ) );
+	bilder->setDatei( new Text( "data/client/bilder/titel.ltdb" ) );
+	bilder->leseDaten( 0 );
+	logoutBild = bilder->laden( 0, new Text( "logout.png" ) );
+	Bild *hintergrund = bilder->laden( 0, new Text( "titelleiste.jpg" ) );
+	bilder = bilder->release();
+	Punkt bgr = BildschirmGröße();
+	version = initTextFeld( 1, 1, 200, 12, zSchrift, TextFeld::Style::Text | TextFeld::Style::Sichtbar, "client version: " );
+	Datei *vDat = new Datei();
+	vDat->setDatei( new Text( "data/version" ) );
+	vDat->open( Datei::Style::lesen );
+	char clientVersion[ 4 ] = { 0, 0, 0, 0 };
+	vDat->lese( clientVersion, 4 );
+	vDat->close();
+	vDat = vDat->release();
+	version->zText()->append( (int)clientVersion[ 3 ] );
+	version->zText()->append( "." );
+	version->zText()->append( (int)clientVersion[ 2 ] );
+	version->zText()->append( "." );
+	version->zText()->append( (int)clientVersion[ 1 ] );
+	version->zText()->append( "." );
+	version->zText()->append( (int)clientVersion[ 0 ] );
+	close = initKnopf( bgr.x - 23, -1, 22, 22, 0, 0, "" );
+	close->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::KlickBuffer | Knopf::Style::HAlpha | Knopf::Style::Rahmen );
+	close->setLinienRahmenFarbe( 0xFFFFFFFF );
+	close->setLinienRahmenBreite( 1 );
+	close->setHintergrundBildZ( closeBild->getThis() );
+	initToolTip( close, "Kolja-Strohm Games Client beenden.", zSchrift->getThis(), hauptScreen );
+	close->setMausEreignisParameter( this );
+	close->setMausEreignis( titelLeisteSchließenME );
+	einstellungen = initKnopf( bgr.x - 44, -1, 22, 22, 0, 0, "" );
+	einstellungen->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::KlickBuffer | Knopf::Style::HAlpha | Knopf::Style::Rahmen );
+	einstellungen->setLinienRahmenFarbe( 0xFFFFFFFF );
+	einstellungen->setLinienRahmenBreite( 1 );
+	einstellungen->setHintergrundBildZ( einstellungenBild->getThis() );
+	einstellungen->setMausEreignisParameter( this );
+	einstellungen->setMausEreignis( titelLeisteEinstellungenME );
+	initToolTip( einstellungen, "Einstellungen ändern.", zSchrift->getThis(), hauptScreen );
+	logout = initKnopf( bgr.x - 65, -1, 22, 22, 0, 0, "" );
+	logout->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::KlickBuffer | Knopf::Style::HAlpha | Knopf::Style::Rahmen );
+	logout->setLinienRahmenFarbe( 0xFFFFFFFF );
+	logout->setLinienRahmenBreite( 1 );
+	logout->setHintergrundBildZ( logoutBild->getThis() );
+	logout->setMausEreignisParameter( this );
+	logout->setMausEreignis( titelLeisteLogoutME );
+	initToolTip( logout, "Ausloggen.", zSchrift->getThis(), hauptScreen );
+	news = initKnopf( bgr.x - 103, 67, 102, 32, zSchrift, Knopf::Style::Sichtbar, "Information" );
+	news->setLinienRahmenFarbe( 0xFFFFFFFF );
+	news->setLinienRahmenBreite( 1 );
+	news->setMausEreignisParameter( this );
+	news->setMausEreignis( titelLeisteNewsME );
+	miniGames = initKnopf( bgr.x - 204, 67, 102, 32, zSchrift, Knopf::Style::Sichtbar, "Mini Games" );
+	miniGames->setLinienRahmenFarbe( 0xFFFFFFFF );
+	miniGames->setLinienRahmenBreite( 1 );
+	miniGames->setMausEreignisParameter( this );
+	miniGames->setMausEreignis( titelLeisteMiniGamesME );
+	accountAnsehen = initKnopf( bgr.x - 305, 67, 102, 32, zSchrift, Knopf::Style::Sichtbar, "Account" );
+	accountAnsehen->setLinienRahmenFarbe( 0xFFFFFFFF );
+	accountAnsehen->setLinienRahmenBreite( 1 );
+	accountAnsehen->setMausEreignisParameter( this );
+	accountAnsehen->setMausEreignis( titelLeisteAccountAnsehenME );
+	shop = initKnopf( bgr.x - 406, 67, 102, 32, zSchrift, Knopf::Style::Sichtbar, "Shop" );
+	shop->setLinienRahmenFarbe( 0xFFFFFFFF );
+	shop->setLinienRahmenBreite( 1 );
+	shop->setMausEreignisParameter( this );
+	shop->setMausEreignis( titelLeisteShopME );
+	spielen = initKnopf( bgr.x - 507, 67, 102, 32, zSchrift, Knopf::Style::Sichtbar, "Spielen" );
+	spielen->setLinienRahmenFarbe( 0xFFFFFFFF );
+	spielen->setLinienRahmenBreite( 1 );
+	spielen->setMausEreignisParameter( this );
+	spielen->setMausEreignis( titelLeisteSpielenME );
+	editor = initKnopf( bgr.x - 507, 35, 102, 32, zSchrift, 0, "Editor" );
+	editor->setLinienRahmenFarbe( 0xFFFFFFFF );
+	editor->setLinienRahmenBreite( 1 );
+	editor->setMausEreignisParameter( this );
+	editor->setMausEreignis( titelLeisteEditorME );
+	info = initTextFeld( 200, 11, 300, 76, zSchrift, TextFeld::Style::Sichtbar | TextFeld::Style::Mehrzeilig | TextFeld::Style::Mehrfarbig | TextFeld::Style::Rahmen, "Wilkommen bei Kolja-Strohm Games!\nViel Spaß beim spielen." );
+	info->setLinienRahmenFarbe( 0xFFFFFFFF );
+	int minus = bgr.x / 2 - 254;
+	if( minus < 511 )
+		minus = 511;
+	minus = bgr.x - 508 - minus;
+	news->setPosition( news->getX() - minus, news->getY() );
+	miniGames->setPosition( miniGames->getX() - minus, miniGames->getY() );
+	accountAnsehen->setPosition( accountAnsehen->getX() - minus, accountAnsehen->getY() );
+	shop->setPosition( shop->getX() - minus, shop->getY() );
+	spielen->setPosition( spielen->getX() - minus, spielen->getY() );
+	editor->setPosition( editor->getX() - minus, editor->getY() );
+	fenster = new Fenster();
+	fenster->setStyle( Fenster::Style::Sichtbar | Fenster::Style::BodyHintergrund | Fenster::Style::BodyHBild | Fenster::Style::Erlaubt | Fenster::Style::Rahmen );
+	fenster->setRFarbe( 0xFFFFFFFF );
+	fenster->setSize( bgr.x, 100 );
+	fenster->setKBgBildZ( hintergrund );
+	fenster->addMember( close );
+	fenster->addMember( einstellungen );
+	fenster->addMember( logout );
+	fenster->addMember( accountAnsehen );
+	fenster->addMember( spielen );
+	fenster->addMember( editor );
+	fenster->addMember( miniGames );
+	fenster->addMember( news );
+	fenster->addMember( shop );
+	fenster->addMember( info );
+	fenster->addMember( version );
+
+	kupfer = initTextFeld( fenster->getBreite() - 40, 70, 10, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "0" );
+	silber = initTextFeld( kupfer->getX() - 40, 70, 10, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "0" );
+	gold = initTextFeld( silber->getX() - 40, 70, 10, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "0" );
+	goldBild = new BildZ();
+	goldBild->setStyle( BildZ::Style::Sichtbar );
+	goldBild->setBildZ( goldB );
+	goldBild->setSize( 20, 20 );
+	goldBild->setPosition( gold->getX() + gold->getBreite(), 70 );
+	silberBild = new BildZ();
+	silberBild->setStyle( BildZ::Style::Sichtbar );
+	silberBild->setBildZ( silberB );
+	silberBild->setSize( 20, 20 );
+	silberBild->setPosition( silber->getX() + silber->getBreite(), 70 );
+	kupferBild = new BildZ();
+	kupferBild->setStyle( BildZ::Style::Sichtbar );
+	kupferBild->setBildZ( kupferB );
+	kupferBild->setSize( 20, 20 );
+	kupferBild->setPosition( kupfer->getX() + kupfer->getBreite(), 70 );
+
+	fenster->addMember( gold );
+	fenster->addMember( silber );
+	fenster->addMember( kupfer );
+	fenster->addMember( goldBild );
+	fenster->addMember( silberBild );
+	fenster->addMember( kupferBild );
+	zNachLogin->addMember( fenster );
+	next = new Array< int >();
+	nextAnzahl = 0;
+	rend = 0;
+	ref = 1;
+	start();
+}
+
+// Destruktor
+TitelLeiste::~TitelLeiste()
+{
+	ende();
+	if( closeBild )
+		closeBild = closeBild->release();
+	if( einstellungenBild )
+		einstellungenBild = einstellungenBild->release();
+	if( logoutBild )
+		logoutBild = logoutBild->release();
+	if( close )
+		close = close->release();
+	if( einstellungen )
+		einstellungen = einstellungen->release();
+	if( logout )
+		logout = logout->release();
+	if( accountAnsehen )
+		accountAnsehen = accountAnsehen->release();
+	if( spielen )
+		spielen = spielen->release();
+	if( editor )
+		editor = editor->release();
+	if( miniGames )
+		miniGames = miniGames->release();
+	if( news )
+		news = news->release();
+	if( shop )
+		shop = shop->release();
+	if( info )
+		info = info->release();
+	if( version )
+		version = version->release();
+	if( fenster )
+		fenster = fenster->release();
+	if( next )
+		next = next->release();
+	goldBild->release();
+	silberBild->release();
+	kupferBild->release();
+	gold->release();
+	silber->release();
+	kupfer->release();
+}
+
+// nicht constant
+void TitelLeiste::setImSpiel( bool imSpiel ) // aktiviert oder deaktiviert Knöpfe
+{
+	close->setStyle( Knopf::Style::Erlaubt, !imSpiel );
+	einstellungen->setStyle( Knopf::Style::Erlaubt, !imSpiel );
+	logout->setStyle( Knopf::Style::Erlaubt, !imSpiel );
+	accountAnsehen->setStyle( Knopf::Style::Erlaubt, !imSpiel );
+	spielen->setStyle( Knopf::Style::Erlaubt, !imSpiel );
+	editor->setStyle( Knopf::Style::Erlaubt, !imSpiel );
+	miniGames->setStyle( Knopf::Style::Erlaubt, !imSpiel );
+	news->setStyle( Knopf::Style::Erlaubt, !imSpiel );
+	shop->setStyle( Knopf::Style::Erlaubt, !imSpiel );
+}
+
+void TitelLeiste::setImVideo( bool imVideo ) // aktiviert oder deaktiviert Knöpfe
+{
+	einstellungen->setStyle( Knopf::Style::Erlaubt, !imVideo );
+	accountAnsehen->setStyle( Knopf::Style::Erlaubt, !imVideo );
+	spielen->setStyle( Knopf::Style::Erlaubt, !imVideo );
+	editor->setStyle( Knopf::Style::Erlaubt, !imVideo );
+	miniGames->setStyle( Knopf::Style::Erlaubt, !imVideo );
+	news->setStyle( Knopf::Style::Erlaubt, !imVideo );
+	shop->setStyle( Knopf::Style::Erlaubt, !imVideo );
+}
+
+bool TitelLeiste::druckSchließen( MausEreignis &me ) // Schließen wurde gedrückt
+{
+	if( me.id == ME_RLinks )
+	{
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Schließen" ), new Text( "Möchtest du den Client wirklich beenden?" ),
+													  new Text( "Ja" ), new Text( "Nein" ), NachrichtType::close, 0 );
+	}
+	return 1;
+}
+
+bool TitelLeiste::druckEinstellungen( MausEreignis &me ) // Einstellungen wurde gedrückt
+{
+	if( me.id == ME_RLinks )
+		nachLogin->zEinstellungen()->setSichtbar();
+	return 1;
+}
+
+bool TitelLeiste::druckLogout( MausEreignis &me ) // Logout wurde gedrückt
+{
+	if( me.id == ME_RLinks )
+	{
+		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Logout" ), new Text( "Möchtest du dich wirklich ausloggen?" ),
+													  new Text( "Ja" ), new Text( "Nein" ), NachrichtType::logout, 0 );
+	}
+	return 1;
+}
+
+bool TitelLeiste::druckSpielen( MausEreignis &me ) // Spielen wurde gedrückt
+{
+	if( me.id == ME_RLinks )
+	{
+		if( nachLogin->zSpielenFenster()->istSichtbar() && !nextAnzahl )
+			return 1;
+		next->add( 1, nextAnzahl );
+		nextAnzahl++;
+	}
+	return 1;
+}
+
+bool TitelLeiste::druckAccountAnsehen( MausEreignis &me ) // AccountAnsehen wurde gedrückt
+{
+	if( me.id == ME_RLinks )
+	{
+		if( nachLogin->zAccountAnsehenFenster()->istSichtbar() && !nextAnzahl )
+			return 1;
+		next->add( 2, nextAnzahl );
+		nextAnzahl++;
+	}
+	return 1;
+}
+
+bool TitelLeiste::druckMiniGames( MausEreignis &me ) // MiniGames wurde gedrückt
+{
+	if( me.id == ME_RLinks )
+	{
+		if( nachLogin->zMGFenster()->istSichtbar() && !nextAnzahl )
+			return 1;
+		next->add( 3, nextAnzahl );
+		nextAnzahl++;
+	}
+	return 1;
+}
+
+bool TitelLeiste::druckNews( MausEreignis &me ) // News wurde gedrückt
+{
+	if( me.id == ME_RLinks )
+	{
+		if( nachLogin->zNewsFenster()->istSichtbar() && !nextAnzahl )
+			return 1;
+		next->add( 4, nextAnzahl );
+		nextAnzahl++;
+	}
+	return 1;
+}
+
+bool TitelLeiste::druckShop( MausEreignis &me ) // Spielen wurde gedrückt
+{
+	if( me.id == ME_RLinks )
+	{
+		if( nachLogin->zShopFenster()->istSichtbar() && !nextAnzahl )
+			return 1;
+		next->add( 5, nextAnzahl );
+		nextAnzahl++;
+	}
+	return 1;
+}
+
+bool TitelLeiste::druckEditor( MausEreignis &me ) // Spielen wurde gedrückt
+{
+	if( me.id == ME_RLinks )
+	{
+		if( nachLogin->zEditorFenster()->istSichtbar() && !nextAnzahl )
+			return 1;
+		next->add( 6, nextAnzahl );
+		nextAnzahl++;
+	}
+	return 1;
+}
+
+void TitelLeiste::thread()
+{
+	while( 1 )
+	{
+		if( infoKlient )
+		{
+            cs.lock();
+			Text *infoTxt = new Text( "" );
+			int typ = 0;
+			bool b = infoKlient->getInformationText( infoTxt, &typ );
+			if( b && infoTxt->getLength() )
+				info->setText( infoTxt->getThis() );
+			infoTxt = infoTxt->release();
+			int k = infoKlient->getKupfer();
+			int s = k / 100;
+			int g = s / 100;
+			s = s % 100;
+			k = k % 100;
+			Text *gt = new Text();
+			gt->append( g );
+			Text *st = new Text();
+			st->append( s );
+			Text *kt = new Text();
+			kt->append( k );
+			Schrift *schrift = gold->zSchrift();
+			schrift->lock();
+			schrift->setSchriftSize( 12 );
+			int gtbr = schrift->getTextBreite( gt );
+			int stbr = schrift->getTextBreite( st );
+			int ktbr = schrift->getTextBreite( kt );
+			schrift->unlock();
+			kupfer->setPosition( fenster->getBreite() - 30 - ktbr, kupfer->getY() );
+			kupfer->setSize( ktbr, 20 );
+			silber->setPosition( kupfer->getX() - 30 - stbr, silber->getY() );
+			silber->setSize( stbr, 20 );
+			gold->setPosition( silber->getX() - 30 - gtbr, gold->getY() );
+			gold->setSize( gtbr, 20 );
+			goldBild->setPosition( gold->getX() + gold->getBreite(), goldBild->getY() );
+			silberBild->setPosition( silber->getX() + silber->getBreite(), silberBild->getY() );
+			kupferBild->setPosition( kupfer->getX() + kupfer->getBreite(), kupferBild->getY() );
+			gold->setText( gt );
+			silber->setText( st );
+			kupfer->setText( kt );
+			editor->setStyle( Knopf::Style::Sichtbar, infoKlient->hatRecht( 1 ) );
+            cs.unlock();
+		}
+		Sleep( 60 * 1000 );
+	}
+	run = 0;
+}
+
+bool TitelLeiste::tick() // tick
+{
+	if( nextAnzahl )
+	{
+		rend = 1;
+		int n = next->hat( 0 ) ? next->get( 0 ) : 0;
+		switch( n )
+		{
+		case 1: // Spielen
+			// Andere Fenster Unsichtbar machen
+			if( nachLogin->zShopFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zShopFenster()->istAnimiert() )
+					nachLogin->zShopFenster()->setSichtbar( 0 );
+				break;
+			}
+			if( nachLogin->zAccountAnsehenFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zAccountAnsehenFenster()->istAnimiert() )
+					nachLogin->zAccountAnsehenFenster()->setSichtbar( 0 );
+				break;
+			}
+			if( nachLogin->zMGFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zMGFenster()->istAnimiert() )
+					nachLogin->zMGFenster()->setSichtbar( 0 );
+				break;
+			}
+			if( nachLogin->zNewsFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zNewsFenster()->istAnimiert() )
+					nachLogin->zNewsFenster()->setSichtbar( 0 );
+				break;
+			}
+			if( nachLogin->zEditorFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zEditorFenster()->istAnimiert() )
+					nachLogin->zEditorFenster()->setSichtbar( 0 );
+				break;
+			}
+			// Fenster Sichtbar machen
+			spielen->setAlphaFeldFarbe( 0x0000FF00 );
+			accountAnsehen->setAlphaFeldFarbe( 0x5500FF00 );
+			miniGames->setAlphaFeldFarbe( 0x5500FF00 );
+			news->setAlphaFeldFarbe( 0x5500FF00 );
+			shop->setAlphaFeldFarbe( 0x5500FF00 );
+			editor->setAlphaFeldFarbe( 0x5500FF00 );
+			nachLogin->zSpielenFenster()->setSichtbar( 1 );
+			next->remove( 0 );
+			nextAnzahl--;
+			break;
+		case 2: // Account ansehen
+			// Andere Fenster Unsichtbar machen
+			if( nachLogin->zSpielenFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zSpielenFenster()->istAnimiert() )
+					nachLogin->zSpielenFenster()->setSichtbar( 0 );
+				break;
+			}
+			if( nachLogin->zShopFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zShopFenster()->istAnimiert() )
+					nachLogin->zShopFenster()->setSichtbar( 0 );
+				break;
+			}
+			if( nachLogin->zMGFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zMGFenster()->istAnimiert() )
+					nachLogin->zMGFenster()->setSichtbar( 0 );
+				break;
+			}
+			if( nachLogin->zNewsFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zNewsFenster()->istAnimiert() )
+					nachLogin->zNewsFenster()->setSichtbar( 0 );
+				break;
+			}
+			if( nachLogin->zEditorFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zEditorFenster()->istAnimiert() )
+					nachLogin->zEditorFenster()->setSichtbar( 0 );
+				break;
+			}
+			// Fenster Sichtbar machen
+			spielen->setAlphaFeldFarbe( 0x5500FF00 );
+			accountAnsehen->setAlphaFeldFarbe( 0x0000FF00 );
+			miniGames->setAlphaFeldFarbe( 0x5500FF00 );
+			news->setAlphaFeldFarbe( 0x5500FF00 );
+			shop->setAlphaFeldFarbe( 0x5500FF00 );
+			editor->setAlphaFeldFarbe( 0x5500FF00 );
+			nachLogin->zAccountAnsehenFenster()->setSichtbar( 1 );
+			next->remove( 0 );
+			nextAnzahl--;
+			break;
+		case 3: // MiniGames
+			// Andere Fenster Unsichtbar machen
+			if( nachLogin->zSpielenFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zSpielenFenster()->istAnimiert() )
+					nachLogin->zSpielenFenster()->setSichtbar( 0 );
+				break;
+			}
+			if( nachLogin->zShopFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zShopFenster()->istAnimiert() )
+					nachLogin->zShopFenster()->setSichtbar( 0 );
+				break;
+			}
+			if( nachLogin->zAccountAnsehenFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zAccountAnsehenFenster()->istAnimiert() )
+					nachLogin->zAccountAnsehenFenster()->setSichtbar( 0 );
+				break;
+			}
+			if( nachLogin->zNewsFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zNewsFenster()->istAnimiert() )
+					nachLogin->zNewsFenster()->setSichtbar( 0 );
+				break;
+			}
+			if( nachLogin->zEditorFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zEditorFenster()->istAnimiert() )
+					nachLogin->zEditorFenster()->setSichtbar( 0 );
+				break;
+			}
+			// Fenster Sichtbar machen
+			spielen->setAlphaFeldFarbe( 0x5500FF00 );
+			accountAnsehen->setAlphaFeldFarbe( 0x5500FF00 );
+			miniGames->setAlphaFeldFarbe( 0x0000FF00 );
+			news->setAlphaFeldFarbe( 0x5500FF00 );
+			shop->setAlphaFeldFarbe( 0x5500FF00 );
+			editor->setAlphaFeldFarbe( 0x5500FF00 );
+			nachLogin->zMGFenster()->setSichtbar( 1 );
+			next->remove( 0 );
+			nextAnzahl--;
+			break;
+		case 4: // News
+			// Andere Fenster Unsichtbar machen
+			if( nachLogin->zSpielenFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zSpielenFenster()->istAnimiert() )
+					nachLogin->zSpielenFenster()->setSichtbar( 0 );
+				break;
+			}
+			if( nachLogin->zShopFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zShopFenster()->istAnimiert() )
+					nachLogin->zShopFenster()->setSichtbar( 0 );
+				break;
+			}
+			if( nachLogin->zAccountAnsehenFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zAccountAnsehenFenster()->istAnimiert() )
+					nachLogin->zAccountAnsehenFenster()->setSichtbar( 0 );
+				break;
+			}
+			if( nachLogin->zMGFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zMGFenster()->istAnimiert() )
+					nachLogin->zMGFenster()->setSichtbar( 0 );
+				break;
+			}
+			if( nachLogin->zEditorFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zEditorFenster()->istAnimiert() )
+					nachLogin->zEditorFenster()->setSichtbar( 0 );
+				break;
+			}
+			// Fenster Sichtbar machen
+			spielen->setAlphaFeldFarbe( 0x5500FF00 );
+			accountAnsehen->setAlphaFeldFarbe( 0x5500FF00 );
+			miniGames->setAlphaFeldFarbe( 0x5500FF00 );
+			news->setAlphaFeldFarbe( 0x0000FF00 );
+			shop->setAlphaFeldFarbe( 0x5500FF00 );
+			editor->setAlphaFeldFarbe( 0x5500FF00 );
+			nachLogin->zNewsFenster()->setSichtbar( 1 );
+			next->remove( 0 );
+			nextAnzahl--;
+			break;
+		case 5: // Shop
+			// Andere Fenster Unsichtbar machen
+			if( nachLogin->zSpielenFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zSpielenFenster()->istAnimiert() )
+					nachLogin->zSpielenFenster()->setSichtbar( 0 );
+				break;
+			}
+			if( nachLogin->zAccountAnsehenFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zAccountAnsehenFenster()->istAnimiert() )
+					nachLogin->zAccountAnsehenFenster()->setSichtbar( 0 );
+				break;
+			}
+			if( nachLogin->zMGFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zMGFenster()->istAnimiert() )
+					nachLogin->zMGFenster()->setSichtbar( 0 );
+				break;
+			}
+			if( nachLogin->zNewsFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zNewsFenster()->istAnimiert() )
+					nachLogin->zNewsFenster()->setSichtbar( 0 );
+				break;
+			}
+			if( nachLogin->zEditorFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zEditorFenster()->istAnimiert() )
+					nachLogin->zEditorFenster()->setSichtbar( 0 );
+				break;
+			}
+			// Fenster Sichtbar machen
+			spielen->setAlphaFeldFarbe( 0x5500FF00 );
+			accountAnsehen->setAlphaFeldFarbe( 0x5500FF00 );
+			miniGames->setAlphaFeldFarbe( 0x5500FF00 );
+			news->setAlphaFeldFarbe( 0x5500FF00 );
+			shop->setAlphaFeldFarbe( 0x0000FF00 );
+			editor->setAlphaFeldFarbe( 0x5500FF00 );
+			nachLogin->zShopFenster()->setSichtbar( 1 );
+			next->remove( 0 );
+			nextAnzahl--;
+			break;
+		case 6: // Editor
+			// Andere Fenster Unsichtbar machen
+			if( nachLogin->zSpielenFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zSpielenFenster()->istAnimiert() )
+					nachLogin->zSpielenFenster()->setSichtbar( 0 );
+				break;
+			}
+			if( nachLogin->zAccountAnsehenFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zAccountAnsehenFenster()->istAnimiert() )
+					nachLogin->zAccountAnsehenFenster()->setSichtbar( 0 );
+				break;
+			}
+			if( nachLogin->zMGFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zMGFenster()->istAnimiert() )
+					nachLogin->zMGFenster()->setSichtbar( 0 );
+				break;
+			}
+			if( nachLogin->zNewsFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zNewsFenster()->istAnimiert() )
+					nachLogin->zNewsFenster()->setSichtbar( 0 );
+				break;
+			}
+			if( nachLogin->zShopFenster()->istSichtbar() )
+			{
+				if( !nachLogin->zShopFenster()->istAnimiert() )
+					nachLogin->zShopFenster()->setSichtbar( 0 );
+				break;
+			}
+			// Fenster Sichtbar machen
+			spielen->setAlphaFeldFarbe( 0x5500FF00 );
+			accountAnsehen->setAlphaFeldFarbe( 0x5500FF00 );
+			miniGames->setAlphaFeldFarbe( 0x5500FF00 );
+			news->setAlphaFeldFarbe( 0x5500FF00 );
+			shop->setAlphaFeldFarbe( 0x5500FF00 );
+			editor->setAlphaFeldFarbe( 0x0000FF00 );
+			nachLogin->zEditorFenster()->setSichtbar( 1 );
+			next->remove( 0 );
+			nextAnzahl--;
+			break;
+		}
+	}
+	bool ret = rend;
+	rend = 0;
+	return ret;
+}
+
+// constant
+int TitelLeiste::getSpielenX() const
+{
+	return spielen->getX();
+}
+
+// Reference Counting
+TitelLeiste *TitelLeiste::getThis()
+{
+	ref++;
+	return this;
+}
+
+TitelLeiste *TitelLeiste::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Ereignisse
+bool titelLeisteSchließenME( void *p, void *obj, MausEreignis me )
+{
+	return ( (TitelLeiste*)p )->druckSchließen( me );
+}
+
+bool titelLeisteEinstellungenME( void *p, void *obj, MausEreignis me )
+{
+	return ( (TitelLeiste*)p )->druckEinstellungen( me );
+}
+
+bool titelLeisteLogoutME( void *p, void *obj, MausEreignis me )
+{
+	return ( (TitelLeiste*)p )->druckLogout( me );
+}
+
+bool titelLeisteAccountAnsehenME( void *p, void *obj, MausEreignis me )
+{
+	return ( (TitelLeiste*)p )->druckAccountAnsehen( me );
+}
+
+bool titelLeisteSpielenME( void *p, void *obj, MausEreignis me )
+{
+	return ( (TitelLeiste*)p )->druckSpielen( me );
+}
+
+bool titelLeisteMiniGamesME( void *p, void *obj, MausEreignis me )
+{
+	return ( (TitelLeiste*)p )->druckMiniGames( me );
+}
+
+bool titelLeisteNewsME( void *p, void *obj, MausEreignis me )
+{
+	return ( (TitelLeiste*)p )->druckNews( me );
+}
+
+bool titelLeisteShopME( void *p, void *obj, MausEreignis me )
+{
+	return ( (TitelLeiste*)p )->druckShop( me );
+}
+
+bool titelLeisteEditorME( void *p, void *obj, MausEreignis me )
+{
+	return ( (TitelLeiste*)p )->druckEditor( me );
+}

+ 79 - 0
KSGClient/NachLogin/Titel/TitelLeiste.h

@@ -0,0 +1,79 @@
+#ifndef TitelLeiste_H
+#define TitelLeiste_H
+
+#include <Klient.h>
+#include <Knopf.h>
+#include <Fenster.h>
+#include <Bild.h>
+#include <Thread.h>
+
+using namespace Framework;
+
+class TitelLeiste : private Thread
+{
+private:
+	Knopf *close;
+	Knopf *einstellungen;
+	Knopf *logout;
+	Knopf *accountAnsehen;
+	Knopf *spielen;
+	Knopf *miniGames;
+	Knopf *news;
+	Knopf *shop;
+	Knopf *editor;
+	Bild *closeBild;
+	Bild *einstellungenBild;
+	Bild *logoutBild;
+	TextFeld *info;
+	TextFeld *version;
+	Fenster *fenster;
+	Array< int > *next;
+	Critical cs;
+	BildZ *goldBild;
+	BildZ *silberBild;
+	BildZ *kupferBild;
+	TextFeld *gold;
+	TextFeld *silber;
+	TextFeld *kupfer;
+	int nextAnzahl;
+	bool rend;
+	int ref;
+
+public:
+	// Konstruktor
+	TitelLeiste( Fenster *zNachLogin, Schrift *zSchrift );
+	// Destruktor
+	~TitelLeiste();
+	// nicht constant
+	void setImSpiel( bool imSpiel ); // aktiviert oder deaktiviert Knöpfe
+	void setImVideo( bool imVideo ); // aktiviert oder deaktiviert Knöpfe
+	bool druckSchließen( MausEreignis &me ); // Schließen wurde gedrückt
+	bool druckEinstellungen( MausEreignis &me ); // Einstellungen wurde gedrückt
+	bool druckLogout( MausEreignis &me ); // Logout wurde gedrückt
+	bool druckAccountAnsehen( MausEreignis &me ); // AccountAnsehen wurde gedrückt
+	bool druckSpielen( MausEreignis &me ); // Spielen wurde gedrückt
+	bool druckMiniGames( MausEreignis &me ); // MiniGames wurde gedrückt
+	bool druckNews( MausEreignis &me ); // News wurde gedrückt
+	bool druckShop( MausEreignis &me ); // Shop wurde gedrückt
+	bool druckEditor( MausEreignis &me ); // Shop wurde gedrückt
+	void thread(); // aktualisierungs Thread
+	bool tick(); // tick
+	// constant
+	int getSpielenX() const;
+	// Reference Counting
+	TitelLeiste *getThis();
+	TitelLeiste *release();
+};
+
+// Ereignisse
+bool titelLeisteSchließenME( void *p, void *obj, MausEreignis me );
+bool titelLeisteEinstellungenME( void *p, void *obj, MausEreignis me );
+bool titelLeisteLogoutME( void *p, void *obj, MausEreignis me );
+bool titelLeisteAccountAnsehenME( void *p, void *obj, MausEreignis me );
+bool titelLeisteSpielenME( void *p, void *obj, MausEreignis me );
+bool titelLeisteMiniGamesME( void *p, void *obj, MausEreignis me );
+bool titelLeisteNewsME( void *p, void *obj, MausEreignis me );
+bool titelLeisteShopME( void *p, void *obj, MausEreignis me );
+bool titelLeisteEditorME( void *p, void *obj, MausEreignis me );
+
+#endif

+ 296 - 0
KSGClient/NachLogin/UpdateGUI/UpdateGUI.cpp

@@ -0,0 +1,296 @@
+#include "../../Global/Initialisierung.h"
+#include <MausEreignis.h>
+#include "../../Global/Variablen.h"
+
+// Inhalt der UpdateGUI klasse aus UpdateGUI.h
+// Konstruktor
+UpdateGUI::UpdateGUI( Schrift *zSchrift, int spielId, int dg )
+	: Thread()
+{
+	p = 0;
+	updateStatus = initTextFeld( 0, 0, 302, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, "Neuste Version Herunterladen" );
+	updateStarten = initKnopf( 302, 0, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Herunterladen" );
+	updateFortschritt = initFBalken( 0, 25, 402, 22, zSchrift, FBalken::Style::Sichtbar | FBalken::Style::Hintergrund | FBalken::Style::HBild |
+									 FBalken::Style::FBild | FBalken::Style::Rahmen | FBalken::Style::Prozent | FBalken::Style::L_R );
+	updateAbbrechen = 1;
+	sichtbar = 0;
+	alpha = 0;
+	this->spielId = spielId;
+	this->dg = dg;
+	ref = 1;
+}
+
+// Destruktor
+UpdateGUI::~UpdateGUI()
+{
+	if( isRunning() )
+	{
+		updateAbbrechen = 1;
+		warteAufThread( 5000 );
+		if( isRunning() )
+			ende();
+	}
+	updateStatus->release();
+	updateStarten->release();
+	updateFortschritt->release();
+	if( p )
+		p->release();
+}
+
+// nicht constant
+void UpdateGUI::setSichtbar( bool sichtbar )
+{
+	this->sichtbar = sichtbar;
+}
+
+void UpdateGUI::doMausEreignis( MausEreignis &me, Patcher *zP )
+{
+	bool vera = me.verarbeitet;
+	updateStarten->doMausEreignis( me );
+	if( !vera && me.verarbeitet && me.id == ME_RLinks )
+	{
+		if( updateAbbrechen )
+		{
+			updateAbbrechen = 0;
+			if( !p )
+				p = zP->getThis();
+			updateStarten->setText( "Abbrechen" );
+			start();
+		}
+		else
+		{
+			updateAbbrechen = 1;
+			if( isRunning() )
+				warteAufThread( 5000 );
+			if( isRunning() )
+				ende();
+			updateStatus->setText( "Neuste Version Herunterladen" );
+			updateStarten->setText( "Herunterladen" );
+			updateFortschritt->reset();
+		}
+	}
+}
+
+bool UpdateGUI::tick( double zeit )
+{
+	bool ret = updateStatus->tick( zeit );
+	ret |= updateStarten->tick( zeit );
+	ret |= updateFortschritt->tick( zeit );
+	if( !alpha )
+		ret = 0;
+	if( sichtbar && alpha != 255 )
+	{
+		alpha += (int)( zeit * 150 );
+		if( alpha > 255 )
+			alpha = 255;
+		ret = 1;
+	}
+	if( !sichtbar && alpha )
+	{
+		alpha -= (int)( zeit * 150 );
+		if( alpha < 0 )
+			alpha = 0;
+		ret = 1;
+	}
+	return ret;
+}
+
+void UpdateGUI::render( int xOff, int yOff, Bild &zRObj )
+{
+	if( !zRObj.setDrawOptions( xOff, yOff, 402, 50 ) )
+		return;
+	zRObj.setAlpha( (unsigned char)alpha );
+	updateStatus->render( zRObj );
+	updateStarten->render( zRObj );
+	updateFortschritt->render( zRObj );
+	zRObj.releaseAlpha();
+	zRObj.releaseDrawOptions();
+}
+
+void UpdateGUI::thread()
+{
+	int dgId = dg;
+	if( spielId )
+		dgId = infoKlient->getDateiGruppeIdVonSpiel( spielId );
+	Text err;
+	if( !p->update( dgId, &updateAbbrechen, updateFortschritt->getThis(), updateStatus->getThis(), &err ) )
+	{
+		if( nachLogin && nachLogin->zNachrichtenListe() )
+			nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), err.getThis(), new Text( "Ok" ) );
+	}
+	updateStatus->setText( "Neuste Version Herunterladen" );
+	updateStarten->setText( "Herunterladen" );
+	updateFortschritt->reset();
+	updateAbbrechen = 1;
+	run = 0;
+	if( nachLogin && nachLogin->zSpielenFenster() && spielId )
+		nachLogin->zSpielenFenster()->updateErlaubt();
+	if( nachLogin && nachLogin->zMGFenster() && dg )
+		nachLogin->zMGFenster()->setAktuell( 1 );
+}
+
+// constant
+bool UpdateGUI::istGleich( int spielId, int dg )
+{
+	return this->spielId == spielId && this->dg == dg;
+}
+
+// Reference Counting
+UpdateGUI *UpdateGUI::getThis()
+{
+	ref++;
+	return this;
+}
+
+UpdateGUI *UpdateGUI::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// inhalt der UpdateHandler Klasse aus UpdateGUI.h
+// Konstruktor
+UpdateHandler::UpdateHandler()
+{
+	patcher = new Patcher();
+	updates = new RCArray< UpdateGUI >();
+	ref = 1;
+}
+
+// Destruktor
+UpdateHandler::~UpdateHandler()
+{
+	updates->release();
+	patcher->release();
+}
+
+// privat
+void UpdateHandler::lock()
+{
+    cs.lock();
+}
+
+void UpdateHandler::unlock()
+{
+    cs.unlock();
+}
+
+// nicht constant
+void UpdateHandler::erstellen( Schrift *zSchrift, int spiel, int dg )
+{
+	lock();
+	updates->add( new UpdateGUI( zSchrift, spiel, dg ) );
+	unlock();
+}
+
+void UpdateHandler::setSichtbar( int spiel, bool sichtbar, int dg )
+{
+	lock();
+	int anz = updates->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+	{
+		if( updates->z( i )->istGleich( spiel, dg ) )
+		{
+			updates->z( i )->setSichtbar( sichtbar );
+			break;
+		}
+	}
+	unlock();
+}
+
+void UpdateHandler::doMausEreignis( int spiel, MausEreignis &me, int dg )
+{
+	lock();
+	int anz = updates->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+	{
+		if( updates->z( i )->istGleich( spiel, dg ) )
+		{
+			updates->z( i )->doMausEreignis( me, patcher );
+			break;
+		}
+	}
+	unlock();
+}
+
+bool UpdateHandler::tick( int spiel, double zeit, int dg )
+{
+	lock();
+	bool ret = 0;
+	int anz = updates->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+	{
+		if( updates->z( i )->istGleich( spiel, dg ) )
+		{
+			ret = updates->z( i )->tick( zeit );
+			break;
+		}
+	}
+	unlock();
+	return ret;
+}
+
+void UpdateHandler::render( int spiel, int xOff, int yOff, Bild &zRObj, int dg )
+{
+	lock();
+	int anz = updates->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+	{
+		if( updates->z( i )->istGleich( spiel, dg ) )
+		{
+			updates->z( i )->render( xOff, yOff, zRObj );
+			break;
+		}
+	}
+	unlock();
+}
+
+void UpdateHandler::remove( int spiel, int dg )
+{
+	lock();
+	int anz = updates->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+	{
+		if( updates->z( i )->istGleich( spiel, dg ) )
+		{
+			updates->remove( i );
+			break;
+		}
+	}
+	unlock();
+}
+
+bool UpdateHandler::hat( int spiel, int dg )
+{
+	lock();
+	bool ret = 0;
+	int anz = updates->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+	{
+		if( updates->z( i )->istGleich( spiel, dg ) )
+		{
+			ret = 1;
+			break;
+		}
+	}
+	unlock();
+	return ret;
+}
+
+// Reference Counting
+UpdateHandler *UpdateHandler::getThis()
+{
+	ref++;
+	return this;
+}
+
+UpdateHandler *UpdateHandler::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 73 - 0
KSGClient/NachLogin/UpdateGUI/UpdateGUI.h

@@ -0,0 +1,73 @@
+#ifndef UpdateGUI_H
+#define UpdateGUI_H
+
+#include "../../Netzwerk/Patcher.h"
+#include <Fortschritt.h>
+#include <Knopf.h>
+#include <Array.h>
+#include <Thread.h>
+
+using namespace Framework;
+
+class UpdateGUI : private Thread
+{
+private:
+	Patcher *p;
+	TextFeld *updateStatus;
+	Knopf *updateStarten;
+	FBalken *updateFortschritt;
+	bool updateAbbrechen;
+	bool sichtbar;
+	int alpha;
+	int spielId;
+	int dg;
+	int ref;
+
+public:
+	// Konstruktor
+	UpdateGUI( Schrift *zSchrift, int spielId, int dg = 0 );
+	// Destruktor
+	~UpdateGUI();
+	// nicht constant
+	void setSichtbar( bool sichtbar );
+	void doMausEreignis( MausEreignis &me, Patcher *zP );
+	bool tick( double zeit );
+	void render( int xOff, int yOff, Bild &zRObj );
+	void thread();
+	// constant
+	bool istGleich( int spielId, int dg = 0 );
+	// Reference Counting
+	UpdateGUI *getThis();
+	UpdateGUI *release();
+};
+
+class UpdateHandler
+{
+private:
+	Patcher *patcher;
+	RCArray< UpdateGUI > *updates;
+	Critical cs;
+	int ref;
+	// privat
+	void lock();
+	void unlock();
+
+public:
+	// Konstruktor
+	UpdateHandler();
+	// Destruktor
+	~UpdateHandler();
+	// nicht constant
+	void erstellen( Schrift *zSchrift, int spiel, int dg = 0 );
+	void setSichtbar( int spiel, bool sichtbar, int dg = 0 );
+	void doMausEreignis( int spiel, MausEreignis &me, int dg = 0 );
+	bool tick( int spiel, double zeit, int dg = 0 );
+	void render( int spiel, int xOff, int yOff, Bild &zRObj, int dg = 0 );
+	void remove( int spiel, int dg = 0 );
+	bool hat( int spiel, int dg = 0 );
+	// Reference Counting
+	UpdateHandler *getThis();
+	UpdateHandler *release();
+};
+
+#endif

+ 501 - 0
KSGClient/Netzwerk/KSGKlient.h

@@ -0,0 +1,501 @@
+#ifndef KSGKlient_H
+#define KSGKlient_H
+
+#include "KSGKlientV.h"
+#include "../Strukturen/Strukturen.h"
+#include <Bild.h>
+#include <GSLSoundV.h>
+#include "Critical.h"
+
+using namespace Network;
+using namespace Framework;
+
+#define LOCK( cs ) EnterCriticalSection( cs )
+#define UNLOCK( cs ) LeaveCriticalSection( cs )
+
+struct AHDaten;
+
+class LoginKlient
+{
+private:
+	Klient *klient;
+	bool verbunden;
+	char *fehler;
+	bool brauchKick;
+	int klientId;
+	int accountId;
+	int ref;
+	Critical cs;
+
+public:
+	// Konstruktor 
+	LoginKlient();
+	// Destruktor 
+	~LoginKlient(); // wenn verbunden, dann trennen
+	// nicht constant
+	bool verbinde(); // verbindet sich mit dem Login Server
+	int login( const char *name, const char *pass ); // gibt bei Erfolg 1 zurück
+	bool kick( const char *geheim );
+	bool logout(); // logt den Account aus
+	bool keepAlive(); // Erhält die Verbindung aufrecht
+	bool trenne(); // trennt sich von dem Login Server
+	void setLetzterFehler( char *err ); // setzt den letzten Fehler
+	// constant
+	bool istVerbunden() const; // prüft, ob mit Login Server verbunden
+	int getAccountId() const; // gibt die AccountId zurück
+	char *getLetzterFehler() const; // gibt den Letzten Fehlertext zuück
+	// Reference Counting
+	LoginKlient *getThis();
+	LoginKlient *release();
+};
+
+class RegisterKlient
+{
+private:
+	Klient *klient;
+	bool verbunden;
+	char *fehler;
+	bool brauchSchlüssel;
+	int klientId;
+	int ref;
+	Critical cs;
+
+public:
+	// Konstruktor 
+	RegisterKlient();
+	// Destruktor
+	~RegisterKlient(); // wenn verbunden, dann trennen
+	// nicht constant
+	bool verbinde(); // verbindet ich mit dem Register Server
+	bool accountErstellen( const char *name, const char *pass, const char *geheim, const char *eMail, unsigned short jahr, char monat, char tag ); // erstellt den Account
+	bool accountLöschen( const char *name, const char *pass, const char *geheim ); // löscht den Account
+	int accountBestätigen( const char *name, const char *pass ); // account Bestätigung fortsetzen
+	bool bestätigen( const char *schlüssel ); // bestätigt den Vorgang mit Schüssel
+	void eMailErneutSenden(); // E-Mail nochmal senden
+	void später(); // bestätigung später abclose
+	void abbrechen(); // bricht den Vorgang ab
+	bool passwortÄndern( const char *name, const char *pass, const char *geheim, const char *nPass ); // ändert das Passwort
+	bool eMailÄndern( const char *name, const char *pass, const char *geheim, const char *nEMail ); // ändert die E-Mail Addresse
+	bool geheimnisÄndern( const char *name, const char *pass, const char *geheim, const char *nGeheim ); // ändert das Geheimnis
+	bool nameVergessen( const char *pass, const char *geheim ); // schickt den Account Namen an die Bekannte E-Mail Addresse
+	bool passwortVergessen( const char *name, const char *geheim ); // schickt das Account Passwort an die Bekannte E-Mail Addresse
+	bool geheimnisVergessen( const char *name, const char *pass ); // schickt das Account Geheimnis an die Bekannte E-Mail Addresse
+	bool eMailVergessen( const char *name, const char *pass, const char *geheim, char **eMail ); // gibt die E-Mail Addresse des Accounts zurück
+	bool keepAlive(); // Erhält die Verbindung aufrecht
+	bool trenne(); // trennt sich von dem Register Server
+	// constant
+	bool istVerbunden() const; // prüft, ob mit Register Server verbunden
+	bool vorgangBrauchBestätigung() const; // prüft, ob eine Bestätigung notwendig ist
+	char *getLetzterFehler() const; // gibt den Letzten Fehlertext zuück
+	// Reference Counting
+	RegisterKlient *getThis();
+	RegisterKlient *release();
+};
+
+class InformationKlient : public InformationKlientV
+{
+private:
+	Klient *klient;
+	bool verbunden;
+	Text *fehler;
+	int klientId;
+	int ref;
+	Critical cs;
+
+public:
+	// Konstruktor
+	InformationKlient();
+	// Destruktor
+	~InformationKlient(); // wenn verbunden, dann trennen
+	// nicht constant
+	virtual bool verbinde() override; // verbindet ich mit dem Informaion Server
+    virtual bool getInformationText( Text *txt, int *typ ) override; // fragt nach Informationstext
+	virtual bool istSpielErlaubt( int spielId ) override; // fragt, ob das entsprechende Spiel vom Server gesperrt wurde
+	virtual bool istKarteErlaubt( int karteId ) override; // fragt, ob die entsprechende Karte vom Server gesperrt wurde
+	virtual int getKarteId( char *name ) override; // fragt nach der Id einer Karte
+	virtual int getSpielId( char *name ) override; // fragt nach der id eines Spiels
+	virtual Text *getSpielerName( int accountId ); // fragt nach dem Namen eines Accounts
+    virtual bool getSpielStatistik( int accountId, int spielId, Array< int > *werte ) override; // fragt nach der Spiel Statistik eines Accounts
+	virtual Text *getKarteName( int karteId ) override; // fragt nach dem Namen einer Karte
+	virtual Text *getSpielName( int spielId ) override; // fragt nach dem Namen einer Spielart
+    virtual Text *getChatroomName( int chatroomId ) override; // fragt nach dem Namen eines Chatrooms
+    virtual int getSpielId( int karteId ) override; // fragt zu welcher Spielart die Karte gehört
+    virtual int getAccountId( char *name ) override; // gibt die Id des Accounts zurück
+    virtual int getChatroomId( char *name ) override; // gibt die Id des Chatrooms zurück
+    virtual int getGruppenKarteId( int gruppenId ) override; // gibt die karten Id der gruppe zurück
+    virtual bool getGruppeSpielerHinzufügen( int gruppeId ) override; // gibt die Spieler hinzufügen Funktion der Gruppe zurück
+    virtual int getGruppeAdminId( int gruppeId ) override; // gibt den Gruppen Administrator zurück
+    virtual int getSpielerPunkte( int accountId, int spielId ) override; // gibt die Punkte eines Spielers zurück
+    virtual Array< int > *getAccountSpielArtListe() override; // gibt eine Liste mit gekauften Spielen zurück
+    virtual int getSpielVersion( int spielId ) override; // gibt die neuste Version eines Spiels zurück
+    virtual int getKupfer() override; // gibt das Kupfer des Accounts zurück
+    virtual int getDateiGruppeIdVonSpiel( int spielId ) override; // Gibt die Dateigruppe eines Spieles zurück
+    virtual Text *getDateiGruppePfad( int dgId ) override; // Gibt den Dateigruppen Pfad zurück
+    virtual Array< int > *getAccountKarteListe( int spielId ) override; // gibt eine Liste mit gekauften Karten zurück
+    virtual int getDateiGruppeIdVonPfad( char *pfad ) override; // Gibt die Dateigruppe eines Pfades zurück
+    virtual int getDateiGruppeVersion( int dg ) override; // gibt die neuste Version einer Dateigruppe zurück
+	virtual int getSpielerListe( char *suche, int *seite, int *maxSeite, char sortSpalte, char rückwärts, 
+								 Array< int > *accounts, RCArray< Text > *name, RCArray< Text > *zuletztOnline,
+                                 RCArray< Text > *letztesSpiel, RCArray< Text > *letzteKarte, RCArray< Text > *punkte ) override; // sucht nach Spielern
+	virtual bool getSpielerAktivität( int accId, RCArray< Text > *datum, Array< double > *stOnline, Array< double > *stGespielt, 
+                                      Array< int > *anzSpiele, Array< int > *anzGewonnen ) override; // ermittelt die aktivität eines Spielers
+    virtual int getAccountKarteSpiele( int account, int karte ) override; // Gibt zurück, wie oft ein Spieler eine Karte schon gespielt hat
+    virtual int getAccountKarteSpieleGewonnen( int account, int karte ) override; // Gibt zurück, wie oft ein Spieler eine Karte schon gewonnen hat
+	virtual bool hatAccountKarte( int account, int karte ) override; // Gibt zurück, ob ein Spieler die Karte im Besitz hat
+	virtual bool hatAccountSpiel( int account, int spiel ) override; // Gibt zurück, ob ein Spieler ein Spiel im Besitz hat
+    virtual Array< int > *getAccountKarteGespieltListe( int account, int spielId ) override; // gibt eine Liste mit Karten zurück, die von einem Spieler bereits gespielt wurden
+    virtual Array< int > *getAccountSpielGespieltListe( int account ) override; // gibt eine Liste mit Spielen zurück, die von einem Spieler bereits gespielt wurden
+    virtual bool getSpielPartnerListe( int account, Array< int > *spieler, Array< int > *karten, Array< int > *anzahl ) override; // Gibt eine Liste von Spiel Partnern eines Spielers zurück
+	virtual bool getStatistikListe( int account, int *seite, int *maxSeite, char sortSpalte, char rückwärts, 
+                                    RCArray< Array< int > > *werte, RCArray< Text > *namen ) override; // Gibt eine Liste mit Spiel Statistiken zurück
+    virtual AHDaten *getSpielHistorieDaten( int account ) override; // Gibt eine Liste mit den letzten 20 Spielen zurück
+    virtual bool getHistorieServer( int spielId, int *port, Text *ip ) override; // sucht nach dem Historie Server von einem Spiel
+    virtual bool keepAlive() override; // Erhält die Verbindung aufrecht
+    virtual bool hatRecht( int recht ) override; // Prüft ob Berechtigung vorhanden
+	virtual int getKartenListe( char *filter, char sortSpalte, char absteigend, Array< int > *kId, RCArray< Text > *kName, RCArray< Text > *sName,
+                                Array< int > *kupfer, Array< int > *verkauft, Array< int > *maxSpieler ) override; // Gibt eine Liste mit Karten zurück
+	virtual bool getEditorServer( int karteId, int *port, Text *ip ) override; // sucht nach dem Editor Server von einer Karte
+    virtual bool getKartenServer( int karteId, int *port, Text *ip ) override; // sucht nach dem Karten Server von einer Karte
+    virtual bool trenne() override; // trennt sich von dem Informaion Server
+	// constant
+    virtual bool istVerbunden() const override; // prüft, ob mit Informaion Server verbunden
+    virtual char *getLetzterFehler() const override; // gibt den Letzten Fehlertext zuück
+	// Reference Counting
+	virtual InformationKlientV *getThis() override;
+	virtual InformationKlientV *release() override;
+};
+
+class ChatKlient : private Thread
+{
+private:
+	Klient *senden;
+	Klient *empfangen;
+	bool verbunden;
+	Text *fehler;
+	int klientId;
+	int ref;
+	Critical cs;
+
+public:
+	// Konstruktor
+	ChatKlient();
+	// Destruktor 
+	~ChatKlient();
+	// nicht constant
+	bool verbinde(); // verbindet ich mit dem Chat Server
+	bool chatNachricht( int zuAccount, const char *nachricht ); // sendet eine Nachricht zu einem Account
+	bool accountNameÄndern( const char *name ); // ändert den Account Namen
+	bool freundschaftBeenden( int accountId ); // beendet die Freundschaft mit einem Account
+	bool freundesAnfrage( int accountId ); // sendet eine Freundesanfragezu einem Account
+	bool freundesAnfrageBeantworten( int accountId, bool ja ); // beantwortet eine Freundesanfrage
+	int chatroomErstellen( const char *name ); // erstellt ein chatroom
+	bool chatroomEinladung( int accountId, int chatroomId ); // verschickt eine Einladung zu einem Chatroom
+	bool chatroomEinladungAblehnen( int accountId, int chatroomId ); // Einladung zum Chatroom wird abgelehnt
+	bool chatroomBetreten( int chatroomId ); // betritt ein chatroom
+	bool chatroomNachricht( int chatroomId, const char *nachricht ); // chatroom Nachricht senden
+	bool chatroomVerlassen( int chatroomId ); // verlässt chatroom
+	bool chatroomKick( int chatroomId, int accountId ); // kickt Spieler aus Chatroom( nur wenn admin )
+	bool freundesListeAnfragen(); // fragt nach allen freunden
+	bool chatNachrichtAnfrage(); // fragt nach chat nachrichten in abwesenheit
+	bool keepAlive(); // Erhält die Verbindung aufrecht
+	bool trenne(); // trennt sich von dem Chat Server
+	virtual void thread(); // empfangen von Nachrichten
+	// constant
+	bool istVerbunden() const; // prüft, ob mit Chat Server verbunden
+	char *getLetzterFehler() const; // gibt den Letzten Fehlertext zuück
+	// Reference Counting
+	ChatKlient *getThis();
+	ChatKlient *release();
+};
+
+class AnmeldungKlient
+{
+private:
+	Klient *klient;
+	bool verbunden;
+	Text *fehler;
+	int klientId;
+	bool spielHistorie;
+	int ref;
+	Critical cs;
+
+public:
+	// Konstruktor
+	AnmeldungKlient();
+	// Destruktor
+	~AnmeldungKlient();
+	// nicht constant
+	bool verbinde(); // verbindet ich mit dem Chat Server
+	int gruppeErstellen( int karteId ); // erstellt eine gruppe
+	bool gruppeBetreten( int gruppeId, Array< int > *mitglieder, int *anzahl ); // betritt Gruppe
+	bool gruppeVerlassen( int gruppeId ); // Verlässt die gruppe
+	bool gruppeAnmelden( int gruppeId ); // meldet gruppe an
+	bool gruppeAbmelden( int gruppeId ); // meldet gruppe ab
+	bool gruppeSpielerEinladen( int accountId, int gruppeId ); // läht Spieler ein die Gruppe zu betreten
+	bool gruppeEinladungAbbrechen( int accountId, int gruppeId ); // bricht einladung ab
+	bool gruppeEinladungAblehnen( int gruppeId ); // Einladung zur Gruppe ablehnen
+	bool kickSpielerAusGruppe( int accountId, int gruppeId ); // wirft Spieler aus Gruppe
+	bool gruppeSpielStarten( int gruppeId, bool spielStarten ); // startet das Spiel der Gruppe
+	bool gruppeNachricht( int gruppeId, char *nachricht ); // nachricht an gruppe senden
+	bool anmelden( int karteId ); // betritt warteschlange
+	bool abmelden(); // verlässt warteschlange
+	bool keepAlive(); // Erhält die Verbindung aufrecht
+	bool trenne(); // trennt sich von dem Chat Server
+	// constant
+	bool istVerbunden() const; // prüft, ob mit Chat Server verbunden
+	char *getLetzterFehler() const; // gibt den Letzten Fehlertext zuück
+	// Reference Counting
+	AnmeldungKlient *getThis();
+	AnmeldungKlient *release();
+};
+
+class SpielKlient : public SpielKlientV
+{
+private:
+	Klient *senden;
+	Klient *empfangen;
+	bool verbunden;
+	Text *fehler;
+	int klientId;
+	int ref;
+	Critical cs;
+
+public:
+	// Konstruktor
+	SpielKlient();
+	// Destruktor
+	~SpielKlient();
+	// nicht constant
+	virtual bool verbinde( unsigned short port, char *ip ); // verbindet ich mit dem Chat Server
+	virtual bool spielErstelltAnnehmen(); // klient ist bereit dem erstellten Spiel beizutreten
+	virtual bool spielErstelltAblehnen(); // klient ist nicht bereit dem erstellten Spiel beizutreten
+	virtual bool spielErstelltTeamWechseln( int team ); // wechselt das Team
+	virtual bool spielErstelltTeamFertig(); // bestetigt die Team Auswahl
+	virtual bool spielErstelltChatNachricht( char *nachricht ); // sendet eine Chat Nachricht an die mitglieder des erstellten Spiels
+	virtual bool bereitZumLaden(); // Klient ist bereit zum Laden
+	virtual bool setLadenProzent( int prozent ); // Setzt den Fortschritt des Klients
+	virtual bool bereitZumSpiel(); // Klient ist bereit zum Spiel
+	virtual bool spielNachricht( short län, char *bytes ); // Nachricht während des Spiels
+	virtual bool statistikNachricht( short län, char *bytes ); // Nachricht während der Statistik
+	virtual bool keepAlive(); // Erhält die Verbindung aufrecht
+	virtual bool trenne(); // trennt sich von dem Chat Server
+	virtual void thread(); // empfangen von Nachrichten
+	// constant
+	virtual bool istVerbunden() const; // prüft, ob mit Chat Server verbunden
+	virtual char *getLetzterFehler() const; // gibt den Letzten Fehlertext zuück
+	// Reference Counting
+	virtual SpielKlientV *getThis();
+	virtual SpielKlientV *release();
+};
+
+class ShopKlient
+{
+private:
+	Klient *klient;
+	bool verbunden;
+	Text *fehler;
+	int klientId;
+	int ref;
+    Critical cs;
+
+    bool verbinde( int port, char *ip ); // verbindet sich mit vorgegebenem Server 
+
+public:
+	// Konstruktor
+	ShopKlient();
+	// Destruktor
+	~ShopKlient();
+	// nicht constant
+	bool verbinde(); // verbindet sich mit dem Shop Server
+	Array< int > *suchSpiele( const char *suche ); // sucht nach Spielen
+	bool ladeSpielTitel( int id ); // läd Titelbild des Spieles herunter
+	bool ladeSpielSeite( int id ); // läd Seite des Spieles herunter
+	int getSpielBesitzStatus( int id ); // 0 = nicht im Besitz, 1 = Testversion, 2 = gekauft
+	int getSpielTestversion( int id ); // gibt die Anzahl der verbleibenden Spiele zurück
+	int istSpielErwerbbar( int id ); // 0 = nichts, 1 = nur Testversion, 2 = nur Vollversion, 3 = beides
+	int getSpielPreis( int id, bool testVersion ); // gibt den Preis eines Spieles zurück
+	bool spielErwerben( int spielId, bool testVersion ); // Spiel kaufen
+	Array< int > *suchKarten( const char *suche, int spielId ); // sucht nach Karten
+	bool ladeKarteTitel( int id ); // läd Titelbild der Karte herunter
+	bool ladeKarteSeite( int id ); // läd Seite der Karte herunter
+	int getKarteBesitzStatus( int id ); // 0 = nicht im Besitz, 1 = Testversion, 2 = gekauft
+	int getKarteTestversion( int id ); // gibt die Anzahl der verbleibenden Spiele zurück
+	int istKarteErwerbbar( int id ); // prüft, ob die Karte erworben werden kann
+	int getKartePreis( int id, bool testVersion ); // gibt den Preis einer Karte zurück
+	bool karteErwerben( int karteId, bool testVersion ); // Karte kaufen
+	bool keepAlive(); // Erhält die Verbindung aufrecht
+	bool trenne(); // trennt sich von dem Shop Server
+	// constant
+	bool istVerbunden() const; // prüft, ob mit Shop Server verbunden
+	char *getLetzterFehler() const; // gibt den Letzten Fehlertext zuück
+	// Reference Counting
+	ShopKlient *getThis();
+	ShopKlient *release();
+};
+
+class HistorieKlient
+{
+private:
+	Klient *klient;
+	Text *fehler;
+	int klientId;
+	int ref;
+	Critical cs;
+	// privat
+	bool verbinde( char *ip, int port ); // verbindet ich mit dem Historie Server
+	bool trenne(); // trennt sich von dem Historie Server
+
+public:
+	// Konstruktor
+	HistorieKlient();
+	// Destruktor
+	~HistorieKlient();
+	// nicht constant
+	bool downloadSpielHistorie( int spielId ); // läd Spiel Historie herunter
+	// constant
+	bool istVerbunden() const; // prüft, ob mit Historie Server verbunden
+	char *getLetzterFehler() const; // gibt den Letzten Fehlertext zuück
+	// Reference Counting
+	HistorieKlient *getThis();
+	HistorieKlient *release();
+};
+
+class NewsKlient
+{
+private:
+	Klient *klient;
+	bool verbunden;
+	Text *fehler;
+	int klientId;
+	int ref;
+	Critical cs;
+
+public:
+	// Konstruktor
+	NewsKlient();
+	// Destruktor
+	~NewsKlient();
+	// nicht constant
+	bool verbinde(); // verbindet ich mit dem News Server
+	bool ladeSeite( char *name );
+	bool keepAlive(); // Erhält die Verbindung aufrecht
+	bool trenne(); // trennt sich von dem News Server
+	// constant
+	bool istVerbunden() const; // prüft, ob mit News Server verbunden
+	char *getLetzterFehler() const; // gibt den Letzten Fehlertext zuück
+	// Reference Counting
+	NewsKlient *getThis();
+	NewsKlient *release();
+};
+
+class EditorKlient : public EditorKlientV
+{
+private:
+	Klient *klient;
+	bool verbunden;
+	Text *fehler;
+	int klientId;
+	int ref;
+	Critical cs;
+
+public:
+	// Konstruktor
+	EditorKlient();
+	// Destruktor
+	~EditorKlient();
+	// nicht constant
+	bool verbinde( unsigned short port, char *ip ) override; // verbindet ich mit dem Editor Server
+    bool karteErstellen( Text *zName, int spielArt ) override; // Erstellt eine neue Karte
+	bool ladeKarte( int id ) override; // lädt eine bestimmte Karte
+    int getAbbildListe( RCArray< Text > *name, RCArray< Zeit > *datum ) override; // gibt eine Liste mit Abbildern der geladenen Karte zurück
+    bool abbildErstellen( char *name ) override; // Erstellt ein neues Abbild der Karte
+    bool abbildLöschen( char *name ) override; // Löscht ein altes Abbild der Karte
+    bool abbildHerstellen( char *name ) override; // Stellt ein altes Abbild der Karte wieder her
+    bool veröffentlichen() override; // Veröffentlicht die Karte
+    bool shopSeiteVeröffentlichen() override; // Veröffentlicht die Shop Seite
+    bool ladeShopSeiteVorschau() override; // Läht die Vorschau der Shop Seite herrunter
+    bool ssDateiErstellen( char *name, int typ ) override; // Erstellt eine neue Shop Seiten Datei (typ:0=Ordner,1=Bild,2=Text)
+    bool ssOrdnerÖffnen( char *name ) override; // Öffnet einen Ordner der Shop Seite
+    Bild *ssBildLaden( char *datei, char *bild ) override; // Läht das ein Bild der Shop Seite
+    bool ssDateiLöschen( char *name ) override; // Löscht eine Datei der Shop Seite
+    Text *ssTextLaden( char *datei ) override; // Läd eine KSGS Datei der Shop Seite
+    bool ssTextSpeichern( char *datei, Text *zText ) override; // Spechert eine KSGS Datei der Shop Seite
+    bool ssBildLöschen( char *datei, char *bild ) override; // Löscht ein Bild der Shop Seite
+    bool ssBildSpeichern( char *datei, char *name, Bild *zBild ) override; // Speichert ein Bild einer ShopSeite
+    int ssGetDateiListe( RCArray< Text > *zList ) override; // Läd die Datei Liste der Shop Seite
+    int ssGetBildListe( char *name, RCArray< Text > *zList ) override; // Läd die Bild Liste einer Bild Datei der Shop Seite
+    bool getShopDaten( int &es, int &tp, int &vp ) override; // Läht die Shop Daten
+    bool setShopDaten( int es, int tp, int vp ) override; // Setzt die Shop Daten
+    Text *beschreibungLaden() override; // läht die Kartenbeschreibung
+    Bild *titelbildLaden() override; // läht das Titelbild
+    Bild *minimapLaden() override; // läht das Minimapbild
+    Bild *ladebildLaden() override; // läht das Ladebild
+    bool beschreibungSpeichern( Text *zText ) override; // speichert die Kartenbeschreibung
+    bool titelbildSpeichern( Bild *zBild ) override; // speichert das Titelbild
+    bool minimapSpeichern( Bild *zBild ) override; // speichert das Minimapbild
+    bool ladebildSpeichern( Bild *zBild ) override; // speichert das Ladebild
+    bool ladeTeamDaten( SpielerTeamStruktur *sts ) override; // läht die Team Daten
+    bool speicherTeamDaten( SpielerTeamStruktur *sts ) override; // speichert die Team Daten
+    bool deNeueDatei( char typ, Text *zName ) override; // DateienEditor: Erstellt neue Datei (typ: 0=ordner 1=bild 2=modell2d 3=sound
+    bool deOrdnerÖffnen( Text *zName ) override; // DateienEditor: Öffnet Ordner
+    Bild *deBildLaden( Text *zDatei, Text *zBild, FBalken *zF ) override; // DateienEditor: Bild laden
+    bool deDateiLöschen( Text *zName ) override; // DateienEditor: Löscht Datei
+    bool deBildLöschen( Text *zDatei, Text *zBild ) override; // DateienEditor: Löscht Bild aus Datei
+    bool deBildSpeichern( Text *zDatei, Text *zName, Bild *zBild, FBalken *zF ) override; // DateienEditor: Speichert Bild
+    int deGetDateiListe( RCArray< Text > *zNamen ) override; // DateienEditor: Datei Liste herunterladen
+    int deGetBildListe( Text *zDatei, RCArray< Text > *zNamen ) override; // DateienEditor: Liste mit in der Datei gespeicherten Bildern
+    int deGetModelListe( Text *zDatei, RCArray< Text > *zNamen ) override; // DateienEditor Liste mit in der Datei gespeicherten Modellen
+    int deGetSoundListe( Text *zDatei, RCArray< Text > *zNamen ) override; // DateienEditor: Liste mit in der Datei gespeicherten Tönen
+    bool deModelLöschen( Text *zDatei, Text *zModel ) override; // DateienEditor: Löscht Modell
+    bool deSoundLöschen( Text *zDatei, Text *zSound ) override; // DateienEditor: Löscht Ton
+    Model2DData *deModelLaden( Text *zDatei, Text *zModel, FBalken *zF ) override; // DateienEditor: läd ein Model herunter
+    GSL::GSLSoundV *deSoundLaden( Text *zDatei, Text *zSound, FBalken *zF ) override; // DateienEditor: läd Sound herunter
+    bool deModelSpeichern( Text *zDatei, Text *zModel, Model2DData *zData, FBalken *zF ) override; // DateienEditor: Speichert Modell
+    bool deSoundSpeichern( Text *zDatei, Text *zSound, GSL::GSLSoundV *zData, FBalken *zF ) override; // DateienEditor: Speichert Sound
+    bool initEditor() override; // Initialisiert den Editor auf Serverseite
+	bool keepAlive() override; // Erhält die Verbindung aufrecht
+	bool trenne() override; // trennt sich von dem Editor Server
+    void lock() override;
+    void unlock() override;
+    Klient *zKlient() override; // gibt den Klient zurück
+	// constant
+	bool istVerbunden() const override; // prüft, ob mit Editor Server verbunden
+	char *getLetzterFehler() const override; // gibt den Letzten Fehlertext zuück
+	// Reference Counting
+	EditorKlientV *getThis() override;
+	EditorKlientV *release() override;
+};
+
+class KartenKlient
+{
+private:
+    Klient *klient;
+    bool verbunden;
+    Text *fehler;
+    int klientId;
+    int ref;
+    Critical cs;
+
+public:
+    // Konstruktor
+    KartenKlient();
+    // Destruktor
+    ~KartenKlient();
+    // nicht constant
+    bool verbinde( unsigned short port, char *ip ); // verbindet ich mit dem Karten Server
+    bool downloadKarte( int id ); // läd die Karte herunter
+    bool downloadKarteTitel( int id ); // läd das Titelbild einer Karte herunter
+    bool downloadKarteBeschreibung( int id ); // läd die Beschreibung einer Karte herunter
+    bool downloadKarteMinimap( int id ); // läd die Minimap einer Karte herunter
+    bool downloadKarteLadebild( int id ); // läd das Ladebild einer Karte herunter
+    bool keepAlive(); // Erhält die Verbindung aufrecht
+    bool trenne(); // trennt sich von dem Editor Server
+    // constant
+    bool istVerbunden() const; // prüft, ob mit Editor Server verbunden
+    char *getLetzterFehler() const; // gibt den Letzten Fehlertext zuück
+    // Reference Counting
+    KartenKlient *getThis();
+    KartenKlient *release();
+};
+
+#endif

+ 56 - 0
KSGClient/Netzwerk/KSGServer.cpp

@@ -0,0 +1,56 @@
+#include "KSGServer.h"
+#include <Datei.h>
+#include <Text.h>
+#include <InitDatei.h>
+
+using namespace Framework;
+
+char *getMainServerIp()
+{
+	InitDatei *dat = new InitDatei( "data/optionen.ini" );
+	dat->laden();
+	Text *ipT = dat->getWert( "ServerIP" );
+	dat->release();
+	int län = ipT->getLength();
+	char *ret = new char[ län + 1 ];
+	ret[ län ] = 0;
+	for( int i = 0; i < län; i++ )
+		ret[ i ] = ipT->getText()[ i ];
+	ipT->release();
+	return ret;
+}
+
+unsigned short getMainServerPort()
+{
+	InitDatei *dat = new InitDatei( "data/optionen.ini" );
+	dat->laden();
+	unsigned short ret = (unsigned short)TextZuInt( dat->zWert( "ServerPort" )->getText(), 10 );
+	dat->release();
+	return ret;
+}
+
+unsigned int getKlientId()
+{
+	Datei *dat = new Datei();
+	dat->setDatei( "data/tmp/k.id" );
+	dat->open( Datei::Style::lesen );
+	unsigned int ret = 0;
+	dat->lese( (char*)&ret, 4 );
+	dat->close();
+	dat = dat->release();
+	return ret;
+}
+
+char getSchlüssel( char **schlüssel )
+{
+	char län = 0;
+	Datei *dat = new Datei();
+	dat->setDatei( "data/tmp/schlüssel.netw" );
+	dat->open( Datei::Style::lesen );
+	dat->lese( &län, 1 );
+	*schlüssel = new char[ län ];
+	dat->lese( *schlüssel, län );
+	dat->close();
+	dat = dat->release();
+	return län;
+}

+ 20 - 0
KSGClient/Netzwerk/KSGServer.h

@@ -0,0 +1,20 @@
+#ifndef KSGServer_H
+#define KSGServer_H
+
+#ifdef _DEBUG
+#ifndef _LTMDB
+#define _CRTDBG_MAP_ALLOC
+#include <stdlib.h>
+#include <crtdbg.h>
+#define DEBUG_CLIENTBLOCK   new( _CLIENT_BLOCK, __FILE__, __LINE__)
+#define new DEBUG_CLIENTBLOCK
+#define _LTMDB
+#endif
+#endif
+
+char *getMainServerIp();
+unsigned short getMainServerPort();
+unsigned int getKlientId();
+char getSchlüssel( char **schlüssel );
+
+#endif

+ 47 - 0
KSGClient/Netzwerk/KeepAlive.cpp

@@ -0,0 +1,47 @@
+#include "KeepAlive.h"
+#include "../Global/Variablen.h"
+
+// Inhalt der KeepAliveTh Klasse aus KeepAlive.h
+// Konstruktor
+KeepAliveTh::KeepAliveTh()
+	: Thread()
+{
+	exit = 0;
+	start();
+}
+
+// nicht constant
+void KeepAliveTh::thread()
+{
+	while( !exit )
+	{
+		if( loginKlient && loginKlient->istVerbunden() )
+			loginKlient->keepAlive();
+		if( registerKlient && registerKlient->istVerbunden() )
+			registerKlient->keepAlive();
+		if( infoKlient && infoKlient->istVerbunden() )
+			infoKlient->keepAlive();
+		if( chatKlient && chatKlient->istVerbunden() )
+			chatKlient->keepAlive();
+		if( anmeldungKlient && anmeldungKlient->istVerbunden() )
+			anmeldungKlient->keepAlive();
+		if( spielKlient && spielKlient->istVerbunden() )
+			spielKlient->keepAlive();
+		if( shopKlient && shopKlient->istVerbunden() )
+			shopKlient->keepAlive();
+		if( newsKlient && newsKlient->istVerbunden() )
+            newsKlient->keepAlive();
+        if( editorKlient && editorKlient->istVerbunden() )
+            editorKlient->keepAlive();
+        if( kartenKlient && kartenKlient->istVerbunden() )
+            kartenKlient->keepAlive();
+		for( int i = 0; i < 300 && !exit; i++ )
+			Sleep( 100 );
+	}
+	run = 0;
+}
+
+void KeepAliveTh::doExit()
+{
+	exit = 1;
+}

+ 21 - 0
KSGClient/Netzwerk/KeepAlive.h

@@ -0,0 +1,21 @@
+#ifndef KeepAlive_H
+#define KeepAlive_H
+
+#include <Thread.h>
+
+using namespace Framework;
+
+class KeepAliveTh : public Thread
+{
+private:
+	bool exit;
+
+public:
+	// Konstruktor
+	KeepAliveTh();
+	// nicht constant
+	void thread() override;
+	void doExit();
+};
+
+#endif

+ 18 - 0
KSGClient/Netzwerk/Keys.cpp

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

+ 43 - 0
KSGClient/Netzwerk/Keys.h

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

+ 833 - 0
KSGClient/Netzwerk/Klients/AnmeldungK.cpp

@@ -0,0 +1,833 @@
+#include "../KSGKlient.h"
+#include "../KSGServer.h"
+#include "../Keys.h"
+
+// Inhalt der AnmeldungKlient Klasse aus KSGKlient.h
+// Konstruktor
+AnmeldungKlient::AnmeldungKlient()
+{
+    verbunden = 0;
+    klient = 0;
+    fehler = new Text( "" );
+    spielHistorie = 0;
+    klientId = getKlientId();
+    ref = 1;
+}
+
+// Destruktor
+AnmeldungKlient::~AnmeldungKlient()
+{
+    cs.lock();
+    if( klient )
+    {
+        char serverReturn = 0;
+        if( verbunden )
+        {
+            klient->sendeEncrypted( "\4", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            if( serverReturn == 3 )
+            {
+                char län = 0;
+                klient->getNachrichtEncrypted( &län, 1 );
+                char *nachricht = new char[ län + 1 ];
+                nachricht[ län ] = 0;
+                klient->getNachrichtEncrypted( nachricht, län );
+                delete[]nachricht;
+            }
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+        }
+        else
+        {
+            int keyLen = 0;
+            char *key = 0;
+            Keys::getServerKey( &key, keyLen, Keys::ANMELDUNG, Keys::SENDEN );
+            klient->setSendeKey( key, keyLen );
+            delete[] key;
+            Keys::getServerKey( &key, keyLen, Keys::ANMELDUNG, Keys::EMPFANGEN );
+            klient->setEmpfangKey( key, keyLen );
+            delete[] key;
+            klient->verbinde( klient->getServerPort(), klient->getServerIp() );
+            klient->sendeEncrypted( "\1", 1 );
+            klient->sendeEncrypted( (char*)&klientId, 4 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            if( serverReturn == 3 )
+            {
+                char län = 0;
+                klient->getNachrichtEncrypted( &län, 1 );
+                char *nachricht = new char[ län + 1 ];
+                nachricht[ län ] = 0;
+                klient->getNachrichtEncrypted( nachricht, län );
+                delete[]nachricht;
+            }
+            else
+            {
+                char *sl = 0;
+                char slLän = getSchlüssel( &sl );
+                klient->setSendeKey( sl, slLän );
+                klient->setEmpfangKey( sl, slLän );
+                delete[] sl;
+                klient->sendeEncrypted( "\4", 1 );
+                klient->getNachrichtEncrypted( &serverReturn, 1 );
+                if( serverReturn == 3 )
+                {
+                    char län = 0;
+                    klient->getNachrichtEncrypted( &län, 1 );
+                    char *nachricht = new char[ län + 1 ];
+                    nachricht[ län ] = 0;
+                    klient->getNachrichtEncrypted( nachricht, län );
+                    delete[]nachricht;
+                }
+            }
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+        }
+        klient = klient->release();
+    }
+    fehler = fehler->release();
+    cs.unlock();
+}
+
+// nicht constant
+bool AnmeldungKlient::verbinde() // verbindet ich mit dem Chat Server
+{
+    cs.lock();
+    if( verbunden )
+    {
+        cs.unlock();
+        return 1;
+    }
+    spielHistorie = 0;
+    if( !klient )
+    {
+        char *msIp = getMainServerIp();
+        unsigned short msPort = getMainServerPort();
+        klient = new Klient();
+        int keyLen = 0;
+        char *key = 0;
+        Keys::getServerKey( &key, keyLen, Keys::MAIN, Keys::SENDEN );
+        klient->setSendeKey( key, keyLen );
+        delete[] key;
+        Keys::getServerKey( &key, keyLen, Keys::MAIN, Keys::EMPFANGEN );
+        klient->setEmpfangKey( key, keyLen );
+        delete[] key;
+        if( !klient->verbinde( msPort, msIp ) )
+        {
+            fehler->setText( "Fehler beim verbinden mit dem Main Server. Bitte versuche es Später erneut." );
+            klient = klient->release();
+            delete[]msIp;
+            cs.unlock();
+            return 0;
+        }
+        delete[]msIp;
+        klient->sende( "\0", 1 ); // Verschlüsselung aktivieren
+        klient->sendeEncrypted( "\1", 1 );
+        klient->sendeEncrypted( (char*)&klientId, 4 );
+        char serverReturn = 0;
+        klient->getNachrichtEncrypted( &serverReturn, 1 );
+        if( serverReturn == 3 )
+        {
+            char län = 0;
+            klient->getNachrichtEncrypted( &län, 1 );
+            char *nachricht = new char[ län + 1 ];
+            nachricht[ län ] = 0;
+            klient->getNachrichtEncrypted( nachricht, län );
+            fehler->setText( nachricht );
+            delete[]nachricht;
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+            klient = klient->release();
+            cs.unlock();
+            return 0;
+        }
+        char *sl = 0;
+        char slLän = getSchlüssel( &sl );
+        klient->setSendeKey( sl, slLän );
+        klient->setEmpfangKey( sl, slLän );
+        delete[] sl;
+        klient->sendeEncrypted( "\6\6", 2 );
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        if( byte == 2 )
+        {
+            unsigned char lsIp[ 4 ];
+            klient->getNachrichtEncrypted( (char *)lsIp, 4 );
+            unsigned short lsPort = 0;
+            klient->getNachrichtEncrypted( (char*)&lsPort, 2 );
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+            Text *lsIpT = new Text( "" );
+            lsIpT->append( (int)lsIp[ 0 ] );
+            lsIpT->append( "." );
+            lsIpT->append( (int)lsIp[ 1 ] );
+            lsIpT->append( "." );
+            lsIpT->append( (int)lsIp[ 2 ] );
+            lsIpT->append( "." );
+            lsIpT->append( (int)lsIp[ 3 ] );
+            int keyLen = 0;
+            char *key = 0;
+            Keys::getServerKey( &key, keyLen, Keys::ANMELDUNG, Keys::SENDEN );
+            klient->setSendeKey( key, keyLen );
+            delete[] key;
+            Keys::getServerKey( &key, keyLen, Keys::ANMELDUNG, Keys::EMPFANGEN );
+            klient->setEmpfangKey( key, keyLen );
+            delete[] key;
+            klient->verbinde( lsPort, lsIpT->getText() );
+            lsIpT = lsIpT->release();
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+        }
+        if( byte == 3 )
+        {
+            klient->getNachrichtEncrypted( &byte, 1 );
+            char *f = new char[ byte + 1 ];
+            f[ byte ] = 0;
+            klient->getNachrichtEncrypted( f, byte );
+            fehler->setText( f );
+            delete[]f;
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+            klient = klient->release();
+            cs.unlock();
+            return 0;
+        }
+    }
+    int keyLen = 0;
+    char *key = 0;
+    Keys::getServerKey( &key, keyLen, Keys::ANMELDUNG, Keys::SENDEN );
+    klient->setSendeKey( key, keyLen );
+    delete[] key;
+    Keys::getServerKey( &key, keyLen, Keys::ANMELDUNG, Keys::EMPFANGEN );
+    klient->setEmpfangKey( key, keyLen );
+    delete[] key;
+    if( klient->verbinde( klient->getServerPort(), klient->getServerIp() ) )
+    {
+        if( klient->sendeEncrypted( "\1", 1 ) )
+        {
+            klient->sendeEncrypted( (char*)&klientId, 4 );
+            char serverReturn = 0;
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            if( serverReturn == 3 )
+            {
+                char byte = 0;
+                klient->getNachrichtEncrypted( &byte, 1 );
+                char *f = new char[ byte + 1 ];
+                f[ byte ] = 0;
+                klient->getNachrichtEncrypted( f, byte );
+                fehler->setText( f );
+                delete[]f;
+                klient->sendeEncrypted( "\3", 1 );
+                klient->getNachrichtEncrypted( &serverReturn, 1 );
+                klient->trenne();
+                cs.unlock();
+                return 0;
+            }
+            char *sl = 0;
+            char slLän = getSchlüssel( &sl );
+            klient->setSendeKey( sl, slLän );
+            klient->setEmpfangKey( sl, slLän );
+            delete[] sl;
+            verbunden = 1;
+            cs.unlock();
+            return 1;
+        }
+        else
+        {
+            fehler->setText( "Der dir zugewiesene Anmeldung Server hat die Verbindung abgebrochen. Bitte versuche es Später erneut." );
+            klient = klient->release();
+        }
+    }
+    else
+    {
+        fehler->setText( "Der dir zugewiesene Anmeldung Server antwortet nicht. Bitte versuche es Später erneut." );
+        klient = klient->release();
+    }
+    cs.unlock();
+    return 0;
+}
+
+int AnmeldungKlient::gruppeErstellen( int karteId ) // erstellt eine gruppe
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    klient->sendeEncrypted( "\5", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *message = new char[ län + 1 ];
+        message[ län ] = 0;
+        klient->getNachrichtEncrypted( message, län );
+        fehler->setText( message );
+        delete[] message;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&karteId, 4 );
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *message = new char[ län + 1 ];
+        message[ län ] = 0;
+        klient->getNachrichtEncrypted( message, län );
+        fehler->setText( message );
+        delete[] message;
+        cs.unlock();
+        return 0;
+    }
+    int gruppeId = 0;
+    klient->getNachrichtEncrypted( (char*)&gruppeId, 4 );
+    cs.unlock();
+    return gruppeId;
+}
+
+bool AnmeldungKlient::gruppeBetreten( int gruppeId, Array< int > *mitglieder, int *anzahl ) // betritt Gruppe
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    klient->sendeEncrypted( "\x6", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *message = new char[ län + 1 ];
+        message[ län ] = 0;
+        klient->getNachrichtEncrypted( message, län );
+        fehler->setText( message );
+        delete[] message;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&gruppeId, 4 );
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *message = new char[ län + 1 ];
+        message[ län ] = 0;
+        klient->getNachrichtEncrypted( message, län );
+        fehler->setText( message );
+        delete[] message;
+        cs.unlock();
+        return 0;
+    }
+    klient->getNachrichtEncrypted( (char*)anzahl, 4 );
+    for( int i = 0; i < *anzahl; i++ )
+    {
+        int id = 0;
+        klient->getNachrichtEncrypted( (char*)&id, 4 );
+        mitglieder->add( id, i );
+    }
+    cs.unlock();
+    return 1;
+}
+
+bool AnmeldungKlient::gruppeVerlassen( int gruppeId ) // Verlässt die gruppe
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    klient->sendeEncrypted( "\x7", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *message = new char[ län + 1 ];
+        message[ län ] = 0;
+        klient->getNachrichtEncrypted( message, län );
+        fehler->setText( message );
+        delete[] message;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&gruppeId, 4 );
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *message = new char[ län + 1 ];
+        message[ län ] = 0;
+        klient->getNachrichtEncrypted( message, län );
+        fehler->setText( message );
+        delete[] message;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+bool AnmeldungKlient::gruppeAnmelden( int gruppeId ) // meldet gruppe an
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    klient->sendeEncrypted( "\x9", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *message = new char[ län + 1 ];
+        message[ län ] = 0;
+        klient->getNachrichtEncrypted( message, län );
+        fehler->setText( message );
+        delete[] message;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&gruppeId, 4 );
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *message = new char[ län + 1 ];
+        message[ län ] = 0;
+        klient->getNachrichtEncrypted( message, län );
+        fehler->setText( message );
+        delete[] message;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+bool AnmeldungKlient::gruppeAbmelden( int gruppeId ) // meldet gruppe ab
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    klient->sendeEncrypted( "\xA", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *message = new char[ län + 1 ];
+        message[ län ] = 0;
+        klient->getNachrichtEncrypted( message, län );
+        fehler->setText( message );
+        delete[] message;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&gruppeId, 4 );
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *message = new char[ län + 1 ];
+        message[ län ] = 0;
+        klient->getNachrichtEncrypted( message, län );
+        fehler->setText( message );
+        delete[] message;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+bool AnmeldungKlient::gruppeSpielerEinladen( int accountId, int gruppeId ) // läht Spieler ein die Gruppe zu betreten
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    klient->sendeEncrypted( "\xB", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *message = new char[ län + 1 ];
+        message[ län ] = 0;
+        klient->getNachrichtEncrypted( message, län );
+        fehler->setText( message );
+        delete[] message;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&accountId, 4 );
+    klient->sendeEncrypted( (char*)&gruppeId, 4 );
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *message = new char[ län + 1 ];
+        message[ län ] = 0;
+        klient->getNachrichtEncrypted( message, län );
+        fehler->setText( message );
+        delete[] message;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+bool AnmeldungKlient::gruppeEinladungAbbrechen( int accountId, int gruppeId ) // bricht einladung ab
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    klient->sendeEncrypted( "\x11", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *message = new char[ län + 1 ];
+        message[ län ] = 0;
+        klient->getNachrichtEncrypted( message, län );
+        fehler->setText( message );
+        delete[] message;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&gruppeId, 4 );
+    klient->sendeEncrypted( (char*)&accountId, 4 );
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *message = new char[ län + 1 ];
+        message[ län ] = 0;
+        klient->getNachrichtEncrypted( message, län );
+        fehler->setText( message );
+        delete[] message;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+bool AnmeldungKlient::gruppeEinladungAblehnen( int gruppeId ) // Einladung zur Gruppe ablehnen
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    klient->sendeEncrypted( "\x12", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *message = new char[ län + 1 ];
+        message[ län ] = 0;
+        klient->getNachrichtEncrypted( message, län );
+        fehler->setText( message );
+        delete[] message;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&gruppeId, 4 );
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *message = new char[ län + 1 ];
+        message[ län ] = 0;
+        klient->getNachrichtEncrypted( message, län );
+        fehler->setText( message );
+        delete[] message;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+bool AnmeldungKlient::kickSpielerAusGruppe( int accountId, int gruppeId ) // wirft Spieler aus Gruppe
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    klient->sendeEncrypted( "\xC", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *message = new char[ län + 1 ];
+        message[ län ] = 0;
+        klient->getNachrichtEncrypted( message, län );
+        fehler->setText( message );
+        delete[] message;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&accountId, 4 );
+    klient->sendeEncrypted( (char*)&gruppeId, 4 );
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *message = new char[ län + 1 ];
+        message[ län ] = 0;
+        klient->getNachrichtEncrypted( message, län );
+        fehler->setText( message );
+        delete[] message;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+bool AnmeldungKlient::gruppeSpielStarten( int gruppeId, bool spielStarten ) // startet das Spiel der Gruppe
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    klient->sendeEncrypted( "\x10", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *message = new char[ län + 1 ];
+        message[ län ] = 0;
+        klient->getNachrichtEncrypted( message, län );
+        fehler->setText( message );
+        delete[] message;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&gruppeId, 4 );
+    klient->sendeEncrypted( (char*)&spielStarten, 1 );
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *message = new char[ län + 1 ];
+        message[ län ] = 0;
+        klient->getNachrichtEncrypted( message, län );
+        fehler->setText( message );
+        delete[] message;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+bool AnmeldungKlient::gruppeNachricht( int gruppeId, char *nachricht ) // nachricht an gruppe senden
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    char län = textLength( nachricht );
+    if( !län )
+        return 1;
+    cs.lock();
+    klient->sendeEncrypted( "\xD", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *message = new char[ län + 1 ];
+        message[ län ] = 0;
+        klient->getNachrichtEncrypted( message, län );
+        fehler->setText( message );
+        delete[] message;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&gruppeId, 4 );
+    klient->sendeEncrypted( (char*)&län, 1 );
+    klient->sendeEncrypted( nachricht, län );
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *message = new char[ län + 1 ];
+        message[ län ] = 0;
+        klient->getNachrichtEncrypted( message, län );
+        fehler->setText( message );
+        delete[] message;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+bool AnmeldungKlient::anmelden( int karteId ) // betritt warteschlange
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    klient->sendeEncrypted( "\xE", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *message = new char[ län + 1 ];
+        message[ län ] = 0;
+        klient->getNachrichtEncrypted( message, län );
+        fehler->setText( message );
+        delete[] message;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&karteId, 4 );
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *message = new char[ län + 1 ];
+        message[ län ] = 0;
+        klient->getNachrichtEncrypted( message, län );
+        fehler->setText( message );
+        delete[] message;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+bool AnmeldungKlient::abmelden() // verlässt warteschlange
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    klient->sendeEncrypted( "\xF", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *message = new char[ län + 1 ];
+        message[ län ] = 0;
+        klient->getNachrichtEncrypted( message, län );
+        fehler->setText( message );
+        delete[] message;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+bool AnmeldungKlient::keepAlive() // Erhält die Verbindung aufrecht
+{
+    if( !verbunden )
+        return 0;
+    char res = 0;
+    if( !cs.tryLock() )
+        return 1;
+    klient->sendeEncrypted( "\x13", 1 );
+    klient->getNachrichtEncrypted( &res, 1 );
+    cs.unlock();
+    if( res != 1 )
+        trenne();
+    return res == 1;
+}
+
+bool AnmeldungKlient::trenne() // trennt sich von dem Chat Server
+{
+    if( !verbunden )
+        return 1;
+    cs.lock();
+    klient->sendeEncrypted( "\3", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    klient->trenne();
+    verbunden = 0;
+    klient->trenne();
+    cs.unlock();
+    return 1;
+}
+
+// constant
+bool AnmeldungKlient::istVerbunden() const // prüft, ob mit Chat Server verbunden
+{
+    return verbunden;
+}
+
+char *AnmeldungKlient::getLetzterFehler() const // gibt den Letzten Fehlertext zuück
+{
+    return fehler->getText();
+}
+
+// Reference Counting
+AnmeldungKlient *AnmeldungKlient::getThis()
+{
+    ref++;
+    return this;
+}
+
+AnmeldungKlient *AnmeldungKlient::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 1184 - 0
KSGClient/Netzwerk/Klients/ChatK.cpp

@@ -0,0 +1,1184 @@
+#include "../KSGKlient.h"
+#include "../KSGServer.h"
+#include "../../Global/Variablen.h"
+#include "../Keys.h"
+
+// Inhalt der ChatKlient Klasse aus KSGKlient.h
+// Konstruktor
+ChatKlient::ChatKlient()
+{
+    verbunden = 0;
+    senden = 0;
+    empfangen = 0;
+    fehler = new Text( "" );
+    klientId = getKlientId();
+    ref = 1;
+}
+
+// Destruktor 
+ChatKlient::~ChatKlient()
+{
+    cs.lock();
+    if( senden )
+    {
+        char serverReturn = 0;
+        if( verbunden )
+        {
+            senden->sendeEncrypted( "\4", 1 );
+            senden->getNachrichtEncrypted( &serverReturn, 1 );
+            senden->sendeEncrypted( "\3", 1 );
+            senden->getNachrichtEncrypted( &serverReturn, 1 );
+            senden->trenne();
+        }
+        senden = senden->release();
+        verbunden = 0;
+        if( empfangen )
+        {
+            warteAufThread( 5000 );
+            ende();
+            empfangen->trenne();
+            empfangen = empfangen->release();
+        }
+    }
+    fehler = fehler->release();
+    cs.unlock();
+}
+
+// nicht constant
+bool ChatKlient::verbinde() // verbindet ich mit dem Chat Server
+{
+    cs.lock();
+    if( verbunden )
+    {
+        cs.unlock();
+        return 1;
+    }
+    if( !senden )
+    {
+        char *msIp = getMainServerIp();
+        unsigned short msPort = getMainServerPort();
+        senden = new Klient();
+        int keyLen = 0;
+        char *key = 0;
+        Keys::getServerKey( &key, keyLen, Keys::MAIN, Keys::SENDEN );
+        senden->setSendeKey( key, keyLen );
+        delete[] key;
+        Keys::getServerKey( &key, keyLen, Keys::MAIN, Keys::EMPFANGEN );
+        senden->setEmpfangKey( key, keyLen );
+        delete[] key;
+        if( !senden->verbinde( msPort, msIp ) )
+        {
+            fehler->setText( "Fehler beim verbinden mit dem Main Server. Bitte versuche es Später erneut." );
+            senden = senden->release();
+            delete[]msIp;
+            cs.unlock();
+            return 0;
+        }
+        delete[]msIp;
+        senden->sende( "\0", 1 ); // Verschlüsselung aktivieren
+        senden->sendeEncrypted( "\1", 1 );
+        senden->sendeEncrypted( (char*)&klientId, 4 );
+        char serverReturn = 0;
+        senden->getNachrichtEncrypted( &serverReturn, 1 );
+        if( serverReturn == 3 )
+        {
+            char län = 0;
+            senden->getNachrichtEncrypted( &län, 1 );
+            char *nachricht = new char[ län + 1 ];
+            nachricht[ län ] = 0;
+            senden->getNachrichtEncrypted( nachricht, län );
+            fehler->setText( nachricht );
+            delete[]nachricht;
+            senden->sendeEncrypted( "\3", 1 );
+            senden->getNachrichtEncrypted( &serverReturn, 1 );
+            senden->trenne();
+            senden = senden->release();
+            cs.unlock();
+            return 0;
+        }
+        char *sl = 0;
+        char slLän = getSchlüssel( &sl );
+        senden->setSendeKey( sl, slLän );
+        senden->setEmpfangKey( sl, slLän );
+        delete[] sl;
+        senden->sendeEncrypted( "\6\5", 2 );
+        char byte = 0;
+        senden->getNachrichtEncrypted( &byte, 1 );
+        if( byte == 2 )
+        {
+            unsigned char lsIp[ 4 ];
+            senden->getNachrichtEncrypted( (char *)lsIp, 4 );
+            unsigned short lsPort = 0;
+            senden->getNachrichtEncrypted( (char*)&lsPort, 2 );
+            senden->sendeEncrypted( "\3", 1 );
+            senden->getNachrichtEncrypted( &serverReturn, 1 );
+            senden->trenne();
+            Text *lsIpT = new Text( "" );
+            lsIpT->append( (int)lsIp[ 0 ] );
+            lsIpT->append( "." );
+            lsIpT->append( (int)lsIp[ 1 ] );
+            lsIpT->append( "." );
+            lsIpT->append( (int)lsIp[ 2 ] );
+            lsIpT->append( "." );
+            lsIpT->append( (int)lsIp[ 3 ] );
+            int keyLen = 0;
+            char *key = 0;
+            Keys::getServerKey( &key, keyLen, Keys::CHAT, Keys::SENDEN );
+            senden->setSendeKey( key, keyLen );
+            delete[] key;
+            Keys::getServerKey( &key, keyLen, Keys::CHAT, Keys::EMPFANGEN );
+            senden->setEmpfangKey( key, keyLen );
+            delete[] key;
+            senden->verbinde( lsPort, lsIpT->getText() );
+            lsIpT = lsIpT->release();
+            //senden->sendeEncrypted( "\xFF", 1 );
+            senden->sendeEncrypted( "\3", 1 );
+            senden->getNachrichtEncrypted( &serverReturn, 1 );
+            senden->trenne();
+        }
+        if( byte == 3 )
+        {
+            senden->getNachrichtEncrypted( &byte, 1 );
+            char *f = new char[ byte + 1 ];
+            f[ byte ] = 0;
+            senden->getNachrichtEncrypted( f, byte );
+            fehler->setText( f );
+            delete[]f;
+            senden->sendeEncrypted( "\3", 1 );
+            senden->getNachrichtEncrypted( &serverReturn, 1 );
+            senden->trenne();
+            senden = senden->release();
+            cs.unlock();
+            return 0;
+        }
+    }
+    int keyLen = 0;
+    char *key = 0;
+    Keys::getServerKey( &key, keyLen, Keys::CHAT, Keys::SENDEN );
+    senden->setSendeKey( key, keyLen );
+    delete[] key;
+    Keys::getServerKey( &key, keyLen, Keys::CHAT, Keys::EMPFANGEN );
+    senden->setEmpfangKey( key, keyLen );
+    delete[] key;
+    if( senden->verbinde( senden->getServerPort(), senden->getServerIp() ) )
+    {
+        if( senden->sendeEncrypted( "\1", 1 ) )
+        {
+            senden->sendeEncrypted( (char*)&klientId, 4 );
+            char ret = 0;
+            senden->getNachrichtEncrypted( &ret, 1 );
+            if( ret != 1 )
+            {
+                char byte = 0;
+                senden->getNachrichtEncrypted( &byte, 1 );
+                char *f = new char[ byte + 1 ];
+                f[ byte ] = 0;
+                senden->getNachrichtEncrypted( f, byte );
+                fehler->setText( f );
+                delete[]f;
+                senden->sendeEncrypted( "\3", 1 );
+                char serverReturn = 0;
+                senden->getNachrichtEncrypted( &serverReturn, 1 );
+                senden->trenne();
+                cs.unlock();
+                return 0;
+            }
+            char *sl = 0;
+            char slLän = getSchlüssel( &sl );
+            senden->setSendeKey( sl, slLän );
+            senden->setEmpfangKey( sl, slLän );
+            delete[] sl;
+            if( !empfangen )
+                empfangen = new Klient();
+            int keyLen = 0;
+            char *key = 0;
+            Keys::getServerKey( &key, keyLen, Keys::CHAT, Keys::SENDEN );
+            empfangen->setSendeKey( key, keyLen );
+            delete[] key;
+            Keys::getServerKey( &key, keyLen, Keys::CHAT, Keys::EMPFANGEN );
+            empfangen->setEmpfangKey( key, keyLen );
+            delete[] key;
+            if( empfangen->verbinde( senden->getServerPort(), senden->getServerIp() ) )
+            {
+                start();
+                verbunden = 1;
+                cs.unlock();
+                return 1;
+            }
+            else
+            {
+                fehler->setText( "Der dir zugewiesene Chat Server kann dir keine Nachrichten senden." );
+                cs.unlock();
+                return 1;
+            }
+        }
+        else
+        {
+            fehler->setText( "Der dir zugewiesene Chat Server hat die Verbindung abgebrochen. Bitte versuche es Später erneut." );
+            senden = senden->release();
+        }
+    }
+    else
+    {
+        fehler->setText( "Der dir zugewiesene Chat Server antwortet nicht. Bitte versuche es Später erneut." );
+        senden = senden->release();
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool ChatKlient::chatNachricht( int zuAccount, const char *nachricht ) // sendet eine Nachricht zu einem Account
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    char län = textLength( nachricht );
+    if( !län )
+        return 1;
+    cs.lock();
+    senden->sendeEncrypted( "\6", 1 );
+    char serverReturn = 0;
+    senden->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn )
+    {
+        senden->sendeEncrypted( (char*)&zuAccount, 4 );
+        senden->sendeEncrypted( &län, 1 );
+        senden->sendeEncrypted( nachricht, län );
+    }
+    else
+    {
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+bool ChatKlient::accountNameÄndern( const char *name ) // ändert den Account Namen
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    char län = textLength( name );
+    if( !län )
+        return 1;
+    cs.lock();
+    senden->sendeEncrypted( "\x8", 1 );
+    char serverReturn = 0;
+    senden->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn )
+    {
+        senden->sendeEncrypted( &län, 1 );
+        senden->sendeEncrypted( name, län );
+        senden->getNachrichtEncrypted( &serverReturn, 1 );
+        cs.unlock();
+        return serverReturn == 1;
+    }
+    else
+    {
+        cs.unlock();
+        return 0;
+    }
+}
+
+bool ChatKlient::freundschaftBeenden( int accountId ) // beendet die Freundschaft mit einem Account
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    senden->sendeEncrypted( "\x9", 1 );
+    char serverReturn = 0;
+    senden->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn )
+    {
+        senden->sendeEncrypted( (char*)&accountId, 4 );
+        senden->getNachrichtEncrypted( &serverReturn, 1 );
+        cs.unlock();
+        return serverReturn == 1;
+    }
+    else
+    {
+        cs.unlock();
+        return 0;
+    }
+}
+
+bool ChatKlient::freundesAnfrage( int accountId ) // sendet eine Freundesanfragezu einem Account
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    senden->sendeEncrypted( "\xA", 1 );
+    char serverReturn = 0;
+    senden->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn )
+    {
+        senden->sendeEncrypted( (char*)&accountId, 4 );
+        senden->getNachrichtEncrypted( &serverReturn, 1 );
+        cs.unlock();
+        return serverReturn == 1;
+    }
+    else
+    {
+        cs.unlock();
+        return 0;
+    }
+}
+
+bool ChatKlient::freundesAnfrageBeantworten( int accountId, bool ja ) // beantwortet eine Freundesanfrage
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    senden->sendeEncrypted( "\xB", 1 );
+    char serverReturn = 0;
+    senden->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn )
+    {
+        senden->sendeEncrypted( (char*)&accountId, 4 );
+        char ok = (char)ja;
+        senden->sendeEncrypted( &ok, 1 );
+        senden->getNachrichtEncrypted( &serverReturn, 1 );
+        cs.unlock();
+        return serverReturn == 1;
+    }
+    else
+    {
+        cs.unlock();
+        return 0;
+    }
+}
+
+int ChatKlient::chatroomErstellen( const char *name ) // erstellt ein chatroom
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    char län = textLength( name );
+    if( !län )
+        return 0;
+    cs.lock();
+    senden->sendeEncrypted( "\xC", 1 );
+    char serverReturn = 0;
+    senden->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn )
+    {
+        senden->sendeEncrypted( &län, 1 );
+        senden->sendeEncrypted( name, län );
+        senden->getNachrichtEncrypted( &serverReturn, 1 );
+        if( !serverReturn )
+        {
+            cs.unlock();
+            return 0;
+        }
+        int ret = 0;
+        senden->getNachrichtEncrypted( (char*)&ret, 4 );
+        cs.unlock();
+        return ret;
+    }
+    else
+    {
+        cs.unlock();
+        return 0;
+    }
+}
+
+bool ChatKlient::chatroomEinladung( int accountId, int chatroomId ) // verschickt eine Einladung zu einem Chatroom
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    senden->sendeEncrypted( "\xD", 1 );
+    char serverReturn = 0;
+    senden->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn )
+    {
+        senden->sendeEncrypted( (char*)&accountId, 4 );
+        senden->sendeEncrypted( (char*)&chatroomId, 4 );
+        senden->getNachrichtEncrypted( &serverReturn, 1 );
+        cs.unlock();
+        return serverReturn == 1;
+    }
+    else
+    {
+        cs.unlock();
+        return 0;
+    }
+}
+
+bool ChatKlient::chatroomEinladungAblehnen( int accountId, int chatroomId ) // Einladung zum Chatroom wird abgelehnt
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    senden->sendeEncrypted( "\xE", 1 );
+    char serverReturn = 0;
+    senden->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn )
+    {
+        senden->sendeEncrypted( (char*)&accountId, 4 );
+        senden->sendeEncrypted( (char*)&chatroomId, 4 );
+        senden->getNachrichtEncrypted( &serverReturn, 1 );
+        cs.unlock();
+        return serverReturn == 1;
+    }
+    else
+    {
+        cs.unlock();
+        return 0;
+    }
+}
+
+bool ChatKlient::chatroomBetreten( int chatroomId ) // betritt ein chatroom
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    senden->sendeEncrypted( "\xF", 1 );
+    char serverReturn = 0;
+    senden->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn )
+    {
+        senden->sendeEncrypted( (char*)&chatroomId, 4 );
+        senden->getNachrichtEncrypted( &serverReturn, 1 );
+        cs.unlock();
+        return serverReturn == 1;
+    }
+    else
+    {
+        cs.unlock();
+        return 0;
+    }
+}
+
+bool ChatKlient::chatroomNachricht( int chatroomId, const char *nachricht ) // chatroom Nachricht senden
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    char län = textLength( nachricht );
+    if( !län )
+        return 0;
+    cs.lock();
+    senden->sendeEncrypted( "\x10", 1 );
+    char serverReturn = 0;
+    senden->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn )
+    {
+        senden->sendeEncrypted( (char*)&chatroomId, 4 );
+        senden->sendeEncrypted( &län, 1 );
+        senden->sendeEncrypted( nachricht, län );
+        senden->getNachrichtEncrypted( &serverReturn, 1 );
+        cs.unlock();
+        return serverReturn == 1;
+    }
+    else
+    {
+        cs.unlock();
+        return 0;
+    }
+}
+
+bool ChatKlient::chatroomVerlassen( int chatroomId ) // verlässt chatroom
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    senden->sendeEncrypted( "\x11", 1 );
+    char serverReturn = 0;
+    senden->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn )
+    {
+        senden->sendeEncrypted( (char*)&chatroomId, 4 );
+        senden->getNachrichtEncrypted( &serverReturn, 1 );
+        cs.unlock();
+        return serverReturn == 1;
+    }
+    else
+    {
+        cs.unlock();
+        return 0;
+    }
+}
+
+bool ChatKlient::chatroomKick( int chatroomId, int accountId ) // kickt Spieler aus Chatroom( nur wenn admin )
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    senden->sendeEncrypted( "\x12", 1 );
+    char serverReturn = 0;
+    senden->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn )
+    {
+        senden->sendeEncrypted( (char*)&chatroomId, 4 );
+        senden->sendeEncrypted( (char*)&accountId, 4 );
+        senden->getNachrichtEncrypted( &serverReturn, 1 );
+        cs.unlock();
+        return serverReturn == 1;
+    }
+    else
+    {
+        cs.unlock();
+        return 0;
+    }
+}
+
+bool ChatKlient::freundesListeAnfragen() // fragt nach allen freunden
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    char serverReturn = 0;
+    cs.lock();
+    senden->sendeEncrypted( "\x13", 1 );
+    senden->getNachrichtEncrypted( &serverReturn, 1 );
+    cs.unlock();
+    return serverReturn == 1;
+}
+
+bool ChatKlient::chatNachrichtAnfrage() // fragt nach chat nachrichten in abwesenheit
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    char serverReturn = 0;
+    cs.lock();
+    senden->sendeEncrypted( "\x14", 1 );
+    senden->getNachrichtEncrypted( &serverReturn, 1 );
+    cs.unlock();
+    return serverReturn == 1;
+}
+
+bool ChatKlient::keepAlive() // Erhält die Verbindung aufrecht
+{
+    if( !verbunden )
+        return 0;
+    char res = 0;
+    if( !cs.tryLock() )
+        return 1;
+    senden->sendeEncrypted( "\x15", 1 );
+    senden->getNachrichtEncrypted( &res, 1 );
+    cs.unlock();
+    if( res != 1 )
+        trenne();
+    return res == 1;
+}
+
+bool ChatKlient::trenne() // trennt sich von dem Chat Server
+{
+    if( !verbunden )
+        return 1;
+    cs.lock();
+    senden->sendeEncrypted( "\3", 1 );
+    char serverReturn = 0;
+    senden->getNachrichtEncrypted( &serverReturn, 1 );
+    senden->trenne();
+    verbunden = 0;
+    warteAufThread( 5000 );
+    ende();
+    if( empfangen )
+        empfangen->trenne();
+    cs.unlock();
+    return 1;
+}
+
+void ChatKlient::thread() // empfangen von Nachrichten
+{
+    if( !verbunden || !empfangen || !senden )
+        return;
+    empfangen->sendeEncrypted( "\1", 1 );
+    empfangen->sendeEncrypted( (char*)&klientId, 4 );
+    char res = 0;
+    empfangen->getNachrichtEncrypted( &res, 1 );
+    if( res == 3 )
+    {
+        char län = 0;
+        senden->getNachrichtEncrypted( &län, 1 );
+        char *nachricht = new char[ län + 1 ];
+        nachricht[ län ] = 0;
+        senden->getNachrichtEncrypted( nachricht, län );
+        fehler->setText( nachricht );
+        delete[]nachricht;
+    }
+    if( res != 1 )
+    {
+        WMessageBox( 0, new Text( "Fehler" ), new Text( "Server akzeptiert den Klient nicht" ), MB_ICONERROR );
+        return;
+    }
+    char *sl = 0;
+    char slLän = getSchlüssel( &sl );
+    empfangen->setSendeKey( sl, slLän );
+    empfangen->setEmpfangKey( sl, slLän );
+    delete[] sl;
+    char befehl = 0;
+    while( verbunden )
+    {
+        if( !empfangen->getNachrichtEncrypted( &befehl, 1 ) )
+            return;
+        switch( befehl )
+        {
+        case 0: // verbindung getrennt
+            return;
+            break;
+        case 1: // kick
+            if( 1 )
+            {
+                loginKlient->trenne();
+                infoKlient->trenne();
+                chatKlient->trenne();
+                aktion = 4;
+            }
+            break;
+        case 2: // Server Ausgelastet
+            aktion = 1;
+            if( nachLogin && nachLogin->zNachrichtenListe() )
+            {
+                hauptScreen->lock();
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Server Ausgelastet" ),
+                                                              new Text( "Der Chat Server ist derzeit ausgelastet. Es wird versucht auf einen anderen Server auszuweichen." ),
+                                                              new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+                hauptScreen->unlock();
+            }
+            break;
+        case 3: // Fehler
+            if( 1 )
+            {
+                char länge = 0;
+                empfangen->getNachrichtEncrypted( &länge, 1 );
+                char *txt = new char[ länge + 1 ];
+                txt[ länge ] = 0;
+                empfangen->getNachrichtEncrypted( txt, länge );
+                hauptScreen->lock();
+                if( nachLogin && nachLogin->zNachrichtenListe() )
+                    nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( txt ), new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+                hauptScreen->unlock();
+                delete[]txt;
+            }
+            break;
+        case 4: // Chat Nachricht
+            if( 1 )
+            {
+                int vonAccount = 0;
+                empfangen->getNachrichtEncrypted( (char*)&vonAccount, 4 );
+                char länge = 0;
+                empfangen->getNachrichtEncrypted( &länge, 1 );
+                char *nachricht = new char[ länge + 1 ];
+                nachricht[ länge ] = 0;
+                empfangen->getNachrichtEncrypted( nachricht, länge );
+                if( nachLogin && nachLogin->zChatLeiste() )
+                {
+                    hauptScreen->lock();
+                    nachLogin->zChatLeiste()->chatNachricht( vonAccount, nachricht );
+                    hauptScreen->unlock();
+                }
+                delete[]nachricht;
+            }
+            break;
+        case 5: // Spiel Einladung
+            if( 1 )
+            {
+                int vonAccount = 0;
+                empfangen->getNachrichtEncrypted( (char*)&vonAccount, 4 );
+                int gruppeId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&gruppeId, 4 );
+                if( nachLogin && nachLogin->zNachrichtenListe() )
+                {
+                    int karteId = infoKlient->getGruppenKarteId( gruppeId );
+                    int spielId = infoKlient->getSpielId( karteId );
+                    Text *spiel = infoKlient->getSpielName( spielId );
+                    Text *karte = infoKlient->getKarteName( karteId );
+                    Text *name = infoKlient->getSpielerName( vonAccount );
+                    Text *titel = new Text( "Spiel Einladung" );
+                    Text *nachricht = new Text( "Von: " );
+                    nachricht->append( name );
+                    nachricht->append( "\nSpiel: " );
+                    nachricht->append( spiel );
+                    nachricht->append( "\nKarte: " );
+                    nachricht->append( karte );
+                    SpielEinladungParam *param = new SpielEinladungParam();
+                    param->gruppeId = gruppeId;
+                    param->vonAccount = vonAccount;
+                    hauptScreen->lock();
+                    nachLogin->zNachrichtenListe()->addNachricht( titel, nachricht, new Text( "annehmen" ), new Text( "ablehnen" ), NachrichtType::spielEinladung, param );
+                    hauptScreen->unlock();
+                }
+            }
+            break;
+        case 6: // Account Status ändert sich
+            if( 1 )
+            {
+                int accountId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&accountId, 4 );
+                char län = 0;
+                empfangen->getNachrichtEncrypted( &län, 1 );
+                char *status = new char[ län + 1 ];
+                status[ län ] = 0;
+                empfangen->getNachrichtEncrypted( status, län );
+                hauptScreen->lock();
+                if( nachLogin && nachLogin->zNachrichtenListe() )
+                    nachLogin->zFreundesListe()->setStatus( accountId, status );
+                hauptScreen->unlock();
+                delete[]status;
+            }
+            break;
+        case 7: // Account Name ändert sich
+            if( 1 )
+            {
+                int accountId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&accountId, 4 );
+                char län = 0;
+                empfangen->getNachrichtEncrypted( &län, 1 );
+                char *name = new char[ län + 1 ];
+                name[ län ] = 0;
+                empfangen->getNachrichtEncrypted( name, län );
+                hauptScreen->lock();
+                if( nachLogin && nachLogin->zNachrichtenListe() )
+                    nachLogin->zFreundesListe()->setName( accountId, name );
+                hauptScreen->unlock();
+                delete[]name;
+            }
+            break;
+        case 8: // kein Freund mehr
+            if( 1 )
+            {
+                int accountId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&accountId, 4 );
+                hauptScreen->lock();
+                if( nachLogin && nachLogin->zNachrichtenListe() )
+                    nachLogin->zFreundesListe()->removeMember( accountId );
+                hauptScreen->unlock();
+            }
+            break;
+        case 9: // Freundesanfrage
+            if( 1 )
+            {
+                int vonAccount = 0;
+                empfangen->getNachrichtEncrypted( (char*)&vonAccount, 4 );
+                if( nachLogin->zNachrichtenListe() )
+                {
+                    Text *titel = new Text( "Freundeseinladung" );
+                    Text *nachricht = new Text( "" );
+                    nachricht->append( infoKlient->getSpielerName( vonAccount ) );
+                    nachricht->append( " möchte sich mit dir befreunden." );
+                    int *accountId = new int;
+                    *accountId = vonAccount;
+                    hauptScreen->lock();
+                    if( nachLogin && nachLogin->zNachrichtenListe() )
+                    {
+                        nachLogin->zNachrichtenListe()->addNachricht( titel, nachricht, new Text( "annehmen" ), new Text( "ablehnen" ),
+                                                                      NachrichtType::freundEinladung, (void*)accountId );
+                    }
+                    hauptScreen->unlock();
+                }
+            }
+            break;
+        case 0xA: // Neuer Freund
+            if( 1 )
+            {
+                int accountId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&accountId, 4 );
+                hauptScreen->lock();
+                if( nachLogin && nachLogin->zNachrichtenListe() )
+                    nachLogin->zFreundesListe()->addMember( accountId );
+                hauptScreen->unlock();
+            }
+            break;
+        case 0xB: // Freundesanfrage abgelehnt
+            if( 1 )
+            {
+                int vonAccount = 0;
+                empfangen->getNachrichtEncrypted( (char*)&vonAccount, 4 );
+                if( nachLogin && nachLogin->zNachrichtenListe() )
+                {
+                    Text *titel = new Text( "Freundeseinladung Abgelehnt" );
+                    Text *nachricht = new Text( "" );
+                    nachricht->append( infoKlient->getSpielerName( vonAccount ) );
+                    nachricht->append( " hat deine Freundesanfrage abgelehnt." );
+                    hauptScreen->lock();
+                    nachLogin->zNachrichtenListe()->addNachricht( titel, nachricht, new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+                    hauptScreen->unlock();
+                }
+            }
+            break;
+        case 0xC: // Einladung zum Chatroom
+            if( 1 )
+            {
+                int vonAccount = 0;
+                empfangen->getNachrichtEncrypted( (char*)&vonAccount, 4 );
+                int chatroomId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&chatroomId, 4 );
+                if( nachLogin && nachLogin->zNachrichtenListe() )
+                {
+                    Text *titel = new Text( "Chatroom Einladung" );
+                    Text *nachricht = new Text( "" );
+                    nachricht->append( infoKlient->getSpielerName( vonAccount ) );
+                    nachricht->append( " lädt dich dazu ein das Chatroom '" );
+                    nachricht->append( infoKlient->getChatroomName( chatroomId ) );
+                    nachricht->append( "' zu betreten." );
+                    ChatroomEinladungParam *param = new ChatroomEinladungParam();
+                    param->chatroomId = chatroomId;
+                    param->vonAccount = vonAccount;
+                    nachLogin->zNachrichtenListe()->addNachricht( titel, nachricht, new Text( "betreten" ), new Text( "ablehnen" ), NachrichtType::chatroomEinladung, param );
+                }
+            }
+            break;
+        case 0xD: // Einladung zum Chatroom abgelehnt
+            if( 1 )
+            {
+                int accountId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&accountId, 4 );
+                int chatroomId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&chatroomId, 4 );
+                if( nachLogin && nachLogin->zNachrichtenListe() )
+                {
+                    Text *titel = new Text( "Chatroom Einladung Abgelehnt" );
+                    Text *nachricht = new Text( "" );
+                    nachricht->append( infoKlient->getSpielerName( accountId ) );
+                    nachricht->append( " möchte dem Chatroom '" );
+                    nachricht->append( infoKlient->getChatroomName( chatroomId ) );
+                    nachricht->append( "' nicht beitreten." );
+                    hauptScreen->lock();
+                    nachLogin->zNachrichtenListe()->addNachricht( titel, nachricht, new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+                    hauptScreen->unlock();
+                }
+            }
+            break;
+        case 0xE: // Spieler betritt Chatroom
+            if( 1 )
+            {
+                int chatroomId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&chatroomId, 4 );
+                int accountId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&accountId, 4 );
+                hauptScreen->lock();
+                if( nachLogin && nachLogin->zChatLeiste() )
+                    nachLogin->zChatLeiste()->addSpieler( chatroomId, accountId );
+                hauptScreen->unlock();
+            }
+            break;
+        case 0xF: // Chatroom Nachricht
+            if( 1 )
+            {
+                int chatroomId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&chatroomId, 4 );
+                int vonAccount = 0;
+                empfangen->getNachrichtEncrypted( (char*)&vonAccount, 4 );
+                char län = 0;
+                empfangen->getNachrichtEncrypted( &län, 1 );
+                char *nachricht = new char[ län + 1 ];
+                nachricht[ län ] = 0;
+                if( län )
+                {
+                    empfangen->getNachrichtEncrypted( nachricht, län );
+                    hauptScreen->lock();
+                    if( nachLogin && nachLogin->zChatLeiste() )
+                        nachLogin->zChatLeiste()->chatroomNachricht( chatroomId, vonAccount, nachricht );
+                    hauptScreen->unlock();
+                }
+                delete[]nachricht;
+            }
+            break;
+        case 0x10: // Spieler verlässt Chatroom
+            if( 1 )
+            {
+                int chatroomId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&chatroomId, 4 );
+                int accountId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&accountId, 4 );
+                hauptScreen->lock();
+                if( nachLogin && nachLogin->zChatLeiste() )
+                    nachLogin->zChatLeiste()->removeSpieler( chatroomId, accountId );
+                hauptScreen->unlock();
+            }
+            break;
+        case 0x11: // Freunde
+            if( 1 )
+            {
+                char freundeAnzahl;
+                empfangen->getNachrichtEncrypted( &freundeAnzahl, 1 );
+                for( int i = 0; i < freundeAnzahl; i++ )
+                {
+                    int accountId = 0;
+                    empfangen->getNachrichtEncrypted( (char*)&accountId, 4 );
+                    if( nachLogin )
+                    {
+                        while( !nachLogin->zFreundesListe() )
+                        {
+                            Sleep( 50 );
+                        }
+                        hauptScreen->lock();
+                        nachLogin->zFreundesListe()->addMember( accountId );
+                        hauptScreen->unlock();
+                    }
+                }
+            }
+            break;
+        case 0x12: // Spieler im Chatroom
+            if( 1 )
+            {
+                int chatroomId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&chatroomId, 4 );
+                char anzahl = 0;
+                empfangen->getNachrichtEncrypted( &anzahl, 1 );
+                for( char i = 0; i < anzahl; i++ )
+                {
+                    int accountId = 0;
+                    empfangen->getNachrichtEncrypted( (char*)&accountId, 4 );
+                    hauptScreen->lock();
+                    if( nachLogin && nachLogin->zChatLeiste() )
+                        nachLogin->zChatLeiste()->addSpieler( chatroomId, accountId );
+                    hauptScreen->unlock();
+                }
+            }
+            break;
+        case 0x13: // Freund online
+            if( 1 )
+            {
+                int accountId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&accountId, 4 );
+                hauptScreen->lock();
+                if( nachLogin && nachLogin->zFreundesListe() )
+                    nachLogin->zFreundesListe()->setOnline( accountId, 1 );
+                hauptScreen->unlock();
+            }
+            break;
+        case 0x14: // Freund offline
+            if( 1 )
+            {
+                int accountId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&accountId, 4 );
+                hauptScreen->lock();
+                if( nachLogin && nachLogin->zFreundesListe() )
+                    nachLogin->zFreundesListe()->setOnline( accountId, 0 );
+                hauptScreen->unlock();
+            }
+            break;
+        case 0x15: // Chatroom Admin
+            if( 1 )
+            {
+                int chatroomId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&chatroomId, 4 );
+                hauptScreen->lock();
+                if( nachLogin && nachLogin->zChatLeiste() )
+                    nachLogin->zChatLeiste()->setChatroomAdmin( chatroomId );
+                hauptScreen->unlock();
+            }
+            break;
+        case 0x16: // Chatroom Kick
+            if( 1 )
+            {
+                int chatroomId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&chatroomId, 4 );
+                hauptScreen->lock();
+                if( nachLogin && nachLogin->zChatLeiste() )
+                    nachLogin->zChatLeiste()->removeChat( 0, chatroomId );
+                hauptScreen->unlock();
+            }
+            break;
+        case 0x17: // Spieler betritt Gruppe
+            if( 1 )
+            {
+                int accountId = 0;
+                int gruppeId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&accountId, 4 );
+                empfangen->getNachrichtEncrypted( (char*)&gruppeId, 4 );
+                if( nachLogin && nachLogin->zSpielenFenster() )
+                    nachLogin->zSpielenFenster()->spielerBetrittGruppe( gruppeId, accountId );
+            }
+            break;
+        case 0x18: // Spieler verlässt Gruppe
+            if( 1 )
+            {
+                int accountId = 0;
+                int gruppeId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&accountId, 4 );
+                empfangen->getNachrichtEncrypted( (char*)&gruppeId, 4 );
+                if( nachLogin && nachLogin->zSpielenFenster() )
+                    nachLogin->zSpielenFenster()->spielerVerlässtGruppe( gruppeId, accountId );
+            }
+            break;
+        case 0x19: // gruppe Nachricht
+            if( 1 )
+            {
+                int gruppeId = 0;
+                char län = 0;
+                empfangen->getNachrichtEncrypted( (char*)&gruppeId, 4 );
+                empfangen->getNachrichtEncrypted( &län, 1 );
+                if( län )
+                {
+                    char *nachricht = new char[ län + 1 ];
+                    nachricht[ län ] = 0;
+                    empfangen->getNachrichtEncrypted( nachricht, län );
+                    if( nachLogin && nachLogin->zSpielenFenster() )
+                        nachLogin->zSpielenFenster()->gruppeNachricht( gruppeId, nachricht );
+                    delete[] nachricht;
+                }
+            }
+            break;
+        case 0x1A: // gruppe Angemeldet
+            if( 1 )
+            {
+                int gruppeId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&gruppeId, 4 );
+                if( nachLogin && nachLogin->zSpielenFenster() )
+                    nachLogin->zSpielenFenster()->gruppeAnmelden( gruppeId );
+            }
+            break;
+        case 0x1B: // gruppe Abgemeldet
+            if( 1 )
+            {
+                int gruppeId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&gruppeId, 4 );
+                if( nachLogin && nachLogin->zSpielenFenster() )
+                    nachLogin->zSpielenFenster()->gruppeAbmelden( gruppeId );
+            }
+            break;
+        case 0x1C: // gruppe Spiel starten
+            if( 1 )
+            {
+                int gruppeId = 0;
+                char starten = 0;
+                empfangen->getNachrichtEncrypted( (char*)&gruppeId, 4 );
+                empfangen->getNachrichtEncrypted( &starten, 1 );
+                if( nachLogin && nachLogin->zSpielenFenster() )
+                    nachLogin->zSpielenFenster()->setGruppeSpielStarten( gruppeId, starten == 1 );
+            }
+            break;
+        case 0x1D: // kick aus Gruppe
+            if( 1 )
+            {
+                int gruppeId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&gruppeId, 4 );
+                if( nachLogin && nachLogin->zSpielenFenster() )
+                    nachLogin->zSpielenFenster()->kickAusGruppe( gruppeId );
+            }
+            break;
+        case 0x1E: // gruppe Admin
+            if( 1 )
+            {
+                int gruppeId = 0;
+                int adminId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&gruppeId, 4 );
+                empfangen->getNachrichtEncrypted( (char*)&adminId, 4 );
+                if( nachLogin && nachLogin->zSpielenFenster() )
+                    nachLogin->zSpielenFenster()->setGruppeAdmin( gruppeId, adminId );
+            }
+            break;
+        case 0x1F: // gruppe Einladung abgelehnt
+            if( 1 )
+            {
+                int gruppeId;
+                int accountId;
+                empfangen->getNachrichtEncrypted( (char*)&gruppeId, 4 );
+                empfangen->getNachrichtEncrypted( (char*)&accountId, 4 );
+                if( nachLogin && nachLogin->zSpielenFenster() )
+                    nachLogin->zSpielenFenster()->gruppeEinadungAbgelehnt( gruppeId, accountId );
+            }
+            break;
+        case 0x20: // SpielServer Verbindungs Anfrage
+            if( 1 )
+            {
+                unsigned short port;
+                unsigned char *ip = new unsigned char[ 4 ];
+                empfangen->getNachrichtEncrypted( (char*)&port, 2 );
+                empfangen->getNachrichtEncrypted( (char*)ip, 4 );
+                Text *ipT = new Text( "" );
+                ipT->append( (int)ip[ 0 ] );
+                ipT->append( "." );
+                ipT->append( (int)ip[ 1 ] );
+                ipT->append( "." );
+                ipT->append( (int)ip[ 2 ] );
+                ipT->append( "." );
+                ipT->append( (int)ip[ 3 ] );
+                spielKlient->verbinde( port, ipT->getText() );
+                delete[] ip;
+                ipT->release();
+            }
+            break;
+        case 0x21: // Gruppe Einladung abgebrochen
+            if( 1 )
+            {
+                int gruppeId = 0;
+                int account = 0;
+                empfangen->getNachrichtEncrypted( (char*)&gruppeId, 4 );
+                empfangen->getNachrichtEncrypted( (char*)&account, 4 );
+                if( nachLogin && nachLogin->zSpielenFenster() )
+                    nachLogin->zSpielenFenster()->gruppeEinladungAbgebrochen( gruppeId, account );
+            }
+            break;
+        case 0x22: // Gruppe Einladung hinzufügen
+            if( 1 )
+            {
+                int gruppeId = 0;
+                int account = 0;
+                empfangen->getNachrichtEncrypted( (char*)&gruppeId, 4 );
+                empfangen->getNachrichtEncrypted( (char*)&account, 4 );
+                if( nachLogin && nachLogin->zSpielenFenster() )
+                    nachLogin->zSpielenFenster()->gruppeEinladungNeu( gruppeId, account );
+            }
+            break;
+        case 0x23: // ping
+            empfangen->sendeEncrypted( "\1", 1 );
+            break;
+        default: // Unbekannte Servernachricht
+            if( nachLogin && nachLogin->zNachrichtenListe() )
+            {
+                hauptScreen->lock();
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                              new Text( "Unbekannte Nachricht vom Server. Eventuel ist der Client nicht mehr Aktuell." ),
+                                                              new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+                hauptScreen->unlock();
+            }
+            break;
+        }
+    }
+}
+
+// constant
+bool ChatKlient::istVerbunden() const // prüft, ob mit Chat Server verbunden
+{
+    return verbunden;
+}
+
+char *ChatKlient::getLetzterFehler() const // gibt den Letzten Fehlertext zuück
+{
+    return fehler->getText();
+}
+
+// Reference Counting
+ChatKlient *ChatKlient::getThis()
+{
+    ref++;
+    return this;
+}
+
+ChatKlient *ChatKlient::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 2829 - 0
KSGClient/Netzwerk/Klients/EditorK.cpp

@@ -0,0 +1,2829 @@
+#include "../KSGKlient.h"
+#include "../KSGServer.h"
+#include <Datei.h>
+#include "../../Global/Variablen.h"
+#include <GSLDateiV.h>
+#include "../Keys.h"
+
+typedef GSL::GSLDateiV *( *GetGSLDatei )( );
+
+class DownloadSound : public GSL::GSLSoundV
+{
+private:
+    bool istM;
+    int sample;
+    __int64 län;
+    Klient *k;
+    FBalken *f;
+    int ref;
+
+public:
+    // Konstruktor
+    DownloadSound( Klient *zK, FBalken *zF )
+    {
+        k = zK;
+        f = zF;
+        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
+    {
+        char m = 0;
+        k->getNachrichtEncrypted( &m, 1 );
+        istM = ( m == 1 );
+        sample = 0;
+        k->getNachrichtEncrypted( (char*)&sample, 4 );
+        län = 0;
+        k->getNachrichtEncrypted( (char*)&län, 8 );
+        f->setAktionAnzahl( län );
+    }
+    int getDaten( char *buffer, int län ) override
+    {
+        int l = län < this->län ? län : ( int )this->län;
+        if( !l )
+            return -1;
+        k->getNachricht( buffer, l );
+        this->län -= l;
+        f->aktionPlus( l );
+        return l;
+    }
+    void close() override
+    {}
+    bool istMono() const override
+    {
+        return istM;
+    }
+    int getSampleRate() const override
+    {
+        return sample;
+    }
+    __int64 getDatLength() const override
+    {
+        return län;
+    }
+    // Reference Counting
+    GSL::GSLSoundV *getThis() override
+    {
+        ref++;
+        return this;
+    }
+    GSL::GSLSoundV *release() override
+    {
+        ref--;
+        if( !ref )
+            delete this;
+        return 0;
+    }
+};
+
+// Inhalt der EditorKlient Klasse aus KSGKlient.h
+// Konstruktor
+EditorKlient::EditorKlient()
+{
+    verbunden = 0;
+    klient = 0;
+    fehler = new Text( "" );
+    klientId = getKlientId();
+    ref = 1;
+}
+
+// Destruktor
+EditorKlient::~EditorKlient()
+{
+    cs.lock();
+    if( verbunden )
+        trenne();
+    fehler = fehler->release();
+    cs.unlock();
+}
+
+// nicht constant
+bool EditorKlient::verbinde( unsigned short port, char *ip ) // verbindet ich mit dem Editor Server
+{
+    if( klient && verbunden && klient->getServerPort() == port && Text( ip ).istGleich( klient->getServerIp() ) )
+        return 1;
+    if( klient || verbunden )
+        trenne();
+    klient = new Klient();
+    int keyLen = 0;
+    char *key = 0;
+    Keys::getServerKey( &key, keyLen, Keys::EDITOR, Keys::SENDEN );
+    klient->setSendeKey( key, keyLen );
+    delete[] key;
+    Keys::getServerKey( &key, keyLen, Keys::EDITOR, Keys::EMPFANGEN );
+    klient->setEmpfangKey( key, keyLen );
+    delete[] key;
+    if( !klient->verbinde( (unsigned short)port, ip ) )
+    {
+        klient = klient->release();
+        fehler->setText( "Fehler beim verbinden mit dem Editor Server." );
+        return 0;
+    }
+    klient->sendeEncrypted( "\1", 1 );
+    klient->sendeEncrypted( (char*)&klientId, 4 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *nachricht = new char[ län + 1 ];
+        nachricht[ län ] = 0;
+        klient->getNachrichtEncrypted( nachricht, län );
+        fehler->setText( nachricht );
+        delete[]nachricht;
+        trenne();
+        return 0;
+    }
+    if( ret == 1 )
+    {
+        char *sl = 0;
+        char slLän = getSchlüssel( &sl );
+        klient->setSendeKey( sl, slLän );
+        klient->setEmpfangKey( sl, slLän );
+        delete[] sl;
+        verbunden = 1;
+    }
+    return 1;
+}
+
+bool EditorKlient::karteErstellen( Text *zName, int spielArt ) // Erstellt eine neue Karte
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\xA", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        char l = (char)zName->getLength();
+        klient->sendeEncrypted( &l, 1 );
+        klient->sendeEncrypted( zName->getText(), l );
+        klient->sendeEncrypted( (char*)&spielArt, 4 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool EditorKlient::ladeKarte( int id ) // lädt eine bestimmte Karte
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x6", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&id, 4 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+int EditorKlient::getAbbildListe( RCArray< Text > *name, RCArray< Zeit > *datum )
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\x5", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            int anz = 0;
+            klient->getNachrichtEncrypted( (char*)&anz, 4 );
+            for( int i = 0; i < anz; i++ )
+            {
+                char l = 0;
+                klient->getNachrichtEncrypted( &l, 1 );
+                char *n = new char[ l + 1 ];
+                n[ l ] = 0;
+                klient->getNachrichtEncrypted( n, l );
+                name->set( new Text( n ), i );
+                delete[] n;
+                Zeit *dat = new Zeit();
+                int d = 0;
+                klient->getNachrichtEncrypted( (char*)&d, 4 );
+                dat->setJahr( d );
+                klient->getNachrichtEncrypted( (char*)&d, 4 );
+                dat->setMonat( d );
+                klient->getNachrichtEncrypted( (char*)&d, 4 );
+                dat->setTag( d );
+                klient->getNachrichtEncrypted( (char*)&d, 4 );
+                dat->setStunde( d );
+                klient->getNachrichtEncrypted( (char*)&d, 4 );
+                dat->setMinute( d );
+                klient->getNachrichtEncrypted( (char*)&d, 4 );
+                dat->setSekunde( d );
+                datum->set( dat, i );
+            }
+            cs.unlock();
+            return anz;
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool EditorKlient::abbildErstellen( char *name )
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\x1", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            char l = (char)textLength( name );
+            klient->sendeEncrypted( &l, 1 );
+            if( l )
+                klient->sendeEncrypted( name, l );
+            klient->getNachrichtEncrypted( &ret, 1 );
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+bool EditorKlient::abbildLöschen( char *name )
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\x2", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            char l = (char)textLength( name );
+            klient->sendeEncrypted( &l, 1 );
+            if( l )
+                klient->sendeEncrypted( name, l );
+            klient->getNachrichtEncrypted( &ret, 1 );
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+bool EditorKlient::abbildHerstellen( char *name )
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\x3", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            char l = (char)textLength( name );
+            klient->sendeEncrypted( &l, 1 );
+            if( l )
+                klient->sendeEncrypted( name, l );
+            klient->getNachrichtEncrypted( &ret, 1 );
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+bool EditorKlient::veröffentlichen()
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\x4", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+            klient->getNachrichtEncrypted( &ret, 1 );
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+bool EditorKlient::shopSeiteVeröffentlichen() // Veröffentlicht die Shop Seite
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\x6", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+            klient->getNachrichtEncrypted( &ret, 1 );
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+bool EditorKlient::ladeShopSeiteVorschau() // Läht die Vorschau der Shop Seite herrunter
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\x8", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            int anz = 0;
+            klient->getNachrichtEncrypted( (char*)&anz, 4 );
+            Text pf = "data/tmp/ke/ssv";
+            for( int i = 0; i < anz; i++ )
+            {
+                char l = 0;
+                klient->getNachrichtEncrypted( &l, 1 );
+                char *pfad = new char[ l + 1 ];
+                pfad[ l ] = 0;
+                klient->getNachrichtEncrypted( pfad, l );
+                Text p = pf.getText();
+                p += pfad;
+                delete[] pfad;
+                Datei d;
+                d.setDatei( p );
+                d.erstellen();
+                d.open( Datei::Style::schreiben );
+                __int64 größe = 0;
+                klient->getNachrichtEncrypted( (char*)&größe, 8 );
+                char *buffer = new char[ 2048 ];
+                while( größe > 0 )
+                {
+                    int l = größe > 2048 ? 2048 : (int)größe;
+                    klient->getNachricht( buffer, l );
+                    d.schreibe( buffer, l );
+                    größe -= l;
+                }
+                delete[] buffer;
+                d.close();
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+bool EditorKlient::ssDateiErstellen( char *name, int typ ) // Erstellt eine neue Shop Seiten Datei (typ:0=Ordner,1=Bild,2=Text)
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\x7", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x1", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                char t = typ;
+                klient->sendeEncrypted( &t, 1 );
+                char l = (char)textLength( name );
+                klient->sendeEncrypted( &l, 1 );
+                if( l )
+                    klient->sendeEncrypted( name, l );
+                klient->getNachrichtEncrypted( &ret, 1 );
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+bool EditorKlient::ssOrdnerÖffnen( char *name ) // Öffnet einen Ordner der Shop Seite
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\x7", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x2", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                char l = (char)textLength( name );
+                klient->sendeEncrypted( &l, 1 );
+                if( l )
+                    klient->sendeEncrypted( name, l );
+                klient->getNachrichtEncrypted( &ret, 1 );
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+Bild *EditorKlient::ssBildLaden( char *datei, char *bild ) // Läht das ein Bild der Shop Seite
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\x7", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x3", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                char l = (char)textLength( datei );
+                klient->sendeEncrypted( &l, 1 );
+                if( l )
+                    klient->sendeEncrypted( datei, l );
+                l = (char)textLength( bild );
+                klient->sendeEncrypted( &l, 1 );
+                if( l )
+                    klient->sendeEncrypted( bild, l );
+                klient->getNachrichtEncrypted( &ret, 1 );
+                if( ret == 1 )
+                {
+                    Bild *ret = new Bild();
+                    int br = 0;
+                    int hö = 0;
+                    klient->getNachrichtEncrypted( (char*)&br, 4 );
+                    klient->getNachrichtEncrypted( (char*)&hö, 4 );
+                    ret->neuBild( br, hö, 0 );
+                    char *buffer = (char*)ret->getBuffer();
+                    __int64 län = br * hö * 4;
+                    for( int i = 0, l = län > 2048 ? 2048 : (int)län; län > 0; l = län > 2048 ? 2048 : (int)län )
+                    {
+                        klient->getNachricht( &( buffer[ i ] ), l );
+                        i += l;
+                        län -= l;
+                    }
+                    cs.unlock();
+                    return ret;
+                }
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool EditorKlient::ssDateiLöschen( char *name ) // Löscht eine Datei der Shop Seite
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\x7", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x4", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                char l = (char)textLength( name );
+                klient->sendeEncrypted( &l, 1 );
+                if( l )
+                    klient->sendeEncrypted( name, l );
+                klient->getNachrichtEncrypted( &ret, 1 );
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+Text *EditorKlient::ssTextLaden( char *datei ) // Läd eine KSGS Datei der Shop Seite
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\x7", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\xA", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                char l = (char)textLength( datei );
+                klient->sendeEncrypted( &l, 1 );
+                if( l )
+                    klient->sendeEncrypted( datei, l );
+                klient->getNachrichtEncrypted( &ret, 1 );
+                if( ret == 1 )
+                {
+                    int län = 0;
+                    klient->getNachrichtEncrypted( (char*)&län, 4 );
+                    char *txt = new char[ län + 1 ];
+                    txt[ län ] = 0;
+                    for( int i = 0, l = län > 2048 ? 2048 : län; län > 0; i += l, län -= l, l = län > 2048 ? 2048 : län )
+                        klient->getNachricht( &( txt[ i ] ), l );
+                    klient->getNachrichtEncrypted( &ret, 1 );
+                    if( ret == 1 )
+                    {
+                        Text *t = new Text( txt );
+                        delete[] txt;
+                        cs.unlock();
+                        return t;
+                    }
+                    delete[] txt;
+                }
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool EditorKlient::ssTextSpeichern( char *datei, Text *zText ) // Spechert eine KSGS Datei der Shop Seite
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\x7", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x5", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                char l = (char)textLength( datei );
+                klient->sendeEncrypted( &l, 1 );
+                if( l )
+                    klient->sendeEncrypted( datei, l );
+                klient->getNachrichtEncrypted( &ret, 1 );
+                if( ret == 1 )
+                {
+                    int län = zText->getLength();
+                    klient->sendeEncrypted( (char*)&län, 4 );
+                    for( int i = 0, l = län > 2048 ? 2048 : län; län > 0; i += l, län -= l, l = län > 2048 ? 2048 : län )
+                        klient->sende( &( zText->getText()[ i ] ), l );
+                    klient->getNachrichtEncrypted( &ret, 1 );
+                }
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+bool EditorKlient::ssBildLöschen( char *datei, char *bild ) // Löscht ein Bild der Shop Seite
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\x7", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x6", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                char l = (char)textLength( datei );
+                klient->sendeEncrypted( &l, 1 );
+                if( l )
+                    klient->sendeEncrypted( datei, l );
+                l = (char)textLength( bild );
+                klient->sendeEncrypted( &l, 1 );
+                if( l )
+                    klient->sendeEncrypted( bild, l );
+                klient->getNachrichtEncrypted( &ret, 1 );
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+bool EditorKlient::ssBildSpeichern( char *datei, char *name, Bild *zBild ) // Speichert ein Bild einer ShopSeite
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\x7", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x7", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                char l = (char)textLength( datei );
+                klient->sendeEncrypted( &l, 1 );
+                if( l )
+                    klient->sendeEncrypted( datei, l );
+                l = (char)textLength( name );
+                klient->sendeEncrypted( &l, 1 );
+                if( l )
+                    klient->sendeEncrypted( name, l );
+                klient->getNachrichtEncrypted( &ret, 1 );
+                if( ret == 1 )
+                {
+                    int br = zBild->getBreite();
+                    int hö = zBild->getHeight();
+                    klient->sendeEncrypted( (char*)&br, 4 );
+                    klient->sendeEncrypted( (char*)&hö, 4 );
+                    __int64 län = br * hö * 4;
+                    char *buffer = (char*)zBild->getBuffer();
+                    for( int i = 0, l = län > 2048 ? 2048 : (int)län; län > 0; i += l, län -= l, l = län > 2048 ? 2048 : (int)län )
+                        klient->sende( &( buffer[ i ] ), l );
+                    klient->getNachrichtEncrypted( &ret, 1 );
+                }
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+int EditorKlient::ssGetDateiListe( RCArray< Text > *zList ) // Läd die Datei Liste der Shop Seite
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\x7", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x8", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                int anz = 0;
+                klient->getNachrichtEncrypted( (char*)&anz, 4 );
+                for( int i = 0; i < anz; i++ )
+                {
+                    char l = 0;
+                    klient->getNachrichtEncrypted( &l, 1 );
+                    char *n = new char[ l + 1 ];
+                    n[ l ] = 0;
+                    klient->getNachrichtEncrypted( n, l );
+                    zList->add( new Text( n ) );
+                    delete[] n;
+                }
+                cs.unlock();
+                return anz;
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return -1;
+    }
+    cs.unlock();
+    return 0;
+}
+
+int EditorKlient::ssGetBildListe( char *name, RCArray< Text > *zList ) // Läd die Bild Liste einer Bild Datei der Shop Seite
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\x7", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x9", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                char l = (char)textLength( name );
+                klient->sendeEncrypted( &l, 1 );
+                if( l )
+                    klient->sendeEncrypted( name, l );
+                klient->getNachrichtEncrypted( &ret, 1 );
+                if( ret == 1 )
+                {
+                    int anz = 0;
+                    klient->getNachrichtEncrypted( (char*)&anz, 4 );
+                    for( int i = 0; i < anz; i++ )
+                    {
+                        l = 0;
+                        klient->getNachrichtEncrypted( &l, 1 );
+                        char *n = new char[ l + 1 ];
+                        n[ l ] = 0;
+                        klient->getNachrichtEncrypted( n, l );
+                        zList->add( new Text( n ) );
+                        delete[] n;
+                    }
+                    cs.unlock();
+                    return anz;
+                }
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return -1;
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool EditorKlient::getShopDaten( int &es, int &tp, int &vp ) // Läht die Shop Daten
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\x9", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->getNachrichtEncrypted( (char*)&es, 4 );
+            klient->getNachrichtEncrypted( (char*)&tp, 4 );
+            klient->getNachrichtEncrypted( (char*)&vp, 4 );
+            cs.unlock();
+            return 1;
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool EditorKlient::setShopDaten( int es, int tp, int vp ) // Setzt die Shop Daten
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xA", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( (char*)&es, 4 );
+            klient->sendeEncrypted( (char*)&tp, 4 );
+            klient->sendeEncrypted( (char*)&vp, 4 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                cs.unlock();
+                return 1;
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 0;
+}
+
+Text *EditorKlient::beschreibungLaden() // läht die Kartenbeschreibung
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xB", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x1", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                int län = 0;
+                klient->getNachrichtEncrypted( (char*)&län, 4 );
+                char *txt = new char[ län + 1 ];
+                txt[ län ] = 0;
+                for( int i = 0, l = län > 2048 ? 2048 : län; län > 0; i += l, län -= l, l = län > 2048 ? 2048 : län )
+                    klient->getNachricht( &( txt[ i ] ), l );
+                klient->getNachrichtEncrypted( &ret, 1 );
+                if( ret == 1 )
+                {
+                    Text *t = new Text( txt );
+                    delete[] txt;
+                    cs.unlock();
+                    return t;
+                }
+                delete[] txt;
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 0;
+}
+
+Bild *EditorKlient::titelbildLaden() // läht das Titelbild
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xB", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x2", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                Bild *ret = new Bild();
+                int br = 0;
+                int hö = 0;
+                klient->getNachrichtEncrypted( (char*)&br, 4 );
+                klient->getNachrichtEncrypted( (char*)&hö, 4 );
+                ret->neuBild( br, hö, 0 );
+                char *buffer = (char*)ret->getBuffer();
+                __int64 län = br * hö * 4;
+                for( int i = 0, l = län > 2048 ? 2048 : (int)län; län > 0; l = län > 2048 ? 2048 : (int)län )
+                {
+                    klient->getNachricht( &( buffer[ i ] ), l );
+                    i += l;
+                    län -= l;
+                }
+                cs.unlock();
+                return ret;
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 0;
+}
+
+Bild *EditorKlient::minimapLaden() // läht das Minimapbild
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xB", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x3", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                Bild *ret = new Bild();
+                int br = 0;
+                int hö = 0;
+                klient->getNachrichtEncrypted( (char*)&br, 4 );
+                klient->getNachrichtEncrypted( (char*)&hö, 4 );
+                ret->neuBild( br, hö, 0 );
+                char *buffer = (char*)ret->getBuffer();
+                __int64 län = br * hö * 4;
+                for( int i = 0, l = län > 2048 ? 2048 : (int)län; län > 0; l = län > 2048 ? 2048 : (int)län )
+                {
+                    klient->getNachricht( &( buffer[ i ] ), l );
+                    i += l;
+                    län -= l;
+                }
+                cs.unlock();
+                return ret;
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 0;
+}
+
+Bild *EditorKlient::ladebildLaden() // läht das Ladebild
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xB", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x4", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                Bild *ret = new Bild();
+                int br = 0;
+                int hö = 0;
+                klient->getNachrichtEncrypted( (char*)&br, 4 );
+                klient->getNachrichtEncrypted( (char*)&hö, 4 );
+                ret->neuBild( br, hö, 0 );
+                char *buffer = (char*)ret->getBuffer();
+                __int64 län = br * hö * 4;
+                for( int i = 0, l = län > 2048 ? 2048 : (int)län; län > 0; l = län > 2048 ? 2048 : (int)län )
+                {
+                    klient->getNachricht( &( buffer[ i ] ), l );
+                    i += l;
+                    län -= l;
+                }
+                cs.unlock();
+                return ret;
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool EditorKlient::beschreibungSpeichern( Text *zText ) // speichert die Kartenbeschreibung
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xB", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x5", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                int län = zText->getLength();
+                klient->sendeEncrypted( (char*)&län, 4 );
+                for( int i = 0, l = län > 2048 ? 2048 : län; län > 0; i += l, län -= l, l = län > 2048 ? 2048 : län )
+                    klient->sende( &( zText->getText()[ i ] ), l );
+                klient->getNachrichtEncrypted( &ret, 1 );
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+bool EditorKlient::titelbildSpeichern( Bild *zBild ) // speichert das Titelbild
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xB", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x6", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                int br = zBild->getBreite();
+                int hö = zBild->getHeight();
+                klient->sendeEncrypted( (char*)&br, 4 );
+                klient->sendeEncrypted( (char*)&hö, 4 );
+                __int64 län = br * hö * 4;
+                char *buffer = (char*)zBild->getBuffer();
+                for( int i = 0, l = län > 2048 ? 2048 : (int)län; län > 0; i += l, län -= l, l = län > 2048 ? 2048 : (int)län )
+                    klient->sende( &( buffer[ i ] ), l );
+                klient->getNachrichtEncrypted( &ret, 1 );
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+bool EditorKlient::minimapSpeichern( Bild *zBild ) // speichert das Minimapbild
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xB", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x7", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                int br = zBild->getBreite();
+                int hö = zBild->getHeight();
+                klient->sendeEncrypted( (char*)&br, 4 );
+                klient->sendeEncrypted( (char*)&hö, 4 );
+                __int64 län = br * hö * 4;
+                char *buffer = (char*)zBild->getBuffer();
+                for( int i = 0, l = län > 2048 ? 2048 : (int)län; län > 0; i += l, län -= l, l = län > 2048 ? 2048 : (int)län )
+                    klient->sende( &( buffer[ i ] ), l );
+                klient->getNachrichtEncrypted( &ret, 1 );
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+bool EditorKlient::ladebildSpeichern( Bild *zBild ) // speichert das Ladebild
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xB", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x8", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                int br = zBild->getBreite();
+                int hö = zBild->getHeight();
+                klient->sendeEncrypted( (char*)&br, 4 );
+                klient->sendeEncrypted( (char*)&hö, 4 );
+                __int64 län = br * hö * 4;
+                char *buffer = (char*)zBild->getBuffer();
+                for( int i = 0, l = län > 2048 ? 2048 : (int)län; län > 0; i += l, län -= l, l = län > 2048 ? 2048 : (int)län )
+                    klient->sende( &( buffer[ i ] ), l );
+                klient->getNachrichtEncrypted( &ret, 1 );
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+bool EditorKlient::ladeTeamDaten( SpielerTeamStruktur *sts ) // läht die Team Daten
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xC", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x1", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                klient->getNachrichtEncrypted( (char*)&sts->spielerAnzahl, 4 );
+                klient->getNachrichtEncrypted( (char*)&sts->teamAnzahl, 4 );
+                for( int i = 0; i < sts->spielerAnzahl; i++ )
+                {
+                    int f = 0;
+                    klient->getNachrichtEncrypted( (char*)&f, 4 );
+                    sts->spielerFarbe->set( f, i );
+                }
+                for( int i = 0; i < sts->teamAnzahl; i++ )
+                {
+                    int f = 0;
+                    klient->getNachrichtEncrypted( (char*)&f, 4 );
+                    sts->teamFarbe->set( f, i );
+                }
+                for( int i = 0; i < sts->teamAnzahl; i++ )
+                {
+                    char l = 0;
+                    klient->getNachrichtEncrypted( &l, 1 );
+                    char *n = new char[ l + 1 ];
+                    n[ l ] = 0;
+                    klient->getNachrichtEncrypted( n, l );
+                    sts->teamName->set( new Text( n ), i );
+                    delete[] n;
+                }
+                for( int i = 0; i < sts->teamAnzahl; i++ )
+                {
+                    int g = 0;
+                    klient->getNachrichtEncrypted( (char*)&g, 4 );
+                    sts->teamGröße->set( g, i );
+                }
+                cs.unlock();
+                return 1;
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool EditorKlient::speicherTeamDaten( SpielerTeamStruktur *sts ) // speichert die Team Daten
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xC", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x2", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                klient->sendeEncrypted( (char*)&sts->spielerAnzahl, 4 );
+                klient->sendeEncrypted( (char*)&sts->teamAnzahl, 4 );
+                for( int i = 0; i < sts->spielerAnzahl; i++ )
+                {
+                    int f = sts->spielerFarbe->get( i );
+                    klient->sendeEncrypted( (char*)&f, 4 );
+                }
+                for( int i = 0; i < sts->teamAnzahl; i++ )
+                {
+                    int f = sts->teamFarbe->get( i );
+                    klient->sendeEncrypted( (char*)&f, 4 );
+                }
+                for( int i = 0; i < sts->teamAnzahl; i++ )
+                {
+                    char l = (char)sts->teamName->z( i )->getLength();
+                    klient->sendeEncrypted( &l, 1 );
+                    klient->sendeEncrypted( sts->teamName->z( i )->getText(), l );
+                }
+                for( int i = 0; i < sts->teamAnzahl; i++ )
+                {
+                    int g = sts->teamGröße->get( i );
+                    klient->sendeEncrypted( (char*)&g, 4 );
+                }
+                cs.unlock();
+                return 1;
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool EditorKlient::deNeueDatei( char typ, Text *zName ) // DateienEditor: Erstellt neue Datei (typ: 0=ordner 1=bild 2=modell2d 3=sound
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xD", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x1", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                klient->sendeEncrypted( &typ, 1 );
+                char l = (char)zName->getLength();
+                klient->sendeEncrypted( &l, 1 );
+                if( l )
+                    klient->sendeEncrypted( zName->getText(), l );
+                klient->getNachrichtEncrypted( &ret, 1 );
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+bool EditorKlient::deOrdnerÖffnen( Text *zName ) // DateienEditor: Öffnet Ordner
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xD", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x2", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                char län = (char)zName->getLength();
+                klient->sendeEncrypted( &län, 1 );
+                if( län )
+                    klient->sendeEncrypted( zName->getText(), län );
+                klient->getNachrichtEncrypted( &ret, 1 );
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+Bild *EditorKlient::deBildLaden( Text *zDatei, Text *zBild, FBalken *zF ) // DateienEditor: Bild laden
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    Bild *retB = 0;
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xD", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x3", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                char län = (char)zDatei->getLength();
+                klient->sendeEncrypted( &län, 1 );
+                if( län )
+                    klient->sendeEncrypted( zDatei->getText(), län );
+                län = (char)zBild->getLength();
+                klient->sendeEncrypted( &län, 1 );
+                if( län )
+                    klient->sendeEncrypted( zBild->getText(), län );
+                klient->getNachrichtEncrypted( &ret, 1 );
+                if( ret == 1 )
+                {
+                    int br = 0;
+                    int hö = 0;
+                    klient->getNachrichtEncrypted( (char*)&br, 4 );
+                    klient->getNachrichtEncrypted( (char*)&hö, 4 );
+                    retB = new Bild();
+                    retB->neuBild( br, hö, 0 );
+                    char *buffer = (char*)retB->getBuffer();
+                    __int64 län = br * hö * 4;
+                    zF->setAktionAnzahl( län );
+                    for( int i = 0, l = län > 2048 ? 2048 : (int)län; län > 0; l = län > 2048 ? 2048 : (int)län )
+                    {
+                        klient->getNachricht( &( buffer[ i ] ), l );
+                        i += l;
+                        län -= l;
+                        zF->aktionPlus( l );
+                    }
+                }
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    if( !ret && retB )
+        retB = retB->release();
+    return retB;
+}
+
+bool EditorKlient::deDateiLöschen( Text *zName ) // DateienEditor: Löscht Datei
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xD", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x4", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                char län = (char)zName->getLength();
+                klient->sendeEncrypted( &län, 1 );
+                if( län )
+                    klient->sendeEncrypted( zName->getText(), län );
+                klient->getNachrichtEncrypted( &ret, 1 );
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+bool EditorKlient::deBildLöschen( Text *zDatei, Text *zBild ) // DateienEditor: Löscht Bild aus Datei
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xD", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x5", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                char l = (char)zDatei->getLength();
+                klient->sendeEncrypted( &l, 1 );
+                if( l )
+                    klient->sendeEncrypted( zDatei->getText(), l );
+                l = (char)zBild->getLength();
+                klient->sendeEncrypted( &l, 1 );
+                if( l )
+                    klient->sendeEncrypted( zBild->getText(), l );
+                klient->getNachrichtEncrypted( &ret, 1 );
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+bool EditorKlient::deBildSpeichern( Text *zDatei, Text *zName, Bild *zBild, FBalken *zF ) // DateienEditor: Speichert Bild
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xD", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x6", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                char län = (char)zDatei->getLength();
+                klient->sendeEncrypted( &län, 1 );
+                if( län )
+                    klient->sendeEncrypted( zDatei->getText(), län );
+                län = (char)zName->getLength();
+                klient->sendeEncrypted( &län, 1 );
+                if( län )
+                    klient->sendeEncrypted( zName->getText(), län );
+                klient->getNachrichtEncrypted( &ret, 1 );
+                if( ret == 1 )
+                {
+                    int br = zBild->getBreite();
+                    int hö = zBild->getHeight();
+                    klient->sendeEncrypted( (char*)&br, 4 );
+                    klient->sendeEncrypted( (char*)&hö, 4 );
+                    char *buffer = (char*)zBild->getBuffer();
+                    __int64 gr = br * hö * 4;
+                    zF->setAktionAnzahl( gr );
+                    for( int i = 0, l = gr > 2048 ? 2048 : (int)gr; gr > 0; i += l, gr -= l, l = gr > 2048 ? 2048 : (int)gr )
+                    {
+                        klient->sende( &( buffer[ i ] ), l );
+                        zF->aktionPlus( l );
+                    }
+                    klient->getNachrichtEncrypted( &ret, 1 );
+                }
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+int EditorKlient::deGetDateiListe( RCArray< Text > *zNamen ) // DateienEditor: Datei Liste herunterladen
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xD", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x7", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                int anz = 0;
+                klient->getNachrichtEncrypted( (char*)&anz, 4 );
+                for( int i = 0; i < anz; i++ )
+                {
+                    char l = 0;
+                    klient->getNachrichtEncrypted( &l, 1 );
+                    char *n = new char[ l + 1 ];
+                    n[ l ] = 0;
+                    if( l )
+                        klient->getNachrichtEncrypted( n, l );
+                    zNamen->add( new Text( n ) );
+                    delete[] n;
+                }
+                cs.unlock();
+                return anz;
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return -1;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+int EditorKlient::deGetBildListe( Text *zDatei, RCArray< Text > *zNamen ) // DateienEditor: Liste mit in der Datei gespeicherten Bildern
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xD", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x8", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                char l = (char)zDatei->getLength();
+                klient->sendeEncrypted( &l, 1 );
+                klient->sendeEncrypted( zDatei->getText(), l );
+                klient->getNachrichtEncrypted( &ret, 1 );
+                if( ret == 1 )
+                {
+                    int anz = 0;
+                    klient->getNachrichtEncrypted( (char*)&anz, 4 );
+                    for( int i = 0; i < anz; i++ )
+                    {
+                        klient->getNachrichtEncrypted( &l, 1 );
+                        char *n = new char[ l + 1 ];
+                        n[ l ] = 0;
+                        if( l )
+                            klient->getNachrichtEncrypted( n, l );
+                        zNamen->add( new Text( n ) );
+                        delete[] n;
+                    }
+                    cs.unlock();
+                    return anz;
+                }
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+int EditorKlient::deGetModelListe( Text *zDatei, RCArray< Text > *zNamen ) // DateienEditor Liste mit in der Datei gespeicherten Modellen
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xD", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x9", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                char l = (char)zDatei->getLength();
+                klient->sendeEncrypted( &l, 1 );
+                klient->sendeEncrypted( zDatei->getText(), l );
+                klient->getNachrichtEncrypted( &ret, 1 );
+                if( ret == 1 )
+                {
+                    int anz = 0;
+                    klient->getNachrichtEncrypted( (char*)&anz, 4 );
+                    for( int i = 0; i < anz; i++ )
+                    {
+                        klient->getNachrichtEncrypted( &l, 1 );
+                        char *n = new char[ l + 1 ];
+                        n[ l ] = 0;
+                        if( l )
+                            klient->getNachrichtEncrypted( n, l );
+                        zNamen->add( new Text( n ) );
+                        delete[] n;
+                    }
+                    cs.unlock();
+                    return anz;
+                }
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+int EditorKlient::deGetSoundListe( Text *zDatei, RCArray< Text > *zNamen ) // DateienEditor: Liste mit in der Datei gespeicherten Tönen
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xD", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\xA", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                char l = (char)zDatei->getLength();
+                klient->sendeEncrypted( &l, 1 );
+                klient->sendeEncrypted( zDatei->getText(), l );
+                klient->getNachrichtEncrypted( &ret, 1 );
+                if( ret == 1 )
+                {
+                    int anz = 0;
+                    klient->getNachrichtEncrypted( (char*)&anz, 4 );
+                    for( int i = 0; i < anz; i++ )
+                    {
+                        klient->getNachrichtEncrypted( &l, 1 );
+                        char *n = new char[ l + 1 ];
+                        n[ l ] = 0;
+                        if( l )
+                            klient->getNachrichtEncrypted( n, l );
+                        zNamen->add( new Text( n ) );
+                        delete[] n;
+                    }
+                    cs.unlock();
+                    return anz;
+                }
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+bool EditorKlient::deModelLöschen( Text *zDatei, Text *zModel ) // DateienEditor: Löscht Modell
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xD", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\xB", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                char l = (char)zDatei->getLength();
+                klient->sendeEncrypted( &l, 1 );
+                klient->sendeEncrypted( zDatei->getText(), l );
+                klient->getNachrichtEncrypted( &ret, 1 );
+                if( ret == 1 )
+                {
+                    l = (char)zModel->getLength();
+                    klient->sendeEncrypted( &l, 1 );
+                    klient->sendeEncrypted( zModel->getText(), l );
+                    klient->getNachrichtEncrypted( &ret, 1 );
+                }
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+bool EditorKlient::deSoundLöschen( Text *zDatei, Text *zSound ) // DateienEditor: Löscht Ton
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xD", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\xC", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                char l = (char)zDatei->getLength();
+                klient->sendeEncrypted( &l, 1 );
+                klient->sendeEncrypted( zDatei->getText(), l );
+                klient->getNachrichtEncrypted( &ret, 1 );
+                if( ret == 1 )
+                {
+                    l = (char)zSound->getLength();
+                    klient->sendeEncrypted( &l, 1 );
+                    klient->sendeEncrypted( zSound->getText(), l );
+                    klient->getNachrichtEncrypted( &ret, 1 );
+                }
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+Model2DData *EditorKlient::deModelLaden( Text *zDatei, Text *zModel, FBalken *zF ) // DateienEditor: läd ein Model herunter
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xD", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\xD", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                char l = (char)zDatei->getLength();
+                klient->sendeEncrypted( &l, 1 );
+                klient->sendeEncrypted( zDatei->getText(), l );
+                klient->getNachrichtEncrypted( &ret, 1 );
+                if( ret == 1 )
+                {
+                    l = (char)zModel->getLength();
+                    klient->sendeEncrypted( &l, 1 );
+                    klient->sendeEncrypted( zModel->getText(), l );
+                    klient->getNachrichtEncrypted( &ret, 1 );
+                    if( ret == 1 )
+                    {
+                        int anz = 0;
+                        klient->getNachrichtEncrypted( (char*)&anz, 4 );
+                        zF->setAktionAnzahl( anz );
+                        Array< Polygon2D > *pol = new Array< Polygon2D >();
+                        for( int i = 0; i < anz; i++ )
+                        {
+                            Polygon2D p;
+                            p.vertex = new Array< Vertex >();
+                            p.tKordinaten = new Array< Punkt >();
+                            int anz2 = 0;
+                            klient->getNachrichtEncrypted( (char*)&anz2, 4 );
+                            for( int j = 0; j < anz2; j++ )
+                            {
+                                Vertex v;
+                                klient->getNachrichtEncrypted( (char*)&v.x, 4 );
+                                klient->getNachrichtEncrypted( (char*)&v.y, 4 );
+                                Punkt t;
+                                klient->getNachrichtEncrypted( (char*)&t.x, 4 );
+                                klient->getNachrichtEncrypted( (char*)&t.y, 4 );
+                                p.vertex->add( v );
+                                p.tKordinaten->add( t );
+                            }
+                            pol->add( p );
+                            zF->aktionPlus();
+                        }
+                        Model2DData *data = new Model2DData();
+                        data->erstelleModell( pol );
+                        cs.unlock();
+                        return data;
+                    }
+                }
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 0;
+}
+
+GSL::GSLSoundV *EditorKlient::deSoundLaden( Text *zDatei, Text *zSound, FBalken *zF ) // DateienEditor: läd Sound herunter
+{
+    HMODULE gslDll = dllDateien->ladeDLL( "GSL.dll", "data/bin/GSL.dll" );
+    if( !gslDll )
+    {
+        fehler->setText( "Die DLL Datei 'data/bin/GSL.dll' wurde nicht gefunden." );
+        return 0;
+    }
+    GetGSLDatei getGSLDatei = (GetGSLDatei)GetProcAddress( gslDll, "getGSLDatei" );
+    if( !getGSLDatei )
+    {
+        fehler->setText( "Der Einstiegspunkt 'getGSLDatei' wurde in der Datei 'data/bin/GSL.dll' nicht gefunden." );
+        return 0;
+    }
+    DateiRemove( "data/tmp/editor/dateien/sounds/tmp.gsl" );
+    DateiPfadErstellen( "data/tmp/editor/dateien/sounds/tmp.gsl" );
+    GSL::GSLDateiV *gslDatei = getGSLDatei();
+    gslDatei->setDatei( "data/tmp/editor/dateien/sounds/tmp.gsl" );
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        gslDatei->release();
+        dllDateien->releaseDLL( "GSL.dll" );
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xD", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\xE", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                char l = (char)zDatei->getLength();
+                klient->sendeEncrypted( &l, 1 );
+                klient->sendeEncrypted( zDatei->getText(), l );
+                klient->getNachrichtEncrypted( &ret, 1 );
+                if( ret == 1 )
+                {
+                    l = (char)zSound->getLength();
+                    klient->sendeEncrypted( &l, 1 );
+                    klient->sendeEncrypted( zSound->getText(), l );
+                    klient->getNachrichtEncrypted( &ret, 1 );
+                    if( ret == 1 )
+                    {
+                        DownloadSound dws( klient, zF );
+                        gslDatei->speicherSound( &dws, zSound->getText() );
+                        GSL::GSLSoundV *s = gslDatei->getSound( zSound->getText() );
+                        gslDatei->release();
+                        dllDateien->releaseDLL( "GSL.dll" );
+                        cs.unlock();
+                        return s;
+                    }
+                }
+            }
+        }
+    }
+    gslDatei->release();
+    dllDateien->releaseDLL( "GSL.dll" );
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool EditorKlient::deModelSpeichern( Text *zDatei, Text *zModel, Model2DData *zData, FBalken *zF ) // DateienEditor: Speichert Modell
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xD", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\xF", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                char l = (char)zDatei->getLength();
+                klient->sendeEncrypted( &l, 1 );
+                klient->sendeEncrypted( zDatei->getText(), l );
+                klient->getNachrichtEncrypted( &ret, 1 );
+                if( ret == 1 )
+                {
+                    l = (char)zModel->getLength();
+                    klient->sendeEncrypted( &l, 1 );
+                    klient->sendeEncrypted( zModel->getText(), l );
+                    klient->getNachrichtEncrypted( &ret, 1 );
+                    if( ret == 1 )
+                    {
+                        int anz = zData->polygons ? zData->polygons->getEintragAnzahl() : 0;
+                        zF->setAktionAnzahl( anz );
+                        klient->sendeEncrypted( (char*)&anz, 4 );
+                        for( int i = 0; i < anz; i++ )
+                        {
+                            Polygon2D pol = zData->polygons->get( i );
+                            int anz2 = pol.vertex->getEintragAnzahl();
+                            klient->sendeEncrypted( (char*)&anz2, 4 );
+                            for( int j = 0; j < anz2; j++ )
+                            {
+                                Vertex v = pol.vertex->get( j );
+                                Punkt p;
+                                if( pol.tKordinaten )
+                                    p = pol.tKordinaten->hat( j ) ? pol.tKordinaten->get( j ) : Punkt( 0, 0 );
+                                klient->sendeEncrypted( (char*)&v.x, 4 );
+                                klient->sendeEncrypted( (char*)&v.y, 4 );
+                                klient->sendeEncrypted( (char*)&p.x, 4 );
+                                klient->sendeEncrypted( (char*)&p.y, 4 );
+                            }
+                            zF->aktionPlus();
+                        }
+                        klient->getNachrichtEncrypted( &ret, 1 );
+                    }
+                }
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+bool EditorKlient::deSoundSpeichern( Text *zDatei, Text *zSound, GSL::GSLSoundV *zData, FBalken *zF ) // DateienEditor: Speichert Sound
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xD", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->sendeEncrypted( "\x10", 1 );
+            klient->getNachrichtEncrypted( &ret, 1 );
+            if( ret == 1 )
+            {
+                char l = (char)zDatei->getLength();
+                klient->sendeEncrypted( &l, 1 );
+                klient->sendeEncrypted( zDatei->getText(), l );
+                klient->getNachrichtEncrypted( &ret, 1 );
+                if( ret == 1 )
+                {
+                    l = (char)zSound->getLength();
+                    klient->sendeEncrypted( &l, 1 );
+                    klient->sendeEncrypted( zSound->getText(), l );
+                    klient->getNachrichtEncrypted( &ret, 1 );
+                    if( ret == 1 )
+                    {
+                        char channels = zData->istMono() ? 1 : 2;
+                        klient->sendeEncrypted( &channels, 1 );
+                        int sample = zData->getSampleRate();
+                        klient->sendeEncrypted( (char*)&sample, 4 );
+                        __int64 slän = zData->getDatLength();
+                        klient->sendeEncrypted( (char*)&slän, 8 );
+                        zF->setAktionAnzahl( slän );
+                        zData->open();
+                        char *buffer = new char[ 2048 ];
+                        while( slän > 0 )
+                        {
+                            int l = slän > 2048 ? 2048 : (int)slän;
+                            zData->getDaten( buffer, l );
+                            klient->sende( buffer, l );
+                            slän -= l;
+                            zF->aktionPlus( l );
+                        }
+                        delete[] buffer;
+                        zData->close();
+                    }
+                }
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+bool EditorKlient::initEditor() // Initialisiert den Editor auf Serverseite
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x7", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( "\xE", 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+bool EditorKlient::keepAlive() // Erhält die Verbindung aufrecht
+{
+    if( !cs.tryLock() )
+        return 1;
+    if( !verbunden || !klient )
+    {
+        cs.unlock();
+        return 0;
+    }
+    char res = 0;
+    klient->sendeEncrypted( "\x5", 1 );
+    klient->getNachrichtEncrypted( &res, 1 );
+    cs.unlock();
+    if( res != 1 )
+    {
+        trenne();
+        fehler->setText( "Verbindung unterbrochen: 'Keep Alive' nicht erfolgreich." );
+    }
+    return res == 1;
+}
+
+bool EditorKlient::trenne() // trennt sich von dem Editor Server
+{
+    cs.lock();
+    if( !klient || !verbunden )
+    {
+        if( klient )
+            klient = klient->release();
+        cs.unlock();
+        return 1;
+    }
+    char serverReturn;
+    klient->sendeEncrypted( "\4", 1 );
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *nachricht = new char[ län + 1 ];
+        nachricht[ län ] = 0;
+        klient->getNachrichtEncrypted( nachricht, län );
+        delete[]nachricht;
+    }
+    klient->sendeEncrypted( "\3", 1 );
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    klient->trenne();
+    klient = klient->release();
+    verbunden = 0;
+    cs.unlock();
+    return 1;
+}
+
+void EditorKlient::lock()
+{
+    cs.lock();
+}
+
+void EditorKlient::unlock()
+{
+    cs.unlock();
+}
+
+Klient *EditorKlient::zKlient() // gibt den Klient zurück
+{
+    if( cs.isLocked() && cs.zOwner() && cs.zOwner()->getThreadHandle() == GetCurrentThread() )
+        return klient;
+    return 0;
+}
+
+// constant
+bool EditorKlient::istVerbunden() const // prüft, ob mit Editor Server verbunden
+{
+    return verbunden;
+}
+
+char *EditorKlient::getLetzterFehler() const // gibt den Letzten Fehlertext zuück
+{
+    return fehler->getText();
+}
+
+// Reference Counting
+EditorKlientV *EditorKlient::getThis()
+{
+    ref++;
+    return this;
+}
+
+EditorKlientV *EditorKlient::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 203 - 0
KSGClient/Netzwerk/Klients/HistorieK.cpp

@@ -0,0 +1,203 @@
+#include "../KSGKlient.h"
+#include "../KSGServer.h"
+#include "../../Global/Variablen.h"
+#include <Datei.h>
+#include "../Keys.h"
+
+// Inhalt der HistorieKlient Klasse KSGKlient.h
+// Konstruktor
+HistorieKlient::HistorieKlient()
+{
+    klient = 0;
+    fehler = new Text( "" );
+    klientId = getKlientId();
+    ref = 1;
+}
+
+// Destruktor
+HistorieKlient::~HistorieKlient()
+{
+    cs.lock();
+    trenne();
+    fehler = fehler->release();
+    cs.unlock();
+}
+
+// privat
+bool HistorieKlient::verbinde( char *ip, int port ) // verbindet ich mit dem Historie Server
+{
+    if( klient && klient->getServerPort() == port && Text( ip ).istGleich( klient->getServerIp() ) )
+        return 1;
+    if( klient )
+        trenne();
+    klient = new Klient();
+    int keyLen = 0;
+    char *key = 0;
+    Keys::getServerKey( &key, keyLen, Keys::HISTORIE, Keys::SENDEN );
+    klient->setSendeKey( key, keyLen );
+    delete[] key;
+    Keys::getServerKey( &key, keyLen, Keys::HISTORIE, Keys::EMPFANGEN );
+    klient->setEmpfangKey( key, keyLen );
+    delete[] key;
+    if( !klient->verbinde( (unsigned short)port, ip ) )
+    {
+        klient = klient->release();
+        fehler->setText( "Fehler beim verbinden mit dem Historie Server." );
+        return 0;
+    }
+    klient->sendeEncrypted( "\1", 1 );
+    klient->sendeEncrypted( (char*)&klientId, 4 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *nachricht = new char[ län + 1 ];
+        nachricht[ län ] = 0;
+        klient->getNachrichtEncrypted( nachricht, län );
+        fehler->setText( nachricht );
+        delete[]nachricht;
+        trenne();
+        return 0;
+    }
+    if( ret == 1 )
+    {
+        char *sl = 0;
+        char slLän = getSchlüssel( &sl );
+        klient->setSendeKey( sl, slLän );
+        klient->setEmpfangKey( sl, slLän );
+        delete[] sl;
+    }
+    return 1;
+}
+
+bool HistorieKlient::trenne() // trennt sich von dem Historie Server
+{
+    if( !klient )
+        return 1;
+    char serverReturn;
+    klient->sendeEncrypted( "\4", 1 );
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *nachricht = new char[ län + 1 ];
+        nachricht[ län ] = 0;
+        klient->getNachrichtEncrypted( nachricht, län );
+        delete[]nachricht;
+    }
+    klient->sendeEncrypted( "\3", 1 );
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    klient->trenne();
+    klient = klient->release();
+    return 1;
+}
+
+// nicht constant
+bool HistorieKlient::downloadSpielHistorie( int spielId ) // läd Spiel Historie herunter
+{
+    if( DateiIstVerzeichnis( Text( "data/tmp/historie/" ) += spielId ) )
+        return 1;
+    cs.lock();
+    int port = 0;
+    Text *ip = new Text();
+    if( !infoKlient->getHistorieServer( spielId, &port, ip ) )
+    {
+        cs.unlock();
+        ip->release();
+        fehler->setText( infoKlient->getLetzterFehler() );
+        return 0;
+    }
+    if( !verbinde( *ip, port ) )
+    {
+        cs.unlock();
+        ip->release();
+        return 0;
+    }
+    ip->release();
+    klient->sendeEncrypted( "\6", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&spielId, 4 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            char län = 0;
+            klient->getNachrichtEncrypted( &län, 1 );
+            while( län )
+            {
+                char *pf = new char[ län + 1 ];
+                pf[ län ] = 0;
+                klient->getNachrichtEncrypted( pf, län );
+                __int64 gr = 0;
+                klient->getNachrichtEncrypted( (char*)&gr, 8 );
+                Text *pfad = new Text( "data/tmp/historie/" );
+                pfad->append( spielId );
+                pfad->append( pf );
+                delete[] pf;
+                Datei *d = new Datei();
+                d->setDatei( pfad );
+                d->erstellen();
+                d->open( Datei::Style::schreiben );
+                char *bytes = new char[ 2048 ];
+                while( gr )
+                {
+                    int dLän = gr > 2048 ? 2048 : (int)gr;
+                    klient->getNachricht( bytes, dLän );
+                    d->schreibe( bytes, dLän );
+                    gr -= dLän;
+                }
+                delete[] bytes;
+                d->close();
+                d->release();
+                klient->getNachrichtEncrypted( &län, 1 );
+            }
+            trenne();
+            cs.unlock();
+            return 1;
+        }
+    }
+    if( ret == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *nachricht = new char[ län + 1 ];
+        nachricht[ län ] = 0;
+        klient->getNachrichtEncrypted( nachricht, län );
+        fehler->setText( nachricht );
+        delete[]nachricht;
+    }
+    trenne();
+    cs.unlock();
+    return 0;
+}
+
+// constant
+bool HistorieKlient::istVerbunden() const // prüft, ob mit Historie Server verbunden
+{
+    return klient != 0;
+}
+
+char *HistorieKlient::getLetzterFehler() const // gibt den Letzten Fehlertext zuück
+{
+    return *fehler;
+}
+
+// Reference Counting
+HistorieKlient *HistorieKlient::getThis()
+{
+    ref++;
+    return this;
+}
+
+HistorieKlient *HistorieKlient::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 2079 - 0
KSGClient/Netzwerk/Klients/InformationK.cpp

@@ -0,0 +1,2079 @@
+#include "../KSGKlient.h"
+#include "../KSGServer.h"
+#include "../../NachLogin/Account/Historie/AccountHistorieDaten.h"
+#include <iostream>
+#include "../Keys.h"
+
+int waiting = 0;
+
+// Inhalt der InformationKlient Klasse aus KSGKlient.h
+// Konstruktor
+InformationKlient::InformationKlient()
+{
+    verbunden = 0;
+    klient = 0;
+    fehler = new Text( "" );
+    klientId = getKlientId();
+    ref = 1;
+    std::cout << "Initialize CS INF\n";
+}
+
+// Destruktor
+InformationKlient::~InformationKlient() // wenn verbunden, dann trennen
+{
+    cs.lock();
+    if( klient )
+    {
+        char serverReturn = 0;
+        if( verbunden )
+        {
+            klient->sendeEncrypted( "\4", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            if( serverReturn == 3 )
+            {
+                char län = 0;
+                klient->getNachrichtEncrypted( &län, 1 );
+                char *nachricht = new char[ län + 1 ];
+                nachricht[ län ] = 0;
+                klient->getNachrichtEncrypted( nachricht, län );
+                delete[]nachricht;
+            }
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+        }
+        else
+        {
+            int keyLen = 0;
+            char *key = 0;
+            Keys::getServerKey( &key, keyLen, Keys::INFORMATION, Keys::SENDEN );
+            klient->setSendeKey( key, keyLen );
+            delete[] key;
+            Keys::getServerKey( &key, keyLen, Keys::INFORMATION, Keys::EMPFANGEN );
+            klient->setEmpfangKey( key, keyLen );
+            delete[] key;
+            klient->verbinde( klient->getServerPort(), klient->getServerIp() );
+            klient->sendeEncrypted( "\1", 1 );
+            klient->sendeEncrypted( (char*)&klientId, 4 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            if( serverReturn == 3 )
+            {
+                char län = 0;
+                klient->getNachrichtEncrypted( &län, 1 );
+                char *nachricht = new char[ län + 1 ];
+                nachricht[ län ] = 0;
+                klient->getNachrichtEncrypted( nachricht, län );
+                delete[]nachricht;
+            }
+            else
+            {
+                char *sl = 0;
+                char slLän = getSchlüssel( &sl );
+                klient->setSendeKey( sl, slLän );
+                klient->setEmpfangKey( sl, slLän );
+                delete[] sl;
+                klient->sendeEncrypted( "\4", 1 );
+                klient->getNachrichtEncrypted( &serverReturn, 1 );
+                if( serverReturn == 3 )
+                {
+                    char län = 0;
+                    klient->getNachrichtEncrypted( &län, 1 );
+                    char *nachricht = new char[ län + 1 ];
+                    nachricht[ län ] = 0;
+                    klient->getNachrichtEncrypted( nachricht, län );
+                    delete[]nachricht;
+                }
+            }
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+        }
+        klient = klient->release();
+    }
+    fehler = fehler->release();
+    cs.unlock();
+    std::cout << "DELETE CS INF\n";
+}
+
+// nicht constant
+bool InformationKlient::verbinde() // verbindet ich mit dem Informaion Server
+{
+    cs.lock();
+    if( verbunden )
+    {
+        cs.unlock();
+        return 1;
+    }
+    if( !klient )
+    {
+        char *msIp = getMainServerIp();
+        unsigned short msPort = getMainServerPort();
+        klient = new Klient();
+        int keyLen = 0;
+        char *key = 0;
+        Keys::getServerKey( &key, keyLen, Keys::MAIN, Keys::SENDEN );
+        klient->setSendeKey( key, keyLen );
+        delete[] key;
+        Keys::getServerKey( &key, keyLen, Keys::MAIN, Keys::EMPFANGEN );
+        klient->setEmpfangKey( key, keyLen );
+        delete[] key;
+        if( !klient->verbinde( msPort, msIp ) )
+        {
+            fehler->setText( "Fehler beim verbinden mit dem Main Server. Bitte versuche es Später erneut." );
+            klient = klient->release();
+            delete[]msIp;
+            cs.unlock();
+            return 0;
+        }
+        delete[]msIp;
+        klient->sende( "\0", 1 ); // Verschlüsselung aktivieren
+        klient->sendeEncrypted( "\1", 1 );
+        klient->sendeEncrypted( (char*)&klientId, 4 );
+        char serverReturn = 0;
+        klient->getNachrichtEncrypted( &serverReturn, 1 );
+        if( serverReturn == 3 )
+        {
+            char län = 0;
+            klient->getNachrichtEncrypted( &län, 1 );
+            char *nachricht = new char[ län + 1 ];
+            nachricht[ län ] = 0;
+            klient->getNachrichtEncrypted( nachricht, län );
+            fehler->setText( nachricht );
+            delete[]nachricht;
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+            klient = klient->release();
+            cs.unlock();
+            return 0;
+        }
+        char *sl = 0;
+        char slLän = getSchlüssel( &sl );
+        klient->setSendeKey( sl, slLän );
+        klient->setEmpfangKey( sl, slLän );
+        delete[] sl;
+        klient->sendeEncrypted( "\6\4", 2 );
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        if( byte == 2 )
+        {
+            unsigned char lsIp[ 4 ];
+            klient->getNachrichtEncrypted( (char *)lsIp, 4 );
+            unsigned short lsPort = 0;
+            klient->getNachrichtEncrypted( (char*)&lsPort, 2 );
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+            Text *lsIpT = new Text( "" );
+            lsIpT->append( (int)lsIp[ 0 ] );
+            lsIpT->append( "." );
+            lsIpT->append( (int)lsIp[ 1 ] );
+            lsIpT->append( "." );
+            lsIpT->append( (int)lsIp[ 2 ] );
+            lsIpT->append( "." );
+            lsIpT->append( (int)lsIp[ 3 ] );
+            int keyLen = 0;
+            char *key = 0;
+            Keys::getServerKey( &key, keyLen, Keys::INFORMATION, Keys::SENDEN );
+            klient->setSendeKey( key, keyLen );
+            delete[] key;
+            Keys::getServerKey( &key, keyLen, Keys::INFORMATION, Keys::EMPFANGEN );
+            klient->setEmpfangKey( key, keyLen );
+            delete[] key;
+            klient->verbinde( lsPort, lsIpT->getText() );
+            lsIpT = lsIpT->release();
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+        }
+        if( byte == 3 )
+        {
+            klient->getNachrichtEncrypted( &byte, 1 );
+            char *f = new char[ byte + 1 ];
+            f[ byte ] = 0;
+            klient->getNachrichtEncrypted( f, byte );
+            fehler->setText( f );
+            delete[]f;
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+            klient = klient->release();
+            cs.unlock();
+            return 0;
+        }
+    }
+    int keyLen = 0;
+    char *key = 0;
+    Keys::getServerKey( &key, keyLen, Keys::INFORMATION, Keys::SENDEN );
+    klient->setSendeKey( key, keyLen );
+    delete[] key;
+    Keys::getServerKey( &key, keyLen, Keys::INFORMATION, Keys::EMPFANGEN );
+    klient->setEmpfangKey( key, keyLen );
+    delete[] key;
+    if( klient->verbinde( klient->getServerPort(), klient->getServerIp() ) )
+    {
+        if( klient->sendeEncrypted( "\1", 1 ) )
+        {
+            klient->sendeEncrypted( (char*)&klientId, 4 );
+            char serverReturn = 0;
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            if( serverReturn == 3 )
+            {
+                char byte = 0;
+                klient->getNachrichtEncrypted( &byte, 1 );
+                char *f = new char[ byte + 1 ];
+                f[ byte ] = 0;
+                klient->getNachrichtEncrypted( f, byte );
+                fehler->setText( f );
+                delete[]f;
+                klient->sendeEncrypted( "\3", 1 );
+                klient->getNachrichtEncrypted( &serverReturn, 1 );
+                klient->trenne();
+                cs.unlock();
+                return 0;
+            }
+            char *sl = 0;
+            char slLän = getSchlüssel( &sl );
+            klient->setSendeKey( sl, slLän );
+            klient->setEmpfangKey( sl, slLän );
+            delete[] sl;
+            verbunden = 1;
+            cs.unlock();
+            return 1;
+        }
+        else
+        {
+            fehler->setText( "Der dir zugewiesene Informations Server hat die Verbindung abgebrochen. Bitte versuche es Später erneut." );
+            klient = klient->release();
+        }
+    }
+    else
+    {
+        fehler->setText( "Der dir zugewiesene Informations Server antwortet nicht. Bitte versuche es Später erneut." );
+        klient = klient->release();
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool InformationKlient::getInformationText( Text *txt, int *typ ) // fragt nach Informationstext
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    bool ret = 1;
+    ret = ret & klient->sendeEncrypted( "\5", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[]f;
+        cs.unlock();
+        return 0;
+    }
+    short län = 0;
+    ret = ret & klient->getNachrichtEncrypted( (char*)&län, 2 );
+    char *text = new char[ län + 1 ];
+    text[ län ] = 0;
+    if( län )
+        ret = ret & klient->getNachrichtEncrypted( text, län );
+    txt->setText( text );
+    delete[]text;
+    char type = 0;
+    ret = ret & klient->getNachrichtEncrypted( &type, 1 );
+    *typ = type;
+    if( !ret )
+        fehler->setText( "Verbindungsfehler" );
+    cs.unlock();
+    return ret;
+}
+
+bool InformationKlient::istSpielErlaubt( int spielId ) // fragt, ob das entsprechende Spiel vom Server gesperrt wurde
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\6", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[]f;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&spielId, 4 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    cs.unlock();
+    return ret != 0;
+}
+
+bool InformationKlient::istKarteErlaubt( int karteId ) // fragt, ob die entsprechende Karte vom Server gesperrt wurde
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\7", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[]f;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&karteId, 4 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    cs.unlock();
+    return ret != 0;
+}
+
+int InformationKlient::getKarteId( char *name ) // fragt nach der Id einer Karte
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x9", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[]f;
+        cs.unlock();
+        return 0;
+    }
+    char län = textLength( name );
+    klient->sendeEncrypted( &län, 1 );
+    klient->sendeEncrypted( name, län );
+    int id = 0;
+    klient->getNachrichtEncrypted( (char*)&id, 4 );
+    cs.unlock();
+    return id;
+}
+
+int InformationKlient::getSpielId( char *name ) // fragt nach der id eines Spiels
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x8", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[]f;
+        cs.unlock();
+        return 0;
+    }
+    char län = textLength( name );
+    klient->sendeEncrypted( &län, 1 );
+    klient->sendeEncrypted( name, län );
+    int id = 0;
+    klient->getNachrichtEncrypted( (char*)&id, 4 );
+    cs.unlock();
+    return id;
+}
+
+Text *InformationKlient::getSpielerName( int accountId ) // fragt nach dem Namen eines Accounts
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\xA", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[]f;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&accountId, 4 );
+    char län = 0;
+    klient->getNachrichtEncrypted( &län, 1 );
+    char *name = new char[ län + 1 ];
+    name[ län ] = 0;
+    if( län )
+        klient->getNachrichtEncrypted( name, län );
+    Text *ret = new Text( name );
+    delete[]name;
+    cs.unlock();
+    return ret;
+}
+
+bool InformationKlient::getSpielStatistik( int accountId, int spielId, Array< int > *werte ) // fragt nach der Spiel Statistik eines Accounts
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    bool ret = 1;
+    ret = ret & klient->sendeEncrypted( "\xB", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[]f;
+        cs.unlock();
+        return 0;
+    }
+    ret = ret & klient->sendeEncrypted( (char*)&accountId, 4 );
+    ret = ret & klient->sendeEncrypted( (char*)&spielId, 4 );
+    for( int i = 0; i < 10; i++ )
+    {
+        int tmp = 0;
+        ret = ret & klient->getNachrichtEncrypted( (char*)&tmp, 4 );
+        werte->add( tmp, i );
+    }
+    if( !ret )
+        fehler->setText( "Verbindungsfehler" );
+    cs.unlock();
+    return ret;
+}
+
+Text *InformationKlient::getKarteName( int karteId ) // fragt nach dem Namen einer Karte
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\xE", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[]f;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&karteId, 4 );
+    char län = 0;
+    klient->getNachrichtEncrypted( &län, 1 );
+    char *name = new char[ län + 1 ];
+    name[ län ] = 0;
+    if( län )
+        klient->getNachrichtEncrypted( name, län );
+    Text *ret = new Text( name );
+    delete[]name;
+    cs.unlock();
+    return ret;
+}
+
+Text *InformationKlient::getSpielName( int spielId ) // fragt nach dem Namen einer Spielart
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\xF", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[]f;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&spielId, 4 );
+    char län = 0;
+    klient->getNachrichtEncrypted( &län, 1 );
+    char *name = new char[ län + 1 ];
+    name[ län ] = 0;
+    if( län )
+        klient->getNachrichtEncrypted( name, län );
+    Text *ret = new Text( name );
+    delete[]name;
+    cs.unlock();
+    return ret;
+}
+
+Text *InformationKlient::getChatroomName( int chatroomId ) // fragt nach dem Namen eines Chatrooms
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x10", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[]f;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&chatroomId, 4 );
+    char län = 0;
+    klient->getNachrichtEncrypted( &län, 1 );
+    char *name = new char[ län + 1 ];
+    name[ län ] = 0;
+    if( län )
+        klient->getNachrichtEncrypted( name, län );
+    Text *ret = new Text( name );
+    delete[]name;
+    cs.unlock();
+    return ret;
+}
+
+int InformationKlient::getSpielId( int karteId ) // fragt zu welcher Spielart die Karte gehört
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x11", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[]f;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&karteId, 4 );
+    int ret = 0;
+    klient->getNachrichtEncrypted( (char*)&ret, 4 );
+    cs.unlock();
+    return ret;
+}
+
+int InformationKlient::getAccountId( char *name ) // gibt die Id des Accounts zurück
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    char län = textLength( name );
+    if( !län )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x12", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[]f;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( &län, 1 );
+    klient->sendeEncrypted( name, län );
+    int ret = 0;
+    klient->getNachrichtEncrypted( (char*)&ret, 4 );
+    cs.unlock();
+    return ret;
+}
+
+int InformationKlient::getChatroomId( char *name ) // gibt die Id des Chatrooms zurück
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    char län = textLength( name );
+    if( !län )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x13", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[]f;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( &län, 1 );
+    klient->sendeEncrypted( name, län );
+    int ret = 0;
+    klient->getNachrichtEncrypted( (char*)&ret, 4 );
+    cs.unlock();
+    return ret;
+}
+
+int InformationKlient::getGruppenKarteId( int gruppenId ) // gibt die karten Id der gruppe zurück
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\xD", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[]f;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&gruppenId, 4 );
+    int id = 0;
+    klient->getNachrichtEncrypted( (char*)&id, 4 );
+    cs.unlock();
+    return id;
+}
+
+bool InformationKlient::getGruppeSpielerHinzufügen( int gruppeId ) // gibt die Spieler hinzufügen Funktion der Gruppe zurück
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x1E", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[]f;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&gruppeId, 4 );
+    char sh = 0;
+    klient->getNachrichtEncrypted( (char*)&sh, 1 );
+    cs.unlock();
+    return sh == 1;
+}
+
+int InformationKlient::getGruppeAdminId( int gruppeId ) // gibt den Gruppen Administrator zurück
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x15", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[]f;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&gruppeId, 4 );
+    int id = 0;
+    klient->getNachrichtEncrypted( (char*)&id, 4 );
+    cs.unlock();
+    return id;
+}
+
+int InformationKlient::getSpielerPunkte( int accountId, int spielId ) // gibt die Punkte eines Spielers zurück
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x14", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[]f;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&spielId, 4 );
+    klient->sendeEncrypted( (char*)&accountId, 4 );
+    int punkte = 0;
+    klient->getNachrichtEncrypted( (char*)&punkte, 4 );
+    cs.unlock();
+    return punkte;
+}
+
+Array< int > *InformationKlient::getAccountSpielArtListe() // gibt eine Liste mit gekauften Spielen zurück
+{
+    char ret = 0;
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x16", 1 );
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        int anz = 0;
+        klient->getNachrichtEncrypted( (char*)&anz, 4 );
+        Array< int > *list = new Array< int >();
+        for( int i = 0; i < anz; i++ )
+        {
+            int id = 0;
+            klient->getNachrichtEncrypted( (char*)&id, 4 );
+            list->add( id );
+        }
+        cs.unlock();
+        return list;
+    }
+    if( ref == 3 )
+    {
+        klient->getNachrichtEncrypted( &ret, 1 );
+        char *err = new char[ ret + 1 ];
+        err[ ret ] = 0;
+        if( ret )
+            klient->getNachrichtEncrypted( err, ret );
+        fehler->setText( err );
+        delete[] err;
+    }
+    cs.unlock();
+    return 0;
+}
+
+int InformationKlient::getSpielVersion( int spielId ) // gibt die neuste Version eines Spiels zurück
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x17", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&spielId, 4 );
+    int version = 0;
+    klient->getNachrichtEncrypted( (char*)&version, 4 );
+    cs.unlock();
+    return version;
+}
+
+int InformationKlient::getKupfer() // gibt das Kupfer des Accounts zurück
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x18", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    int kupfer = 0;
+    klient->getNachrichtEncrypted( (char*)&kupfer, 4 );
+    cs.unlock();
+    return kupfer;
+}
+
+int InformationKlient::getDateiGruppeIdVonSpiel( int spielId ) // Gibt die Dateigruppe eines Spieles zurück
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x19", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&spielId, 4 );
+    int dgId = 0;
+    klient->getNachrichtEncrypted( (char*)&dgId, 4 );
+    cs.unlock();
+    return dgId;
+}
+
+Text *InformationKlient::getDateiGruppePfad( int dgId ) // Gibt den Dateigruppen Pfad zurück
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x1A", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 1 )
+    {
+        klient->sendeEncrypted( (char*)&dgId, 4 );
+        klient->getNachrichtEncrypted( &serverReturn, 1 );
+        if( serverReturn == 1 )
+        {
+            char län = 0;
+            klient->getNachrichtEncrypted( &län, 1 );
+            char *pf = new char[ län + 1 ];
+            pf[ län ] = 0;
+            if( län )
+                klient->getNachrichtEncrypted( pf, län );
+            Text *pfad = new Text( pf );
+            delete[] pf;
+            cs.unlock();
+            return pfad;
+        }
+    }
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 0;
+}
+
+Array< int > *InformationKlient::getAccountKarteListe( int spielId ) // gibt eine Liste mit gekauften Karten zurück
+{
+    char ret = 0;
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x1B", 1 );
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&spielId, 4 );
+        int anz = 0;
+        klient->getNachrichtEncrypted( (char*)&anz, 4 );
+        Array< int > *list = new Array< int >();
+        for( int i = 0; i < anz; i++ )
+        {
+            int id = 0;
+            klient->getNachrichtEncrypted( (char*)&id, 4 );
+            list->add( id );
+        }
+        cs.unlock();
+        return list;
+    }
+    if( ref == 3 )
+    {
+        klient->getNachrichtEncrypted( &ret, 1 );
+        char *err = new char[ ret + 1 ];
+        err[ ret ] = 0;
+        if( ret )
+            klient->getNachrichtEncrypted( err, ret );
+        fehler->setText( err );
+        delete[] err;
+    }
+    cs.unlock();
+    return 0;
+}
+
+int InformationKlient::getDateiGruppeIdVonPfad( char *pfad ) // Gibt die Dateigruppe eines Pfades zurück
+{
+    char län = textLength( pfad );
+    if( !län )
+        return 0;
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x2A", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&län, 1 );
+    klient->sendeEncrypted( (char*)pfad, län );
+    int dgId = 0;
+    klient->getNachrichtEncrypted( (char*)&dgId, 4 );
+    cs.unlock();
+    return dgId;
+}
+
+int InformationKlient::getDateiGruppeVersion( int dg ) // gibt die neuste Version einer Dateigruppe zurück
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x2B", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&dg, 4 );
+    int version = 0;
+    klient->getNachrichtEncrypted( (char*)&version, 4 );
+    cs.unlock();
+    return version;
+}
+
+int InformationKlient::getSpielerListe( char *suche, int *seite, int *maxSeite, char sortSpalte, char rückwärts,
+                                        Array< int > *accounts, RCArray< Text > *name, RCArray< Text > *zuletztOnline,
+                                        RCArray< Text > *letztesSpiel, RCArray< Text > *letzteKarte, RCArray< Text > *punkte ) // sucht nach Spielern
+{
+    char län = textLength( suche );
+    if( !län )
+        return -1;
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return -1;
+    }
+    char serverReturn = 0;
+    klient->sendeEncrypted( "\xC", 1 );
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 1 )
+    {
+        klient->sendeEncrypted( &län, 1 );
+        klient->sendeEncrypted( suche, län );
+        klient->sendeEncrypted( (char*)seite, 4 );
+        klient->sendeEncrypted( &sortSpalte, 1 );
+        klient->sendeEncrypted( &rückwärts, 1 );
+        klient->getNachrichtEncrypted( (char*)seite, 4 );
+        klient->getNachrichtEncrypted( (char*)maxSeite, 4 );
+        int ret = 0;
+        klient->getNachrichtEncrypted( (char*)&ret, 4 );
+        for( int i = 0; i < ret; i++ )
+        {
+            int accId = 0;
+            klient->getNachrichtEncrypted( (char*)&accId, 4 );
+            accounts->set( accId, i );
+            klient->getNachrichtEncrypted( &län, 1 );
+            char *txt = new char[ län + 1 ];
+            txt[ län ] = 0;
+            klient->getNachrichtEncrypted( txt, län );
+            name->set( new Text( txt ), i );
+            delete[] txt;
+            klient->getNachrichtEncrypted( &län, 1 );
+            txt = new char[ län + 1 ];
+            txt[ län ] = 0;
+            klient->getNachrichtEncrypted( txt, län );
+            zuletztOnline->set( new Text( txt ), i );
+            delete[] txt;
+            klient->getNachrichtEncrypted( &län, 1 );
+            txt = new char[ län + 1 ];
+            txt[ län ] = 0;
+            klient->getNachrichtEncrypted( txt, län );
+            letztesSpiel->set( new Text( txt ), i );
+            delete[] txt;
+            klient->getNachrichtEncrypted( &län, 1 );
+            txt = new char[ län + 1 ];
+            txt[ län ] = 0;
+            klient->getNachrichtEncrypted( txt, län );
+            letzteKarte->set( new Text( txt ), i );
+            delete[] txt;
+            klient->getNachrichtEncrypted( &län, 1 );
+            txt = new char[ län + 1 ];
+            txt[ län ] = 0;
+            klient->getNachrichtEncrypted( txt, län );
+            punkte->set( new Text( txt ), i );
+            delete[] txt;
+        }
+        cs.unlock();
+        return ret;
+    }
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+    }
+    cs.unlock();
+    return -1;
+}
+
+bool InformationKlient::getSpielerAktivität( int accId, RCArray< Text > *datum, Array< double > *stOnline, Array< double > *stGespielt,
+                                             Array< int > *anzSpiele, Array< int > *anzGewonnen ) // ermittelt die aktivität eines Spielers
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    char ret = 0;
+    klient->sendeEncrypted( "\x1F", 1 );
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&accId, 4 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            klient->getNachrichtEncrypted( &ret, 1 );
+            for( int i = 0; ret; i++ )
+            {
+                char *txt = new char[ ret + 1 ];
+                txt[ ret ] = 0;
+                klient->getNachrichtEncrypted( txt, ret );
+                datum->set( new Text( txt ), i );
+                delete[] txt;
+                double sto = 0;
+                klient->getNachrichtEncrypted( (char*)&sto, 8 );
+                stOnline->set( sto, i );
+                double sts = 0;
+                klient->getNachrichtEncrypted( (char*)&sts, 8 );
+                stGespielt->set( sts, i );
+                int anzs = 0;
+                klient->getNachrichtEncrypted( (char*)&anzs, 4 );
+                anzSpiele->set( anzs, i );
+                int anzg = 0;
+                klient->getNachrichtEncrypted( (char*)&anzg, 4 );
+                anzGewonnen->set( anzg, i );
+                klient->getNachrichtEncrypted( &ret, 1 );
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+int InformationKlient::getAccountKarteSpiele( int account, int karte ) // Gibt zurück, wie oft ein Spieler eine Karte schon gespielt hat
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    char ret = 0;
+    klient->sendeEncrypted( "\x20", 1 );
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&account, 4 );
+        klient->sendeEncrypted( (char*)&karte, 4 );
+        int anz = 0;
+        klient->getNachrichtEncrypted( (char*)&anz, 4 );
+        cs.unlock();
+        return anz;
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 0;
+}
+
+int InformationKlient::getAccountKarteSpieleGewonnen( int account, int karte ) // Gibt zurück, wie oft ein Spieler eine Karte schon gewonnen hat
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    char ret = 0;
+    klient->sendeEncrypted( "\x21", 1 );
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&account, 4 );
+        klient->sendeEncrypted( (char*)&karte, 4 );
+        int anz = 0;
+        klient->getNachrichtEncrypted( (char*)&anz, 4 );
+        cs.unlock();
+        return anz;
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool InformationKlient::hatAccountKarte( int account, int karte ) // Gibt zurück, ob ein Spieler die Karte im Besitz hat
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    char ret = 0;
+    klient->sendeEncrypted( "\x22", 1 );
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&account, 4 );
+        klient->sendeEncrypted( (char*)&karte, 4 );
+        char status = 0;
+        klient->getNachrichtEncrypted( &status, 1 );
+        cs.unlock();
+        return status != 0;
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool InformationKlient::hatAccountSpiel( int account, int spiel ) // Gibt zurück, ob ein Spieler ein Spiel im Besitz hat
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    char ret = 0;
+    klient->sendeEncrypted( "\x23", 1 );
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&account, 4 );
+        klient->sendeEncrypted( (char*)&spiel, 4 );
+        char status = 0;
+        klient->getNachrichtEncrypted( &status, 1 );
+        cs.unlock();
+        return status != 0;
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 0;
+}
+
+Array< int > *InformationKlient::getAccountKarteGespieltListe( int account, int spielId ) // gibt eine Liste mit Karten zurück, die von einem Spieler bereits gespielt wurden
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x24", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&account, 4 );
+        klient->sendeEncrypted( (char*)&spielId, 4 );
+        int anz = 0;
+        klient->getNachrichtEncrypted( (char*)&anz, 4 );
+        Array< int > *ret = new Array< int >();
+        for( int i = 0; i < anz; i++ )
+        {
+            int val = 0;
+            klient->getNachrichtEncrypted( (char*)&val, 4 );
+            ret->set( val, i );
+        }
+        cs.unlock();
+        return ret;
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 0;
+}
+
+Array< int > *InformationKlient::getAccountSpielGespieltListe( int account ) // gibt eine Liste mit Spielen zurück, die von einem Spieler bereits gespielt wurden
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x25", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&account, 4 );
+        int anz = 0;
+        klient->getNachrichtEncrypted( (char*)&anz, 4 );
+        Array< int > *ret = new Array< int >();
+        for( int i = 0; i < anz; i++ )
+        {
+            int val = 0;
+            klient->getNachrichtEncrypted( (char*)&val, 4 );
+            ret->set( val, i );
+        }
+        cs.unlock();
+        return ret;
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool InformationKlient::getSpielPartnerListe( int account, Array< int > *spieler, Array< int > *karten, Array< int > *anzahl ) // Gibt eine Liste von Spiel Partnern eines Spielers zurück
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x26", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&account, 4 );
+        int anz = 0;
+        klient->getNachrichtEncrypted( (char*)&anz, 4 );
+        for( int i = 0; i < anz; i++ )
+        {
+            int val = 0;
+            klient->getNachrichtEncrypted( (char*)&val, 4 );
+            spieler->set( val, i );
+            klient->getNachrichtEncrypted( (char*)&val, 4 );
+            karten->set( val, i );
+            klient->getNachrichtEncrypted( (char*)&val, 4 );
+            anzahl->set( val, i );
+        }
+        cs.unlock();
+        return 1;
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool InformationKlient::getStatistikListe( int account, int *seite, int *maxSeite, char sortSpalte, char rückwärts,
+                                           RCArray< Array< int > > *werte, RCArray< Text > *namen ) // Gibt eine Liste mit Spiel Statistiken zurück
+{
+    if( !*seite )
+        *seite = 1;
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    char serverReturn = 0;
+    klient->sendeEncrypted( "\x27", 1 );
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 1 )
+    {
+        klient->sendeEncrypted( (char*)&account, 4 );
+        klient->sendeEncrypted( (char*)seite, 4 );
+        klient->sendeEncrypted( &sortSpalte, 1 );
+        klient->sendeEncrypted( &rückwärts, 1 );
+        klient->getNachrichtEncrypted( (char*)seite, 4 );
+        klient->getNachrichtEncrypted( (char*)maxSeite, 4 );
+        int zAnz = 0;
+        int sAnz = 0;
+        klient->getNachrichtEncrypted( (char*)&zAnz, 4 );
+        klient->getNachrichtEncrypted( (char*)&sAnz, 4 );
+        for( int i = 0; i < zAnz; i++ )
+        {
+            Array< int > *tmp = new Array< int >();
+            for( int j = 0; j < sAnz; j++ )
+            {
+                if( j != 1 )
+                {
+                    int val = 0;
+                    klient->getNachrichtEncrypted( (char*)&val, 4 );
+                    tmp->set( val, j );
+                }
+                else
+                {
+                    char län = 0;
+                    klient->getNachrichtEncrypted( &län, 1 );
+                    char *n = new char[ län + 1 ];
+                    n[ län ] = 0;
+                    if( län )
+                        klient->getNachrichtEncrypted( n, län );
+                    namen->set( new Text( n ), i );
+                    delete[] n;
+                }
+            }
+            werte->set( tmp, i );
+        }
+        cs.unlock();
+        return 1;
+    }
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+    }
+    cs.unlock();
+    return 0;
+}
+
+AHDaten *InformationKlient::getSpielHistorieDaten( int account ) // Gibt eine Liste mit den letzten 20 Spielen zurück
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x28", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&account, 4 );
+        AHDaten *ret = new AHDaten();
+        char anz = 0;
+        klient->getNachrichtEncrypted( &anz, 1 );
+        for( char i = 0; i < anz; i++ )
+        {
+            AHSpielDaten *spiel = new AHSpielDaten();
+            klient->getNachrichtEncrypted( (char*)&spiel->id, 4 );
+            klient->getNachrichtEncrypted( (char*)&spiel->karteId, 4 );
+            char län = 0;
+            klient->getNachrichtEncrypted( &län, 1 );
+            char *txt = new char[ län + 1 ];
+            txt[ län ] = 0;
+            if( län )
+                klient->getNachrichtEncrypted( txt, län );
+            spiel->spiel->setText( txt );
+            delete[] txt;
+            klient->getNachrichtEncrypted( &län, 1 );
+            txt = new char[ län + 1 ];
+            txt[ län ] = 0;
+            if( län )
+                klient->getNachrichtEncrypted( txt, län );
+            spiel->karte->setText( txt );
+            delete[] txt;
+            klient->getNachrichtEncrypted( &län, 1 );
+            txt = new char[ län + 1 ];
+            txt[ län ] = 0;
+            if( län )
+                klient->getNachrichtEncrypted( txt, län );
+            spiel->datum->setText( txt );
+            delete[] txt;
+            klient->getNachrichtEncrypted( &län, 1 );
+            txt = new char[ län + 1 ];
+            txt[ län ] = 0;
+            if( län )
+                klient->getNachrichtEncrypted( txt, län );
+            spiel->status->setText( txt );
+            delete[] txt;
+            klient->getNachrichtEncrypted( &län, 1 );
+            txt = new char[ län + 1 ];
+            txt[ län ] = 0;
+            if( län )
+                klient->getNachrichtEncrypted( txt, län );
+            spiel->dauer->setText( txt );
+            delete[] txt;
+            klient->getNachrichtEncrypted( &län, 1 );
+            txt = new char[ län + 1 ];
+            txt[ län ] = 0;
+            if( län )
+                klient->getNachrichtEncrypted( txt, län );
+            spiel->spielStatus->setText( txt );
+            delete[] txt;
+            klient->getNachrichtEncrypted( &län, 1 );
+            txt = new char[ län + 1 ];
+            txt[ län ] = 0;
+            if( län )
+                klient->getNachrichtEncrypted( txt, län );
+            spiel->gewinner->setText( txt );
+            delete[] txt;
+            klient->getNachrichtEncrypted( (char*)&spiel->sAnzahl, 4 );
+            char tAnz = 0;
+            klient->getNachrichtEncrypted( &tAnz, 1 );
+            for( char j = 0; j < tAnz; j++ )
+            {
+                AHSpielTeamDaten *team = new AHSpielTeamDaten();
+                char län = 0;
+                klient->getNachrichtEncrypted( &län, 1 );
+                char *txt = new char[ län + 1 ];
+                txt[ län ] = 0;
+                if( län )
+                    klient->getNachrichtEncrypted( txt, län );
+                team->name->setText( txt );
+                delete[] txt;
+                klient->getNachrichtEncrypted( (char*)&team->sAnzahl, 4 );
+                klient->getNachrichtEncrypted( &län, 1 );
+                txt = new char[ län + 1 ];
+                txt[ län ] = 0;
+                if( län )
+                    klient->getNachrichtEncrypted( txt, län );
+                team->status->setText( txt );
+                delete[] txt;
+                klient->getNachrichtEncrypted( (char*)&team->farbe, 4 );
+                char sAnz = 0;
+                klient->getNachrichtEncrypted( &sAnz, 1 );
+                for( char k = 0; k < sAnz; k++ )
+                {
+                    AHSpielSpielerDaten *spieler = new AHSpielSpielerDaten();
+                    char län = 0;
+                    klient->getNachrichtEncrypted( &län, 1 );
+                    char *txt = new char[ län + 1 ];
+                    txt[ län ] = 0;
+                    if( län )
+                        klient->getNachrichtEncrypted( txt, län );
+                    spieler->name->setText( txt );
+                    delete[] txt;
+                    klient->getNachrichtEncrypted( (char*)&spieler->punkte, 4 );
+                    klient->getNachrichtEncrypted( &län, 1 );
+                    txt = new char[ län + 1 ];
+                    txt[ län ] = 0;
+                    if( län )
+                        klient->getNachrichtEncrypted( txt, län );
+                    spieler->status->setText( txt );
+                    delete[] txt;
+                    klient->getNachrichtEncrypted( (char*)&spieler->farbe, 4 );
+                    team->spieler->set( spieler, k );
+                }
+                spiel->teams->set( team, j );
+            }
+            ret->spiele->set( spiel, i );
+        }
+        cs.unlock();
+        return ret;
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool InformationKlient::getHistorieServer( int spielId, int *port, Text *ip ) // sucht nach dem Historie Server von einem Spiel
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x29", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&spielId, 4 );
+        klient->getNachrichtEncrypted( (char*)&ret, 1 );
+        if( ret == 1 )
+        {
+            klient->getNachrichtEncrypted( (char*)port, 4 );
+            char län = 0;
+            klient->getNachrichtEncrypted( &län, 1 );
+            ip->fillText( ' ', län );
+            klient->getNachrichtEncrypted( ip->getText(), län );
+            cs.unlock();
+            return 1;
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool InformationKlient::keepAlive() // Erhält die Verbindung aufrecht
+{
+    if( !verbunden )
+        return 0;
+    char res = 0;
+    if( !cs.tryLock() )
+        return 1;
+    klient->sendeEncrypted( "\x2C", 1 );
+    klient->getNachrichtEncrypted( &res, 1 );
+    cs.unlock();
+    if( res != 1 )
+        trenne();
+    return res == 1;
+}
+
+bool InformationKlient::hatRecht( int recht ) // Prüft ob Berechtigung vorhanden
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x2D", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&recht, 4 );
+        klient->getNachrichtEncrypted( (char*)&ret, 1 );
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+int InformationKlient::getKartenListe( char *filter, char sortSpalte, char absteigend, Array< int > *kId, RCArray< Text > *kName, RCArray< Text > *sName,
+                                       Array< int > *kupfer, Array< int > *verkauft, Array< int > *maxSpieler ) // Gibt eine Liste mit Karten zurück
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x2E", 1 );
+    char res = 0;
+    klient->getNachrichtEncrypted( &res, 1 );
+    int ret = 0;
+    if( res == 1 )
+    {
+        char län = textLength( filter );
+        klient->sendeEncrypted( &län, 1 );
+        klient->sendeEncrypted( filter, län );
+        klient->sendeEncrypted( &sortSpalte, 1 );
+        klient->sendeEncrypted( &absteigend, 1 );
+        klient->getNachrichtEncrypted( (char*)&ret, 4 );
+        for( int i = 0; i < ret; i++ )
+        {
+            int val = 0;
+            klient->getNachrichtEncrypted( (char*)&val, 4 );
+            kId->set( val, i );
+            klient->getNachrichtEncrypted( &län, 1 );
+            char *txt = new char[ län + 1 ];
+            txt[ län ] = 0;
+            if( län )
+                klient->getNachrichtEncrypted( txt, län );
+            kName->set( new Text( txt ), i );
+            delete[] txt;
+            klient->getNachrichtEncrypted( &län, 1 );
+            txt = new char[ län + 1 ];
+            txt[ län ] = 0;
+            if( län )
+                klient->getNachrichtEncrypted( txt, län );
+            sName->set( new Text( txt ), i );
+            delete[] txt;
+            klient->getNachrichtEncrypted( (char*)&val, 4 );
+            kupfer->set( val, i );
+            klient->getNachrichtEncrypted( (char*)&val, 4 );
+            verkauft->set( val, i );
+            klient->getNachrichtEncrypted( (char*)&val, 4 );
+            maxSpieler->set( val, i );
+        }
+    }
+    if( res == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+    }
+    cs.unlock();
+    return ret;
+}
+
+bool InformationKlient::getEditorServer( int karteId, int *port, Text *ip ) // sucht nach dem Editor Server von einer Karte
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x2F", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&karteId, 4 );
+        klient->getNachrichtEncrypted( (char*)&ret, 1 );
+        if( ret == 1 )
+        {
+            klient->getNachrichtEncrypted( (char*)port, 4 );
+            char län = 0;
+            klient->getNachrichtEncrypted( &län, 1 );
+            ip->fillText( ' ', län );
+            klient->getNachrichtEncrypted( ip->getText(), län );
+            cs.unlock();
+            return 1;
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool InformationKlient::getKartenServer( int karteId, int *port, Text *ip ) // sucht nach dem Karten Server von einer Karte
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x30", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&karteId, 4 );
+        klient->getNachrichtEncrypted( (char*)&ret, 1 );
+        if( ret == 1 )
+        {
+            klient->getNachrichtEncrypted( (char*)port, 4 );
+            char län = 0;
+            klient->getNachrichtEncrypted( &län, 1 );
+            ip->fillText( ' ', län );
+            klient->getNachrichtEncrypted( ip->getText(), län );
+            cs.unlock();
+            return 1;
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool InformationKlient::trenne() // trennt sich von dem Informaion Server
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 1;
+    }
+    klient->sendeEncrypted( "\3", 1 );
+    Sleep( 100 );
+    klient->trenne();
+    verbunden = 0;
+    cs.unlock();
+    return 1;
+}
+
+// constant
+bool InformationKlient::istVerbunden() const // prüft, ob mit Informaion Server verbunden
+{
+    return verbunden;
+}
+
+char *InformationKlient::getLetzterFehler() const // gibt den Letzten Fehlertext zuück
+{
+    return fehler->getText();
+}
+
+// Reference Counting
+InformationKlientV *InformationKlient::getThis()
+{
+    ref++;
+    return this;
+}
+
+InformationKlientV *InformationKlient::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 461 - 0
KSGClient/Netzwerk/Klients/KartenK.cpp

@@ -0,0 +1,461 @@
+#include "../KSGKlient.h"
+#include "../KSGServer.h"
+#include <Datei.h>
+#include "../../Global/Variablen.h"
+#include "../Keys.h"
+
+// Inhalt der KartenKlient Klasse aus KSGKlient.h
+// Konstruktor
+KartenKlient::KartenKlient()
+{
+    verbunden = 0;
+    klient = 0;
+    fehler = new Text( "" );
+    klientId = getKlientId();
+    ref = 1;
+}
+
+// Destruktor
+KartenKlient::~KartenKlient()
+{
+    cs.lock();
+    if( verbunden )
+        trenne();
+    fehler = fehler->release();
+    cs.unlock();
+}
+
+// nicht constant
+bool KartenKlient::verbinde( unsigned short port, char *ip ) // verbindet ich mit dem Karten Server
+{
+    if( klient && verbunden && klient->getServerPort() == port && Text( ip ).istGleich( klient->getServerIp() ) )
+        return 1;
+    if( klient || verbunden )
+        trenne();
+    klient = new Klient();
+    int keyLen = 0;
+    char *key = 0;
+    Keys::getServerKey( &key, keyLen, Keys::KARTEN, Keys::SENDEN );
+    klient->setSendeKey( key, keyLen );
+    delete[] key;
+    Keys::getServerKey( &key, keyLen, Keys::KARTEN, Keys::EMPFANGEN );
+    klient->setEmpfangKey( key, keyLen );
+    delete[] key;
+    if( !klient->verbinde( (unsigned short)port, ip ) )
+    {
+        klient = klient->release();
+        fehler->setText( "Fehler beim verbinden mit dem Editor Server." );
+        return 0;
+    }
+    klient->sendeEncrypted( "\1", 1 );
+    klient->sendeEncrypted( (char*)&klientId, 4 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *nachricht = new char[ län + 1 ];
+        nachricht[ län ] = 0;
+        klient->getNachrichtEncrypted( nachricht, län );
+        fehler->setText( nachricht );
+        delete[]nachricht;
+        trenne();
+        return 0;
+    }
+    if( ret == 1 )
+    {
+        char *sl = 0;
+        char slLän = getSchlüssel( &sl );
+        klient->setSendeKey( sl, slLän );
+        klient->setEmpfangKey( sl, slLän );
+        delete[] sl;
+        verbunden = 1;
+    }
+    return 1;
+}
+
+bool KartenKlient::downloadKarte( int id ) // läd die Karte herunter
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x6", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&id, 4 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 2 )
+        { // update
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Die Karte wird momentan aktualisiert." ), new Text( "Ok" ) );
+            cs.unlock();
+            return 0;
+        }
+        else if( ret == 1 )
+        {
+            int anz = 0;
+            klient->getNachrichtEncrypted( (char*)&anz, 4 );
+            for( int i = 0; i < anz; i++ )
+            {
+                char län = 0;
+                klient->getNachrichtEncrypted( &län, 1 );
+                if( !län )
+                    continue;
+                char *pf = new char[ län + 1 ];
+                pf[ län ] = 0;
+                klient->getNachrichtEncrypted( pf, län );
+                __int64 größe = 0;
+                klient->getNachrichtEncrypted( (char*)&größe, 8 );
+                char *buffer = new char[ 2048 ];
+                Text pfad = "data/tmp/Karten/";
+                pfad += id;
+                pfad += "/spiel";
+                pfad += pf;
+                delete[] pf;
+                Datei d;
+                d.setDatei( pfad );
+                d.erstellen();
+                d.open( Datei::Style::schreiben );
+                while( größe )
+                {
+                    int l = größe >= 2048 ? 2048 : (int)größe;
+                    klient->getNachricht( buffer, l );
+                    d.schreibe( buffer, l );
+                    größe -= l;
+                }
+                d.close();
+                delete[] buffer;
+            }
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+bool KartenKlient::downloadKarteTitel( int id ) // läd das Titelbild einer Karte herunter
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x8", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&id, 4 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 2 )
+        { // update
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Die Karte wird momentan aktualisiert." ), new Text( "Ok" ) );
+            cs.unlock();
+            return 0;
+        }
+        else if( ret == 1 )
+        {
+            __int64 größe = 0;
+            klient->getNachrichtEncrypted( (char*)&größe, 8 );
+            char *buffer = new char[ 2048 ];
+            Text pfad = "data/tmp/Karten/";
+            pfad += id;
+            pfad += "/titel.ltdb";
+            Datei d;
+            d.setDatei( pfad );
+            d.erstellen();
+            d.open( Datei::Style::schreiben );
+            while( größe )
+            {
+                int l = größe >= 2048 ? 2048 : (int)größe;
+                klient->getNachricht( buffer, l );
+                d.schreibe( buffer, l );
+                größe -= l;
+            }
+            d.close();
+            delete[] buffer;
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+bool KartenKlient::downloadKarteBeschreibung( int id ) // läd die Beschreibung einer Karte herunter
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x9", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&id, 4 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 2 )
+        { // update
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Die Karte wird momentan aktualisiert." ), new Text( "Ok" ) );
+            cs.unlock();
+            return 0;
+        }
+        else if( ret == 1 )
+        {
+            __int64 größe = 0;
+            klient->getNachrichtEncrypted( (char*)&größe, 8 );
+            char *buffer = new char[ 2048 ];
+            Text pfad = "data/tmp/Karten/";
+            pfad += id;
+            pfad += "/beschreibung.ksgs";
+            Datei d;
+            d.setDatei( pfad );
+            d.erstellen();
+            d.open( Datei::Style::schreiben );
+            while( größe )
+            {
+                int l = größe >= 2048 ? 2048 : (int)größe;
+                klient->getNachricht( buffer, l );
+                d.schreibe( buffer, l );
+                größe -= l;
+            }
+            d.close();
+            delete[] buffer;
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+bool KartenKlient::downloadKarteMinimap( int id ) // läd die Minimap einer Karte herunter
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\xA", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&id, 4 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 2 )
+        { // update
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Die Karte wird momentan aktualisiert." ), new Text( "Ok" ) );
+            cs.unlock();
+            return 0;
+        }
+        else if( ret == 1 )
+        {
+            __int64 größe = 0;
+            klient->getNachrichtEncrypted( (char*)&größe, 8 );
+            char *buffer = new char[ 2048 ];
+            Text pfad = "data/tmp/Karten/";
+            pfad += id;
+            pfad += "/minimap.ltdb";
+            Datei d;
+            d.setDatei( pfad );
+            d.erstellen();
+            d.open( Datei::Style::schreiben );
+            while( größe )
+            {
+                int l = größe >= 2048 ? 2048 : (int)größe;
+                klient->getNachricht( buffer, l );
+                d.schreibe( buffer, l );
+                größe -= l;
+            }
+            d.close();
+            delete[] buffer;
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+bool KartenKlient::downloadKarteLadebild( int id ) // läd das Ladebild einer Karte herunter
+{
+    cs.lock();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\xB", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&id, 4 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 2 )
+        { // update
+            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Die Karte wird momentan aktualisiert." ), new Text( "Ok" ) );
+            cs.unlock();
+            return 0;
+        }
+        else if( ret == 1 )
+        {
+            __int64 größe = 0;
+            klient->getNachrichtEncrypted( (char*)&größe, 8 );
+            char *buffer = new char[ 2048 ];
+            Text pfad = "data/tmp/Karten/";
+            pfad += id;
+            pfad += "/ladebild.ltdb";
+            Datei d;
+            d.setDatei( pfad );
+            d.erstellen();
+            d.open( Datei::Style::schreiben );
+            while( größe )
+            {
+                int l = größe >= 2048 ? 2048 : (int)größe;
+                klient->getNachricht( buffer, l );
+                d.schreibe( buffer, l );
+                größe -= l;
+            }
+            d.close();
+            delete[] buffer;
+        }
+    }
+    if( ret == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        char *f = new char[ byte + 1 ];
+        f[ byte ] = 0;
+        klient->getNachrichtEncrypted( f, byte );
+        fehler->setText( f );
+        delete[] f;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+bool KartenKlient::keepAlive() // Erhält die Verbindung aufrecht
+{
+    if( !verbunden )
+        return 0;
+    char res = 0;
+    if( !cs.tryLock() )
+        return 1;
+    klient->sendeEncrypted( "\x5", 1 );
+    klient->getNachrichtEncrypted( &res, 1 );
+    cs.unlock();
+    if( res != 1 )
+    {
+        trenne();
+        fehler->setText( "Verbindung unterbrochen: 'Keep Alive' nicht erfolgreich." );
+    }
+    return res == 1;
+}
+
+bool KartenKlient::trenne() // trennt sich von dem Editor Server
+{
+    if( !klient || !verbunden )
+    {
+        if( klient )
+            klient = klient->release();
+        return 1;
+    }
+    char serverReturn;
+    klient->sendeEncrypted( "\4", 1 );
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char län = 0;
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *nachricht = new char[ län + 1 ];
+        nachricht[ län ] = 0;
+        klient->getNachrichtEncrypted( nachricht, län );
+        delete[]nachricht;
+    }
+    klient->sendeEncrypted( "\3", 1 );
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    klient->trenne();
+    klient = klient->release();
+    return 1;
+}
+
+// constant
+bool KartenKlient::istVerbunden() const // prüft, ob mit Editor Server verbunden
+{
+    return verbunden;
+}
+
+char *KartenKlient::getLetzterFehler() const // gibt den Letzten Fehlertext zuück
+{
+    return fehler->getText();
+}
+
+// Reference Counting
+KartenKlient *KartenKlient::getThis()
+{
+    ref++;
+    return this;
+}
+
+KartenKlient *KartenKlient::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 486 - 0
KSGClient/Netzwerk/Klients/LoginK.cpp

@@ -0,0 +1,486 @@
+#include "../KSGKlient.h"
+#include "../KSGServer.h"
+#include "../Keys.h"
+
+// Inhalt der LoginKlient Klase aus KSGKlient.h
+// Konstruktor 
+LoginKlient::LoginKlient()
+{
+    verbunden = 0;
+    fehler = 0;
+    brauchKick = 0;
+    klient = 0;
+    klientId = getKlientId();
+    accountId = 0;
+    ref = 1;
+}
+
+// Destruktor 
+LoginKlient::~LoginKlient() // wenn verbunden, dann trennen
+{
+    cs.lock();
+    if( klient )
+    {
+        char serverReturn = 0;
+        if( verbunden )
+        {
+            if( brauchKick )
+                klient->sendeEncrypted( "\0", 1 );
+            klient->sendeEncrypted( "\4", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            if( serverReturn == 3 )
+            {
+                char län = 0;
+                klient->getNachrichtEncrypted( &län, 1 );
+                char *nachricht = new char[ län + 1 ];
+                nachricht[ län ] = 0;
+                klient->getNachrichtEncrypted( nachricht, län );
+                delete[]nachricht;
+            }
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+        }
+        else
+        {
+            int keyLen = 0;
+            char *key = 0;
+            Keys::getServerKey( &key, keyLen, Keys::LOGIN, Keys::SENDEN );
+            klient->setSendeKey( key, keyLen );
+            delete[] key;
+            Keys::getServerKey( &key, keyLen, Keys::LOGIN, Keys::EMPFANGEN );
+            klient->setEmpfangKey( key, keyLen );
+            delete[] key;
+            klient->verbinde( klient->getServerPort(), klient->getServerIp() );
+            klient->sendeEncrypted( "\1", 1 );
+            klient->sendeEncrypted( (char*)&klientId, 4 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            if( serverReturn == 3 )
+            {
+                char län = 0;
+                klient->getNachrichtEncrypted( &län, 1 );
+                char *nachricht = new char[ län + 1 ];
+                nachricht[ län ] = 0;
+                klient->getNachrichtEncrypted( nachricht, län );
+                delete[]nachricht;
+            }
+            else
+            {
+                char *sl = 0;
+                char slLän = getSchlüssel( &sl );
+                klient->setSendeKey( sl, slLän );
+                klient->setEmpfangKey( sl, slLän );
+                delete[] sl;
+                klient->sendeEncrypted( "\4", 1 );
+                klient->getNachrichtEncrypted( &serverReturn, 1 );
+                if( serverReturn == 3 )
+                {
+                    char län = 0;
+                    klient->getNachrichtEncrypted( &län, 1 );
+                    char *nachricht = new char[ län + 1 ];
+                    nachricht[ län ] = 0;
+                    klient->getNachrichtEncrypted( nachricht, län );
+                    delete[]nachricht;
+                }
+            }
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+        }
+        klient = klient->release();
+    }
+    delete[]fehler;
+    cs.unlock();
+}
+
+// nicht constant
+bool LoginKlient::verbinde() // verbindet sich mit dem Login Server
+{
+    cs.lock();
+    if( verbunden )
+    {
+        cs.unlock();
+        return 1;
+    }
+    brauchKick = 0;
+    if( !klient )
+    {
+        char *msIp = getMainServerIp();
+        unsigned short msPort = getMainServerPort();
+        klient = new Klient();
+        int keyLen = 0;
+        char *key = 0;
+        Keys::getServerKey( &key, keyLen, Keys::MAIN, Keys::SENDEN );
+        klient->setSendeKey( key, keyLen );
+        delete[] key;
+        Keys::getServerKey( &key, keyLen, Keys::MAIN, Keys::EMPFANGEN );
+        klient->setEmpfangKey( key, keyLen );
+        delete[] key;
+        if( !klient->verbinde( msPort, msIp ) )
+        {
+            char *err = "Fehler beim verbinden mit dem Main Server. Bitte versuche es Später erneut.";
+            delete[]fehler;
+            fehler = new char[ textLength( err ) + 1 ];
+            fehler[ textLength( err ) ] = 0;
+            memcpy( fehler, err, textLength( err ) );
+            klient = klient->release();
+            delete[]msIp;
+            cs.unlock();
+            return 0;
+        }
+        delete[]msIp;
+        klient->sende( "\0", 1 ); // verschlüsselung aktivieren
+        klient->sendeEncrypted( "\1", 1 );
+        klient->sendeEncrypted( (char*)&klientId, 4 );
+        char serverReturn = 0;
+        klient->getNachrichtEncrypted( &serverReturn, 1 );
+        if( serverReturn == 3 )
+        {
+            char byte = 0;
+            klient->getNachrichtEncrypted( &byte, 1 );
+            delete[]fehler;
+            fehler = new char[ byte + 1 ];
+            fehler[ byte ] = 0;
+            klient->getNachrichtEncrypted( fehler, byte );
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+            klient = klient->release();
+            cs.unlock();
+            return 0;
+        }
+        char *sl = 0;
+        char slLän = getSchlüssel( &sl );
+        klient->setSendeKey( sl, slLän );
+        klient->setEmpfangKey( sl, slLän );
+        delete[] sl;
+        klient->sendeEncrypted( "\6\3", 2 );
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        if( byte == 2 )
+        {
+            unsigned char lsIp[ 4 ];
+            klient->getNachrichtEncrypted( (char *)lsIp, 4 );
+            unsigned short lsPort = 0;
+            klient->getNachrichtEncrypted( (char*)&lsPort, 2 );
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+            Text *lsIpT = new Text( "" );
+            lsIpT->append( (int)lsIp[ 0 ] );
+            lsIpT->append( "." );
+            lsIpT->append( (int)lsIp[ 1 ] );
+            lsIpT->append( "." );
+            lsIpT->append( (int)lsIp[ 2 ] );
+            lsIpT->append( "." );
+            lsIpT->append( (int)lsIp[ 3 ] );
+            int keyLen = 0;
+            char *key = 0;
+            Keys::getServerKey( &key, keyLen, Keys::LOGIN, Keys::SENDEN );
+            klient->setSendeKey( key, keyLen );
+            delete[] key;
+            Keys::getServerKey( &key, keyLen, Keys::LOGIN, Keys::EMPFANGEN );
+            klient->setEmpfangKey( key, keyLen );
+            delete[] key;
+            klient->verbinde( lsPort, lsIpT->getText() );
+            lsIpT = lsIpT->release();
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+        }
+        if( byte == 3 )
+        {
+            klient->getNachrichtEncrypted( &byte, 1 );
+            delete[]fehler;
+            fehler = new char[ byte + 1 ];
+            fehler[ byte ] = 0;
+            klient->getNachrichtEncrypted( fehler, byte );
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+            klient = klient->release();
+            cs.unlock();
+            return 0;
+        }
+    }
+    int keyLen = 0;
+    char *key = 0;
+    Keys::getServerKey( &key, keyLen, Keys::LOGIN, Keys::SENDEN );
+    klient->setSendeKey( key, keyLen );
+    delete[] key;
+    Keys::getServerKey( &key, keyLen, Keys::LOGIN, Keys::EMPFANGEN );
+    klient->setEmpfangKey( key, keyLen );
+    delete[] key;
+    if( klient->verbinde( klient->getServerPort(), klient->getServerIp() ) )
+    {
+        if( klient->sendeEncrypted( "\1", 1 ) )
+        {
+            klient->sendeEncrypted( (char*)&klientId, 4 );
+            char serverReturn = 0;
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            if( serverReturn == 3 )
+            {
+                char byte = 0;
+                klient->getNachrichtEncrypted( &byte, 1 );
+                delete[]fehler;
+                fehler = new char[ byte + 1 ];
+                fehler[ byte ] = 0;
+                klient->getNachrichtEncrypted( fehler, byte );
+                klient->sendeEncrypted( "\3", 1 );
+                klient->getNachrichtEncrypted( &serverReturn, 1 );
+                klient->trenne();
+                cs.unlock();
+                return 0;
+            }
+            char *sl = 0;
+            char slLän = getSchlüssel( &sl );
+            klient->setSendeKey( sl, slLän );
+            klient->setEmpfangKey( sl, slLän );
+            delete[] sl;
+            verbunden = 1;
+            cs.unlock();
+            return 1;
+        }
+        else
+        {
+            char *err = "Der dir zugewiesene Login Server hat die Verbindung abgebrochen. Bitte versuche es Später erneut.";
+            delete[]fehler;
+            fehler = new char[ textLength( err ) + 1 ];
+            fehler[ textLength( err ) ] = 0;
+            memcpy( fehler, err, textLength( err ) );
+            klient = klient->release();
+        }
+    }
+    else
+    {
+        char *err = "Der dir zugewiesene Login Server antwortet nicht. Bitte versuche es Später erneut.";
+        delete[]fehler;
+        fehler = new char[ textLength( err ) + 1 ];
+        fehler[ textLength( err ) ] = 0;
+        memcpy( fehler, err, textLength( err ) );
+        klient = klient->release();
+    }
+    cs.unlock();
+    return 0;
+}
+
+int LoginKlient::login( const char *name, const char *pass ) // gibt bei Erfolg 1 zurück
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    if( brauchKick )
+        klient->sendeEncrypted( "\0", 1 );
+    brauchKick = 0;
+    klient->sendeEncrypted( "\5", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        delete[]fehler;
+        fehler = new char[ byte + 1 ];
+        fehler[ byte ] = 0;
+        klient->getNachrichtEncrypted( fehler, byte );
+        cs.unlock();
+        return 0;
+    }
+    unsigned char byte = (unsigned char)textLength( name );
+    klient->sendeEncrypted( (char*)&byte, 1 );
+    klient->sendeEncrypted( name, byte );
+    byte = (unsigned char)textLength( pass );
+    klient->sendeEncrypted( (char*)&byte, 1 );
+    klient->sendeEncrypted( pass, byte );
+    klient->getNachrichtEncrypted( (char*)&byte, 1 );
+    if( byte == 1 )
+    {
+        char host[ 255 ] = "";
+        getHostName( host, 255 );
+        Text *addresse = new Text( getHostAddresse() );
+        unsigned char localIp[ 4 ];
+        localIp[ 0 ] = TextZuInt( addresse->getText(), 10 );
+        localIp[ 1 ] = TextZuInt( addresse->getText() + addresse->positionVon( '.', 0 ) + 1, 10 );
+        localIp[ 2 ] = TextZuInt( addresse->getText() + addresse->positionVon( '.', 1 ) + 1, 10 );
+        localIp[ 3 ] = TextZuInt( addresse->getText() + addresse->positionVon( '.', 2 ) + 1, 10 );
+        addresse = addresse->release();
+        klient->sendeEncrypted( (char*)&localIp, 4 );
+        byte = textLength( host );
+        klient->sendeEncrypted( (char*)&byte, 1 );
+        klient->sendeEncrypted( host, byte );
+        klient->getNachrichtEncrypted( (char*)&accountId, 4 );
+        cs.unlock();
+        return 1;
+    }
+    else if( byte == 2 )
+    {
+        brauchKick = 1;
+        cs.unlock();
+        return 2;
+    }
+    else if( byte == 3 )
+    {
+        klient->getNachrichtEncrypted( (char*)&byte, 1 );
+        delete[]fehler;
+        fehler = new char[ byte + 1 ];
+        fehler[ byte ] = 0;
+        klient->getNachrichtEncrypted( fehler, byte );
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool LoginKlient::kick( const char *geheim )
+{
+    if( !brauchKick )
+        return 1;
+    cs.lock();
+    brauchKick = 0;
+    unsigned char byte = (unsigned char)textLength( geheim );
+    klient->sendeEncrypted( (char*)&byte, 1 );
+    klient->sendeEncrypted( geheim, byte );
+    klient->getNachrichtEncrypted( (char*)&byte, 1 );
+    if( !byte )
+    {
+        cs.unlock();
+        return 0;
+    }
+    char host[ 255 ];
+    getHostName( host, 255 );
+    Text *addresse = new Text( getHostAddresse() );
+    unsigned char localIp[ 4 ];
+    localIp[ 0 ] = TextZuInt( addresse->getText(), 10 );
+    localIp[ 1 ] = TextZuInt( addresse->getText() + addresse->positionVon( '.', 0 ) + 1, 10 );
+    localIp[ 2 ] = TextZuInt( addresse->getText() + addresse->positionVon( '.', 1 ) + 1, 10 );
+    localIp[ 3 ] = TextZuInt( addresse->getText() + addresse->positionVon( '.', 2 ) + 1, 10 );
+    addresse = addresse->release();
+    klient->sendeEncrypted( (char*)&localIp, 4 );
+    byte = textLength( host );
+    klient->sendeEncrypted( (char*)&byte, 1 );
+    klient->sendeEncrypted( host, byte );
+    klient->getNachrichtEncrypted( (char*)&accountId, 4 );
+    cs.unlock();
+    return 1;
+}
+
+bool LoginKlient::logout() // logt den Account aus
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    if( brauchKick )
+        klient->sendeEncrypted( "\0", 1 );
+    brauchKick = 0;
+    klient->sendeEncrypted( "\6", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        delete[]fehler;
+        fehler = new char[ byte + 1 ];
+        fehler[ byte ] = 0;
+        klient->getNachrichtEncrypted( fehler, byte );
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( (char*)&accountId, 4 );
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        delete[]fehler;
+        fehler = new char[ byte + 1 ];
+        fehler[ byte ] = 0;
+        klient->getNachrichtEncrypted( fehler, byte );
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+bool LoginKlient::keepAlive() // Erhält die Verbindung aufrecht
+{
+    if( !verbunden )
+        return 0;
+    char res = 0;
+    if( !cs.tryLock() )
+        return 1;
+    klient->sendeEncrypted( "\x7", 1 );
+    klient->getNachrichtEncrypted( &res, 1 );
+    cs.unlock();
+    if( res != 1 )
+        trenne();
+    return res == 1;
+}
+
+bool LoginKlient::trenne() // trennt sich von dem Login Server
+{
+    if( verbunden )
+    {
+        cs.lock();
+        if( brauchKick )
+            klient->sendeEncrypted( "\0", 1 );
+        brauchKick = 0;
+        klient->sendeEncrypted( "\3", 1 );
+        char serverReturn = 0;
+        klient->getNachrichtEncrypted( &serverReturn, 1 );
+        klient->trenne();
+        verbunden = 0;
+        cs.unlock();
+    }
+    return 1;
+}
+
+void LoginKlient::setLetzterFehler( char *err ) // setzt den letzten Fehler
+{
+    if( fehler )
+        delete[]fehler;
+    fehler = new char[ textLength( err ) + 1 ];
+    memcpy( fehler, err, textLength( err ) );
+    fehler[ textLength( err ) ] = 0;
+}
+
+// constant
+bool LoginKlient::istVerbunden() const // prüft, ob mit Login Server verbunden
+{
+    return verbunden;
+}
+
+int LoginKlient::getAccountId() const // gibt die AccountId zurück
+{
+    return accountId;
+}
+
+char *LoginKlient::getLetzterFehler() const // gibt den Letzten Fehlertext zuück
+{
+    return fehler;
+}
+
+// Reference Counting
+LoginKlient *LoginKlient::getThis()
+{
+    ref++;
+    return this;
+}
+
+LoginKlient *LoginKlient::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 381 - 0
KSGClient/Netzwerk/Klients/NewsK.cpp

@@ -0,0 +1,381 @@
+#include "../KSGKlient.h"
+#include "../KSGServer.h"
+#include <Datei.h>
+#include "../Keys.h"
+
+// Inhalt der NewsKlients Klasse aus KSGKlient.h
+// Konstruktor
+NewsKlient::NewsKlient()
+{
+    verbunden = 0;
+    klient = 0;
+    fehler = new Text( "" );
+    klientId = getKlientId();
+    ref = 1;
+}
+
+// Destruktor
+NewsKlient::~NewsKlient()
+{
+    cs.lock();
+    if( klient )
+    {
+        char serverReturn = 0;
+        if( verbunden )
+        {
+            klient->sendeEncrypted( "\4", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            if( serverReturn == 3 )
+            {
+                char län = 0;
+                klient->getNachrichtEncrypted( &län, 1 );
+                char *nachricht = new char[ län + 1 ];
+                nachricht[ län ] = 0;
+                klient->getNachrichtEncrypted( nachricht, län );
+                delete[]nachricht;
+            }
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+        }
+        else
+        {
+            int keyLen = 0;
+            char *key = 0;
+            Keys::getServerKey( &key, keyLen, Keys::NEWS, Keys::SENDEN );
+            klient->setSendeKey( key, keyLen );
+            delete[] key;
+            Keys::getServerKey( &key, keyLen, Keys::NEWS, Keys::EMPFANGEN );
+            klient->setEmpfangKey( key, keyLen );
+            delete[] key;
+            klient->verbinde( klient->getServerPort(), klient->getServerIp() );
+            klient->sendeEncrypted( "\1", 1 );
+            klient->sendeEncrypted( (char*)&klientId, 4 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            if( serverReturn == 3 )
+            {
+                char län = 0;
+                klient->getNachrichtEncrypted( &län, 1 );
+                char *nachricht = new char[ län + 1 ];
+                nachricht[ län ] = 0;
+                klient->getNachrichtEncrypted( nachricht, län );
+                delete[]nachricht;
+            }
+            else
+            {
+                char *sl = 0;
+                char slLän = getSchlüssel( &sl );
+                klient->setSendeKey( sl, slLän );
+                klient->setEmpfangKey( sl, slLän );
+                delete[] sl;
+                klient->sendeEncrypted( "\4", 1 );
+                klient->getNachrichtEncrypted( &serverReturn, 1 );
+                if( serverReturn == 3 )
+                {
+                    char län = 0;
+                    klient->getNachrichtEncrypted( &län, 1 );
+                    char *nachricht = new char[ län + 1 ];
+                    nachricht[ län ] = 0;
+                    klient->getNachrichtEncrypted( nachricht, län );
+                    delete[]nachricht;
+                }
+            }
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+        }
+        klient = klient->release();
+    }
+    fehler = fehler->release();
+    cs.unlock();
+}
+
+// nicht constant
+bool NewsKlient::verbinde() // verbindet ich mit dem News Server
+{
+    cs.lock();
+    if( verbunden )
+    {
+        cs.unlock();
+        return 1;
+    }
+    if( !klient )
+    {
+        char *msIp = getMainServerIp();
+        unsigned short msPort = getMainServerPort();
+        klient = new Klient();
+        int keyLen = 0;
+        char *key = 0;
+        Keys::getServerKey( &key, keyLen, Keys::MAIN, Keys::SENDEN );
+        klient->setSendeKey( key, keyLen );
+        delete[] key;
+        Keys::getServerKey( &key, keyLen, Keys::MAIN, Keys::EMPFANGEN );
+        klient->setEmpfangKey( key, keyLen );
+        delete[] key;
+        if( !klient->verbinde( msPort, msIp ) )
+        {
+            fehler->setText( "Fehler beim verbinden mit dem Main Server. Bitte versuche es Später erneut." );
+            klient = klient->release();
+            delete[]msIp;
+            cs.unlock();
+            return 0;
+        }
+        delete[]msIp;
+        klient->sende( "\0", 1 ); // Verschlüsselung aktivieren
+        klient->sendeEncrypted( "\1", 1 );
+        klient->sendeEncrypted( (char*)&klientId, 4 );
+        char serverReturn = 0;
+        klient->getNachrichtEncrypted( &serverReturn, 1 );
+        if( serverReturn == 3 )
+        {
+            char län = 0;
+            klient->getNachrichtEncrypted( &län, 1 );
+            char *nachricht = new char[ län + 1 ];
+            nachricht[ län ] = 0;
+            klient->getNachrichtEncrypted( nachricht, län );
+            fehler->setText( nachricht );
+            delete[]nachricht;
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+            klient = klient->release();
+            cs.unlock();
+            return 0;
+        }
+        char *sl = 0;
+        char slLän = getSchlüssel( &sl );
+        klient->setSendeKey( sl, slLän );
+        klient->setEmpfangKey( sl, slLän );
+        delete[] sl;
+        klient->sendeEncrypted( "\6\x9", 2 );
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        if( byte == 2 )
+        {
+            unsigned char lsIp[ 4 ];
+            klient->getNachrichtEncrypted( (char *)lsIp, 4 );
+            unsigned short lsPort = 0;
+            klient->getNachrichtEncrypted( (char*)&lsPort, 2 );
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+            Text *lsIpT = new Text( "" );
+            lsIpT->append( (int)lsIp[ 0 ] );
+            lsIpT->append( "." );
+            lsIpT->append( (int)lsIp[ 1 ] );
+            lsIpT->append( "." );
+            lsIpT->append( (int)lsIp[ 2 ] );
+            lsIpT->append( "." );
+            lsIpT->append( (int)lsIp[ 3 ] );
+            int keyLen = 0;
+            char *key = 0;
+            Keys::getServerKey( &key, keyLen, Keys::NEWS, Keys::SENDEN );
+            klient->setSendeKey( key, keyLen );
+            delete[] key;
+            Keys::getServerKey( &key, keyLen, Keys::NEWS, Keys::EMPFANGEN );
+            klient->setEmpfangKey( key, keyLen );
+            delete[] key;
+            klient->verbinde( lsPort, lsIpT->getText() );
+            lsIpT = lsIpT->release();
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+        }
+        if( byte == 3 )
+        {
+            klient->getNachrichtEncrypted( &byte, 1 );
+            char *f = new char[ byte + 1 ];
+            f[ byte ] = 0;
+            klient->getNachrichtEncrypted( f, byte );
+            fehler->setText( f );
+            delete[]f;
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+            klient = klient->release();
+            cs.unlock();
+            return 0;
+        }
+    }
+    int keyLen = 0;
+    char *key = 0;
+    Keys::getServerKey( &key, keyLen, Keys::NEWS, Keys::SENDEN );
+    klient->setSendeKey( key, keyLen );
+    delete[] key;
+    Keys::getServerKey( &key, keyLen, Keys::NEWS, Keys::EMPFANGEN );
+    klient->setEmpfangKey( key, keyLen );
+    delete[] key;
+    if( klient->verbinde( klient->getServerPort(), klient->getServerIp() ) )
+    {
+        if( klient->sendeEncrypted( "\1", 1 ) )
+        {
+            klient->sendeEncrypted( (char*)&klientId, 4 );
+            char serverReturn = 0;
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            if( serverReturn == 3 )
+            {
+                char byte = 0;
+                klient->getNachrichtEncrypted( &byte, 1 );
+                char *f = new char[ byte + 1 ];
+                f[ byte ] = 0;
+                klient->getNachrichtEncrypted( f, byte );
+                fehler->setText( f );
+                delete[]f;
+                klient->sendeEncrypted( "\3", 1 );
+                klient->getNachrichtEncrypted( &serverReturn, 1 );
+                klient->trenne();
+                cs.unlock();
+                return 0;
+            }
+            char *sl = 0;
+            char slLän = getSchlüssel( &sl );
+            klient->setSendeKey( sl, slLän );
+            klient->setEmpfangKey( sl, slLän );
+            delete[] sl;
+            verbunden = 1;
+            cs.unlock();
+            return 1;
+        }
+        else
+        {
+            fehler->setText( "Der dir zugewiesene News Server hat die Verbindung abgebrochen. Bitte versuche es Später erneut." );
+            klient = klient->release();
+        }
+    }
+    else
+    {
+        fehler->setText( "Der dir zugewiesene News Server antwortet nicht. Bitte versuche es Später erneut." );
+        klient = klient->release();
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool NewsKlient::ladeSeite( char *name )
+{
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\5", 1 );
+    char ret = 0;
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        char län = (char)textLength( name );
+        klient->sendeEncrypted( &län, 1 );
+        klient->sendeEncrypted( name, län );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            Text *pfad = new Text( "data/tmp/news/" );
+            pfad->append( name );
+            if( DateiExistiert( pfad->getThis() ) )
+                DateiRemove( pfad->getThis() );
+            pfad->append( "/" );
+            int dAnz = 0;
+            klient->getNachrichtEncrypted( (char*)&dAnz, 4 );
+            for( int i = 0; i < dAnz; i++ )
+            {
+                char nLän = 0;
+                klient->getNachrichtEncrypted( &nLän, 1 );
+                char *dName = new char[ nLän + 1 ];
+                dName[ nLän ] = 0;
+                klient->getNachrichtEncrypted( dName, nLän );
+                Text *pf = new Text( pfad->getText() );
+                pf->append( dName );
+                delete[] dName;
+                Datei *d = new Datei();
+                d->setDatei( pf );
+                d->erstellen();
+                d->open( Datei::Style::schreiben );
+                __int64 dGr = 0;
+                klient->getNachrichtEncrypted( (char*)&dGr, 8 );
+                char buffer[ 2048 ];
+                while( dGr > 0 )
+                {
+                    int län = dGr > 2048 ? 2048 : (int)dGr;
+                    klient->getNachricht( buffer, län );
+                    d->schreibe( buffer, län );
+                    dGr -= län;
+                }
+                d->close();
+                d->release();
+            }
+            pfad->release();
+        }
+    }
+    if( ret == 3 )
+    {
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret )
+        {
+            char *tmp = new char[ ret ];
+            klient->getNachrichtEncrypted( tmp, ret );
+            delete[] tmp;
+        }
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+bool NewsKlient::keepAlive() // Erhält die Verbindung aufrecht
+{
+    if( !verbunden )
+        return 0;
+    char res = 0;
+    if( !cs.tryLock() )
+        return 1;
+    klient->sendeEncrypted( "\x6", 1 );
+    klient->getNachrichtEncrypted( &res, 1 );
+    cs.unlock();
+    if( res != 1 )
+        trenne();
+    return res == 1;
+}
+
+bool NewsKlient::trenne() // trennt sich von dem News Server
+{
+    if( !verbunden )
+        return 1;
+    cs.lock();
+    klient->sendeEncrypted( "\3", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    klient->trenne();
+    verbunden = 0;
+    cs.unlock();
+    return 1;
+}
+
+// constant
+bool NewsKlient::istVerbunden() const // prüft, ob mit News Server verbunden
+{
+    return verbunden;
+}
+
+char *NewsKlient::getLetzterFehler() const // gibt den Letzten Fehlertext zuück
+{
+    return fehler->getText();
+}
+
+// Reference Counting
+NewsKlient *NewsKlient::getThis()
+{
+    ref++;
+    return this;
+}
+
+NewsKlient *NewsKlient::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 956 - 0
KSGClient/Netzwerk/Klients/RegisterK.cpp

@@ -0,0 +1,956 @@
+#include "../KSGKlient.h"
+#include "../KSGServer.h"
+#include "../Keys.h"
+
+// Inhalt der RegisterKlient Klasse aus KSGKlient.h
+// Konstruktor 
+RegisterKlient::RegisterKlient()
+{
+    klient = 0;
+    verbunden = 0;
+    fehler = 0;
+    brauchSchlüssel = 0;
+    klientId = getKlientId();
+    ref = 1;
+}
+
+// Destruktor
+RegisterKlient::~RegisterKlient() // wenn verbunden, dann trennen
+{
+    cs.lock();
+    if( klient )
+    {
+        char serverReturn = 0;
+        if( verbunden )
+        {
+            if( brauchSchlüssel )
+            {
+                char byte = -1;
+                klient->sendeEncrypted( &byte, 1 );
+            }
+            klient->sendeEncrypted( "\4", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            if( serverReturn == 3 )
+            {
+                char län = 0;
+                klient->getNachrichtEncrypted( &län, 1 );
+                char *nachricht = new char[ län + 1 ];
+                nachricht[ län ] = 0;
+                klient->getNachrichtEncrypted( nachricht, län );
+                delete[]nachricht;
+            }
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+        }
+        else
+        {
+            int keyLen = 0;
+            char *key = 0;
+            Keys::getServerKey( &key, keyLen, Keys::REGISTER, Keys::SENDEN );
+            klient->setSendeKey( key, keyLen );
+            delete[] key;
+            Keys::getServerKey( &key, keyLen, Keys::REGISTER, Keys::EMPFANGEN );
+            klient->setEmpfangKey( key, keyLen );
+            delete[] key;
+            klient->verbinde( klient->getServerPort(), klient->getServerIp() );
+            klient->sendeEncrypted( "\1", 1 );
+            klient->sendeEncrypted( (char*)&klientId, 4 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            if( serverReturn == 3 )
+            {
+                char län = 0;
+                klient->getNachrichtEncrypted( &län, 1 );
+                char *nachricht = new char[ län + 1 ];
+                nachricht[ län ] = 0;
+                klient->getNachrichtEncrypted( nachricht, län );
+                delete[]nachricht;
+            }
+            else
+            {
+                char *sl = 0;
+                char slLän = getSchlüssel( &sl );
+                klient->setSendeKey( sl, slLän );
+                klient->setEmpfangKey( sl, slLän );
+                delete[] sl;
+                klient->sendeEncrypted( "\4", 1 );
+                klient->getNachrichtEncrypted( &serverReturn, 1 );
+                if( serverReturn == 3 )
+                {
+                    char län = 0;
+                    klient->getNachrichtEncrypted( &län, 1 );
+                    char *nachricht = new char[ län + 1 ];
+                    nachricht[ län ] = 0;
+                    klient->getNachrichtEncrypted( nachricht, län );
+                    delete[]nachricht;
+                }
+            }
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+        }
+        klient = klient->release();
+    }
+    delete[]fehler;
+    cs.unlock();
+}
+
+// nicht constant
+bool RegisterKlient::verbinde() // verbindet ich mit dem Register Server
+{
+    cs.lock();
+    if( verbunden )
+    {
+        cs.unlock();
+        return 1;
+    }
+    brauchSchlüssel = 0;
+    if( !klient )
+    {
+        char *msIp = getMainServerIp();
+        unsigned short msPort = getMainServerPort();
+        klient = new Klient();
+        int keyLen = 0;
+        char *key = 0;
+        Keys::getServerKey( &key, keyLen, Keys::MAIN, Keys::SENDEN );
+        klient->setSendeKey( key, keyLen );
+        delete[] key;
+        Keys::getServerKey( &key, keyLen, Keys::MAIN, Keys::EMPFANGEN );
+        klient->setEmpfangKey( key, keyLen );
+        delete[] key;
+        if( !klient->verbinde( msPort, msIp ) )
+        {
+            char *err = "Fehler beim verbinden mit dem Main Server. Bitte versuche es Später erneut.";
+            delete[]fehler;
+            fehler = new char[ textLength( err ) + 1 ];
+            fehler[ textLength( err ) ] = 0;
+            memcpy( fehler, err, textLength( err ) );
+            klient = klient->release();
+            delete[]msIp;
+            cs.unlock();
+            return 0;
+        }
+        delete[]msIp;
+        klient->sende( "\0", 1 ); // Verschlüsselung aktivieren
+        klient->sendeEncrypted( "\1", 1 );
+        klient->sendeEncrypted( (char*)&klientId, 4 );
+        char serverReturn = 0;
+        klient->getNachrichtEncrypted( &serverReturn, 1 );
+        if( serverReturn == 3 )
+        {
+            char byte = 0;
+            klient->getNachrichtEncrypted( &byte, 1 );
+            delete[]fehler;
+            fehler = new char[ byte + 1 ];
+            fehler[ byte ] = 0;
+            klient->getNachrichtEncrypted( fehler, byte );
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+            klient = klient->release();
+            cs.unlock();
+            return 0;
+        }
+        char *sl = 0;
+        char slLän = getSchlüssel( &sl );
+        klient->setSendeKey( sl, slLän );
+        klient->setEmpfangKey( sl, slLän );
+        delete[] sl;
+        klient->sendeEncrypted( "\6\1", 2 );
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        if( byte == 2 )
+        {
+            unsigned char lsIp[ 4 ];
+            klient->getNachrichtEncrypted( (char *)lsIp, 4 );
+            unsigned short lsPort = 0;
+            klient->getNachrichtEncrypted( (char*)&lsPort, 2 );
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+            Text *lsIpT = new Text( "" );
+            lsIpT->append( (int)lsIp[ 0 ] );
+            lsIpT->append( "." );
+            lsIpT->append( (int)lsIp[ 1 ] );
+            lsIpT->append( "." );
+            lsIpT->append( (int)lsIp[ 2 ] );
+            lsIpT->append( "." );
+            lsIpT->append( (int)lsIp[ 3 ] );
+            int keyLen = 0;
+            char *key = 0;
+            Keys::getServerKey( &key, keyLen, Keys::REGISTER, Keys::SENDEN );
+            klient->setSendeKey( key, keyLen );
+            delete[] key;
+            Keys::getServerKey( &key, keyLen, Keys::REGISTER, Keys::EMPFANGEN );
+            klient->setEmpfangKey( key, keyLen );
+            delete[] key;
+            klient->verbinde( lsPort, lsIpT->getText() );
+            lsIpT = lsIpT->release();
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+        }
+        if( byte == 3 )
+        {
+            klient->getNachrichtEncrypted( &byte, 1 );
+            delete[]fehler;
+            fehler = new char[ byte + 1 ];
+            fehler[ byte ] = 0;
+            klient->getNachrichtEncrypted( fehler, byte );
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+            klient = klient->release();
+            cs.unlock();
+            return 0;
+        }
+    }
+    int keyLen = 0;
+    char *key = 0;
+    Keys::getServerKey( &key, keyLen, Keys::REGISTER, Keys::SENDEN );
+    klient->setSendeKey( key, keyLen );
+    delete[] key;
+    Keys::getServerKey( &key, keyLen, Keys::REGISTER, Keys::EMPFANGEN );
+    klient->setEmpfangKey( key, keyLen );
+    delete[] key;
+    if( klient->verbinde( klient->getServerPort(), klient->getServerIp() ) )
+    {
+        if( klient->sendeEncrypted( "\1", 1 ) )
+        {
+            klient->sendeEncrypted( (char*)&klientId, 4 );
+            char serverReturn = 0;
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            if( serverReturn == 3 )
+            {
+                char byte = 0;
+                klient->getNachrichtEncrypted( &byte, 1 );
+                delete[]fehler;
+                fehler = new char[ byte + 1 ];
+                fehler[ byte ] = 0;
+                klient->getNachrichtEncrypted( fehler, byte );
+                klient->sendeEncrypted( "\3", 1 );
+                klient->getNachrichtEncrypted( &serverReturn, 1 );
+                klient->trenne();
+                cs.unlock();
+                return 0;
+            }
+            char *sl = 0;
+            char slLän = getSchlüssel( &sl );
+            klient->setSendeKey( sl, slLän );
+            klient->setEmpfangKey( sl, slLän );
+            delete[] sl;
+            verbunden = 1;
+            cs.unlock();
+            return 1;
+        }
+        else
+        {
+            char *err = "Der dir zugewiesene Registrierungs Server hat die Verbindung abgebrochen. Bitte versuche es Später erneut.";
+            delete[]fehler;
+            fehler = new char[ textLength( err ) + 1 ];
+            fehler[ textLength( err ) ] = 0;
+            memcpy( fehler, err, textLength( err ) );
+            klient = klient->release();
+        }
+    }
+    else
+    {
+        char *err = "Der dir zugewiesene Registrierungs Server antwortet nicht. Bitte versuche es Später erneut.";
+        delete[]fehler;
+        fehler = new char[ textLength( err ) + 1 ];
+        fehler[ textLength( err ) ] = 0;
+        memcpy( fehler, err, textLength( err ) );
+        klient = klient->release();
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool RegisterKlient::accountErstellen( const char *name, const char *pass, const char *geheim, const char *eMail, unsigned short jahr, char monat, char tag ) // erstellt den Account
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    if( brauchSchlüssel )
+    {
+        char byte = -1;
+        klient->sendeEncrypted( &byte, 1 );
+    }
+    brauchSchlüssel = 0;
+    klient->sendeEncrypted( "\5", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        delete[]fehler;
+        fehler = new char[ byte + 1 ];
+        fehler[ byte ] = 0;
+        klient->getNachrichtEncrypted( fehler, byte );
+        cs.unlock();
+        return 0;
+    }
+    unsigned char län[ 4 ] = {
+        (unsigned char)textLength( name ),
+        (unsigned char)textLength( pass ),
+        (unsigned char)textLength( geheim ),
+        (unsigned char)textLength( eMail )
+    };
+    klient->sendeEncrypted( (char*)län, 4 );
+    klient->sendeEncrypted( name, län[ 0 ] );
+    klient->sendeEncrypted( pass, län[ 1 ] );
+    klient->sendeEncrypted( geheim, län[ 2 ] );
+    klient->sendeEncrypted( eMail, län[ 3 ] );
+    klient->sendeEncrypted( (char*)&jahr, 2 );
+    klient->sendeEncrypted( &monat, 1 );
+    klient->sendeEncrypted( &tag, 1 );
+    char byte = 0;
+    klient->getNachrichtEncrypted( &byte, 1 );
+    if( byte == 1 )
+    {
+        brauchSchlüssel = 1;
+        cs.unlock();
+        return 1;
+    }
+    else if( byte == 3 )
+    {
+        klient->getNachrichtEncrypted( &byte, 1 );
+        delete[]fehler;
+        fehler = new char[ byte + 1 ];
+        fehler[ byte ] = 0;
+        klient->getNachrichtEncrypted( fehler, byte );
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool RegisterKlient::accountLöschen( const char *name, const char *pass, const char *geheim ) // löscht den Account
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    if( brauchSchlüssel )
+    {
+        char byte = -1;
+        klient->sendeEncrypted( &byte, 1 );
+    }
+    brauchSchlüssel = 0;
+    klient->sendeEncrypted( "\6", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        delete[]fehler;
+        fehler = new char[ byte + 1 ];
+        fehler[ byte ] = 0;
+        klient->getNachrichtEncrypted( fehler, byte );
+        cs.unlock();
+        return 0;
+    }
+    unsigned char län[ 3 ] = {
+        (unsigned char)textLength( name ),
+        (unsigned char)textLength( pass ),
+        (unsigned char)textLength( geheim )
+    };
+    klient->sendeEncrypted( (char*)län, 3 );
+    klient->sendeEncrypted( name, län[ 0 ] );
+    klient->sendeEncrypted( pass, län[ 1 ] );
+    klient->sendeEncrypted( geheim, län[ 2 ] );
+    char byte = 0;
+    klient->getNachrichtEncrypted( &byte, 1 );
+    if( byte == 1 )
+    {
+        brauchSchlüssel = 1;
+        cs.unlock();
+        return 1;
+    }
+    else if( byte == 3 )
+    {
+        klient->getNachrichtEncrypted( &byte, 1 );
+        delete[]fehler;
+        fehler = new char[ byte + 1 ];
+        fehler[ byte ] = 0;
+        klient->getNachrichtEncrypted( fehler, byte );
+    }
+    cs.unlock();
+    return 0;
+}
+
+int RegisterKlient::accountBestätigen( const char *name, const char *pass ) // account Bestätigung fortsetzen
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    if( brauchSchlüssel )
+    {
+        char byte = -1;
+        klient->sendeEncrypted( &byte, 1 );
+    }
+    char byte = 0xE;
+    klient->sendeEncrypted( &byte, 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        delete[]fehler;
+        fehler = new char[ byte + 1 ];
+        fehler[ byte ] = 0;
+        klient->getNachrichtEncrypted( fehler, byte );
+        cs.unlock();
+        return 0;
+    }
+    unsigned char län[ 2 ] = {
+        (unsigned char)textLength( name ),
+        (unsigned char)textLength( pass )
+    };
+    klient->sendeEncrypted( (char*)län, 2 );
+    klient->sendeEncrypted( name, län[ 0 ] );
+    klient->sendeEncrypted( pass, län[ 1 ] );
+    byte = 0;
+    klient->getNachrichtEncrypted( &byte, 1 );
+    brauchSchlüssel = 1;
+    if( byte == 1 )
+    {
+        cs.unlock();
+        return 1;
+    }
+    if( byte == 2 )
+    {
+        cs.unlock();
+        return 2;
+    }
+    brauchSchlüssel = 0;
+    if( byte == 3 )
+    {
+        klient->getNachrichtEncrypted( &byte, 1 );
+        delete[]fehler;
+        fehler = new char[ byte + 1 ];
+        fehler[ byte ] = 0;
+        klient->getNachrichtEncrypted( fehler, byte );
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool RegisterKlient::bestätigen( const char *schlüssel ) // bestätigt den Vorgang mit Schüssel
+{
+    if( !brauchSchlüssel )
+        return 1;
+    cs.lock();
+    unsigned char län = textLength( schlüssel );
+    klient->sendeEncrypted( (char*)&län, 1 );
+    klient->sendeEncrypted( schlüssel, län );
+    klient->getNachrichtEncrypted( (char*)&län, 1 );
+    cs.unlock();
+    if( län )
+    {
+        brauchSchlüssel = 0;
+        return 1;
+    }
+    else
+        return 0;
+}
+
+void RegisterKlient::eMailErneutSenden() // E-Mail nochmal senden
+{
+    cs.lock();
+    char byte = -2;
+    if( brauchSchlüssel )
+        klient->sendeEncrypted( &byte, 1 );
+    cs.unlock();
+}
+
+void RegisterKlient::später() // bestätigung später abclose
+{
+    cs.lock();
+    if( brauchSchlüssel )
+    {
+        char byte = -1;
+        klient->sendeEncrypted( &byte, 1 );
+    }
+    brauchSchlüssel = 0;
+    cs.unlock();
+}
+
+void RegisterKlient::abbrechen() // bricht den Vorgang ab
+{
+    cs.lock();
+    if( brauchSchlüssel )
+        klient->sendeEncrypted( "\0", 1 );
+    brauchSchlüssel = 0;
+    cs.unlock();
+}
+
+bool RegisterKlient::passwortÄndern( const char *name, const char *pass, const char *geheim, const char *nPass ) // ändert das Passwort
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    if( brauchSchlüssel )
+    {
+        char byte = -1;
+        klient->sendeEncrypted( &byte, 1 );
+    }
+    brauchSchlüssel = 0;
+    klient->sendeEncrypted( "\7", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        delete[]fehler;
+        fehler = new char[ byte + 1 ];
+        fehler[ byte ] = 0;
+        klient->getNachrichtEncrypted( fehler, byte );
+        cs.unlock();
+        return 0;
+    }
+    unsigned char län[ 4 ] = {
+        (unsigned char)textLength( name ),
+        (unsigned char)textLength( pass ),
+        (unsigned char)textLength( nPass ),
+        (unsigned char)textLength( geheim )
+    };
+    klient->sendeEncrypted( (char*)län, 4 );
+    klient->sendeEncrypted( name, län[ 0 ] );
+    klient->sendeEncrypted( pass, län[ 1 ] );
+    klient->sendeEncrypted( nPass, län[ 2 ] );
+    klient->sendeEncrypted( geheim, län[ 3 ] );
+    char byte = 0;
+    klient->getNachrichtEncrypted( &byte, 1 );
+    if( byte == 1 )
+    {
+        cs.unlock();
+        return 1;
+    }
+    else if( byte == 3 )
+    {
+        klient->getNachrichtEncrypted( &byte, 1 );
+        delete[]fehler;
+        fehler = new char[ byte + 1 ];
+        fehler[ byte ] = 0;
+        klient->getNachrichtEncrypted( fehler, byte );
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool RegisterKlient::eMailÄndern( const char *name, const char *pass, const char *geheim, const char *nEMail ) // ändert die E-Mail Addresse
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    if( brauchSchlüssel )
+    {
+        char byte = -1;
+        klient->sendeEncrypted( &byte, 1 );
+    }
+    brauchSchlüssel = 0;
+    char byte = 8;
+    klient->sendeEncrypted( &byte, 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        delete[]fehler;
+        fehler = new char[ byte + 1 ];
+        fehler[ byte ] = 0;
+        klient->getNachrichtEncrypted( fehler, byte );
+        cs.unlock();
+        return 0;
+    }
+    unsigned char län[ 4 ] = {
+        (unsigned char)textLength( name ),
+        (unsigned char)textLength( pass ),
+        (unsigned char)textLength( geheim ),
+        (unsigned char)textLength( nEMail )
+    };
+    klient->sendeEncrypted( (char*)län, 4 );
+    klient->sendeEncrypted( name, län[ 0 ] );
+    klient->sendeEncrypted( pass, län[ 1 ] );
+    klient->sendeEncrypted( geheim, län[ 2 ] );
+    klient->sendeEncrypted( nEMail, län[ 3 ] );
+    byte = 0;
+    klient->getNachrichtEncrypted( &byte, 1 );
+    if( byte == 1 )
+    {
+        cs.unlock();
+        return 1;
+    }
+    else if( byte == 3 )
+    {
+        klient->getNachrichtEncrypted( &byte, 1 );
+        delete[]fehler;
+        fehler = new char[ byte + 1 ];
+        fehler[ byte ] = 0;
+        klient->getNachrichtEncrypted( fehler, byte );
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool RegisterKlient::geheimnisÄndern( const char *name, const char *pass, const char *geheim, const char *nGeheim ) // ändert das Geheimnis
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    if( brauchSchlüssel )
+    {
+        char byte = -1;
+        klient->sendeEncrypted( &byte, 1 );
+    }
+    brauchSchlüssel = 0;
+    char byte = 9;
+    klient->sendeEncrypted( &byte, 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        delete[]fehler;
+        fehler = new char[ byte + 1 ];
+        fehler[ byte ] = 0;
+        klient->getNachrichtEncrypted( fehler, byte );
+        cs.unlock();
+        return 0;
+    }
+    unsigned char län[ 4 ] = {
+        (unsigned char)textLength( name ),
+        (unsigned char)textLength( pass ),
+        (unsigned char)textLength( geheim ),
+        (unsigned char)textLength( nGeheim )
+    };
+    klient->sendeEncrypted( (char*)län, 4 );
+    klient->sendeEncrypted( name, län[ 0 ] );
+    klient->sendeEncrypted( pass, län[ 1 ] );
+    klient->sendeEncrypted( geheim, län[ 2 ] );
+    klient->sendeEncrypted( nGeheim, län[ 3 ] );
+    byte = 0;
+    klient->getNachrichtEncrypted( &byte, 1 );
+    if( byte == 1 )
+    {
+        cs.unlock();
+        return 1;
+    }
+    else if( byte == 3 )
+    {
+        klient->getNachrichtEncrypted( &byte, 1 );
+        delete[]fehler;
+        fehler = new char[ byte + 1 ];
+        fehler[ byte ] = 0;
+        klient->getNachrichtEncrypted( fehler, byte );
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool RegisterKlient::nameVergessen( const char *pass, const char *geheim ) // schickt den Account Namen an die Bekannte E-Mail Addresse
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    if( brauchSchlüssel )
+    {
+        char byte = -1;
+        klient->sendeEncrypted( &byte, 1 );
+    }
+    brauchSchlüssel = 0;
+    char byte = 0xA;
+    klient->sendeEncrypted( &byte, 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        delete[]fehler;
+        fehler = new char[ byte + 1 ];
+        fehler[ byte ] = 0;
+        klient->getNachrichtEncrypted( fehler, byte );
+        cs.unlock();
+        return 0;
+    }
+    unsigned char län[ 2 ] = {
+        (unsigned char)textLength( pass ),
+        (unsigned char)textLength( geheim )
+    };
+    klient->sendeEncrypted( (char*)län, 2 );
+    klient->sendeEncrypted( pass, län[ 0 ] );
+    klient->sendeEncrypted( geheim, län[ 1 ] );
+    byte = 0;
+    klient->getNachrichtEncrypted( &byte, 1 );
+    if( byte == 1 )
+    {
+        cs.unlock();
+        return 1;
+    }
+    else if( byte == 3 )
+    {
+        klient->getNachrichtEncrypted( &byte, 1 );
+        delete[]fehler;
+        fehler = new char[ byte + 1 ];
+        fehler[ byte ] = 0;
+        klient->getNachrichtEncrypted( fehler, byte );
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool RegisterKlient::passwortVergessen( const char *name, const char *geheim ) // schickt das Account Passwort an die Bekannte E-Mail Addresse
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    if( brauchSchlüssel )
+    {
+        char byte = -1;
+        klient->sendeEncrypted( &byte, 1 );
+    }
+    brauchSchlüssel = 0;
+    char byte = 0xB;
+    klient->sendeEncrypted( &byte, 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        delete[]fehler;
+        fehler = new char[ byte + 1 ];
+        fehler[ byte ] = 0;
+        klient->getNachrichtEncrypted( fehler, byte );
+        cs.unlock();
+        return 0;
+    }
+    unsigned char län[ 2 ] = {
+        (unsigned char)textLength( name ),
+        (unsigned char)textLength( geheim )
+    };
+    klient->sendeEncrypted( (char*)län, 2 );
+    klient->sendeEncrypted( name, län[ 0 ] );
+    klient->sendeEncrypted( geheim, län[ 1 ] );
+    byte = 0;
+    klient->getNachrichtEncrypted( &byte, 1 );
+    if( byte == 1 )
+    {
+        cs.unlock();
+        return 1;
+    }
+    else if( byte == 3 )
+    {
+        klient->getNachrichtEncrypted( &byte, 1 );
+        delete[]fehler;
+        fehler = new char[ byte + 1 ];
+        fehler[ byte ] = 0;
+        klient->getNachrichtEncrypted( fehler, byte );
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool RegisterKlient::geheimnisVergessen( const char *name, const char *pass ) // schickt das Account Geheimnis an die Bekannte E-Mail Addresse
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    if( brauchSchlüssel )
+    {
+        char byte = -1;
+        klient->sendeEncrypted( &byte, 1 );
+    }
+    brauchSchlüssel = 0;
+    char byte = 0xC;
+    klient->sendeEncrypted( &byte, 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        delete[]fehler;
+        fehler = new char[ byte + 1 ];
+        fehler[ byte ] = 0;
+        klient->getNachrichtEncrypted( fehler, byte );
+        cs.unlock();
+        return 0;
+    }
+    unsigned char län[ 2 ] = {
+        (unsigned char)textLength( name ),
+        (unsigned char)textLength( pass )
+    };
+    klient->sendeEncrypted( (char*)län, 2 );
+    klient->sendeEncrypted( name, län[ 0 ] );
+    klient->sendeEncrypted( pass, län[ 1 ] );
+    byte = 0;
+    klient->getNachrichtEncrypted( &byte, 1 );
+    if( byte == 1 )
+    {
+        cs.unlock();
+        return 1;
+    }
+    else if( byte == 3 )
+    {
+        klient->getNachrichtEncrypted( &byte, 1 );
+        delete[]fehler;
+        fehler = new char[ byte + 1 ];
+        fehler[ byte ] = 0;
+        klient->getNachrichtEncrypted( fehler, byte );
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool RegisterKlient::eMailVergessen( const char *name, const char *pass, const char *geheim, char **eMail ) // gibt die E-Mail Addresse des Accounts zurück
+{
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+        return 0;
+    cs.lock();
+    if( brauchSchlüssel )
+    {
+        char byte = -1;
+        klient->sendeEncrypted( &byte, 1 );
+    }
+    brauchSchlüssel = 0;
+    char byte2 = 0xD;
+    klient->sendeEncrypted( &byte2, 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    if( serverReturn == 3 )
+    {
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        delete[]fehler;
+        fehler = new char[ byte + 1 ];
+        fehler[ byte ] = 0;
+        klient->getNachrichtEncrypted( fehler, byte );
+        cs.unlock();
+        return 0;
+    }
+    unsigned char län[ 3 ] = {
+        (unsigned char)textLength( name ),
+        (unsigned char)textLength( pass ),
+        (unsigned char)textLength( geheim )
+    };
+    klient->sendeEncrypted( (char*)län, 3 );
+    klient->sendeEncrypted( name, län[ 0 ] );
+    klient->sendeEncrypted( pass, län[ 1 ] );
+    klient->sendeEncrypted( geheim, län[ 2 ] );
+    unsigned char byte = 0;
+    klient->getNachrichtEncrypted( (char*)&byte, 1 );
+    if( byte == 1 )
+    {
+        klient->getNachrichtEncrypted( (char*)&byte, 1 );
+        char *mail = new char[ byte + 1 ];
+        mail[ byte ] = 0;
+        klient->getNachrichtEncrypted( mail, byte );
+        *eMail = mail;
+        cs.unlock();
+        return 1;
+    }
+    else if( byte == 3 )
+    {
+        klient->getNachrichtEncrypted( (char*)&byte, 1 );
+        delete[]fehler;
+        fehler = new char[ byte + 1 ];
+        fehler[ byte ] = 0;
+        klient->getNachrichtEncrypted( fehler, byte );
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool RegisterKlient::keepAlive() // Erhält die Verbindung aufrecht
+{
+    if( !verbunden )
+        return 0;
+    char res = 0;
+    if( !cs.tryLock() )
+        return 1;
+    klient->sendeEncrypted( "\xF", 1 );
+    klient->getNachrichtEncrypted( &res, 1 );
+    cs.unlock();
+    if( res != 1 )
+        trenne();
+    return res == 1;
+}
+
+bool RegisterKlient::trenne() // trennt sich von dem Register Server
+{
+    if( verbunden )
+    {
+        cs.lock();
+        if( brauchSchlüssel )
+        {
+            char byte = -1;
+            klient->sendeEncrypted( &byte, 1 );
+        }
+        brauchSchlüssel = 0;
+        klient->sendeEncrypted( "\3", 1 );
+        char serverReturn = 0;
+        klient->getNachrichtEncrypted( &serverReturn, 1 );
+        klient->trenne();
+        verbunden = 0;
+        cs.unlock();
+    }
+    return 1;
+}
+
+// constant
+bool RegisterKlient::istVerbunden() const // prüft, ob mit Register Server verbunden
+{
+    return verbunden;
+}
+
+bool RegisterKlient::vorgangBrauchBestätigung() const // prüft, ob eine Bestätigung notwendig ist
+{
+    return brauchSchlüssel;
+}
+
+char *RegisterKlient::getLetzterFehler() const // gibt den Letzten Fehlertext zuück
+{
+    return fehler;
+}
+
+// Reference Counting
+RegisterKlient *RegisterKlient::getThis()
+{
+    ref++;
+    return this;
+}
+
+RegisterKlient *RegisterKlient::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 1150 - 0
KSGClient/Netzwerk/Klients/ShopK.cpp

@@ -0,0 +1,1150 @@
+#include "../KSGKlient.h"
+#include "../KSGServer.h"
+#include <Datei.h>
+#include "../Keys.h"
+
+// Inhalt der ShopKlient Klasse aus KSGKtient.h
+// Konstruktor
+ShopKlient::ShopKlient()
+{
+    verbunden = 0;
+    klient = 0;
+    fehler = new Text( "" );
+    klientId = getKlientId();
+    ref = 1;
+}
+
+// Destruktor
+ShopKlient::~ShopKlient()
+{
+    cs.lock();
+    if( klient )
+    {
+        char serverReturn = 0;
+        if( verbunden )
+        {
+            klient->sendeEncrypted( "\4", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            if( serverReturn == 3 )
+            {
+                char län = 0;
+                klient->getNachrichtEncrypted( &län, 1 );
+                char *nachricht = new char[ län + 1 ];
+                nachricht[ län ] = 0;
+                klient->getNachrichtEncrypted( nachricht, län );
+                delete[]nachricht;
+            }
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+        }
+        else
+        {
+            int keyLen = 0;
+            char *key = 0;
+            Keys::getServerKey( &key, keyLen, Keys::SHOP, Keys::SENDEN );
+            klient->setSendeKey( key, keyLen );
+            delete[] key;
+            Keys::getServerKey( &key, keyLen, Keys::SHOP, Keys::EMPFANGEN );
+            klient->setEmpfangKey( key, keyLen );
+            delete[] key;
+            klient->verbinde( klient->getServerPort(), klient->getServerIp() );
+            klient->sendeEncrypted( "\1", 1 );
+            klient->sendeEncrypted( (char*)&klientId, 4 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            if( serverReturn == 3 )
+            {
+                char län = 0;
+                klient->getNachrichtEncrypted( &län, 1 );
+                char *nachricht = new char[ län + 1 ];
+                nachricht[ län ] = 0;
+                klient->getNachrichtEncrypted( nachricht, län );
+                delete[]nachricht;
+            }
+            else
+            {
+                char *sl = 0;
+                char slLän = getSchlüssel( &sl );
+                klient->setSendeKey( sl, slLän );
+                klient->setEmpfangKey( sl, slLän );
+                delete[] sl;
+                klient->sendeEncrypted( "\4", 1 );
+                klient->getNachrichtEncrypted( &serverReturn, 1 );
+                if( serverReturn == 3 )
+                {
+                    char län = 0;
+                    klient->getNachrichtEncrypted( &län, 1 );
+                    char *nachricht = new char[ län + 1 ];
+                    nachricht[ län ] = 0;
+                    klient->getNachrichtEncrypted( nachricht, län );
+                    delete[]nachricht;
+                }
+            }
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+        }
+        klient = klient->release();
+    }
+    fehler = fehler->release();
+    cs.unlock();
+}
+
+// privat
+bool ShopKlient::verbinde( int port, char *ip ) // verbindet sich mit vorgegebenem Server
+{
+    int keyLen = 0;
+    char *key = 0;
+    Keys::getServerKey( &key, keyLen, Keys::SHOP, Keys::SENDEN );
+    klient->setSendeKey( key, keyLen );
+    delete[] key;
+    Keys::getServerKey( &key, keyLen, Keys::SHOP, Keys::EMPFANGEN );
+    klient->setEmpfangKey( key, keyLen );
+    delete[] key;
+    if( klient->verbinde( port, ip ) )
+    {
+        if( klient->sendeEncrypted( "\1", 1 ) )
+        {
+            klient->sendeEncrypted( (char*)&klientId, 4 );
+            char serverReturn = 0;
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            if( serverReturn == 3 )
+            {
+                char byte = 0;
+                klient->getNachrichtEncrypted( &byte, 1 );
+                char *f = new char[ byte + 1 ];
+                f[ byte ] = 0;
+                klient->getNachrichtEncrypted( f, byte );
+                fehler->setText( f );
+                delete[]f;
+                return 0;
+            }
+            char *sl = 0;
+            char slLän = getSchlüssel( &sl );
+            klient->setSendeKey( sl, slLän );
+            klient->setEmpfangKey( sl, slLän );
+            delete[] sl;
+            return 1;
+        }
+        else
+        {
+            fehler->setText( "Der dir zugewiesene Shop Server hat die Verbindung abgebrochen. Bitte versuche es Später erneut." );
+            klient = klient->release();
+        }
+    }
+    else
+    {
+        fehler->setText( "Der dir zugewiesene Shop Server antwortet nicht. Bitte versuche es Später erneut." );
+        klient = klient->release();
+    }
+    return 0;
+}
+
+// nicht constant
+bool ShopKlient::verbinde() // verbindet ich mit dem Shop Server
+{
+    cs.lock();
+    if( verbunden )
+    {
+        cs.unlock();
+        return 1;
+    }
+    if( !klient )
+    {
+        char *msIp = getMainServerIp();
+        unsigned short msPort = getMainServerPort();
+        klient = new Klient();
+        int keyLen = 0;
+        char *key = 0;
+        Keys::getServerKey( &key, keyLen, Keys::MAIN, Keys::SENDEN );
+        klient->setSendeKey( key, keyLen );
+        delete[] key;
+        Keys::getServerKey( &key, keyLen, Keys::MAIN, Keys::EMPFANGEN );
+        klient->setEmpfangKey( key, keyLen );
+        delete[] key;
+        if( !klient->verbinde( msPort, msIp ) )
+        {
+            fehler->setText( "Fehler beim verbinden mit dem Main Server. Bitte versuche es Später erneut." );
+            klient = klient->release();
+            delete[]msIp;
+            cs.unlock();
+            return 0;
+        }
+        delete[]msIp;
+        klient->sende( "\0", 1 ); // Verschlüsselung aktivieren
+        klient->sendeEncrypted( "\1", 1 );
+        klient->sendeEncrypted( (char*)&klientId, 4 );
+        char serverReturn = 0;
+        klient->getNachrichtEncrypted( &serverReturn, 1 );
+        if( serverReturn == 3 )
+        {
+            char län = 0;
+            klient->getNachrichtEncrypted( &län, 1 );
+            char *nachricht = new char[ län + 1 ];
+            nachricht[ län ] = 0;
+            klient->getNachrichtEncrypted( nachricht, län );
+            fehler->setText( nachricht );
+            delete[]nachricht;
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+            klient = klient->release();
+            cs.unlock();
+            return 0;
+        }
+        char *sl = 0;
+        char slLän = getSchlüssel( &sl );
+        klient->setSendeKey( sl, slLän );
+        klient->setEmpfangKey( sl, slLän );
+        delete[] sl;
+        klient->sendeEncrypted( "\6\7", 2 );
+        char byte = 0;
+        klient->getNachrichtEncrypted( &byte, 1 );
+        if( byte == 2 )
+        {
+            unsigned char lsIp[ 4 ];
+            klient->getNachrichtEncrypted( (char *)lsIp, 4 );
+            unsigned short lsPort = 0;
+            klient->getNachrichtEncrypted( (char*)&lsPort, 2 );
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+            Text *lsIpT = new Text( "" );
+            lsIpT->append( (int)lsIp[ 0 ] );
+            lsIpT->append( "." );
+            lsIpT->append( (int)lsIp[ 1 ] );
+            lsIpT->append( "." );
+            lsIpT->append( (int)lsIp[ 2 ] );
+            lsIpT->append( "." );
+            lsIpT->append( (int)lsIp[ 3 ] );
+            int keyLen = 0;
+            char *key = 0;
+            Keys::getServerKey( &key, keyLen, Keys::SHOP, Keys::SENDEN );
+            klient->setSendeKey( key, keyLen );
+            delete[] key;
+            Keys::getServerKey( &key, keyLen, Keys::SHOP, Keys::EMPFANGEN );
+            klient->setEmpfangKey( key, keyLen );
+            delete[] key;
+            klient->verbinde( lsPort, lsIpT->getText() );
+            lsIpT = lsIpT->release();
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+        }
+        if( byte == 3 )
+        {
+            klient->getNachrichtEncrypted( &byte, 1 );
+            char *f = new char[ byte + 1 ];
+            f[ byte ] = 0;
+            klient->getNachrichtEncrypted( f, byte );
+            fehler->setText( f );
+            delete[]f;
+            klient->sendeEncrypted( "\3", 1 );
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            klient->trenne();
+            klient = klient->release();
+            cs.unlock();
+            return 0;
+        }
+    }
+    int keyLen = 0;
+    char *key = 0;
+    Keys::getServerKey( &key, keyLen, Keys::SHOP, Keys::SENDEN );
+    klient->setSendeKey( key, keyLen );
+    delete[] key;
+    Keys::getServerKey( &key, keyLen, Keys::SHOP, Keys::EMPFANGEN );
+    klient->setEmpfangKey( key, keyLen );
+    delete[] key;
+    if( klient->verbinde( klient->getServerPort(), klient->getServerIp() ) )
+    {
+        if( klient->sendeEncrypted( "\1", 1 ) )
+        {
+            klient->sendeEncrypted( (char*)&klientId, 4 );
+            char serverReturn = 0;
+            klient->getNachrichtEncrypted( &serverReturn, 1 );
+            if( serverReturn == 3 )
+            {
+                char byte = 0;
+                klient->getNachrichtEncrypted( &byte, 1 );
+                char *f = new char[ byte + 1 ];
+                f[ byte ] = 0;
+                klient->getNachrichtEncrypted( f, byte );
+                fehler->setText( f );
+                delete[]f;
+                klient->sendeEncrypted( "\3", 1 );
+                klient->getNachrichtEncrypted( &serverReturn, 1 );
+                klient->trenne();
+                cs.unlock();
+                return 0;
+            }
+            char *sl = 0;
+            char slLän = getSchlüssel( &sl );
+            klient->setSendeKey( sl, slLän );
+            klient->setEmpfangKey( sl, slLän );
+            delete[] sl;
+            verbunden = 1;
+            cs.unlock();
+            return 1;
+        }
+        else
+        {
+            fehler->setText( "Der dir zugewiesene Shop Server hat die Verbindung abgebrochen. Bitte versuche es Später erneut." );
+            klient = klient->release();
+        }
+    }
+    else
+    {
+        fehler->setText( "Der dir zugewiesene Shop Server antwortet nicht. Bitte versuche es Später erneut." );
+        klient = klient->release();
+    }
+    cs.unlock();
+    return 0;
+}
+
+Array< int > *ShopKlient::suchSpiele( const char *suche ) // sucht nach Spielen
+{
+    char län = (char)textLength( suche );
+    char ret = 0;
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\5", 1 );
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( &län, 1 );
+        if( län )
+            klient->sendeEncrypted( suche, län );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            int anz = 0;
+            klient->getNachrichtEncrypted( (char*)&anz, 4 );
+            Array< int > *ret = new Array< int >();
+            for( int i = 0; i < anz; i++ )
+            {
+                int w = 0;
+                klient->getNachrichtEncrypted( (char*)&w, 4 );
+                ret->add( w );
+            }
+            cs.unlock();
+            return ret;
+        }
+    }
+    if( ret == 3 )
+    {
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *err = new char[ län + 1 ];
+        err[ län ] = 0;
+        if( län )
+            klient->getNachrichtEncrypted( err, län );
+        fehler->setText( err );
+        delete[] err;
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool ShopKlient::ladeSpielTitel( int id ) // läd Titelbild des Spieles herunter
+{
+    char ret = 0;
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\6", 1 );
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&id, 4 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            Text *pf = new Text( "data/tmp/shop/kaufen/spiele/" );
+            pf->append( id );
+            pf->append( "/titelbg.ltdb" );
+            Datei *dat = new Datei();
+            dat->setDatei( pf );
+            dat->erstellen();
+            dat->open( Datei::Style::schreiben );
+            __int64 gr = 0;
+            klient->getNachrichtEncrypted( (char*)&gr, 8 );
+            char bytes[ 2048 ];
+            while( gr > 0 )
+            {
+                int län = gr > 2048 ? 2048 : (int)gr;
+                klient->getNachricht( bytes, län );
+                dat->schreibe( bytes, län );
+                gr -= län;
+            }
+            dat->close();
+            dat->release();
+        }
+        if( ret == 2 )
+        { // Verweis auf anderen ShopServer
+            int port = 0;
+            char län = 0;
+            klient->getNachrichtEncrypted( (char*)&port, 4 );
+            klient->getNachrichtEncrypted( &län, 1 );
+            char *ip = new char[ län + 1 ];
+            klient->getNachrichtEncrypted( ip, län );
+            ip[ län ] = 0;
+            klient->trenne();
+            if( !verbinde( port, ip ) )
+            {
+                delete[] ip;
+                trenne();
+                cs.unlock();
+                return 0;
+            }
+            delete[] ip;
+            cs.unlock();
+            return ladeSpielTitel( id );
+        }
+    }
+    if( ret == 3 )
+    {
+        klient->getNachrichtEncrypted( &ret, 1 );
+        char *err = new char[ ret + 1 ];
+        err[ ret ] = 0;
+        if( ret )
+            klient->getNachrichtEncrypted( err, ret );
+        fehler->setText( err );
+        delete[] err;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+bool ShopKlient::ladeSpielSeite( int id ) // läd Seite des Spieles herunter
+{
+    char ret = 0;
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\7", 1 );
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&id, 4 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            Text *pf = new Text( "data/tmp/shop/kaufen/spiele/" );
+            pf->append( id );
+            pf->append( "/" );
+            int anz = 0;
+            klient->getNachrichtEncrypted( (char*)&anz, 4 );
+            for( int i = 0; i < anz; i++ )
+            {
+                char län = 0;
+                klient->getNachrichtEncrypted( &län, 1 );
+                char *name = new char[ län + 1 ];
+                name[ län ] = 0;
+                klient->getNachrichtEncrypted( name, län );
+                Text *pfad = new Text( pf->getText() );
+                pfad->append( name );
+                delete[] name;
+                Datei *d = new Datei();
+                d->setDatei( pfad );
+                d->erstellen();
+                d->open( Datei::Style::schreiben );
+                __int64 gr = 0;
+                klient->getNachrichtEncrypted( (char*)&gr, 8 );
+                char bytes[ 2048 ];
+                while( gr > 0 )
+                {
+                    int län = gr > 2048 ? 2048 : (int)gr;
+                    klient->getNachricht( bytes, län );
+                    d->schreibe( bytes, län );
+                    gr -= län;
+                }
+                d->close();
+                d->release();
+            }
+            pf->release();
+        }
+        if( ret == 2 )
+        { // Verweis auf anderen ShopServer
+            int port = 0;
+            char län = 0;
+            klient->getNachrichtEncrypted( (char*)&port, 4 );
+            klient->getNachrichtEncrypted( &län, 1 );
+            char *ip = new char[ län + 1 ];
+            klient->getNachrichtEncrypted( ip, län );
+            ip[ län ] = 0;
+            klient->trenne();
+            if( !verbinde( port, ip ) )
+            {
+                delete[] ip;
+                trenne();
+                cs.unlock();
+                return 0;
+            }
+            delete[] ip;
+            cs.unlock();
+            return ladeSpielSeite( id );
+        }
+    }
+    if( ret == 3 )
+    {
+        klient->getNachrichtEncrypted( &ret, 1 );
+        char *err = new char[ ret + 1 ];
+        err[ ret ] = 0;
+        if( ret )
+            klient->getNachrichtEncrypted( err, ret );
+        fehler->setText( err );
+        delete[] err;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+int ShopKlient::getSpielBesitzStatus( int id ) // 0 = nicht im Besitz, 1 = Testversion, 2 = gekauft
+{
+    char ret = 0;
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x8", 1 );
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&id, 4 );
+        int ret = 0;
+        klient->getNachrichtEncrypted( (char*)&ret, 4 );
+        cs.unlock();
+        return ret;
+    }
+    if( ret == 3 )
+    {
+        klient->getNachrichtEncrypted( &ret, 1 );
+        char *err = new char[ ret + 1 ];
+        err[ ret ] = 0;
+        if( ret )
+            klient->getNachrichtEncrypted( err, ret );
+        fehler->setText( err );
+        delete[] err;
+    }
+    cs.unlock();
+    return 0;
+}
+
+int ShopKlient::getSpielTestversion( int id ) // gibt die Anzahl der verbleibenden Spiele zurück
+{
+    char ret = 0;
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x9", 1 );
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&id, 4 );
+        int ret = 0;
+        klient->getNachrichtEncrypted( (char*)&ret, 4 );
+        cs.unlock();
+        return ret;
+    }
+    if( ret == 3 )
+    {
+        klient->getNachrichtEncrypted( &ret, 1 );
+        char *err = new char[ ret + 1 ];
+        err[ ret ] = 0;
+        if( ret )
+            klient->getNachrichtEncrypted( err, ret );
+        fehler->setText( err );
+        delete[] err;
+    }
+    cs.unlock();
+    return 0;
+}
+
+int ShopKlient::istSpielErwerbbar( int id ) // prüft, ob das Spiel erworben werden kann
+{
+    char ret = 0;
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\xA", 1 );
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&id, 4 );
+        int ret = 0;
+        klient->getNachrichtEncrypted( (char*)&ret, 4 );
+        cs.unlock();
+        return ret;
+    }
+    if( ret == 3 )
+    {
+        klient->getNachrichtEncrypted( &ret, 1 );
+        char *err = new char[ ret + 1 ];
+        err[ ret ] = 0;
+        if( ret )
+            klient->getNachrichtEncrypted( err, ret );
+        fehler->setText( err );
+        delete[] err;
+    }
+    cs.unlock();
+    return 0;
+}
+
+int ShopKlient::getSpielPreis( int id, bool testVersion ) // gibt den Preis eines Spieles zurück
+{
+    char ret = 0;
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\xB", 1 );
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&id, 4 );
+        klient->sendeEncrypted( (char*)&testVersion, 1 );
+        int ret = 0;
+        klient->getNachrichtEncrypted( (char*)&ret, 4 );
+        cs.unlock();
+        return ret;
+    }
+    if( ret == 3 )
+    {
+        klient->getNachrichtEncrypted( &ret, 1 );
+        char *err = new char[ ret + 1 ];
+        err[ ret ] = 0;
+        if( ret )
+            klient->getNachrichtEncrypted( err, ret );
+        fehler->setText( err );
+        delete[] err;
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool ShopKlient::spielErwerben( int spielId, bool testVersion ) // Spiel kaufen
+{
+    char ret = 0;
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\xC", 1 );
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&spielId, 4 );
+        klient->sendeEncrypted( (char*)&testVersion, 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            cs.unlock();
+            return 1;
+        }
+    }
+    if( ret == 3 )
+    {
+        klient->getNachrichtEncrypted( &ret, 1 );
+        char *err = new char[ ret + 1 ];
+        err[ ret ] = 0;
+        if( ret )
+            klient->getNachrichtEncrypted( err, ret );
+        fehler->setText( err );
+        delete[] err;
+    }
+    cs.unlock();
+    return 0;
+}
+
+Array< int > *ShopKlient::suchKarten( const char *suche, int spielId ) // sucht nach Karten
+{
+    char län = (char)textLength( suche );
+    char ret = 0;
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\xD", 1 );
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&spielId, 4 );
+        klient->sendeEncrypted( &län, 1 );
+        if( län )
+            klient->sendeEncrypted( suche, län );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            int anz = 0;
+            klient->getNachrichtEncrypted( (char*)&anz, 4 );
+            Array< int > *ret = new Array< int >();
+            for( int i = 0; i < anz; i++ )
+            {
+                int w = 0;
+                klient->getNachrichtEncrypted( (char*)&w, 4 );
+                ret->add( w );
+            }
+            cs.unlock();
+            return ret;
+        }
+    }
+    if( ret == 3 )
+    {
+        klient->getNachrichtEncrypted( &län, 1 );
+        char *err = new char[ län + 1 ];
+        err[ län ] = 0;
+        if( län )
+            klient->getNachrichtEncrypted( err, län );
+        fehler->setText( err );
+        delete[] err;
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool ShopKlient::ladeKarteTitel( int id ) // läd Titelbild der Karte herunter
+{
+    char ret = 0;
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\xE", 1 );
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&id, 4 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            Text *pf = new Text( "data/tmp/shop/kaufen/karten/" );
+            pf->append( id );
+            pf->append( "/titelbg.ltdb" );
+            Datei *dat = new Datei();
+            dat->setDatei( pf );
+            dat->erstellen();
+            dat->open( Datei::Style::schreiben );
+            __int64 gr = 0;
+            klient->getNachrichtEncrypted( (char*)&gr, 8 );
+            char bytes[ 2048 ];
+            while( gr > 0 )
+            {
+                int län = gr > 2048 ? 2048 : (int)gr;
+                klient->getNachricht( bytes, län );
+                dat->schreibe( bytes, län );
+                gr -= län;
+            }
+            dat->close();
+            dat->release();
+        }
+        if( ret == 2 )
+        { // Verweis auf anderen ShopServer
+            int port = 0;
+            char län = 0;
+            klient->getNachrichtEncrypted( (char*)&port, 4 );
+            klient->getNachrichtEncrypted( &län, 1 );
+            char *ip = new char[ län + 1 ];
+            klient->getNachrichtEncrypted( ip, län );
+            ip[ län ] = 0;
+            klient->trenne();
+            if( !verbinde( port, ip ) )
+            {
+                delete[] ip;
+                trenne();
+                cs.unlock();
+                return 0;
+            }
+            delete[] ip;
+            cs.unlock();
+            return ladeKarteTitel( id );
+        }
+    }
+    if( ret == 3 )
+    {
+        klient->getNachrichtEncrypted( &ret, 1 );
+        char *err = new char[ ret + 1 ];
+        err[ ret ] = 0;
+        if( ret )
+            klient->getNachrichtEncrypted( err, ret );
+        fehler->setText( err );
+        delete[] err;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+bool ShopKlient::ladeKarteSeite( int id ) // läd Seite der Karte herunter
+{
+    char ret = 0;
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\xF", 1 );
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&id, 4 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            Text *pf = new Text( "data/tmp/shop/kaufen/karten/" );
+            pf->append( id );
+            pf->append( "/" );
+            int anz = 0;
+            klient->getNachrichtEncrypted( (char*)&anz, 4 );
+            for( int i = 0; i < anz; i++ )
+            {
+                char län = 0;
+                klient->getNachrichtEncrypted( &län, 1 );
+                char *name = new char[ län + 1 ];
+                name[ län ] = 0;
+                klient->getNachrichtEncrypted( name, län );
+                Text *pfad = new Text( pf->getText() );
+                pfad->append( name );
+                delete[] name;
+                Datei *d = new Datei();
+                d->setDatei( pfad );
+                d->erstellen();
+                d->open( Datei::Style::schreiben );
+                __int64 gr = 0;
+                klient->getNachrichtEncrypted( (char*)&gr, 8 );
+                char bytes[ 2048 ];
+                while( gr > 0 )
+                {
+                    int län = gr > 2048 ? 2048 : (int)gr;
+                    klient->getNachricht( bytes, län );
+                    d->schreibe( bytes, län );
+                    gr -= län;
+                }
+                d->close();
+                d->release();
+            }
+            pf->release();
+        }
+        if( ret == 2 )
+        { // Verweis auf anderen ShopServer
+            int port = 0;
+            char län = 0;
+            klient->getNachrichtEncrypted( (char*)&port, 4 );
+            klient->getNachrichtEncrypted( &län, 1 );
+            char *ip = new char[ län + 1 ];
+            klient->getNachrichtEncrypted( ip, län );
+            ip[ län ] = 0;
+            klient->trenne();
+            if( !verbinde( port, ip ) )
+            {
+                delete[] ip;
+                trenne();
+                cs.unlock();
+                return 0;
+            }
+            delete[] ip;
+            cs.unlock();
+            return ladeKarteSeite( id );
+        }
+    }
+    if( ret == 3 )
+    {
+        klient->getNachrichtEncrypted( &ret, 1 );
+        char *err = new char[ ret + 1 ];
+        err[ ret ] = 0;
+        if( ret )
+            klient->getNachrichtEncrypted( err, ret );
+        fehler->setText( err );
+        delete[] err;
+        cs.unlock();
+        return 0;
+    }
+    cs.unlock();
+    return 1;
+}
+
+int ShopKlient::getKarteBesitzStatus( int id ) // 0 = nicht im Besitz, 1 = Testversion, 2 = gekauft
+{
+    char ret = 0;
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x10", 1 );
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&id, 4 );
+        int ret = 0;
+        klient->getNachrichtEncrypted( (char*)&ret, 4 );
+        cs.unlock();
+        return ret;
+    }
+    if( ret == 3 )
+    {
+        klient->getNachrichtEncrypted( &ret, 1 );
+        char *err = new char[ ret + 1 ];
+        err[ ret ] = 0;
+        if( ret )
+            klient->getNachrichtEncrypted( err, ret );
+        fehler->setText( err );
+        delete[] err;
+    }
+    cs.unlock();
+    return 0;
+}
+
+int ShopKlient::getKarteTestversion( int id ) // gibt die Anzahl der verbleibenden Spiele zurück
+{
+    char ret = 0;
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x11", 1 );
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&id, 4 );
+        int ret = 0;
+        klient->getNachrichtEncrypted( (char*)&ret, 4 );
+        cs.unlock();
+        return ret;
+    }
+    if( ret == 3 )
+    {
+        klient->getNachrichtEncrypted( &ret, 1 );
+        char *err = new char[ ret + 1 ];
+        err[ ret ] = 0;
+        if( ret )
+            klient->getNachrichtEncrypted( err, ret );
+        fehler->setText( err );
+        delete[] err;
+    }
+    cs.unlock();
+    return 0;
+}
+
+int ShopKlient::istKarteErwerbbar( int id ) // prüft, ob die Karte erworben werden kann
+{
+    char ret = 0;
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x12", 1 );
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&id, 4 );
+        int ret = 0;
+        klient->getNachrichtEncrypted( (char*)&ret, 4 );
+        cs.unlock();
+        return ret;
+    }
+    if( ret == 3 )
+    {
+        klient->getNachrichtEncrypted( &ret, 1 );
+        char *err = new char[ ret + 1 ];
+        err[ ret ] = 0;
+        if( ret )
+            klient->getNachrichtEncrypted( err, ret );
+        fehler->setText( err );
+        delete[] err;
+    }
+    cs.unlock();
+    return 0;
+}
+
+int ShopKlient::getKartePreis( int id, bool testVersion ) // gibt den Preis einer Karte zurück
+{
+    char ret = 0;
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x13", 1 );
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&id, 4 );
+        klient->sendeEncrypted( (char*)&testVersion, 1 );
+        int ret = 0;
+        klient->getNachrichtEncrypted( (char*)&ret, 4 );
+        cs.unlock();
+        return ret;
+    }
+    if( ret == 3 )
+    {
+        klient->getNachrichtEncrypted( &ret, 1 );
+        char *err = new char[ ret + 1 ];
+        err[ ret ] = 0;
+        if( ret )
+            klient->getNachrichtEncrypted( err, ret );
+        fehler->setText( err );
+        delete[] err;
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool ShopKlient::karteErwerben( int karteId, bool testVersion ) // Karte kaufen
+{
+    char ret = 0;
+    cs.lock();
+    if( !verbunden )
+        verbinde();
+    if( !verbunden )
+    {
+        cs.unlock();
+        return 0;
+    }
+    klient->sendeEncrypted( "\x14", 1 );
+    klient->getNachrichtEncrypted( &ret, 1 );
+    if( ret == 1 )
+    {
+        klient->sendeEncrypted( (char*)&karteId, 4 );
+        klient->sendeEncrypted( (char*)&testVersion, 1 );
+        klient->getNachrichtEncrypted( &ret, 1 );
+        if( ret == 1 )
+        {
+            cs.unlock();
+            return 1;
+        }
+    }
+    if( ret == 3 )
+    {
+        klient->getNachrichtEncrypted( &ret, 1 );
+        char *err = new char[ ret + 1 ];
+        err[ ret ] = 0;
+        if( ret )
+            klient->getNachrichtEncrypted( err, ret );
+        fehler->setText( err );
+        delete[] err;
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool ShopKlient::keepAlive() // Erhält die Verbindung aufrecht
+{
+    if( !verbunden )
+        return 0;
+    char res = 0;
+    if( !cs.tryLock() )
+        return 1;
+    klient->sendeEncrypted( "\x15", 1 );
+    klient->getNachrichtEncrypted( &res, 1 );
+    cs.unlock();
+    if( res != 1 )
+        trenne();
+    return res == 1;
+}
+
+bool ShopKlient::trenne() // trennt sich von dem Shop Server
+{
+    if( !verbunden )
+        return 1;
+    cs.lock();
+    klient->sendeEncrypted( "\3", 1 );
+    char serverReturn = 0;
+    klient->getNachrichtEncrypted( &serverReturn, 1 );
+    klient->trenne();
+    verbunden = 0;
+    cs.unlock();
+    return 1;
+}
+
+// constant
+bool ShopKlient::istVerbunden() const // prüft, ob mit Shop Server verbunden
+{
+    return verbunden;
+}
+
+char *ShopKlient::getLetzterFehler() const // gibt den Letzten Fehlertext zuück
+{
+    return fehler->getText();
+}
+
+// Reference Counting
+ShopKlient *ShopKlient::getThis()
+{
+    ref++;
+    return this;
+}
+
+ShopKlient *ShopKlient::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 622 - 0
KSGClient/Netzwerk/Klients/SpielK.cpp

@@ -0,0 +1,622 @@
+#include "../KSGKlient.h"
+#include "../KSGServer.h"
+#include "../../Global/Variablen.h"
+#include "../Keys.h"
+
+// Inhalt der SpielKlient Klasse aus KSGKlient.h
+// Konstruktor
+SpielKlient::SpielKlient()
+    : Thread()
+{
+    verbunden = 0;
+    senden = 0;
+    empfangen = 0;
+    fehler = new Text( "" );
+    klientId = getKlientId();
+    ref = 1;
+}
+
+// Destruktor
+SpielKlient::~SpielKlient()
+{
+    cs.lock();
+    if( senden )
+    {
+        char serverReturn = 0;
+        if( verbunden )
+        {
+            senden->sendeEncrypted( "\3", 1 );
+            senden->getNachrichtEncrypted( &serverReturn, 1 );
+            senden->trenne();
+        }
+        senden = senden->release();
+        verbunden = 0;
+        if( empfangen )
+        {
+            warteAufThread( 5000 );
+            ende();
+            empfangen->trenne();
+            empfangen = empfangen->release();
+        }
+    }
+    fehler = fehler->release();
+    cs.unlock();
+}
+
+// nicht constant
+bool SpielKlient::verbinde( unsigned short port, char *ip ) // verbindet ich mit dem Spiel Server
+{
+    cs.lock();
+    if( verbunden )
+    {
+        cs.unlock();
+        return 1;
+    }
+    if( !senden )
+        senden = new Klient();
+    int keyLen = 0;
+    char *key = 0;
+    Keys::getServerKey( &key, keyLen, Keys::SPIEL, Keys::SENDEN );
+    senden->setSendeKey( key, keyLen );
+    delete[] key;
+    Keys::getServerKey( &key, keyLen, Keys::SPIEL, Keys::EMPFANGEN );
+    senden->setEmpfangKey( key, keyLen );
+    delete[] key;
+    if( senden->verbinde( port, ip ) )
+    {
+        if( senden->sendeEncrypted( "\1", 1 ) )
+        {
+            char serverReturn = 0;
+            senden->sendeEncrypted( (char*)&klientId, 4 );
+            char ret = 0;
+            senden->getNachrichtEncrypted( &ret, 1 );
+            if( ret != 1 )
+            {
+                if( ret == 3 )
+                {
+                    char byte = 0;
+                    senden->getNachrichtEncrypted( &byte, 1 );
+                    char *f = new char[ byte + 1 ];
+                    f[ byte ] = 0;
+                    senden->getNachrichtEncrypted( f, byte );
+                    fehler->setText( f );
+                    delete[]f;
+                }
+                senden->sendeEncrypted( "\3", 1 );
+                senden->getNachrichtEncrypted( &serverReturn, 1 );
+                senden->trenne();
+                WMessageBox( 0, new Text( "Fehler" ), new Text( "Server akzeptiert den Klient nicht" ), MB_ICONERROR );
+                cs.unlock();
+                return 0;
+            }
+            char *sl = 0;
+            char slLän = getSchlüssel( &sl );
+            senden->setSendeKey( sl, slLän );
+            senden->setEmpfangKey( sl, slLän );
+            delete[] sl;
+            if( !empfangen )
+                empfangen = new Klient();
+            int keyLen = 0;
+            char *key = 0;
+            Keys::getServerKey( &key, keyLen, Keys::SPIEL, Keys::SENDEN );
+            empfangen->setSendeKey( key, keyLen );
+            delete[] key;
+            Keys::getServerKey( &key, keyLen, Keys::SPIEL, Keys::EMPFANGEN );
+            empfangen->setEmpfangKey( key, keyLen );
+            delete[] key;
+            if( empfangen->verbinde( senden->getServerPort(), senden->getServerIp() ) )
+            {
+                start();
+                verbunden = 1;
+                cs.unlock();
+                return 1;
+            }
+            else
+            {
+                fehler->setText( "Der dir zugewiesene Spiel Server kann dir keine Nachrichten senden." );
+                cs.unlock();
+                return 1;
+            }
+        }
+        else
+        {
+            fehler->setText( "Der dir zugewiesene Spiel Server hat die Verbindung abgebrochen. Bitte versuche es Später erneut." );
+            senden = senden->release();
+        }
+    }
+    else
+    {
+        fehler->setText( "Der dir zugewiesene Spiel Server antwortet nicht. Bitte versuche es Später erneut." );
+        senden = senden->release();
+    }
+    cs.unlock();
+    return 0;
+}
+
+bool SpielKlient::spielErstelltAnnehmen() // klient ist bereit dem erstellten Spiel beizutreten
+{
+    if( !senden )
+        return 0;
+    char ret = 0;
+    cs.lock();
+    senden->sendeEncrypted( "\4", 1 );
+    senden->getNachrichtEncrypted( &ret, 1 );
+    cs.unlock();
+    return ret == 1;
+}
+
+bool SpielKlient::spielErstelltAblehnen() // klient ist nicht bereit dem erstellten Spiel beizutreten
+{
+    if( !senden )
+        return 0;
+    char ret = 0;
+    cs.lock();
+    senden->sendeEncrypted( "\5", 1 );
+    senden->getNachrichtEncrypted( &ret, 1 );
+    cs.unlock();
+    return ret == 1;
+}
+
+bool SpielKlient::spielErstelltTeamWechseln( int team ) // wechselt das Team
+{
+    if( !senden )
+        return 0;
+    char ret = 0;
+    cs.lock();
+    senden->sendeEncrypted( "\6", 1 );
+    senden->getNachrichtEncrypted( &ret, 1 );
+    if( !ret )
+    {
+        cs.unlock();
+        return 0;
+    }
+    senden->sendeEncrypted( (char*)&team, 4 );
+    senden->getNachrichtEncrypted( &ret, 1 );
+    cs.unlock();
+    return ret == 1;
+}
+
+bool SpielKlient::spielErstelltTeamFertig() // bestetigt die Team Auswahl
+{
+    if( !senden )
+        return 0;
+    char ret = 0;
+    cs.lock();
+    senden->sendeEncrypted( "\xE", 1 );
+    senden->getNachrichtEncrypted( &ret, 1 );
+    cs.unlock();
+    return ret == 1;
+}
+
+bool SpielKlient::spielErstelltChatNachricht( char *nachricht ) // sendet eine Chat Nachricht an die mitglieder des erstellten Spiels
+{
+    char län = textLength( nachricht );
+    if( !län )
+        return 1;
+    if( !senden )
+        return 0;
+    char ret = 0;
+    cs.lock();
+    senden->sendeEncrypted( "\7", 1 );
+    senden->getNachrichtEncrypted( &ret, 1 );
+    if( !ret )
+    {
+        cs.unlock();
+        return 0;
+    }
+    senden->sendeEncrypted( &län, 1 );
+    senden->sendeEncrypted( nachricht, län );
+    senden->getNachrichtEncrypted( &ret, 1 );
+    cs.unlock();
+    return ret == 1;
+}
+
+bool SpielKlient::bereitZumLaden() // Klient ist bereit zum Laden
+{
+    if( !senden )
+        return 0;
+    char ret = 0;
+    cs.lock();
+    senden->sendeEncrypted( "\x9", 1 );
+    senden->getNachrichtEncrypted( &ret, 1 );
+    cs.unlock();
+    return ret == 1;
+}
+
+bool SpielKlient::setLadenProzent( int prozent ) // Setzt den Fortschritt des Klients
+{
+    if( !senden )
+        return 0;
+    char ret = 0;
+    cs.lock();
+    senden->sendeEncrypted( "\xC", 1 );
+    senden->getNachrichtEncrypted( &ret, 1 );
+    if( ret )
+    {
+        senden->sendeEncrypted( (char*)&prozent, 4 );
+        senden->getNachrichtEncrypted( &ret, 1 );
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+bool SpielKlient::bereitZumSpiel() // Klient ist bereit zum Spiel
+{
+    if( !senden )
+        return 0;
+    char ret = 0;
+    cs.lock();
+    senden->sendeEncrypted( "\xA", 1 );
+    senden->getNachrichtEncrypted( &ret, 1 );
+    cs.unlock();
+    return ret == 1;
+}
+
+bool SpielKlient::spielNachricht( short län, char *bytes ) // Nachricht während des Spiels
+{
+    if( !senden )
+        return 0;
+    cs.lock();
+    senden->sendeEncrypted( "\xB", 1 );
+    senden->sende( (char*)&län, 2 );
+    senden->sende( bytes, län );
+    cs.unlock();
+    return 1;
+}
+
+bool SpielKlient::statistikNachricht( short län, char *bytes ) // Nachricht während der Statistik
+{
+    if( !senden )
+        return 0;
+    char ret = 0;
+    cs.lock();
+    senden->sendeEncrypted( "\xD", 1 );
+    senden->getNachrichtEncrypted( &ret, 1 );
+    if( ret )
+    {
+        senden->sendeEncrypted( (char*)&län, 2 );
+        senden->sendeEncrypted( bytes, län );
+        senden->getNachrichtEncrypted( &ret, 1 );
+    }
+    cs.unlock();
+    return ret == 1;
+}
+
+bool SpielKlient::keepAlive() // Erhält die Verbindung aufrecht
+{
+    if( !verbunden )
+        return 0;
+    char res = 0;
+    if( !cs.tryLock() )
+        return 1;
+    senden->sendeEncrypted( "\xF", 1 );
+    senden->getNachrichtEncrypted( &res, 1 );
+    cs.unlock();
+    if( res != 1 )
+        trenne();
+    return res == 1;
+}
+
+bool SpielKlient::trenne() // trennt sich von dem Chat Server
+{
+    if( !verbunden )
+        return 1;
+    verbunden = 0;
+    cs.lock();
+    senden->sendeEncrypted( "\3", 1 );
+    char serverReturn = 0;
+    senden->getNachrichtEncrypted( &serverReturn, 1 );
+    senden->trenne();
+    warteAufThread( 2000 );
+    empfangen->trenne();
+    cs.unlock();
+    run = 0;
+    ende();
+    return 1;
+}
+
+void SpielKlient::thread() // empfangen von Nachrichten
+{
+    if( !verbunden || !empfangen || !senden )
+        return;
+    empfangen->sendeEncrypted( "\1", 1 );
+    empfangen->sendeEncrypted( (char*)&klientId, 4 );
+    char res = 0;
+    empfangen->getNachrichtEncrypted( &res, 1 );
+    if( res == 3 )
+    {
+        char län = 0;
+        empfangen->getNachrichtEncrypted( &län, 1 );
+        char *nachricht = new char[ län + 1 ];
+        nachricht[ län ] = 0;
+        empfangen->getNachrichtEncrypted( nachricht, län );
+        fehler->setText( nachricht );
+        delete[]nachricht;
+    }
+    if( res == 1 )
+    {
+        char *sl = 0;
+        char slLän = getSchlüssel( &sl );
+        empfangen->setSendeKey( sl, slLän );
+        empfangen->setEmpfangKey( sl, slLän );
+        delete[] sl;
+    }
+    else if( res != 0 )
+    {
+        WMessageBox( 0, new Text( "Fehler" ), new Text( "Server hat keine Verwendung für den Client." ), MB_ICONERROR );
+        return;
+    }
+    char befehl = 0;
+    while( verbunden )
+    {
+        if( !empfangen->getNachrichtEncrypted( &befehl, 1 ) )
+        {
+            run = 0;
+            return;
+        }
+        switch( befehl )
+        {
+        case 0: // verbindung getrennt
+            trenne();
+            run = 0;
+            return;
+        case 1: // verbleibende Zeit
+            if( 1 )
+            {
+                char sekunden = 0;
+                empfangen->getNachrichtEncrypted( &sekunden, 1 );
+                if( nachLogin && nachLogin->zSpielenFenster() )
+                    nachLogin->zSpielenFenster()->spielGefundenZeitVerbleibend( sekunden );
+            }
+            break;
+        case 2: // SpielErstellt abbruch
+            if( 1 )
+            {
+                char län = 0;
+                empfangen->getNachrichtEncrypted( &län, 1 );
+                char *grund = new char[ län + 1 ];
+                grund[ län ] = 0;
+                empfangen->getNachrichtEncrypted( grund, län );
+                if( nachLogin && nachLogin->zNachrichtenListe() )
+                    nachLogin->zNachrichtenListe()->addNachricht( new Text( "Spiel Abgebrochen" ), new Text( grund ), new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+                if( nachLogin && nachLogin->zSpielenFenster() )
+                    nachLogin->zSpielenFenster()->spielGefundenAbbruch();
+                delete[] grund;
+            }
+            break;
+        case 3: // Fehler
+            if( 1 )
+            {
+                char länge = 0;
+                empfangen->getNachrichtEncrypted( &länge, 1 );
+                char *txt = new char[ länge + 1 ];
+                txt[ länge ] = 0;
+                empfangen->getNachrichtEncrypted( txt, länge );
+                hauptScreen->lock();
+                if( nachLogin && nachLogin->zNachrichtenListe() )
+                    nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( txt ), new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+                hauptScreen->unlock();
+                delete[]txt;
+            }
+            break;
+        case 4: // zurück in Warteschlange
+            if( 1 )
+            {
+                char stunden = 0;
+                char minuten = 0;
+                char sekunden = 0;
+                empfangen->getNachrichtEncrypted( &stunden, 1 );
+                empfangen->getNachrichtEncrypted( &minuten, 1 );
+                empfangen->getNachrichtEncrypted( &sekunden, 1 );
+                if( nachLogin && nachLogin->zSpielenFenster() )
+                    nachLogin->zSpielenFenster()->zurückInWarteschlange( stunden, minuten, sekunden );
+            }
+            break;
+        case 5: // Erstellung fortsetzen
+            if( nachLogin && nachLogin->zSpielenFenster() )
+                nachLogin->zSpielenFenster()->teamAuswahlBetreten();
+            break;
+        case 6: // SpielErstellt Initialisierung
+            if( 1 )
+            {
+                SpielerTeamStruktur *sts = new SpielerTeamStruktur();
+                empfangen->getNachrichtEncrypted( (char*)&sts->spielerAnzahl, 4 );
+                empfangen->getNachrichtEncrypted( (char*)&sts->teamAnzahl, 4 );
+                for( int i = 0; i < sts->spielerAnzahl; i++ )
+                {
+                    int farbe = 0;
+                    empfangen->getNachrichtEncrypted( (char*)&farbe, 4 );
+                    sts->spielerFarbe->set( farbe, i );
+                }
+                for( int i = 0; i < sts->teamAnzahl; i++ )
+                {
+                    int farbe = 0;
+                    empfangen->getNachrichtEncrypted( (char*)&farbe, 4 );
+                    sts->teamFarbe->set( farbe, i );
+                }
+                for( int i = 0; i < sts->teamAnzahl; i++ )
+                {
+                    char län = 0;
+                    empfangen->getNachrichtEncrypted( &län, 1 );
+                    char *name = new char[ län + 1 ];
+                    name[ län ] = 0;
+                    if( län )
+                        empfangen->getNachrichtEncrypted( name, län );
+                    Text *tmp = new Text( name );
+                    delete[] name;
+                    sts->teamName->set( tmp, i );
+                }
+                for( int i = 0; i < sts->teamAnzahl; i++ )
+                {
+                    int größe = 0;
+                    empfangen->getNachrichtEncrypted( (char*)&größe, 4 );
+                    sts->teamGröße->set( größe, i );
+                }
+                if( nachLogin && nachLogin->zSpielenFenster() )
+                    nachLogin->zSpielenFenster()->teamAuswahlInit( sts );
+                else
+                    sts->release();
+            }
+            break;
+        case 7: // SpielErstellt Spieler hinzugefügt
+            if( 1 )
+            {
+                int accountId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&accountId, 4 );
+                if( nachLogin && nachLogin->zSpielenFenster() )
+                    nachLogin->zSpielenFenster()->teamAuswahlAddSpieler( accountId );
+            }
+            break;
+        case 8: // SpielErstellt Spieler entfernt
+            if( 1 )
+            {
+                int accountId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&accountId, 4 );
+                if( nachLogin && nachLogin->zSpielenFenster() )
+                    nachLogin->zSpielenFenster()->teamAuswahlRemoveSpieler( accountId );
+            }
+            break;
+        case 9: // SpielErstellt Spieler wechselt Team
+            if( 1 )
+            {
+                int accountId = 0;
+                int spielerNummer = 0;
+                empfangen->getNachrichtEncrypted( (char*)&accountId, 4 );
+                empfangen->getNachrichtEncrypted( (char*)&spielerNummer, 4 );
+                if( nachLogin && nachLogin->zSpielenFenster() )
+                    nachLogin->zSpielenFenster()->teamAuswahlSpielerWehseltTeam( accountId, spielerNummer );
+            }
+            break;
+        case 0xA: // SpielErstellt Chat Nachricht
+            if( 1 )
+            {
+                char län = 0;
+                empfangen->getNachrichtEncrypted( &län, 1 );
+                char *nachricht = new char[ län + 1 ];
+                nachricht[ län ] = 0;
+                if( län )
+                    empfangen->getNachrichtEncrypted( nachricht, län );
+                if( nachLogin && nachLogin->zSpielenFenster() )
+                    nachLogin->zSpielenFenster()->teamAuswahlChatNachricht( nachricht );
+                delete[] nachricht;
+            }
+            break;
+        case 0xB: // Spiel gefunden
+            if( 1 )
+            {
+                int karteId = 0;
+                empfangen->getNachrichtEncrypted( (char*)&karteId, 4 );
+                if( nachLogin && nachLogin->zSpielenFenster() )
+                    nachLogin->zSpielenFenster()->spielGefunden( karteId );
+            }
+            break;
+        case 0xC: // Spiel Laden beginnen
+            aktion = 5;
+            break;
+        case 0xD: // Spiel Laden Spieler hinzufügen
+            if( 1 )
+            {
+                int accId = 0;
+                int spielerNummer = 0;
+                empfangen->getNachrichtEncrypted( (char*)&accId, 4 );
+                empfangen->getNachrichtEncrypted( (char*)&spielerNummer, 4 );
+                if( nachLogin->zImSpiel() && nachLogin->zImSpiel()->istSichtbar() )
+                    nachLogin->zImSpiel()->lBAddSpieler( accId, spielerNummer );
+            }
+            break;
+        case 0xE: // Spiel Laden Spieler Prozent
+            if( 1 )
+            {
+                int accId = 0;
+                int prozent = 0;
+                empfangen->getNachrichtEncrypted( (char*)&accId, 4 );
+                empfangen->getNachrichtEncrypted( (char*)&prozent, 4 );
+                if( nachLogin->zImSpiel() && nachLogin->zImSpiel()->istSichtbar() )
+                    nachLogin->zImSpiel()->lBSetSpielerProzent( accId, prozent );
+            }
+            break;
+        case 0xF: // Spiel Laden Spieler Ping
+            if( 1 )
+            {
+                int accId = 0;
+                int ping = 0;
+                empfangen->getNachrichtEncrypted( (char*)&accId, 4 );
+                empfangen->getNachrichtEncrypted( (char*)&ping, 4 );
+                if( nachLogin->zImSpiel() && nachLogin->zImSpiel()->istSichtbar() )
+                    nachLogin->zImSpiel()->lBSetSpielerPing( accId, ping );
+            }
+            break;
+        case 0x10: // ping
+            empfangen->sendeEncrypted( "\1", 1 );
+            break;
+        case 0x11: // Spiel Laden Fertig
+            if( nachLogin->zImSpiel() && nachLogin->zImSpiel()->istSichtbar() )
+                nachLogin->zImSpiel()->endLaden();
+            break;
+        case 0x12: // Spiel Nachricht
+            if( 1 )
+            {
+                short län = 0;
+                empfangen->getNachricht( (char*)&län, 2 );
+                char *n = new char[ län ];
+                empfangen->getNachricht( n, län );
+                if( nachLogin->zImSpiel() && nachLogin->zImSpiel()->istSichtbar() )
+                    nachLogin->zImSpiel()->spielNachricht( län, n );
+                delete[] n;
+            }
+            break;
+        case 0x13: // Statistik Nachricht
+            if( 1 )
+            {
+                short län = 0;
+                empfangen->getNachrichtEncrypted( (char*)&län, 2 );
+                char *n = new char[ län ];
+                empfangen->getNachrichtEncrypted( n, län );
+                if( nachLogin && nachLogin->zSpielenFenster() )
+                    nachLogin->zSpielenFenster()->statistikNachricht( län, n );
+                delete[] n;
+            }
+            break;
+        case 0x14: // ping
+            empfangen->sendeEncrypted( "\1", 1 );
+            break;
+        default: // Unbekannte Servernachricht
+            if( nachLogin && nachLogin->zNachrichtenListe() )
+            {
+                hauptScreen->lock();
+                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
+                                                              new Text( "Unbekannte Nachricht vom Server. Eventuel ist der Client nicht mehr Aktuell." ),
+                                                              new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
+                hauptScreen->unlock();
+            }
+            break;
+        }
+    }
+    run = 0;
+}
+
+// constant
+bool SpielKlient::istVerbunden() const // prüft, ob mit Chat Server verbunden
+{
+    return verbunden;
+}
+
+char *SpielKlient::getLetzterFehler() const // gibt den Letzten Fehlertext zuück
+{
+    return fehler->getText();
+}
+
+// Reference Counting
+SpielKlientV *SpielKlient::getThis()
+{
+    ref++;
+    return this;
+}
+
+SpielKlientV *SpielKlient::release()
+{
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
+}

+ 103 - 0
KSGClient/Netzwerk/Patcher.cpp

@@ -0,0 +1,103 @@
+#include "Patcher.h"
+#include <Text.h>
+#include "../Global/Variablen.h"
+
+typedef UpdaterV *( *GetUpdater )( );
+
+// Inhalt der Patcher Klasse aus Patcher.h
+// Konstruktor
+Patcher::Patcher()
+{
+	updater = 0;
+	updateDll = 0;
+	läuft = 0;
+	ref = 1;
+}
+
+// Destruktor
+Patcher::~Patcher()
+{
+	if( updater )
+		updater->release();
+	if( updateDll )
+		FreeLibrary( updateDll );
+}
+
+// nicht constant
+bool Patcher::update( int dateiGruppe, bool *abbruch, FBalken *fortschritt, TextFeld *status, Text *zError )
+{
+	if( läuft )
+	{
+		zError->setText( "Es kann nur ein Update zur Zeit herruntergeladen werden." );
+		fortschritt->release();
+		status->release();
+		return 0;
+	}
+	läuft = 1;
+	if( !updater )
+	{
+		if( !updateDll )
+		    updateDll = dllDateien->ladeDLL("update.dll","data/bin/update.dll" );
+		if( !updateDll )
+		{
+			updater = 0;
+			zError->setText( "Die DLL Datei 'data/bin/update.dll' wurde nicht gefunden." );
+		}
+		else
+		{
+			GetUpdater getUpdater = (GetUpdater)GetProcAddress( updateDll, "getUpdater" );
+			if( !getUpdater )
+			{
+				updater = 0;
+				zError->setText( "Der Einstiegspunkt 'getUpdater' konnte in der DLL Datei 'data/bin/update.dll' nicht gefunden." );
+			}
+			else
+				updater = getUpdater();
+		}
+	}
+	if( !updater )
+	{
+		fortschritt->release();
+		status->release();
+		läuft = 0;
+		return 0;
+	}
+	UpdateParams p;
+	p.abbruch = abbruch;
+	p.dateiGruppe = dateiGruppe;
+	p.zFortschritt = fortschritt;
+	p.zStatus = status;
+	int ret = updater->update( &p );
+	fortschritt->release();
+	status->release();
+	if( ret == 1 )
+		zError->setText( updater->getError() );
+	läuft = 0;
+	return ret != 1;
+}
+
+// constant
+bool Patcher::läuftPatch() const
+{
+	return läuft;
+}
+
+int Patcher::getDownload() const
+{
+	return updater ? updater->getDownload() : 0;
+}
+
+// Reference Counting
+Patcher *Patcher::getThis()
+{
+	ref++;
+	return this;
+}
+
+Patcher *Patcher::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 35 - 0
KSGClient/Netzwerk/Patcher.h

@@ -0,0 +1,35 @@
+#ifndef Patcher_H
+#define Patcher_H
+
+#include <Update.h>
+#include <Thread.h>
+#include <Textfeld.h>
+#include <Knopf.h>
+#include <Thread.h>
+
+using namespace Framework;
+
+class Patcher
+{
+private:
+	HMODULE updateDll;
+	UpdaterV *updater;
+	bool läuft;
+	int ref;
+
+public:
+	// Konstruktor
+	Patcher();
+	// Destruktor
+	~Patcher();
+	// nicht constant
+	bool update( int dateiGruppe, bool *abbruch, FBalken *fortschritt, TextFeld *status, Text *zError );
+	// constant
+	bool läuftPatch() const;
+	int getDownload() const;
+	// Reference Counting
+	Patcher *getThis();
+	Patcher *release();
+};
+
+#endif

+ 182 - 0
KSGClient/Start/Start.cpp

@@ -0,0 +1,182 @@
+#include "..\Global\Variablen.h"
+#include <main.h>
+#include <MausEreignis.h>
+#include <TastaturEreignis.h>
+#include <Maus.h>
+#include <Punkt.h>
+#include "..\Global\Render.h"
+#include <Bild.h>
+#include <DateiSystem.h>
+#include <Globals.h>
+#include <Text.h>
+#include "..\Global\Initialisierung.h"
+#include <Datei.h>
+#include <iostream>
+#include <vector>
+#include <sstream>
+
+void fensterVS( void *p, void *f )
+{
+	PostQuitMessage( 0 );
+}
+
+bool fensterME( void *p, void *f, MausEreignis me )
+{
+	return 1;
+}
+
+bool fensterTE( void *p, void *f, TastaturEreignis te )
+{
+#ifdef _DEBUG
+	std::cout.flush();
+#endif
+	return 1;
+}
+
+#ifdef _DEBUG
+template<typename TChar, typename TTraits>
+class OutputDebugStringBuf : public std::basic_stringbuf<TChar, TTraits>
+{
+public:
+	explicit OutputDebugStringBuf() : _buffer( 256 )
+	{
+		setg( nullptr, nullptr, nullptr );
+		setp( _buffer.data(), _buffer.data(), _buffer.data() + _buffer.size() );
+	}
+
+	~OutputDebugStringBuf()
+	{
+	}
+
+	static_assert( std::is_same<TChar, char>::value || std::is_same<TChar, wchar_t>::value, "OutputDebugStringBuf only supports char and wchar_t types" );
+
+	int sync() try
+	{
+		MessageOutputer<TChar, TTraits>()( pbase(), pptr() );
+		setp( _buffer.data(), _buffer.data(), _buffer.data() + _buffer.size() );
+		return 0;
+	}
+	catch( ... )
+	{
+		return -1;
+	}
+
+	int overflow( int c = TTraits::eof() )
+	{
+		auto syncRet = sync();
+		if( c != TTraits::eof() )
+		{
+			_buffer[ 0 ] = c;
+			setp( _buffer.data(), _buffer.data() + 1, _buffer.data() + _buffer.size() );
+		}
+		return syncRet == -1 ? TTraits::eof() : 0;
+	}
+
+
+private:
+	std::vector<TChar>		_buffer;
+
+	template<typename TChar, typename TTraits>
+	struct MessageOutputer;
+
+	template<>
+	struct MessageOutputer<char, std::char_traits<char>>
+	{
+		template<typename TIterator>
+		void operator()( TIterator begin, TIterator end ) const
+		{
+			std::string s( begin, end );
+			OutputDebugStringA( s.c_str() );
+		}
+	};
+
+	template<>
+	struct MessageOutputer<wchar_t, std::char_traits<wchar_t>>
+	{
+		template<typename TIterator>
+		void operator()( TIterator begin, TIterator end ) const
+		{
+			std::wstring s( begin, end );
+			OutputDebugStringW( s.c_str() );
+		}
+	};
+
+};
+#endif
+
+int KSGStart Framework::Start( Startparam p )
+{
+#ifdef _DEBUG
+	static OutputDebugStringBuf<char, std::char_traits<char>> charDebugOutput;
+	std::cout.rdbuf( &charDebugOutput );
+#endif
+	Network::Start( 50 );
+
+	Punkt bildschirmGröße = BildschirmGröße();
+	bildschirmGröße.x++;
+	bildschirmGröße.y++;
+	
+	WNDCLASS wc = F_Normal( p.hinst );
+	wc.lpszClassName = "Game Client";
+
+    /*WFenster *fenster = new WFenster();
+    fenster->erstellen( WS_OVERLAPPEDWINDOW, wc );
+    fenster->setSize( 700, 770 );
+    fenster->setPosition( Bildschirmmitte( fenster->getThis() ) );
+    fenster->setAnzeigeModus( 1 );
+    fenster->setVSchließAktion( fensterVS );
+    fenster->setMausAktion( fensterME );
+    fenster->setTastaturAktion( fensterTE );
+
+    Bildschirm *bildschirm = new Bildschirm3D( fenster->getThis() );
+    fenster->setBildschirm( bildschirm->getThis() );*/
+	WFenster *fenster = new WFenster();
+	fenster->erstellen( WS_POPUP, wc );
+	fenster->setPosition( Punkt( 0, 0 ) );
+	fenster->setSize( bildschirmGröße );
+	fenster->setMausAktion( fensterME );
+	fenster->setTastaturAktion( fensterTE );
+	fenster->setVSchließAktion( fensterVS );
+    
+	Bildschirm *bildschirm = new Bildschirm3D( fenster->getThis() );
+	fenster->setBildschirm( bildschirm->getThis() );
+    fenster->setAnzeigeModus( 1 );
+	fenster->setFokus();
+	bildschirm->update();
+	bildschirm->render();
+
+	LTDSDatei *schriftDatei = new LTDSDatei();
+	schriftDatei->setPfad( new Text( "data/schriften/normal.ltds" ) );
+	schriftDatei->leseDaten();
+	Schrift *schrift = schriftDatei->ladeSchrift();
+	schriftDatei = schriftDatei->release();
+
+	Render *render = new Render( schrift->getThis() );
+	render->setBildschirm( bildschirm->getThis() );
+
+	initVariables( schrift, bildschirm );
+
+	render->start();
+
+	StartNachrichtenSchleife();
+
+	render->beenden();
+	render = render->release();
+
+	bildschirm->removeMember( vorLogin->zFenster() );
+	bildschirm->removeMember( nachLogin );
+
+	releaseVariables();
+	schrift = schrift->release();
+
+	bildschirm = bildschirm->release();
+	fenster->setBildschirm( 0 );
+	fenster->zerstören();
+	fenster = fenster->release();
+
+	Network::Exit();
+	
+	DateiPfadErstellen( new Text( "data/tmp/keinabsturz" ) );
+
+	return 0;
+}

+ 38 - 0
KSGClient/Strukturen/Strukturen.cpp

@@ -0,0 +1,38 @@
+#include "Strukturen.h"
+
+// Inhalt der SpielerTeamStruktur Struktur aus trukturen.h
+	// Konstruktor
+SpielerTeamStruktur::SpielerTeamStruktur()
+{
+	spielerAnzahl = 0;
+	teamAnzahl = 0;
+	spielerFarbe = new Array< int >();
+	teamFarbe = new Array< int >();
+	teamName = new RCArray< Text >();
+	teamGröße = new Array< int >();
+	ref = 1;
+}
+
+// Destruktor
+SpielerTeamStruktur::~SpielerTeamStruktur()
+{
+	spielerFarbe->release();
+	teamFarbe->release();
+	teamName->release();
+	teamGröße->release();
+}
+
+// Reference Counting
+SpielerTeamStruktur *SpielerTeamStruktur::getThis()
+{
+	ref++;
+	return this;
+}
+
+SpielerTeamStruktur *SpielerTeamStruktur::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 29 - 0
KSGClient/Strukturen/Strukturen.h

@@ -0,0 +1,29 @@
+#ifndef Strukturen_H
+#define Strukturen_H
+
+#include <Klient.h>
+#include <Array.h>
+#include <Text.h>
+
+using namespace Framework;
+
+struct SpielerTeamStruktur
+{
+	// Konstruktor
+	SpielerTeamStruktur();
+	// Destruktor
+	~SpielerTeamStruktur();
+	// variablen
+	int spielerAnzahl;
+	int teamAnzahl;
+	Array< int > *spielerFarbe;
+	Array< int > *teamFarbe;
+	RCArray< Text > *teamName;
+	Array< int > *teamGröße;
+	int ref;
+	// Reference Counting
+	SpielerTeamStruktur *getThis();
+	SpielerTeamStruktur *release();
+};
+
+#endif

+ 414 - 0
KSGClient/VorLogin/Account verwalten/Bestätigung.cpp

@@ -0,0 +1,414 @@
+#include "..\..\Global\Variablen.h"
+#include "Bestätigung.h"
+#include "..\..\Global\Initialisierung.h"
+#include <Punkt.h>
+#include <Text.h>
+
+// Inhalt der Bestätigung Klasse aus Bestätigung.h
+// Konstruktor
+Bestätigung::Bestätigung( Schrift *zSchrift, Fenster *zVorLoginFenster )
+{
+	Punkt bildschirmGröße = BildschirmGröße();
+	bestätigung = initKnopf( 10, 450, 130, 30, zSchrift, Knopf::Style::Sichtbar, "Bestätigung" );
+	bestätigung->setMausEreignisParameter( this );
+	bestätigung->setMausEreignis( bestätigungBestätigungME );
+	initToolTip( bestätigung, "Account aktivieren oder remove.", zSchrift->getThis(), hauptScreen );
+	zVorLoginFenster->addMember( bestätigung );
+	fenster = initFenster( bildschirmGröße.x / 2 - 125, bildschirmGröße.y / 2 - 70, 250, 140, zSchrift, Fenster::Style::Erlaubt | Fenster::Style::Rahmen | Fenster::Style::Titel | Fenster::Style::TitelBuffered, "Vorgang Bestätigen" );
+	name = initTextFeld( 24, 20, 200, 20, zSchrift, TextFeld::Style::TextFeld, "Name" );
+	name->setTastaturEreignisParameter( this );
+	name->setTastaturEreignis( bestätigungNameTE );
+	initToolTip( name, "Account Name.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( name );
+	passwort = initTextFeld( 24, 50, 200, 20, zSchrift, TextFeld::Style::TextFeld, "Passwort" );
+	passwort->setTastaturEreignisParameter( this );
+	passwort->setTastaturEreignis( bestätigungPasswortTE );
+	initToolTip( passwort, "Account Passwort.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( passwort );
+	weiter = initKnopf( 74, 80, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Weiter" );
+	weiter->setMausEreignisParameter( this );
+	weiter->setMausEreignis( bestätigungWeiterME );
+	fenster->addMember( weiter );
+	nachricht = initTextFeld( 0, 5, 250, 150, zSchrift, TextFeld::Style::Mehrzeilig | TextFeld::Style::HCenter, "" );
+	fenster->addMember( nachricht );
+	schlüssel = initTextFeld( 24, 55, 200, 20, zSchrift, TextFeld::Style::TextFeld & ~TextFeld::Style::Sichtbar, "Schlüssel" );
+	schlüssel->setTastaturEreignisParameter( this );
+	schlüssel->setTastaturEreignis( bestätigungSchlüsselTE );
+	initToolTip( schlüssel, "Zugeschickter Schlüssel.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( schlüssel );
+	später = initKnopf( 20, 85, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Später" );
+	später->setMausEreignisParameter( this );
+	später->setMausEreignis( bestätigungSpäterME );
+	initToolTip( später, "Vorgang später fortsetzen.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( später );
+	abbruch = initKnopf( 20, 115, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Abbrechen" );
+	abbruch->setMausEreignisParameter( this );
+	abbruch->setMausEreignis( bestätigungAbbruchME );
+	initToolTip( abbruch, "Vorgang abbrechen.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( abbruch );
+	neuSenden = initKnopf( 129, 115, 100, 20, zSchrift, Knopf::Style::Sichtbar, "neu senden" );
+	neuSenden->setMausEreignisParameter( this );
+	neuSenden->setMausEreignis( bestätigungNeuSendenME );
+	initToolTip( neuSenden, "E-Mail erneut senden.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( neuSenden );
+	zVorLoginFenster->addMember( fenster );
+	ref = 1;
+}
+
+// Destruktor
+Bestätigung::~Bestätigung()
+{
+	if( bestätigung )
+		bestätigung = bestätigung->release();
+	if( fenster )
+		fenster = fenster->release();
+	if( name )
+		name = name->release();
+	if( passwort )
+		passwort = passwort->release();
+	if( weiter )
+		weiter = weiter->release();
+	if( nachricht )
+		nachricht = nachricht->release();
+	if( schlüssel )
+		schlüssel = schlüssel->release();
+	if( später )
+		später = später->release();
+	if( abbruch )
+		abbruch = abbruch->release();
+	if( neuSenden )
+		neuSenden = neuSenden->release();
+}
+
+// Privat
+void Bestätigung::zeigeNachricht( const char *txt )
+{
+	Punkt bildschirmmitte = Bildschirmmitte();
+	name->removeStyle( TextFeld::Style::Sichtbar );
+	passwort->removeStyle( TextFeld::Style::Sichtbar );
+	schlüssel->removeStyle( TextFeld::Style::Sichtbar );
+	später->removeStyle( Knopf::Style::Sichtbar );
+	abbruch->removeStyle( Knopf::Style::Sichtbar );
+	neuSenden->removeStyle( Knopf::Style::Sichtbar );
+	fenster->setSize( 250, 150 );
+	fenster->setPosition( bildschirmmitte.x - 125, bildschirmmitte.y - 75 );
+	weiter->setPosition( 139, 100 );
+	weiter->setText( "Ok" );
+	nachricht->setText( txt );
+	if( nachricht->zText()->getLength() > 30 )
+	{
+		int pos = -1;
+		bool set = 0;
+		int lastp = 0;
+		for( int i = 20; i < nachricht->zText()->getLength(); )
+		{
+			char *tmp = &nachricht->zText()->getText()[ i ];
+			while( *tmp != ' ' && i < nachricht->zText()->getLength() )
+			{
+				tmp++;
+				i++;
+				if( i - 30 >= lastp )
+				{
+					if( set )
+					{
+						lastp = pos;
+						set = 0;
+						nachricht->zText()->getText()[ pos ] = '\n';
+					}
+					else
+						lastp += 5;
+				}
+			}
+			if( i < nachricht->zText()->getLength() )
+			{
+				pos = i;
+				set = 1;
+				tmp++;
+				i++;
+			}
+		}
+	}
+	nachricht->addStyle( TextFeld::Style::Sichtbar );
+}
+
+// Knopfdruck
+void Bestätigung::druckFremdKnopf() // Ein anderer Bereich des Programms wurde ausgewählt
+{
+	fenster->removeStyle( Fenster::Style::Sichtbar );
+	registerKlient->trenne();
+	bestätigung->setLinienRahmenBreite( 2 );
+	bestätigung->setAlphaFeldFarbe( 0x5500FF00 );
+	bestätigung->setAlphaFeldStrength( -5 );
+}
+
+bool Bestätigung::bestätigungME( void *obj, MausEreignis me ) // MausEreignis im Knopf bestärigung
+{
+	if( me.id == ME_RLinks )
+	{
+		vorLogin->setBestätigung();
+
+		bestätigung->setLinienRahmenBreite( 3 );
+		bestätigung->setAlphaFeldFarbe( 0xFF000000 );
+		bestätigung->setAlphaFeldStrength( 20 );
+
+		Punkt bildschirmGröße = BildschirmGröße();
+		nachricht->removeStyle( TextFeld::Style::Sichtbar );
+		schlüssel->removeStyle( TextFeld::Style::Sichtbar );
+		später->removeStyle( Knopf::Style::Sichtbar );
+		abbruch->removeStyle( Knopf::Style::Sichtbar );
+		neuSenden->removeStyle( Knopf::Style::Sichtbar );
+		fenster->setTitel( "Vorgang Bestätigen" );
+		fenster->setSize( 250, 140 );
+		fenster->setPosition( bildschirmGröße.x / 2 - 125, bildschirmGröße.y / 2 - 70 );
+		fenster->addStyle( Fenster::Style::Sichtbar );
+		weiter->setText( "Weiter" );
+		weiter->setPosition( 74, 80 );
+		name->addStyle( TextFeld::Style::Sichtbar );
+		passwort->addStyle( TextFeld::Style::Sichtbar );
+		name->addStyle( TextFeld::Style::Fokus );
+		name->setAuswahl( name->zText()->getLength(), 0 );
+	}
+	return 1;
+}
+
+bool Bestätigung::nameTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld name
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Release && ( te.taste == T_Enter || te.taste == T_Tab ) )
+	{
+		name->removeStyle( TextFeld::Style::Fokus );
+		passwort->addStyle( TextFeld::Style::Fokus );
+		passwort->setAuswahl( passwort->zText()->getLength(), 0 );
+	}
+	if( bestätigung->zText()->getLength() >= 25 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool Bestätigung::passwortTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld passwort
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Press )
+		passwort->setSchowChar( '*' );
+	if( te.id == TE_Release && te.taste == T_Enter )
+	{
+		passwort->removeStyle( TextFeld::Style::Fokus );
+		MausEreignis me;
+		me.id = ME_RLinks;
+		weiterME( 0, me );
+	}
+	if( passwort->zText()->getLength() >= 25 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool Bestätigung::weiterME( void *obj, MausEreignis me ) // MausEreignis im Knopf weiter
+{
+	if( me.id == ME_RLinks )
+	{
+		if( weiter->zText()->istGleich( "Weiter" ) )
+		{
+			if( name->zText()->getLength() <= 0 )
+				zeigeNachricht( "Bitte gebe deinen Accountnamen ein." );
+			if( passwort->zText()->getLength() == 0 )
+				zeigeNachricht( "Bitte gebe dein Accountpasswort ein." );
+			if( weiter->zText()->istGleich( "Ok" ) )
+				return 1;
+			new AktionsThread( 6, name->zText()->getText(), passwort->zText()->getText(), 0, 0, 0 );
+		}
+		else if( weiter->zText()->istGleich( "Fertig" ) )
+		{
+			if( schlüssel->zText()->getLength() <= 0 )
+			{
+				zeigeNachricht( "Bitte gebe den dir zugesendeten Schlüssel ein." );
+				return 1;
+			}
+			new AktionsThread( 7, schlüssel->zText()->getText(), 0, 0, 0, 0 );
+		}
+		else
+		{
+			if( fenster->zTitel()->istGleich( "Vorgang Bestätigen" ) )
+			{
+				MausEreignis me;
+				me.id = ME_RLinks;
+				bestätigungME( 0, me );
+			}
+			else
+			{
+				nachricht->setText( "Dir wurde eine E-Mail mit einem\nSchlüssel gesendet, den du hier\neingeben musst." );
+				schlüssel->addStyle( TextFeld::Style::Sichtbar );
+				fenster->setSize( 250, 170 );
+				Punkt bildschirmGröße = BildschirmGröße();
+				fenster->setPosition( bildschirmGröße.x / 2 - 125, bildschirmGröße.y / 2 - 85 );
+				später->addStyle( Knopf::Style::Sichtbar );
+				weiter->setText( "Fertig" );
+				weiter->setPosition( 129, 85 );
+				abbruch->addStyle( Knopf::Style::Sichtbar );
+				neuSenden->addStyle( Knopf::Style::Sichtbar );
+			}
+		}
+	}
+	return 1;
+}
+
+bool Bestätigung::schlüsselTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld schlüssel
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Release && te.taste == T_Enter )
+	{
+		schlüssel->removeStyle( TextFeld::Style::Fokus );
+		MausEreignis me;
+		me.id = ME_RLinks;
+		weiterME( 0, me );
+	}
+	if( schlüssel->zText()->getLength() >= 20 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool Bestätigung::späterME( void *obj, MausEreignis me ) // MausEreignis im Knopf später
+{
+	if( me.id == ME_RLinks )
+	{
+		registerKlient->später();
+		MausEreignis me;
+		me.id = ME_RLinks;
+		bestätigungME( 0, me );
+	}
+	return 1;
+}
+
+bool Bestätigung::abbruchME( void *obj, MausEreignis me ) // MausEreignis im Knopf abbruch
+{
+	if( me.id == ME_RLinks )
+	{
+		registerKlient->abbrechen();
+		MausEreignis me;
+		me.id = ME_RLinks;
+		bestätigungME( 0, me );
+	}
+	return 1;
+}
+
+bool Bestätigung::neuSendenME( void *obj, MausEreignis me ) // MausEreignis im Knopf neuSenden
+{
+	if( me.id == ME_RLinks )
+		registerKlient->eMailErneutSenden();
+	return 1;
+}
+
+void Bestätigung::setWeiterResult( int ret ) // setzt den Returnwert des Weiter drückens
+{
+	if( !ret )
+	{
+		if( registerKlient->getLetzterFehler() )
+			zeigeNachricht( registerKlient->getLetzterFehler() );
+		else
+			zeigeNachricht( "Es ist ein unbekannter Fehler aufgetreten." );
+		return;
+	}
+	name->removeStyle( TextFeld::Style::Sichtbar );
+	passwort->removeStyle( TextFeld::Style::Sichtbar );
+	if( ret == 1 )
+		fenster->setTitel( "Account aktivieren" );
+	else
+		fenster->setTitel( "Account remove" );
+	fenster->setSize( 250, 170 );
+	Punkt bildschirmGröße = BildschirmGröße();
+	fenster->setPosition( bildschirmGröße.x / 2 - 125, bildschirmGröße.y / 2 - 85 );
+	nachricht->setText( "Dir wurde eine E-Mail mit einem\nSchlüssel gesendet, den du hier\neingeben musst." );
+	nachricht->addStyle( TextFeld::Style::Sichtbar );
+	schlüssel->addStyle( TextFeld::Style::Sichtbar );
+	später->addStyle( Knopf::Style::Sichtbar );
+	weiter->setText( "Fertig" );
+	weiter->setPosition( 129, 85 );
+	abbruch->addStyle( Knopf::Style::Sichtbar );
+	neuSenden->addStyle( Knopf::Style::Sichtbar );
+}
+
+void Bestätigung::setFertigResult( bool ret ) // setzt den Returnwert des Fertig drükens
+{
+	if( ret )
+	{
+		fenster->setTitel( "Vorgang Bestätigen" );
+		zeigeNachricht( "Der Vorgang wurde erfolgreich abgeschlossen." );
+	}
+	else
+		zeigeNachricht( "Du hast nicht den richtigen Schlüssel eingegeben." );
+}
+
+// Reference Counting
+Bestätigung *Bestätigung::getThis()
+{
+	ref++;
+	return this;
+}
+
+Bestätigung *Bestätigung::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// messages
+bool bestätigungBestätigungME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (Bestätigung*)p )->bestätigungME( obj, me );
+}
+
+bool bestätigungNameTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (Bestätigung*)p )->nameTE( obj, te );
+}
+
+bool bestätigungPasswortTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (Bestätigung*)p )->passwortTE( obj, te );
+}
+
+bool bestätigungWeiterME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (Bestätigung*)p )->weiterME( obj, me );
+}
+
+bool bestätigungSchlüsselTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (Bestätigung*)p )->schlüsselTE( obj, te );
+}
+
+bool bestätigungSpäterME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (Bestätigung*)p )->späterME( obj, me );
+}
+
+bool bestätigungAbbruchME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (Bestätigung*)p )->abbruchME( obj, me );
+}
+
+bool bestätigungNeuSendenME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (Bestätigung*)p )->neuSendenME( obj, me );
+}

+ 63 - 0
KSGClient/VorLogin/Account verwalten/Bestätigung.h

@@ -0,0 +1,63 @@
+#ifndef Bestätigung_H
+#define Bestätigung_H
+
+#include <Fenster.h>
+#include <TextFeld.h>
+#include <Knopf.h>
+#include <MausEreignis.h>
+#include <TastaturEreignis.h>
+#include <Schrift.h>
+#include <Bildschirm.h>
+#include "..\..\Aktionen\AktionsThread.h"
+
+using namespace Framework;
+
+class Bestätigung
+{
+private:
+	Knopf *bestätigung;
+	Fenster *fenster;
+	TextFeld *name;
+	TextFeld *passwort;
+	Knopf *weiter;
+	TextFeld *schlüssel;
+	Knopf *später;
+	Knopf *abbruch;
+	Knopf *neuSenden;
+	TextFeld *nachricht;
+	int ref;
+	void zeigeNachricht( const char *txt );
+
+public:
+	// Konstruktor
+	Bestätigung( Schrift *zSchrift, Fenster *zVorLoginFenster );
+	// Destruktor
+	~Bestätigung();
+	// Knopfdruck
+	void druckFremdKnopf(); // Ein anderer Bereich des Programms wurde ausgewählt
+	bool bestätigungME( void *obj, MausEreignis me ); // MausEreignis im Knopf bestärigung
+	bool nameTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld name
+	bool passwortTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld passwort
+	bool weiterME( void *obj, MausEreignis me ); // MausEreignis im Knopf weiter
+	bool schlüsselTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld schlüssel
+	bool späterME( void *obj, MausEreignis me ); // MausEreignis im Knopf später
+	bool abbruchME( void *obj, MausEreignis me ); // MausEreignis im Knopf abbruch
+	bool neuSendenME( void *obj, MausEreignis me ); // MausEreignis im Knopf neuSenden
+	void setWeiterResult( int ret ); // setzt den Returnwert des Weiter drückens
+	void setFertigResult( bool ret ); // setzt den Returnwert des Fertig drükens
+	// Reference Counting
+	Bestätigung *getThis();
+	Bestätigung *release();
+};
+
+// messages
+bool bestätigungBestätigungME( void *p, void *obj, MausEreignis me );
+bool bestätigungNameTE( void *p, void *obj, TastaturEreignis te );
+bool bestätigungPasswortTE( void *p, void *obj, TastaturEreignis te );
+bool bestätigungWeiterME( void *p, void *obj, MausEreignis me );
+bool bestätigungSchlüsselTE( void *p, void *obj, TastaturEreignis te );
+bool bestätigungSpäterME( void *p, void *obj, MausEreignis me );
+bool bestätigungAbbruchME( void *p, void *obj, MausEreignis me );
+bool bestätigungNeuSendenME( void *p, void *obj, MausEreignis me );
+
+#endif

+ 618 - 0
KSGClient/VorLogin/Account verwalten/EMail.cpp

@@ -0,0 +1,618 @@
+#include "..\..\Global\Variablen.h"
+#include "..\..\Global\Initialisierung.h"
+#include "EMail.h"
+#include <Text.h>
+#include <Punkt.h>
+
+// Inhalt der EMailÄndern Klasse aus EMail.h
+// Konstruktor
+EMailÄndern::EMailÄndern( Schrift *zSchrift, Fenster *zVorLoginFenster )
+{
+	Punkt bildschirmmitte = Bildschirmmitte();
+	eMailÄndern = initKnopf( 10, 210, 130, 30, zSchrift, Knopf::Style::Sichtbar, "E-Mail ändern" );
+	eMailÄndern->setMausEreignisParameter( this );
+	eMailÄndern->setMausEreignis( eMailÄndernEMailÄndernME );
+	initToolTip( eMailÄndern, "Account E-Mail Adresse ändern.", zSchrift->getThis(), hauptScreen );
+	zVorLoginFenster->addMember( eMailÄndern );
+	fenster = initFenster( bildschirmmitte.x - 125, bildschirmmitte.y - 100, 250, 200, zSchrift, Fenster::Style::Erlaubt | Fenster::Style::Rahmen | Fenster::Style::Titel | Fenster::Style::TitelBuffered, "E-Mail ändern" );
+	name = initTextFeld( 20, 20, 208, 20, zSchrift, TextFeld::Style::TextFeld, "Name" );
+	name->setTastaturEreignisParameter( this );
+	name->setTastaturEreignis( eMailÄndernNameTE );
+	initToolTip( name, "Account Name.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( name );
+	passwort = initTextFeld( 20, 50, 208, 20, zSchrift, TextFeld::Style::TextFeld, "Passwort" );
+	passwort->setTastaturEreignisParameter( this );
+	passwort->setTastaturEreignis( eMailÄndernPasswortTE );
+	initToolTip( passwort, "Account Passwort.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( passwort );
+	geheimnis = initTextFeld( 20, 80, 208, 20, zSchrift, TextFeld::Style::TextFeld, "Geheimis" );
+	geheimnis->setTastaturEreignisParameter( this );
+	geheimnis->setTastaturEreignis( eMailÄndernGeheimnisTE );
+	initToolTip( geheimnis, "Account Geheimnis.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( geheimnis );
+	nEMail = initTextFeld( 20, 110, 208, 20, zSchrift, TextFeld::Style::TextFeld, "neue E-Mail Adresse" );
+	nEMail->setTastaturEreignisParameter( this );
+	nEMail->setTastaturEreignis( eMailÄndernNEMailTE );
+	initToolTip( nEMail, "Neue E-Mail Adresse.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( nEMail );
+	weiter = initKnopf( 74, 140, 100, 20, zSchrift, Knopf::Style::Sichtbar, "weiter" );
+	weiter->setMausEreignisParameter( this );
+	weiter->setMausEreignis( eMailÄndernWeiterME );
+	nachricht = initTextFeld( 0, 5, 255, 150, zSchrift, TextFeld::Style::HCenter | TextFeld::Style::Mehrzeilig, "" );
+	fenster->addMember( nachricht );
+	fenster->addMember( weiter );
+	zVorLoginFenster->addMember( fenster );
+	ref = 1;
+}
+
+// Destruktor
+EMailÄndern::~EMailÄndern()
+{
+	if( eMailÄndern )
+		eMailÄndern = eMailÄndern->release();
+	if( fenster )
+		fenster = fenster->release();
+	if( name )
+		name = name->release();
+	if( passwort )
+		passwort = passwort->release();
+	if( geheimnis )
+		geheimnis = geheimnis->release();
+	if( nEMail )
+		nEMail = nEMail->release();
+	if( weiter )
+		weiter = weiter->release();
+	if( nachricht )
+		nachricht = nachricht->release();
+}
+
+// Privat
+void EMailÄndern::zeigeNachricht( const char *txt )
+{
+	Punkt bildschirmmitte = Bildschirmmitte();
+	name->removeStyle( TextFeld::Style::Sichtbar );
+	passwort->removeStyle( TextFeld::Style::Sichtbar );
+	geheimnis->removeStyle( TextFeld::Style::Sichtbar );
+	nEMail->removeStyle( TextFeld::Style::Sichtbar );
+	fenster->setSize( 250, 150 );
+	fenster->setPosition( bildschirmmitte.x - 125, bildschirmmitte.y - 75 );
+	weiter->setPosition( 139, 100 );
+	weiter->setText( "Ok" );
+	nachricht->setText( txt );
+	if( nachricht->zText()->getLength() > 30 )
+	{
+		int pos = -1;
+		bool set = 0;
+		int lastp = 0;
+		for( int i = 20; i < nachricht->zText()->getLength(); )
+		{
+			char *tmp = &nachricht->zText()->getText()[ i ];
+			while( *tmp != ' ' && i < nachricht->zText()->getLength() )
+			{
+				tmp++;
+				i++;
+				if( i - 30 >= lastp )
+				{
+					if( set )
+					{
+						lastp = pos;
+						set = 0;
+						nachricht->zText()->getText()[ pos ] = '\n';
+					}
+					else
+						lastp += 5;
+				}
+			}
+			if( i < nachricht->zText()->getLength() )
+			{
+				pos = i;
+				set = 1;
+				tmp++;
+				i++;
+			}
+		}
+	}
+	nachricht->addStyle( TextFeld::Style::Sichtbar );
+}
+
+// Knopfdruck
+void EMailÄndern::druckFremdKnopf() // Ein anderer Knopf wurde gedrückt
+{
+	fenster->removeStyle( Fenster::Style::Sichtbar );
+	registerKlient->trenne();
+	eMailÄndern->setLinienRahmenBreite( 2 );
+	eMailÄndern->setAlphaFeldFarbe( 0x5500FF00 );
+	eMailÄndern->setAlphaFeldStrength( -5 );
+}
+
+bool EMailÄndern::eMailÄndernME( void *obj, MausEreignis me ) // MausEreignis im Knopf eMailÄndern
+{
+	if( me.id == ME_RLinks )
+	{
+		vorLogin->setEMailÄndern();
+
+		eMailÄndern->setLinienRahmenBreite( 3 );
+		eMailÄndern->setAlphaFeldFarbe( 0xFF000000 );
+		eMailÄndern->setAlphaFeldStrength( 20 );
+		Punkt bildschirmmitte = Bildschirmmitte();
+		fenster->setSize( 255, 200 );
+		fenster->setPosition( bildschirmmitte.x - 125, bildschirmmitte.y - 100 );
+		fenster->addStyle( Fenster::Style::Sichtbar );
+		nachricht->removeStyle( TextFeld::Style::Sichtbar );
+		weiter->setText( "weiter" );
+		weiter->setPosition( 75, 140 );
+		name->addStyle( TextFeld::Style::Sichtbar );
+		passwort->addStyle( TextFeld::Style::Sichtbar );
+		geheimnis->addStyle( TextFeld::Style::Sichtbar );
+		nEMail->addStyle( TextFeld::Style::Sichtbar );
+		name->addStyle( TextFeld::Style::Fokus );
+		name->setAuswahl( name->zText()->getLength(), 0 );
+	}
+	return 1;
+}
+
+bool EMailÄndern::nameTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld name
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Release && ( te.taste == T_Enter || te.taste == T_Tab ) )
+	{
+		name->removeStyle( TextFeld::Style::Fokus );
+		passwort->addStyle( TextFeld::Style::Fokus );
+		passwort->setAuswahl( passwort->zText()->getLength(), 0 );
+	}
+	if( name->zText()->getLength() >= 25 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool EMailÄndern::passwortTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld passwort
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Press )
+		passwort->setSchowChar( '*' );
+	if( te.id == TE_Release && ( te.taste == T_Enter || te.taste == T_Tab ) )
+	{
+		passwort->removeStyle( TextFeld::Style::Fokus );
+		geheimnis->addStyle( TextFeld::Style::Fokus );
+		geheimnis->setAuswahl( geheimnis->zText()->getLength(), 0 );
+	}
+	if( passwort->zText()->getLength() >= 25 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool EMailÄndern::geheimnisTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld geheimnis
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Press )
+		geheimnis->setSchowChar( '*' );
+	if( te.id == TE_Release && ( te.taste == T_Enter || te.taste == T_Tab ) )
+	{
+		geheimnis->removeStyle( TextFeld::Style::Fokus );
+		nEMail->addStyle( TextFeld::Style::Fokus );
+		nEMail->setAuswahl( nEMail->zText()->getLength(), 0 );
+	}
+	if( geheimnis->zText()->getLength() >= 50 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool EMailÄndern::nEMailTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld nEMail
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Press )
+		nEMail->setSchowChar( '*' );
+	if( te.id == TE_Release && te.taste == T_Enter )
+	{
+		nEMail->removeStyle( TextFeld::Style::Fokus );
+		MausEreignis me;
+		me.id = ME_RLinks;
+		weiterME( 0, me );
+	}
+	if( nEMail->zText()->getLength() >= 50 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool EMailÄndern::weiterME( void *obj, MausEreignis me ) // MausEreignis im Knopf weiter
+{
+	if( me.id == ME_RLinks )
+	{
+		if( weiter->zText()->istGleich( "weiter" ) )
+		{
+			if( name->zText()->getLength() == 0 )
+				zeigeNachricht( "Bitte gebe deinen Accountnamen ein." );
+			if( passwort->zText()->getLength() == 0 )
+				zeigeNachricht( "Bitte gebe dein Accountpasswort ein." );
+			if( geheimnis->zText()->getLength() == 0 )
+				zeigeNachricht( "Bitte gebe dein Accountgeheimnis ein." );
+			if( nEMail->zText()->getLength() == 0 )
+				zeigeNachricht( "Bitte gebe eine neue E-Mail Addresse ein." );
+			if( weiter->zText()->istGleich( "Ok" ) )
+				return 1;
+			new AktionsThread( 8, name->zText()->getText(), passwort->zText()->getText(), geheimnis->zText()->getText(), nEMail->zText()->getText(), 0 );
+		}
+		else
+		{
+			Punkt bildschirmmitte = Bildschirmmitte();
+			fenster->setSize( 255, 200 );
+			fenster->setPosition( bildschirmmitte.x - 125, bildschirmmitte.y - 100 );
+			fenster->addStyle( Fenster::Style::Sichtbar );
+			nachricht->removeStyle( TextFeld::Style::Sichtbar );
+			weiter->setText( "weiter" );
+			weiter->setPosition( 75, 140 );
+			name->addStyle( TextFeld::Style::Sichtbar );
+			passwort->addStyle( TextFeld::Style::Sichtbar );
+			geheimnis->addStyle( TextFeld::Style::Sichtbar );
+			nEMail->addStyle( TextFeld::Style::Sichtbar );
+			name->addStyle( TextFeld::Style::Fokus );
+			name->setAuswahl( name->zText()->getLength(), 0 );
+		}
+	}
+	return 1;
+}
+
+void EMailÄndern::setReturn( bool ret ) // Setzt den Returnwert
+{
+	if( ret )
+		zeigeNachricht( "E-Mail erfolgreich geändert." );
+	else if( registerKlient->getLetzterFehler() )
+		zeigeNachricht( registerKlient->getLetzterFehler() );
+	else
+		zeigeNachricht( "Es ist ein Unbekannter Fehler aufgetreten." );
+}
+
+// Reference Counting
+EMailÄndern *EMailÄndern::getThis()
+{
+	ref++;
+	return this;
+}
+
+EMailÄndern *EMailÄndern::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der EMailVergessen Klasse aus EMail.h
+// Konstruktor
+EMailVergessen::EMailVergessen( Schrift *zSchrift, Fenster *zVorLoginFenster )
+{
+	Punkt bildschirmmitte = Bildschirmmitte();
+	eMailVergessen = initKnopf( 10, 410, 130, 30, zSchrift, Knopf::Style::Sichtbar, "E-Mail vergessen" );
+	eMailVergessen->setMausEreignisParameter( this );
+	eMailVergessen->setMausEreignis( eMailVergessenEMailVergessenME );
+	initToolTip( eMailVergessen, "Account E-Mail Adresse anzeigen.", zSchrift->getThis(), hauptScreen );
+	zVorLoginFenster->addMember( eMailVergessen );
+	fenster = initFenster( bildschirmmitte.x - 125, bildschirmmitte.y - 85, 250, 170, zSchrift, Fenster::Style::Erlaubt | Fenster::Style::Rahmen | Fenster::Style::Titel | Fenster::Style::TitelBuffered, "E-Mail vergessen" );
+	name = initTextFeld( 20, 20, 208, 20, zSchrift, TextFeld::Style::TextFeld, "Name" );
+	name->setTastaturEreignisParameter( this );
+	name->setTastaturEreignis( eMailVergessenNameTE );
+	initToolTip( name, "Account Name.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( name );
+	passwort = initTextFeld( 20, 50, 208, 20, zSchrift, TextFeld::Style::TextFeld, "Passwort" );
+	passwort->setTastaturEreignisParameter( this );
+	passwort->setTastaturEreignis( eMailVergessenPasswortTE );
+	initToolTip( passwort, "Account Passwort.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( passwort );
+	geheimnis = initTextFeld( 20, 80, 208, 20, zSchrift, TextFeld::Style::TextFeld, "Geheimis" );
+	geheimnis->setTastaturEreignisParameter( this );
+	geheimnis->setTastaturEreignis( eMailVergessenGeheimnisTE );
+	initToolTip( geheimnis, "Account Geheimnis.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( geheimnis );
+	weiter = initKnopf( 74, 110, 100, 20, zSchrift, Knopf::Style::Sichtbar, "weiter" );
+	weiter->setMausEreignisParameter( this );
+	weiter->setMausEreignis( eMailVergessenWeiterME );
+	nachricht = initTextFeld( 0, 5, 255, 150, zSchrift, TextFeld::Style::HCenter | TextFeld::Style::Mehrzeilig, "" );
+	fenster->addMember( nachricht );
+	fenster->addMember( weiter );
+	zVorLoginFenster->addMember( fenster );
+	ref = 1;
+}
+
+// Destruktor
+EMailVergessen::~EMailVergessen()
+{
+	if( eMailVergessen )
+		eMailVergessen = eMailVergessen->release();
+	if( fenster )
+		fenster = fenster->release();
+	if( name )
+		name = name->release();
+	if( passwort )
+		passwort = passwort->release();
+	if( geheimnis )
+		geheimnis = geheimnis->release();
+	if( weiter )
+		weiter = weiter->release();
+	if( nachricht )
+		nachricht = nachricht->release();
+}
+
+// Privat
+void EMailVergessen::zeigeNachricht( const char *txt )
+{
+	Punkt bildschirmmitte = Bildschirmmitte();
+	name->removeStyle( TextFeld::Style::Sichtbar );
+	passwort->removeStyle( TextFeld::Style::Sichtbar );
+	geheimnis->removeStyle( TextFeld::Style::Sichtbar );
+	fenster->setSize( 250, 150 );
+	fenster->setPosition( bildschirmmitte.x - 125, bildschirmmitte.y - 75 );
+	weiter->setPosition( 139, 100 );
+	weiter->setText( "Ok" );
+	nachricht->setText( txt );
+	if( nachricht->zText()->getLength() > 30 )
+	{
+		int pos = -1;
+		bool set = 0;
+		int lastp = 0;
+		for( int i = 20; i < nachricht->zText()->getLength(); )
+		{
+			char *tmp = &nachricht->zText()->getText()[ i ];
+			while( *tmp != ' ' && i < nachricht->zText()->getLength() )
+			{
+				tmp++;
+				i++;
+				if( i - 30 >= lastp )
+				{
+					if( set )
+					{
+						lastp = pos;
+						set = 0;
+						nachricht->zText()->getText()[ pos ] = '\n';
+					}
+					else
+						lastp += 5;
+				}
+			}
+			if( i < nachricht->zText()->getLength() )
+			{
+				pos = i;
+				set = 1;
+				tmp++;
+				i++;
+			}
+		}
+	}
+	nachricht->addStyle( TextFeld::Style::Sichtbar );
+}
+
+// Knopfdruck
+void EMailVergessen::druckFremdKnopf() // Ein anderer Knopf wurde gedrückt
+{
+	fenster->removeStyle( Fenster::Style::Sichtbar );
+	registerKlient->trenne();
+	eMailVergessen->setLinienRahmenBreite( 2 );
+	eMailVergessen->setAlphaFeldFarbe( 0x5500FF00 );
+	eMailVergessen->setAlphaFeldStrength( -5 );
+}
+
+bool EMailVergessen::eMailVergessenME( void *obj, MausEreignis me ) // MausEreignis im Knopf eMailVergessen
+{
+	if( me.id == ME_RLinks )
+	{
+		vorLogin->setEMailVergessen();
+
+		eMailVergessen->setLinienRahmenBreite( 3 );
+		eMailVergessen->setAlphaFeldFarbe( 0xFF000000 );
+		eMailVergessen->setAlphaFeldStrength( 20 );
+		Punkt bildschirmmitte = Bildschirmmitte();
+		fenster->setSize( 255, 170 );
+		fenster->setPosition( bildschirmmitte.x - 125, bildschirmmitte.y - 85 );
+		fenster->addStyle( Fenster::Style::Sichtbar );
+		nachricht->removeStyle( TextFeld::Style::Sichtbar );
+		weiter->setText( "weiter" );
+		weiter->setPosition( 75, 110 );
+		name->addStyle( TextFeld::Style::Sichtbar );
+		passwort->addStyle( TextFeld::Style::Sichtbar );
+		geheimnis->addStyle( TextFeld::Style::Sichtbar );
+		name->addStyle( TextFeld::Style::Fokus );
+		name->setAuswahl( name->zText()->getLength(), 0 );
+	}
+	return 1;
+}
+
+bool EMailVergessen::nameTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld name
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Release && ( te.taste == T_Enter || te.taste == T_Tab ) )
+	{
+		name->removeStyle( TextFeld::Style::Fokus );
+		passwort->addStyle( TextFeld::Style::Fokus );
+		passwort->setAuswahl( passwort->zText()->getLength(), 0 );
+	}
+	if( name->zText()->getLength() >= 25 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool EMailVergessen::passwortTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld passwort
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Press )
+		passwort->setSchowChar( '*' );
+	if( te.id == TE_Release && ( te.taste == T_Enter || te.taste == T_Tab ) )
+	{
+		passwort->removeStyle( TextFeld::Style::Fokus );
+		geheimnis->addStyle( TextFeld::Style::Fokus );
+		geheimnis->setAuswahl( geheimnis->zText()->getLength(), 0 );
+	}
+	if( passwort->zText()->getLength() >= 25 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool EMailVergessen::geheimnisTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld geheimnis
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Press )
+		geheimnis->setSchowChar( '*' );
+	if( te.id == TE_Release && te.taste == T_Enter )
+	{
+		geheimnis->removeStyle( TextFeld::Style::Fokus );
+		MausEreignis me;
+		me.id = ME_RLinks;
+		weiterME( 0, me );
+	}
+	if( geheimnis->zText()->getLength() >= 50 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool EMailVergessen::weiterME( void *obj, MausEreignis me ) // MausEreignis im Knopf weiter
+{
+	if( me.id == ME_RLinks )
+	{
+		if( weiter->zText()->istGleich( "weiter" ) )
+		{
+			if( name->zText()->getLength() == 0 )
+				zeigeNachricht( "Bitte gebe deinen Accountnamen ein." );
+			if( passwort->zText()->getLength() == 0 )
+				zeigeNachricht( "Bitte gebe dein Accountpasswort ein." );
+			if( geheimnis->zText()->getLength() == 0 )
+				zeigeNachricht( "Bitte gebe dein Accountgeheimnis ein." );
+			if( weiter->zText()->istGleich( "Ok" ) )
+				return 1;
+			new AktionsThread( 9, name->zText()->getText(), passwort->zText()->getText(), geheimnis->zText()->getText(), 0, 0 );
+		}
+		else
+		{
+			Punkt bildschirmmitte = Bildschirmmitte();
+			fenster->setSize( 255, 170 );
+			fenster->setPosition( bildschirmmitte.x - 125, bildschirmmitte.y - 85 );
+			fenster->addStyle( Fenster::Style::Sichtbar );
+			nachricht->removeStyle( TextFeld::Style::Sichtbar );
+			weiter->setText( "weiter" );
+			weiter->setPosition( 75, 110 );
+			name->addStyle( TextFeld::Style::Sichtbar );
+			passwort->addStyle( TextFeld::Style::Sichtbar );
+			geheimnis->addStyle( TextFeld::Style::Sichtbar );
+			name->addStyle( TextFeld::Style::Fokus );
+			name->setAuswahl( name->zText()->getLength(), 0 );
+		}
+	}
+	return 1;
+}
+
+void EMailVergessen::setReturn( bool ret, char *eMail ) // Setzt den Returnwert
+{
+	if( ret )
+	{
+		Text *nachricht = new Text( "Deine E-Mail Addresse lautet:'" );
+		nachricht->append( eMail );
+		nachricht->append( "'." );
+		zeigeNachricht( nachricht->getText() );
+		nachricht = nachricht->release();
+	}
+	else if( registerKlient->getLetzterFehler() )
+		zeigeNachricht( registerKlient->getLetzterFehler() );
+	else
+		zeigeNachricht( "Es ist ein Unbekannter Fehler aufgetreten." );
+	delete eMail;
+}
+
+// Reference Counting
+EMailVergessen *EMailVergessen::getThis()
+{
+	ref++;
+	return this;
+}
+
+EMailVergessen *EMailVergessen::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// messages
+bool eMailÄndernEMailÄndernME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (EMailÄndern*)p )->eMailÄndernME( obj, me );
+}
+
+bool eMailÄndernNameTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (EMailÄndern*)p )->nameTE( obj, te );
+}
+
+bool eMailÄndernPasswortTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (EMailÄndern*)p )->passwortTE( obj, te );
+}
+
+bool eMailÄndernGeheimnisTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (EMailÄndern*)p )->geheimnisTE( obj, te );
+}
+
+bool eMailÄndernNEMailTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (EMailÄndern*)p )->nEMailTE( obj, te );
+}
+
+bool eMailÄndernWeiterME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (EMailÄndern*)p )->weiterME( obj, me );
+}
+
+
+bool eMailVergessenEMailVergessenME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (EMailVergessen*)p )->eMailVergessenME( obj, me );
+}
+
+bool eMailVergessenNameTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (EMailVergessen*)p )->nameTE( obj, te );
+}
+
+bool eMailVergessenPasswortTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (EMailVergessen*)p )->passwortTE( obj, te );
+}
+
+bool eMailVergessenGeheimnisTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (EMailVergessen*)p )->geheimnisTE( obj, te );
+}
+
+bool eMailVergessenWeiterME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (EMailVergessen*)p )->weiterME( obj, me );
+}

+ 91 - 0
KSGClient/VorLogin/Account verwalten/EMail.h

@@ -0,0 +1,91 @@
+#ifndef EMail_H
+#define EMail_H
+
+#include <Knopf.h>
+#include <Fenster.h>
+#include <TextFeld.h>
+#include <Schrift.h>
+#include <Bildschirm.h>
+#include "..\..\Aktionen\AktionsThread.h"
+
+using namespace Framework;
+
+class EMailÄndern
+{
+private:
+	Knopf *eMailÄndern;
+	Fenster *fenster;
+	TextFeld *name;
+	TextFeld *passwort;
+	TextFeld *geheimnis;
+	TextFeld *nEMail;
+	Knopf *weiter;
+	TextFeld *nachricht;
+	int ref;
+	void zeigeNachricht( const char *txt );
+
+public:
+	// Konstruktor
+	EMailÄndern( Schrift *zSchrift, Fenster *zVorLoginFenster );
+	// Destruktor
+	~EMailÄndern();
+	// Knopfdruck
+	void druckFremdKnopf(); // Ein anderer Knopf wurde gedrückt
+	bool eMailÄndernME( void *obj, MausEreignis me ); // MausEreignis im Knopf eMailÄndern
+	bool nameTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld name
+	bool passwortTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld passwort
+	bool geheimnisTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld geheimnis
+	bool nEMailTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld nEMail
+	bool weiterME( void *obj, MausEreignis me ); // MausEreignis im Knopf weiter
+	void setReturn( bool ret ); // Setzt den Returnwert
+	// Reference Counting
+	EMailÄndern *getThis();
+	EMailÄndern *release();
+};
+
+class EMailVergessen
+{
+private:
+	Knopf *eMailVergessen;
+	Fenster *fenster;
+	TextFeld *name;
+	TextFeld *passwort;
+	TextFeld *geheimnis;
+	Knopf *weiter;
+	TextFeld *nachricht;
+	int ref;
+	void zeigeNachricht( const char *txt );
+
+public:
+	// Konstruktor
+	EMailVergessen( Schrift *zSchrift, Fenster *zVorLoginFenster );
+	// Destruktor
+	~EMailVergessen();
+	// Knopfdruck
+	void druckFremdKnopf(); // Ein anderer Knopf wurde gedrückt
+	bool eMailVergessenME( void *obj, MausEreignis me ); // MausEreignis im Knopf eMailVergessen
+	bool nameTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld name
+	bool passwortTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld passwort
+	bool geheimnisTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld geheimnis
+	bool weiterME( void *obj, MausEreignis me ); // MausEreignis im Knopf weiter
+	void setReturn( bool ret, char *eMail ); // Setzt den Returnwert
+	// Reference Counting
+	EMailVergessen *getThis();
+	EMailVergessen *release();
+};
+
+// messages
+bool eMailÄndernEMailÄndernME( void *p, void *obj, MausEreignis me );
+bool eMailÄndernNameTE( void *p, void *obj, TastaturEreignis te );
+bool eMailÄndernPasswortTE( void *p, void *obj, TastaturEreignis te );
+bool eMailÄndernGeheimnisTE( void *p, void *obj, TastaturEreignis te );
+bool eMailÄndernNEMailTE( void *p, void *obj, TastaturEreignis te );
+bool eMailÄndernWeiterME( void *p, void *obj, MausEreignis me );
+
+bool eMailVergessenEMailVergessenME( void *p, void *obj, MausEreignis me );
+bool eMailVergessenNameTE( void *p, void *obj, TastaturEreignis te );
+bool eMailVergessenPasswortTE( void *p, void *obj, TastaturEreignis te );
+bool eMailVergessenGeheimnisTE( void *p, void *obj, TastaturEreignis te );
+bool eMailVergessenWeiterME( void *p, void *obj, MausEreignis me );
+
+#endif

+ 573 - 0
KSGClient/VorLogin/Account verwalten/Geheimnis.cpp

@@ -0,0 +1,573 @@
+#include "..\..\Global\Variablen.h"
+#include "Geheimnis.h"
+#include "..\..\Global\Initialisierung.h"
+#include <Punkt.h>
+#include <Text.h>
+
+// Inhalt der GeheimnisÄndern Klasse aus Geheimnis.h
+// Konstruktor
+GeheimnisÄndern::GeheimnisÄndern( Schrift *zSchrift, Fenster *zVorLoginFenster )
+{
+	Punkt bildschirmmitte = Bildschirmmitte();
+	geheimnisÄndern = initKnopf( 10, 250, 130, 30, zSchrift, Knopf::Style::Sichtbar, "Geheimnis ändern" );
+	geheimnisÄndern->setMausEreignisParameter( this );
+	geheimnisÄndern->setMausEreignis( geheimnisÄndernGeheimnisÄndernME );
+	initToolTip( geheimnisÄndern, "Account Geheimnis ändern.", zSchrift->getThis(), hauptScreen );
+	zVorLoginFenster->addMember( geheimnisÄndern );
+	fenster = initFenster( bildschirmmitte.x - 125, bildschirmmitte.y - 100, 250, 200, zSchrift, Fenster::Style::Erlaubt | Fenster::Style::Rahmen | Fenster::Style::Titel | Fenster::Style::TitelBuffered, "Geheimnis ändern" );
+	name = initTextFeld( 20, 20, 208, 20, zSchrift, TextFeld::Style::TextFeld, "Name" );
+	name->setTastaturEreignisParameter( this );
+	name->setTastaturEreignis( geheimnisÄndernNameTE );
+	initToolTip( name, "Account Name.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( name );
+	passwort = initTextFeld( 20, 50, 208, 20, zSchrift, TextFeld::Style::TextFeld, "Passwort" );
+	passwort->setTastaturEreignisParameter( this );
+	passwort->setTastaturEreignis( geheimnisÄndernPasswortTE );
+	initToolTip( passwort, "Account Passwort.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( passwort );
+	geheimnis = initTextFeld( 20, 80, 208, 20, zSchrift, TextFeld::Style::TextFeld, "Geheimis" );
+	geheimnis->setTastaturEreignisParameter( this );
+	geheimnis->setTastaturEreignis( geheimnisÄndernGeheimnisTE );
+	initToolTip( geheimnis, "Account Geheimni.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( geheimnis );
+	nGeheimnis = initTextFeld( 20, 110, 208, 20, zSchrift, TextFeld::Style::TextFeld, "neues Geheimnis" );
+	nGeheimnis->setTastaturEreignisParameter( this );
+	nGeheimnis->setTastaturEreignis( geheimnisÄndernNGeheimnisTE );
+	initToolTip( nGeheimnis, "Neues Account Geheimnis.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( nGeheimnis );
+	weiter = initKnopf( 74, 140, 100, 20, zSchrift, Knopf::Style::Sichtbar, "weiter" );
+	weiter->setMausEreignisParameter( this );
+	weiter->setMausEreignis( geheimnisÄndernWeiterME );
+	nachricht = initTextFeld( 0, 5, 255, 150, zSchrift, TextFeld::Style::HCenter | TextFeld::Style::Mehrzeilig, "" );
+	fenster->addMember( nachricht );
+	fenster->addMember( weiter );
+	zVorLoginFenster->addMember( fenster );
+	ref = 1;
+}
+
+// Destruktor
+GeheimnisÄndern::~GeheimnisÄndern()
+{
+	if( geheimnisÄndern )
+		geheimnisÄndern = geheimnisÄndern->release();
+	if( fenster )
+		fenster = fenster->release();
+	if( name )
+		name = name->release();
+	if( passwort )
+		passwort = passwort->release();
+	if( geheimnis )
+		geheimnis = geheimnis->release();
+	if( nGeheimnis )
+		nGeheimnis = nGeheimnis->release();
+	if( weiter )
+		weiter = weiter->release();
+	if( nachricht )
+		nachricht = nachricht->release();
+}
+
+// Privat
+void GeheimnisÄndern::zeigeNachricht( const char *txt )
+{
+	Punkt bildschirmmitte = Bildschirmmitte();
+	name->removeStyle( TextFeld::Style::Sichtbar );
+	passwort->removeStyle( TextFeld::Style::Sichtbar );
+	geheimnis->removeStyle( TextFeld::Style::Sichtbar );
+	nGeheimnis->removeStyle( TextFeld::Style::Sichtbar );
+	fenster->setSize( 250, 150 );
+	fenster->setPosition( bildschirmmitte.x - 125, bildschirmmitte.y - 75 );
+	weiter->setPosition( 139, 100 );
+	weiter->setText( "Ok" );
+	nachricht->setText( txt );
+	if( nachricht->zText()->getLength() > 30 )
+	{
+		int pos = -1;
+		bool set = 0;
+		int lastp = 0;
+		for( int i = 20; i < nachricht->zText()->getLength(); )
+		{
+			char *tmp = &nachricht->zText()->getText()[ i ];
+			while( *tmp != ' ' && i < nachricht->zText()->getLength() )
+			{
+				tmp++;
+				i++;
+				if( i - 30 >= lastp )
+				{
+					if( set )
+					{
+						lastp = pos;
+						set = 0;
+						nachricht->zText()->getText()[ pos ] = '\n';
+					}
+					else
+						lastp += 5;
+				}
+			}
+			if( i < nachricht->zText()->getLength() )
+			{
+				pos = i;
+				set = 1;
+				tmp++;
+				i++;
+			}
+		}
+	}
+	nachricht->addStyle( TextFeld::Style::Sichtbar );
+}
+
+// Knopfdruck
+void GeheimnisÄndern::druckFremdKnopf() // Ein anderer Knopf wurde gedrückt
+{
+	fenster->removeStyle( Fenster::Style::Sichtbar );
+	registerKlient->trenne();
+	geheimnisÄndern->setLinienRahmenBreite( 2 );
+	geheimnisÄndern->setAlphaFeldFarbe( 0x5500FF00 );
+	geheimnisÄndern->setAlphaFeldStrength( -5 );
+}
+
+bool GeheimnisÄndern::geheimnisÄndernME( void *obj, MausEreignis me ) // MausEreignis im Knopf geheimnisÄndern
+{
+	if( me.id == ME_RLinks )
+	{
+		vorLogin->setGeheimnisÄndern();
+
+		geheimnisÄndern->setLinienRahmenBreite( 3 );
+		geheimnisÄndern->setAlphaFeldFarbe( 0xFF000000 );
+		geheimnisÄndern->setAlphaFeldStrength( 20 );
+		Punkt bildschirmmitte = Bildschirmmitte();
+		fenster->setSize( 255, 200 );
+		fenster->setPosition( bildschirmmitte.x - 125, bildschirmmitte.y - 100 );
+		fenster->addStyle( Fenster::Style::Sichtbar );
+		nachricht->removeStyle( TextFeld::Style::Sichtbar );
+		weiter->setText( "weiter" );
+		weiter->setPosition( 75, 140 );
+		name->addStyle( TextFeld::Style::Sichtbar );
+		passwort->addStyle( TextFeld::Style::Sichtbar );
+		geheimnis->addStyle( TextFeld::Style::Sichtbar );
+		nGeheimnis->addStyle( TextFeld::Style::Sichtbar );
+		name->addStyle( TextFeld::Style::Fokus );
+		name->setAuswahl( name->zText()->getLength(), 0 );
+	}
+	return 1;
+}
+
+bool GeheimnisÄndern::nameTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld name
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Release && ( te.taste == T_Enter || te.taste == T_Tab ) )
+	{
+		name->removeStyle( TextFeld::Style::Fokus );
+		passwort->addStyle( TextFeld::Style::Fokus );
+		passwort->setAuswahl( passwort->zText()->getLength(), 0 );
+	}
+	if( name->zText()->getLength() >= 25 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool GeheimnisÄndern::passwortTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld passwort
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Press )
+		passwort->setSchowChar( '*' );
+	if( te.id == TE_Release && ( te.taste == T_Enter || te.taste == T_Tab ) )
+	{
+		passwort->removeStyle( TextFeld::Style::Fokus );
+		geheimnis->addStyle( TextFeld::Style::Fokus );
+		geheimnis->setAuswahl( geheimnis->zText()->getLength(), 0 );
+	}
+	if( passwort->zText()->getLength() >= 25 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool GeheimnisÄndern::geheimnisTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld geheimnis
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Press )
+		geheimnis->setSchowChar( '*' );
+	if( te.id == TE_Release && ( te.taste == T_Enter || te.taste == T_Tab ) )
+	{
+		geheimnis->removeStyle( TextFeld::Style::Fokus );
+		nGeheimnis->addStyle( TextFeld::Style::Fokus );
+		nGeheimnis->setAuswahl( nGeheimnis->zText()->getLength(), 0 );
+	}
+	if( geheimnis->zText()->getLength() >= 50 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool GeheimnisÄndern::nGeheimnisTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld nGeheimnis
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Release && te.taste == T_Enter )
+	{
+		nGeheimnis->removeStyle( TextFeld::Style::Fokus );
+		MausEreignis me;
+		me.id = ME_RLinks;
+		weiterME( 0, me );
+	}
+	if( nGeheimnis->zText()->getLength() >= 25 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool GeheimnisÄndern::weiterME( void *obj, MausEreignis me ) // MausEreignis im Knopf weiter
+{
+	if( me.id == ME_RLinks )
+	{
+		if( weiter->zText()->istGleich( "weiter" ) )
+		{
+			if( name->zText()->getLength() == 0 )
+				zeigeNachricht( "Bitte gebe deinen Accountnamen ein." );
+			if( passwort->zText()->getLength() == 0 )
+				zeigeNachricht( "Bitte gebe dein Accountpasswort ein." );
+			if( geheimnis->zText()->getLength() == 0 )
+				zeigeNachricht( "Bitte gebe dein Accountgeheimnis ein." );
+			if( nGeheimnis->zText()->getLength() == 0 )
+				zeigeNachricht( "Bitte gebe ein neues Accountgeheimnis ein." );
+			if( weiter->zText()->istGleich( "Ok" ) )
+				return 1;
+			new AktionsThread( 10, name->zText()->getText(), passwort->zText()->getText(), geheimnis->zText()->getText(), nGeheimnis->zText()->getText(), 0 );
+		}
+		else
+		{
+			Punkt bildschirmmitte = Bildschirmmitte();
+			fenster->setSize( 255, 200 );
+			fenster->setPosition( bildschirmmitte.x - 125, bildschirmmitte.y - 100 );
+			fenster->addStyle( Fenster::Style::Sichtbar );
+			nachricht->removeStyle( TextFeld::Style::Sichtbar );
+			weiter->setText( "weiter" );
+			weiter->setPosition( 75, 140 );
+			name->addStyle( TextFeld::Style::Sichtbar );
+			passwort->addStyle( TextFeld::Style::Sichtbar );
+			geheimnis->addStyle( TextFeld::Style::Sichtbar );
+			nGeheimnis->addStyle( TextFeld::Style::Sichtbar );
+			name->addStyle( TextFeld::Style::Fokus );
+			name->setAuswahl( name->zText()->getLength(), 0 );
+		}
+	}
+	return 1;
+}
+
+void GeheimnisÄndern::setResult( bool ret ) // Setzt den Returnwert
+{
+	if( ret )
+		zeigeNachricht( "Geheimnis erfolgreich geändert." );
+	else if( registerKlient->getLetzterFehler() )
+		zeigeNachricht( registerKlient->getLetzterFehler() );
+	else
+		zeigeNachricht( "Es ist ein Unbekannter Fehler aufgetreten." );
+}
+
+// Reference Counting
+GeheimnisÄndern *GeheimnisÄndern::getThis()
+{
+	ref++;
+	return 0;
+}
+
+GeheimnisÄndern *GeheimnisÄndern::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der GeheimnisVergessen Klasse aus Geheimnis.h
+// Konstruktor
+GeheimnisVergessen::GeheimnisVergessen( Schrift *zSchrift, Fenster *zVorLoginFenster )
+{
+	Punkt bildschirmmitte = Bildschirmmitte();
+	geheimnisVergessen = initKnopf( 10, 370, 130, 30, zSchrift, Knopf::Style::Sichtbar, "Geheimnis vergessen" );
+	geheimnisVergessen->setMausEreignisParameter( this );
+	geheimnisVergessen->setMausEreignis( geheimnisVergessenGeheimnisVergessenME );
+	initToolTip( geheimnisVergessen, "Account Geheimnis per E-Mail senden.", zSchrift->getThis(), hauptScreen );
+	zVorLoginFenster->addMember( geheimnisVergessen );
+	fenster = initFenster( bildschirmmitte.x - 125, bildschirmmitte.y - 70, 250, 140, zSchrift, Fenster::Style::Erlaubt | Fenster::Style::Rahmen | Fenster::Style::Titel | Fenster::Style::TitelBuffered, "Geheimnis vergessen" );
+	name = initTextFeld( 20, 20, 208, 20, zSchrift, TextFeld::Style::TextFeld, "Name" );
+	name->setTastaturEreignisParameter( this );
+	name->setTastaturEreignis( geheimnisVergessenNameTE );
+	initToolTip( name, "Account Name.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( name );
+	passwort = initTextFeld( 20, 50, 208, 20, zSchrift, TextFeld::Style::TextFeld, "Passwort" );
+	passwort->setTastaturEreignisParameter( this );
+	passwort->setTastaturEreignis( geheimnisVergessenPasswortTE );
+	initToolTip( passwort, "Account Passwort.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( passwort );
+	weiter = initKnopf( 74, 80, 100, 20, zSchrift, Knopf::Style::Sichtbar, "weiter" );
+	weiter->setMausEreignisParameter( this );
+	weiter->setMausEreignis( geheimnisVergessenWeiterME );
+	nachricht = initTextFeld( 0, 5, 255, 150, zSchrift, TextFeld::Style::HCenter | TextFeld::Style::Mehrzeilig, "" );
+	fenster->addMember( nachricht );
+	fenster->addMember( weiter );
+	zVorLoginFenster->addMember( fenster );
+	ref = 1;
+}
+
+// Destruktor
+GeheimnisVergessen::~GeheimnisVergessen()
+{
+	if( geheimnisVergessen )
+		geheimnisVergessen = geheimnisVergessen->release();
+	if( fenster )
+		fenster = fenster->release();
+	if( name )
+		name = name->release();
+	if( passwort )
+		passwort = passwort->release();
+	if( weiter )
+		weiter = weiter->release();
+	if( nachricht )
+		nachricht = nachricht->release();
+}
+
+// Privat
+void GeheimnisVergessen::zeigeNachricht( const char *txt )
+{
+	Punkt bildschirmmitte = Bildschirmmitte();
+	name->removeStyle( TextFeld::Style::Sichtbar );
+	passwort->removeStyle( TextFeld::Style::Sichtbar );
+	fenster->setSize( 250, 150 );
+	fenster->setPosition( bildschirmmitte.x - 125, bildschirmmitte.y - 75 );
+	weiter->setPosition( 139, 100 );
+	weiter->setText( "Ok" );
+	nachricht->setText( txt );
+	if( nachricht->zText()->getLength() > 30 )
+	{
+		int pos = -1;
+		bool set = 0;
+		int lastp = 0;
+		for( int i = 20; i < nachricht->zText()->getLength(); )
+		{
+			char *tmp = &nachricht->zText()->getText()[ i ];
+			while( *tmp != ' ' && i < nachricht->zText()->getLength() )
+			{
+				tmp++;
+				i++;
+				if( i - 30 >= lastp )
+				{
+					if( set )
+					{
+						lastp = pos;
+						set = 0;
+						nachricht->zText()->getText()[ pos ] = '\n';
+					}
+					else
+						lastp += 5;
+				}
+			}
+			if( i < nachricht->zText()->getLength() )
+			{
+				pos = i;
+				set = 1;
+				tmp++;
+				i++;
+			}
+		}
+	}
+	nachricht->addStyle( TextFeld::Style::Sichtbar );
+}
+
+// Knopfdruck
+void GeheimnisVergessen::druckFremdKnopf() // Ein anderer Knopf wurde gedrückt
+{
+	fenster->removeStyle( Fenster::Style::Sichtbar );
+	registerKlient->trenne();
+	geheimnisVergessen->setLinienRahmenBreite( 2 );
+	geheimnisVergessen->setAlphaFeldFarbe( 0x5500FF00 );
+	geheimnisVergessen->setAlphaFeldStrength( -5 );
+}
+
+bool GeheimnisVergessen::geheimnisVergessenME( void *obj, MausEreignis me ) // MausEreignis im Knopf geheimnisVergessen
+{
+	if( me.id == ME_RLinks )
+	{
+		vorLogin->setGeheilnisVergessen();
+
+		geheimnisVergessen->setLinienRahmenBreite( 3 );
+		geheimnisVergessen->setAlphaFeldFarbe( 0xFF000000 );
+		geheimnisVergessen->setAlphaFeldStrength( 20 );
+		Punkt bildschirmmitte = Bildschirmmitte();
+		fenster->setSize( 255, 140 );
+		fenster->setPosition( bildschirmmitte.x - 125, bildschirmmitte.y - 70 );
+		fenster->addStyle( Fenster::Style::Sichtbar );
+		nachricht->removeStyle( TextFeld::Style::Sichtbar );
+		weiter->setText( "weiter" );
+		weiter->setPosition( 75, 80 );
+		name->addStyle( TextFeld::Style::Sichtbar );
+		passwort->addStyle( TextFeld::Style::Sichtbar );
+		name->addStyle( TextFeld::Style::Fokus );
+		name->setAuswahl( name->zText()->getLength(), 0 );
+	}
+	return 1;
+}
+
+bool GeheimnisVergessen::nameTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld name
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Release && ( te.taste == T_Enter || te.taste == T_Tab ) )
+	{
+		name->removeStyle( TextFeld::Style::Fokus );
+		passwort->addStyle( TextFeld::Style::Fokus );
+		passwort->setAuswahl( passwort->zText( )->getLength( ), 0 );
+	}
+	if( name->zText( )->getLength( ) >= 25 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool GeheimnisVergessen::passwortTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld passwort
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Press )
+		passwort->setSchowChar( '*' );
+	if( te.id == TE_Release && te.taste == T_Enter )
+	{
+		passwort->removeStyle( TextFeld::Style::Fokus );
+		MausEreignis me;
+		me.id = ME_RLinks;
+		weiterME( 0, me );
+	}
+	if( passwort->zText( )->getLength( ) >= 25 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool GeheimnisVergessen::weiterME( void *obj, MausEreignis me ) // MausEreignis im Knopf weiter
+{
+	if( me.id == ME_RLinks )
+	{
+		if( weiter->zText()->istGleich( "weiter" ) )
+		{
+			if( name->zText()->getLength() == 0 )
+				zeigeNachricht( "Bitte gebe deinen Accountnamen ein." );
+			if( passwort->zText()->getLength() == 0 )
+				zeigeNachricht( "Bitte gebe dein Accountpasswort ein." );
+			if( weiter->zText()->istGleich( "Ok" ) )
+				return 1;
+			new AktionsThread( 11, name->zText()->getText(), passwort->zText()->getText(), 0, 0, 0 );
+		}
+		else
+		{
+			Punkt bildschirmmitte = Bildschirmmitte();
+			fenster->setSize( 255, 140 );
+			fenster->setPosition( bildschirmmitte.x - 125, bildschirmmitte.y - 70 );
+			fenster->addStyle( Fenster::Style::Sichtbar );
+			nachricht->removeStyle( TextFeld::Style::Sichtbar );
+			weiter->setText( "weiter" );
+			weiter->setPosition( 75, 80 );
+			name->addStyle( TextFeld::Style::Sichtbar );
+			passwort->addStyle( TextFeld::Style::Sichtbar );
+			name->addStyle( TextFeld::Style::Fokus );
+			name->setAuswahl( name->zText()->getLength(), 0 );
+		}
+	}
+	return 1;
+}
+
+void GeheimnisVergessen::setResult( bool ret ) // Setzt den Returnwert
+{
+	if( ret )
+		zeigeNachricht( "Dir wurde eine E-Mail mit deinem Accountgeheimnis gesendet." );
+	else if( registerKlient->getLetzterFehler() )
+		zeigeNachricht( registerKlient->getLetzterFehler() );
+	else
+		zeigeNachricht( "Es ist ein Unbekannter Fehler aufgetreten." );
+}
+
+// Reference Counting
+GeheimnisVergessen *GeheimnisVergessen::getThis()
+{
+	ref++;
+	return this;
+}
+
+GeheimnisVergessen *GeheimnisVergessen::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// messages
+bool geheimnisÄndernGeheimnisÄndernME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (GeheimnisÄndern*)p )->geheimnisÄndernME( obj, me );
+}
+
+bool geheimnisÄndernNameTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (GeheimnisÄndern*)p )->nameTE( obj, te );
+}
+
+bool geheimnisÄndernPasswortTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (GeheimnisÄndern*)p )->passwortTE( obj, te );
+}
+
+bool geheimnisÄndernGeheimnisTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (GeheimnisÄndern*)p )->geheimnisTE( obj, te );
+}
+
+bool geheimnisÄndernNGeheimnisTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (GeheimnisÄndern*)p )->nGeheimnisTE( obj, te );
+}
+
+bool geheimnisÄndernWeiterME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (GeheimnisÄndern*)p )->weiterME( obj, me );
+}
+
+
+bool geheimnisVergessenGeheimnisVergessenME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (GeheimnisVergessen*)p )->geheimnisVergessenME( obj, me );
+}
+
+bool geheimnisVergessenNameTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (GeheimnisVergessen*)p )->nameTE( obj, te );
+}
+
+bool geheimnisVergessenPasswortTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (GeheimnisVergessen*)p )->passwortTE( obj, te );
+}
+
+bool geheimnisVergessenWeiterME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (GeheimnisVergessen*)p )->weiterME( obj, me );
+}

+ 88 - 0
KSGClient/VorLogin/Account verwalten/Geheimnis.h

@@ -0,0 +1,88 @@
+#ifndef Geheimnis_H
+#define Geheimnis_H
+
+#include <Knopf.h>
+#include <Fenster.h>
+#include <TextFeld.h>
+#include <Schrift.h>
+#include <Bildschirm.h>
+#include "..\..\Aktionen\AktionsThread.h"
+
+using namespace Framework;
+
+class GeheimnisÄndern
+{
+private:
+	Knopf *geheimnisÄndern;
+	Fenster *fenster;
+	TextFeld *name;
+	TextFeld *passwort;
+	TextFeld *geheimnis;
+	TextFeld *nGeheimnis;
+	Knopf *weiter;
+	TextFeld *nachricht;
+	int ref;
+	void zeigeNachricht( const char *txt );
+
+public:
+	// Konstruktor
+	GeheimnisÄndern( Schrift *zSchrift, Fenster *zVorLoginFenster );
+	// Destruktor
+	~GeheimnisÄndern();
+	// Knopfdruck
+	void druckFremdKnopf(); // Ein anderer Knopf wurde gedrückt
+	bool geheimnisÄndernME( void *obj, MausEreignis me ); // MausEreignis im Knopf geheimnisÄndern
+	bool nameTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld name
+	bool passwortTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld passwort
+	bool geheimnisTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld geheimnis
+	bool nGeheimnisTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld nGeheimnis
+	bool weiterME( void *obj, MausEreignis me ); // MausEreignis im Knopf weiter
+	void setResult( bool ret ); // Setzt den Returnwert
+	// Reference Counting
+	GeheimnisÄndern *getThis();
+	GeheimnisÄndern *release();
+};
+
+class GeheimnisVergessen
+{
+private:
+	Knopf *geheimnisVergessen;
+	Fenster *fenster;
+	TextFeld *name;
+	TextFeld *passwort;
+	Knopf *weiter;
+	TextFeld *nachricht;
+	int ref;
+	void zeigeNachricht( const char *txt );
+
+public:
+	// Konstruktor
+	GeheimnisVergessen( Schrift *zSchrift, Fenster *zVorLoginFenster );
+	// Destruktor
+	~GeheimnisVergessen();
+	// Knopfdruck
+	void druckFremdKnopf(); // Ein anderer Knopf wurde gedrückt
+	bool geheimnisVergessenME( void *obj, MausEreignis me ); // MausEreignis im Knopf geheimnisVergessen
+	bool nameTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld name
+	bool passwortTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld passwort
+	bool weiterME( void *obj, MausEreignis me ); // MausEreignis im Knopf weiter
+	void setResult( bool ret ); // Setzt den Returnwert
+	// Reference Counting
+	GeheimnisVergessen *getThis();
+	GeheimnisVergessen *release();
+};
+
+// messages
+bool geheimnisÄndernGeheimnisÄndernME( void *p, void *obj, MausEreignis me );
+bool geheimnisÄndernNameTE( void *p, void *obj, TastaturEreignis te );
+bool geheimnisÄndernPasswortTE( void *p, void *obj, TastaturEreignis te );
+bool geheimnisÄndernGeheimnisTE( void *p, void *obj, TastaturEreignis te );
+bool geheimnisÄndernNGeheimnisTE( void *p, void *obj, TastaturEreignis te );
+bool geheimnisÄndernWeiterME( void *p, void *obj, MausEreignis me );
+
+bool geheimnisVergessenGeheimnisVergessenME( void *p, void *obj, MausEreignis me );
+bool geheimnisVergessenNameTE( void *p, void *obj, TastaturEreignis te );
+bool geheimnisVergessenPasswortTE( void *p, void *obj, TastaturEreignis te );
+bool geheimnisVergessenWeiterME( void *p, void *obj, MausEreignis me );
+
+#endif

+ 254 - 0
KSGClient/VorLogin/Account verwalten/Name.cpp

@@ -0,0 +1,254 @@
+#include "..\..\Global\Variablen.h"
+#include "Name.h"
+#include "..\..\Global\Initialisierung.h"
+#include <Punkt.h>
+#include <Text.h>
+
+// Inhalt der NameVergessen Klasse aus Name.h
+// Konstruktor
+NameVergessen::NameVergessen( Schrift *zSchrift, Fenster *zVorLoginFenster )
+{
+	Punkt bildschirmmitte = Bildschirmmitte();
+	nameVergessen = initKnopf( 10, 290, 130, 30, zSchrift, Knopf::Style::Sichtbar, "Name vergessen" );
+	nameVergessen->setMausEreignisParameter( this );
+	nameVergessen->setMausEreignis( nameVergessenNameVergessenME );
+	initToolTip( nameVergessen, "Accoutnt Name per E-MAil senden.", zSchrift->getThis(), hauptScreen );
+	zVorLoginFenster->addMember( nameVergessen );
+	fenster = initFenster( bildschirmmitte.x - 125, bildschirmmitte.y - 70, 250, 140, zSchrift, Fenster::Style::Erlaubt | Fenster::Style::Rahmen | Fenster::Style::Titel | Fenster::Style::TitelBuffered, "Name vergessen" );
+	passwort = initTextFeld( 20, 20, 208, 20, zSchrift, TextFeld::Style::TextFeld, "Passwort" );
+	passwort->setTastaturEreignisParameter( this );
+	passwort->setTastaturEreignis( nameVergessenPasswortTE );
+	initToolTip( passwort, "Accoutnt Passwort.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( passwort );
+	geheimnis = initTextFeld( 20, 50, 208, 20, zSchrift, TextFeld::Style::TextFeld, "Geheimis" );
+	geheimnis->setTastaturEreignisParameter( this );
+	geheimnis->setTastaturEreignis( nameVergessenGeheimnisTE );
+	initToolTip( geheimnis, "Account Geheimnis.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( geheimnis );
+	weiter = initKnopf( 74, 80, 100, 20, zSchrift, Knopf::Style::Sichtbar, "weiter" );
+	weiter->setMausEreignisParameter( this );
+	weiter->setMausEreignis( nameVergessenWeiterME );
+	nachricht = initTextFeld( 0, 5, 255, 150, zSchrift, TextFeld::Style::HCenter | TextFeld::Style::Mehrzeilig, "" );
+	fenster->addMember( nachricht );
+	fenster->addMember( weiter );
+	zVorLoginFenster->addMember( fenster );
+	ref = 1;
+}
+
+// Destruktor
+NameVergessen::~NameVergessen()
+{
+	if( nameVergessen )
+		nameVergessen = nameVergessen->release();
+	if( fenster )
+		fenster = fenster->release();
+	if( passwort )
+		passwort = passwort->release();
+	if( geheimnis )
+		geheimnis = geheimnis->release();
+	if( weiter )
+		weiter = weiter->release();
+	if( nachricht )
+		nachricht = nachricht->release();
+}
+
+// Privat
+void NameVergessen::zeigeNachricht( const char *txt )
+{
+	Punkt bildschirmmitte = Bildschirmmitte();
+	passwort->removeStyle( TextFeld::Style::Sichtbar );
+	geheimnis->removeStyle( TextFeld::Style::Sichtbar );
+	fenster->setSize( 250, 150 );
+	fenster->setPosition( bildschirmmitte.x - 125, bildschirmmitte.y - 75 );
+	weiter->setPosition( 139, 100 );
+	weiter->setText( "Ok" );
+	nachricht->setText( txt );
+	if( nachricht->zText()->getLength() > 30 )
+	{
+		int pos = -1;
+		bool set = 0;
+		int lastp = 0;
+		for( int i = 20; i < nachricht->zText()->getLength(); )
+		{
+			char *tmp = &nachricht->zText()->getText()[ i ];
+			while( *tmp != ' ' && i < nachricht->zText()->getLength() )
+			{
+				tmp++;
+				i++;
+				if( i - 30 >= lastp )
+				{
+					if( set )
+					{
+						lastp = pos;
+						set = 0;
+						nachricht->zText()->getText()[ pos ] = '\n';
+					}
+					else
+						lastp += 5;
+				}
+			}
+			if( i < nachricht->zText()->getLength() )
+			{
+				pos = i;
+				set = 1;
+				tmp++;
+				i++;
+			}
+		}
+	}
+	nachricht->addStyle( TextFeld::Style::Sichtbar );
+}
+
+// Knopfdruck
+void NameVergessen::druckFremdKnopf() // Ein anderer Knopf wurde gedrückt
+{
+	fenster->removeStyle( Fenster::Style::Sichtbar );
+	registerKlient->trenne();
+	nameVergessen->setLinienRahmenBreite( 2 );
+	nameVergessen->setAlphaFeldFarbe( 0x5500FF00 );
+	nameVergessen->setAlphaFeldStrength( -5 );
+}
+
+bool NameVergessen::nameVergessenME( void *obj, MausEreignis me ) // MausEreignis im Knopf nameVergessen
+{
+	if( me.id == ME_RLinks )
+	{
+		vorLogin->setNameVergessen();
+
+		nameVergessen->setLinienRahmenBreite( 3 );
+		nameVergessen->setAlphaFeldFarbe( 0xFF000000 );
+		nameVergessen->setAlphaFeldStrength( 20 );
+		Punkt bildschirmmitte = Bildschirmmitte();
+		fenster->setSize( 255, 140 );
+		fenster->setPosition( bildschirmmitte.x - 125, bildschirmmitte.y - 70 );
+		fenster->addStyle( Fenster::Style::Sichtbar );
+		nachricht->removeStyle( TextFeld::Style::Sichtbar );
+		weiter->setText( "weiter" );
+		weiter->setPosition( 75, 80 );
+		passwort->addStyle( TextFeld::Style::Sichtbar );
+		geheimnis->addStyle( TextFeld::Style::Sichtbar );
+		passwort->addStyle( TextFeld::Style::Fokus );
+		passwort->setAuswahl( passwort->zText()->getLength(), 0 );
+	}
+	return 1;
+}
+
+bool NameVergessen::passwortTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld passwort
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Press )
+		passwort->setSchowChar( '*' );
+	if( te.id == TE_Release && ( te.taste == T_Enter || te.taste == T_Tab ) )
+	{
+		passwort->removeStyle( TextFeld::Style::Fokus );
+		geheimnis->addStyle( TextFeld::Style::Fokus );
+		geheimnis->setAuswahl( geheimnis->zText()->getLength(), 0 );
+	}
+	if( passwort->zText()->getLength() >= 25 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool NameVergessen::geheimnisTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld geheimnis
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Release && te.taste == T_Enter )
+	{
+		passwort->removeStyle( TextFeld::Style::Fokus );
+		MausEreignis me;
+		me.id = ME_RLinks;
+		weiterME( 0, me );
+	}
+	if( passwort->zText()->getLength() >= 25 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool NameVergessen::weiterME( void *obj, MausEreignis me ) // MausEreignis im Knopf weiter
+{
+	if( me.id == ME_RLinks )
+	{
+		if( weiter->zText( )->istGleich( "weiter" ) )
+		{
+			if( passwort->zText( )->getLength( ) == 0 )
+				zeigeNachricht( "Bitte gebe dein Accountpasswort ein." );
+			if( geheimnis->zText( )->getLength( ) == 0 )
+				zeigeNachricht( "Bitte gebe dein Accountgeheimnis ein." );
+			if( weiter->zText( )->istGleich( "Ok" ) )
+				return 1;
+			new AktionsThread( 12, passwort->zText( )->getText( ), geheimnis->zText( )->getText( ), 0, 0, 0 );
+		}
+		else
+		{
+			Punkt bildschirmmitte = Bildschirmmitte( );
+			fenster->setSize( 255, 140 );
+			fenster->setPosition( bildschirmmitte.x - 125, bildschirmmitte.y - 70 );
+			fenster->addStyle( Fenster::Style::Sichtbar );
+			nachricht->removeStyle( TextFeld::Style::Sichtbar );
+			weiter->setText( "weiter" );
+			weiter->setPosition( 75, 80 );
+			passwort->addStyle( TextFeld::Style::Sichtbar );
+			geheimnis->addStyle( TextFeld::Style::Sichtbar );
+			passwort->addStyle( TextFeld::Style::Fokus );
+			passwort->setAuswahl( passwort->zText( )->getLength( ), 0 );
+		}
+	}
+	return 1;
+}
+
+void NameVergessen::setResult( bool ret ) // Setzt den Returnwert
+{
+	if( ret )
+		zeigeNachricht( "Dir wurde eine E-Mail mit deinem Accountnamen geschickt." );
+	else if( registerKlient->getLetzterFehler() )
+		zeigeNachricht( registerKlient->getLetzterFehler() );
+	else
+		zeigeNachricht( "Es ist ein Unbekannter Fehler aufgetreten." );
+}
+
+// Reference Counting
+NameVergessen *NameVergessen::getThis()
+{
+	ref++;
+	return this;
+}
+
+NameVergessen *NameVergessen::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// messages
+bool nameVergessenNameVergessenME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (NameVergessen*)p )->nameVergessenME( obj, me );
+}
+
+bool nameVergessenPasswortTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (NameVergessen*)p )->passwortTE( obj, te );
+}
+
+bool nameVergessenGeheimnisTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (NameVergessen*)p )->geheimnisTE( obj, te );
+}
+
+bool nameVergessenWeiterME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (NameVergessen*)p )->weiterME( obj, me );
+}

+ 47 - 0
KSGClient/VorLogin/Account verwalten/Name.h

@@ -0,0 +1,47 @@
+#ifndef Name_H
+#define Name_H
+
+#include <Knopf.h>
+#include <Fenster.h>
+#include <TextFeld.h>
+#include <Schrift.h>
+#include <Bildschirm.h>
+
+using namespace Framework;
+
+class NameVergessen
+{
+private:
+	Knopf *nameVergessen;
+	Fenster *fenster;
+	TextFeld *passwort;
+	TextFeld *geheimnis;
+	Knopf *weiter;
+	TextFeld *nachricht;
+	int ref;
+	void zeigeNachricht( const char *txt );
+
+public:
+	// Konstruktor
+	NameVergessen( Schrift *zSchrift, Fenster *zVorLoginFenster );
+	// Destruktor
+	~NameVergessen();
+	// Knopfdruck
+	void druckFremdKnopf(); // Ein anderer Knopf wurde gedrückt
+	bool nameVergessenME( void *obj, MausEreignis me ); // MausEreignis im Knopf nameVergessen
+	bool passwortTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld passwort
+	bool geheimnisTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld geheimnis
+	bool weiterME( void *obj, MausEreignis me ); // MausEreignis im Knopf weiter
+	void setResult( bool ret ); // Setzt den Returnwert
+	// Reference Counting
+	NameVergessen *getThis();
+	NameVergessen *release();
+};
+
+// messages
+bool nameVergessenNameVergessenME( void *p, void *obj, MausEreignis me );
+bool nameVergessenPasswortTE( void *p, void *obj, TastaturEreignis te );
+bool nameVergessenGeheimnisTE( void *p, void *obj, TastaturEreignis te );
+bool nameVergessenWeiterME( void *p, void *obj, MausEreignis me );
+
+#endif

+ 610 - 0
KSGClient/VorLogin/Account verwalten/Passwort.cpp

@@ -0,0 +1,610 @@
+#include "..\..\Global\Variablen.h"
+#include "Passwort.h"
+#include "..\..\Global\Initialisierung.h"
+#include <Punkt.h>
+#include <Text.h>
+
+// Inhalt der PasswortÄndern Klasse aus Passwort.h
+// Konstruktor
+PasswortÄndern::PasswortÄndern( Schrift *zSchrift, Fenster *zVorLoginFenster )
+{
+	Punkt bildschirmmitte = Bildschirmmitte();
+	passwortÄndern = initKnopf( 10, 170, 130, 30, zSchrift, Knopf::Style::Sichtbar, "Passwort ändern" );
+	passwortÄndern->setMausEreignisParameter( this );
+	passwortÄndern->setMausEreignis( passwortÄndernPasswortÄndernME );
+	initToolTip( passwortÄndern, "Account Passwort ändern.", zSchrift->getThis(), hauptScreen );
+	zVorLoginFenster->addMember( passwortÄndern );
+	fenster = initFenster( bildschirmmitte.x - 125, bildschirmmitte.y - 115, 250, 230, zSchrift, Fenster::Style::Erlaubt | Fenster::Style::Rahmen | Fenster::Style::Titel | Fenster::Style::TitelBuffered, "Passwort ändern" );
+	name = initTextFeld( 20, 20, 208, 20, zSchrift, TextFeld::Style::TextFeld, "Name" );
+	name->setTastaturEreignisParameter( this );
+	name->setTastaturEreignis( passwortÄndernNameTE );
+	initToolTip( name, "Account Name.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( name );
+	passwort = initTextFeld( 20, 50, 208, 20, zSchrift, TextFeld::Style::TextFeld, "Passwort" );
+	passwort->setTastaturEreignisParameter( this );
+	passwort->setTastaturEreignis( passwortÄndernPasswortTE );
+	initToolTip( passwort, "Account Passwort.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( passwort );
+	neuPasswort = initTextFeld( 20, 80, 208, 20, zSchrift, TextFeld::Style::TextFeld, "neues Passwort" );
+	neuPasswort->setTastaturEreignisParameter( this );
+	neuPasswort->setTastaturEreignis( passwortÄndernNeuPasswortTE );
+	initToolTip( neuPasswort, "Neues Account Passwort.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( neuPasswort );
+	neuPasswort2 = initTextFeld( 20, 110, 208, 20, zSchrift, TextFeld::Style::TextFeld, "Passwort wiederholen" );
+	neuPasswort2->setTastaturEreignisParameter( this );
+	neuPasswort2->setTastaturEreignis( passwortÄndernNeuPasswort2TE );
+	initToolTip( neuPasswort2, "Neues Passwort Wiederhohlen.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( neuPasswort2 );
+	geheimnis = initTextFeld( 20, 140, 208, 20, zSchrift, TextFeld::Style::TextFeld, "Geheimis" );
+	geheimnis->setTastaturEreignisParameter( this );
+	geheimnis->setTastaturEreignis( passwortÄndernGeheimnisTE );
+	initToolTip( geheimnis, "Account Geheimnis.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( geheimnis );
+	weiter = initKnopf( 74, 170, 100, 20, zSchrift, Knopf::Style::Sichtbar, "weiter" );
+	weiter->setMausEreignisParameter( this );
+	weiter->setMausEreignis( passwortÄndernWeiterME );
+	nachricht = initTextFeld( 0, 5, 255, 150, zSchrift, TextFeld::Style::HCenter | TextFeld::Style::Mehrzeilig, "" );
+	fenster->addMember( nachricht );
+	fenster->addMember( weiter );
+	zVorLoginFenster->addMember( fenster );
+	ref = 1;
+}
+
+// Destruktor
+PasswortÄndern::~PasswortÄndern()
+{
+	if( passwortÄndern )
+		passwortÄndern = passwortÄndern->release();
+	if( fenster )
+		fenster = fenster->release();
+	if( name )
+		name = name->release();
+	if( passwort )
+		passwort = passwort->release();
+	if( neuPasswort )
+		neuPasswort = neuPasswort->release();
+	if( neuPasswort2 )
+		neuPasswort2 = neuPasswort2->release();
+	if( geheimnis )
+		geheimnis = geheimnis->release();
+	if( weiter )
+		weiter = weiter->release();
+	if( nachricht )
+		nachricht = nachricht->release();
+}
+
+// Privat
+void PasswortÄndern::zeigeNachricht( const char *txt )
+{
+	Punkt bildschirmmitte = Bildschirmmitte();
+	name->removeStyle( TextFeld::Style::Sichtbar );
+	passwort->removeStyle( TextFeld::Style::Sichtbar );
+	neuPasswort->removeStyle( TextFeld::Style::Sichtbar );
+	neuPasswort2->removeStyle( TextFeld::Style::Sichtbar );
+	geheimnis->removeStyle( TextFeld::Style::Sichtbar );
+	fenster->setSize( 250, 150 );
+	fenster->setPosition( bildschirmmitte.x - 125, bildschirmmitte.y - 75 );
+	weiter->setPosition( 139, 100 );
+	weiter->setText( "Ok" );
+	nachricht->setText( txt );
+	if( nachricht->zText()->getLength() > 30 )
+	{
+		int pos = -1;
+		bool set = 0;
+		int lastp = 0;
+		for( int i = 20; i < nachricht->zText()->getLength(); )
+		{
+			char *tmp = &nachricht->zText()->getText()[ i ];
+			while( *tmp != ' ' && i < nachricht->zText()->getLength() )
+			{
+				tmp++;
+				i++;
+				if( i - 30 >= lastp )
+				{
+					if( set )
+					{
+						lastp = pos;
+						set = 0;
+						nachricht->zText()->getText()[ pos ] = '\n';
+					}
+					else
+						lastp += 5;
+				}
+			}
+			if( i < nachricht->zText()->getLength() )
+			{
+				pos = i;
+				set = 1;
+				tmp++;
+				i++;
+			}
+		}
+	}
+	nachricht->addStyle( TextFeld::Style::Sichtbar );
+}
+
+// Knopfdruck
+void PasswortÄndern::druckFremdKnopf() // Ein anderer Knopf wurde gedrückt
+{
+	fenster->removeStyle( Fenster::Style::Sichtbar );
+	registerKlient->trenne();
+	passwortÄndern->setLinienRahmenBreite( 2 );
+	passwortÄndern->setAlphaFeldFarbe( 0x5500FF00 );
+	passwortÄndern->setAlphaFeldStrength( -5 );
+}
+
+bool PasswortÄndern::passwortÄndernME( void *obj, MausEreignis me ) // MausEreignis im Knopf passwortVergessen
+{
+	if( me.id == ME_RLinks )
+	{
+		vorLogin->setPasswortÄndern();
+
+		passwortÄndern->setLinienRahmenBreite( 3 );
+		passwortÄndern->setAlphaFeldFarbe( 0xFF000000 );
+		passwortÄndern->setAlphaFeldStrength( 20 );
+		Punkt bildschirmmitte = Bildschirmmitte();
+		fenster->setSize( 255, 230 );
+		fenster->setPosition( bildschirmmitte.x - 125, bildschirmmitte.y - 115 );
+		fenster->addStyle( Fenster::Style::Sichtbar );
+		nachricht->removeStyle( TextFeld::Style::Sichtbar );
+		weiter->setText( "weiter" );
+		weiter->setPosition( 75, 170 );
+		name->addStyle( TextFeld::Style::Sichtbar );
+		passwort->addStyle( TextFeld::Style::Sichtbar );
+		neuPasswort->addStyle( TextFeld::Style::Sichtbar );
+		neuPasswort2->addStyle( TextFeld::Style::Sichtbar );
+		geheimnis->addStyle( TextFeld::Style::Sichtbar );
+		name->addStyle( TextFeld::Style::Fokus );
+		name->setAuswahl( name->zText()->getLength(), 0 );
+	}
+	return 1;
+}
+
+bool PasswortÄndern::nameTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld name
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Release && ( te.taste == T_Enter || te.taste == T_Tab ) )
+	{
+		name->removeStyle( TextFeld::Style::Fokus );
+		passwort->addStyle( TextFeld::Style::Fokus );
+		passwort->setAuswahl( passwort->zText()->getLength(), 0 );
+	}
+	if( name->zText()->getLength() >= 25 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool PasswortÄndern::passwortTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld passwort
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Press )
+		passwort->setSchowChar( '*' );
+	if( te.id == TE_Release && ( te.taste == T_Enter || te.taste == T_Tab ) )
+	{
+		passwort->removeStyle( TextFeld::Style::Fokus );
+		neuPasswort->addStyle( TextFeld::Style::Fokus );
+		neuPasswort->setAuswahl( neuPasswort->zText()->getLength(), 0 );
+	}
+	if( passwort->zText()->getLength() >= 25 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool PasswortÄndern::neuPasswortTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld neuPasswort
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Press )
+		neuPasswort->setSchowChar( '*' );
+	if( te.id == TE_Release && ( te.taste == T_Enter || te.taste == T_Tab ) )
+	{
+		neuPasswort->removeStyle( TextFeld::Style::Fokus );
+		neuPasswort2->addStyle( TextFeld::Style::Fokus );
+		neuPasswort2->setAuswahl( neuPasswort2->zText()->getLength(), 0 );
+	}
+	if( neuPasswort->zText()->getLength() >= 25 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool PasswortÄndern::neuPasswort2TE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld neuPasswort2
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Press )
+		neuPasswort2->setSchowChar( '*' );
+	if( te.id == TE_Release && ( te.taste == T_Enter || te.taste == T_Tab ) )
+	{
+		neuPasswort2->removeStyle( TextFeld::Style::Fokus );
+		geheimnis->addStyle( TextFeld::Style::Fokus );
+		geheimnis->setAuswahl( geheimnis->zText()->getLength(), 0 );
+	}
+	if( neuPasswort2->zText()->getLength() >= 25 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool PasswortÄndern::geheimnisTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld geheimnis
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Press )
+		geheimnis->setSchowChar( '*' );
+	if( te.id == TE_Release && te.taste == T_Enter )
+	{
+		geheimnis->removeStyle( TextFeld::Style::Fokus );
+		MausEreignis me;
+		me.id = ME_RLinks;
+		weiterME( 0, me );
+	}
+	if( geheimnis->zText()->getLength() >= 50 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool PasswortÄndern::weiterME( void *obj, MausEreignis me ) // MausEreignis im Knopf weiter
+{
+	if( me.id == ME_RLinks )
+	{
+		if( weiter->zText()->istGleich( "weiter" ) )
+		{
+			if( name->zText()->getLength() == 0 )
+				zeigeNachricht( "Bitte gebe deinen Accountnamen ein." );
+			if( passwort->zText()->getLength() == 0 )
+				zeigeNachricht( "Bitte gebe dein Accountpasswort ein." );
+			if( neuPasswort->zText()->getLength() == 0 )
+				zeigeNachricht( "Bitte gebe ein neues Passwort ein." );
+			if( geheimnis->zText()->getLength() == 0 )
+				zeigeNachricht( "Bitte gebe dein Accountgeheimnis ein." );
+			if( !neuPasswort2->zText()->istGleich( neuPasswort->zText()->getText() ) )
+				zeigeNachricht( "Das wiederhohlte Passwort stimmt nicht mit dem neuen Passwort überein." );
+			if( weiter->zText()->istGleich( "Ok" ) )
+				return 1;
+			new AktionsThread( 13, name->zText()->getText(), passwort->zText()->getText(), geheimnis->zText()->getText(), neuPasswort->zText()->getText(), 0 );
+		}
+		else
+		{
+			Punkt bildschirmmitte = Bildschirmmitte();
+			fenster->setSize( 255, 230 );
+			fenster->setPosition( bildschirmmitte.x - 125, bildschirmmitte.y - 115 );
+			fenster->addStyle( Fenster::Style::Sichtbar );
+			nachricht->removeStyle( TextFeld::Style::Sichtbar );
+			weiter->setText( "weiter" );
+			weiter->setPosition( 75, 170 );
+			name->addStyle( TextFeld::Style::Sichtbar );
+			passwort->addStyle( TextFeld::Style::Sichtbar );
+			neuPasswort->addStyle( TextFeld::Style::Sichtbar );
+			neuPasswort2->addStyle( TextFeld::Style::Sichtbar );
+			geheimnis->addStyle( TextFeld::Style::Sichtbar );
+			name->addStyle( TextFeld::Style::Fokus );
+			name->setAuswahl( name->zText()->getLength(), 0 );
+		}
+	}
+	return 1;
+}
+
+void PasswortÄndern::setResult( bool ret ) // Setzt den Returnwert
+{
+	if( ret )
+		zeigeNachricht( "Passwort erfolgreich geändert." );
+	else if( registerKlient->getLetzterFehler() )
+		zeigeNachricht( registerKlient->getLetzterFehler() );
+	else
+		zeigeNachricht( "Es ist ein Unbekannter Fehler aufgetreten." );
+}
+
+// Reference Counting
+PasswortÄndern *PasswortÄndern::getThis()
+{
+	ref++;
+	return this;
+}
+
+PasswortÄndern *PasswortÄndern::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Inhalt der PasswortVergessen Klasse aus Passwort.h
+// Konstruktor
+PasswortVergessen::PasswortVergessen( Schrift *zSchrift, Fenster *zVorLoginFenster )
+{
+	Punkt bildschirmmitte = Bildschirmmitte();
+	passwortVergessen = initKnopf( 10, 330, 130, 30, zSchrift, Knopf::Style::Sichtbar, "Passwort vergessen" );
+	passwortVergessen->setMausEreignisParameter( this );
+	passwortVergessen->setMausEreignis( passwortVergessenPasswortVergessenME );
+	initToolTip( passwortVergessen, "Account Passwort per E-Mail senden.", zSchrift->getThis(), hauptScreen );
+	zVorLoginFenster->addMember( passwortVergessen );
+	fenster = initFenster( bildschirmmitte.x - 125, bildschirmmitte.y - 70, 250, 140, zSchrift, Fenster::Style::Erlaubt | Fenster::Style::Rahmen | Fenster::Style::Titel | Fenster::Style::TitelBuffered, "Passwort vergessen" );
+	name = initTextFeld( 20, 20, 208, 20, zSchrift, TextFeld::Style::TextFeld, "Name" );
+	name->setTastaturEreignisParameter( this );
+	name->setTastaturEreignis( passwortVergessenNameTE );
+	initToolTip( name, "Account Name.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( name );
+	geheimnis = initTextFeld( 20, 50, 208, 20, zSchrift, TextFeld::Style::TextFeld, "Geheimis" );
+	geheimnis->setTastaturEreignisParameter( this );
+	geheimnis->setTastaturEreignis( passwortVergessenGeheimnisTE );
+	initToolTip( geheimnis, "Account geheimnis.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( geheimnis );
+	weiter = initKnopf( 74, 80, 100, 20, zSchrift, Knopf::Style::Sichtbar, "weiter" );
+	weiter->setMausEreignisParameter( this );
+	weiter->setMausEreignis( passwortVergessenWeiterME );
+	nachricht = initTextFeld( 0, 5, 255, 150, zSchrift, TextFeld::Style::HCenter | TextFeld::Style::Mehrzeilig, "" );
+	fenster->addMember( nachricht );
+	fenster->addMember( weiter );
+	zVorLoginFenster->addMember( fenster );
+	ref = 1;
+}
+
+// Destruktor
+PasswortVergessen::~PasswortVergessen()
+{
+	if( passwortVergessen )
+		passwortVergessen = passwortVergessen->release();
+	if( fenster )
+		fenster = fenster->release();
+	if( name )
+		name = name->release();
+	if( geheimnis )
+		geheimnis = geheimnis->release();
+	if( weiter )
+		weiter = weiter->release();
+	if( nachricht )
+		nachricht = nachricht->release();
+}
+
+// Privat
+void PasswortVergessen::zeigeNachricht( const char *txt )
+{
+	Punkt bildschirmmitte = Bildschirmmitte();
+	name->removeStyle( TextFeld::Style::Sichtbar );
+	geheimnis->removeStyle( TextFeld::Style::Sichtbar );
+	fenster->setSize( 250, 150 );
+	fenster->setPosition( bildschirmmitte.x - 125, bildschirmmitte.y - 75 );
+	weiter->setPosition( 139, 100 );
+	weiter->setText( "Ok" );
+	nachricht->setText( txt );
+	if( nachricht->zText()->getLength() > 30 )
+	{
+		int pos = -1;
+		bool set = 0;
+		int lastp = 0;
+		for( int i = 20; i < nachricht->zText()->getLength(); )
+		{
+			char *tmp = &nachricht->zText()->getText()[ i ];
+			while( *tmp != ' ' && i < nachricht->zText()->getLength() )
+			{
+				tmp++;
+				i++;
+				if( i - 30 >= lastp )
+				{
+					if( set )
+					{
+						lastp = pos;
+						set = 0;
+						nachricht->zText()->getText()[ pos ] = '\n';
+					}
+					else
+						lastp += 5;
+				}
+			}
+			if( i < nachricht->zText()->getLength() )
+			{
+				pos = i;
+				set = 1;
+				tmp++;
+				i++;
+			}
+		}
+	}
+	nachricht->addStyle( TextFeld::Style::Sichtbar );
+}
+
+// Knopfdruck
+void PasswortVergessen::druckFremdKnopf() // Ein anderer Knopf wurde gedrückt
+{
+	fenster->removeStyle( Fenster::Style::Sichtbar );
+	registerKlient->trenne();
+	passwortVergessen->setLinienRahmenBreite( 2 );
+	passwortVergessen->setAlphaFeldFarbe( 0x5500FF00 );
+	passwortVergessen->setAlphaFeldStrength( -5 );
+}
+
+bool PasswortVergessen::passwortVergessenME( void *obj, MausEreignis me ) // MausEreignis im Knopf passwortVergessen
+{
+	if( me.id == ME_RLinks )
+	{
+		vorLogin->setPasswortVergessen();
+
+		passwortVergessen->setLinienRahmenBreite( 3 );
+		passwortVergessen->setAlphaFeldFarbe( 0xFF000000 );
+		passwortVergessen->setAlphaFeldStrength( 20 );
+		Punkt bildschirmmitte = Bildschirmmitte();
+		fenster->setSize( 255, 140 );
+		fenster->setPosition( bildschirmmitte.x - 125, bildschirmmitte.y - 70 );
+		fenster->addStyle( Fenster::Style::Sichtbar );
+		nachricht->removeStyle( TextFeld::Style::Sichtbar );
+		weiter->setText( "weiter" );
+		weiter->setPosition( 75, 80 );
+		name->addStyle( TextFeld::Style::Sichtbar );
+		geheimnis->addStyle( TextFeld::Style::Sichtbar );
+		name->addStyle( TextFeld::Style::Fokus );
+		name->setAuswahl( name->zText()->getLength(), 0 );
+	}
+	return 1;
+}
+
+bool PasswortVergessen::nameTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld name
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Release && ( te.taste == T_Enter || te.taste == T_Tab ) )
+	{
+		name->removeStyle( TextFeld::Style::Fokus );
+		geheimnis->addStyle( TextFeld::Style::Fokus );
+		geheimnis->setAuswahl( geheimnis->zText()->getLength(), 0 );
+	}
+	if( name->zText()->getLength() >= 25 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool PasswortVergessen::geheimnisTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld geheimnis
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Press )
+		geheimnis->setSchowChar( '*' );
+	if( te.id == TE_Release && te.taste == T_Enter )
+	{
+		geheimnis->removeStyle( TextFeld::Style::Fokus );
+		MausEreignis me;
+		me.id = ME_RLinks;
+		weiterME( 0, me );
+	}
+	if( geheimnis->zText()->getLength() >= 50 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool PasswortVergessen::weiterME( void *obj, MausEreignis me ) // MausEreignis im Knopf weiter
+{
+	if( me.id == ME_RLinks )
+	{
+		if( weiter->zText()->istGleich( "weiter" ) )
+		{
+			if( name->zText()->getLength() == 0 )
+				zeigeNachricht( "Bitte gebe deinen Accountnamen ein." );
+			if( geheimnis->zText()->getLength() == 0 )
+				zeigeNachricht( "Bitte gebe dein Accountgeheimnis ein." );
+			if( weiter->zText()->istGleich( "Ok" ) )
+				return 1;
+			new AktionsThread( 14, name->zText()->getText(), geheimnis->zText()->getText(), 0, 0, 0 );
+		}
+		else
+		{
+			Punkt bildschirmmitte = Bildschirmmitte();
+			fenster->setSize( 255, 140 );
+			fenster->setPosition( bildschirmmitte.x - 125, bildschirmmitte.y - 70 );
+			fenster->addStyle( Fenster::Style::Sichtbar );
+			nachricht->removeStyle( TextFeld::Style::Sichtbar );
+			weiter->setText( "weiter" );
+			weiter->setPosition( 75, 80 );
+			name->addStyle( TextFeld::Style::Sichtbar );
+			geheimnis->addStyle( TextFeld::Style::Sichtbar );
+			name->addStyle( TextFeld::Style::Fokus );
+			name->setAuswahl( name->zText()->getLength(), 0 );
+		}
+	}
+	return 1;
+}
+
+void PasswortVergessen::setResult( bool ret ) // Setzt den Returnwert
+{
+	if( ret )
+		zeigeNachricht( "Dir wurde eine E-Mail mit deinem Accountpasswort gesendet." );
+	else if( registerKlient->getLetzterFehler() )
+		zeigeNachricht( registerKlient->getLetzterFehler() );
+	else
+		zeigeNachricht( "Es ist ein Unbekannter Fehler aufgetreten." );
+}
+
+// Reference Counting
+PasswortVergessen *PasswortVergessen::getThis()
+{
+	ref++;
+	return this;
+}
+
+PasswortVergessen *PasswortVergessen::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// messages
+bool passwortÄndernPasswortÄndernME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (PasswortÄndern*)p )->passwortÄndernME( obj, me );
+}
+
+bool passwortÄndernNameTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (PasswortÄndern*)p )->nameTE( obj, te );
+}
+
+bool passwortÄndernPasswortTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (PasswortÄndern*)p )->passwortTE( obj, te );
+}
+
+bool passwortÄndernNeuPasswortTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (PasswortÄndern*)p )->neuPasswortTE( obj, te );
+}
+
+bool passwortÄndernNeuPasswort2TE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (PasswortÄndern*)p )->neuPasswort2TE( obj, te );
+}
+
+bool passwortÄndernGeheimnisTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (PasswortÄndern*)p )->geheimnisTE( obj, te );
+}
+
+bool passwortÄndernWeiterME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (PasswortÄndern*)p )->weiterME( obj, me );
+}
+
+
+bool passwortVergessenPasswortVergessenME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (PasswortVergessen*)p )->passwortVergessenME( obj, me );
+}
+
+bool passwortVergessenNameTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (PasswortVergessen*)p )->nameTE( obj, te );
+}
+
+bool passwortVergessenGeheimnisTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (PasswortVergessen*)p )->geheimnisTE( obj, te );
+}
+
+bool passwortVergessenWeiterME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (PasswortVergessen*)p )->weiterME( obj, me );
+}

+ 93 - 0
KSGClient/VorLogin/Account verwalten/Passwort.h

@@ -0,0 +1,93 @@
+#ifndef Passwort_H
+#define Passwort_H
+
+#include <Knopf.h>
+#include <Fenster.h>
+#include <TextFeld.h>
+#include <MausEreignis.h>
+#include <TastaturEreignis.h>
+#include <Schrift.h>
+#include <Bildschirm.h>
+#include "..\..\Aktionen\AktionsThread.h"
+
+using namespace Framework;
+
+class PasswortÄndern
+{
+private:
+	Knopf *passwortÄndern;
+	Fenster *fenster;
+	TextFeld *name;
+	TextFeld *passwort;
+	TextFeld *neuPasswort;
+	TextFeld *neuPasswort2;
+	TextFeld *geheimnis;
+	Knopf *weiter;
+	TextFeld *nachricht;
+	int ref;
+	void zeigeNachricht( const char *txt );
+
+public:
+	// Konstruktor
+	PasswortÄndern( Schrift *zSchrift, Fenster *zVorLoginFenster );
+	// Destruktor
+	~PasswortÄndern();
+	// Knopfdruck
+	void druckFremdKnopf(); // Ein anderer Knopf wurde gedrückt
+	bool passwortÄndernME( void *obj, MausEreignis me ); // MausEreignis im Knopf passwortVergessen
+	bool nameTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld name
+	bool passwortTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld passwort
+	bool neuPasswortTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld neuPasswort
+	bool neuPasswort2TE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld neuPasswort2
+	bool geheimnisTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld geheimnis
+	bool weiterME( void *obj, MausEreignis me ); // MausEreignis im Knopf weiter
+	void setResult( bool ret ); // Setzt den Returnwert
+	// Reference Counting
+	PasswortÄndern *getThis();
+	PasswortÄndern *release();
+};
+
+class PasswortVergessen
+{
+private:
+	Knopf *passwortVergessen;
+	Fenster *fenster;
+	TextFeld *name;
+	TextFeld *geheimnis;
+	Knopf *weiter;
+	TextFeld *nachricht;
+	int ref;
+	void zeigeNachricht( const char *txt );
+
+public:
+	// Konstruktor
+	PasswortVergessen( Schrift *zSchrift, Fenster *zVorLoginFenster );
+	// Destruktor
+	~PasswortVergessen();
+	// Knopfdruck
+	void druckFremdKnopf(); // Ein anderer Knopf wurde gedrückt
+	bool passwortVergessenME( void *obj, MausEreignis me ); // MausEreignis im Knopf passwortVergessen
+	bool nameTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld name
+	bool geheimnisTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld geheimnis
+	bool weiterME( void *obj, MausEreignis me ); // MausEreignis im Knopf weiter
+	void setResult( bool ret ); // Setzt den Returnwert
+	// Reference Counting
+	PasswortVergessen *getThis();
+	PasswortVergessen *release();
+};
+
+// messages
+bool passwortÄndernPasswortÄndernME( void *p, void *obj, MausEreignis me );
+bool passwortÄndernNameTE( void *p, void *obj, TastaturEreignis te );
+bool passwortÄndernPasswortTE( void *p, void *obj, TastaturEreignis te );
+bool passwortÄndernNeuPasswortTE( void *p, void *obj, TastaturEreignis te );
+bool passwortÄndernNeuPasswort2TE( void *p, void *obj, TastaturEreignis te );
+bool passwortÄndernGeheimnisTE( void *p, void *obj, TastaturEreignis te );
+bool passwortÄndernWeiterME( void *p, void *obj, MausEreignis me );
+
+bool passwortVergessenPasswortVergessenME( void *p, void *obj, MausEreignis me );
+bool passwortVergessenNameTE( void *p, void *obj, TastaturEreignis te );
+bool passwortVergessenGeheimnisTE( void *p, void *obj, TastaturEreignis te );
+bool passwortVergessenWeiterME( void *p, void *obj, MausEreignis me );
+
+#endif

+ 637 - 0
KSGClient/VorLogin/Account verwalten/Registrierung.cpp

@@ -0,0 +1,637 @@
+#include "..\..\Global\Variablen.h"
+#include "..\..\Global\Initialisierung.h"
+#include "Registrierung.h"
+#include <Punkt.h>
+#include <Text.h>
+#include <Zeit.h>
+
+// Inhalt der Registrierung Klasse aus Registrierung.h
+// Konstruktor 
+Registrierung::Registrierung( Schrift *zSchrift, Fenster *zVorLoginFenster )
+{
+	Punkt bildschirmGröße = BildschirmGröße();
+	registrierung = initKnopf( 10, 90, 130, 30, zSchrift, Knopf::Style::Sichtbar, "Registrieren" );
+	registrierung->setMausEreignisParameter( this );
+	registrierung->setMausEreignis( registrierungRegistrierungME );
+	initToolTip( registrierung, "Account erstellen.", zSchrift->getThis(), hauptScreen );
+	zVorLoginFenster->addMember( registrierung );
+	fenster = initFenster( bildschirmGröße.x / 2 - 175, bildschirmGröße.y / 2 - 131, 350, 262, zSchrift, Fenster::Style::Erlaubt | Fenster::Style::Rahmen | Fenster::Style::Titel | Fenster::Style::TitelBuffered, "Account erstellen" );
+	name = initTextFeld( 74, 20, 200, 20, zSchrift, TextFeld::Style::TextFeld, "Account Name" );
+	name->setTastaturEreignisParameter( this );
+	name->setTastaturEreignis( registrierungNameTE );
+	initToolTip( name, "Account Name.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( name );
+	passwort = initTextFeld( 74, 50, 200, 20, zSchrift, TextFeld::Style::TextFeld, "Account Passwort" );
+	passwort->setTastaturEreignisParameter( this );
+	passwort->setTastaturEreignis( registrierungPasswortTE );
+	initToolTip( passwort, "Account Passwort.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( passwort );
+	passwort2 = initTextFeld( 74, 80, 200, 20, zSchrift, TextFeld::Style::TextFeld, "Passwort wiederholen" );
+	passwort2->setTastaturEreignisParameter( this );
+	passwort2->setTastaturEreignis( registrierungPasswort2TE );
+	initToolTip( passwort2, "Account Passwort wiederhohlen.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( passwort2 );
+	geheimnis = initTextFeld( 10, 110, 328, 20, zSchrift, TextFeld::Style::TextFeld, "Account Geheimnis" );
+	geheimnis->setTastaturEreignisParameter( this );
+	geheimnis->setTastaturEreignis( registrierungGeheimnisTE );
+	initToolTip( geheimnis, "Gib etwas ein, was nur du jederzeit weißt.\n(zweites sicherheitspasswort Passwort)", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( geheimnis );
+	eMail = initTextFeld( 74, 140, 200, 20, zSchrift, TextFeld::Style::TextFeld, "E-Mail Addresse" );
+	eMail->setTastaturEreignisParameter( this );
+	eMail->setTastaturEreignis( registrierungEMailTE );
+	initToolTip( eMail, "E-Mail Addresse.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( eMail );
+	geburtsdatum = initTextFeld( 40, 170, 85, 20, zSchrift, TextFeld::Style::Text, "Geburtsdatum:" );
+	fenster->addMember( geburtsdatum );
+	gbdTag = new AuswahlBox();
+	gbdTag->setStyle( AuswahlBox::Style::Sichtbar | AuswahlBox::Style::Erlaubt | AuswahlBox::Style::Rahmen | AuswahlBox::Style::MausBuffer | AuswahlBox::Style::AuswahlBuffer | AuswahlBox::Style::MaxHeight | AuswahlBox::Style::VScroll | AuswahlBox::Style::Hintergrund );
+	gbdTag->setPosition( 130, 167 );
+	gbdTag->setSize( 50, 20 );
+	gbdTag->setMaxAuskappHeight( 100 );
+	gbdTag->setSchriftZ( zSchrift->getThis() );
+	gbdTag->setLinienRahmenFarbe( 0xFFFFFFFF );
+	gbdTag->setHintergrundFarbe( 0xFF000000 );
+	gbdTag->setMausEreignis( _ret1ME );
+	gbdTag->addEintrag( "Tag" );
+	for( int i = 0; i < 31; i++ )
+	{
+		Text *txt = new Text( "" );
+		txt->append( i + 1 );
+		gbdTag->addEintrag( txt );
+	}
+	gbdMonat = new AuswahlBox();
+	gbdMonat->setStyle( AuswahlBox::Style::Sichtbar | AuswahlBox::Style::Erlaubt | AuswahlBox::Style::Rahmen | AuswahlBox::Style::MausBuffer | AuswahlBox::Style::AuswahlBuffer | AuswahlBox::Style::MaxHeight | AuswahlBox::Style::VScroll | AuswahlBox::Style::Hintergrund );
+	gbdMonat->setPosition( 185, 167 );
+	gbdMonat->setSize( 65, 20 );
+	gbdMonat->setMaxAuskappHeight( 100 );
+	gbdMonat->setSchriftZ( zSchrift->getThis() );
+	gbdMonat->setLinienRahmenFarbe( 0xFFFFFFFF );
+	gbdMonat->setHintergrundFarbe( 0xFF000000 );
+	gbdMonat->setMausEreignis( _ret1ME );
+	gbdMonat->addEintrag( "Monat" );
+	for( int i = 0; i < 12; i++ )
+	{
+		Text *txt = new Text( "" );
+		txt->append( i + 1 );
+		gbdMonat->addEintrag( txt );
+	}
+	gbdJahr = new AuswahlBox();
+	gbdJahr->setStyle( AuswahlBox::Style::Sichtbar | AuswahlBox::Style::Erlaubt | AuswahlBox::Style::Rahmen | AuswahlBox::Style::MausBuffer | AuswahlBox::Style::AuswahlBuffer | AuswahlBox::Style::MaxHeight | AuswahlBox::Style::VScroll | AuswahlBox::Style::Hintergrund );
+	gbdJahr->setPosition( 255, 167 );
+	gbdJahr->setSize( 55, 20 );
+	gbdJahr->setMaxAuskappHeight( 100 );
+	gbdJahr->setSchriftZ( zSchrift->getThis() );
+	gbdJahr->setLinienRahmenFarbe( 0xFFFFFFFF );
+	gbdJahr->setHintergrundFarbe( 0xFF000000 );
+	gbdJahr->setMausEreignis( _ret1ME );
+	gbdJahr->addEintrag( "Jahr" );
+	for( int i = 2013; i > 1913; i-- )
+	{
+		Text *txt = new Text( "" );
+		txt->append( i + 1 );
+		gbdJahr->addEintrag( txt );
+	}
+	weiter = initKnopf( 124, 200, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Weiter" );
+	weiter->setMausEreignisParameter( this );
+	weiter->setMausEreignis( registrierungWeiterME );
+	fenster->addMember( weiter );
+	später = initKnopf( 20, 115, 100, 20, zSchrift, 0, "Später" );
+	später->setMausEreignisParameter( this );
+	später->setMausEreignis( registrierungSpäterME );
+	initToolTip( später, "Vorgang später unter 'Bestätigung' abclose.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( später );
+	neuSenden = initKnopf( 129, 145, 100, 20, zSchrift, 0, "neu senden" );
+	neuSenden->setMausEreignisParameter( this );
+	neuSenden->setMausEreignis( registrierungNeuSendenME );
+	initToolTip( neuSenden, "E-Mail erneut senden.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( neuSenden );
+	text = initTextFeld( 0, 5, 250, 150, zSchrift, TextFeld::Style::Mehrzeilig | TextFeld::Style::HCenter, "" );
+	fenster->addMember( text );
+	schlüssel = initTextFeld( 25, 85, 200, 20, zSchrift, TextFeld::Style::TextFeld & ~TextFeld::Style::Sichtbar, "Schlüssel" );
+	schlüssel->setTastaturEreignisParameter( this );
+	schlüssel->setTastaturEreignis( registrierungSchlüsselTE );
+	initToolTip( schlüssel, "Zugeschickter Account Aktivierungsschlüssel.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( schlüssel );
+	fertig = initKnopf( 129, 115, 100, 20, zSchrift, 0, "Fertig" );
+	fertig->setMausEreignisParameter( this );
+	fertig->setMausEreignis( registrierungFertigME );
+	fenster->addMember( fertig );
+	zVorLoginFenster->addMember( fenster );
+	fenster->addMember( gbdTag );
+	fenster->addMember( gbdMonat );
+	fenster->addMember( gbdJahr );
+	ref = 1;
+}
+
+// Destruktor 
+Registrierung::~Registrierung()
+{
+	if( fenster )
+		fenster = fenster->release();
+	if( name )
+		name = name->release();
+	if( passwort )
+		passwort = passwort->release();
+	if( passwort2 )
+		passwort2 = passwort2->release();
+	if( geheimnis )
+		geheimnis = geheimnis->release();
+	if( eMail )
+		eMail = eMail->release();
+	if( geburtsdatum )
+		geburtsdatum = geburtsdatum->release();
+	if( gbdTag )
+		gbdTag = gbdTag->release();
+	if( gbdMonat )
+		gbdMonat = gbdMonat->release();
+	if( gbdJahr )
+		gbdJahr = gbdJahr->release();
+	if( weiter )
+		weiter = weiter->release();
+	if( text )
+		text = text->release();
+	if( schlüssel )
+		schlüssel = schlüssel->release();
+	if( später )
+		später = später->release();
+	if( neuSenden )
+		neuSenden = neuSenden->release();
+	if( fertig )
+		fertig = fertig->release();
+	if( registrierung )
+		registrierung = registrierung->release();
+}
+
+// Privat
+void Registrierung::zeigeNachricht( const char *txt )
+{
+	Punkt bildschirmmitte = Bildschirmmitte();
+	name->removeStyle( TextFeld::Style::Sichtbar );
+	passwort->removeStyle( TextFeld::Style::Sichtbar );
+	passwort2->removeStyle( TextFeld::Style::Sichtbar );
+	geheimnis->removeStyle( TextFeld::Style::Sichtbar );
+	eMail->removeStyle( TextFeld::Style::Sichtbar );
+	geburtsdatum->removeStyle( TextFeld::Style::Sichtbar );
+	gbdTag->removeStyle( TextFeld::Style::Sichtbar );
+	gbdMonat->removeStyle( TextFeld::Style::Sichtbar );
+	gbdJahr->removeStyle( TextFeld::Style::Sichtbar );
+	schlüssel->removeStyle( TextFeld::Style::Sichtbar );
+	später->removeStyle( Knopf::Style::Sichtbar );
+	fertig->removeStyle( Knopf::Style::Sichtbar );
+	neuSenden->removeStyle( Knopf::Style::Sichtbar );
+	fenster->setSize( 250, 150 );
+	fenster->setPosition( bildschirmmitte.x - 125, bildschirmmitte.y - 75 );
+	weiter->setPosition( 139, 100 );
+	weiter->setText( "Ok" );
+	text->setText( txt );
+	if( text->zText()->getLength() > 30 )
+	{
+		int pos = -1;
+		bool set = 0;
+		int lastp = 0;
+		for( int i = 20; i < text->zText()->getLength(); )
+		{
+			char *tmp = &text->zText()->getText()[ i ];
+			while( *tmp != ' ' && i < text->zText()->getLength() )
+			{
+				tmp++;
+				i++;
+				if( i - 30 >= lastp )
+				{
+					if( set )
+					{
+						lastp = pos;
+						set = 0;
+						text->zText()->getText()[ pos ] = '\n';
+					}
+					else
+						lastp += 5;
+				}
+			}
+			if( i < text->zText()->getLength() )
+			{
+				pos = i;
+				set = 1;
+				tmp++;
+				i++;
+			}
+		}
+	}
+	text->addStyle( TextFeld::Style::Sichtbar );
+}
+
+// Knopfdruck
+void Registrierung::druckFremdKnopf() // Ein anderer Knopfwurde gedrückt
+{
+	fenster->removeStyle( Fenster::Style::Sichtbar );
+	registerKlient->trenne();
+	registrierung->setLinienRahmenBreite( 2 );
+	registrierung->setAlphaFeldFarbe( 0x5500FF00 );
+	registrierung->setAlphaFeldStrength( -5 );
+}
+
+bool Registrierung::nameTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld name
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Release && ( te.taste == T_Enter || te.taste == T_Tab ) )
+	{
+		name->removeStyle( TextFeld::Style::Fokus );
+		passwort->addStyle( TextFeld::Style::Fokus );
+		passwort->setAuswahl( passwort->zText()->getLength(), 0 );
+	}
+	if( name->zText()->getLength() >= 25 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool Registrierung::passwortTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld passwort
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Press )
+		passwort->setSchowChar( '*' );
+	if( te.id == TE_Release && ( te.taste == T_Enter || te.taste == T_Tab ) )
+	{
+		passwort->removeStyle( TextFeld::Style::Fokus );
+		passwort2->addStyle( TextFeld::Style::Fokus );
+		passwort2->setAuswahl( passwort2->zText()->getLength(), 0 );
+	}
+	if( passwort->zText()->getLength() >= 25 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool Registrierung::passwort2TE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld passwort2
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Press )
+		passwort2->setSchowChar( '*' );
+	if( te.id == TE_Release && ( te.taste == T_Enter || te.taste == T_Tab ) )
+	{
+		passwort2->removeStyle( TextFeld::Style::Fokus );
+		geheimnis->addStyle( TextFeld::Style::Fokus );
+		geheimnis->setAuswahl( geheimnis->zText()->getLength(), 0 );
+	}
+	if( passwort2->zText()->getLength() >= 25 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool Registrierung::geheimnisTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld geheimnis
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Release && ( te.taste == T_Enter || te.taste == T_Tab ) )
+	{
+		geheimnis->removeStyle( TextFeld::Style::Fokus );
+		eMail->addStyle( TextFeld::Style::Fokus );
+		eMail->setAuswahl( eMail->zText()->getLength(), 0 );
+	}
+	if( geheimnis->zText()->getLength() - abs( geheimnis->getCursorPos() - geheimnis->getSelectionPos() ) >= 50 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool Registrierung::eMailTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld eMail
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Release && ( te.taste == T_Enter || te.taste == T_Tab ) )
+	{
+		eMail->removeStyle( TextFeld::Style::Fokus );
+		gbdTag->addStyle( AuswahlBox::Style::Fokus );
+	}
+	if( eMail->zText()->getLength() >= 50 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool Registrierung::weiterME( void *obj, MausEreignis me ) // MausEreignis im Knopf weiter
+{
+	if( me.id == ME_RLinks )
+	{
+		Punkt bildchirmGröße = BildschirmGröße();
+		if( schlüssel->hatStyle( TextFeld::Style::Sichtbar ) )
+		{
+			text->removeStyle( TextFeld::Style::Sichtbar );
+			schlüssel->removeStyle( TextFeld::Style::Sichtbar );
+			fertig->removeStyle( Knopf::Style::Sichtbar );
+			später->removeStyle( Knopf::Style::Sichtbar );
+            neuSenden->removeStyle( Knopf::Style::Sichtbar );
+			weiter->setPosition( 124, 200 );
+			weiter->setText( "Weiter" );
+			fenster->setSize( 350, 262 );
+			fenster->setPosition( bildchirmGröße.x / 2 - 175, bildchirmGröße.y / 2 - 131 );
+			fenster->setTitel( "Account erstellen" );
+			name->addStyle( TextFeld::Style::Sichtbar );
+			passwort->addStyle( TextFeld::Style::Sichtbar );
+			passwort2->addStyle( TextFeld::Style::Sichtbar );
+			geheimnis->addStyle( TextFeld::Style::Sichtbar );
+			eMail->addStyle( TextFeld::Style::Sichtbar );
+			geburtsdatum->addStyle( TextFeld::Style::Sichtbar );
+			gbdTag->addStyle( TextFeld::Style::Sichtbar );
+			gbdMonat->addStyle( TextFeld::Style::Sichtbar );
+			gbdJahr->addStyle( TextFeld::Style::Sichtbar );
+			registerKlient->abbrechen();
+			name->addStyle( TextFeld::Style::Fokus );
+			name->setAuswahl( name->zText()->getLength(), 0 );
+		}
+		else
+		{
+			if( weiter->zText()->istGleich( "Ok" ) )
+			{
+				if( fenster->zTitel()->istGleich( "Account erstellen" ) )
+				{
+					text->removeStyle( TextFeld::Style::Sichtbar );
+					weiter->setPosition( 124, 200 );
+					weiter->setText( "Weiter" );
+					fenster->setSize( 350, 262 );
+					fenster->setPosition( bildchirmGröße.x / 2 - 175, bildchirmGröße.y / 2 - 131 );
+					name->addStyle( TextFeld::Style::Sichtbar );
+					passwort->addStyle( TextFeld::Style::Sichtbar );
+					passwort2->addStyle( TextFeld::Style::Sichtbar );
+					geheimnis->addStyle( TextFeld::Style::Sichtbar );
+					eMail->addStyle( TextFeld::Style::Sichtbar );
+					geburtsdatum->addStyle( TextFeld::Style::Sichtbar );
+					gbdTag->addStyle( TextFeld::Style::Sichtbar );
+					gbdMonat->addStyle( TextFeld::Style::Sichtbar );
+					gbdJahr->addStyle( TextFeld::Style::Sichtbar );
+					name->addStyle( TextFeld::Style::Fokus );
+					name->setAuswahl( name->zText()->getLength(), 0 );
+				}
+				else
+				{
+					weiter->setPosition( 20, 145 );
+					weiter->setText( "Abbrechen" );
+					text->setText( "Dir wurde eine E-Mail mit einem\naktivierungsode zugeschickt,\nden du in den nächsten 12 Stunden\nhier eingeben musst." );
+					fenster->setSize( 250, 200 );
+					fenster->setPosition( bildchirmGröße.x / 2 - 125, bildchirmGröße.y / 2 - 100 );
+					schlüssel->addStyle( TextFeld::Style::Sichtbar );
+					fertig->addStyle( Knopf::Style::Sichtbar );
+					später->addStyle( Knopf::Style::Sichtbar );
+					neuSenden->addStyle( Knopf::Style::Sichtbar );
+					schlüssel->addStyle( TextFeld::Style::Fokus );
+					schlüssel->setAuswahl( schlüssel->zText()->getLength(), 0 );
+				}
+			}
+			else if( passwort2->zText()->istGleich( passwort->zText()->getText() ) )
+			{
+				if( name->zText()->getLength() == 0 ||
+					passwort->zText()->getLength() == 0 ||
+					geheimnis->zText()->getLength() == 0 ||
+					eMail->zText()->getLength() == 0 )
+				{
+					if( name->zText()->getLength() == 0 )
+						zeigeNachricht( "Bitte gebe einen Accountnamen ein." );
+					else if( passwort->zText()->getLength() == 0 )
+						zeigeNachricht( "Bitte gebe ein Accountpasswort ein." );
+					else if( geheimnis->zText()->getLength() == 0 )
+						zeigeNachricht( "Bitte gebe ein Accountgeheimnis ein. Dieß wird benötig, wenn du deinen Accountnamen oder dein Accountpasswort vergisst." );
+					else if( eMail->zText()->getLength() == 0 )
+						zeigeNachricht( "Bitte gebe deine E-Mail Addresse ein. Diese benötigen wir, um dir den Bestätigungscode für deinen Account zu senden." );
+					return 1;
+				}
+				Datum *gebDat = new Datum();
+				gebDat->setDatum( 1, 1, 1 );
+				bool ok = 1;
+				do
+				{
+					if( !gbdTag->getAuswahl() || !gbdMonat->getAuswahl() || !gbdJahr->getAuswahl() )
+					{
+						ok = 0;
+						break;
+					}
+					int jahr = TextZuInt( gbdJahr->zEintrag( gbdJahr->getAuswahl() )->zText()->getText(), 10 );
+					gebDat->setJahr( jahr );
+					gebDat->setMonat( gbdMonat->getAuswahl() );
+					gebDat->setTag( gbdTag->getAuswahl() );
+					if( jahr != gebDat->getJahr() || gbdMonat->getAuswahl() != gebDat->getMonat() || gbdTag->getAuswahl() != gebDat->getTag() )
+					{
+						ok = 0;
+						break;
+					}
+				}
+				while( 0 );
+				if( ok )
+					new AktionsThread( 15, name->zText()->getText(), passwort->zText()->getText(), geheimnis->zText()->getText(), eMail->zText()->getText(), gebDat->getThis() );
+				else
+					zeigeNachricht( "Bitte gebe ein gültiges Geburtsdatum an." );
+				gebDat = gebDat->release();
+			}
+			else
+				zeigeNachricht( "Das wiederhohlte Passwort stimmt nicht mit dem Passwort überein." );
+		}
+	}
+	return 1;
+}
+
+bool Registrierung::schlüsselTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld schlüssel
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Release && te.taste == T_Enter )
+	{
+		schlüssel->removeStyle( TextFeld::Style::Fokus );
+		MausEreignis me;
+		me.id = ME_RLinks;
+		fertigME( 0, me );
+	}
+	if( schlüssel->zText()->getLength() >= 20 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool Registrierung::fertigME( void *obj, MausEreignis me ) // MausEreignis im Knopf fertig
+{
+	if( me.id == ME_RLinks )
+		new AktionsThread( 16, schlüssel->zText()->getText(), 0, 0, 0, 0 );
+	return 1;
+}
+
+bool Registrierung::späterME( void *obj, MausEreignis me ) // MausEreignis im Knopf später
+{
+	if( me.id == ME_RLinks )
+	{
+		fenster->setTitel( "Account erstellen" );
+		zeigeNachricht( "Du kannst den Vorgang nun später unter 'Bestätigung' vollenden." );
+	}
+	return 1;
+}
+
+bool Registrierung::neuSendenME( void *obj, MausEreignis me ) // MausEreignis im Knopf neuSenden
+{
+	if( me.id == ME_RLinks )
+		registerKlient->eMailErneutSenden();
+	return 1;
+}
+
+bool Registrierung::registrierungME( void *obj, MausEreignis me ) // MausEreignis im Knopf registrierung
+{
+	if( me.id == ME_RLinks )
+	{
+		vorLogin->setRegistrierung();
+		fenster->addStyle( Fenster::Style::Sichtbar );
+		registrierung->setLinienRahmenBreite( 3 );
+		registrierung->setAlphaFeldFarbe( 0xFF000000 );
+		registrierung->setAlphaFeldStrength( 20 );
+
+		if( schlüssel->hatStyle( TextFeld::Style::Sichtbar ) )
+			registerKlient->abbrechen();
+		Punkt bildchirmGröße = BildschirmGröße();
+		text->removeStyle( TextFeld::Style::Sichtbar );
+		schlüssel->removeStyle( TextFeld::Style::Sichtbar );
+		fertig->removeStyle( Knopf::Style::Sichtbar );
+		später->removeStyle( Knopf::Style::Sichtbar );
+		neuSenden->removeStyle( Knopf::Style::Sichtbar );
+		weiter->setPosition( 124, 200 );
+		weiter->setText( "Weiter" );
+		fenster->setSize( 350, 262 );
+		fenster->setPosition( bildchirmGröße.x / 2 - 175, bildchirmGröße.y / 2 - 131 );
+		fenster->setTitel( "Account erstellen" );
+		name->addStyle( TextFeld::Style::Sichtbar );
+		passwort->addStyle( TextFeld::Style::Sichtbar );
+		passwort2->addStyle( TextFeld::Style::Sichtbar );
+		geheimnis->addStyle( TextFeld::Style::Sichtbar );
+		eMail->addStyle( TextFeld::Style::Sichtbar );
+		geburtsdatum->addStyle( TextFeld::Style::Sichtbar );
+		gbdTag->addStyle( TextFeld::Style::Sichtbar );
+		gbdMonat->addStyle( TextFeld::Style::Sichtbar );
+		gbdJahr->addStyle( TextFeld::Style::Sichtbar );
+		name->addStyle( TextFeld::Style::Fokus );
+		name->setAuswahl( name->zText()->getLength(), 0 );
+	}
+	return 1;
+}
+
+void Registrierung::setWeiterReturn( bool ret ) // setzt den Weiter Returnwert
+{
+	Punkt bildchirmGröße = BildschirmGröße();
+	if( ret )
+	{
+		name->removeStyle( TextFeld::Style::Sichtbar );
+		passwort->removeStyle( TextFeld::Style::Sichtbar );
+		passwort2->removeStyle( TextFeld::Style::Sichtbar );
+		geheimnis->removeStyle( TextFeld::Style::Sichtbar );
+		eMail->removeStyle( TextFeld::Style::Sichtbar );
+		geburtsdatum->removeStyle( TextFeld::Style::Sichtbar );
+		gbdTag->removeStyle( TextFeld::Style::Sichtbar );
+		gbdMonat->removeStyle( TextFeld::Style::Sichtbar );
+		gbdJahr->removeStyle( TextFeld::Style::Sichtbar );
+		fenster->setSize( 250, 200 );
+		fenster->setPosition( bildchirmGröße.x / 2 - 125, bildchirmGröße.y / 2 - 100 );
+		fenster->setTitel( "Account aktivieren" );
+		weiter->setPosition( 20, 145 );
+		weiter->setText( "Abbrechen" );
+		text->setText( "Dir wurde eine E-Mail mit einem\naktivierungsode zugeschickt,\nden du in den nächsten 12 Stunden\nhier eingeben musst." );
+		text->addStyle( TextFeld::Style::Sichtbar );
+		schlüssel->addStyle( TextFeld::Style::Sichtbar );
+		später->addStyle( Knopf::Style::Sichtbar );
+		neuSenden->addStyle( Knopf::Style::Sichtbar );
+		fertig->addStyle( Knopf::Style::Sichtbar );
+	}
+	else if( registerKlient->getLetzterFehler() )
+		zeigeNachricht( registerKlient->getLetzterFehler() );
+}
+
+void Registrierung::setFertigReturn( bool ret ) // setzt den Fertig Returnwert
+{
+	if( ret )
+		vorLogin->setLogin( 0 );
+	else
+		zeigeNachricht( "Falscher Schlüssel." );
+}
+
+// Reference Counting
+Registrierung *Registrierung::getThis()
+{
+	ref++;
+	return this;
+}
+
+Registrierung *Registrierung::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Ereignisse
+bool registrierungNameTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (Registrierung*)p )->nameTE( obj, te );
+}
+
+bool registrierungPasswortTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (Registrierung*)p )->passwortTE( obj, te );
+}
+
+bool registrierungPasswort2TE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (Registrierung*)p )->passwort2TE( obj, te );
+}
+
+bool registrierungGeheimnisTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (Registrierung*)p )->geheimnisTE( obj, te );
+}
+
+bool registrierungEMailTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (Registrierung*)p )->eMailTE( obj, te );
+}
+
+bool registrierungWeiterME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (Registrierung*)p )->weiterME( obj, me );
+}
+
+bool registrierungSchlüsselTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (Registrierung*)p )->schlüsselTE( obj, te );
+}
+
+bool registrierungFertigME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (Registrierung*)p )->fertigME( obj, me );
+}
+
+bool registrierungSpäterME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (Registrierung*)p )->späterME( obj, me );
+}
+
+bool registrierungNeuSendenME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (Registrierung*)p )->neuSendenME( obj, me );
+}
+
+bool registrierungRegistrierungME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (Registrierung*)p )->registrierungME( obj, me );
+}

+ 76 - 0
KSGClient/VorLogin/Account verwalten/Registrierung.h

@@ -0,0 +1,76 @@
+#ifndef Registrierung_H
+#define Registrierung_H
+
+#include <Fenster.h>
+#include <TextFeld.h>
+#include <Knopf.h>
+#include <TastaturEreignis.h>
+#include <MausEreignis.h>
+#include <Schrift.h>
+#include <Bildschirm.h>
+#include <AuswahlBox.h>
+#include "..\..\Aktionen\AktionsThread.h"
+
+using namespace Framework;
+
+class Registrierung
+{
+private:
+	Fenster *fenster;
+	TextFeld *text;
+	TextFeld *name;
+	TextFeld *passwort;
+	TextFeld *passwort2;
+	TextFeld *geheimnis;
+	TextFeld *eMail;
+	TextFeld *geburtsdatum;
+	AuswahlBox *gbdJahr;
+	AuswahlBox *gbdMonat;
+	AuswahlBox *gbdTag;
+	Knopf *weiter;
+	TextFeld *schlüssel;
+	Knopf *fertig;
+	Knopf *später;
+	Knopf *neuSenden;
+	Knopf *registrierung;
+	int ref;
+	void zeigeNachricht( const char *txt );
+
+public:
+	// Konstruktor 
+	Registrierung( Schrift *zSchrift, Fenster *zVorLoginFenster );
+	// Destruktor 
+	~Registrierung();
+	// Knopfdruck
+	void druckFremdKnopf(); // Ein anderer Knopf wurde gedrückt
+	bool nameTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld name
+	bool passwortTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld passwort
+	bool passwort2TE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld passwort2
+	bool geheimnisTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld geheimnis
+	bool eMailTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld eMail
+	bool weiterME( void *obj, MausEreignis me ); // MausEreignis im Knopf weiter
+	bool schlüsselTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld schlüssel
+	bool fertigME( void *obj, MausEreignis me ); // MausEreignis im Knopf fertig
+	bool späterME( void *obj, MausEreignis me ); // MausEreignis im Knopf später
+	bool neuSendenME( void *obj, MausEreignis me ); // MausEreignis im Knopf neuSenden
+	bool registrierungME( void *obj, MausEreignis me ); // MausEreignis im Knopf registrierung
+	void setWeiterReturn( bool ret ); // setzt den Weiter Returnwert
+	void setFertigReturn( bool ret ); // setzt den Fertig Returnwert
+	// Reference Counting
+	Registrierung *getThis();
+	Registrierung *release();
+};
+
+bool registrierungNameTE( void *p, void *obj, TastaturEreignis te );
+bool registrierungPasswortTE( void *p, void *obj, TastaturEreignis te );
+bool registrierungPasswort2TE( void *p, void *obj, TastaturEreignis te );
+bool registrierungGeheimnisTE( void *p, void *obj, TastaturEreignis te );
+bool registrierungEMailTE( void *p, void *obj, TastaturEreignis te );
+bool registrierungWeiterME( void *p, void *obj, MausEreignis me );
+bool registrierungSchlüsselTE( void *p, void *obj, TastaturEreignis te );
+bool registrierungFertigME( void *p, void *obj, MausEreignis me );
+bool registrierungSpäterME( void *p, void *obj, MausEreignis me );
+bool registrierungNeuSendenME( void *p, void *obj, MausEreignis me );
+bool registrierungRegistrierungME( void *p, void *obj, MausEreignis me );
+
+#endif

+ 461 - 0
KSGClient/VorLogin/Account verwalten/Unregistrierung.cpp

@@ -0,0 +1,461 @@
+#include "..\..\Global\Variablen.h"
+#include "..\..\Global\Initialisierung.h"
+#include "Unregistrierung.h"
+#include <Text.h>
+#include <Punkt.h>
+
+// Inhalt der Unregistrierung Klasse aus Unregistrierung.h
+// Konstruktor 
+Unregistrierung::Unregistrierung( Schrift *zSchrift, Fenster *zVorLoginFenster )
+{
+	Punkt bildschirmGröße = BildschirmGröße();
+	unregistrierung = initKnopf( 10, 130, 130, 30, zSchrift, Knopf::Style::Sichtbar, "Account remove" );
+	unregistrierung->setMausEreignisParameter( this );
+	unregistrierung->setMausEreignis( unregistrierungUnregistrierungME );
+	initToolTip( unregistrierung, "Account für alle Zeiten entfernen.", zSchrift->getThis(), hauptScreen );
+	zVorLoginFenster->addMember( unregistrierung );
+	fenster = initFenster( bildschirmGröße.x / 2 - 125, bildschirmGröße.y / 2 - 85, 250, 170, zSchrift, Fenster::Style::Erlaubt | Fenster::Style::Rahmen | Fenster::Style::Titel | Fenster::Style::TitelBuffered, "Account remove" );
+	name = initTextFeld( 24, 20, 200, 20, zSchrift, TextFeld::Style::TextFeld, "Account Name" );
+	name->setTastaturEreignisParameter( this );
+	name->setTastaturEreignis( unregistrierungNameTE );
+	initToolTip( name, "Account Name eingeben.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( name );
+	passwort = initTextFeld( 24, 50, 200, 20, zSchrift, TextFeld::Style::TextFeld, "Account Passwort" );
+	passwort->setTastaturEreignisParameter( this );
+	passwort->setTastaturEreignis( unregistrierungPasswortTE );
+	initToolTip( passwort, "Account Passwort eingeben.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( passwort );
+	geheimnis = initTextFeld( 24, 80, 200, 20, zSchrift, TextFeld::Style::TextFeld, "Account Geheimnis" );
+	geheimnis->setTastaturEreignisParameter( this );
+	geheimnis->setTastaturEreignis( unregistrierungGeheimnisTE );
+	initToolTip( geheimnis, "Account Geheimnis eingeben.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( geheimnis );
+	weiter = initKnopf( 74, 110, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Weiter" );
+	weiter->setMausEreignisParameter( this );
+	weiter->setMausEreignis( unregistrierungWeiterME );
+	fenster->addMember( weiter );
+	text = initTextFeld( 0, 5, 250, 170, zSchrift, TextFeld::Style::Mehrzeilig | TextFeld::Style::HCenter, "" );
+	fenster->addMember( text );
+	schlüssel = initTextFeld( 25, 85, 200, 20, zSchrift, TextFeld::Style::TextFeld & ~TextFeld::Style::Sichtbar, "Schlüssel" );
+	schlüssel->setTastaturEreignisParameter( this );
+	schlüssel->setTastaturEreignis( unregistrierungSchlüsselTE );
+	initToolTip( schlüssel, "Zugeschickter Bestätigungsschlüssel.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( schlüssel );
+	später = initKnopf( 20, 145, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Später" );
+	später->setMausEreignisParameter( this );
+	später->setMausEreignis( unregistrierungSpäterME );
+	initToolTip( später, "Vorgang später unter 'Bestätigung' beenden.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( später );
+	neuSenden = initKnopf( 129, 145, 100, 20, zSchrift, Knopf::Style::Sichtbar, "neu senden" );
+	neuSenden->setMausEreignisParameter( this );
+	neuSenden->setMausEreignis( unregistrierungNeuSendenME );
+	initToolTip( neuSenden, "E-Mail erneut senden.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( neuSenden );
+	fertig = initKnopf( 129, 115, 100, 20, zSchrift, 0, "Fertig" );
+	fertig->setMausEreignisParameter( this );
+	fertig->setMausEreignis( unregistrierungFertigME );
+	fenster->addMember( fertig );
+	zVorLoginFenster->addMember( fenster );
+	ref = 1;
+}
+
+// Destruktor 
+Unregistrierung::~Unregistrierung()
+{
+	if( fenster )
+		fenster = fenster->release();
+	if( name )
+		name = name->release();
+	if( passwort )
+		passwort = passwort->release();
+	if( geheimnis )
+		geheimnis = geheimnis->release();
+	if( weiter )
+		weiter = weiter->release();
+	if( text )
+		text = text->release();
+	if( schlüssel )
+		schlüssel = schlüssel->release();
+	if( später )
+		später = später->release();
+	if( neuSenden )
+		neuSenden = neuSenden->release();
+	if( fertig )
+		fertig = fertig->release();
+	if( unregistrierung )
+		unregistrierung = unregistrierung->release();
+}
+
+// Privat
+void Unregistrierung::zeigeNachricht( const char *txt )
+{
+	Punkt bildschirmmitte = Bildschirmmitte();
+	name->removeStyle( TextFeld::Style::Sichtbar );
+	passwort->removeStyle( TextFeld::Style::Sichtbar );
+	geheimnis->removeStyle( TextFeld::Style::Sichtbar );
+	schlüssel->removeStyle( TextFeld::Style::Sichtbar );
+	später->removeStyle( Knopf::Style::Sichtbar );
+	fertig->removeStyle( Knopf::Style::Sichtbar );
+	neuSenden->removeStyle( Knopf::Style::Sichtbar );
+	fenster->setSize( 250, 150 );
+	fenster->setPosition( bildschirmmitte.x - 125, bildschirmmitte.y - 75 );
+	weiter->setPosition( 139, 100 );
+	weiter->setText( "Ok" );
+	text->setText( txt );
+	if( text->zText()->getLength() > 30 )
+	{
+		int pos = -1;
+		bool set = 0;
+		int lastp = 0;
+		for( int i = 20; i < text->zText()->getLength(); )
+		{
+			char *tmp = &text->zText()->getText()[ i ];
+			while( *tmp != ' ' && i < text->zText()->getLength() )
+			{
+				tmp++;
+				i++;
+				if( i - 30 >= lastp )
+				{
+					if( set )
+					{
+						lastp = pos;
+						set = 0;
+						text->zText()->getText()[ pos ] = '\n';
+					}
+					else
+						lastp += 5;
+				}
+			}
+			if( i < text->zText()->getLength() )
+			{
+				pos = i;
+				set = 1;
+				tmp++;
+				i++;
+			}
+		}
+	}
+	text->addStyle( TextFeld::Style::Sichtbar );
+}
+
+// Knopfdruck
+void Unregistrierung::druckFremdKnopf() // Ein anderer Knopfwurde gedrückt
+{
+	fenster->removeStyle( Fenster::Style::Sichtbar );
+	registerKlient->trenne();
+	unregistrierung->setLinienRahmenBreite( 2 );
+	unregistrierung->setAlphaFeldFarbe( 0x5500FF00 );
+	unregistrierung->setAlphaFeldStrength( -5 );
+}
+
+bool Unregistrierung::nameTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld name
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Release && ( te.taste == T_Enter || te.taste == T_Tab ) )
+	{
+		name->removeStyle( TextFeld::Style::Fokus );
+		passwort->addStyle( TextFeld::Style::Fokus );
+		passwort->setAuswahl( passwort->zText()->getLength(), 0 );
+	}
+	if( name->zText()->getLength() >= 25 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool Unregistrierung::passwortTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld passwort
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Press )
+		passwort->setSchowChar( '*' );
+	if( te.id == TE_Release && ( te.taste == T_Enter || te.taste == T_Tab ) )
+	{
+		passwort->removeStyle( TextFeld::Style::Fokus );
+		geheimnis->addStyle( TextFeld::Style::Fokus );
+		geheimnis->setAuswahl( geheimnis->zText()->getLength(), 0 );
+	}
+	if( passwort->zText()->getLength() >= 25 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool Unregistrierung::geheimnisTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld geheimnis
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Release && te.taste == T_Enter )
+	{
+		geheimnis->removeStyle( TextFeld::Style::Fokus );
+		MausEreignis me;
+		me.id = ME_RLinks;
+		weiterME( 0, me );
+	}
+	if( geheimnis->zText()->getLength() - abs( geheimnis->getCursorPos() - geheimnis->getSelectionPos() ) >= 50 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool Unregistrierung::weiterME( void *obj, MausEreignis me ) // MausEreignis im Knopf weiter
+{
+	if( me.id == ME_RLinks )
+	{
+		Punkt bildchirmGröße = BildschirmGröße();
+		if( schlüssel->hatStyle( TextFeld::Style::Sichtbar ) )
+		{
+			text->removeStyle( TextFeld::Style::Sichtbar );
+			schlüssel->removeStyle( TextFeld::Style::Sichtbar );
+			fertig->removeStyle( Knopf::Style::Sichtbar );
+			später->removeStyle( Knopf::Style::Sichtbar );
+			neuSenden->removeStyle( Knopf::Style::Sichtbar );
+			weiter->setPosition( 74, 110 );
+			weiter->setText( "Weiter" );
+			fenster->setSize( 250, 170 );
+			fenster->setPosition( bildchirmGröße.x / 2 - 125, bildchirmGröße.y / 2 - 85 );
+			fenster->setTitel( "Account remove" );
+			name->addStyle( TextFeld::Style::Sichtbar );
+			passwort->addStyle( TextFeld::Style::Sichtbar );
+			geheimnis->addStyle( TextFeld::Style::Sichtbar );
+			registerKlient->abbrechen();
+			name->addStyle( TextFeld::Style::Fokus );
+			name->setAuswahl( name->zText()->getLength(), 0 );
+		}
+		else
+		{
+			if( weiter->zText()->istGleich( "Ok" ) )
+			{
+				if( fenster->zTitel()->istGleich( "Account remove" ) )
+				{
+					text->removeStyle( TextFeld::Style::Sichtbar );
+					fenster->setSize( 250, 170 );
+					fenster->setPosition( bildchirmGröße.x / 2 - 125, bildchirmGröße.y / 2 - 85 );
+					weiter->setPosition( 74, 110 );
+					weiter->setText( "Weiter" );
+					name->addStyle( TextFeld::Style::Sichtbar );
+					passwort->addStyle( TextFeld::Style::Sichtbar );
+					geheimnis->addStyle( TextFeld::Style::Sichtbar );
+					name->addStyle( TextFeld::Style::Fokus );
+					name->setAuswahl( name->zText()->getLength(), 0 );
+				}
+				else
+				{
+					fenster->setSize( 250, 200 );
+					fenster->setPosition( bildchirmGröße.x / 2 - 125, bildchirmGröße.y / 2 - 100 );
+					weiter->setPosition( 20, 115 );
+					weiter->setText( "Abbrechen" );
+					text->setText( "Dir wurde eine E-Mail mit einem\ndeaktivierungsode zugeschickt,\nden du in den nächsten 12 Stunden\nhier eingeben musst." );
+					schlüssel->addStyle( TextFeld::Style::Sichtbar );
+					später->addStyle( Knopf::Style::Sichtbar );
+					neuSenden->addStyle( Knopf::Style::Sichtbar );
+					fertig->addStyle( Knopf::Style::Sichtbar );
+					schlüssel->addStyle( TextFeld::Style::Fokus );
+					schlüssel->setAuswahl( schlüssel->zText()->getLength(), 0 );
+				}
+			}
+			else
+			{
+				if( name->zText()->getLength() == 0 ||
+					passwort->zText()->getLength() == 0 ||
+					geheimnis->zText()->getLength() == 0 )
+				{
+					if( name->zText()->getLength() == 0 )
+						zeigeNachricht( "Bitte gebe deinen Accountnamen\nein." );
+					else if( passwort->zText()->getLength() == 0 )
+						zeigeNachricht( "Bitte gebe dein Accountpasswort\nein." );
+					else if( geheimnis->zText()->getLength() == 0 )
+						zeigeNachricht( "Bitte gebe dein Accountgeheimnis\nein." );
+					return 1;
+				}
+				new AktionsThread( 17, name->zText()->getText(), passwort->zText()->getText(), geheimnis->zText()->getText(), 0, 0 );
+			}
+		}
+	}
+	return 1;
+}
+
+bool Unregistrierung::schlüsselTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld schlüssel
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Release && te.taste == T_Enter )
+	{
+		schlüssel->removeStyle( TextFeld::Style::Fokus );
+		MausEreignis me;
+		me.id = ME_RLinks;
+		fertigME( 0, me );
+	}
+	if( schlüssel->zText()->getLength() >= 20 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool Unregistrierung::späterME( void *obj, MausEreignis me ) // MausEreignis im Knopf später
+{
+	if( me.id == ME_RLinks )
+	{
+		fenster->setTitel( "Account remove" );
+		zeigeNachricht( "Du kannst den Vorgang nun später unter 'Bestätigung' vollenden." );
+	}
+	return 1;
+}
+
+bool Unregistrierung::neuSendenME( void *obj, MausEreignis me ) // MausEreignis im Knopf neuSenden
+{
+	if( me.id == ME_RLinks )
+		registerKlient->eMailErneutSenden();
+	return 1;
+}
+
+bool Unregistrierung::fertigME( void *obj, MausEreignis me ) // MausEreignis im Knopf fertig
+{
+	if( me.id == ME_RLinks )
+		new AktionsThread( 18, schlüssel->zText()->getText(), 0, 0, 0, 0 );
+	return 1;
+}
+
+bool Unregistrierung::unregistrierungME( void *obj, MausEreignis me ) // MausEreignis im Knopf unregistrierung
+{
+	if( me.id == ME_RLinks )
+	{
+		vorLogin->setUnregistrierung();
+
+		fenster->addStyle( Fenster::Style::Sichtbar );
+		unregistrierung->setLinienRahmenBreite( 3 );
+		unregistrierung->setAlphaFeldFarbe( 0xFF000000 );
+		unregistrierung->setAlphaFeldStrength( 20 );
+
+		if( schlüssel->hatStyle( TextFeld::Style::Sichtbar ) )
+			registerKlient->abbrechen();
+		text->removeStyle( TextFeld::Style::Sichtbar );
+		schlüssel->removeStyle( TextFeld::Style::Sichtbar );
+		fertig->removeStyle( Knopf::Style::Sichtbar );
+		später->removeStyle( Knopf::Style::Sichtbar );
+		neuSenden->removeStyle( Knopf::Style::Sichtbar );
+		weiter->setPosition( 74, 110 );
+		weiter->setText( "Weiter" );
+		fenster->setTitel( "Account remove" );
+		fenster->setSize( 250, 170 );
+		Punkt bildchirmGröße = BildschirmGröße();
+		fenster->setPosition( bildchirmGröße.x / 2 - 125, bildchirmGröße.y / 2 - 85 );
+		name->addStyle( TextFeld::Style::Sichtbar );
+		passwort->addStyle( TextFeld::Style::Sichtbar );
+		geheimnis->addStyle( TextFeld::Style::Sichtbar );
+		name->addStyle( TextFeld::Style::Fokus );
+		name->setAuswahl( name->zText()->getLength(), 0 );
+	}
+	return 1;
+}
+
+void Unregistrierung::setWeiterReturn( bool ret ) // setzt den Weiter Returnwert
+{
+	Punkt bildchirmGröße = BildschirmGröße();
+	if( ret )
+	{
+		name->removeStyle( TextFeld::Style::Sichtbar );
+		passwort->removeStyle( TextFeld::Style::Sichtbar );
+		geheimnis->removeStyle( TextFeld::Style::Sichtbar );
+		fenster->setTitel( "Account deaktiveren" );
+		fenster->setSize( 250, 200 );
+		fenster->setPosition( bildchirmGröße.x / 2 - 125, bildchirmGröße.y / 2 - 100 );
+		weiter->setPosition( 20, 115 );
+		weiter->setText( "Abbrechen" );
+		text->setText( "Dir wurde eine E-Mail mit einem\ndeaktivierungsode zugeschickt,\nden du in den nächsten 12 Stunden\nhier eingeben musst." );
+		text->addStyle( TextFeld::Style::Sichtbar );
+		schlüssel->addStyle( TextFeld::Style::Sichtbar );
+		fertig->addStyle( Knopf::Style::Sichtbar );
+		später->addStyle( Knopf::Style::Sichtbar );
+		neuSenden->addStyle( Knopf::Style::Sichtbar );
+		schlüssel->addStyle( TextFeld::Style::Fokus );
+		schlüssel->setAuswahl( schlüssel->zText()->getLength(), 0 );
+	}
+	else if( registerKlient->getLetzterFehler() )
+		zeigeNachricht( registerKlient->getLetzterFehler() );
+}
+
+void Unregistrierung::setFertigReturn( bool ret ) // setzt den Fertig Returnwert
+{
+	if( ret )
+		vorLogin->setLogin( 0 );
+	else
+		zeigeNachricht( registerKlient->getLetzterFehler() );
+}
+
+// Reference Counting
+Unregistrierung *Unregistrierung::getThis()
+{
+	ref++;
+	return this;
+}
+
+Unregistrierung *Unregistrierung::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+
+// Ereignisse
+bool unregistrierungNameTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (Unregistrierung*)p )->nameTE( obj, te );
+}
+
+bool unregistrierungPasswortTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (Unregistrierung*)p )->passwortTE( obj, te );
+}
+
+bool unregistrierungGeheimnisTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (Unregistrierung*)p )->geheimnisTE( obj, te );
+}
+
+bool unregistrierungWeiterME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (Unregistrierung*)p )->weiterME( obj, me );
+}
+
+bool unregistrierungSchlüsselTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (Unregistrierung*)p )->schlüsselTE( obj, te );
+}
+
+bool unregistrierungSpäterME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (Unregistrierung*)p )->späterME( obj, me );
+}
+
+bool unregistrierungNeuSendenME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (Unregistrierung*)p )->neuSendenME( obj, me );
+}
+
+bool unregistrierungFertigME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (Unregistrierung*)p )->fertigME( obj, me );
+}
+
+bool unregistrierungUnregistrierungME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (Unregistrierung*)p )->unregistrierungME( obj, me );
+}

+ 66 - 0
KSGClient/VorLogin/Account verwalten/Unregistrierung.h

@@ -0,0 +1,66 @@
+#ifndef Unregistrierung_H
+#define Unregistrierung_H
+
+#include <Klient.h>
+#include <Fenster.h>
+#include <Knopf.h>
+#include <TextFeld.h>
+#include <MausEreignis.h>
+#include <TastaturEreignis.h>
+#include "..\..\Aktionen\AktionsThread.h"
+
+using namespace Framework;
+using namespace Network;
+
+class Unregistrierung
+{
+private:
+	Fenster *fenster;
+	TextFeld *name;
+	TextFeld *passwort;
+	TextFeld *geheimnis;
+	Knopf *weiter;
+	TextFeld *text;
+	TextFeld *schlüssel;
+	Knopf *fertig;
+	Knopf *später;
+	Knopf *neuSenden;
+	Knopf *unregistrierung;
+	int ref;
+	void zeigeNachricht( const char *txt );
+
+public:
+	// Konstruktor 
+	Unregistrierung( Schrift *zSchrift, Fenster *zVorLoginFenster );
+	// Destruktor 
+	~Unregistrierung();
+	// Knopfdruck
+	void druckFremdKnopf(); // Ein anderer Knopfwurde gedrückt
+	bool nameTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld name
+	bool passwortTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld passwort
+	bool geheimnisTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld geheimnis
+	bool weiterME( void *obj, MausEreignis me ); // MausEreignis im Knopf weiter
+	bool schlüsselTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld schlüssel
+	bool späterME( void *obj, MausEreignis me ); // MausEreignis im Knopf später
+	bool neuSendenME( void *obj, MausEreignis me ); // MausEreignis im Knopf neuSenden
+	bool fertigME( void *obj, MausEreignis me ); // MausEreignis im Knopf fertig
+	bool unregistrierungME( void *obj, MausEreignis me ); // MausEreignis im Knopf unregistrierung
+	void setWeiterReturn( bool ret ); // setzt den Weiter Returnwert
+	void setFertigReturn( bool ret ); // setzt den Fertig Returnwert
+	// Reference Counting
+	Unregistrierung *getThis();
+	Unregistrierung *release();
+};
+
+// Ereignisse
+bool unregistrierungNameTE( void *p, void *obj, TastaturEreignis te );
+bool unregistrierungPasswortTE( void *p, void *obj, TastaturEreignis te );
+bool unregistrierungGeheimnisTE( void *p, void *obj, TastaturEreignis te );
+bool unregistrierungWeiterME( void *p, void *obj, MausEreignis me );
+bool unregistrierungSchlüsselTE( void *p, void *obj, TastaturEreignis te );
+bool unregistrierungSpäterME( void *p, void *obj, MausEreignis me );
+bool unregistrierungNeuSendenME( void *p, void *obj, MausEreignis me );
+bool unregistrierungFertigME( void *p, void *obj, MausEreignis me );
+bool unregistrierungUnregistrierungME( void *p, void *obj, MausEreignis me );
+
+#endif

+ 406 - 0
KSGClient/VorLogin/Login/Login.cpp

@@ -0,0 +1,406 @@
+#include "..\..\Global\Variablen.h"
+#include "Login.h"
+#include "..\..\Global\Initialisierung.h"
+#include <Punkt.h>
+#include <Text.h>
+
+// Inhalt der Login Klasse aus Login.h
+// Konstruktor 
+Login::Login( Schrift *zSchrift, Fenster *vorLoginFenster )
+{
+	Punkt bildschirmGröße = BildschirmGröße();
+	login = initKnopf( 10, 50, 130, 30, zSchrift, Knopf::Style::Sichtbar, "Login" );
+	login->setMausEreignisParameter( this );
+	login->setMausEreignis( loginLoginME );
+	initToolTip( login, "Einloggen.", zSchrift->getThis(), hauptScreen );
+	vorLoginFenster->addMember( login );
+	fenster = initFenster( bildschirmGröße.x / 2 - 125, bildschirmGröße.y / 2 - 75, 250, 150, zSchrift, Fenster::Style::Sichtbar | Fenster::Style::Erlaubt | Fenster::Style::Rahmen | Fenster::Style::Titel | Fenster::Style::TitelBuffered, "Login" );
+	name = initTextFeld( 20, 20, 208, 20, zSchrift, TextFeld::Style::TextFeld, "Name" );
+	name->setTastaturEreignisParameter( this );
+	name->setTastaturEreignis( loginNameTE );
+	initToolTip( name, "Account Name.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( name );
+	passwort = initTextFeld( 20, 55, 208, 20, zSchrift, TextFeld::Style::TextFeld, "Passwort" );
+	passwort->setTastaturEreignisParameter( this );
+	passwort->setTastaturEreignis( loginPasswortTE );
+	initToolTip( passwort, "Account Passwort.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( passwort );
+	weiter = initKnopf( 75, 90, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Login" );
+	weiter->setMausEreignisParameter( this );
+	weiter->setMausEreignis( loginWeiterME );
+	fenster->addMember( weiter );
+	nachricht = initTextFeld( 5, 5, 238, 50, zSchrift, TextFeld::Style::HCenter | TextFeld::Style::Mehrzeilig, "" );
+	fenster->addMember( nachricht );
+	geheimnis = initTextFeld( 20, 55, 208, 20, zSchrift, TextFeld::Style::TextFeld, "Geheimnis" );
+	geheimnis->removeStyle( TextFeld::Style::Sichtbar );
+	geheimnis->setTastaturEreignisParameter( this );
+	geheimnis->setTastaturEreignis( loginGeheimnisTE );
+	initToolTip( geheimnis, "Account Geheimnis.", zSchrift->getThis(), hauptScreen );
+	fenster->addMember( geheimnis );
+	abbrechen = initKnopf( 10, 98, 100, 20, zSchrift, 0, "Abbrechen" );
+	abbrechen->setMausEreignisParameter( this );
+	abbrechen->setMausEreignis( loginAbbrechenME );
+	fenster->addMember( abbrechen );
+	ok = initKnopf( 138, 98, 100, 20, zSchrift, 0, "Ok" );
+	ok->setMausEreignisParameter( this );
+	ok->setMausEreignis( loginOkME );
+	fenster->addMember( ok );
+	vorLoginFenster->addMember( fenster );
+	MausEreignis me;
+	me.id = ME_RLinks;
+	loginME( 0, me );
+	ref = 1;
+}
+
+// Destruktor 
+Login::~Login()
+{
+	if( fenster )
+		fenster = fenster->release();
+	if( name )
+		name = name->release();
+	if( passwort )
+		passwort = passwort->release();
+	if( nachricht )
+		nachricht = nachricht->release();
+	if( geheimnis )
+		geheimnis = geheimnis->release();
+	if( weiter )
+		weiter = weiter->release();
+	if( abbrechen )
+		abbrechen = abbrechen->release();
+	if( ok )
+		ok = ok->release();
+	if( login )
+		login = login->release();
+}
+
+// Knopfdruck
+void Login::druckFremdKnopf() // Ein anderer Bereich des Programms wurde ausgewählt
+{
+	fenster->removeStyle( Fenster::Style::Sichtbar );
+	loginKlient->trenne();
+	login->setLinienRahmenBreite( 2 );
+	login->setAlphaFeldFarbe( 0x5500FF00 );
+	login->setAlphaFeldStrength( -5 );
+}
+
+bool Login::nameTE( void *obj, TastaturEreignis te ) // Tastaturereignis im Textfeld name
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Release && ( te.taste == T_Enter || te.taste == T_Tab ) )
+	{
+		name->removeStyle( TextFeld::Style::Fokus );
+		passwort->addStyle( TextFeld::Style::Fokus );
+		passwort->setAuswahl( passwort->zText()->getLength(), 0 );
+	}
+	if( name->zText()->getLength() >= 25 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool Login::passwortTE( void *obj, TastaturEreignis te ) // TastaturEreignis im Textfeld passwort
+{
+	if( te.id == TE_Press )
+		passwort->setSchowChar( '*' );
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Release && te.taste == T_Enter )
+	{
+		passwort->removeStyle( TextFeld::Style::Fokus );
+		MausEreignis me;
+		me.id = ME_RLinks;
+		weiterME( 0, me );
+	}
+	if( passwort->zText()->getLength() >= 25 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool Login::geheimnisTE( void *obj, TastaturEreignis te ) // TastaturEreignis im Textfeld geheimnis
+{
+	if( te.id == TE_Press && te.taste == T_Enter )
+		return 0;
+	if( te.id == TE_Press )
+		geheimnis->setSchowChar( '*' );
+	if( te.id == TE_Release && te.taste == T_Enter )
+	{
+		geheimnis->removeStyle( TextFeld::Style::Fokus );
+		MausEreignis me;
+		me.id = ME_RLinks;
+		okME( 0, me );
+	}
+	if( geheimnis->zText()->getLength() >= 50 && istSchreibbar( te.taste ) )
+		return 0;
+	return 1;
+}
+
+bool Login::weiterME( void *obj, MausEreignis me ) // MausEreignis im Knopf weiter
+{
+	if( me.id == ME_RLinks )
+	{
+		if( name->zText()->getLength() == 0 )
+		{
+			name->removeStyle( TextFeld::Style::Sichtbar );
+			passwort->removeStyle( TextFeld::Style::Sichtbar );
+			weiter->removeStyle( Knopf::Style::Sichtbar );
+			nachricht->setText( "Bitte trage deinen Accountnamen\nein." );
+			nachricht->addStyle( TextFeld::Style::Sichtbar );
+			ok->addStyle( Knopf::Style::Sichtbar );
+			return 1;
+		}
+		if( passwort->zText()->getLength() == 0 )
+		{
+			name->removeStyle( TextFeld::Style::Sichtbar );
+			passwort->removeStyle( TextFeld::Style::Sichtbar );
+			weiter->removeStyle( Knopf::Style::Sichtbar );
+			nachricht->setText( "Bitte trage dein Passwort ein." );
+			nachricht->addStyle( TextFeld::Style::Sichtbar );
+			ok->addStyle( Knopf::Style::Sichtbar );
+			return 1;
+		}
+		new AktionsThread( 1, name->zText()->getText(), passwort->zText()->getText(), 0, 0, 0 );
+	}
+	return 1;
+}
+
+bool Login::okME( void *obj, MausEreignis me ) // MausEreignis im Knopf ok
+{
+	if( me.id == ME_RLinks )
+	{
+		if( geheimnis->hatStyle( TextFeld::Style::Sichtbar ) )
+			new AktionsThread( 3, geheimnis->zText()->getText(), 0, 0, 0, 0 );
+		else
+		{
+			nachricht->removeStyle( TextFeld::Style::Sichtbar );
+			geheimnis->removeStyle( TextFeld::Style::Sichtbar );
+			ok->removeStyle( Knopf::Style::Sichtbar );
+			abbrechen->removeStyle( Knopf::Style::Sichtbar );
+			name->addStyle( TextFeld::Style::Sichtbar );
+			passwort->addStyle( TextFeld::Style::Sichtbar );
+			weiter->addStyle( TextFeld::Style::Sichtbar );
+			name->addStyle( TextFeld::Style::Fokus );
+			name->setAuswahl( name->zText()->getLength(), 0 );
+		}
+	}
+	return 1;
+}
+
+bool Login::abbrechenME( void *obj, MausEreignis me ) // MausEreignis im Knopf abbrechen
+{
+	if( me.id == ME_RLinks )
+	{
+		nachricht->removeStyle( TextFeld::Style::Sichtbar );
+		geheimnis->removeStyle( TextFeld::Style::Sichtbar );
+		ok->removeStyle( Knopf::Style::Sichtbar );
+		abbrechen->removeStyle( Knopf::Style::Sichtbar );
+		name->addStyle( TextFeld::Style::Sichtbar );
+		passwort->addStyle( TextFeld::Style::Sichtbar );
+		weiter->addStyle( TextFeld::Style::Sichtbar );
+		name->addStyle( TextFeld::Style::Fokus );
+		name->setAuswahl( name->zText()->getLength(), 0 );
+	}
+	return 1;
+}
+
+bool Login::loginME( void *obj, MausEreignis me ) // MausEreignis im Knopf login
+{
+	if( me.id == ME_RLinks )
+	{
+		vorLogin->setLogin( 1 );
+
+		nachricht->removeStyle( TextFeld::Style::Sichtbar );
+		geheimnis->removeStyle( TextFeld::Style::Sichtbar );
+		ok->removeStyle( Knopf::Style::Sichtbar );
+		abbrechen->removeStyle( Knopf::Style::Sichtbar );
+		fenster->addStyle( Fenster::Style::Sichtbar );
+		name->addStyle( TextFeld::Style::Sichtbar );
+		passwort->addStyle( TextFeld::Style::Sichtbar );
+		weiter->addStyle( TextFeld::Style::Sichtbar );
+
+		login->setLinienRahmenBreite( 3 );
+		login->setAlphaFeldFarbe( 0xFF000000 );
+		login->setAlphaFeldStrength( 20 );
+		name->addStyle( TextFeld::Style::Fokus );
+		name->setAuswahl( name->zText()->getLength(), 0 );
+	}
+	return 1;
+}
+
+void Login::setLoginReturn( int ret ) // setzt den Returnwert vom login
+{
+	if( ret == 1 )
+		new AktionsThread( 2, 0, 0, 0, 0, 0 );
+	else if( ret == 2 )
+	{
+		name->removeStyle( TextFeld::Style::Sichtbar );
+		passwort->removeStyle( TextFeld::Style::Sichtbar );
+		weiter->removeStyle( Knopf::Style::Sichtbar );
+		nachricht->setText( "Der Account ist bereits online.\nGebe dein Account Geheimnis ein,\num den anderen Benutzer zu kicken." );
+		nachricht->addStyle( TextFeld::Style::Sichtbar );
+		geheimnis->addStyle( TextFeld::Style::Sichtbar );
+		ok->addStyle( Knopf::Style::Sichtbar );
+		abbrechen->addStyle( Knopf::Style::Sichtbar );
+		geheimnis->addStyle( TextFeld::Style::Fokus );
+		geheimnis->setAuswahl( geheimnis->zText()->getLength(), 0 );
+	}
+	else if( !ret && loginKlient->getLetzterFehler() )
+	{
+		name->removeStyle( TextFeld::Style::Sichtbar );
+		passwort->removeStyle( TextFeld::Style::Sichtbar );
+		weiter->removeStyle( Knopf::Style::Sichtbar );
+		nachricht->setText( loginKlient->getLetzterFehler() );
+		if( nachricht->zText()->getLength() > 30 )
+		{
+			int pos = -1;
+			bool set = 0;
+			int lastp = 0;
+			for( int i = 20; i < nachricht->zText()->getLength(); )
+			{
+				char *tmp = &nachricht->zText()->getText()[ i ];
+				while( *tmp != ' ' && i < nachricht->zText()->getLength() )
+				{
+					tmp++;
+					i++;
+					if( i - 30 >= lastp )
+					{
+						if( set )
+						{
+							lastp = pos;
+							set = 0;
+							nachricht->zText()->getText()[ pos ] = '\n';
+						}
+						else
+							lastp += 5;
+					}
+				}
+				if( i < nachricht->zText()->getLength() )
+				{
+					pos = i;
+					set = 1;
+					tmp++;
+					i++;
+				}
+			}
+		}
+		nachricht->addStyle( TextFeld::Style::Sichtbar );
+		ok->addStyle( Knopf::Style::Sichtbar );
+	}
+}
+
+void Login::setKickReturn( int ret ) // setzt den returnwert vom kick
+{
+	if( ret == 1 )
+		new AktionsThread( 2, 0, 0, 0, 0, 0 );
+	else if( ret == 2 )
+	{
+		nachricht->setText( loginKlient->getLetzterFehler() );
+		if( nachricht->zText()->getLength() > 30 )
+		{
+			int pos = -1;
+			bool set = 0;
+			int lastp = 0;
+			for( int i = 20; i < nachricht->zText()->getLength(); )
+			{
+				char *tmp = &nachricht->zText()->getText()[ i ];
+				while( *tmp != ' ' && i < nachricht->zText()->getLength() )
+				{
+					tmp++;
+					i++;
+					if( i - 30 >= lastp )
+					{
+						if( set )
+						{
+							lastp = pos;
+							set = 0;
+							nachricht->zText()->getText()[ pos ] = '\n';
+						}
+						else
+							lastp += 5;
+					}
+				}
+				if( i < nachricht->zText()->getLength() )
+				{
+					pos = i;
+					set = 1;
+					tmp++;
+					i++;
+				}
+			}
+		}
+		geheimnis->removeStyle( TextFeld::Style::Sichtbar );
+		abbrechen->removeStyle( Knopf::Style::Sichtbar );
+	}
+	else if( !ret )
+	{
+		nachricht->setText( "Das Geheimnis stimmt nicht mit dem des Accounts\nüberein. Achte auf Groß - und Kleinschreibung." );
+		geheimnis->removeStyle( TextFeld::Style::Sichtbar );
+		abbrechen->removeStyle( Knopf::Style::Sichtbar );
+	}
+}
+
+// Reference Counting
+Login *Login::getThis()
+{
+	ref++;
+	return this;
+}
+
+Login *Login::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Ereignisse
+bool loginNameTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (Login*)p )->nameTE( obj, te );
+}
+
+bool loginPasswortTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (Login*)p )->passwortTE( obj, te );
+}
+
+bool loginGeheimnisTE( void *p, void *obj, TastaturEreignis te )
+{
+	if( !p )
+		return 0;
+	return ( (Login*)p )->geheimnisTE( obj, te );
+}
+
+bool loginWeiterME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (Login*)p )->weiterME( obj, me );
+}
+
+bool loginAbbrechenME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (Login*)p )->abbrechenME( obj, me );
+}
+
+bool loginOkME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (Login*)p )->okME( obj, me );
+}
+
+bool loginLoginME( void *p, void *obj, MausEreignis me )
+{
+	if( !p )
+		return 0;
+	return ( (Login*)p )->loginME( obj, me );
+}

+ 59 - 0
KSGClient/VorLogin/Login/Login.h

@@ -0,0 +1,59 @@
+#ifndef Login_H
+#define Login_H
+
+#include <Fenster.h>
+#include <TextFeld.h>
+#include <Knopf.h>
+#include <MausEreignis.h>
+#include <TastaturEreignis.h>
+#include <Schrift.h>
+#include <Bildschirm.h>
+#include "..\..\Aktionen\AktionsThread.h"
+
+using namespace Framework;
+using namespace Network;
+
+class Login
+{
+private:
+	Fenster *fenster;
+	TextFeld *name;
+	TextFeld *passwort;
+	Knopf *weiter;
+	Knopf *login;
+	TextFeld *nachricht;
+	TextFeld *geheimnis;
+	Knopf *ok;
+	Knopf *abbrechen;
+	int ref;
+
+public:
+	// Konstruktor 
+	Login( Schrift *zSchrift, Fenster *vorLoginFenster );
+	// Destruktor 
+	~Login();
+	// Knopfdruck
+	void Login::druckFremdKnopf(); // Ein anderer Bereich des Programms wurde ausgewählt
+	bool nameTE( void *obj, TastaturEreignis te ); // Tastaturereignis im Textfeld name
+	bool passwortTE( void *obj, TastaturEreignis te ); // TastaturEreignis im Textfeld passwort
+	bool geheimnisTE( void *obj, TastaturEreignis te ); // TastaturEreignis im Textfeld geheimnis
+	bool weiterME( void *obj, MausEreignis me ); // MausEreignis im Knopf weiter
+	bool okME( void *obj, MausEreignis me ); // MausEreignis im Knopf ok
+	bool abbrechenME( void *obj, MausEreignis me ); // MausEreignis im Knopf abbrechen
+	bool loginME( void *obj, MausEreignis me ); // MausEreignis im Knopf login
+	void setLoginReturn( int ret ); // setzt den Returnwert vom login
+	void setKickReturn( int ret ); // setzt den returnwert vom kick
+	// Reference Counting
+	Login *getThis();
+	Login *release();
+};
+
+bool loginNameTE( void *p, void *obj, TastaturEreignis te );
+bool loginPasswortTE( void *p, void *obj, TastaturEreignis te );
+bool loginGeheimnisTE( void *p, void *obj, TastaturEreignis te );
+bool loginWeiterME( void *p, void *obj, MausEreignis me );
+bool loginOkME( void *p, void *obj, MausEreignis me );
+bool loginAbbrechenME( void *p, void *obj, MausEreignis me );
+bool loginLoginME( void *p, void *obj, MausEreignis me );
+
+#endif

+ 509 - 0
KSGClient/VorLogin/VorLogin.cpp

@@ -0,0 +1,509 @@
+#include "VorLogin.h"
+#include "..\Global\Initialisierung.h"
+
+// Inhalt der VorLogin Klasse aus VorLogin.h
+// Konstruktor 
+VorLogin::VorLogin( Schrift *zSchrift, Bildschirm *zBildschirm )
+{
+	if( zSchrift )
+		schrift = zSchrift->getThis();
+	if( zBildschirm )
+		bildschirm = zBildschirm->getThis();
+	fenster = 0;
+	beenden = 0;
+	login = 0;
+	bestätigung = 0;
+	eMailÄndern = 0;
+	eMailVergessen = 0;
+	geheimnisÄndern = 0;
+	geheimnisVergessen = 0;
+	nameVergessen = 0;
+	passwortÄndern = 0;
+	passwortVergessen = 0;
+	registrierung = 0;
+	unregistrierung = 0;
+	ref = 1;
+}
+
+// Destruktor 
+VorLogin::~VorLogin()
+{
+	if( fenster )
+		setSichtbar( 0 );
+	if( schrift )
+		schrift = schrift->release();
+	if( bildschirm )
+		bildschirm = bildschirm->release();
+}
+
+// nicht constant
+void VorLogin::setSichtbar( bool s ) // Setzt die Sichtbarkeit der VorLogin Oberfräche
+{
+	if( s )
+	{
+		if( fenster )
+			setSichtbar( 0 );
+		fenster = new Fenster();
+		fenster->setStyle( Fenster::Style::Erlaubt | Fenster::Style::Sichtbar );
+		fenster->setSize( bildschirm->getBackBufferSize() );
+		fenster->setPosition( 0, 0 );
+		beenden = initKnopf( 10, 10, 130, 30, schrift, Knopf::Style::Sichtbar, "Beenden" );
+		beenden->setMausEreignis( VorLoginBeendenME );
+		initToolTip( beenden, "Beendet den Kolja-Strohm Games Client.", schrift->getThis(), bildschirm );
+		fenster->addMember( beenden );
+		login = new Login( schrift, fenster );
+		bestätigung = new Bestätigung( schrift, fenster );
+		eMailÄndern = new EMailÄndern( schrift, fenster );
+		eMailVergessen = new EMailVergessen( schrift, fenster );
+		geheimnisÄndern = new GeheimnisÄndern( schrift, fenster );
+		geheimnisVergessen = new GeheimnisVergessen( schrift, fenster );
+		nameVergessen = new NameVergessen( schrift, fenster );
+		passwortÄndern = new PasswortÄndern( schrift, fenster );
+		passwortVergessen = new PasswortVergessen( schrift, fenster );
+		registrierung = new Registrierung( schrift, fenster );
+		unregistrierung = new Unregistrierung( schrift, fenster );
+		bildschirm->addMember( fenster );
+	}
+	else
+	{
+		if( bildschirm )
+			bildschirm->removeMember( fenster );
+		if( beenden )
+			beenden = beenden->release();
+		if( login )
+			login = login->release();
+		if( bestätigung )
+			bestätigung = bestätigung->release();
+		if( eMailÄndern )
+			eMailÄndern = eMailÄndern->release();
+		if( eMailVergessen )
+			eMailVergessen = eMailVergessen->release();
+		if( geheimnisÄndern )
+			geheimnisÄndern = geheimnisÄndern->release();
+		if( geheimnisVergessen )
+			geheimnisVergessen = geheimnisVergessen->release();
+		if( nameVergessen )
+			nameVergessen = nameVergessen->release();
+		if( passwortÄndern )
+			passwortÄndern = passwortÄndern->release();
+		if( passwortVergessen )
+			passwortVergessen = passwortVergessen->release();
+		if( registrierung )
+			registrierung = registrierung->release();
+		if( unregistrierung )
+			unregistrierung = unregistrierung->release();
+		if( fenster )
+			fenster = fenster->release();
+	}
+}
+
+void VorLogin::setLogin( bool knopfPress ) // macht Login Oberfläche sichtbar
+{
+	if( !knopfPress )
+	{
+		MausEreignis me;
+		me.id = ME_RLinks;
+		if( login )
+			login->loginME( 0, me );
+		return;
+	}
+	if( registrierung )
+		registrierung->druckFremdKnopf();
+	if( unregistrierung )
+		unregistrierung->druckFremdKnopf();
+	if( passwortÄndern )
+		passwortÄndern->druckFremdKnopf();
+	if( passwortVergessen )
+		passwortVergessen->druckFremdKnopf();
+	if( eMailÄndern )
+		eMailÄndern->druckFremdKnopf();
+	if( eMailVergessen )
+		eMailVergessen->druckFremdKnopf();
+	if( geheimnisÄndern )
+		geheimnisÄndern->druckFremdKnopf();
+	if( geheimnisVergessen )
+		geheimnisVergessen->druckFremdKnopf();
+	if( nameVergessen )
+		nameVergessen->druckFremdKnopf();
+	if( bestätigung )
+		bestätigung->druckFremdKnopf();
+}
+
+void VorLogin::setBestätigung() // macht Bestätigung Oberfläche sichtbar
+{
+	if( registrierung )
+		registrierung->druckFremdKnopf();
+	if( unregistrierung )
+		unregistrierung->druckFremdKnopf();
+	if( passwortÄndern )
+		passwortÄndern->druckFremdKnopf();
+	if( passwortVergessen )
+		passwortVergessen->druckFremdKnopf();
+	if( eMailÄndern )
+		eMailÄndern->druckFremdKnopf();
+	if( eMailVergessen )
+		eMailVergessen->druckFremdKnopf();
+	if( geheimnisÄndern )
+		geheimnisÄndern->druckFremdKnopf();
+	if( geheimnisVergessen )
+		geheimnisVergessen->druckFremdKnopf();
+	if( nameVergessen )
+		nameVergessen->druckFremdKnopf();
+	if( login )
+		login->druckFremdKnopf();
+}
+
+void VorLogin::setEMailÄndern() // macht EMailÄndern Oberfläche sichtbar
+{
+	if( registrierung )
+		registrierung->druckFremdKnopf();
+	if( unregistrierung )
+		unregistrierung->druckFremdKnopf();
+	if( passwortÄndern )
+		passwortÄndern->druckFremdKnopf();
+	if( passwortVergessen )
+		passwortVergessen->druckFremdKnopf();
+	if( bestätigung )
+		bestätigung->druckFremdKnopf();
+	if( eMailVergessen )
+		eMailVergessen->druckFremdKnopf();
+	if( geheimnisÄndern )
+		geheimnisÄndern->druckFremdKnopf();
+	if( geheimnisVergessen )
+		geheimnisVergessen->druckFremdKnopf();
+	if( nameVergessen )
+		nameVergessen->druckFremdKnopf();
+	if( login )
+		login->druckFremdKnopf();
+}
+
+void VorLogin::setEMailVergessen() // macht EMailVergessen Oberfläche sichtbar
+{
+	if( registrierung )
+		registrierung->druckFremdKnopf();
+	if( unregistrierung )
+		unregistrierung->druckFremdKnopf();
+	if( passwortÄndern )
+		passwortÄndern->druckFremdKnopf();
+	if( passwortVergessen )
+		passwortVergessen->druckFremdKnopf();
+	if( bestätigung )
+		bestätigung->druckFremdKnopf();
+	if( eMailÄndern )
+		eMailÄndern->druckFremdKnopf();
+	if( geheimnisÄndern )
+		geheimnisÄndern->druckFremdKnopf();
+	if( geheimnisVergessen )
+		geheimnisVergessen->druckFremdKnopf();
+	if( nameVergessen )
+		nameVergessen->druckFremdKnopf();
+	if( login )
+		login->druckFremdKnopf();
+}
+
+void VorLogin::setGeheimnisÄndern() // macht GeheimnisÄndern Oberfläche sichtbar
+{
+	if( registrierung )
+		registrierung->druckFremdKnopf();
+	if( unregistrierung )
+		unregistrierung->druckFremdKnopf();
+	if( passwortÄndern )
+		passwortÄndern->druckFremdKnopf();
+	if( passwortVergessen )
+		passwortVergessen->druckFremdKnopf();
+	if( bestätigung )
+		bestätigung->druckFremdKnopf();
+	if( eMailÄndern )
+		eMailÄndern->druckFremdKnopf();
+	if( eMailVergessen )
+		eMailVergessen->druckFremdKnopf();
+	if( geheimnisVergessen )
+		geheimnisVergessen->druckFremdKnopf();
+	if( nameVergessen )
+		nameVergessen->druckFremdKnopf();
+	if( login )
+		login->druckFremdKnopf();
+}
+
+void VorLogin::setGeheilnisVergessen() // macht GeheimnisVergessen Oberfläche sichtbar
+{
+	if( registrierung )
+		registrierung->druckFremdKnopf();
+	if( unregistrierung )
+		unregistrierung->druckFremdKnopf();
+	if( passwortÄndern )
+		passwortÄndern->druckFremdKnopf();
+	if( passwortVergessen )
+		passwortVergessen->druckFremdKnopf();
+	if( bestätigung )
+		bestätigung->druckFremdKnopf();
+	if( eMailÄndern )
+		eMailÄndern->druckFremdKnopf();
+	if( eMailVergessen )
+		eMailVergessen->druckFremdKnopf();
+	if( geheimnisÄndern )
+		geheimnisÄndern->druckFremdKnopf();
+	if( nameVergessen )
+		nameVergessen->druckFremdKnopf();
+	if( login )
+		login->druckFremdKnopf();
+}
+
+void VorLogin::setNameVergessen() // macht NameVergessen Oberfläche sichtbar
+{
+	if( registrierung )
+		registrierung->druckFremdKnopf();
+	if( unregistrierung )
+		unregistrierung->druckFremdKnopf();
+	if( passwortÄndern )
+		passwortÄndern->druckFremdKnopf();
+	if( passwortVergessen )
+		passwortVergessen->druckFremdKnopf();
+	if( bestätigung )
+		bestätigung->druckFremdKnopf();
+	if( eMailÄndern )
+		eMailÄndern->druckFremdKnopf();
+	if( eMailVergessen )
+		eMailVergessen->druckFremdKnopf();
+	if( geheimnisÄndern )
+		geheimnisÄndern->druckFremdKnopf();
+	if( geheimnisVergessen )
+		geheimnisVergessen->druckFremdKnopf();
+	if( login )
+		login->druckFremdKnopf();
+}
+
+void VorLogin::setPasswortÄndern() // macht PasswortÄndern Oberfläche sichtbar
+{
+	if( registrierung )
+		registrierung->druckFremdKnopf();
+	if( unregistrierung )
+		unregistrierung->druckFremdKnopf();
+	if( nameVergessen )
+		nameVergessen->druckFremdKnopf();
+	if( passwortVergessen )
+		passwortVergessen->druckFremdKnopf();
+	if( bestätigung )
+		bestätigung->druckFremdKnopf();
+	if( eMailÄndern )
+		eMailÄndern->druckFremdKnopf();
+	if( eMailVergessen )
+		eMailVergessen->druckFremdKnopf();
+	if( geheimnisÄndern )
+		geheimnisÄndern->druckFremdKnopf();
+	if( geheimnisVergessen )
+		geheimnisVergessen->druckFremdKnopf();
+	if( login )
+		login->druckFremdKnopf();
+}
+
+void VorLogin::setPasswortVergessen() // macht passwortVergessen Oberfläche sichtbar
+{
+	if( registrierung )
+		registrierung->druckFremdKnopf();
+	if( unregistrierung )
+		unregistrierung->druckFremdKnopf();
+	if( nameVergessen )
+		nameVergessen->druckFremdKnopf();
+	if( passwortÄndern )
+		passwortÄndern->druckFremdKnopf();
+	if( bestätigung )
+		bestätigung->druckFremdKnopf();
+	if( eMailÄndern )
+		eMailÄndern->druckFremdKnopf();
+	if( eMailVergessen )
+		eMailVergessen->druckFremdKnopf();
+	if( geheimnisÄndern )
+		geheimnisÄndern->druckFremdKnopf();
+	if( geheimnisVergessen )
+		geheimnisVergessen->druckFremdKnopf();
+	if( login )
+		login->druckFremdKnopf();
+}
+
+void VorLogin::setRegistrierung() // macht Registrierung Oberfläche sichtbar
+{
+	if( passwortVergessen )
+		passwortVergessen->druckFremdKnopf();
+	if( unregistrierung )
+		unregistrierung->druckFremdKnopf();
+	if( nameVergessen )
+		nameVergessen->druckFremdKnopf();
+	if( passwortÄndern )
+		passwortÄndern->druckFremdKnopf();
+	if( bestätigung )
+		bestätigung->druckFremdKnopf();
+	if( eMailÄndern )
+		eMailÄndern->druckFremdKnopf();
+	if( eMailVergessen )
+		eMailVergessen->druckFremdKnopf();
+	if( geheimnisÄndern )
+		geheimnisÄndern->druckFremdKnopf();
+	if( geheimnisVergessen )
+		geheimnisVergessen->druckFremdKnopf();
+	if( login )
+		login->druckFremdKnopf();
+}
+
+void VorLogin::setUnregistrierung() // macht Unregistrierung Oberfläche sichtbar
+{
+	if( passwortVergessen )
+		passwortVergessen->druckFremdKnopf();
+	if( registrierung )
+		registrierung->druckFremdKnopf();
+	if( nameVergessen )
+		nameVergessen->druckFremdKnopf();
+	if( passwortÄndern )
+		passwortÄndern->druckFremdKnopf();
+	if( bestätigung )
+		bestätigung->druckFremdKnopf();
+	if( eMailÄndern )
+		eMailÄndern->druckFremdKnopf();
+	if( eMailVergessen )
+		eMailVergessen->druckFremdKnopf();
+	if( geheimnisÄndern )
+		geheimnisÄndern->druckFremdKnopf();
+	if( geheimnisVergessen )
+		geheimnisVergessen->druckFremdKnopf();
+	if( login )
+		login->druckFremdKnopf();
+}
+
+// constant
+Login *VorLogin::getLogin() const // gibt die Login Oberfläche zurück
+{
+	return login ? login->getThis() : 0;
+}
+
+Login *VorLogin::zLogin() const
+{
+	return login;
+}
+
+Bestätigung *VorLogin::getBestätigung() const // gibt die Bestätigung Oberfläche zurück
+{
+	return bestätigung ? bestätigung->getThis() : 0;
+}
+
+Bestätigung *VorLogin::zBestätigung() const
+{
+	return bestätigung;
+}
+
+EMailÄndern *VorLogin::getEMailÄndern() const // gibt die EMailÄndern Oberfläche zurück
+{
+	return eMailÄndern ? eMailÄndern->getThis() : 0;
+}
+
+EMailÄndern *VorLogin::zEMailÄndern() const
+{
+	return eMailÄndern;
+}
+
+EMailVergessen *VorLogin::getEMailVergessen() const // gibt die EMailVergessen Oberfläche zurück
+{
+	return eMailVergessen ? eMailVergessen->getThis() : 0;
+}
+
+EMailVergessen *VorLogin::zEMailVergessen() const
+{
+	return eMailVergessen;
+}
+
+GeheimnisÄndern *VorLogin::getGeheimnisÄndern() const // gibt die GeheimnisÄndern Oberfläche zurück
+{
+	return geheimnisÄndern ? geheimnisÄndern->getThis() : 0;
+}
+
+GeheimnisÄndern *VorLogin::zGeheimnisÄndern() const
+{
+	return geheimnisÄndern;
+}
+
+GeheimnisVergessen *VorLogin::getGeheimnisVergessen() const // gibt die GeheimnisVergessen Oberfläche zurück
+{
+	return geheimnisVergessen ? geheimnisVergessen->getThis() : 0;
+}
+
+GeheimnisVergessen *VorLogin::zGeheimnisVergessen() const
+{
+	return geheimnisVergessen;
+}
+
+NameVergessen *VorLogin::getNameVergessen() const // gibt die NameVergessen Oberfläche zurück
+{
+	return nameVergessen ? nameVergessen->getThis() : 0;
+}
+
+NameVergessen *VorLogin::zNameVergessen() const
+{
+	return nameVergessen;
+}
+
+PasswortÄndern *VorLogin::getPasswortÄndern() const // gibt die PasswortÄndern Oberfläche zurück
+{
+	return passwortÄndern ? passwortÄndern->getThis() : 0;
+}
+
+PasswortÄndern *VorLogin::zPasswortÄndern() const
+{
+	return passwortÄndern;
+}
+
+PasswortVergessen *VorLogin::getPasswortVergessen() const // gibt die PasswortVergessen Oberfläche zurück
+{
+	return passwortVergessen ? passwortVergessen->getThis() : 0;
+}
+
+PasswortVergessen *VorLogin::zPasswortVergessen() const
+{
+	return passwortVergessen;
+}
+
+Registrierung *VorLogin::getRegistrierung() const // gibt die Registrierung Oberfläche zurück
+{
+	return registrierung ? registrierung->getThis() : 0;
+}
+
+Registrierung *VorLogin::zRegistrierung() const
+{
+	return registrierung;
+}
+
+Unregistrierung *VorLogin::getUnregistrierung() const // gibt die Unregistrierung Oberfläche zurück
+{
+	return unregistrierung ? unregistrierung->getThis() : 0;
+}
+
+Unregistrierung *VorLogin::zUnregistrierung() const
+{
+	return unregistrierung;
+}
+
+Fenster *VorLogin::zFenster() const
+{
+	return fenster;
+}
+
+// Reference Counting
+VorLogin *VorLogin::getThis()
+{
+	ref++;
+	return this;
+}
+
+VorLogin *VorLogin::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}
+
+// Ereignisse
+bool VorLoginBeendenME( void *p, void *obj, MausEreignis me )
+{
+	if( me.id == ME_RLinks )
+		PostQuitMessage( 0 );
+	return 1;
+}

+ 84 - 0
KSGClient/VorLogin/VorLogin.h

@@ -0,0 +1,84 @@
+#ifndef VorLogin_H
+#define VorLogin_H
+
+#include <Klient.h>
+#include "Login\Login.h"
+#include "Account verwalten\Bestätigung.h"
+#include "Account verwalten\EMail.h"
+#include "Account verwalten\Geheimnis.h"
+#include "Account verwalten\Name.h"
+#include "Account verwalten\Passwort.h"
+#include "Account verwalten\Registrierung.h"
+#include "Account verwalten\Unregistrierung.h"
+
+class VorLogin
+{
+private:
+	Knopf				*beenden;
+	Login				*login;
+	Bestätigung			*bestätigung;
+	EMailÄndern			*eMailÄndern;
+	EMailVergessen		*eMailVergessen;
+	GeheimnisÄndern		*geheimnisÄndern;
+	GeheimnisVergessen	*geheimnisVergessen;
+	NameVergessen		*nameVergessen;
+	PasswortÄndern		*passwortÄndern;
+	PasswortVergessen	*passwortVergessen;
+	Registrierung		*registrierung;
+	Unregistrierung		*unregistrierung;
+	Schrift				*schrift;
+	Bildschirm			*bildschirm;
+	Fenster             *fenster;
+	int ref;
+
+public:
+	// Konstruktor 
+	VorLogin( Schrift *zSchrift, Bildschirm *zBildschirm );
+	// Destruktor 
+	~VorLogin();
+	// nicht constant
+	void setSichtbar( bool s ); // Setzt die Sichtbarkeit der VorLogin Oberfräche
+	void setLogin( bool knopfPress ); // macht Login Oberfläche sichtbar
+	void setBestätigung(); // macht Bestätigung Oberfläche sichtbar
+	void setEMailÄndern(); // macht EMailÄndern Oberfläche sichtbar
+	void setEMailVergessen(); // macht EMailVergessen Oberfläche sichtbar
+	void setGeheimnisÄndern(); // macht GeheimnisÄndern Oberfläche sichtbar
+	void setGeheilnisVergessen(); // macht GeheimnisVergessen Oberfläche sichtbar
+	void setNameVergessen(); // macht NameVergessen Oberfläche sichtbar
+	void setPasswortÄndern(); // macht PasswortÄndern Oberfläche sichtbar
+	void setPasswortVergessen(); // macht passwortVergessen Oberfläche sichtbar
+	void setRegistrierung(); // macht Registrierung Oberfläche sichtbar
+	void setUnregistrierung(); // macht Unregistrierung Oberfläche sichtbar
+	// constant
+	Login *getLogin() const; // gibt die Login Oberfläche zurück
+	Login *zLogin() const;
+	Bestätigung *getBestätigung() const; // gibt die Bestätigung Oberfläche zurück
+	Bestätigung *zBestätigung() const;
+	EMailÄndern *getEMailÄndern() const; // gibt die EMailÄndern Oberfläche zurück
+	EMailÄndern *zEMailÄndern() const;
+	EMailVergessen *getEMailVergessen() const; // gibt die EMailVergessen Oberfläche zurück
+	EMailVergessen *zEMailVergessen() const;
+	GeheimnisÄndern *getGeheimnisÄndern() const; // gibt die GeheimnisÄndern Oberfläche zurück
+	GeheimnisÄndern *zGeheimnisÄndern() const;
+	GeheimnisVergessen *getGeheimnisVergessen() const; // gibt die GeheimnisVergessen Oberfläche zurück
+	GeheimnisVergessen *zGeheimnisVergessen() const;
+	NameVergessen *getNameVergessen() const; // gibt die NameVergessen Oberfläche zurück
+	NameVergessen *zNameVergessen() const;
+	PasswortÄndern *getPasswortÄndern() const; // gibt die PasswortÄndern Oberfläche zurück
+	PasswortÄndern *zPasswortÄndern() const;
+	PasswortVergessen *getPasswortVergessen() const; // gibt die PasswortVergessen Oberfläche zurück
+	PasswortVergessen *zPasswortVergessen() const;
+	Registrierung *getRegistrierung() const; // gibt die Registrierung Oberfläche zurück
+	Registrierung *zRegistrierung() const;
+	Unregistrierung *getUnregistrierung() const; // gibt die Unregistrierung Oberfläche zurück
+	Unregistrierung *zUnregistrierung() const;
+	Fenster *zFenster() const;
+	// Reference Counting
+	VorLogin *getThis();
+	VorLogin *release();
+};
+
+// Ereignisse
+bool VorLoginBeendenME( void *p, void *obj, MausEreignis me );
+
+#endif

+ 3 - 0
build.bat

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