Переглянути джерело

Projektdateien hinzufügen.

Kolja Strohm 6 роки тому
батько
коміт
ca63070343
47 змінених файлів з 4855 додано та 0 видалено
  1. 136 0
      Linie Linux/Linie Linux.vcxproj
  2. 147 0
      Linie Linux/Linie Linux.vcxproj.filters
  3. BIN
      Linie Linux/readme/images/ArchOptions.gif
  4. BIN
      Linie Linux/readme/images/ChangeRemote.gif
  5. BIN
      Linie Linux/readme/images/ManageConnections.gif
  6. BIN
      Linie Linux/readme/images/OutputTypes.gif
  7. BIN
      Linie Linux/readme/images/debuggerexport.png
  8. BIN
      Linie Linux/readme/images/firstconnection.png
  9. BIN
      Linie Linux/readme/images/linker.png
  10. BIN
      Linie Linux/readme/images/postbuild.png
  11. 85 0
      Linie Linux/readme/readme.html
  12. 119 0
      Linie Linux/readme/stylesheet.css
  13. 34 0
      Linie.sln
  14. 171 0
      Linie/Bestenliste.cpp
  15. 42 0
      Linie/Bestenliste.h
  16. 9 0
      Linie/DllStart.cpp
  17. 143 0
      Linie/GesamtSpielerStatistik.cpp
  18. 53 0
      Linie/GesamtSpielerStatistik.h
  19. 105 0
      Linie/GesamtTeamStatistik.cpp
  20. 44 0
      Linie/GesamtTeamStatistik.h
  21. 67 0
      Linie/Karte.cpp
  22. 34 0
      Linie/Karte.h
  23. 114 0
      Linie/KartenLeser.cpp
  24. 31 0
      Linie/KartenLeser.h
  25. 497 0
      Linie/Klient.cpp
  26. 63 0
      Linie/Klient.h
  27. 223 0
      Linie/Linie.vcxproj
  28. 147 0
      Linie/Linie.vcxproj.filters
  29. 151 0
      Linie/RundenRundenStatistik.cpp
  30. 52 0
      Linie/RundenRundenStatistik.h
  31. 111 0
      Linie/RundenSpielerStatistik.cpp
  32. 45 0
      Linie/RundenSpielerStatistik.h
  33. 97 0
      Linie/RundenTeamStatistik.cpp
  34. 42 0
      Linie/RundenTeamStatistik.h
  35. 34 0
      Linie/SSDatenbankV.h
  36. 29 0
      Linie/SSKlientV.h
  37. 774 0
      Linie/Spiel.cpp
  38. 62 0
      Linie/Spiel.h
  39. 38 0
      Linie/SpielKlasse.h
  40. 453 0
      Linie/Spieler.cpp
  41. 102 0
      Linie/Spieler.h
  42. 462 0
      Linie/Statistik.cpp
  43. 55 0
      Linie/Statistik.h
  44. 23 0
      Linie/StatistikKlasse.h
  45. 35 0
      Linie/Strukturen.cpp
  46. 24 0
      Linie/Strukturen.h
  47. 2 0
      build.bat

+ 136 - 0
Linie Linux/Linie Linux.vcxproj

@@ -0,0 +1,136 @@
+<?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|ARM">
+      <Configuration>Debug</Configuration>
+      <Platform>ARM</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|ARM">
+      <Configuration>Release</Configuration>
+      <Platform>ARM</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x86">
+      <Configuration>Debug</Configuration>
+      <Platform>x86</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x86">
+      <Configuration>Release</Configuration>
+      <Platform>x86</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{cba57e9d-0927-44ff-a092-8c62be2ed1b2}</ProjectGuid>
+    <Keyword>Linux</Keyword>
+    <RootNamespace>Linie_Linux</RootNamespace>
+    <MinimumVisualStudioVersion>15.0</MinimumVisualStudioVersion>
+    <ApplicationType>Linux</ApplicationType>
+    <ApplicationTypeRevision>1.0</ApplicationTypeRevision>
+    <TargetLinuxPlatform>Generic</TargetLinuxPlatform>
+    <LinuxProjectType>{D51BCBC9-82E9-4017-911E-C93873C4EA2B}</LinuxProjectType>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
+    <UseDebugLibraries>true</UseDebugLibraries>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
+    <UseDebugLibraries>false</UseDebugLibraries>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'" Label="Configuration">
+    <UseDebugLibraries>true</UseDebugLibraries>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'" Label="Configuration">
+    <UseDebugLibraries>false</UseDebugLibraries>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <RemoteRootDir>~/projects</RemoteRootDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <RemoteRootDir>~/projects</RemoteRootDir>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings" />
+  <ImportGroup Label="Shared" />
+  <ImportGroup Label="PropertySheets" />
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <TargetName>Linie</TargetName>
+    <TargetExt>.so</TargetExt>
+    <RemoteProjectDir>$(RemoteRootDir)/Spiele/Linie/debug</RemoteProjectDir>
+    <IncludePath>..\..\..\..\..\Allgemein\Framework;..\..\..\..\..\Allgemein\Network\Network;../../../Framework/debug;../../../Network/debug;..\Linie;$(IncludePath)</IncludePath>
+    <OutDir>$(ProjectDir)bin\$(Platform)\debug\</OutDir>
+    <IntDir>$(ProjectDir)obj\$(Platform)\debug\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <TargetName>Linie</TargetName>
+    <TargetExt>.so</TargetExt>
+    <RemoteProjectDir>$(RemoteRootDir)/Spiele/Linie/release</RemoteProjectDir>
+    <IncludePath>..\..\..\..\..\Allgemein\Framework;..\..\..\..\..\Allgemein\Network\Network;../../../Framework/release;../../../Network/release;..\Linie;$(IncludePath)</IncludePath>
+    <OutDir>$(ProjectDir)bin\$(Platform)\release\</OutDir>
+    <IntDir>$(ProjectDir)obj\$(Platform)\release\</IntDir>
+  </PropertyGroup>
+  <ItemGroup>
+    <ClInclude Include="..\Linie\Bestenliste.h" />
+    <ClInclude Include="..\Linie\GesamtSpielerStatistik.h" />
+    <ClInclude Include="..\Linie\GesamtTeamStatistik.h" />
+    <ClInclude Include="..\Linie\Karte.h" />
+    <ClInclude Include="..\Linie\KartenLeser.h" />
+    <ClInclude Include="..\Linie\Klient.h" />
+    <ClInclude Include="..\Linie\RundenRundenStatistik.h" />
+    <ClInclude Include="..\Linie\RundenSpielerStatistik.h" />
+    <ClInclude Include="..\Linie\RundenTeamStatistik.h" />
+    <ClInclude Include="..\Linie\Spiel.h" />
+    <ClInclude Include="..\Linie\Spieler.h" />
+    <ClInclude Include="..\Linie\SpielKlasse.h" />
+    <ClInclude Include="..\Linie\SSDatenbankV.h" />
+    <ClInclude Include="..\Linie\SSKlientV.h" />
+    <ClInclude Include="..\Linie\Statistik.h" />
+    <ClInclude Include="..\Linie\StatistikKlasse.h" />
+    <ClInclude Include="..\Linie\Strukturen.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\Linie\Bestenliste.cpp" />
+    <ClCompile Include="..\Linie\DllStart.cpp" />
+    <ClCompile Include="..\Linie\GesamtSpielerStatistik.cpp" />
+    <ClCompile Include="..\Linie\GesamtTeamStatistik.cpp" />
+    <ClCompile Include="..\Linie\Karte.cpp" />
+    <ClCompile Include="..\Linie\KartenLeser.cpp" />
+    <ClCompile Include="..\Linie\Klient.cpp" />
+    <ClCompile Include="..\Linie\RundenRundenStatistik.cpp" />
+    <ClCompile Include="..\Linie\RundenSpielerStatistik.cpp" />
+    <ClCompile Include="..\Linie\RundenTeamStatistik.cpp" />
+    <ClCompile Include="..\Linie\Spiel.cpp" />
+    <ClCompile Include="..\Linie\Spieler.cpp" />
+    <ClCompile Include="..\Linie\Statistik.cpp" />
+    <ClCompile Include="..\Linie\Strukturen.cpp" />
+  </ItemGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Link>
+      <UnresolvedSymbolReferences>false</UnresolvedSymbolReferences>
+    </Link>
+    <ClCompile>
+      <AdditionalOptions>-fPIC %(AdditionalOptions)</AdditionalOptions>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Link>
+      <UnresolvedSymbolReferences>false</UnresolvedSymbolReferences>
+    </Link>
+    <ClCompile>
+      <AdditionalOptions>-fPIC %(AdditionalOptions)</AdditionalOptions>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets" />
+</Project>

+ 147 - 0
Linie Linux/Linie Linux.vcxproj.filters

@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Datenbank">
+      <UniqueIdentifier>{f9b86396-8b8d-4072-a4ba-b974ba2a6757}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Leser">
+      <UniqueIdentifier>{d4bda9b8-ea2b-426a-91bd-69177f1bc307}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Netzwerk">
+      <UniqueIdentifier>{cdd8cfc2-e1a9-4d99-a50c-4bdb773cf94e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Spiel">
+      <UniqueIdentifier>{0a78d23c-a0a5-4827-a19c-797935b0fe3e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Start">
+      <UniqueIdentifier>{7ec7bd3b-b17d-496d-9958-2ca919d031d7}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Statistik">
+      <UniqueIdentifier>{5b0fbf37-0913-4b2f-aabf-d4d997031300}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Statistik\Gesamt">
+      <UniqueIdentifier>{1543c096-ebf9-40a5-831d-fdad1a695f65}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Statistik\Runden">
+      <UniqueIdentifier>{6267586e-60e5-4a39-bab6-f9b74b41d493}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Statistik\Gesamt\Team">
+      <UniqueIdentifier>{a6175fa5-01fe-4545-8797-850378528e0d}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Statistik\Gesamt\Spieler">
+      <UniqueIdentifier>{9c7cf2b3-3036-466c-9998-a68b5f84cb2c}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Statistik\Runden\Spieler">
+      <UniqueIdentifier>{e88ad75c-e356-49cb-b534-9e2ab8377d4f}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Statistik\Runden\Team">
+      <UniqueIdentifier>{729bb387-fc3f-4bfc-88a3-12f2aeda1241}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Spiel\Bestenliste">
+      <UniqueIdentifier>{23af21af-92a6-4ba2-b10a-34e131a325ab}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Spiel\Spieler">
+      <UniqueIdentifier>{b29b4e9c-a17b-4a54-a292-1bad0d7e2661}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Spiel\Karte">
+      <UniqueIdentifier>{537763c3-2797-42d6-a340-6e84452f7026}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\Linie\SSDatenbankV.h">
+      <Filter>Datenbank</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Linie\KartenLeser.h">
+      <Filter>Leser</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Linie\SSKlientV.h">
+      <Filter>Netzwerk</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Linie\Klient.h">
+      <Filter>Netzwerk</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Linie\Statistik.h">
+      <Filter>Statistik</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Linie\StatistikKlasse.h">
+      <Filter>Statistik</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Linie\RundenRundenStatistik.h">
+      <Filter>Statistik\Runden</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Linie\GesamtTeamStatistik.h">
+      <Filter>Statistik\Gesamt\Team</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Linie\GesamtSpielerStatistik.h">
+      <Filter>Statistik\Gesamt\Spieler</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Linie\RundenSpielerStatistik.h">
+      <Filter>Statistik\Runden\Spieler</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Linie\RundenTeamStatistik.h">
+      <Filter>Statistik\Runden\Team</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Linie\Strukturen.h">
+      <Filter>Spiel</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Linie\Spiel.h">
+      <Filter>Spiel</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Linie\SpielKlasse.h">
+      <Filter>Spiel</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Linie\Bestenliste.h">
+      <Filter>Spiel\Bestenliste</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Linie\Karte.h">
+      <Filter>Spiel\Karte</Filter>
+    </ClInclude>
+    <ClInclude Include="..\Linie\Spieler.h">
+      <Filter>Spiel\Spieler</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\Linie\DllStart.cpp">
+      <Filter>Start</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Linie\KartenLeser.cpp">
+      <Filter>Leser</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Linie\Klient.cpp">
+      <Filter>Netzwerk</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Linie\Statistik.cpp">
+      <Filter>Statistik</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Linie\RundenRundenStatistik.cpp">
+      <Filter>Statistik\Runden</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Linie\GesamtTeamStatistik.cpp">
+      <Filter>Statistik\Gesamt\Team</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Linie\GesamtSpielerStatistik.cpp">
+      <Filter>Statistik\Gesamt\Spieler</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Linie\RundenSpielerStatistik.cpp">
+      <Filter>Statistik\Runden\Spieler</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Linie\RundenTeamStatistik.cpp">
+      <Filter>Statistik\Runden\Team</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Linie\Spiel.cpp">
+      <Filter>Spiel</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Linie\Strukturen.cpp">
+      <Filter>Spiel</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Linie\Bestenliste.cpp">
+      <Filter>Spiel\Bestenliste</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Linie\Karte.cpp">
+      <Filter>Spiel\Karte</Filter>
+    </ClCompile>
+    <ClCompile Include="..\Linie\Spieler.cpp">
+      <Filter>Spiel\Spieler</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>

BIN
Linie Linux/readme/images/ArchOptions.gif


BIN
Linie Linux/readme/images/ChangeRemote.gif


BIN
Linie Linux/readme/images/ManageConnections.gif


BIN
Linie Linux/readme/images/OutputTypes.gif


BIN
Linie Linux/readme/images/debuggerexport.png


BIN
Linie Linux/readme/images/firstconnection.png


BIN
Linie Linux/readme/images/linker.png


BIN
Linie Linux/readme/images/postbuild.png


+ 85 - 0
Linie Linux/readme/readme.html

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

+ 119 - 0
Linie Linux/readme/stylesheet.css

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

+ 34 - 0
Linie.sln

@@ -0,0 +1,34 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26020.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Linie Linux", "Linie Linux\Linie Linux.vcxproj", "{CBA57E9D-0927-44FF-A092-8C62BE2ED1B2}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|ARM = Debug|ARM
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		Release|ARM = Release|ARM
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{CBA57E9D-0927-44FF-A092-8C62BE2ED1B2}.Debug|ARM.ActiveCfg = Debug|ARM
+		{CBA57E9D-0927-44FF-A092-8C62BE2ED1B2}.Debug|ARM.Build.0 = Debug|ARM
+		{CBA57E9D-0927-44FF-A092-8C62BE2ED1B2}.Debug|Win32.ActiveCfg = Debug|x86
+		{CBA57E9D-0927-44FF-A092-8C62BE2ED1B2}.Debug|Win32.Build.0 = Debug|x86
+		{CBA57E9D-0927-44FF-A092-8C62BE2ED1B2}.Debug|x64.ActiveCfg = Debug|x64
+		{CBA57E9D-0927-44FF-A092-8C62BE2ED1B2}.Debug|x64.Build.0 = Debug|x64
+		{CBA57E9D-0927-44FF-A092-8C62BE2ED1B2}.Release|ARM.ActiveCfg = Release|ARM
+		{CBA57E9D-0927-44FF-A092-8C62BE2ED1B2}.Release|ARM.Build.0 = Release|ARM
+		{CBA57E9D-0927-44FF-A092-8C62BE2ED1B2}.Release|Win32.ActiveCfg = Release|x86
+		{CBA57E9D-0927-44FF-A092-8C62BE2ED1B2}.Release|Win32.Build.0 = Release|x86
+		{CBA57E9D-0927-44FF-A092-8C62BE2ED1B2}.Release|x64.ActiveCfg = Release|x64
+		{CBA57E9D-0927-44FF-A092-8C62BE2ED1B2}.Release|x64.Build.0 = Release|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

+ 171 - 0
Linie/Bestenliste.cpp

@@ -0,0 +1,171 @@
+#include "Bestenliste.h"
+
+// Inhalt der Bestenliste Klasse aus Bestenliste.h
+// Konstruktor
+Bestenliste::Bestenliste()
+{
+	spielerPunkte = new Array< int >();
+	spielerNummern = new Array< int >();
+	teamPunkte = new Array< int >();
+	teamMaxPunkte = new Array< int >();
+	teamNummern = new Array< int >();
+	spielerAnzahl = 0;
+	teamAnzahl = 0;
+	ref = 1;
+}
+
+// Destruktor
+Bestenliste::~Bestenliste()
+{
+	spielerPunkte->release();
+	spielerNummern->release();
+	teamPunkte->release();
+	teamMaxPunkte->release();
+	teamNummern->release();
+}
+
+// nicht constant
+void Bestenliste::setTeamMaxPunkte( int team, int mP )
+{
+	int i = -1;
+	for( int j = 0; j < teamAnzahl; j++ )
+	{
+		if( teamNummern->hat( j ) && teamNummern->get( j ) == team )
+		{
+			i = j;
+			break;
+		}
+	}
+	if( i < 0 )
+	{
+		i = teamAnzahl;
+		teamNummern->add( team, teamAnzahl );
+		teamPunkte->add( 0, teamAnzahl );
+		teamMaxPunkte->add( 0, teamAnzahl );
+		teamAnzahl++;
+	}
+	teamMaxPunkte->set( mP, i );
+}
+
+void Bestenliste::setTeamPunkte( int team, int p )
+{
+	for( int i = 0; i < teamAnzahl; i++ )
+	{
+		if( teamNummern->hat( i ) && teamNummern->get( i ) == team )
+		{
+			teamPunkte->set( p, i );
+			return;
+		}
+	}
+}
+
+void Bestenliste::setSpielerPunkte( int spieler, int p )
+{
+	int i = -1;
+	for( int j = 0; j < spielerAnzahl; j++ )
+	{
+		if( spielerNummern->hat( j ) && spielerNummern->get( j ) == spieler )
+		{
+			i = j;
+			break;
+		}
+	}
+	if( i < 0 )
+	{
+		i = spielerAnzahl;
+		spielerNummern->add( spieler, spielerAnzahl );
+		spielerPunkte->add( 0, spielerAnzahl );
+		spielerAnzahl++;
+	}
+	spielerPunkte->set( p, i );
+}
+
+void Bestenliste::addTeamPunkt( int team, bool plus )
+{
+	for( int i = 0; i < teamAnzahl; i++ )
+	{
+		if( teamNummern->hat( i ) && teamNummern->get( i ) == team )
+		{
+			int jetzt = teamPunkte->hat( i ) ? teamPunkte->get( i ) : 0;
+			if( plus )
+				jetzt++;
+			else
+				jetzt--;
+			if( jetzt < 0 )
+				jetzt = 0;
+			teamPunkte->set( jetzt, i );
+			return;
+		}
+	}
+}
+
+void Bestenliste::addSpielerPunkt( int spieler, bool plus )
+{
+	for( int i = 0; i < spielerAnzahl; i++ )
+	{
+		if( spielerNummern->hat( i ) && spielerNummern->get( i ) == spieler )
+		{
+			if( plus )
+				spielerPunkte->set( ( spielerPunkte->hat( i ) ? spielerPunkte->get( i ) : 0 ) + 1, i );
+			else
+				spielerPunkte->set( ( spielerPunkte->hat( i ) ? spielerPunkte->get( i ) : 0 ) - 1, i );
+			return;
+		}
+	}
+}
+
+// constant
+bool Bestenliste::istTeamAmLeben( int team ) const
+{
+	for( int i = 0; i < teamAnzahl; i++ )
+	{
+		if( teamNummern->hat( i ) && teamNummern->get( i ) == team )
+			return teamPunkte->hat( i ) && teamPunkte->get( i ) != 0;
+	}
+	return 0;
+}
+
+bool Bestenliste::hatTeamGewonnen( int team ) const
+{
+	for( int i = 0; i < teamAnzahl; i++ )
+	{
+		if( teamNummern->hat( i ) && teamNummern->get( i ) == team )
+			return ( ( teamPunkte->hat( i ) && teamMaxPunkte->hat( i ) ) ? ( teamPunkte->get( i ) >= teamMaxPunkte->get( i ) ) : 0 );
+	}
+	return 0;
+}
+
+int Bestenliste::getTeamPunkte( int team ) const
+{
+	for( int i = 0; i < teamAnzahl; i++ )
+	{
+		if( teamNummern->hat( i ) && teamNummern->get( i ) == team )
+			return teamPunkte->hat( i ) ? teamPunkte->get( i ) : 0;
+	}
+	return 0;
+}
+
+int Bestenliste::getTeamMaxPunkte( int team ) const
+{
+	for( int i = 0; i < teamAnzahl; i++ )
+	{
+		if( teamNummern->hat( i ) && teamNummern->get( i ) == team )
+			return teamMaxPunkte->hat( i ) ? teamMaxPunkte->get( i ) : 0;
+	}
+	return 0;
+}
+
+// Reference Counting
+Bestenliste *Bestenliste::getThis()
+{
+	ref++;
+	return this;
+}
+
+Bestenliste *Bestenliste::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 42 - 0
Linie/Bestenliste.h

@@ -0,0 +1,42 @@
+#ifndef Bestenliste_H
+#define Bestenliste_H
+
+#include <Array.h>
+
+using namespace Framework;
+
+class Bestenliste
+{
+private:
+	Array< int > *spielerPunkte;
+	Array< int > *spielerNummern;
+	Array< int > *teamPunkte;
+	Array< int > *teamMaxPunkte;
+	Array< int > *teamNummern;
+	int spielerAnzahl;
+	int teamAnzahl;
+	int ref;
+
+public:
+	// Konstruktor
+	Bestenliste();
+	// Destruktor
+	~Bestenliste();
+	// nicht constant
+	void setTeamMaxPunkte( int team, int mP );
+	void setTeamPunkte( int team, int p );
+	void setSpielerPunkte( int spieler, int p );
+	void addTeamPunkt( int team, bool plus );
+	void addSpielerPunkt( int spieler, bool plus );
+	void neueRunde();
+	// constant
+	bool istTeamAmLeben( int team ) const;
+	bool hatTeamGewonnen( int team ) const;
+	int getTeamPunkte( int team ) const;
+	int getTeamMaxPunkte( int team ) const;
+	// Reference Counting
+	Bestenliste *getThis();
+	Bestenliste *release();
+};
+
+#endif

+ 9 - 0
Linie/DllStart.cpp

@@ -0,0 +1,9 @@
+#include "Spiel.h"
+
+extern "C" 
+{
+	__declspec( dllexport ) Spiel *getSpielKlasse()
+	{
+		return new Spiel();
+	}
+}

+ 143 - 0
Linie/GesamtSpielerStatistik.cpp

@@ -0,0 +1,143 @@
+#include "GesamtSpielerStatistik.h"
+
+// Inhalt der GesamtSpielerStatistik Klasse aus GesamtSpielerStatistik.h
+// Konstruktor
+GesamtSpielerStatistik::GesamtSpielerStatistik()
+{
+	spielerNummer = 0;
+	spielerName = new Text();
+	teamName = new Text();
+	spielerFarbe = 0;
+	teamFarbe = 0;
+	gewonneneRunden = 0;
+	punkte = 0;
+	linienLength = 0;
+	zeitAmLeben = 0;
+	zeitTod = 0;
+	kills = 0;
+	tode = 0;
+	ref = 1;
+}
+
+// Destruktor
+GesamtSpielerStatistik::~GesamtSpielerStatistik()
+{
+	spielerName->release();
+	teamName->release();
+}
+
+// nicht constant
+void GesamtSpielerStatistik::initValues( InitDatei *dat )
+{
+	if( dat->wertExistiert( "SpielerNummer" ) )
+		spielerNummer = *dat->zWert( "SpielerNummer" );
+	if( dat->wertExistiert( "SpielerName" ) )
+		*spielerName = dat->zWert( "SpielerName" )->getText();
+	if( dat->wertExistiert( "TeamName" ) )
+		*teamName = dat->zWert( "TeamName" )->getText();
+	if( dat->wertExistiert( "SpielerFarbe" ) )
+		spielerFarbe = *dat->zWert( "SpielerFarbe" );
+	if( dat->wertExistiert( "TeamFarbe" ) )
+		teamFarbe = *dat->zWert( "TeamFarbe" );
+	if( dat->wertExistiert( "GewonneneRunden" ) )
+		gewonneneRunden = *dat->zWert( "GewonneneRunden" );
+	if( dat->wertExistiert( "Punkte" ) )
+		punkte = *dat->zWert( "Punkte" );
+	if( dat->wertExistiert( "LinienLänge" ) )
+		linienLength = *dat->zWert( "LinienLänge" );
+	if( dat->wertExistiert( "ZeitAmLeben" ) )
+		zeitAmLeben = *dat->zWert( "ZeitAmLeben" );
+	if( dat->wertExistiert( "ZeitTod" ) )
+		zeitTod = *dat->zWert( "ZeitTod" );
+	if( dat->wertExistiert( "Kills" ) )
+		kills = *dat->zWert( "Kills" );
+	if( dat->wertExistiert( "Tode" ) )
+		tode = *dat->zWert( "Tode" );
+	dat->release();
+}
+
+// constant
+int GesamtSpielerStatistik::getSpielerNummer() const
+{
+	return spielerNummer;
+}
+
+Text *GesamtSpielerStatistik::getSpielerName() const
+{
+	return spielerName ? spielerName->getThis() : 0;
+}
+
+Text *GesamtSpielerStatistik::zSpielerName() const
+{
+	return spielerName;
+}
+
+Text *GesamtSpielerStatistik::getTeamName() const
+{
+	return teamName ? teamName->getThis() : 0;
+}
+
+Text *GesamtSpielerStatistik::zTeamName() const
+{
+	return teamName;
+}
+
+int GesamtSpielerStatistik::getSpielerFarbe() const
+{
+	return spielerFarbe;
+}
+
+int GesamtSpielerStatistik::getTeamFarbe() const
+{
+	return teamFarbe;
+}
+
+int GesamtSpielerStatistik::getGewonneneRunden() const
+{
+	return gewonneneRunden;
+}
+
+int GesamtSpielerStatistik::getPunkte() const
+{
+	return punkte;
+}
+
+int GesamtSpielerStatistik::getLinienLength() const
+{
+	return linienLength;
+}
+
+int GesamtSpielerStatistik::getZeitAmLeben() const
+{
+	return zeitAmLeben;
+}
+
+int GesamtSpielerStatistik::getZeitTod() const
+{
+	return zeitTod;
+}
+
+int GesamtSpielerStatistik::getKills() const
+{
+	return kills;
+}
+
+int GesamtSpielerStatistik::getTode() const
+{
+	return tode;
+}
+
+// Reference Counting
+GesamtSpielerStatistik *GesamtSpielerStatistik::getThis()
+{
+	ref++;
+	return this;
+}
+
+GesamtSpielerStatistik *GesamtSpielerStatistik::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 53 - 0
Linie/GesamtSpielerStatistik.h

@@ -0,0 +1,53 @@
+#ifndef GesamtSpielerStatistik_H
+#define GesamtSpielerStatistik_H
+
+#include <Text.h>
+#include <InitDatei.h>
+
+using namespace Framework;
+
+class GesamtSpielerStatistik
+{
+private:
+	int spielerNummer;
+	Text *spielerName;
+	Text *teamName;
+	int spielerFarbe;
+	int teamFarbe;
+	int gewonneneRunden;
+	int punkte;
+	int linienLength;
+	int zeitAmLeben;
+	int zeitTod;
+	int kills;
+	int tode;
+	int ref;
+
+public:
+	// Konstruktor
+	GesamtSpielerStatistik();
+	// Destruktor
+	~GesamtSpielerStatistik();
+	// nicht constant
+	void initValues( InitDatei *dat );
+	// constant
+	int getSpielerNummer() const;
+	Text *getSpielerName() const;
+	Text *zSpielerName() const;
+	Text *getTeamName() const;
+	Text *zTeamName() const;
+	int getSpielerFarbe() const;
+	int getTeamFarbe() const;
+	int getGewonneneRunden() const;
+	int getPunkte() const;
+	int getLinienLength() const;
+	int getZeitAmLeben() const;
+	int getZeitTod() const;
+	int getKills() const;
+	int getTode() const;
+	// Reference Counting
+	GesamtSpielerStatistik *getThis();
+	GesamtSpielerStatistik *release();
+};
+
+#endif

+ 105 - 0
Linie/GesamtTeamStatistik.cpp

@@ -0,0 +1,105 @@
+#include "GesamtTeamStatistik.h"
+
+// Inhalt der GesamtTeamStatistik Klasse aus GesamtTeamStatistik.h
+// Konstruktor
+GesamtTeamStatistik::GesamtTeamStatistik()
+{
+	teamNummer = 0;
+	teamName = new Text();
+	teamFarbe = 0;
+	gewonneneRunden = 0;
+	punkte = 0;
+	linienLength = 0;
+	kills = 0;
+	tode = 0;
+	ref = 1;
+}
+
+// Destruktor
+GesamtTeamStatistik::~GesamtTeamStatistik()
+{
+	teamName->release();
+}
+
+// nicht constant
+void GesamtTeamStatistik::initValues( InitDatei *dat )
+{
+	if( dat->wertExistiert( "TeamNummer" ) )
+		teamNummer = *dat->zWert( "TeamNummer" );
+	if( dat->wertExistiert( "TeamName" ) )
+		*teamName = dat->zWert( "TeamName" )->getText();
+	if( dat->wertExistiert( "TeamFarbe" ) )
+		teamFarbe = *dat->zWert( "TeamFarbe" );
+	if( dat->wertExistiert( "GewonneneRunden" ) )
+		gewonneneRunden = *dat->zWert( "GewonneneRunden" );
+	if( dat->wertExistiert( "Punkte" ) )
+		punkte = *dat->zWert( "Punkte" );
+	if( dat->wertExistiert( "LinienLänge" ) )
+		linienLength = *dat->zWert( "LinienLänge" );
+	if( dat->wertExistiert( "Kills" ) )
+		kills = *dat->zWert( "Kills" );
+	if( dat->wertExistiert( "Tode" ) )
+		tode = *dat->zWert( "Tode" );
+	dat->release();
+}
+
+// constant
+int GesamtTeamStatistik::getTeamNummer() const
+{
+	return teamNummer;
+}
+
+Text *GesamtTeamStatistik::getTeamName() const
+{
+	return teamName ? teamName->getThis() : 0;
+}
+
+Text *GesamtTeamStatistik::zTeamName() const
+{
+	return teamName;
+}
+
+int GesamtTeamStatistik::getTeamFarbe() const
+{
+	return teamFarbe;
+}
+
+int GesamtTeamStatistik::getGewonneneRunden() const
+{
+	return gewonneneRunden;
+}
+
+int GesamtTeamStatistik::getPunkte() const
+{
+	return punkte;
+}
+
+int GesamtTeamStatistik::getLinienLength() const
+{
+	return linienLength;
+}
+
+int GesamtTeamStatistik::getKills() const
+{
+	return kills;
+}
+
+int GesamtTeamStatistik::getTode() const
+{
+	return tode;
+}
+
+// Reference Counting
+GesamtTeamStatistik *GesamtTeamStatistik::getThis()
+{
+	ref++;
+	return this;
+}
+
+GesamtTeamStatistik *GesamtTeamStatistik::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 44 - 0
Linie/GesamtTeamStatistik.h

@@ -0,0 +1,44 @@
+#ifndef GesamtTeamStatistik_H
+#define GesamtTeamStatistik_H
+
+#include <Text.h>
+#include <InitDatei.h>
+
+using namespace Framework;
+
+class GesamtTeamStatistik
+{
+private:
+	int teamNummer;
+	Text *teamName;
+	int teamFarbe;
+	int gewonneneRunden;
+	int punkte;
+	int linienLength;
+	int kills;
+	int tode;
+	int ref;
+
+public:
+	// Konstruktor
+	GesamtTeamStatistik();
+	// Destruktor
+	~GesamtTeamStatistik();
+	// nicht constant
+	void initValues( InitDatei *dat );
+	// constant
+	int getTeamNummer() const;
+	Text *getTeamName() const;
+	Text *zTeamName() const;
+	int getTeamFarbe() const;
+	int getGewonneneRunden() const;
+	int getPunkte() const;
+	int getLinienLength() const;
+	int getKills() const;
+	int getTode() const;
+	// Reference Counting
+	GesamtTeamStatistik *getThis();
+	GesamtTeamStatistik *release();
+};
+
+#endif

+ 67 - 0
Linie/Karte.cpp

@@ -0,0 +1,67 @@
+#include "Karte.h"
+#include <Punkt.h>
+
+// Inhalt der Karte Klasse aus Karte.h
+// Konstruktor
+Karte::Karte()
+{
+	id = 0;
+	map = new Bild();
+	size = Punkt( 0, 0 );
+	ref = 1;
+}
+
+// Destruktor
+Karte::~Karte()
+{
+	map->release();
+}
+
+// nicht constant
+void Karte::setKarteId( int id )
+{
+	this->id = id;
+}
+
+void Karte::setSize( int br, int hi )
+{
+	map->neuBild( br, hi, 0 );
+	size.x = br;
+	size.y = hi;
+}
+
+// constant
+int Karte::getKarteId() const
+{
+	return id;
+}
+
+int Karte::getBreite() const
+{
+	return size.x;
+}
+
+int Karte::getHeight() const
+{
+	return size.y;
+}
+
+Bild *Karte::zMap() const
+{
+	return ( map->getBreite() != 0 && map->getHeight() != 0 ) ? map : 0;
+}
+
+// Reference Counting
+Karte *Karte::getThis()
+{
+	ref++;
+	return this;
+}
+
+Karte *Karte::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 34 - 0
Linie/Karte.h

@@ -0,0 +1,34 @@
+#ifndef Karte_H
+#define Karte_H
+
+#include <Bild.h>
+
+using namespace Framework;
+
+class Karte
+{
+private:
+	int id;
+	Bild *map;
+	Punkt size;
+	int ref;
+
+public:
+	// Konstruktor
+	Karte();
+	// Destruktor
+	~Karte();
+	// nicht constant
+	void setKarteId( int id );
+	void setSize( int br, int hi );
+	// constant
+	int getKarteId() const;
+	int getBreite() const;
+	int getHeight( ) const;
+	Bild *zMap( ) const;
+	// Reference Counting
+	Karte *getThis();
+	Karte *release();
+};
+
+#endif

+ 114 - 0
Linie/KartenLeser.cpp

@@ -0,0 +1,114 @@
+#include "KartenLeser.h"
+#include <Datei.h>
+
+// Inhalt der KartenLeser Klasse aus KartenLeser.h
+// Kontruktor
+KartenLeser::KartenLeser( int karteId, SSDatenbankV *db, char *mapPfad )
+{
+	this->karteId = karteId;
+	this->db = db;
+	pfad = new Text( mapPfad );
+	ref = 1;
+}
+
+// Destruktor
+KartenLeser::~KartenLeser()
+{
+	db->release();
+	if( pfad )
+		pfad->release();
+}
+
+// nicht constant
+bool KartenLeser::ladeSpielerTeamStruktur( SpielerTeamStruktur *zSts )
+{
+	if( !pfad )
+		return 0;
+	Text *pf = new Text( pfad->getText() );
+	pf->append( "sts.ltgd" );
+	Datei *datei = new Datei();
+	datei->setDatei( pf );
+	if( !datei->existiert() || datei->istOrdner() )
+	{
+		datei->release();
+		return 0;
+	}
+	datei->open( Datei::Style::lesen );
+	datei->lese( (char*)&zSts->spielerAnzahl, 4 );
+	datei->lese( (char*)&zSts->teamAnzahl, 4 );
+	if( zSts->spielerFarbe )
+		zSts->spielerFarbe->release();
+	zSts->spielerFarbe = new Array< int >();
+	for( int i = 0; i < zSts->spielerAnzahl; i++ )
+	{
+		int farbe = 0;
+		datei->lese( (char*)&farbe, 4 );
+		zSts->spielerFarbe->set( farbe, i );
+	}
+	if( zSts->teamFarbe )
+		zSts->teamFarbe->release();
+	zSts->teamFarbe = new Array< int >();
+	for( int i = 0; i < zSts->teamAnzahl; i++ )
+	{
+		int farbe = 0;
+		datei->lese( (char*)&farbe, 4 );
+		zSts->teamFarbe->set( farbe, i );
+	}
+	if( zSts->teamName )
+		zSts->teamName->release();
+	zSts->teamName = new RCArray< Text >();
+	for( int i = 0; i < zSts->teamAnzahl; i++ )
+	{
+		char len = 0;
+		datei->lese( &len, 1 );
+		char *txt = new char[ len + 1 ];
+		txt[ (int)len ] = 0;
+		datei->lese( txt, len );
+		Text *name = new Text( txt );
+		delete[] txt;
+		zSts->teamName->set( name, i );
+	}
+	if( zSts->teamSize )
+		zSts->teamSize->release();
+	zSts->teamSize = new Array< int >();
+	for( int i = 0; i < zSts->teamAnzahl; i++ )
+	{
+		int size = 0;
+		datei->lese( (char*)&size, 4 );
+		zSts->teamSize->set( size, i );
+	}
+	datei->close();
+	datei->release();
+	return 1;
+}
+
+// constant
+int KartenLeser::getKarteId() const
+{
+	return karteId;
+}
+
+Text *KartenLeser::getPfad() const
+{
+	return pfad ? pfad->getThis() : 0;
+}
+
+Text *KartenLeser::zPfad() const
+{
+	return pfad;
+}
+
+// Reference Counting
+KartenLeser *KartenLeser::getThis()
+{
+	ref++;
+	return this;
+}
+
+KartenLeser *KartenLeser::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 31 - 0
Linie/KartenLeser.h

@@ -0,0 +1,31 @@
+#ifndef KartenLeser_H
+#define KartenLeser_H
+
+#include "SSDatenbankV.h"
+#include "Strukturen.h"
+
+class KartenLeser
+{
+private:
+	SSDatenbankV *db;
+	Text *pfad;
+	int karteId;
+	int ref;
+
+public:
+	// Kontruktor
+    KartenLeser( int karteId, SSDatenbankV *db, char *mapPfad );
+	// Destruktor
+	~KartenLeser();
+	// nicht constant
+	bool ladeSpielerTeamStruktur( SpielerTeamStruktur *zSts );
+	// constant
+	int getKarteId() const;
+	Text *getPfad() const;
+	Text *zPfad() const;
+	// Reference Counting
+	KartenLeser *getThis();
+	KartenLeser *release();
+};
+
+#endif

+ 497 - 0
Linie/Klient.cpp

@@ -0,0 +1,497 @@
+#include "Klient.h"
+#include "Spieler.h"
+#include <Text.h>
+
+// Inhalt der Klient Klasse aus Klient.h
+// Konstruktor
+Klient::Klient( SSKlientV *klient )
+{
+	this->klient = klient;
+	ref = 1;
+}
+
+// Destruktor
+Klient::~Klient()
+{
+	if( klient )
+		klient->release();
+}
+
+// nicht constant
+void Klient::offline()
+{
+	klient = klient->release();
+}
+
+void Klient::online( SSKlientV *zKlient )
+{
+	if( klient )
+		klient = klient->release();
+	klient = zKlient->getThis();
+}
+
+void Klient::sendeSpielerNummer( int sNum, double spielZeit )
+{
+	if( !klient )
+		return;
+	short len = 13;
+	char *bytes = new char[ len ];
+	*(double*)bytes = spielZeit;
+	*(char*)( bytes + 8 ) = 0;
+	*(int*)( bytes + 9 ) = sNum;
+	klient->spielNachricht( len, bytes );
+	delete[] bytes;
+}
+
+void Klient::sendeInitSpieler( int anzahl, RCArray< Spieler > *zSpieler, double spielZeit )
+{
+	if( !klient )
+		return;
+	short len = (short)( 13 + 20 * anzahl );
+	char *bytes = new char[ len ];
+	*(double*)bytes = spielZeit;
+	*(char*)( bytes + 8 ) = 1;
+	*(int*)( bytes + 9 ) = anzahl;
+	for( int i = 0; i < anzahl; i++ )
+	{
+		*(int*)( bytes + i * 20 + 13 ) = zSpieler->z( i )->getSpielerNummer();
+		*(int*)( bytes + i * 20 + 17 ) = zSpieler->z( i )->getSpielerTeam();
+		*(int*)( bytes + i * 20 + 21 ) = zSpieler->z( i )->getSpielerFarbe();
+		*(int*)( bytes + i * 20 + 25 ) = zSpieler->z( i )->getTeamFarbe();
+		*(int*)( bytes + i * 20 + 29 ) = zSpieler->z( i )->getAccountId();
+	}
+	klient->spielNachricht( len, bytes );
+	delete[] bytes;
+}
+
+void Klient::sendeSpielerPosition( Spieler *zSpieler, double spielZeit )
+{
+	if( !klient )
+		return;
+	short len = 29;
+	char *bytes = new char[ len ];
+	*(double*)bytes = spielZeit;
+	*(char*)( bytes + 8 ) = 2;
+	*(int*)( bytes + 9 ) = zSpieler->getSpielerNummer();
+	*(double*)( bytes + 13 ) = zSpieler->getX();
+	*(double*)( bytes + 21 ) = zSpieler->getY();
+	klient->spielNachricht( len, bytes );
+	delete[] bytes;
+}
+
+void Klient::sendeKammeraSize( int br, int hi, double spielZeit )
+{
+	if( !klient )
+		return;
+	short len = 17;
+	char *bytes = new char[ len ];
+	*(double*)bytes = spielZeit;
+	*(char*)( bytes + 8 ) = 3;
+	*(int*)( bytes + 9 ) = br;
+	*(int*)( bytes + 13 ) = hi;
+	klient->spielNachricht( len, bytes );
+	delete[] bytes;
+}
+
+void Klient::sendeStart( double spielZeit )
+{
+	if( !klient )
+		return;
+	short len = 9;
+	char *bytes = new char[ len ];
+	*(double*)bytes = spielZeit;
+	*(char*)( bytes + 8 ) = 4;
+	klient->spielNachricht( len, bytes );
+	delete[] bytes;
+}
+
+void Klient::sendeSpielerTod( Spieler *zSpieler, double spielZeit )
+{
+	if( !klient )
+		return;
+	short len = 13;
+	char *bytes = new char[ len ];
+	*(double*)bytes = spielZeit;
+	*(char*)( bytes + 8 ) = 5;
+	*(int*)( bytes + 9 ) = zSpieler->getSpielerNummer();
+	klient->spielNachricht( len, bytes );
+	delete[] bytes;
+}
+
+void Klient::sendeSpielEnde( char gewonnen, double spielZeit )
+{
+	if( !klient )
+		return;
+	short len = 10;
+	char *bytes = new char[ len ];
+	*(double*)bytes = spielZeit;
+	*(char*)( bytes + 8 ) = 6;
+	*(char*)( bytes + 9 ) = gewonnen;
+	klient->spielNachricht( len, bytes );
+	delete[] bytes;
+}
+
+void Klient::sendeSpielerGeschwindigkeit( Spieler *zSpieler, double spielZeit )
+{
+	if( !klient )
+		return;
+	short len = 29;
+	char *bytes = new char[ len ];
+	*(double*)bytes = spielZeit;
+	*(char*)( bytes + 8 ) = 7;
+	*(int*)( bytes + 9 ) = zSpieler->getSpielerNummer();
+	*(double*)( bytes + 13 ) = zSpieler->getSpeedX();
+	*(double*)( bytes + 21 ) = zSpieler->getSpeedY();
+	klient->spielNachricht( len, bytes );
+	delete[] bytes;
+}
+
+void Klient::sendeSpielerWendigkeit( Spieler *zSpieler, double spielZeit )
+{
+	if( !klient )
+		return;
+	short len = 21;
+	char *bytes = new char[ len ];
+	*(double*)bytes = spielZeit;
+	*(char*)( bytes + 8 ) = 8;
+	*(int*)( bytes + 9 ) = zSpieler->getSpielerNummer();
+	*(double*)( bytes + 13 ) = zSpieler->getKurve();
+	klient->spielNachricht( len, bytes );
+	delete[] bytes;
+}
+
+void Klient::sendeSpielerKurve( int sNum, char kurve, double spielZeit )
+{
+	if( !klient )
+		return;
+	short len = 14;
+	char *bytes = new char[ len ];
+	*(double*)bytes = spielZeit;
+	*(char*)( bytes + 8 ) = 9;
+	*(int*)( bytes + 9 ) = sNum;
+	bytes[ 13 ] = kurve;
+	klient->spielNachricht( len, bytes );
+	delete[] bytes;
+}
+
+void Klient::sendeKartenSize( int br, int hi, double spielZeit )
+{
+	if( !klient )
+		return;
+	short len = 17;
+	char *bytes = new char[ len ];
+	*(double*)bytes = spielZeit;
+	*(char*)( bytes + 8 ) = 0xA;
+	*(int*)( bytes + 9 ) = br;
+	*(int*)( bytes + 13 ) = hi;
+	klient->spielNachricht( len, bytes );
+	delete[] bytes;
+}
+
+void Klient::sendeChatNachricht( char *txt, double spielZeit )
+{
+	if( !klient )
+		return;
+	short len = (short)( 9 + textLength( txt ) );
+	char *bytes = new char[ len ];
+	*(double*)bytes = spielZeit;
+	*(char*)( bytes + 8 ) = 0xB;
+	for( int i = 9; i < len; i++ )
+		bytes[ i ] = txt[ i - 9 ];
+	klient->spielNachricht( len, bytes );
+	delete[] bytes;
+}
+
+void Klient::sendeLinienUnterbrechung( int sNum, bool unterbrochen, double spielZeit )
+{
+	if( !klient )
+		return;
+	char *bytes = new char[ 14 ];
+	*(double*)bytes = spielZeit;
+	*(char*)( bytes + 8 ) = 0xC;
+	*(int*)( bytes + 9 ) = sNum;
+	*( bytes + 13 ) = (char)unterbrochen;
+	klient->spielNachricht( 14, bytes );
+	delete[] bytes;
+}
+
+void Klient::sendeTeamMaxPunkte( int team, int mP, double spielZeit )
+{
+	if( !klient )
+		return;
+	char *bytes = new char[ 17 ];
+	*(double*)bytes = spielZeit;
+	*(char*)( bytes + 8 ) = 0xD;
+	*(int*)( bytes + 9 ) = team;
+	*(int*)( bytes + 13 ) = mP;
+	klient->spielNachricht( 17, bytes );
+	delete[] bytes;
+}
+
+void Klient::sendeTeamPunkte( int team, int p, double spielZeit )
+{
+	if( !klient )
+		return;
+	char *bytes = new char[ 17 ];
+	*(double*)bytes = spielZeit;
+	*(char*)( bytes + 8 ) = 0xE;
+	*(int*)( bytes + 9 ) = team;
+	*(int*)( bytes + 13 ) = p;
+	klient->spielNachricht( 17, bytes );
+	delete[] bytes;
+}
+
+void Klient::sendeSpielerPunkte( int sNum, int p, double spielZeit )
+{
+	if( !klient )
+		return;
+	char *bytes = new char[ 17 ];
+	*(double*)bytes = spielZeit;
+	*(char*)( bytes + 8 ) = 0xF;
+	*(int*)( bytes + 9 ) = sNum;
+	*(int*)( bytes + 13 ) = p;
+	klient->spielNachricht( 17, bytes );
+	delete[] bytes;
+}
+
+void Klient::sendeTeamTod( int team, double spielZeit )
+{
+	if( !klient )
+		return;
+	char *bytes = new char[ 13 ];
+	*(double*)bytes = spielZeit;
+	*(char*)( bytes + 8 ) = 0x10;
+	*(int*)( bytes + 9 ) = team;
+	klient->spielNachricht( 13, bytes );
+	delete[] bytes;
+}
+
+void Klient::sendeTeamName( int team, char *name )
+{
+	if( !klient )
+		return;
+	int nL = textLength( name );
+	char *bytes = new char[ 13 + nL ];
+	*(double*)bytes = 0;
+	*(char*)( bytes + 8 ) = 0x13;
+	*(int*)( bytes + 9 ) = team;
+	memcpy( bytes + 13, name, nL );
+	klient->spielNachricht( (short)( 13 + nL ), bytes );
+	delete[] bytes;
+}
+
+void Klient::sendeRundenEnde( int winTeam, double spielZeit )
+{
+	if( !klient )
+		return;
+	char *bytes = new char[ 13 ];
+	*(double*)bytes = spielZeit;
+	*(char*)( bytes + 8 ) = 0x11;
+	*(int*)( bytes + 9 ) = winTeam;
+	klient->spielNachricht( 13, bytes );
+	delete[] bytes;
+}
+
+void Klient::sendeZeitVerbleibend( int sekunden, double spielZeit )
+{
+	if( !klient )
+		return;
+	char *bytes = new char[ 13 ];
+	*(double*)bytes = spielZeit;
+	*(char*)( bytes + 8 ) = 0x12;
+	*(int*)( bytes + 9 ) = sekunden;
+	klient->spielNachricht( 13, bytes );
+	delete[] bytes;
+}
+
+void Klient::sendeStatistikChatNachricht( int vonAccount, char *txt )
+{
+	if( !klient )
+		return;
+	short len = (short)( 5 + textLength( txt ) );
+	char *bytes = new char[ len ];
+	*(char*)( bytes ) = 8;
+	*(int*)( bytes + 1 ) = vonAccount;
+	for( int i = 5; i < len; i++ )
+		bytes[ i ] = txt[ i - 5 ];
+	klient->statistikNachricht( len, bytes );
+	delete[] bytes;
+}
+
+void Klient::sendeStatistikSpielerOffline( int account )
+{
+	if( !klient )
+		return;
+	char *bytes = new char[ 5 ];
+	*(char*)( bytes ) = 9;
+	*(int*)( bytes + 1 ) = account;
+	klient->statistikNachricht( 5, bytes );
+	delete[] bytes;
+}
+
+void Klient::sendeGesamtSpielerStatistik( GesamtSpielerStatistik *zS )
+{
+	if( !zS || !klient )
+		return;
+	char snl = (char)zS->zSpielerName()->getLength();
+	char tnl = (char)zS->zTeamName()->getLength();
+	int len = 43 + snl + tnl;
+	char *bytes = new char[ len ];
+	bytes[ 0 ] = 2;
+	*(int*)( bytes + 1 ) = zS->getSpielerNummer();
+	*(char*)( bytes + 5 ) = (char)zS->zSpielerName()->getLength();
+	for( int i = 0; i < snl; i++ )
+		bytes[ i + 6 ] = zS->zSpielerName()->getText()[ i ];
+	*(char*)( bytes + 6 + snl ) = tnl;
+	for( int i = 0; i < tnl; i++ )
+		bytes[ i + 7 + snl ] = zS->zTeamName()->getText()[ i ];
+	*(int*)( bytes + 7 + snl + tnl ) = zS->getSpielerFarbe();
+	*(int*)( bytes + 11 + snl + tnl ) = zS->getTeamFarbe();
+	*(int*)( bytes + 15 + snl + tnl ) = zS->getGewonneneRunden();
+	*(int*)( bytes + 19 + snl + tnl ) = zS->getPunkte();
+	*(int*)( bytes + 23 + snl + tnl ) = zS->getLinienLength();
+	*(int*)( bytes + 27 + snl + tnl ) = zS->getZeitAmLeben();
+	*(int*)( bytes + 31 + snl + tnl ) = zS->getZeitTod();
+	*(int*)( bytes + 35 + snl + tnl ) = zS->getKills();
+	*(int*)( bytes + 39 + snl + tnl ) = zS->getTode();
+	klient->statistikNachricht( (short)len, bytes );
+	delete[] bytes;
+}
+
+void Klient::sendeGesamtTeamStatistik( GesamtTeamStatistik *zS )
+{
+	if( !zS || !klient )
+		return;
+	char tnl = (char)zS->zTeamName()->getLength();
+	int len = 30 + tnl;
+	char *bytes = new char[ len ];
+	bytes[ 0 ] = 3;
+	*(int*)( bytes + 1 ) = zS->getTeamNummer();
+	*(char*)( bytes + 5 ) = tnl;
+	for( int i = 0; i < tnl; i++ )
+		bytes[ i + 6 ] = zS->zTeamName()->getText()[ i ];
+	*(int*)( bytes + 6 + tnl ) = zS->getTeamFarbe();
+	*(int*)( bytes + 10 + tnl ) = zS->getGewonneneRunden();
+	*(int*)( bytes + 14 + tnl ) = zS->getPunkte();
+	*(int*)( bytes + 18 + tnl ) = zS->getLinienLength();
+	*(int*)( bytes + 22 + tnl ) = zS->getKills();
+	*(int*)( bytes + 26 + tnl ) = zS->getTode();
+	klient->statistikNachricht( (short)len, bytes );
+	delete[] bytes;
+}
+
+void Klient::sendeRundeStatistik( RundenRundenStatistik *zS )
+{
+	if( !zS || !klient )
+		return;
+	char *bytes = new char[ 25 ];
+	bytes[ 0 ] = 4;
+	*(int*)( bytes + 1 ) = zS->getRundenNummer();
+	*(int*)( bytes + 5 ) = zS->getRundenDauer();
+	*(int*)( bytes + 9 ) = zS->getSiegerTeam();
+	*(int*)( bytes + 13 ) = zS->getSpielFeldNutzung();
+	*(int*)( bytes + 17 ) = zS->zRundenBild()->getBreite();
+	*(int*)( bytes + 21 ) = zS->zRundenBild()->getHeight();
+	klient->statistikNachricht( 25, bytes );
+	delete[] bytes;
+	Bild *zB = zS->zRundenBild();
+	int pixel = zB->getBreite() * zB->getHeight();
+	while( pixel )
+	{
+		int pStart = zB->getBreite() * zB->getHeight() - pixel;
+		int pLen = pixel > 200 ? 200 : pixel;
+		char *bytes = new char[ 13 + pLen * 4 ];
+		bytes[ 0 ] = 5;
+		*(int*)( bytes + 1 ) = zS->getRundenNummer();
+		*(int*)( bytes + 5 ) = pStart;
+		*(int*)( bytes + 9 ) = pLen;
+		for( int i = 0; i < pLen; i++ )
+			*(int*)( bytes + 13 + i * 4 ) = zB->getBuffer()[ pStart + i ];
+		klient->statistikNachricht( (short)( 13 + pLen * 4 ), bytes );
+		delete[] bytes;
+		pixel -= pLen;
+	}
+	int anz = zS->getSpielerAnzahl();
+	for( int i = 0; i < anz; i++ )
+		sendeRundeSpielerStatistik( zS->zSpielerStatistik( i ), zS->getRundenNummer() );
+	anz = zS->getTeamAnzahl();
+	for( int i = 0; i < anz; i++ )
+		sendeRundeTeamStatistik( zS->zTeamStatistik( i ), zS->getRundenNummer() );
+}
+
+void Klient::sendeRundeSpielerStatistik( RundenSpielerStatistik *zS, int runde )
+{
+	if( !zS || !klient )
+		return;
+	char snl = (char)zS->zSpielerName()->getLength();
+	char tnl = (char)zS->zTeamName()->getLength();
+	int len = 31 + snl + tnl;
+	char *bytes = new char[ len ];
+	bytes[ 0 ] = 6;
+	*(int*)( bytes + 1 ) = runde;
+	*(int*)( bytes + 5 ) = zS->getSpielerNummer();
+	*(char*)( bytes + 9 ) = snl;
+	for( int i = 0; i < snl; i++ )
+		bytes[ i + 10 ] = zS->zSpielerName()->getText()[ i ];
+	*(char*)( bytes + 10 + snl ) = tnl;
+	for( int i = 0; i < tnl; i++ )
+		bytes[ i + 11 + snl ] = zS->zTeamName()->getText()[ i ];
+	*(int*)( bytes + 11 + snl + tnl ) = zS->getSpielerFarbe();
+	*(int*)( bytes + 15 + snl + tnl ) = zS->getTeamFarbe();
+	*(int*)( bytes + 19 + snl + tnl ) = zS->getLinienLength();
+	*(int*)( bytes + 23 + snl + tnl ) = zS->getKills();
+	*(int*)( bytes + 27 + snl + tnl ) = zS->getTodesZeit();
+	klient->statistikNachricht( (short)len, bytes );
+	delete[] bytes;
+}
+
+void Klient::sendeRundeTeamStatistik( RundenTeamStatistik *zS, int runde )
+{
+	if( !zS || !klient )
+		return;
+	char tnl = (char)zS->zTeamName()->getLength();
+	int len = 27 + tnl;
+	char *bytes = new char[ len ];
+	bytes[ 0 ] = 7;
+	*(int*)( bytes + 1 ) = runde;
+	*(int*)( bytes + 5 ) = zS->getTeamNummer();
+	*(char*)( bytes + 9 ) = tnl;
+	for( int i = 0; i < tnl; i++ )
+		bytes[ i + 10 ] = zS->zTeamName()->getText()[ i ];
+	*(int*)( bytes + 10 + tnl ) = zS->getTeamFarbe();
+	*(char*)( bytes + 14 + tnl ) = (char)zS->getErgebnis();
+	*(int*)( bytes + 15 + tnl ) = zS->getLinienLength();
+	*(int*)( bytes + 19 + tnl ) = zS->getKills();
+	*(int*)( bytes + 23 + tnl ) = zS->getTode();
+	klient->statistikNachricht( (short)len, bytes );
+	delete[] bytes;
+}
+
+void Klient::sendeStatistikLadenFertig()
+{
+	if( !klient )
+		return;
+	char byte = 1;
+	klient->statistikNachricht( 1, &byte );
+}
+
+// constant
+bool Klient::istOnline() const
+{
+	return klient != 0;
+}
+
+// reference Counting
+Klient *Klient::getThie()
+{
+	ref++;
+	return this;
+}
+
+Klient *Klient::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 63 - 0
Linie/Klient.h

@@ -0,0 +1,63 @@
+#ifndef Klient_H
+#define Klient_H
+
+#include "SSKlientV.h"
+#include <Array.h>
+#include "GesamtSpielerStatistik.h"
+#include "GesamtTeamStatistik.h"
+#include "RundenRundenStatistik.h"
+
+using namespace Framework;
+
+class Spieler;
+
+class Klient
+{
+private:
+	SSKlientV *klient;
+	int ref;
+
+public:
+	// Konstruktor
+	Klient( SSKlientV *klient );
+	// Destruktor
+	~Klient();
+	// nicht constant
+	void offline();
+	void online( SSKlientV *zKlient );
+	void sendeSpielerNummer( int sNum, double spielZeit );
+	void sendeInitSpieler( int anzahl, RCArray< Spieler > *zSpieler, double spielZeit );
+	void sendeSpielerPosition( Spieler *zSpieler, double spielZeit );
+	void sendeKammeraSize( int br, int hi, double spielZeit );
+	void sendeStart( double spielZeit );
+	void sendeSpielerTod( Spieler *zSpieler, double spielZeit );
+	void sendeSpielEnde( char gewonnen, double spielZeit );
+	void sendeSpielerGeschwindigkeit( Spieler *zSpieler, double spielZeit );
+	void sendeSpielerWendigkeit( Spieler *zSpieler, double spielZeit );
+	void sendeSpielerKurve( int sNum, char kurve, double spielZeit );
+	void sendeKartenSize( int br, int hi, double spielZeit );
+	void sendeChatNachricht( char *txt, double spielZeit );
+	void sendeLinienUnterbrechung( int sNum, bool unterbrochen, double spielZeit );
+	void sendeTeamMaxPunkte( int team, int mP, double spielZeit );
+	void sendeTeamPunkte( int team, int p, double spielZeit );
+	void sendeSpielerPunkte( int sNum, int mP, double spielZeit );
+	void sendeTeamTod( int team, double spielZeit );
+	void sendeTeamName( int team, char *name );
+	void sendeRundenEnde( int winTeam, double spielZeit );
+	void sendeZeitVerbleibend( int sekunden, double spielZeit );
+	void sendeStatistikChatNachricht( int vonAccount, char *txt );
+	void sendeStatistikSpielerOffline( int account );
+	void sendeGesamtSpielerStatistik( GesamtSpielerStatistik *zS );
+	void sendeGesamtTeamStatistik( GesamtTeamStatistik *zS );
+	void sendeRundeStatistik( RundenRundenStatistik *zS );
+	void sendeRundeSpielerStatistik( RundenSpielerStatistik *zS, int runde );
+	void sendeRundeTeamStatistik( RundenTeamStatistik *zS, int runde );
+	void sendeStatistikLadenFertig();
+	// constant
+	bool istOnline() const;
+	// reference Counting
+	Klient *getThie();
+	Klient *release();
+};
+
+#endif

+ 223 - 0
Linie/Linie.vcxproj

@@ -0,0 +1,223 @@
+<?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>
+  <ItemGroup>
+    <ClInclude Include="Bestenliste.h" />
+    <ClInclude Include="GesamtSpielerStatistik.h" />
+    <ClInclude Include="GesamtTeamStatistik.h" />
+    <ClInclude Include="Karte.h" />
+    <ClInclude Include="KartenLeser.h" />
+    <ClInclude Include="Klient.h" />
+    <ClInclude Include="RundenRundenStatistik.h" />
+    <ClInclude Include="RundenSpielerStatistik.h" />
+    <ClInclude Include="RundenTeamStatistik.h" />
+    <ClInclude Include="Spiel.h" />
+    <ClInclude Include="Spieler.h" />
+    <ClInclude Include="SpielKlasse.h" />
+    <ClInclude Include="SSDatenbankV.h" />
+    <ClInclude Include="SSKlientV.h" />
+    <ClInclude Include="Statistik.h" />
+    <ClInclude Include="StatistikKlasse.h" />
+    <ClInclude Include="Strukturen.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="Bestenliste.cpp" />
+    <ClCompile Include="DllStart.cpp" />
+    <ClCompile Include="GesamtSpielerStatistik.cpp" />
+    <ClCompile Include="GesamtTeamStatistik.cpp" />
+    <ClCompile Include="Karte.cpp" />
+    <ClCompile Include="KartenLeser.cpp" />
+    <ClCompile Include="Klient.cpp" />
+    <ClCompile Include="RundenRundenStatistik.cpp" />
+    <ClCompile Include="RundenSpielerStatistik.cpp" />
+    <ClCompile Include="RundenTeamStatistik.cpp" />
+    <ClCompile Include="Spiel.cpp" />
+    <ClCompile Include="Spieler.cpp" />
+    <ClCompile Include="Statistik.cpp" />
+    <ClCompile Include="Strukturen.cpp" />
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{23977C5D-04A4-4EA2-A334-79D0137EEF68}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>Linie</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v141</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v141</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v141</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</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\sql\sql;$(IncludePath)</IncludePath>
+    <LibraryPath>..\..\..\..\..\Allgemein\Framework\x64\Debug;..\..\..\..\..\Allgemein\sql\x64\Debug;$(LibraryPath)</LibraryPath>
+    <CustomBuildBeforeTargets>Build</CustomBuildBeforeTargets>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <IncludePath>..\..\..\..\..\Allgemein\Framework;$(IncludePath)</IncludePath>
+    <LibraryPath>..\..\..\..\..\Allgemein\Framework\Release;$(LibraryPath)</LibraryPath>
+    <CustomBuildBeforeTargets>Build</CustomBuildBeforeTargets>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+    <IncludePath>..\..\..\..\..\Allgemein\Framework;$(IncludePath)</IncludePath>
+    <LibraryPath>..\..\..\..\..\Allgemein\Framework\x64\Release;$(LibraryPath)</LibraryPath>
+    <CustomBuildBeforeTargets>Build</CustomBuildBeforeTargets>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;LINIE_EXPORTS;%(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;_USRDLL;LINIE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>framework.lib;sql.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+    <CustomBuildStep>
+      <Command>copy "..\x64\Debug\Linie.dll" "..\..\..\..\Server\Spiel Server\spiele\Linie\bin\Linie.dll"</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;_USRDLL;LINIE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>framework.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+    <CustomBuild>
+      <Command>copy "..\Release\Linie.dll" "..\..\..\..\Server\x32\spiele\Linie\bin\linie.dll"</Command>
+    </CustomBuild>
+    <CustomBuild>
+      <Outputs>kopieren...;%(Outputs)</Outputs>
+    </CustomBuild>
+    <CustomBuildStep>
+      <Command>copy "..\Release\Linie.dll" "..\..\..\..\Server\Fertig\x32\spiele\Linie\bin\Linie.dll"</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;_USRDLL;LINIE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>framework.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+    <CustomBuild>
+      <Command>copy "..\x64\Release\Linie.dll" "..\..\..\..\Server\x64\spiele\Linie\bin\linie.dll"</Command>
+    </CustomBuild>
+    <CustomBuild>
+      <Outputs>kopieren...;%(Outputs)</Outputs>
+    </CustomBuild>
+    <CustomBuildStep>
+      <Command>copy "..\x64\Release\Linie.dll" "..\..\..\..\Server\Fertig\x64\spiele\Linie\bin\Linie.dll"</Command>
+    </CustomBuildStep>
+    <CustomBuildStep>
+      <Outputs>kopieren...;%(Outputs)</Outputs>
+    </CustomBuildStep>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>

+ 147 - 0
Linie/Linie.vcxproj.filters

@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Datenbank">
+      <UniqueIdentifier>{f9b86396-8b8d-4072-a4ba-b974ba2a6757}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Leser">
+      <UniqueIdentifier>{d4bda9b8-ea2b-426a-91bd-69177f1bc307}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Netzwerk">
+      <UniqueIdentifier>{cdd8cfc2-e1a9-4d99-a50c-4bdb773cf94e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Spiel">
+      <UniqueIdentifier>{0a78d23c-a0a5-4827-a19c-797935b0fe3e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Start">
+      <UniqueIdentifier>{7ec7bd3b-b17d-496d-9958-2ca919d031d7}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Statistik">
+      <UniqueIdentifier>{5b0fbf37-0913-4b2f-aabf-d4d997031300}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Statistik\Gesamt">
+      <UniqueIdentifier>{1543c096-ebf9-40a5-831d-fdad1a695f65}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Statistik\Runden">
+      <UniqueIdentifier>{6267586e-60e5-4a39-bab6-f9b74b41d493}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Statistik\Gesamt\Team">
+      <UniqueIdentifier>{a6175fa5-01fe-4545-8797-850378528e0d}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Statistik\Gesamt\Spieler">
+      <UniqueIdentifier>{9c7cf2b3-3036-466c-9998-a68b5f84cb2c}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Statistik\Runden\Spieler">
+      <UniqueIdentifier>{e88ad75c-e356-49cb-b534-9e2ab8377d4f}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Statistik\Runden\Team">
+      <UniqueIdentifier>{729bb387-fc3f-4bfc-88a3-12f2aeda1241}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Spiel\Bestenliste">
+      <UniqueIdentifier>{23af21af-92a6-4ba2-b10a-34e131a325ab}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Spiel\Spieler">
+      <UniqueIdentifier>{b29b4e9c-a17b-4a54-a292-1bad0d7e2661}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Spiel\Karte">
+      <UniqueIdentifier>{537763c3-2797-42d6-a340-6e84452f7026}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="SSDatenbankV.h">
+      <Filter>Datenbank</Filter>
+    </ClInclude>
+    <ClInclude Include="KartenLeser.h">
+      <Filter>Leser</Filter>
+    </ClInclude>
+    <ClInclude Include="SSKlientV.h">
+      <Filter>Netzwerk</Filter>
+    </ClInclude>
+    <ClInclude Include="Klient.h">
+      <Filter>Netzwerk</Filter>
+    </ClInclude>
+    <ClInclude Include="Statistik.h">
+      <Filter>Statistik</Filter>
+    </ClInclude>
+    <ClInclude Include="StatistikKlasse.h">
+      <Filter>Statistik</Filter>
+    </ClInclude>
+    <ClInclude Include="RundenRundenStatistik.h">
+      <Filter>Statistik\Runden</Filter>
+    </ClInclude>
+    <ClInclude Include="GesamtTeamStatistik.h">
+      <Filter>Statistik\Gesamt\Team</Filter>
+    </ClInclude>
+    <ClInclude Include="GesamtSpielerStatistik.h">
+      <Filter>Statistik\Gesamt\Spieler</Filter>
+    </ClInclude>
+    <ClInclude Include="RundenSpielerStatistik.h">
+      <Filter>Statistik\Runden\Spieler</Filter>
+    </ClInclude>
+    <ClInclude Include="RundenTeamStatistik.h">
+      <Filter>Statistik\Runden\Team</Filter>
+    </ClInclude>
+    <ClInclude Include="Strukturen.h">
+      <Filter>Spiel</Filter>
+    </ClInclude>
+    <ClInclude Include="Spiel.h">
+      <Filter>Spiel</Filter>
+    </ClInclude>
+    <ClInclude Include="SpielKlasse.h">
+      <Filter>Spiel</Filter>
+    </ClInclude>
+    <ClInclude Include="Bestenliste.h">
+      <Filter>Spiel\Bestenliste</Filter>
+    </ClInclude>
+    <ClInclude Include="Karte.h">
+      <Filter>Spiel\Karte</Filter>
+    </ClInclude>
+    <ClInclude Include="Spieler.h">
+      <Filter>Spiel\Spieler</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="DllStart.cpp">
+      <Filter>Start</Filter>
+    </ClCompile>
+    <ClCompile Include="KartenLeser.cpp">
+      <Filter>Leser</Filter>
+    </ClCompile>
+    <ClCompile Include="Klient.cpp">
+      <Filter>Netzwerk</Filter>
+    </ClCompile>
+    <ClCompile Include="Statistik.cpp">
+      <Filter>Statistik</Filter>
+    </ClCompile>
+    <ClCompile Include="RundenRundenStatistik.cpp">
+      <Filter>Statistik\Runden</Filter>
+    </ClCompile>
+    <ClCompile Include="GesamtTeamStatistik.cpp">
+      <Filter>Statistik\Gesamt\Team</Filter>
+    </ClCompile>
+    <ClCompile Include="GesamtSpielerStatistik.cpp">
+      <Filter>Statistik\Gesamt\Spieler</Filter>
+    </ClCompile>
+    <ClCompile Include="RundenSpielerStatistik.cpp">
+      <Filter>Statistik\Runden\Spieler</Filter>
+    </ClCompile>
+    <ClCompile Include="RundenTeamStatistik.cpp">
+      <Filter>Statistik\Runden\Team</Filter>
+    </ClCompile>
+    <ClCompile Include="Spiel.cpp">
+      <Filter>Spiel</Filter>
+    </ClCompile>
+    <ClCompile Include="Strukturen.cpp">
+      <Filter>Spiel</Filter>
+    </ClCompile>
+    <ClCompile Include="Bestenliste.cpp">
+      <Filter>Spiel\Bestenliste</Filter>
+    </ClCompile>
+    <ClCompile Include="Karte.cpp">
+      <Filter>Spiel\Karte</Filter>
+    </ClCompile>
+    <ClCompile Include="Spieler.cpp">
+      <Filter>Spiel\Spieler</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>

+ 151 - 0
Linie/RundenRundenStatistik.cpp

@@ -0,0 +1,151 @@
+#include "RundenRundenStatistik.h"
+#include <Text.h>
+
+// Inhalt der RundenRundenStatistik Klasse aus RundenRundenStatistik.h
+// Konstruktor
+RundenRundenStatistik::RundenRundenStatistik()
+{
+	rundenNummer = 0;
+	rundenDauer = 0;
+	siegerTeam = 0;
+	spielFeldNutzung = 0;
+	rundenBild = 0;
+	rss = new RCArray< RundenSpielerStatistik >();
+	rts = new RCArray< RundenTeamStatistik >();
+	ref = 1;
+}
+
+// Destruktor
+RundenRundenStatistik::~RundenRundenStatistik()
+{
+	if( rundenBild )
+		rundenBild->release();
+	rss->release();
+	rts->release();
+}
+
+// nciht constant
+void RundenRundenStatistik::addSpielerStatistik( RundenSpielerStatistik *rss )
+{
+	this->rss->add( rss );
+}
+
+void RundenRundenStatistik::addTeamStatistik( RundenTeamStatistik *rts )
+{
+	this->rts->add( rts );
+}
+
+void RundenRundenStatistik::setBild( Bild *b )
+{
+	if( rundenBild )
+		rundenBild->release();
+	rundenBild = b;
+}
+
+void RundenRundenStatistik::initValues( InitDatei *dat )
+{
+	if( dat->wertExistiert( "RundenNummer" ) )
+		rundenNummer = *dat->zWert( "RundenNummer" );
+	if( dat->wertExistiert( "RundenDauer" ) )
+		rundenDauer = *dat->zWert( "RundenDauer" );
+	if( dat->wertExistiert( "SiegerTeam" ) )
+		siegerTeam = *dat->zWert( "SiegerTeam" );
+	if( dat->wertExistiert( "SpielFeldNutzung" ) )
+		spielFeldNutzung = *dat->zWert( "SpielFeldNutzung" );
+	dat->release();
+}
+
+// constant
+InitDatei *RundenRundenStatistik::getValues() const
+{
+	InitDatei *ret = new InitDatei();
+	Text w;
+	w = rundenNummer;
+	if( w.getLength() )
+		ret->addWert( "RundenNummer", w.getText() );
+	w = rundenDauer;
+	if( w.getLength() )
+		ret->addWert( "RundenDauer", w.getText() );
+	w = siegerTeam;
+	if( w.getLength() )
+		ret->addWert( "SiegerTeam", w.getText() );
+	w = spielFeldNutzung;
+	if( w.getLength() )
+		ret->addWert( "SpielFeldNutzung", w.getText() );
+	return ret;
+}
+
+int RundenRundenStatistik::getRundenNummer() const
+{
+	return rundenNummer;
+}
+
+Bild *RundenRundenStatistik::getRundenBild() const
+{
+	return rundenBild ? rundenBild->getThis() : 0;
+}
+
+Bild *RundenRundenStatistik::zRundenBild() const
+{
+	return rundenBild;
+}
+
+int RundenRundenStatistik::getRundenDauer() const
+{
+	return rundenDauer;
+}
+
+int RundenRundenStatistik::getSiegerTeam() const
+{
+	return siegerTeam;
+}
+
+int RundenRundenStatistik::getSpielFeldNutzung() const
+{
+	return spielFeldNutzung;
+}
+
+RundenSpielerStatistik *RundenRundenStatistik::getSpielerStatistik( int index ) const
+{
+	return rss->get( index );
+}
+
+RundenSpielerStatistik *RundenRundenStatistik::zSpielerStatistik( int index ) const
+{
+	return rss->z( index );
+}
+
+RundenTeamStatistik *RundenRundenStatistik::getTeamStatistik( int index ) const
+{
+	return rts->get( index );
+}
+
+RundenTeamStatistik *RundenRundenStatistik::zTeamStatistik( int index ) const
+{
+	return rts->z( index );
+}
+
+int RundenRundenStatistik::getSpielerAnzahl() const
+{
+	return rss->getEintragAnzahl();
+}
+
+int RundenRundenStatistik::getTeamAnzahl() const
+{
+	return rts->getEintragAnzahl();
+}
+
+// Reference Counting
+RundenRundenStatistik *RundenRundenStatistik::getThis()
+{
+	ref++;
+	return this;
+}
+
+RundenRundenStatistik *RundenRundenStatistik::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 52 - 0
Linie/RundenRundenStatistik.h

@@ -0,0 +1,52 @@
+#ifndef RundenRundenStatistik_H
+#define RundenRundenStatistik_H
+
+#include <Bild.h>
+#include <InitDatei.h>
+#include "RundenSpielerStatistik.h"
+#include "RundenTeamStatistik.h"
+
+using namespace Framework;
+
+class RundenRundenStatistik
+{
+private:
+	int rundenNummer;
+	int rundenDauer;
+	int siegerTeam;
+	int spielFeldNutzung;
+	Bild *rundenBild;
+	RCArray< RundenSpielerStatistik > *rss;
+	RCArray< RundenTeamStatistik > *rts;
+	int ref;
+
+public:
+	// Konstruktor
+	RundenRundenStatistik();
+	// Destruktor
+	~RundenRundenStatistik();
+	// nciht constant
+	void addSpielerStatistik( RundenSpielerStatistik *rss );
+	void addTeamStatistik( RundenTeamStatistik *rts );
+	void setBild( Bild *b );
+	void initValues( InitDatei *dat );
+	// constant
+	InitDatei *getValues() const;
+	int getRundenNummer() const;
+	Bild *getRundenBild() const;
+	Bild *zRundenBild() const;
+	int getRundenDauer() const;
+	int getSiegerTeam() const;
+	int getSpielFeldNutzung() const;
+	RundenSpielerStatistik *getSpielerStatistik( int index ) const;
+	RundenSpielerStatistik *zSpielerStatistik( int index ) const;
+	RundenTeamStatistik *getTeamStatistik( int index ) const;
+	RundenTeamStatistik *zTeamStatistik( int index ) const;
+	int getSpielerAnzahl() const;
+	int getTeamAnzahl() const;
+	// Reference Counting
+	RundenRundenStatistik *getThis();
+	RundenRundenStatistik *release();
+};
+
+#endif

+ 111 - 0
Linie/RundenSpielerStatistik.cpp

@@ -0,0 +1,111 @@
+#include "RundenSpielerStatistik.h"
+
+// Inhalt der RundenSpielerStatistik Klasse aus RundenSpielerStatistik.h
+// Konstruktor
+RundenSpielerStatistik::RundenSpielerStatistik()
+{
+	spielerNummer = 0;
+	spielerName = new Text();
+	teamName = new Text();
+	spielerFarbe = 0;
+	teamFarbe = 0;
+	linienLength = 0;
+	kills = 0;
+	todeszeit = 0;
+	ref = 1;
+}
+
+// Destruktor
+RundenSpielerStatistik::~RundenSpielerStatistik()
+{
+	spielerName->release();
+	teamName->release();
+}
+
+// nicht constant
+void RundenSpielerStatistik::initValues( InitDatei *dat )
+{
+	if( dat->wertExistiert( "SpielerNummer" ) )
+		spielerNummer = *dat->zWert( "SpielerNummer" );
+	if( dat->wertExistiert( "SpielerName" ) )
+		*spielerName = dat->zWert( "SpielerName" )->getText();
+	if( dat->wertExistiert( "TeamName" ) )
+		*teamName = dat->zWert( "TeamName" )->getText();
+	if( dat->wertExistiert( "SpielerFarbe" ) )
+		spielerFarbe = *dat->zWert( "SpielerFarbe" );
+	if( dat->wertExistiert( "TeamFarbe" ) )
+		teamFarbe = *dat->zWert( "TeamFarbe" );
+	if( dat->wertExistiert( "LinienLänge" ) )
+		linienLength = *dat->zWert( "LinienLänge" );
+	if( dat->wertExistiert( "Kills" ) )
+		kills = *dat->zWert( "Kills" );
+	if( dat->wertExistiert( "Todeszeit" ) )
+		todeszeit = *dat->zWert( "Todeszeit" );
+	dat->release();
+}
+
+// constant
+int RundenSpielerStatistik::getSpielerNummer() const
+{
+	return spielerNummer;
+}
+
+Text *RundenSpielerStatistik::getSpielerName() const
+{
+	return spielerName ? spielerName->getThis() : 0;
+}
+
+Text *RundenSpielerStatistik::zSpielerName() const
+{
+	return spielerName;
+}
+
+Text *RundenSpielerStatistik::getTeamName() const
+{
+	return teamName ? teamName->getThis() : 0;
+}
+
+Text *RundenSpielerStatistik::zTeamName() const
+{
+	return teamName;
+}
+
+int RundenSpielerStatistik::getSpielerFarbe() const
+{
+	return spielerFarbe;
+}
+
+int RundenSpielerStatistik::getTeamFarbe() const
+{
+	return teamFarbe;
+}
+
+int RundenSpielerStatistik::getLinienLength() const
+{
+	return linienLength;
+}
+
+int RundenSpielerStatistik::getKills() const
+{
+	return kills;
+}
+
+int RundenSpielerStatistik::getTodesZeit() const
+{
+	return todeszeit;
+}
+
+// Reference Counting
+RundenSpielerStatistik *RundenSpielerStatistik::getThis()
+{
+	ref++;
+	return this;
+}
+
+RundenSpielerStatistik *RundenSpielerStatistik::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 45 - 0
Linie/RundenSpielerStatistik.h

@@ -0,0 +1,45 @@
+#ifndef RundenSpielerStatistik_H
+#define RundenSpielerStatistik_H
+
+#include <Text.h>
+#include <InitDatei.h>
+
+using namespace Framework;
+
+class RundenSpielerStatistik
+{
+private:
+	int spielerNummer;
+	Text *spielerName;
+	Text *teamName;
+	int spielerFarbe;
+	int teamFarbe;
+	int linienLength;
+	int kills;
+	int todeszeit;
+	int ref;
+
+public:
+	// Konstruktor
+	RundenSpielerStatistik();
+	// Destruktor
+	~RundenSpielerStatistik();
+	// nicht constant
+	void initValues( InitDatei *dat );
+	// constant
+	int getSpielerNummer() const;
+	Text *getSpielerName() const;
+	Text *zSpielerName() const;
+	Text *getTeamName() const;
+	Text *zTeamName() const;
+	int getSpielerFarbe() const;
+	int getTeamFarbe() const;
+	int getLinienLength() const;
+	int getKills() const;
+	int getTodesZeit() const;
+	// Reference Counting
+	RundenSpielerStatistik *getThis();
+	RundenSpielerStatistik *release();
+};
+
+#endif

+ 97 - 0
Linie/RundenTeamStatistik.cpp

@@ -0,0 +1,97 @@
+#include "RundenTeamStatistik.h"
+
+// Inhalt der RundenTeamStatistik Klasse aus RundenTeamStatistik.h
+// Konstruktor
+RundenTeamStatistik::RundenTeamStatistik()
+{
+	teamNummer = 0;
+	teamName = new Text();
+	teamFarbe = 0;
+	ergebnis = 0;
+	linienLength = 0;
+	kills = 0;
+	tode = 0;
+	ref = 1;
+}
+
+// Destruktor
+RundenTeamStatistik::~RundenTeamStatistik()
+{
+	teamName->release();
+}
+
+// nicht constant
+void RundenTeamStatistik::initValues( InitDatei *dat )
+{
+	if( dat->wertExistiert( "TeamNummer" ) )
+		teamNummer = *dat->zWert( "TeamNummer" );
+	if( dat->wertExistiert( "TeamName" ) )
+		*teamName = dat->zWert( "TeamName" )->getText();
+	if( dat->wertExistiert( "TeamFarbe" ) )
+		teamFarbe = *dat->zWert( "TeamFarbe" );
+	if( dat->wertExistiert( "Ergebnis" ) )
+		ergebnis = *dat->zWert( "Ergebnis" );
+	if( dat->wertExistiert( "LinienLänge" ) )
+		linienLength = *dat->zWert( "LinienLänge" );
+	if( dat->wertExistiert( "Kills" ) )
+		kills = *dat->zWert( "Kills" );
+	if( dat->wertExistiert( "Tode" ) )
+		tode = *dat->zWert( "Tode" );
+	dat->release();
+}
+
+// constant
+int RundenTeamStatistik::getTeamNummer() const
+{
+	return teamNummer;
+}
+
+Text *RundenTeamStatistik::getTeamName() const
+{
+	return teamName ? teamName->getThis() : 0;
+}
+
+Text *RundenTeamStatistik::zTeamName() const
+{
+	return teamName;
+}
+
+int RundenTeamStatistik::getTeamFarbe() const
+{
+	return teamFarbe;
+}
+
+int RundenTeamStatistik::getErgebnis() const
+{
+	return ergebnis;
+}
+
+int RundenTeamStatistik::getLinienLength() const
+{
+	return linienLength;
+}
+
+int RundenTeamStatistik::getKills() const
+{
+	return kills;
+}
+
+int RundenTeamStatistik::getTode() const
+{
+	return tode;
+}
+
+// Reference Counting
+RundenTeamStatistik *RundenTeamStatistik::getThis()
+{
+	ref++;
+	return this;
+}
+
+RundenTeamStatistik *RundenTeamStatistik::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 42 - 0
Linie/RundenTeamStatistik.h

@@ -0,0 +1,42 @@
+#ifndef RundenTeamStatistik_H
+#define RundenTeamStatistik_H
+
+#include <Text.h>
+#include <InitDatei.h>
+
+using namespace Framework;
+
+class RundenTeamStatistik
+{
+private:
+	int teamNummer;
+	Text *teamName;
+	int teamFarbe;
+	int ergebnis;
+	int linienLength;
+	int kills;
+	int tode;
+	int ref;
+
+public:
+	// Konstruktor
+	RundenTeamStatistik();
+	// Destruktor
+	~RundenTeamStatistik();
+	// nicht constant
+	void initValues( InitDatei *dat );
+	// constant
+	int getTeamNummer() const;
+	Text *getTeamName() const;
+	Text *zTeamName() const;
+	int getTeamFarbe() const;
+	int getErgebnis() const;
+	int getLinienLength() const;
+	int getKills() const;
+	int getTode() const;
+	// Reference Counting
+	RundenTeamStatistik *getThis();
+	RundenTeamStatistik *release();
+};
+
+#endif

+ 34 - 0
Linie/SSDatenbankV.h

@@ -0,0 +1,34 @@
+#ifndef SSDatenbankV_H
+#define SSDatenbankV_H
+
+#include <Text.h>
+#include <Array.h>
+#include <Zeit.h>
+
+using namespace Framework;
+
+class SSDatenbankV
+{
+private:
+
+public:
+	virtual ~SSDatenbankV()
+	{}
+	// nicht constant
+	virtual int getAccountId( int clientId ) = 0;
+	virtual Text *getSpielArtName( int spielId ) = 0;
+	virtual Text *getKarteName( int karteId ) = 0;
+	virtual int getSpielArtId( int karteId ) = 0;
+	virtual Text *getAccountRufName( int accountId ) = 0;
+	virtual bool setSpielStatusBeendet( int spielId, int status ) = 0;
+	virtual bool setSpielSpielerStatus( int spielId, int accountId, int punkte, int status ) = 0;
+	virtual bool addSpielerStatistik( int accountId, int spielId ) = 0;
+    virtual Text *getSpielPfad( int karteId ) = 0;
+	// constant
+
+	// Reference Counting
+	virtual SSDatenbankV *getThis() = 0;
+	virtual SSDatenbankV *release() = 0;
+};
+
+#endif

+ 29 - 0
Linie/SSKlientV.h

@@ -0,0 +1,29 @@
+#ifndef SSKlientV_H
+#define SSKlientV_H
+
+#include <Thread.h>
+
+using namespace Framework;
+
+class SSKlientV : public Thread
+{
+private:
+
+public:
+	// nicht constant 
+	virtual void nichtTrennen() = 0;
+	virtual double ping() = 0;
+	virtual void spielNachricht( short len, char *bytes ) = 0;
+	virtual void statistikNachricht( short len, char *bytes ) = 0;
+	virtual void trenne() = 0;
+	virtual void thread() = 0;
+	virtual void errorZuKlientEmpfang( const char *nachricht ) = 0; // sendet eine Fehlernachricht zum Klient
+	virtual void errorZuKlientSende( const char *nachricht ) = 0;
+	// const
+	virtual int getAccountId() const = 0;
+	// Reference Counting
+	virtual SSKlientV *getThis() = 0;
+	virtual SSKlientV *release() = 0;
+};
+
+#endif

+ 774 - 0
Linie/Spiel.cpp

@@ -0,0 +1,774 @@
+#include "Spiel.h"
+#include <time.h>
+#include "KartenLeser.h"
+#include "Statistik.h"
+#include <DateiSystem.h>
+#ifdef WIN32
+#include <random>
+#else
+#include <math.h>
+#include <unistd.h>
+#include <stdlib.h>
+#define Sleep( x )    usleep( (x) * 1000 )
+#endif
+
+#define TICK 0.03333333
+
+// Inhalt der Spiel Klasse aus Spiel.h
+// Konstruktor
+Spiel::Spiel()
+{
+	stat = new Statistik();
+	score = new Bestenliste();
+	teams = new Array< int >();
+	teamAnzahl = 0;
+	psqldb = 0;
+	spieler = new RCArray< Spieler >();
+	spielerAnzahl = 0;
+	spielId = 0;
+	karte = new Karte();
+	isRunning = 0;
+	sts = 0;
+	InitializeCriticalSection( &cs );
+	rundenAnzahl = 0;
+	spielZeit = 0;
+	ende = 1;
+	ref = 1;
+}
+
+// Destruktor
+Spiel::~Spiel()
+{
+	teams->release();
+	stat->release();
+	score->release();
+	spieler->release();
+	if( psqldb )
+		psqldb->release();
+	karte->release();
+	if( sts )
+		sts->release();
+	DeleteCriticalSection( &cs );
+}
+
+// nicht constant
+void Spiel::setPSQLK( SSDatenbankV *psqldb )
+{
+	if( this->psqldb )
+		this->psqldb->release();
+	this->psqldb = psqldb;
+	stat->setPSQLDB( psqldb->getThis() );
+}
+
+void Spiel::setSpielId( int id )
+{
+	spielId = id;
+	stat->setSpielId( id );
+}
+
+void Spiel::setKarteId( int karteId )
+{
+	this->karteId = karteId;
+	karte->setKarteId( karteId );
+	stat->setKarteId( karteId );
+}
+
+void Spiel::setTempPfad( char *pfad )
+{
+    mapPfad = pfad;
+    mapPfad += "/";
+}
+
+void Spiel::setAccounts( int anzahl, Array< int > *zAccounts )
+{
+	spielerAnzahl = anzahl;
+	for( int i = 0; i < anzahl; i++ )
+	{
+		Spieler *tmp = new Spieler();
+		tmp->setAccountId( zAccounts->hat( i ) ? zAccounts->get( i ) : 0 );
+		spieler->set( tmp, i );
+	}
+	stat->setSpieler( spielerAnzahl, spieler );
+}
+
+void Spiel::setKlients( int anzahl, RCArray< SSKlientV > *zKlients )
+{
+	for( int i = 0; i < anzahl; i++ )
+	{
+		Spieler *tmp = spieler->z( i );
+		if( tmp )
+			tmp->setKlient( new Klient( zKlients->get( i ) ) );
+	}
+}
+
+void Spiel::setSpielerNummern( int anzahl, Array< int > *spielerNummern )
+{
+	if( !sts )
+	{
+		sts = new SpielerTeamStruktur();
+		KartenLeser *reader = new KartenLeser( karteId, psqldb->getThis(), mapPfad );
+		reader->ladeSpielerTeamStruktur( sts );
+		reader->release();
+		stat->setTeamNamen( sts->teamName->getThis() );
+	}
+	for( int i = 0; i < anzahl; i++ )
+	{
+		Spieler *tmp = spieler->z( i );
+		if( tmp )
+		{
+			int sNum = spielerNummern->hat( i ) ? spielerNummern->get( i ) : 0;
+			tmp->setSpielerNummer( sNum );
+			tmp->setSpielerFarbe( sts->spielerFarbe->hat( sNum ) ? sts->spielerFarbe->get( sNum ) : 0 );
+			int team = 0;
+			int von = 0;
+			int bis = 0;
+			for( int j = 0; j < sts->teamAnzahl; j++ )
+			{
+				bis = von + ( sts->teamSize->hat( j ) ? sts->teamSize->get( j ) : 0 );
+				if( sNum >= von && sNum < bis )
+				{
+					team = j;
+					break;
+				}
+				von = bis;
+			}
+			tmp->setTeam( team );
+			tmp->setTeamFarbe( sts->teamFarbe->hat( team ) ? sts->teamFarbe->get( team ) : 0 );
+		}
+	}
+}
+
+void Spiel::klientOffline( int accountId )
+{
+	for( int i = 0; i < spielerAnzahl; i++ )
+	{
+		if( spieler->z( i )->getAccountId() == accountId )
+			spieler->z( i )->offline();
+	}
+}
+
+void Spiel::klientOnline( int accountId, SSKlientV *zKlient )
+{
+	for( int i = 0; i < spielerAnzahl; i++ )
+	{
+		if( spieler->z( i )->getAccountId() == accountId )
+		{
+			EnterCriticalSection( &cs );
+			Spieler *s = spieler->z( i );
+			s->online( zKlient );
+			Klient *tmp = spieler->z( i )->zKlient();
+			tmp->sendeSpielerNummer( s->getSpielerNummer(), 0 );
+			tmp->sendeInitSpieler( spielerAnzahl, spieler, 0 );
+			tmp->sendeKammeraSize( 400, 400, 0 );
+			tmp->sendeKartenSize( karte->getBreite(), karte->getHeight(), 0 );
+			for( int i = 0; i < spielerAnzahl; i++ )
+			{
+				Spieler *z = spieler->z( i );
+				if( z )
+				{
+					tmp->sendeSpielerPosition( z, 0 );
+					tmp->sendeSpielerGeschwindigkeit( z, 0 );
+					tmp->sendeSpielerWendigkeit( z, 0 );
+				}
+			}
+			LeaveCriticalSection( &cs );
+		}
+	}
+}
+
+void Spiel::nachricht( int accountId, int len, char *bytes )
+{
+	if( !isRunning || ende )
+		return;
+	EnterCriticalSection( &cs );
+	if( ende )
+	{
+		LeaveCriticalSection( &cs );
+		return;
+	}
+	char *msgBeg = bytes;
+	int msgLen = len;
+	int msgAccount = accountId;
+	bool saveMSG = 1;
+	len--;
+	switch( *bytes )
+	{
+	case 0: // Spieler drückt T_Links
+		for( int i = 0; i < spielerAnzahl; i++ )
+		{
+			Spieler *tmp = spieler->z( i );
+			if( tmp && tmp->getAccountId() == accountId )
+			{
+				if( !tmp->istAmLeben() )
+					break;
+				if( tmp->machtKurve( 0 ) )
+				{
+					saveMSG = 0;
+					break;
+				}
+				tmp->setLKurve( 1 );
+				for( int j = 0; j < spielerAnzahl; j++ )
+				{
+					Spieler *s = spieler->z( j );
+					if( s && s->zKlient() )
+						s->zKlient()->sendeSpielerKurve( tmp->getSpielerNummer(), 1, spielZeit );
+				}
+				break;
+			}
+		}
+		break;
+	case 1: // Spieler lässt T_Links los
+		for( int i = 0; i < spielerAnzahl; i++ )
+		{
+			Spieler *tmp = spieler->z( i );
+			if( tmp && tmp->getAccountId() == accountId )
+			{
+				if( !tmp->istAmLeben() )
+					break;
+				if( !tmp->machtKurve( 0 ) )
+				{
+					saveMSG = 0;
+					break;
+				}
+				tmp->setLKurve( 0 );
+				for( int j = 0; j < spielerAnzahl; j++ )
+				{
+					Spieler *s = spieler->z( j );
+					if( s && s->zKlient() )
+						s->zKlient()->sendeSpielerKurve( tmp->getSpielerNummer(), 2, spielZeit );
+				}
+				break;
+			}
+		}
+		break;
+	case 2: // Spieler drückt T_Rechts
+		for( int i = 0; i < spielerAnzahl; i++ )
+		{
+			Spieler *tmp = spieler->z( i );
+			if( tmp && tmp->getAccountId() == accountId )
+			{
+				if( !tmp->istAmLeben() )
+					break;
+				if( tmp->machtKurve( 1 ) )
+				{
+					saveMSG = 0;
+					break;
+				}
+				tmp->setRKurve( 1 );
+				for( int j = 0; j < spielerAnzahl; j++ )
+				{
+					Spieler *s = spieler->z( j );
+					if( s && s->zKlient() )
+						s->zKlient()->sendeSpielerKurve( tmp->getSpielerNummer(), 3, spielZeit );
+				}
+				break;
+			}
+		}
+		break;
+	case 3: // Spieler lässt T_Rechts los
+		for( int i = 0; i < spielerAnzahl; i++ )
+		{
+			Spieler *tmp = spieler->z( i );
+			if( tmp && tmp->getAccountId() == accountId )
+			{
+				if( !tmp->istAmLeben() )
+					break;
+				if( !tmp->machtKurve( 1 ) )
+				{
+					saveMSG = 0;
+					break;
+				}
+				tmp->setRKurve( 0 );
+				for( int j = 0; j < spielerAnzahl; j++ )
+				{
+					Spieler *s = spieler->z( j );
+					if( s && s->zKlient() )
+						s->zKlient()->sendeSpielerKurve( tmp->getSpielerNummer(), 4, spielZeit );
+				}
+				break;
+			}
+		}
+		break;
+	case 4: // chat Nachricht
+		if( 1 )
+		{
+			bytes++;
+			Text *txt = psqldb->getAccountRufName( accountId );
+			txt->append( ": " );
+			txt->append( bytes, len );
+			for( int i = 0; i < spielerAnzahl; i++ )
+			{
+				Spieler *tmp = spieler->z( i );
+				if( tmp && tmp->zKlient() )
+					tmp->zKlient()->sendeChatNachricht( txt->getText(), spielZeit );
+			}
+			txt->release();
+			len = 0;
+		}
+		break;
+	default:
+		saveMSG = 0;
+	}
+	if( len )
+	{
+		// error
+	}
+	if( log && log->istOffen() && saveMSG )
+	{
+		char c = 1;
+		log->schreibe( &c, 1 );
+		int spielerNum = 0;
+		for( int i = 0; i < spielerAnzahl; i++ )
+		{
+			Spieler *tmp = spieler->z( i );
+			if( tmp && tmp->getAccountId() == msgAccount )
+			{
+				spielerNum = tmp->getSpielerNummer();
+				break;
+			}
+		}
+		log->schreibe( (char*)&spielerNum, 4 );
+		short l = (short)msgLen;
+		log->schreibe( (char*)&l, 2 );
+		log->schreibe( msgBeg, l );
+	}
+	LeaveCriticalSection( &cs );
+}
+
+void Spiel::tick( double zeit )
+{
+	for( int i = 0; i < spielerAnzahl; i++ )
+	{
+		Spieler *tmp = spieler->z( i );
+		if( tmp )
+		{
+			bool amLeben = tmp->istAmLeben();
+			bool lu = tmp->linieIstUnterbrochen();
+			tmp->tick( karte->zMap(), zeit );
+			if( amLeben != tmp->istAmLeben() || lu != tmp->linieIstUnterbrochen() )
+			{
+				if( lu != tmp->linieIstUnterbrochen() )
+				{
+					char c = 1;
+					log->schreibe( &c, 1 );
+					int sNum = tmp->getSpielerNummer();
+					log->schreibe( (char*)&sNum, 4 );
+					short len = 2;
+					log->schreibe( (char*)&len, 2 );
+					c = 5;
+					log->schreibe( &c, 1 );
+					c = (char)tmp->linieIstUnterbrochen();
+					log->schreibe( &c, 1 );
+				}
+				for( int j = 0; j < spielerAnzahl; j++ )
+				{
+					Spieler *s = spieler->z( j );
+					if( s && s->zKlient() )
+					{
+						if( amLeben && !tmp->istAmLeben() )
+						{
+							if( tmp->getKillFarbe() == s->getSpielerFarbe() )
+								s->addKill();
+							s->zKlient()->sendeSpielerTod( tmp, spielZeit );
+							if( s != tmp && s->istAmLeben() )
+							{
+								score->addSpielerPunkt( s->getSpielerNummer(), 1 );
+								s->addPunkte( 1 );
+							}
+						}
+						else if( lu != tmp->linieIstUnterbrochen() )
+							s->zKlient()->sendeLinienUnterbrechung( tmp->getSpielerNummer(), tmp->linieIstUnterbrochen(), spielZeit );
+					}
+				}
+				if( amLeben && !tmp->istAmLeben() )
+				{
+					int team = tmp->getSpielerTeam();
+					bool teamLebt = 0;
+					for( int k = 0; k < spielerAnzahl; k++ )
+					{
+						if( spieler->z( k ) && spieler->z( k )->getSpielerTeam() == team )
+							teamLebt |= spieler->z( k )->istAmLeben();
+					}
+					if( !teamLebt )
+					{
+						int teamAmLebenAnzahl = 0;
+						for( int k = 0; k < teamAnzahl; k++ )
+						{
+							int t = teams->hat( k ) ? teams->get( k ) : 0;
+							bool amLeben = 0;
+							for( int l = 0; l < spielerAnzahl; l++ )
+							{
+								if( spieler->z( l ) && spieler->z( l )->getSpielerTeam() == t )
+									amLeben |= spieler->z( l )->istAmLeben();
+							}
+							if( amLeben )
+							{
+								teamAmLebenAnzahl++;
+								score->addTeamPunkt( t, 1 );
+							}
+							else
+								score->addTeamPunkt( t, 0 );
+						}
+						if( teamAmLebenAnzahl <= 1 )
+							ende = 1;
+					}
+				}
+			}
+		}
+	}
+}
+
+void Spiel::run()
+{
+	log = new Datei();
+	Text *pfad = new Text( "../spiel log/" );
+	pfad->append( spielId );
+	pfad->append( "/verlauf.ksggl" );
+	log->setDatei( pfad );
+	log->remove();
+	log->erstellen();
+	log->open( Datei::Style::schreiben );
+	time_t t;
+	time( &t );
+	srand( (unsigned int)t );
+	log->schreibe( (char*)&spielerAnzahl, 4 );
+	for( int i = 0; i < spielerAnzahl; i++ )
+	{
+		Spieler *tmp = spieler->z( i );
+		if( tmp && tmp->zKlient() )
+		{
+			log->schreibe( (char*)&i, 4 );
+			int sNum = tmp->getSpielerNummer();
+			score->setSpielerPunkte( sNum, 0 );
+			log->schreibe( (char*)&sNum, 4 );
+			tmp->zKlient()->sendeSpielerNummer( sNum, 0 );
+			tmp->zKlient()->sendeInitSpieler( spielerAnzahl, spieler, 0 );
+			int kg = 400;
+			log->schreibe( (char*)&kg, 4 );
+			log->schreibe( (char*)&kg, 4 );
+			int team = tmp->getSpielerTeam();
+			log->schreibe( (char*)&team, 4 );
+			int farbe = tmp->getSpielerFarbe();
+			log->schreibe( (char*)&farbe, 4 );
+			farbe = tmp->getTeamFarbe();
+			log->schreibe( (char*)&farbe, 4 );
+			Text *name = psqldb->getAccountRufName( tmp->getAccountId() );
+			char len = (char)( name ? name->getLength() : 0 );
+			log->schreibe( &len, 1 );
+			if( len )
+				log->schreibe( name->getText(), len );
+			if( name )
+				name->release();
+			name = sts->teamName->z( tmp->getSpielerTeam() );
+			len = (char)( name ? name->getLength() : 0 );
+			log->schreibe( &len, 1 );
+			if( len )
+				log->schreibe( name->getText(), len );
+			tmp->zKlient()->sendeKammeraSize( 400, 400, 0 );
+			bool gefunden = 0;
+			for( int j = 0; j < teamAnzahl; j++ )
+				gefunden |= teams->hat( j ) && teams->get( j ) == tmp->getSpielerTeam();
+			if( !gefunden )
+			{
+				score->setTeamMaxPunkte( tmp->getSpielerTeam(), teamAnzahl * 3 );
+				score->setTeamPunkte( tmp->getSpielerTeam(), ( teamAnzahl * 3 ) / 2 );
+				teams->set( tmp->getSpielerTeam(), teamAnzahl );
+				teamAnzahl++;
+			}
+		}
+	}
+	for( int i = 0; i < teamAnzahl; i++ )
+	{
+		score->setTeamMaxPunkte( teams->hat( i ) ? teams->get( i ) : 0, teamAnzahl * 3 );
+		score->setTeamPunkte( teams->hat( i ) ? teams->get( i ) : 0, ( teamAnzahl * 3 ) / 2 );
+	}
+	for( int i = 0; i < spielerAnzahl; i++ )
+	{
+		Spieler *tmp = spieler->z( i );
+		if( tmp && tmp->zKlient() )
+		{
+			for( int j = 0; j < teamAnzahl; j++ )
+			{
+				int team = teams->hat( j ) ? teams->get( j ) : 0;
+				if( i == 0 )
+					log->schreibe( (char*)&team, 4 );
+				int p = score->getTeamMaxPunkte( team );
+				tmp->zKlient()->sendeTeamMaxPunkte( team, p, 0 );
+				if( i == 0 )
+					log->schreibe( (char*)&p, 4 );
+				p = score->getTeamPunkte( team );
+				tmp->zKlient()->sendeTeamPunkte( team, p, 0 );
+				if( i == 0 )
+					log->schreibe( (char*)&p, 4 );
+				if( sts->teamName->z( team ) )
+				    tmp->zKlient()->sendeTeamName( team, sts->teamName->z( team )->getText() );
+			}
+		}
+	}
+	Array< char > spielerStatus;
+	int gewinner = -1;
+	while( 1 )
+	{
+		rundenAnzahl++;
+		int karteBreite = 400 + ( rand() % ( spielerAnzahl * 50 ) );
+		int karteHeignt = 400 + ( rand() % ( spielerAnzahl * 50 ) );
+		karte->setSize( karteBreite, karteHeignt );
+		EnterCriticalSection( &cs );
+		log->schreibe( (char*)&karteBreite, 4 );
+		log->schreibe( (char*)&karteHeignt, 4 );
+		for( int i = 0; i < spielerAnzahl; i++ )
+		{
+			Spieler *tmp = spieler->z( i );
+			if( tmp && tmp->zKlient() )
+			{
+				tmp->zKlient()->sendeKartenSize( karteBreite, karteHeignt, 0 );
+				double w = 50.0 / 180 * PI;
+				log->schreibe( (char*)&w, 8 );
+				tmp->setWendigkeit( w );
+				tmp->setPosition( 100 + ( rand() % ( karteBreite - 200 ) ), 100 + ( rand() % ( karteHeignt - 200 ) ) );
+				double p = tmp->getX();
+				log->schreibe( (char*)&p, 8 );
+				p = tmp->getY();
+				log->schreibe( (char*)&p, 8 );
+				int grad = rand() % 180 - 90;
+				double xs = sin( grad / 180.0 * PI ) * 30;
+				log->schreibe( (char*)&xs, 8 );
+				double ys = sqrt( 30 * 30 - xs * xs );
+				ys *= ( rand() % 2 > 0 ) ? 1 : -1;
+				log->schreibe( (char*)&ys, 8 );
+				tmp->setGeschwindigkeit( xs, ys );
+			}
+		}
+		LeaveCriticalSection( &cs );
+		for( int i = 0; i < spielerAnzahl; i++ )
+		{
+			Spieler *tmp = spieler->z( i );
+			if( tmp )
+			{
+				for( int j = 0; j < spielerAnzahl; j++ )
+				{
+					Spieler *s = spieler->z( j );
+					if( s && s->zKlient() )
+					{
+						s->zKlient()->sendeSpielerPosition( tmp, 0 );
+						s->zKlient()->sendeSpielerGeschwindigkeit( tmp, 0 );
+						s->zKlient()->sendeSpielerWendigkeit( tmp, 0 );
+					}
+				}
+			}
+		}
+		for( int i = 0; i < teamAnzahl; i++ )
+		{
+			if( teams->hat( i ) && !score->istTeamAmLeben( teams->get( i ) ) )
+			{
+				for( int j = 0; j < spielerAnzahl; j++ )
+				{
+					Spieler *tmp = spieler->z( teams->get( i ) );
+					if( tmp )
+						tmp->zKlient()->sendeTeamTod( teams->get( i ), 0 );
+				}
+			}
+		}
+		ZeitMesser *zeit = new ZeitMesser();
+		zeit->messungStart();
+		isRunning = 1;
+		ende = 0;
+		double ausgleich = 0;
+		spielZeit = 0;
+		for( int i = 0; i < spielerAnzahl; i++ )
+		{
+			Spieler *tmp = spieler->z( i );
+			if( tmp && tmp->zKlient() )
+				tmp->zKlient()->sendeStart( 0 );
+		}
+		double rZeit = 0;
+		while( !ende )
+		{
+			zeit->messungEnde();
+			zeit->messungStart();
+			double z = zeit->getSekunden();
+			ausgleich += 1.0 / 25 - z;
+			if( ausgleich > 0 )
+				Sleep( (int)( ausgleich * 1000 ) );
+			rZeit += z;
+			while( spielZeit + TICK < rZeit && !ende )
+			{
+				EnterCriticalSection( &cs );
+				spielZeit += TICK;
+				char c = 0;
+				log->schreibe( &c, 1 );
+				tick( TICK );
+				LeaveCriticalSection( &cs );
+			}
+		}
+		zeit->messungEnde();
+		zeit->release();
+		gewinner = -1;
+		for( int i = 0; i < spielerAnzahl; i++ )
+		{
+			if( spieler->z( i )->istAmLeben() )
+			{
+				gewinner = spieler->z( i )->getSpielerTeam();
+				break;
+			}
+		}
+		if( gewinner < 0 )
+		{
+			double sterbeZeit = 0;
+			for( int i = 0; i < spielerAnzahl; i++ )
+			{
+				if( spieler->z( i )->getTodesZeit() >= sterbeZeit )
+				{
+					sterbeZeit = spieler->z( i )->getTodesZeit();
+					gewinner = spieler->z( i )->getSpielerTeam();
+				}
+			}
+		}
+		stat->rundenEnde( gewinner, (int)spielZeit, karte->zMap()->getThis() );
+		int winTeamAnzahl = 0;
+		Array< int > *winTeams = new Array< int >();
+		for( int i = 0; i < teamAnzahl; i++ )
+		{
+			if( score->hatTeamGewonnen( i ) || rundenAnzahl >= 10 )
+			{
+				winTeams->add( i, winTeamAnzahl );
+				winTeamAnzahl++;
+			}
+		}
+		if( !winTeamAnzahl )
+		{
+			int verloren = 0;
+			int team = -1;
+			for( int i = 0; i < teamAnzahl; i++ )
+			{
+				int t = teams->hat( i ) ? teams->get( i ) : 0;
+				if( !score->getTeamPunkte( t ) )
+					verloren++;
+				else
+					team = t;
+			}
+			if( verloren == teamAnzahl - 1 )
+			{
+				winTeams->add( team, winTeamAnzahl );
+				winTeamAnzahl++;
+			}
+		}
+		if( winTeamAnzahl > 1 )
+		{
+			int p = -1;
+			for( int i = 0; i < winTeamAnzahl; i++ )
+			{
+				int t = winTeams->hat( i ) ? winTeams->get( i ) : 0;
+				if( score->getTeamMaxPunkte( t ) - score->getTeamPunkte( t ) < p || p < 0 )
+				{
+					p = score->getTeamMaxPunkte( t ) - score->getTeamPunkte( t );
+					for( int j = 0; j < winTeamAnzahl; j++ )
+					{
+						int tt = winTeams->hat( j ) ? winTeams->get( j ) : 0;
+						if( score->getTeamMaxPunkte( tt ) - score->getTeamPunkte( tt ) > p )
+						{
+							if( i >= j )
+								i--;
+							score->setTeamPunkte( tt, 0 );
+							winTeams->remove( j );
+							winTeamAnzahl--;
+							j--;
+						}
+					}
+				}
+			}
+		}
+		if( ( !winTeamAnzahl || winTeamAnzahl > 1 ) && teamAnzahl > 1 && rundenAnzahl < 10 )
+		{
+			winTeams->release();
+			for( int i = 0; i < spielerAnzahl; i++ )
+			{
+				if( spieler->z( i ) && spieler->z( i )->zKlient() )
+				{
+					spieler->z( i )->neuRunde( score->getTeamPunkte( spieler->z( i )->getSpielerTeam() ) != 0 );
+					spieler->z( i )->zKlient()->sendeRundenEnde( gewinner, 0 );
+				}
+			}
+			for( int i = 5; i >= 0; i-- )
+			{
+				for( int k = 0; k < 10; k++ )
+				{
+					Sleep( 100 );
+					for( int j = 0; j < spielerAnzahl; j++ )
+					{
+						if( spieler->z( j ) && spieler->z( j )->zKlient() )
+							spieler->z( j )->zKlient()->sendeZeitVerbleibend( i, 0 );
+					}
+					if( !i )
+						break;
+				}
+			}
+		}
+		else
+		{
+			for( int i = 0; i < spielerAnzahl; i++ )
+			{
+				if( spieler->z( i ) && spieler->z( i )->zKlient() )
+				{
+					if( winTeams->getWertIndex( spieler->z( i )->getSpielerTeam() ) < 0 )
+					{
+						spielerStatus.set( 1, i ); // Datenbank Verloren
+						spieler->z( i )->zKlient()->sendeSpielEnde( 0, 0 );
+					}
+					else if( winTeamAnzahl > 1 )
+					{
+						spielerStatus.set( 5, i ); // Datenbank Unentschieden
+						spieler->z( i )->zKlient()->sendeSpielEnde( 2, 0 );
+					}
+					else
+					{
+						spielerStatus.set( 2, i ); // Datenbank Gewonnen
+						spieler->z( i )->zKlient()->sendeSpielEnde( 1, 0 );
+					}
+				}
+				if( spieler->z( i ) && ( !spieler->z( i )->zKlient() || !spieler->z( i )->istOnline() ) )
+					spielerStatus.set( 3, i );
+			}
+			winTeams->release();
+			break;
+		}
+	}
+	if( teamAnzahl == 1 )
+		psqldb->setSpielStatusBeendet( spielId, 6 );
+	else
+		psqldb->setSpielStatusBeendet( spielId, 5 );
+	for( int i = 0; i < spielerAnzahl; i++ )
+	{
+		Spieler *tmp = spieler->z( i );
+		if( tmp )
+		{
+			psqldb->setSpielSpielerStatus( spielId, tmp->getAccountId(), tmp->getPunkte(), spielerStatus.get( i ) );
+			if( teamAnzahl > 1 )
+				psqldb->addSpielerStatistik( tmp->getAccountId(), spielId );
+		}
+	}
+	log->close();
+	log = log->release();
+	isRunning = 0;
+}
+
+// constant
+StatistikV *Spiel::getStatistik() const
+{
+	return stat->getThis();
+}
+
+// Reference Counting 
+SpielKlasse *Spiel::getThis()
+{
+	ref++;
+	return this;
+}
+
+SpielKlasse *Spiel::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 62 - 0
Linie/Spiel.h

@@ -0,0 +1,62 @@
+#ifndef Spiel_H
+#define Spiel_H
+
+#include "SpielKlasse.h"
+#include <Datei.h>
+#include "Strukturen.h"
+#include "Spieler.h"
+#include "Karte.h"
+#include "Bestenliste.h"
+
+class Statistik;
+class StatistikV;
+
+class Spiel : public SpielKlasse
+{
+private:
+	Statistik *stat;
+	Bestenliste *score;
+	Array< int > *teams;
+	int teamAnzahl;
+	RCArray< Spieler > *spieler;
+	SSDatenbankV *psqldb;
+	int spielId;
+	int karteId;
+	int spielerAnzahl;
+	Karte *karte;
+	CRITICAL_SECTION cs;
+	SpielerTeamStruktur *sts;
+	Datei *log;
+	bool isRunning;
+	int rundenAnzahl;
+	double spielZeit;
+	bool ende;
+    Text mapPfad;
+	int ref;
+
+public:
+	// Konstruktor
+	Spiel();
+	// Destruktor
+	~Spiel();
+	// nicht constant
+	virtual void setPSQLK( SSDatenbankV *psqldb );
+	virtual void setSpielId( int id );
+    virtual void setKarteId( int karteId );
+    virtual void setTempPfad( char *pfad );
+	virtual void setAccounts( int anzahl, Array< int > *zAccounts );
+	virtual void setKlients( int anzahl, RCArray< SSKlientV > *zKlients );
+	virtual void setSpielerNummern( int anzahl, Array< int > *spielerNummern );
+	virtual void klientOffline( int accountId );
+	virtual void klientOnline( int accountId, SSKlientV *zKlient );
+	virtual void nachricht( int accountId, int len, char *bytes );
+	void tick( double zeit );
+	virtual void run();
+	// constant
+	virtual StatistikV *getStatistik() const;
+	// Reference Counting 
+	virtual SpielKlasse *getThis();
+	virtual SpielKlasse *release();
+};
+
+#endif

+ 38 - 0
Linie/SpielKlasse.h

@@ -0,0 +1,38 @@
+#ifndef SpielKlasse_H
+#define SpielKlasse_H
+
+#include "SSKlientV.h"
+#include "SSDatenbankV.h"
+#include "StatistikKlasse.h"
+#include <Thread.h>
+
+using namespace Framework;
+
+class SpielKlasse
+{
+private:
+
+public:
+	virtual ~SpielKlasse()
+	{
+	}
+	// nicht constant
+	virtual void setPSQLK( SSDatenbankV *psqldb ) = 0;
+	virtual void setSpielId( int id ) = 0;
+    virtual void setKarteId( int karteId ) = 0;
+    virtual void setTempPfad( char *pfad ) = 0;
+	virtual void setAccounts( int anzahl, Array< int > *zAccounts ) = 0;
+	virtual void setKlients( int anzahl, RCArray< SSKlientV > *zKlients ) = 0;
+	virtual void setSpielerNummern( int anzahl, Array< int > *spielerNummern ) = 0;
+	virtual void klientOffline( int accountId ) = 0;
+	virtual void klientOnline( int accountId, SSKlientV *zKlient ) = 0;
+	virtual void nachricht( int accountId, int len, char *bytes ) = 0;
+	virtual void run() = 0;
+	// constant
+	virtual StatistikV *getStatistik() const = 0;
+	// Reference Counting 
+	virtual SpielKlasse *getThis() = 0;
+	virtual SpielKlasse *release() = 0;
+};
+
+#endif

+ 453 - 0
Linie/Spieler.cpp

@@ -0,0 +1,453 @@
+#include "Spieler.h"
+#include <math.h>
+#ifdef WIN32
+#include <random>
+#else
+#include <stdlib.h>
+#endif
+
+// Inhalt der Spieler Klasse aus Spieler.h
+// Konstruktor
+Spieler::Spieler()
+{
+	accountId = 0;
+	sNum = 0;
+	team = 0;
+	spielerFarbe = 0;
+	teamFarbe = 0;
+	xPos = 0;
+	yPos = 0;
+	xSpeed = 0;
+	ySpeed = 0;
+	kurve = 0;
+	radius = 1;
+	amLeben = 1;
+	lKurve = 0;
+	rKurve = 0;
+	klient = 0;
+	spielZeit = 0;
+	todesZeit = -1;
+	linieUnterbrochen = 1;
+	nLUChange = 3;
+	lUStrength = 0.3;
+	punkte = 0;
+	rundenGewonnen = 0;
+	linienLength = 0;
+	zeitAmLeben = 0;
+	zeitTod = 0;
+	kills = 0;
+	tode = 0;
+	killFarbe = 0;
+	rundenLinienLength = new Array< int >();
+	rundenLinienLength->set( 0, 0 );
+	rundenKills = new Array< int >();
+	rundenKills->set( 0, 0 );
+	rundenTodesZeit = new Array< int >();
+	rundenTodesZeit->set( 0, 0 );
+	rundenNummer = 0;
+	ref = 1;
+}
+
+// Destruktor
+Spieler::~Spieler()
+{
+	if( klient )
+		klient->release();
+	rundenLinienLength->release();
+	rundenKills->release();
+	rundenTodesZeit->release();
+}
+
+// nicht constant
+void Spieler::offline()
+{
+	klient->offline();
+}
+
+void Spieler::online( SSKlientV *zKlient )
+{
+	klient->online( zKlient );
+}
+
+void Spieler::neuRunde( bool amLeben )
+{
+	if( this->amLeben )
+		rundenGewonnen++;
+	killFarbe = 0;
+	xPos = 0;
+	yPos = 0;
+	xSpeed = 0;
+	ySpeed = 0;
+	kurve = 0;
+	radius = 1;
+	this->amLeben = amLeben;
+	lKurve = 0;
+	rKurve = 0;
+	spielZeit = 0;
+	todesZeit = -1;
+	linieUnterbrochen = 1;
+	nLUChange = 3;
+	lUStrength = 0.3;
+	rundenNummer++;
+	rundenLinienLength->set( 0, rundenNummer );
+	rundenKills->set( 0, rundenNummer );
+	rundenTodesZeit->set( 0, rundenNummer );
+}
+
+void Spieler::setAccountId( int id )
+{
+	accountId = id;
+}
+
+void Spieler::setSpielerNummer( int sNum )
+{
+	this->sNum = sNum;
+}
+
+void Spieler::setTeam( int team )
+{
+	this->team = team;
+}
+
+void Spieler::setSpielerFarbe( int farbe )
+{
+	spielerFarbe = farbe;
+}
+
+void Spieler::setTeamFarbe( int farbe )
+{
+	teamFarbe = farbe;
+}
+
+void Spieler::setGeschwindigkeit( double xSpeed, double ySpeed )
+{
+	this->xSpeed = xSpeed;
+	this->ySpeed = ySpeed;
+}
+
+void Spieler::setPosition( double x, double y )
+{
+	xPos = x;
+	yPos = y;
+}
+
+void Spieler::setWendigkeit( double kurve )
+{
+	this->kurve = kurve;
+}
+
+void Spieler::setSize( int radius )
+{
+	this->radius = radius;
+}
+
+void Spieler::setKlient( Klient *klient )
+{
+	if( this->klient )
+		this->klient->release();
+	this->klient = klient;
+}
+
+void Spieler::setLKurve( bool lK )
+{
+	lKurve = lK;
+}
+
+void Spieler::setRKurve( bool rK )
+{
+	rKurve = rK;
+}
+
+void Spieler::setLinienUnterbrechungsStrength( double uS )
+{
+	lUStrength = uS;
+}
+
+void Spieler::addPunkte( int p )
+{
+	punkte += p;
+}
+
+void Spieler::addKill()
+{
+	kills++;
+	if( rundenKills->hat( rundenNummer ) )
+		rundenKills->set( rundenKills->get( rundenNummer ) + 1, rundenNummer );
+}
+
+void Spieler::tick( Bild *zMap, double zeit )
+{
+	spielZeit += zeit;
+	if( amLeben )
+	{
+		zeitAmLeben += zeit;
+		if( lKurve || rKurve )
+		{
+			double grad = kurve * zeit;
+			if( lKurve )
+				grad = -grad;
+			double cs = cos( grad );
+			double sn = sin( grad );
+			double tmpX = ( xSpeed * cs - ySpeed * sn );
+			double tmpY = ( xSpeed * sn + ySpeed * cs );
+			xSpeed = tmpX;
+			ySpeed = tmpY;
+		}
+		if( zMap && !linieUnterbrochen )
+		{
+			int x1 = (int)( xPos + 0.5 );
+			int y1 = (int)( yPos + 0.5 );
+			int x2 = (int)( xPos + xSpeed * zeit + 0.5 );
+			int y2 = (int)( yPos + ySpeed * zeit + 0.5 );
+			int *buff = zMap->getBuffer();
+			int dpx = 0;
+			int dpy = 0;
+			int dgx = zMap->getBreite();
+			int dgy = zMap->getHeight();
+			int xlen = x2 - x1, axlen = abs( xlen );
+			int ylen = y2 - y1, aylen = abs( ylen );
+			double xf = (double)xlen / ( aylen ? aylen : 1 );
+			double yf = (double)ylen / ( axlen ? axlen : 1 );
+			if( axlen > aylen )
+				xf = xf < 0 ? -1 : 1;
+			else
+				yf = yf < 0 ? -1 : 1;
+			double x = (double)x1, y = (double)y1;
+			int maxP = (int)( sqrt( (double)( xlen * xlen + ylen * ylen ) ) + 0.5 );
+			int count = 0;
+			int lastX = (int)( x + 0.5 ), lastY = (int)( y + 0.5 );
+			while( !( (int)( x + 0.5 ) == x2 && (int)( y + 0.5 ) == y2 ) && count < maxP )
+			{
+				if( (int)( x + 0.5 ) < dpx || (int)( x + 0.5 ) >= dgx || (int)( y + 0.5 ) < dpy || (int)( y + 0.5 ) >= dgy )
+				{
+					if( !rundenTodesZeit->hat( rundenNummer ) || !rundenTodesZeit->get( rundenNummer ) )
+						tode++;
+					xPos = x;
+					yPos = y;
+					todesZeit = spielZeit;
+					rundenTodesZeit->set( (int)todesZeit, rundenNummer );
+					amLeben = 0;
+					killFarbe = 0;
+					break;
+				}
+				if( buff[ (int)( x + 0.5 ) + (int)( y + 0.5 ) * zMap->getBreite() ] )
+				{
+					killFarbe = buff[ (int)( x + 0.5 ) + (int)( y + 0.5 ) * zMap->getBreite() ];
+					if( killFarbe == spielerFarbe )
+						killFarbe = 0;
+					if( !rundenTodesZeit->hat( rundenNummer ) || !rundenTodesZeit->get( rundenNummer ) )
+						tode++;
+					xPos = x;
+					yPos = y;
+					todesZeit = spielZeit;
+					rundenTodesZeit->set( (int)todesZeit, rundenNummer );
+					amLeben = 0;
+					break;
+				}
+				buff[ (int)( x + 0.5 ) + (int)( y + 0.5 ) * zMap->getBreite() ] = spielerFarbe;
+				x += xf, y += yf;
+                if( (int)( x + 0.5 ) < dpx || (int)( x + 0.5 ) >= dgx || (int)( y + 0.5 ) < dpy || (int)( y + 0.5 ) >= dgy )
+                {
+                    if( !rundenTodesZeit->hat( rundenNummer ) || !rundenTodesZeit->get( rundenNummer ) )
+                        tode++;
+                    xPos = x;
+                    yPos = y;
+                    todesZeit = spielZeit;
+                    rundenTodesZeit->set( (int)todesZeit, rundenNummer );
+                    amLeben = 0;
+                    killFarbe = 0;
+                    break;
+                }
+				if( ( lastX != (int)( x + 0.5 ) || lastY != (int)( y + 0.5 ) ) && !buff[ (int)( x + 0.5 ) + (int)( y + 0.5 ) * zMap->getBreite() ] )
+				{
+					linienLength++;
+					if( rundenLinienLength->hat( rundenNummer ) )
+						rundenLinienLength->set( rundenLinienLength->get( rundenNummer ) + 1, rundenNummer );
+				}
+				if( lastX != (int)( x + 0.5 ) && lastY != (int)( yf + 0.5 ) )
+				{
+					if( (int)xf )
+					{
+						if( !( lastX < dpx || lastX >= dgx || (int)( y + 0.5 ) < dpy || (int)( y + 0.5 ) >= dgy ) )
+							buff[ lastX + (int)( y + 0.5 ) * zMap->getBreite() ] = spielerFarbe;
+					}
+					else
+					{
+						if( !( (int)( x + 0.5 ) < dpx || (int)( x + 0.5 ) >= dgx || lastY < dpy || lastY >= dgy ) )
+							buff[ (int)( x + 0.5 ) + lastY * zMap->getBreite() ] = spielerFarbe;
+					}
+				}
+				lastX = (int)( x + 0.5 );
+				lastY = (int)( y + 0.5 );
+				count++;
+			}
+		}
+		if( amLeben )
+		{
+			xPos += xSpeed * zeit;
+			yPos += ySpeed * zeit;
+			nLUChange -= zeit;
+			if( nLUChange <= 0 )
+			{
+				linieUnterbrochen = !linieUnterbrochen;
+				if( linieUnterbrochen )
+					nLUChange = lUStrength;
+				else
+					nLUChange = 1 / lUStrength + ( ( rand() % (int)( 1 / lUStrength ) ) - ( ( 1 / lUStrength ) / 2 ) );
+			}
+		}
+	}
+	else
+		zeitTod += zeit;
+}
+
+// constant
+Klient *Spieler::zKlient() const
+{
+	return klient;
+}
+
+int Spieler::getSpielerNummer() const
+{
+	return sNum;
+}
+
+int Spieler::getSpielerFarbe() const
+{
+	return spielerFarbe;
+}
+
+int Spieler::getSpielerTeam() const
+{
+	return team;
+}
+
+int Spieler::getTeamFarbe() const
+{
+	return teamFarbe;
+}
+
+double Spieler::getX() const
+{
+	return xPos;
+}
+
+double Spieler::getY() const
+{
+	return yPos;
+}
+
+double Spieler::getSpeedX() const
+{
+	return xSpeed;
+}
+
+double Spieler::getSpeedY() const
+{
+	return ySpeed;
+}
+
+double Spieler::getKurve() const
+{
+	return kurve;
+}
+
+bool Spieler::istAmLeben() const
+{
+	return amLeben;
+}
+
+int Spieler::getAccountId() const
+{
+	return accountId;
+}
+
+double Spieler::getTodesZeit() const
+{
+	return todesZeit;
+}
+
+bool Spieler::linieIstUnterbrochen() const
+{
+	return linieUnterbrochen;
+}
+
+int Spieler::getPunkte() const
+{
+	return punkte;
+}
+
+bool Spieler::istOnline() const
+{
+	return klient ? klient->istOnline() : 0;
+}
+
+int Spieler::getKillFarbe() const
+{
+	return killFarbe;
+}
+
+int Spieler::getRundenGewonnen() const
+{
+	return rundenGewonnen + amLeben;
+}
+
+int Spieler::getLinienLength() const
+{
+	return linienLength;
+}
+
+int Spieler::getZeitAmLeben() const
+{
+	return (int)zeitAmLeben;
+}
+
+int Spieler::getZeitTod() const
+{
+	return (int)zeitTod;
+}
+
+int Spieler::getKills() const
+{
+	return kills;
+}
+
+int Spieler::getTode() const
+{
+	return tode;
+}
+
+int Spieler::getLinienLength( int runde ) const
+{
+	return rundenLinienLength->hat( runde ) ? rundenLinienLength->get( runde ) : 0;
+}
+
+int Spieler::getKills( int runde ) const
+{
+	return rundenKills->hat( runde ) ? rundenKills->get( runde ) : 0;
+}
+
+int Spieler::getTodesZeit( int runde ) const
+{
+	return rundenTodesZeit->hat( runde ) ? rundenTodesZeit->get( runde ) : 0;
+}
+
+bool Spieler::machtKurve( bool rechts ) const
+{
+	return ( rechts && rKurve ) || ( !rechts && lKurve );
+}
+
+// Reference Counting
+Spieler *Spieler::getThis()
+{
+	ref++;
+	return this;
+}
+
+Spieler *Spieler::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 102 - 0
Linie/Spieler.h

@@ -0,0 +1,102 @@
+#ifndef Spieler_H
+#define Spieler_H
+
+#include "Klient.h"
+#include <Bild.h>
+
+class Spieler
+{
+private:
+	int accountId;
+	int sNum;
+	int team;
+	int spielerFarbe;
+	int teamFarbe;
+	double xPos;
+	double yPos;
+	double xSpeed;
+	double ySpeed;
+	double kurve;
+	int radius;
+	bool amLeben;
+	bool lKurve;
+	bool rKurve;
+	double spielZeit;
+	double todesZeit;
+	bool linieUnterbrochen;
+	double nLUChange;
+	double lUStrength;
+	int punkte;
+	int rundenGewonnen;
+	int linienLength;
+	double zeitAmLeben;
+	double zeitTod;
+	int kills;
+	int tode;
+	int killFarbe;
+	Array< int > *rundenLinienLength;
+	Array< int > *rundenKills;
+	Array< int > *rundenTodesZeit;
+	int rundenNummer;
+	Klient *klient;
+	int ref;
+
+public:
+	// Konstruktor
+	Spieler();
+	// Destruktor
+	~Spieler();
+	// nicht constant
+	void offline();
+	void online( SSKlientV *zKlient );
+	void neuRunde( bool amLeben );
+	void setAccountId( int id );
+	void setSpielerNummer( int sNum );
+	void setTeam( int team );
+	void setSpielerFarbe( int farbe );
+	void setTeamFarbe( int farbe );
+	void setGeschwindigkeit( double xSpeed, double ySpeed );
+	void setPosition( double x, double y );
+	void setWendigkeit( double kurve );
+	void setSize( int radius );
+	void setKlient( Klient *klient );
+	void setLKurve( bool lK );
+	void setRKurve( bool rK );
+	void setLinienUnterbrechungsStrength( double uS );
+	void addPunkte( int p );
+	void addKill();
+	void tick( Bild *zMap, double zeit );
+	// constant
+	Klient *zKlient() const;
+	int getSpielerNummer() const;
+	int getSpielerFarbe() const;
+	int getSpielerTeam() const;
+	int getTeamFarbe() const;
+	double getX() const;
+	double getY() const;
+	double getSpeedX() const;
+	double getSpeedY() const;
+	double getKurve() const;
+	bool istAmLeben() const;
+	int getAccountId() const;
+	double getTodesZeit() const;
+	bool linieIstUnterbrochen() const;
+	int getPunkte() const;
+	bool istOnline() const;
+	int getKillFarbe() const;
+	int getRundenGewonnen() const;
+	int getLinienLength() const;
+	int getZeitAmLeben() const;
+	int getZeitTod() const;
+	int getKills() const;
+	int getTode() const;
+	int getLinienLength( int runde ) const;
+	int getKills( int runde ) const;
+	int getTodesZeit( int runde ) const;
+	bool machtKurve( bool rechts ) const;
+	// Reference Counting
+	Spieler *getThis();
+	Spieler *release();
+};
+
+#endif

+ 462 - 0
Linie/Statistik.cpp

@@ -0,0 +1,462 @@
+#include "Statistik.h"
+#include <DateiSystem.h>
+#include <Datei.h>
+#ifndef WIN32
+#include <unistd.h>
+#define Sleep( x )    usleep( (x) * 1000 )
+#endif
+
+// Inhalt der Statistik Klasse aus Statistik.h
+// Konstruktor
+Statistik::Statistik()
+{
+	spielId = 0;
+	karteId = 0;
+	db = 0;
+	spielerAnzahl = 0;
+	spieler = new RCArray< Spieler >();
+	erstellt = 0;
+	sOnline = new Array< bool >();
+	sBereit = new Array< bool >();
+	gss = new RCArray< GesamtSpielerStatistik >();
+	gts = new RCArray< GesamtTeamStatistik >();
+	rrs = new RCArray< RundenRundenStatistik >();
+	teamNamen = 0;
+	gewinnerTeam = new Array< int >();
+	rundenDauer = new Array< int >();
+	rundenBild = new RCArray< Bild >();
+	ref = 1;
+}
+
+// Destruktor
+Statistik::~Statistik()
+{
+	if( db )
+		db->release();
+	spieler->release();
+	sOnline->release();
+	sBereit->release();
+	gss->release();
+	gts->release();
+	rrs->release();
+	if( teamNamen )
+		teamNamen->release();
+	gewinnerTeam->release();
+	rundenDauer->release();
+	rundenBild->release();
+}
+
+// privat
+void Statistik::sendeStatistik( int index )
+{ // Sendet Statistik an Spieler index
+	if( !sOnline->hat( index ) || !sOnline->get( index ) )
+		return;
+	Klient *zk = spieler->z( index )->zKlient();
+	if( !zk )
+		return;
+	int anz = gss->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+		zk->sendeGesamtSpielerStatistik( gss->z( i ) );
+	anz = gts->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+		zk->sendeGesamtTeamStatistik( gts->z( i ) );
+	anz = rrs->getEintragAnzahl();
+	for( int i = 0; i < anz; i++ )
+		zk->sendeRundeStatistik( rrs->z( i ) );
+	zk->sendeStatistikLadenFertig();
+	for( int i = 0; i < spielerAnzahl; i++ )
+	{
+		if( !sOnline->hat( i ) || !sOnline->get( i ) )
+			zk->sendeStatistikSpielerOffline( spieler->z( i )->getAccountId() );
+	}
+}
+
+// nicht constant
+void Statistik::setSpielId( int id )
+{
+	spielId = id;
+}
+
+void Statistik::setKarteId( int id )
+{
+	karteId = id;
+}
+
+void Statistik::setPSQLDB( SSDatenbankV *db )
+{
+	if( this->db )
+		this->db->release();
+	this->db = db;
+}
+
+void Statistik::setTeamNamen( RCArray< Text > *namen )
+{
+	if( teamNamen )
+		teamNamen->release();
+	teamNamen = namen;
+}
+
+void Statistik::rundenEnde( int team, int dauer, Bild *b )
+{
+	gewinnerTeam->add( team );
+	rundenDauer->add( dauer );
+	Bild *rb = new Bild();
+	rb->neuBild( b->getBreite(), b->getHeight(), 0 );
+	rb->drawBild( 0, 0, rb->getBreite(), rb->getHeight(), *b );
+	rundenBild->add( rb );
+	b->release();
+}
+
+void Statistik::setSpieler( int anzahl, RCArray< Spieler > *zSpieler )
+{
+	spielerAnzahl = anzahl;
+	for( int i = 0; i < anzahl; i++ )
+	{
+		spieler->set( zSpieler->get( i ), i );
+		sOnline->set( 0, i );
+		sBereit->set( 0, i );
+	}
+}
+
+void Statistik::klientOffline( int accountId )
+{
+	for( int i = 0; i < spielerAnzahl; i++ )
+	{
+		if( spieler->z( i )->getAccountId() == accountId )
+		{
+			sOnline->set( 0, i );
+			sBereit->set( 0, i );
+		}
+		else if( sOnline->hat( i ) && sOnline->get( i ) && spieler->z( i )->zKlient() )
+			spieler->z( i )->zKlient()->sendeStatistikSpielerOffline( accountId );
+	}
+}
+
+void Statistik::statistikAnfrage( int accountId, short len, char *bytes )
+{
+	len--;
+	switch( *bytes )
+	{
+	case 1: // Spieler ist Bereit
+		for( int i = 0; i < spielerAnzahl; i++ )
+		{
+			if( !erstellt )
+			{
+				if( spieler->z( i )->getAccountId() == accountId )
+					sBereit->set( 1, i );
+			}
+			else if( spieler->z( i )->getAccountId() == accountId )
+			{
+				sendeStatistik( i );
+				break;
+			}
+		}
+		break;
+	case 2: // Chat Nachricht
+		bytes++;
+		char *txt = new char[ len + 1 ];
+		txt[ len ] = 0;
+		for( int i = 0; i < len; i++ )
+			txt[ i ] = bytes[ i ];
+		for( int i = 0; i < spielerAnzahl; i++ )
+		{
+			if( sOnline->hat( i ) && sOnline->get( i ) && spieler->z( i )->zKlient() )
+				spieler->z( i )->zKlient()->sendeStatistikChatNachricht( accountId, txt );
+		}
+		delete[] txt;
+		break;
+	}
+}
+
+void Statistik::run()
+{
+	for( int i = 0; i < spielerAnzahl; i++ )
+		sOnline->set( spieler->z( i )->istOnline(), i );
+	// Statistik erstellen
+	// gesammt Spieler
+	for( int i = 0; i < spielerAnzahl; i++ )
+	{
+		if( spieler->z( i ) )
+		{
+			Spieler *tmp = spieler->z( i );
+			InitDatei *d = new InitDatei();
+			Text w;
+			w = tmp->getSpielerNummer();
+			if( w.getLength() )
+				d->addWert( "SpielerNummer", w.getText() );
+			Text *sn = db->getAccountRufName( tmp->getAccountId() );
+			if( sn && sn->getLength() )
+				d->addWert( "SpielerName", sn->getText() );
+			if( sn )
+				sn->release();
+			if( teamNamen && teamNamen->z( tmp->getSpielerTeam() ) )
+				d->addWert( "TeamName", teamNamen->z( tmp->getSpielerTeam() )->getText() );
+			w = tmp->getSpielerFarbe();
+			if( w.getLength() )
+				d->addWert( "SpielerFarbe", w.getText() );
+			w = tmp->getTeamFarbe();
+			if( w.getLength() )
+				d->addWert( "TeamFarbe", w.getText() );
+			w = tmp->getRundenGewonnen();
+			if( w.getLength() )
+				d->addWert( "GewonneneRunden", w.getText() );
+			w = tmp->getPunkte();
+			if( w.getLength() )
+				d->addWert( "Punkte", w.getText() );
+			w = tmp->getLinienLength();
+			if( w.getLength() )
+				d->addWert( "LinienLänge", w.getText() );
+			w = tmp->getZeitAmLeben();
+			if( w.getLength() )
+				d->addWert( "ZeitAmLeben", w.getText() );
+			w = tmp->getZeitTod();
+			if( w.getLength() )
+				d->addWert( "ZeitTod", w.getText() );
+			w = tmp->getKills();
+			if( w.getLength() )
+				d->addWert( "Kills", w.getText() );
+			w = tmp->getTode();
+			if( w.getLength() )
+				d->addWert( "Tode", w.getText() );
+			GesamtSpielerStatistik *gss = new GesamtSpielerStatistik();
+			gss->initValues( d );
+			this->gss->add( gss );
+		}
+	}
+	// Gesamt Team
+	for( int i = 0; i < spielerAnzahl; i++ )
+	{
+		Spieler *tmp = spieler->z( i );
+		if( tmp )
+		{
+			int anz = gts->getEintragAnzahl();
+			bool gefunden = 0;
+			for( int j = 0; j < anz; j++ )
+			{
+				if( gts->z( j ) && gts->z( j )->getTeamNummer() == tmp->getSpielerTeam() )
+				{
+					gefunden = 1;
+					break;
+				}
+			}
+			if( gefunden )
+				continue;
+			InitDatei *d = new InitDatei();
+			Text w;
+			w = tmp->getSpielerTeam();
+			if( w.getLength() )
+				d->addWert( "TeamNummer", w.getText() );
+			if( teamNamen && teamNamen->z( tmp->getSpielerTeam() ) )
+				d->addWert( "TeamName", teamNamen->z( tmp->getSpielerTeam() )->getText() );
+			w = tmp->getTeamFarbe();
+			if( w.getLength() )
+				d->addWert( "TeamFarbe", w.getText() );
+			int rundenGewonnen = 0;
+			anz = gewinnerTeam->getEintragAnzahl();
+			for( int j = 0; j < anz; j++ )
+			{
+				if( gewinnerTeam->hat( j ) && gewinnerTeam->get( j ) == tmp->getSpielerTeam() )
+					rundenGewonnen++;
+			}
+			w = rundenGewonnen;
+			if( w.getLength() )
+				d->addWert( "GewonneneRunden", w.getText() );
+			int punkte = 0;
+			int linienLength = 0;
+			int kills = 0;
+			int tode = 0;
+			for( int j = 0; j < spielerAnzahl; j++ )
+			{
+				Spieler *s = spieler->z( j );
+				if( s && s->getSpielerTeam() == tmp->getSpielerTeam() )
+				{
+					punkte += s->getPunkte();
+					linienLength += s->getLinienLength();
+					kills += s->getKills();
+					tode += s->getTode();
+				}
+			}
+			w = punkte;
+			if( w.getLength() )
+				d->addWert( "Punkte", w.getText() );
+			w = linienLength;
+			if( w.getLength() )
+				d->addWert( "LinienLänge", w.getText() );
+			w = kills;
+			if( w.getLength() )
+				d->addWert( "Kills", w.getText() );
+			w = tode;
+			if( w.getLength() )
+				d->addWert( "Tode", w.getText() );
+			GesamtTeamStatistik *gts = new GesamtTeamStatistik();
+			gts->initValues( d );
+			this->gts->add( gts );
+		}
+	}
+	// Rundenweise
+	int rAnz = gewinnerTeam->getEintragAnzahl();
+	for( int i = 0; i < rAnz; i++ )
+	{
+		InitDatei *d = new InitDatei();
+		Text w;
+		w = i;
+		if( w.getLength() )
+			d->addWert( "RundenNummer", w.getText() );
+		w = rundenDauer->hat( i ) ? rundenDauer->get( i ) : -1;
+		if( w.getLength() )
+			d->addWert( "RundenDauer", w.getText() );
+		w = gewinnerTeam->hat( i ) ? gewinnerTeam->get( i ) : -1;
+		if( w.getLength() )
+			d->addWert( "SiegerTeam", w.getText() );
+		int spielFeldNutzung = 0;
+		Bild *rb = rundenBild->get( i );
+		int *rbBuff = rb->getBuffer();
+		for( int j = 0; j < rb->getBreite() * rb->getHeight(); j++ )
+		{
+			if( rbBuff[ j ] )
+				spielFeldNutzung++;
+		}
+		w = (int)( ( spielFeldNutzung / ( (double)( rb->getBreite() * rb->getHeight() ) / 25 ) ) * 100 );
+		if( w.getLength() )
+			d->addWert( "SpielFeldNutzung", w.getText() );
+		RundenRundenStatistik *rrs = new RundenRundenStatistik();
+		rrs->initValues( d );
+		rrs->setBild( rb );
+		// Runde Spieler
+		for( int j = 0; j < spielerAnzahl; j++ )
+		{
+			Spieler *tmp = spieler->z( j );
+			if( tmp )
+			{
+				InitDatei *d = new InitDatei();
+				Text w;
+				w = tmp->getSpielerNummer();
+				if( w.getLength() )
+					d->addWert( "SpielerNummer", w.getText() );
+				Text *sn = db->getAccountRufName( tmp->getAccountId() );
+				if( sn && sn->getLength() )
+					d->addWert( "SpielerName", sn->getText() );
+				if( sn )
+					sn->release();
+				if( teamNamen && teamNamen->z( tmp->getSpielerTeam() ) )
+					d->addWert( "TeamName", teamNamen->z( tmp->getSpielerTeam() )->getText() );
+				w = tmp->getSpielerFarbe();
+				if( w.getLength() )
+					d->addWert( "SpielerFarbe", w.getText() );
+				w = tmp->getTeamFarbe();
+				if( w.getLength() )
+					d->addWert( "TeamFarbe", w.getText() );
+				w = tmp->getLinienLength( i );
+				if( w.getLength() )
+					d->addWert( "LinienLänge", w.getText() );
+				w = tmp->getKills( i );
+				if( w.getLength() )
+					d->addWert( "Kills", w.getText() );
+				w = tmp->getTodesZeit( i );
+				if( w.getLength() )
+					d->addWert( "Todeszeit", w.getText() );
+				RundenSpielerStatistik *rss = new RundenSpielerStatistik();
+				rss->initValues( d );
+				rrs->addSpielerStatistik( rss );
+			}
+		}
+		// Runde Team
+		for( int j = 0; j < spielerAnzahl; j++ )
+		{
+			Spieler *tmp = spieler->z( j );
+			if( tmp )
+			{
+				int anz = gts->getEintragAnzahl();
+				bool gefunden = 0;
+				for( int k = 0; k < anz; k++ )
+				{
+					if( rrs->zTeamStatistik( k ) && rrs->zTeamStatistik( k )->getTeamNummer() == tmp->getSpielerTeam() )
+					{
+						gefunden = 1;
+						break;
+					}
+				}
+				if( gefunden )
+					continue;
+				InitDatei *d = new InitDatei();
+				Text w;
+				w = tmp->getSpielerTeam();
+				if( w.getLength() )
+					d->addWert( "TeamNummer", w.getText() );
+				if( teamNamen && teamNamen->z( tmp->getSpielerTeam() ) )
+					d->addWert( "TeamName", teamNamen->z( tmp->getSpielerTeam() )->getText() );
+				w = tmp->getTeamFarbe();
+				if( w.getLength() )
+					d->addWert( "TeamFarbe", w.getText() );
+				w = (int)( ( gewinnerTeam->hat( i ) ? gewinnerTeam->get( i ) : 0 ) == tmp->getSpielerTeam() );
+				if( w.getLength() )
+					d->addWert( "Ergebnis", w.getText() );
+				int linienLength = 0;
+				int kills = 0;
+				int tode = 0;
+				for( int k = 0; k < spielerAnzahl; k++ )
+				{
+					Spieler *s = spieler->z( k );
+					if( s && s->getSpielerTeam() == tmp->getSpielerTeam() )
+					{
+						linienLength += s->getLinienLength( i );
+						kills += s->getKills( i );
+						tode += ( s->getTodesZeit( i ) != 0 );
+					}
+				}
+				w = linienLength;
+				if( w.getLength() )
+					d->addWert( "LinienLänge", w.getText() );
+				w = kills;
+				if( w.getLength() )
+					d->addWert( "Kills", w.getText() );
+				w = tode;
+				if( w.getLength() )
+					d->addWert( "Tode", w.getText() );
+				RundenTeamStatistik *rts = new RundenTeamStatistik();
+				rts->initValues( d );
+				rrs->addTeamStatistik( rts );
+			}
+		}
+		this->rrs->add( rrs );
+	}
+	erstellt = 1;
+	// Statistik senden
+	for( int i = 0; i < spielerAnzahl; i++ )
+	{
+		if( sBereit->hat( i ) && sBereit->get( i ) )
+			sendeStatistik( i );
+	}
+	// Statistik speichern
+	Text *pfad = new Text( "../spiel log/" );
+	pfad->append( spielId );
+	pfad->append( "/fertig" );
+	DateiPfadErstellen( pfad );
+	// warten bis alle verlassen haben
+	while( 1 )
+	{
+		Sleep( 1000 );
+		int online = 0;
+		for( int i = 0; i < spielerAnzahl; i++ )
+			online += sOnline->hat( i ) && sOnline->get( i );
+		if( !online )
+			break;
+	}
+}
+
+// constant
+
+// Reference Counting
+StatistikV *Statistik::getThis()
+{
+	ref++;
+	return this;
+}
+
+StatistikV *Statistik::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 55 - 0
Linie/Statistik.h

@@ -0,0 +1,55 @@
+#ifndef Statistik_H
+#define Statistik_H
+
+#include "StatistikKlasse.h"
+#include "Spieler.h"
+#include "SSDatenbankV.h"
+#include "GesamtSpielerStatistik.h"
+#include "GesamtTeamStatistik.h"
+#include "RundenRundenStatistik.h"
+
+class Statistik : public StatistikV
+{
+private:
+	int spielId;
+	int karteId;
+	SSDatenbankV *db;
+	int spielerAnzahl;
+	RCArray< Spieler > *spieler;
+	bool erstellt;
+	Array< bool > *sOnline;
+	Array< bool > *sBereit;
+	RCArray< GesamtSpielerStatistik > *gss;
+	RCArray< GesamtTeamStatistik > *gts;
+	RCArray< RundenRundenStatistik > *rrs;
+	RCArray< Text > *teamNamen;
+	Array< int > *gewinnerTeam;
+	Array< int > *rundenDauer;
+	RCArray< Bild > *rundenBild;
+	int ref;
+
+	void sendeStatistik( int index );
+
+public:
+	// Konstruktor
+	Statistik();
+	// Destruktor
+	~Statistik();
+	// nicht constant
+	void setSpielId( int id );
+	void setKarteId( int id );
+	void setPSQLDB( SSDatenbankV *db );
+	void setTeamNamen( RCArray< Text > *namen );
+	void rundenEnde( int team, int dauer, Bild *b );
+	void setSpieler( int anzahl, RCArray< Spieler > *zSpieler );
+	virtual void klientOffline( int accountId );
+	virtual void statistikAnfrage( int accountId, short len, char *bytes );
+	virtual void run();
+	// constant
+
+	// Reference Counting
+	virtual StatistikV *getThis();
+	virtual StatistikV *release();
+};
+
+#endif

+ 23 - 0
Linie/StatistikKlasse.h

@@ -0,0 +1,23 @@
+#ifndef StatistikKlasse_H
+#define StatistikKlasse_H
+
+class StatistikV
+{
+private:
+
+public:
+	virtual ~StatistikV()
+	{
+	}
+	// nicht constant
+	virtual void klientOffline( int accountId ) = 0;
+	virtual void statistikAnfrage( int accountId, short len, char *bytes ) = 0;
+	virtual void run() = 0;
+	// constant
+
+	// Reference Counting
+	virtual StatistikV *getThis() = 0;
+	virtual StatistikV *release() = 0;
+};
+
+#endif

+ 35 - 0
Linie/Strukturen.cpp

@@ -0,0 +1,35 @@
+#include "Strukturen.h"
+
+// Inhalt der SpielerTeamStruktur Struktur aus Strukturen.h
+SpielerTeamStruktur::SpielerTeamStruktur()
+{
+	spielerAnzahl = 0;
+	teamAnzahl = 0;
+	spielerFarbe = new Array< int >();
+	teamFarbe = new Array< int >();
+	teamName = new RCArray< Text >();
+	teamSize = new Array< int >();
+	ref = 1;
+}
+
+SpielerTeamStruktur::~SpielerTeamStruktur()
+{
+	spielerFarbe->release();
+	teamFarbe->release();
+	teamName->release();
+	teamSize->release();
+}
+
+SpielerTeamStruktur *SpielerTeamStruktur::getThis()
+{
+	ref++;
+	return this;
+}
+
+SpielerTeamStruktur *SpielerTeamStruktur::release()
+{
+	ref--;
+	if( !ref )
+		delete this;
+	return 0;
+}

+ 24 - 0
Linie/Strukturen.h

@@ -0,0 +1,24 @@
+#ifndef Strukturen_H
+#define Strukturen_H
+
+#include <Array.h>
+#include <Text.h>
+
+using namespace Framework;
+
+struct SpielerTeamStruktur
+{
+	SpielerTeamStruktur();
+	~SpielerTeamStruktur();
+	int spielerAnzahl;
+	int teamAnzahl;
+	Array< int > *spielerFarbe;
+	Array< int > *teamFarbe;
+	RCArray< Text > *teamName;
+	Array< int > *teamSize;
+	int ref;
+	SpielerTeamStruktur *getThis();
+	SpielerTeamStruktur *release();
+};
+
+#endif

+ 2 - 0
build.bat

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