Browse Source

Projektdateien hinzufügen.

Kolja Strohm 3 years ago
parent
commit
a1cfecfcfb
56 changed files with 3027 additions and 0 deletions
  1. 51 0
      FactoryCraft.sln
  2. 15 0
      FactoryCraft/AbstractEventListener.h
  3. 43 0
      FactoryCraft/BasicBlock.cpp
  4. 37 0
      FactoryCraft/BasicBlocks.h
  5. 22 0
      FactoryCraft/BasicInterpolator.cpp
  6. 9 0
      FactoryCraft/BasicInterpolator.h
  7. 36 0
      FactoryCraft/BiomGenerator.cpp
  8. 28 0
      FactoryCraft/BiomGenerator.h
  9. 24 0
      FactoryCraft/BiomInterpolator.h
  10. 140 0
      FactoryCraft/Block.cpp
  11. 73 0
      FactoryCraft/Block.h
  12. 15 0
      FactoryCraft/BlockDestroyedEvent.h
  13. 15 0
      FactoryCraft/BlockPlacedEvent.h
  14. 15 0
      FactoryCraft/BlockType.cpp
  15. 32 0
      FactoryCraft/BlockType.h
  16. 26 0
      FactoryCraft/Chunk.h
  17. 9 0
      FactoryCraft/Constants.h
  18. 212 0
      FactoryCraft/Datenbank.cpp
  19. 42 0
      FactoryCraft/Datenbank.h
  20. 10 0
      FactoryCraft/DefaultEventListener.h
  21. 15 0
      FactoryCraft/Dimension.h
  22. 84 0
      FactoryCraft/DimensionGenerator.cpp
  23. 27 0
      FactoryCraft/DimensionGenerator.h
  24. 25 0
      FactoryCraft/Effect.h
  25. 14 0
      FactoryCraft/EffectFactory.h
  26. 16 0
      FactoryCraft/Entity.h
  27. 15 0
      FactoryCraft/Event.h
  28. 9 0
      FactoryCraft/EventListener.h
  29. 22 0
      FactoryCraft/EventThrower.h
  30. 171 0
      FactoryCraft/FactoryCraft.vcxproj
  31. 216 0
      FactoryCraft/FactoryCraft.vcxproj.filters
  32. 24 0
      FactoryCraft/Game.h
  33. 22 0
      FactoryCraft/GrasslandBiom.cpp
  34. 12 0
      FactoryCraft/GrasslandBiom.h
  35. 18 0
      FactoryCraft/Inventory.h
  36. 46 0
      FactoryCraft/Item.h
  37. 47 0
      FactoryCraft/ItemSkill.h
  38. 19 0
      FactoryCraft/ItemSlot.h
  39. 20 0
      FactoryCraft/ItemStack.h
  40. 52 0
      FactoryCraft/ItemType.cpp
  41. 38 0
      FactoryCraft/ItemType.h
  42. 20 0
      FactoryCraft/LocationChangedEvent.h
  43. 11 0
      FactoryCraft/Noise.cpp
  44. 20 0
      FactoryCraft/Noise.h
  45. 9 0
      FactoryCraft/OverworldDimension.cpp
  46. 14 0
      FactoryCraft/OverworldDimension.h
  47. 71 0
      FactoryCraft/PerlinNoise.cpp
  48. 22 0
      FactoryCraft/PerlinNoise.h
  49. 12 0
      FactoryCraft/Player.h
  50. 728 0
      FactoryCraft/Server.cpp
  51. 109 0
      FactoryCraft/Server.h
  52. 66 0
      FactoryCraft/Start.cpp
  53. 8 0
      FactoryCraft/StaticInitializerOrder.cpp
  54. 71 0
      FactoryCraft/StaticRegistry.h
  55. 67 0
      FactoryCraft/WorldGenerator.cpp
  56. 33 0
      FactoryCraft/WorldGenerator.h

+ 51 - 0
FactoryCraft.sln

@@ -0,0 +1,51 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31025.194
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FactoryCraft", "FactoryCraft\FactoryCraft.vcxproj", "{A1B59831-7E37-4F83-A545-0E27609E8295}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|ARM = Debug|ARM
+		Debug|ARM64 = Debug|ARM64
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|ARM = Release|ARM
+		Release|ARM64 = Release|ARM64
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{A1B59831-7E37-4F83-A545-0E27609E8295}.Debug|ARM.ActiveCfg = Debug|ARM
+		{A1B59831-7E37-4F83-A545-0E27609E8295}.Debug|ARM.Build.0 = Debug|ARM
+		{A1B59831-7E37-4F83-A545-0E27609E8295}.Debug|ARM.Deploy.0 = Debug|ARM
+		{A1B59831-7E37-4F83-A545-0E27609E8295}.Debug|ARM64.ActiveCfg = Debug|ARM64
+		{A1B59831-7E37-4F83-A545-0E27609E8295}.Debug|ARM64.Build.0 = Debug|ARM64
+		{A1B59831-7E37-4F83-A545-0E27609E8295}.Debug|ARM64.Deploy.0 = Debug|ARM64
+		{A1B59831-7E37-4F83-A545-0E27609E8295}.Debug|x64.ActiveCfg = Debug|x64
+		{A1B59831-7E37-4F83-A545-0E27609E8295}.Debug|x64.Build.0 = Debug|x64
+		{A1B59831-7E37-4F83-A545-0E27609E8295}.Debug|x64.Deploy.0 = Debug|x64
+		{A1B59831-7E37-4F83-A545-0E27609E8295}.Debug|x86.ActiveCfg = Debug|x86
+		{A1B59831-7E37-4F83-A545-0E27609E8295}.Debug|x86.Build.0 = Debug|x86
+		{A1B59831-7E37-4F83-A545-0E27609E8295}.Debug|x86.Deploy.0 = Debug|x86
+		{A1B59831-7E37-4F83-A545-0E27609E8295}.Release|ARM.ActiveCfg = Release|ARM
+		{A1B59831-7E37-4F83-A545-0E27609E8295}.Release|ARM.Build.0 = Release|ARM
+		{A1B59831-7E37-4F83-A545-0E27609E8295}.Release|ARM.Deploy.0 = Release|ARM
+		{A1B59831-7E37-4F83-A545-0E27609E8295}.Release|ARM64.ActiveCfg = Release|ARM64
+		{A1B59831-7E37-4F83-A545-0E27609E8295}.Release|ARM64.Build.0 = Release|ARM64
+		{A1B59831-7E37-4F83-A545-0E27609E8295}.Release|ARM64.Deploy.0 = Release|ARM64
+		{A1B59831-7E37-4F83-A545-0E27609E8295}.Release|x64.ActiveCfg = Release|x64
+		{A1B59831-7E37-4F83-A545-0E27609E8295}.Release|x64.Build.0 = Release|x64
+		{A1B59831-7E37-4F83-A545-0E27609E8295}.Release|x64.Deploy.0 = Release|x64
+		{A1B59831-7E37-4F83-A545-0E27609E8295}.Release|x86.ActiveCfg = Release|x86
+		{A1B59831-7E37-4F83-A545-0E27609E8295}.Release|x86.Build.0 = Release|x86
+		{A1B59831-7E37-4F83-A545-0E27609E8295}.Release|x86.Deploy.0 = Release|x86
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {D61C82D1-9CA9-452F-AF72-D68A8E42B78D}
+	EndGlobalSection
+EndGlobal

+ 15 - 0
FactoryCraft/AbstractEventListener.h

@@ -0,0 +1,15 @@
+#pragma once
+
+#include "EventListener.h"
+#include "BlockDestroyedEvent.h"
+#include "LocationChangedEvent.h"
+
+class AbstractEventListener : public EventListener
+{
+public:
+    void process( Event *event ) override;
+
+protected:
+    virtual void onBlockDestroyed( const BlockDestroyedEvent &event ) = 0;
+    virtual void onLocationChanged( const LocationChangedEvent &event ) = 0;
+};

+ 43 - 0
FactoryCraft/BasicBlock.cpp

@@ -0,0 +1,43 @@
+#include "BasicBlocks.h"
+
+
+BasicBlockType::BasicBlockType()
+    : BlockType( 1 )
+{
+
+}
+
+void BasicBlockType::loadSuperBlock( Block *zBlock, Framework::Reader *zReader )
+{
+
+}
+
+void BasicBlockType::createSuperBlock( Block *zBlock, Framework::Reader *zReader )
+{
+
+}
+
+void BasicBlockType::createSuperItem( Block *zBlock, Item *zItem )
+{
+
+}
+
+Block *BasicBlockType::loadBlock( Framework::Vec3<int> position, Game *zTarget, Framework::Reader *zReader )
+{
+
+}
+
+void BasicBlockType::saveBlock( Block *zBlock, Framework::Writer *zWriter )
+{
+
+}
+
+Item *BasicBlockType::getItemFromBlock( Block *zBlock, Game *zTarget )
+{
+
+}
+
+Block *BasicBlockType::createBlockAt( Framework::Vec3<int> position, Game *zTarget, Item *zUsedItem )
+{
+
+}

+ 37 - 0
FactoryCraft/BasicBlocks.h

@@ -0,0 +1,37 @@
+#pragma once
+
+#include "Block.h"
+#include "BlockType.h"
+#include "Item.h"
+
+class BasicBlockType;
+
+class BasicBlock : public Block
+{
+private:
+
+    friend BasicBlockType;
+};
+
+class BasicBlockType : public BlockType
+{
+    REGISTRABLE( BasicBlockType )
+
+protected:
+    virtual void loadSuperBlock( Block *zBlock, Framework::Reader *zReader ) override;
+    virtual void createSuperBlock( Block *zBlock, Framework::Reader *zReader ) override;
+    virtual void createSuperItem( Block *zBlock, Item *zItem ) override;
+
+public:
+    BasicBlockType();
+
+    virtual Block *loadBlock( Framework::Vec3<int> position, Game *zTarget, Framework::Reader *zReader ) override;
+    virtual void saveBlock( Block *zBlock, Framework::Writer *zWriter ) override;
+    virtual Item *getItemFromBlock( Block *zBlock, Game *zTarget ) override;
+    virtual Block *createBlockAt( Framework::Vec3<int> position, Game *zTarget, Item *zUsedItem ) override;
+};
+
+#ifdef REGISTER
+REGISTER( BasicBlockType )
+#endif
+

+ 22 - 0
FactoryCraft/BasicInterpolator.cpp

@@ -0,0 +1,22 @@
+#include "BasicInterpolator.h"
+#include "Block.h"
+
+Block *BasicInterpolator::interpolateBlocks( Block *a, Block *b, double aWeight, double bWeight, Noise *zNoise )
+{
+    if( aWeight < bWeight )
+        return interpolateBlocks( b, a, bWeight, aWeight, zNoise );
+    double score = bWeight / aWeight;
+    if( score < 0.8 )
+    {
+        b->release();
+        return a;
+    }
+    score = ( score - 0.8 ) * 5;
+    if( score < zNoise->getNoise( ( score + 60 ) * 5, 100, 50 ) )
+    {
+        b->release();
+        return a;
+    }
+    a->release();
+    return b;
+}

+ 9 - 0
FactoryCraft/BasicInterpolator.h

@@ -0,0 +1,9 @@
+#pragma once
+
+#include "BiomInterpolator.h"
+
+class BasicInterpolator : public BiomInterpolator
+{
+public:
+    Block *interpolateBlocks( Block *a, Block *b, double aWeight, double bWeight, Noise *zNoise ) override;
+};

+ 36 - 0
FactoryCraft/BiomGenerator.cpp

@@ -0,0 +1,36 @@
+#include "BiomGenerator.h"
+
+
+BiomGenerator::BiomGenerator()
+    : ReferenceCounter()
+{}
+
+double BiomGenerator::getBiomXMultiplier()
+{
+    return biomXMultiplier;
+}
+
+double BiomGenerator::getBiomYMultiplier()
+{
+    return biomYMultiplier;
+}
+
+double BiomGenerator::getBiomOutputMultiplier()
+{
+    return biomOutputMultiplier;
+}
+
+double BiomGenerator::getAirLevelXMultiplier()
+{
+    return airXMultiplier;
+}
+
+double BiomGenerator::getAirLevelYMultiplier()
+{
+    return airYMultiplier;
+}
+
+double BiomGenerator::getAirLevelOutputMultiplier()
+{
+    return airOutputMultiplier;
+}

+ 28 - 0
FactoryCraft/BiomGenerator.h

@@ -0,0 +1,28 @@
+#pragma once
+
+#include <ReferenceCounter.h>
+
+class Block;
+class Noise;
+class Game;
+
+class BiomGenerator : public virtual Framework::ReferenceCounter
+{
+protected:
+    double biomXMultiplier;
+    double biomYMultiplier;
+    double biomOutputMultiplier;
+    double airXMultiplier;
+    double airYMultiplier;
+    double airOutputMultiplier;
+
+public:
+    BiomGenerator();
+    virtual Block *getBlock( Noise *zNoise, int x, int y, int z, Game *zGame ) = 0;
+    double getBiomXMultiplier();
+    double getBiomYMultiplier();
+    double getBiomOutputMultiplier();
+    double getAirLevelXMultiplier();
+    double getAirLevelYMultiplier();
+    double getAirLevelOutputMultiplier();
+};

+ 24 - 0
FactoryCraft/BiomInterpolator.h

@@ -0,0 +1,24 @@
+#pragma once
+
+#include <ReferenceCounter.h>
+
+#include "Noise.h"
+
+class Block;
+
+class BiomInterpolator : public virtual Framework::ReferenceCounter
+{
+public:
+    /// <summary>
+    /// interpolates two different blocks
+    /// the block with a heigher weight has a heigher propability to be returned
+    /// the block that is not returned will be deleted
+    /// </summary>
+    /// <param name="a">the block with weight aWeight</param>
+    /// <param name="b">the block with weight bWeight</param>
+    /// <param name="aWeight">the weight for block a</param>
+    /// <param name="bWeight">the weight for block b</param>
+    /// <param name="zNoise">the noise to use</param>
+    /// <returns>either a or b</returns>
+    virtual Block *interpolateBlocks( Block *a, Block *b, double aWeight, double bWeight, Noise *zNoise ) = 0;
+};

+ 140 - 0
FactoryCraft/Block.cpp

@@ -0,0 +1,140 @@
+#include "Block.h"
+
+Block::Block( BlockType *zType, ItemType *zTool )
+{
+    transparent = false;
+    passable = false;
+    hp = 1;
+    maxHP = 1;
+    hardness = 1;
+    this->zType = zType;
+    this->zTool = zTool;
+    speedModifier = 1;
+    fluidCapacity = 10;
+    fluidAmount = 0;
+    fluidTypeId = -1;
+    fluidSpeed = 4;
+}
+
+void Block::tick()
+{
+    if( fluidTypeId >= 0 )
+    {
+        int fluidLeft = MIN( fluidSpeed, fluidAmount );
+        if( fluidLeft > 0 )
+        {
+            if( neighbours[ BOTTOM ] )
+            {
+                int result = neighbours[ BOTTOM ]->addFluid( fluidTypeId, fluidLeft, TOP );
+                fluidLeft -= result;
+                fluidAmount -= result;
+            }
+            int distribution = (int)ceil( (float)fluidLeft / 4.f );
+            if( neighbours[ NORTH ] && neighbours[ NORTH ]->getFluidAmount() < fluidAmount - 1 )
+            {
+                int amount = MIN( distribution, ( fluidAmount - neighbours[ NORTH ]->getFluidAmount() ) / 2 );
+                int result = neighbours[ NORTH ]->addFluid( fluidTypeId, amount, SOUTH );
+                fluidLeft -= result;
+                fluidAmount -= result;
+            }
+            if( neighbours[ EAST ] && neighbours[ EAST ]->getFluidAmount() < fluidAmount - 1 )
+            {
+                int amount = MIN( distribution, ( fluidAmount - neighbours[ EAST ]->getFluidAmount() ) / 2 );
+                int result = neighbours[ EAST ]->addFluid( fluidTypeId, amount, WEST );
+                fluidLeft -= result;
+                fluidAmount -= result;
+            }
+            if( neighbours[ SOUTH ] && neighbours[ SOUTH ]->getFluidAmount() < fluidAmount - 1 )
+            {
+                int amount = MIN( distribution, ( fluidAmount - neighbours[ SOUTH ]->getFluidAmount() ) / 2 );
+                int result = neighbours[ SOUTH ]->addFluid( fluidTypeId, amount, NORTH );
+                fluidLeft -= result;
+                fluidAmount -= result;
+            }
+            if( neighbours[ WEST ] && neighbours[ WEST ]->getFluidAmount() < fluidAmount - 1 )
+            {
+                int amount = MIN( distribution, ( fluidAmount - neighbours[ WEST ]->getFluidAmount() ) / 2 );
+                int result = neighbours[ WEST ]->addFluid( fluidTypeId, amount, EAST );
+                fluidLeft -= result;
+                fluidAmount -= result;
+            }
+            if( fluidAmount == 0 )
+                fluidTypeId = -1;
+        }
+    }
+}
+
+void Block::postTick()
+{
+
+}
+
+int Block::addFluid( int fluidTypeId, int amount, DIRECTION dir )
+{
+    if( this->fluidTypeId != -1 && this->fluidTypeId != fluidTypeId )
+        return 0;
+    this->fluidTypeId = fluidTypeId;
+    int result = MIN( amount, fluidCapacity - fluidAmount );
+    fluidAmount += result;
+    return result;
+}
+
+BlockType *Block::zBlockType() const
+{
+    return zType;
+}
+
+bool Block::isTransparent() const
+{
+    return transparent;
+}
+
+bool Block::isPassable() const
+{
+    return passable;
+}
+
+float Block::getHP() const
+{
+    return hp;
+}
+
+float Block::getMaxHP() const
+{
+    return maxHP;
+}
+
+float Block::getHardness() const
+{
+    return hardness;
+}
+
+ItemType *Block::zEffectiveTool() const
+{
+    return zTool;
+}
+
+float Block::getSpeedModifier() const
+{
+    return speedModifier;
+}
+
+int Block::getFluidCapacity() const
+{
+    return fluidCapacity;
+}
+
+int Block::getFluidAmount() const
+{
+    return fluidAmount;
+}
+
+int Block::getFluidTypeId() const
+{
+    return fluidTypeId;
+}
+
+int Block::getFluidSpeed() const
+{
+    return fluidSpeed;
+}

+ 73 - 0
FactoryCraft/Block.h

@@ -0,0 +1,73 @@
+#pragma once
+
+#include "EventListener.h"
+#include "BlockType.h"
+#include "ReferenceCounter.h"
+#include "EventThrower.h"
+
+#include <Trie.h>
+
+class ItemType;
+class Chunk;
+
+enum DIRECTION
+{
+    NORTH,
+    EAST,
+    SOUTH,
+    WEST,
+    TOP,
+    BOTTOM,
+    DIRECTION_COUNT
+};
+
+class Block : public virtual Framework::ReferenceCounter
+{
+private:
+    BlockType *type;
+
+protected:
+    bool transparent;
+    bool passable;
+    float hp;
+    float maxHP;
+    float hardness;
+    BlockType *zType;
+    ItemType *zTool;
+    float speedModifier;
+    int fluidCapacity;
+    int fluidAmount;
+    int fluidTypeId;
+    int fluidSpeed;
+    Block *neighbours[ DIRECTION_COUNT ];
+
+public:
+    Block( BlockType *zType, ItemType *zTool );
+
+    virtual void tick();
+    virtual void postTick();
+
+    /// <summary>
+    /// adds fluid to the internal storage of this block
+    /// </summary>
+    /// <param name="fluidTypeId">the id of the fluid to add</param>
+    /// <param name="amount">the amount of fluids to add</param>
+    /// <param name="dir">the direction from witch the fluid is added</param>
+    /// <returns>the amount of fluids that were added</returns>
+    int addFluid( int fluidTypeId, int amount, DIRECTION dir );
+
+    BlockType *zBlockType() const;
+    bool isTransparent() const;
+    bool isPassable() const;
+    float getHP() const;
+    float getMaxHP() const;
+    float getHardness() const;
+    ItemType *zEffectiveTool() const;
+    float getSpeedModifier() const;
+    int getFluidCapacity() const;
+    int getFluidAmount() const;
+    int getFluidTypeId() const;
+    int getFluidSpeed() const;
+
+    friend Chunk;
+};

+ 15 - 0
FactoryCraft/BlockDestroyedEvent.h

@@ -0,0 +1,15 @@
+#pragma once
+
+#include "Block.h"
+
+// TODO: add course of destruction
+class BlockDestroyedEvent : public Event
+{
+private:
+    const Block *block;
+
+public:
+    BlockDestroyedEvent( Block *block );
+
+    const Block *getBlock() const;
+};

+ 15 - 0
FactoryCraft/BlockPlacedEvent.h

@@ -0,0 +1,15 @@
+#pragma once
+
+#include "Event.h"
+#include "Block.h"
+
+class BlockPlacedEvent : public Event
+{
+private:
+    Block *block;
+
+public:
+    BlockPlacedEvent( Block *block );
+
+    const Block *getBlock() const;
+};

+ 15 - 0
FactoryCraft/BlockType.cpp

@@ -0,0 +1,15 @@
+#include "BlockType.h"
+
+using namespace Framework;
+
+BlockType::BlockType( int id )
+    : ReferenceCounter(),
+    id( id )
+{
+    StaticRegistry<BlockType>::INSTANCE.registerT( this, id );
+}
+
+int BlockType::getId() const
+{
+    return id;
+}

+ 32 - 0
FactoryCraft/BlockType.h

@@ -0,0 +1,32 @@
+#pragma once
+
+#include <Vec3.h>
+#include <Array.h>
+#include <Writer.h>
+
+#include "StaticRegistry.h"
+
+class Game;
+class Block;
+class Item;
+
+class BlockType : public virtual Framework::ReferenceCounter
+{
+private:
+    const int id;
+
+protected:
+    BlockType( int id );
+
+    virtual void loadSuperBlock( Block *zBlock, Framework::Reader *zReader ) = 0;
+    virtual void createSuperBlock( Block *zBlock, Framework::Reader *zReader ) = 0;
+    virtual void createSuperItem( Block *zBlock, Item *zItem ) = 0;
+
+public:
+    virtual Block *loadBlock( Framework::Vec3<int> position, Game *zTarget, Framework::Reader *zReader ) = 0;
+    virtual void saveBlock( Block *zBlock, Framework::Writer *zWriter ) = 0;
+    virtual Item *getItemFromBlock( Block *zBlock, Game *zTarget ) = 0;
+    virtual Block *createBlockAt( Framework::Vec3<int> position, Game *zTarget, Item *zUsedItem ) = 0;
+
+    int getId() const;
+};

+ 26 - 0
FactoryCraft/Chunk.h

@@ -0,0 +1,26 @@
+#pragma once
+
+#include "Block.h"
+#include "DefaultEventListener.h"
+
+#include <Vec3.h>
+#include <Array.h>
+#include <Datei.h>
+#include <Punkt.h>
+
+class Chunk : public EventThrower
+{
+private:
+    Block **blocks;
+    Framework::Punkt location;
+    Framework::RCArray<Event> events;
+    Chunk *neighbours[ 4 ];
+
+public:
+    Chunk( Framework::Punkt location );
+    Block *getBlockAt( Framework::Vec3<int> location );
+    void putBlockAt( Framework::Vec3<int> location, Block *block );
+    void setNeighbor( Chunk *zChunk );
+    virtual void tick();
+    virtual void postTick();
+};

+ 9 - 0
FactoryCraft/Constants.h

@@ -0,0 +1,9 @@
+#pragma once
+
+// needs to be an even number
+#define CHUNK_SIZE 16
+#define WORLD_HEIGHT 500
+#define BIOM_GENERATION_Z_OFFSET 100
+#define AIR_LEVEL_Z_OFFSET 99
+#define MIN_AIR_LEVEL 100
+#define MAX_AIR_LEVEL 400

+ 212 - 0
FactoryCraft/Datenbank.cpp

@@ -0,0 +1,212 @@
+#include "Datenbank.h"
+#include <iostream>
+
+// Inhalt der LSDatenbank Klasse aus Datenbank.h
+// Konstruktor
+LSDatenbank::LSDatenbank( InitDatei *zIni )
+    : ReferenceCounter()
+{
+    datenbank = new Datenbank( zIni->zWert( "DBBenutzer" )->getText(), zIni->zWert( "DBPasswort" )->getText(),
+                               zIni->zWert( "DBName" )->getText(), zIni->zWert( "DBIP" )->getText(),
+                               (unsigned short)TextZuInt( zIni->zWert( "DBPort" )->getText(), 10 ) );
+    if( !datenbank->istOk() )
+    {
+        std::cout << "LS: Die Verbindung zur Datenbank konnte nicht hergestellt werden.\nDas Programm wird beendet.";
+        exit( 1 );
+    }
+    InitializeCriticalSection( &cs );
+    Text befehl = "SELECT port, admin_port  FROM server WHERE id = ";
+    befehl += zIni->zWert( "ServerId" )->getText();
+    lock();
+    datenbank->befehl( befehl );
+    Result res = datenbank->getResult();
+    unlock();
+    if( res.zeilenAnzahl == 1 )
+    {
+        zIni->addWert( "ServerPort", res.values[ 0 ] );
+        zIni->addWert( "AdminServerPort", res.values[ 1 ] );
+    }
+    res.destroy();
+}
+
+// Destruktor
+LSDatenbank::~LSDatenbank()
+{
+    datenbank->release();
+    DeleteCriticalSection( &cs );
+}
+
+// nicht constant
+void LSDatenbank::lock()
+{
+    EnterCriticalSection( &cs );
+}
+
+void LSDatenbank::unlock()
+{
+    LeaveCriticalSection( &cs );
+}
+
+int LSDatenbank::istAdministrator( const char *name, const char *passwort )
+{
+    Text *befehl = new Text( "SELECT id FROM benutzer WHERE name = '" );
+    Text n( name );
+    n.ersetzen( "'", "''" );
+    befehl->append( (char *)n );
+    befehl->append( "' AND passwort = md5( '" );
+    Text p( passwort );
+    p.ersetzen( "'", "''" );
+    befehl->append( (char *)p );
+    befehl->append( "' )" );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    int ret = 0;
+    if( res.zeilenAnzahl > 0 )
+        ret = TextZuInt( res.values[ 0 ].getText(), 10 );
+    res.destroy();
+    return ret;
+}
+
+bool LSDatenbank::adminHatRecht( int id, int recht )
+{
+    Text *befehl = new Text( "SELECT * FROM benutzer_rechte WHERE benutzer_id = " );
+    befehl->append( id );
+    befehl->append( " AND rechte_id = " );
+    befehl->append( recht );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    int ret = datenbank->getZeilenAnzahl();
+    unlock();
+    befehl->release();
+    return ret != 0;
+}
+
+bool LSDatenbank::proveKlient( int num, int sNum )
+{
+    Text *befehl = new Text( "SELECT * FROM server_client WHERE server_id = " );
+    befehl->append( sNum );
+    befehl->append( " AND client_id = " );
+    befehl->append( num );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    bool ret = 0;
+    if( res.zeilenAnzahl == 1 )
+        ret = 1;
+    res.destroy();
+    return ret;
+}
+
+Text *LSDatenbank::getKlientKey( int cId )
+{
+    lock();
+    if( !datenbank->befehl( Text( "SELECT schluessel FROM client WHERE id = " ) += cId ) )
+    {
+        unlock();
+        return 0;
+    }
+    Result res = datenbank->getResult();
+    unlock();
+    if( !res.zeilenAnzahl )
+    {
+        res.destroy();
+        return 0;
+    }
+    Text *ret = new Text( res.values[ 0 ].getText() );
+    res.destroy();
+    return ret;
+}
+
+void LSDatenbank::unregisterKlient( int num, int sNum )
+{
+    Text *befehl = new Text( "DELETE FROM server_client WHERE client_id = " );
+    befehl->append( num );
+    befehl->append( " AND server_id = " );
+    befehl->append( sNum );
+    lock();
+    datenbank->befehl( befehl->getText() );
+    int za = datenbank->getZeilenAnzahl();
+    unlock();
+    if( za == 1 )
+    {
+        befehl->setText( "UPDATE server SET tasks = tasks - 1 WHERE id = " );
+        befehl->append( sNum );
+        lock();
+        datenbank->befehl( befehl->getText() );
+        unlock();
+    }
+    befehl->release();
+}
+
+bool LSDatenbank::setServerStatus( int id, int status )
+{
+    Text *befehl = new Text( "UPDATE server SET server_status_id = " );
+    *befehl += status;
+    *befehl += "WHERE id = ";
+    *befehl += id;
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    bool ret = datenbank->getZeilenAnzahl() != 0;
+    unlock();
+    befehl->release();
+    return ret;
+}
+
+bool LSDatenbank::setMaxClients( int id, int maxC )
+{
+    Text *befehl = new Text( "UPDATE server SET max_tasks = " );
+    befehl->append( maxC );
+    befehl->append( " WHERE id = " );
+    befehl->append( id );
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    bool ret = datenbank->getZeilenAnzahl() > 0;
+    unlock();
+    befehl->release();
+    return ret;
+}
+
+bool LSDatenbank::serverIstNichtPausiert( int id )
+{
+    Text *befehl = new Text( "SELECT server_status_id FROM server WHERE id = " );
+    befehl->append( id );
+    lock();
+    if( !datenbank->befehl( befehl->getText() ) )
+    {
+        unlock();
+        befehl->release();
+        return 0;
+    }
+    Result res = datenbank->getResult();
+    unlock();
+    befehl->release();
+    if( !res.zeilenAnzahl )
+    {
+        res.destroy();
+        return 0;
+    }
+    bool ret = (int)res.values[ 0 ] == 3;
+    res.destroy();
+    return ret;
+}
+
+// constant
+Text *LSDatenbank::getLetzterFehler() const
+{
+    return datenbank->getLetzterFehler();
+}

+ 42 - 0
FactoryCraft/Datenbank.h

@@ -0,0 +1,42 @@
+#pragma once
+
+#include <sql.h>
+#include <Text.h>
+#include <InitDatei.h>
+
+using namespace Framework;
+using namespace sql;
+
+namespace Admin_Recht
+{
+    const int LSStarten = 12;
+    const int LSBeenden = 13;
+    const int LSPausieren = 14;
+    const int LSMCChange = 15;
+}
+
+class LSDatenbank : public virtual Framework::ReferenceCounter
+{
+private:
+    Datenbank *datenbank;
+    CRITICAL_SECTION cs;
+
+public:
+    // Konstruktor
+    LSDatenbank( InitDatei *zIni );
+    // Destruktor
+    ~LSDatenbank();
+    // nicht constant
+    void lock();
+    void unlock();
+    int istAdministrator( const char *name, const char *passwort );
+    bool adminHatRecht( int id, int recht );
+    bool proveKlient( int num, int sNum );
+    Text *getKlientKey( int cId );
+    void unregisterKlient( int num, int sNum );
+    bool setServerStatus( int id, int status );
+    bool setMaxClients( int id, int maxC );
+    bool serverIstNichtPausiert( int id );
+    // constant
+    Text *getLetzterFehler() const;
+};

+ 10 - 0
FactoryCraft/DefaultEventListener.h

@@ -0,0 +1,10 @@
+#pragma once
+
+#include "AbstractEventListener.h"
+
+class DefaultEventListener : public AbstractEventListener
+{
+protected:
+    virtual void onBlockDestroyed( const BlockDestroyedEvent &event ) override;
+    virtual void onLocationChanged( const LocationChangedEvent &event ) override;
+};

+ 15 - 0
FactoryCraft/Dimension.h

@@ -0,0 +1,15 @@
+#pragma once
+
+#include "Chunk.h"
+
+class Dimension : public virtual Framework::ReferenceCounter
+{
+private:
+    int dimensionId;
+    Framework::Trie<Chunk> *chunks;
+
+public:
+    Dimension( int id );
+
+
+};

+ 84 - 0
FactoryCraft/DimensionGenerator.cpp

@@ -0,0 +1,84 @@
+#include "DimensionGenerator.h"
+#include "Constants.h"
+#include "Noise.h"
+
+
+DimensionGenerator::DimensionGenerator( BiomInterpolator *interpolator, int dimensionId )
+    : ReferenceCounter(),
+    interpolator( interpolator ),
+    dimensionId( dimensionId )
+{
+    StaticRegistry<DimensionGenerator>::INSTANCE.registerT( this, dimensionId );
+}
+
+DimensionGenerator::~DimensionGenerator()
+{
+    interpolator->release();
+}
+
+void DimensionGenerator::findBiom( int x, int y, Noise *zNoise, BiomGenerator **firstChoice, BiomGenerator **secondChoice, double &firstChoiceWeight, double &secondChoiceWeight )
+{
+    *firstChoice = biomGenerators.z( 0 );
+    *secondChoice = biomGenerators.z( 0 );
+    firstChoiceWeight = 0;
+    secondChoiceWeight = 0;
+    int z = BIOM_GENERATION_Z_OFFSET;
+    for( Framework::Iterator<BiomGenerator *> it = biomGenerators.getIterator(); it.hasNext(); it.next() )
+    {
+        double noise = zNoise->getNoise( x * it->getBiomXMultiplier(), y * it->getBiomYMultiplier(), z ) * it->getBiomOutputMultiplier();
+        if( noise > firstChoiceWeight )
+        {
+            secondChoiceWeight = firstChoiceWeight;
+            *secondChoice = *firstChoice;
+            firstChoiceWeight = noise;
+            *firstChoice = it;
+        }
+        else if( noise > secondChoiceWeight )
+        {
+            secondChoiceWeight = noise;
+            *secondChoice = it;
+        }
+        z++;
+    }
+}
+
+void DimensionGenerator::registerBiom( BiomGenerator *generator )
+{
+    biomGenerators.add( generator );
+}
+
+Chunk *DimensionGenerator::generateChunk( Noise *zNoise, Game *zGame, int centerX, int centerY )
+{
+    BiomGenerator *actualBiom;
+    BiomGenerator *neighborBiom;
+    double actualWeight;
+    double neighborWeight;
+    Chunk *chunk = new Chunk( Framework::Punkt( centerX, centerY ) );
+    for( int x = -CHUNK_SIZE / 2; x < CHUNK_SIZE / 2; x++ )
+    {
+        for( int y = -CHUNK_SIZE / 2; y < CHUNK_SIZE / 2; y++ )
+        {
+            findBiom( x + centerX, y + centerY, zNoise, &actualBiom, &neighborBiom, actualWeight, neighborWeight );
+            double actualHeight = zNoise->getNoise( ( x + centerX ) * actualBiom->getAirLevelXMultiplier(), ( y + centerY ) * actualBiom->getAirLevelYMultiplier(), AIR_LEVEL_Z_OFFSET ) * actualBiom->getAirLevelOutputMultiplier();
+            double neighborHeight = zNoise->getNoise( ( x + centerX ) * neighborBiom->getAirLevelXMultiplier(), ( y + centerY ) * neighborBiom->getAirLevelYMultiplier(), AIR_LEVEL_Z_OFFSET ) * neighborBiom->getAirLevelOutputMultiplier();
+            int height = MIN_AIR_LEVEL;
+            if( actualWeight + neighborWeight > 0 )
+                height += (int)( ( ( actualHeight * actualHeight + neighborHeight * neighborWeight ) / ( actualWeight + neighborWeight ) ) * ( MAX_AIR_LEVEL - MIN_AIR_LEVEL ) );
+            for( int z = 0; z < WORLD_HEIGHT; z++ )
+            {
+                if( z < height )
+                {
+                    Block *actualBlock = actualBiom->getBlock( zNoise, x + centerX, y + centerY, z, zGame );
+                    Block *neighborBlock = neighborBiom->getBlock( zNoise, x + centerX, y + centerY, z, zGame );
+                    chunk->putBlockAt( Framework::Vec3<int>( x + centerX, y + centerY, z ), interpolator->interpolateBlocks( actualBlock, neighborBlock, actualHeight, neighborWeight, zNoise ) );
+                }
+            }
+        }
+    }
+    return chunk;
+}
+
+int DimensionGenerator::getDimensionId() const
+{
+    return dimensionId;
+}

+ 27 - 0
FactoryCraft/DimensionGenerator.h

@@ -0,0 +1,27 @@
+#pragma once
+
+#include <Array.h>
+#include <ReferenceCounter.h>
+
+#include "BiomGenerator.h"
+#include "BiomInterpolator.h"
+#include "Chunk.h"
+
+class DimensionGenerator : public virtual Framework::ReferenceCounter
+{
+private:
+    BiomInterpolator *interpolator;
+    Framework::RCArray<BiomGenerator> biomGenerators;
+    const int dimensionId;
+
+    void findBiom( int x, int y, Noise *zNoise, BiomGenerator **firstChoice, BiomGenerator **secondChoice, double &firstChoiceWeight, double &secondChoiceWeight );
+
+protected:
+    DimensionGenerator( BiomInterpolator *interpolator, int dimensionId );
+    ~DimensionGenerator();
+    void registerBiom( BiomGenerator *generator );
+
+public:
+    Chunk *generateChunk( Noise *zNoise, Game *zGame, int centerX, int centerY );
+    int getDimensionId() const;
+};

+ 25 - 0
FactoryCraft/Effect.h

@@ -0,0 +1,25 @@
+#pragma once
+
+#include <Text.h>
+
+class Entity;
+class EffectFactory;
+
+class Effect : public virtual Framework::ReferenceCounter
+{
+private:
+    Framework::Text name;
+    float duration;
+
+    Effect( Entity *zTarget );
+
+public:
+    ~Effect();
+
+    virtual void tick();
+
+    Framework::Text getName() const;
+    float getDuration() const;
+
+    friend EffectFactory;
+};

+ 14 - 0
FactoryCraft/EffectFactory.h

@@ -0,0 +1,14 @@
+#pragma once
+
+#include "Effect.h"
+
+class EffectFactory : public virtual Framework::ReferenceCounter
+{
+private:
+    Framework::Text effectName;
+
+public:
+    EffectFactory( Framework::Text effectName );
+
+    virtual Effect *createEffectOn( Entity *target ) = 0;
+};

+ 16 - 0
FactoryCraft/Entity.h

@@ -0,0 +1,16 @@
+#pragma once
+
+#include <ReferenceCounter.h>
+#include <Vec3.h>
+
+#include "Effect.h"
+
+class Entity : public virtual Framework::ReferenceCounter
+{
+private:
+    float maxHP;
+    float currentHP;
+    Framework::Vec3<float> position;
+
+    friend Effect;
+};

+ 15 - 0
FactoryCraft/Event.h

@@ -0,0 +1,15 @@
+#pragma once
+
+#include <Text.h>
+
+
+class Event : public virtual Framework::ReferenceCounter
+{
+private:
+    const Framework::Text name;
+
+public:
+    Event( Framework::Text name );
+
+    const Framework::Text getName() const;
+};

+ 9 - 0
FactoryCraft/EventListener.h

@@ -0,0 +1,9 @@
+#pragma once
+
+#include "Event.h"
+
+class EventListener : public virtual Framework::ReferenceCounter
+{
+public:
+    virtual void process( Event *event ) = 0;
+};

+ 22 - 0
FactoryCraft/EventThrower.h

@@ -0,0 +1,22 @@
+#pragma once
+
+#include "EventListener.h"
+
+#include <Trie.h>
+
+class EventThrower : public virtual Framework::ReferenceCounter
+{
+private:
+    Framework::Trie<EventListener> *listeners;
+
+protected:
+    void throwEvent( Event *event );
+
+public:
+    EventThrower();
+    ~EventThrower();
+
+    void registerEventListener( Framework::Text eventName, EventListener *listener );
+    void removeEventListener( Framework::Text eventName, EventListener *listener );
+    void removeEventListener( EventListener *listener );
+};

+ 171 - 0
FactoryCraft/FactoryCraft.vcxproj

@@ -0,0 +1,171 @@
+<?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|ARM64">
+      <Configuration>Debug</Configuration>
+      <Platform>ARM64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|ARM64">
+      <Configuration>Release</Configuration>
+      <Platform>ARM64</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>{a1b59831-7e37-4f83-a545-0e27609e8295}</ProjectGuid>
+    <Keyword>Linux</Keyword>
+    <RootNamespace>FactoryCraft</RootNamespace>
+    <MinimumVisualStudioVersion>15.0</MinimumVisualStudioVersion>
+    <ApplicationType>Linux</ApplicationType>
+    <ApplicationTypeRevision>1.0</ApplicationTypeRevision>
+    <TargetLinuxPlatform>Generic</TargetLinuxPlatform>
+    <LinuxProjectType>{2238F9CD-F817-4ECC-BD14-2524D2669B35}</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>
+    <RemoteRootDir>/home/kolja/projects</RemoteRootDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <RemoteRootDir>/home/kolja/projects</RemoteRootDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
+    <UseDebugLibraries>false</UseDebugLibraries>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
+    <UseDebugLibraries>true</UseDebugLibraries>
+  </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'">
+    <OutDir>$(RemoteRootDir)/Server/$(ProjectName)/debug/</OutDir>
+    <IntDir>$(RemoteRootDir)/Server/$(ProjectName)/debug/</IntDir>
+    <RemoteProjectDir>$(RemoteRootDir)/Server/$(ProjectName)/debug</RemoteProjectDir>
+    <IncludePath>..\..\..\..\Allgemein\Framework;../../../Framework/debug;..\..\..\..\Allgemein\Network\Network;../../../Network/debug/Network;..\..\..\..\Allgemein\sql\sql;../../../sql/debug/sql;../../../KsgScript/debug/KsgScript;..\..\..\..\Allgemein\KSGScript\KSGScript\Include;$(IncludePath)</IncludePath>
+    <RemoteTargetPath>$(RemoteProjectDir)/$(TargetName)$(TargetExt)</RemoteTargetPath>
+    <RemoteLinkLocalCopyOutput>false</RemoteLinkLocalCopyOutput>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>$(RemoteRootDir)/Server/$(ProjectName)/release/</OutDir>
+    <IntDir>$(RemoteRootDir)/Server/$(ProjectName)/release/</IntDir>
+    <RemoteProjectDir>$(RemoteRootDir)/Server/$(ProjectName)/release</RemoteProjectDir>
+    <IncludePath>..\..\..\..\Allgemein\Framework;../../../Framework/release;..\..\..\..\Allgemein\Network\Network;../../../Network/release/Network;..\..\..\..\Allgemein\sql\sql;../../../sql/release/sql;../../../KsgScript/release/KsgScript;..\..\..\..\Allgemein\KSGScript\KSGScript\Include;$(IncludePath)</IncludePath>
+    <RemoteTargetPath>$(RemoteProjectDir)/$(TargetName)$(TargetExt)</RemoteTargetPath>
+  </PropertyGroup>
+  <ItemGroup>
+    <ClInclude Include="AbstractEventListener.h" />
+    <ClInclude Include="BasicBlocks.h" />
+    <ClInclude Include="BasicInterpolator.h" />
+    <ClInclude Include="BiomGenerator.h" />
+    <ClInclude Include="BiomInterpolator.h" />
+    <ClInclude Include="Block.h" />
+    <ClInclude Include="BlockDestroyedEvent.h" />
+    <ClInclude Include="BlockPlacedEvent.h" />
+    <ClInclude Include="BlockType.h" />
+    <ClInclude Include="Chunk.h" />
+    <ClInclude Include="Constants.h" />
+    <ClInclude Include="Datenbank.h" />
+    <ClInclude Include="DimensionGenerator.h" />
+    <ClInclude Include="Effect.h" />
+    <ClInclude Include="EffectFactory.h" />
+    <ClInclude Include="Entity.h" />
+    <ClInclude Include="Event.h" />
+    <ClInclude Include="EventListener.h" />
+    <ClInclude Include="DefaultEventListener.h" />
+    <ClInclude Include="EventThrower.h" />
+    <ClInclude Include="Game.h" />
+    <ClInclude Include="GrasslandBiom.h" />
+    <ClInclude Include="Inventory.h" />
+    <ClInclude Include="Item.h" />
+    <ClInclude Include="ItemSkill.h" />
+    <ClInclude Include="ItemSlot.h" />
+    <ClInclude Include="ItemStack.h" />
+    <ClInclude Include="ItemType.h" />
+    <ClInclude Include="LocationChangedEvent.h" />
+    <ClInclude Include="Noise.h" />
+    <ClInclude Include="OverworldDimension.h" />
+    <ClInclude Include="PerlinNoise.h" />
+    <ClInclude Include="Player.h" />
+    <ClInclude Include="Server.h" />
+    <ClInclude Include="Dimension.h" />
+    <ClInclude Include="StaticRegistry.h" />
+    <ClInclude Include="WorldGenerator.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="BasicBlock.cpp" />
+    <ClCompile Include="BasicInterpolator.cpp" />
+    <ClCompile Include="BiomGenerator.cpp" />
+    <ClCompile Include="Block.cpp" />
+    <ClCompile Include="BlockType.cpp" />
+    <ClCompile Include="Datenbank.cpp" />
+    <ClCompile Include="DimensionGenerator.cpp" />
+    <ClCompile Include="GrasslandBiom.cpp" />
+    <ClCompile Include="ItemType.cpp" />
+    <ClCompile Include="Noise.cpp" />
+    <ClCompile Include="OverworldDimension.cpp" />
+    <ClCompile Include="PerlinNoise.cpp" />
+    <ClCompile Include="Server.cpp" />
+    <ClCompile Include="Start.cpp" />
+    <ClCompile Include="StaticInitializerOrder.cpp" />
+    <ClCompile Include="WorldGenerator.cpp" />
+  </ItemGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Link>
+      <AdditionalLibraryDirectories>$(RemoteRootDir)/sql/debug;$(RemoteRootDir)/Network/debug;$(RemoteRootDir)/Framework/debug;/usr/lib/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <LibraryDependencies>dbgFramework;dbgNetwork;dbgSQL;pq;pthread;ssl</LibraryDependencies>
+      <AdditionalOptions>-Wl,-rpath,../lib %(AdditionalOptions)</AdditionalOptions>
+      <OutputFile>$(RemoteProjectDir)/$(TargetName)$(TargetExt)</OutputFile>
+    </Link>
+    <ClCompile>
+      <CppLanguageStandard>c++11</CppLanguageStandard>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Link>
+      <AdditionalLibraryDirectories>$(RemoteRootDir)/sql/release;$(RemoteRootDir)/Network/release;$(RemoteRootDir)/Framework/release;/usr/lib/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <LibraryDependencies>Framework;Network;SQL;pq;pthread;ssl</LibraryDependencies>
+      <AdditionalOptions>-Wl,-rpath,../lib %(AdditionalOptions)</AdditionalOptions>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets" />
+</Project>

+ 216 - 0
FactoryCraft/FactoryCraft.vcxproj.filters

@@ -0,0 +1,216 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Headerdateien">
+      <UniqueIdentifier>{e46426ac-18aa-4bc5-a08b-5243ab201396}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Quelldateien">
+      <UniqueIdentifier>{479ff7ea-4fb5-4721-88d5-6f98e4e2ea07}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="events">
+      <UniqueIdentifier>{f323a7f5-5758-46c2-b0fd-6cebe18074f1}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="listeners">
+      <UniqueIdentifier>{36254dc9-eb64-40ed-a14a-dcbfaea372a7}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="world">
+      <UniqueIdentifier>{75490044-5425-4526-abd2-44130408d418}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="game">
+      <UniqueIdentifier>{26d8996d-452d-4c1f-b52b-82310b4ee42f}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="items">
+      <UniqueIdentifier>{4d2e1a89-01ec-4f99-8aed-62d2e9707db9}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="effects">
+      <UniqueIdentifier>{d758dbfd-2172-4c68-bc59-b39c289c28df}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="entities">
+      <UniqueIdentifier>{56ad694e-70aa-4ef4-b698-7ff7755b3e60}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="world\blocks">
+      <UniqueIdentifier>{43e43bc7-14fe-4897-9ec3-746bb2c14489}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="static">
+      <UniqueIdentifier>{ae61cabe-b357-4f84-82c7-79379f6cbf4a}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="world\generator">
+      <UniqueIdentifier>{b84787f0-e7e4-4981-b256-153b0e86120d}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="world\generator\noise">
+      <UniqueIdentifier>{6a594ea1-a32c-4e11-9f2c-d694f42e9076}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="world\generator\bioms">
+      <UniqueIdentifier>{a69078f1-3e20-4b14-943e-9d02c4df470d}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="world\generator\dimensions">
+      <UniqueIdentifier>{b04d9ff5-ad58-41e2-8e72-8de835e09c99}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="world\generator\interpolators">
+      <UniqueIdentifier>{0a55e1c5-132f-4a40-bbfe-9bc9f100e4fa}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="Datenbank.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="Server.h">
+      <Filter>Headerdateien</Filter>
+    </ClInclude>
+    <ClInclude Include="Event.h">
+      <Filter>events</Filter>
+    </ClInclude>
+    <ClInclude Include="LocationChangedEvent.h">
+      <Filter>events</Filter>
+    </ClInclude>
+    <ClInclude Include="BlockDestroyedEvent.h">
+      <Filter>events</Filter>
+    </ClInclude>
+    <ClInclude Include="EventListener.h">
+      <Filter>listeners</Filter>
+    </ClInclude>
+    <ClInclude Include="DefaultEventListener.h">
+      <Filter>listeners</Filter>
+    </ClInclude>
+    <ClInclude Include="AbstractEventListener.h">
+      <Filter>listeners</Filter>
+    </ClInclude>
+    <ClInclude Include="Chunk.h">
+      <Filter>world</Filter>
+    </ClInclude>
+    <ClInclude Include="Block.h">
+      <Filter>world</Filter>
+    </ClInclude>
+    <ClInclude Include="BlockPlacedEvent.h">
+      <Filter>events</Filter>
+    </ClInclude>
+    <ClInclude Include="BlockType.h">
+      <Filter>world</Filter>
+    </ClInclude>
+    <ClInclude Include="Dimension.h">
+      <Filter>world</Filter>
+    </ClInclude>
+    <ClInclude Include="Game.h">
+      <Filter>game</Filter>
+    </ClInclude>
+    <ClInclude Include="Player.h">
+      <Filter>entities</Filter>
+    </ClInclude>
+    <ClInclude Include="Item.h">
+      <Filter>items</Filter>
+    </ClInclude>
+    <ClInclude Include="ItemStack.h">
+      <Filter>items</Filter>
+    </ClInclude>
+    <ClInclude Include="Inventory.h">
+      <Filter>items</Filter>
+    </ClInclude>
+    <ClInclude Include="ItemType.h">
+      <Filter>items</Filter>
+    </ClInclude>
+    <ClInclude Include="ItemSlot.h">
+      <Filter>items</Filter>
+    </ClInclude>
+    <ClInclude Include="EventThrower.h">
+      <Filter>events</Filter>
+    </ClInclude>
+    <ClInclude Include="Effect.h">
+      <Filter>effects</Filter>
+    </ClInclude>
+    <ClInclude Include="EffectFactory.h">
+      <Filter>effects</Filter>
+    </ClInclude>
+    <ClInclude Include="ItemSkill.h">
+      <Filter>items</Filter>
+    </ClInclude>
+    <ClInclude Include="Entity.h">
+      <Filter>entities</Filter>
+    </ClInclude>
+    <ClInclude Include="BasicBlocks.h">
+      <Filter>world\blocks</Filter>
+    </ClInclude>
+    <ClInclude Include="StaticRegistry.h">
+      <Filter>static</Filter>
+    </ClInclude>
+    <ClInclude Include="Noise.h">
+      <Filter>world\generator\noise</Filter>
+    </ClInclude>
+    <ClInclude Include="PerlinNoise.h">
+      <Filter>world\generator\noise</Filter>
+    </ClInclude>
+    <ClInclude Include="WorldGenerator.h">
+      <Filter>world\generator</Filter>
+    </ClInclude>
+    <ClInclude Include="BiomGenerator.h">
+      <Filter>world\generator</Filter>
+    </ClInclude>
+    <ClInclude Include="BiomInterpolator.h">
+      <Filter>world\generator</Filter>
+    </ClInclude>
+    <ClInclude Include="DimensionGenerator.h">
+      <Filter>world\generator</Filter>
+    </ClInclude>
+    <ClInclude Include="GrasslandBiom.h">
+      <Filter>world\generator\bioms</Filter>
+    </ClInclude>
+    <ClInclude Include="OverworldDimension.h">
+      <Filter>world\generator\dimensions</Filter>
+    </ClInclude>
+    <ClInclude Include="BasicInterpolator.h">
+      <Filter>world\generator\interpolators</Filter>
+    </ClInclude>
+    <ClInclude Include="Constants.h">
+      <Filter>game</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="Server.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="Datenbank.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="BlockType.cpp">
+      <Filter>world</Filter>
+    </ClCompile>
+    <ClCompile Include="Block.cpp">
+      <Filter>world</Filter>
+    </ClCompile>
+    <ClCompile Include="BasicBlock.cpp">
+      <Filter>world\blocks</Filter>
+    </ClCompile>
+    <ClCompile Include="Start.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
+    <ClCompile Include="StaticInitializerOrder.cpp">
+      <Filter>static</Filter>
+    </ClCompile>
+    <ClCompile Include="ItemType.cpp">
+      <Filter>items</Filter>
+    </ClCompile>
+    <ClCompile Include="PerlinNoise.cpp">
+      <Filter>world\generator\noise</Filter>
+    </ClCompile>
+    <ClCompile Include="Noise.cpp">
+      <Filter>world\generator\noise</Filter>
+    </ClCompile>
+    <ClCompile Include="DimensionGenerator.cpp">
+      <Filter>world\generator</Filter>
+    </ClCompile>
+    <ClCompile Include="WorldGenerator.cpp">
+      <Filter>world\generator</Filter>
+    </ClCompile>
+    <ClCompile Include="OverworldDimension.cpp">
+      <Filter>world\generator\dimensions</Filter>
+    </ClCompile>
+    <ClCompile Include="GrasslandBiom.cpp">
+      <Filter>world\generator\bioms</Filter>
+    </ClCompile>
+    <ClCompile Include="BasicInterpolator.cpp">
+      <Filter>world\generator\interpolators</Filter>
+    </ClCompile>
+    <ClCompile Include="BiomGenerator.cpp">
+      <Filter>world\generator</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>

+ 24 - 0
FactoryCraft/Game.h

@@ -0,0 +1,24 @@
+#pragma once
+
+#include <Text.h>
+#include <Punkt.h>
+
+#include "Dimension.h"
+#include "Player.h"
+#include "WorldGenerator.h"
+#include "Constants.h"
+
+class Game : public virtual Framework::ReferenceCounter
+{
+private:
+    Framework::Text name;
+    Framework::RCArray<Dimension> *dimension;
+    Framework::RCArray<Entity> *entities;
+    WorldGenerator *generator;
+    __int64 tickId;
+
+public:
+
+    void addChunck( Chunk *chunk, int dimensionId );
+    Framework::Punkt getChunkCenter( int x, int y );
+};

+ 22 - 0
FactoryCraft/GrasslandBiom.cpp

@@ -0,0 +1,22 @@
+#include "GrasslandBiom.h"
+#include "BlockType.h"
+
+GrasslandBiom::GrasslandBiom()
+    : GrasslandBiom( 1, 1, 1, 1, 1, 1 )
+{}
+
+GrasslandBiom::GrasslandBiom( double biomXMultiplier, double biomYMultiplier, double biomOutputMultiplier, double airXMultiplier, double airYMultiplier, double airOutputMultiplier )
+    : BiomGenerator()
+{
+    this->biomXMultiplier = biomXMultiplier;
+    this->biomYMultiplier = biomYMultiplier;
+    this->biomOutputMultiplier = biomOutputMultiplier;
+    this->airXMultiplier = airXMultiplier;
+    this->airYMultiplier = airYMultiplier;
+    this->airOutputMultiplier = airOutputMultiplier;
+}
+
+Block *GrasslandBiom::getBlock( Noise *zNoise, int x, int y, int z, Game *zGame )
+{
+    StaticRegistry<BlockType>::INSTANCE.zElement( 1 )->createBlockAt( Framework::Vec3<int>( x, y, z ), zGame, 0 );
+}

+ 12 - 0
FactoryCraft/GrasslandBiom.h

@@ -0,0 +1,12 @@
+#pragma once
+
+#include "BiomGenerator.h"
+#include "StaticRegistry.h"
+
+class GrasslandBiom : public BiomGenerator
+{
+public:
+    GrasslandBiom();
+    GrasslandBiom( double biomXMultiplier, double biomYMultiplier, double biomOutputMultiplier, double airXMultiplier, double airYMultiplier, double airOutputMultiplier );
+    Block *getBlock( Noise *zNoise, int x, int y, int z, Game *zGame ) override;
+};

+ 18 - 0
FactoryCraft/Inventory.h

@@ -0,0 +1,18 @@
+#pragma once
+
+#include "ItemSlot.h"
+#include "EventThrower.h"
+#include "ReferenceCounter.h"
+
+class Inventory : public EventThrower
+{
+private:
+    Framework::RCArray<ItemSlot> *slots;
+
+protected:
+    void addSlot( ItemSlot *slot );
+
+public:
+    Inventory();
+    virtual ~Inventory();
+};

+ 46 - 0
FactoryCraft/Item.h

@@ -0,0 +1,46 @@
+#pragma once
+
+#include "ItemType.h"
+#include "Reader.h"
+
+class Item : public virtual Framework::ReferenceCounter
+{
+private:
+    ItemType *zType;
+    float damage;
+    float maxDamage;
+    float durability;
+    float maxDurability;
+    bool eatable;
+    bool placeable;
+    bool equippable;
+    int maxStackSize;
+    Framework::Text name;
+
+private:
+    Item( ItemType *zType, float damage );
+    Item( ItemType *zType );
+    Item( Item *zClone );
+    Item( Framework::StreamReader *zItemInfo );
+
+public:
+    virtual void tick();
+
+    const ItemType *zItemType() const;
+    float getDamage() const;
+    float getDurability() const;
+    bool isEatable() const;
+    bool isPlaceable() const;
+    bool isEquippable() const;
+    float getMaxDurability() const;
+    int getMaxStackSize() const;
+    float getMaxDamage() const;
+
+    virtual void applyInventoryEffects( Entity *zTarget );
+    virtual void removeInventoryEffects( Entity *zTarget );
+    virtual void applyEquippedEffects( Entity *zTarget );
+    virtual void removeEquippedEffects( Entity *zTarget );
+    virtual void applyFoodEffects( Entity *zTarget );
+
+    friend ItemType;
+};

+ 47 - 0
FactoryCraft/ItemSkill.h

@@ -0,0 +1,47 @@
+#pragma once
+
+#include "Reader.h"
+
+#include <JSON.h>
+#include <ReferenceCounter.h>
+
+class ItemType;
+class ItemSkill;
+class Block;
+class Entity;
+class Dimension;
+
+class ItemSkillLevelUpRule : public virtual Framework::ReferenceCounter
+{
+public:
+    virtual void applyOn( ItemSkill *zSkill ) = 0;
+};
+
+class ItemSkill : public virtual Framework::ReferenceCounter
+{
+public:
+    virtual void use( Entity *zActor, Block *zTarget, Dimension *zDimension ) = 0;
+    virtual void use( Entity *zActor, Entity *zTarget, Dimension *zDimension ) = 0;
+};
+
+class BasicItemSkill : public ItemSkill
+{
+protected:
+    int level;
+    float xp;
+    float maxXP;
+    float durabilityModifier;
+    float speedModifier;
+    float luckModifier;
+    float staminaModifier;
+    float hungerModifier;
+
+    BasicItemSkill( float maxXp = 100.f, float durabilityModifier = 1.f, float speedModifier = 1.f, float luckModifier = 1.f, float staminaModifier = 1.f, float hungerModifier = 1.f, float xpIncrease = 1.1f );
+
+
+public:
+    virtual void use( Entity *zActor, Block *zTarget, Dimension *zDimension ) override;
+    virtual void use( Entity *zActor, Entity *zTarget, Dimension *zDimension ) override;
+
+    friend ItemType;
+};

+ 19 - 0
FactoryCraft/ItemSlot.h

@@ -0,0 +1,19 @@
+#pragma once
+
+#include "ItemStack.h"
+
+class ItemSlot : public virtual Framework::ReferenceCounter
+{
+private:
+    ItemStack *items;
+    int maxSize;
+
+public:
+    ItemSlot( int maxSize );
+
+    ItemStack *takeItemsOut( int count );
+    void addItems( ItemStack *stack );
+
+    virtual int numberOfAddableItems( ItemStack *stack ) const;
+    const ItemStack *getContainedItems() const;
+};

+ 20 - 0
FactoryCraft/ItemStack.h

@@ -0,0 +1,20 @@
+#pragma once
+
+#include "Item.h"
+
+class ItemStack : public virtual Framework::ReferenceCounter
+{
+private:
+    Item *item;
+    int size;
+
+public:
+    ItemStack( Item *item, int currentSize );
+
+    ItemStack *split( int size );
+
+    bool isStackable( Item *zItem );
+
+    const Item *zItem() const;
+    int getSize() const;
+};

+ 52 - 0
FactoryCraft/ItemType.cpp

@@ -0,0 +1,52 @@
+
+#include "ItemType.h"
+#include "ItemSkill.h"
+#include "ItemStack.h"
+
+ItemType::ItemType( int id, ItemSkillLevelUpRule *levelUpRule )
+    : ReferenceCounter(),
+    id( id )
+{
+    this->levelUpRule = levelUpRule;
+    StaticRegistry<ItemType>::INSTANCE.registerT( this, id );
+}
+
+ItemType::~ItemType()
+{
+    if( levelUpRule )
+        levelUpRule->release();
+}
+
+void ItemType::loadSupperItem( Item *zItem, Framework::Reader *zReader ) const {}
+void ItemType::saveSupperItem( Item *zItem, Framework::Writer *zWriter ) const {}
+
+int ItemType::getId() const
+{
+    return id;
+}
+
+ItemStack *ItemType::createItemStack( int size ) const
+{
+    Item *item = createItem();
+    if( !item )
+        return 0;
+    return new ItemStack( item, MIN( size, item->getMaxStackSize() ) );
+}
+
+ItemSkill *ItemType::createDefaultItemSkill() const
+{
+    return 0;
+}
+
+void ItemType::levelUpItemSkill( ItemSkill *zSkill ) const
+{
+    if( levelUpRule )
+        levelUpRule->applyOn( zSkill );
+}
+
+Item *ItemType::loadItem( Framework::Reader *zReader ) const
+{
+    return createItem();
+}
+
+void ItemType::saveItem( Item *zItem, Framework::Writer *zWriter ) const {}

+ 38 - 0
FactoryCraft/ItemType.h

@@ -0,0 +1,38 @@
+#pragma once
+
+#include <Text.h>
+#include <JSON.h>
+#include <Trie.h>
+#include <Writer.h>
+
+#include "Effect.h"
+#include "StaticRegistry.h"
+
+class Item;
+class ItemStack;
+class ItemSkill;
+class ItemSkillLevelUpRule;
+
+class ItemType : public virtual Framework::ReferenceCounter
+{
+private:
+    const int id;
+    ItemSkillLevelUpRule *levelUpRule;
+
+protected:
+    ItemType( int id, ItemSkillLevelUpRule *levelUpRule );
+
+    virtual void loadSupperItem( Item *zItem, Framework::Reader *zReader ) const;
+    virtual void saveSupperItem( Item *zItem, Framework::Writer *zWriter ) const;
+
+public:
+    ~ItemType();
+
+    int getId() const;
+    virtual Item *createItem() const = 0;
+    virtual ItemStack *createItemStack( int size ) const;
+    virtual ItemSkill *createDefaultItemSkill() const;
+    virtual void levelUpItemSkill( ItemSkill *zSkill ) const;
+    virtual Item *loadItem( Framework::Reader *zReader ) const;
+    virtual void saveItem( Item *zItem, Framework::Writer *zWriter ) const;
+};

+ 20 - 0
FactoryCraft/LocationChangedEvent.h

@@ -0,0 +1,20 @@
+#pragma once
+
+#include "Event.h"
+#include "Block.h"
+
+#include <Vec3.h>
+
+class LocationChangedEvent : public Event
+{
+private:
+    const Block *block;
+    const Framework::Vec3<int> oldPosition;
+    const Framework::Vec3<int> newPosition;
+
+public:
+    LocationChangedEvent( Block *block, Framework::Vec3<int> oldPosition, Framework::Vec3<int> newPosition );
+
+    Framework::Vec3<int> getOldPosition() const;
+    Framework::Vec3<int> getNewPosition() const;
+};

+ 11 - 0
FactoryCraft/Noise.cpp

@@ -0,0 +1,11 @@
+#include "Noise.h"
+
+
+Noise::Noise()
+    : Framework::ReferenceCounter()
+{}
+
+double Noise::getNoise( Framework::Vec3<double> &pos ) const
+{
+    return getNoise( pos.x, pos.y, pos.z );
+}

+ 20 - 0
FactoryCraft/Noise.h

@@ -0,0 +1,20 @@
+#pragma once
+
+#include <Vec3.h>
+#include <ReferenceCounter.h>
+
+class Noise : public virtual Framework::ReferenceCounter
+{
+public:
+    Noise();
+    virtual int getSeed() const = 0;
+    /// <summary>
+    /// get the noise value at a certain destination
+    /// </summary>
+    /// <param name="x">the x coord of the noice value</param>
+    /// <param name="y">the y coord of the noice value</param>
+    /// <param name="z">the z coord of the noice value</param>
+    /// <returns>the noise value scaled to a range from 0 to 1</returns>
+    virtual double getNoise( double x, double y, double z ) const = 0;
+    double getNoise( Framework::Vec3<double> &pos ) const;
+};

+ 9 - 0
FactoryCraft/OverworldDimension.cpp

@@ -0,0 +1,9 @@
+#include "OverworldDimension.h"
+#include "BasicInterpolator.h"
+#include "GrasslandBiom.h"
+
+OverworldDimension::OverworldDimension()
+    : DimensionGenerator( new BasicInterpolator(), 0 )
+{
+    registerBiom( new GrasslandBiom() );
+}

+ 14 - 0
FactoryCraft/OverworldDimension.h

@@ -0,0 +1,14 @@
+#pragma once
+
+#include "DimensionGenerator.h"
+
+class OverworldDimension : public DimensionGenerator
+{
+    REGISTRABLE( OverworldDimension )
+public:
+    OverworldDimension();
+};
+
+#ifdef REGISTER
+REGISTER( OverworldDimension )
+#endif

+ 71 - 0
FactoryCraft/PerlinNoise.cpp

@@ -0,0 +1,71 @@
+#include "PerlinNoise.h"
+
+#include <random>
+#include <algorithm>
+
+
+PerlinNoise::PerlinNoise( int seed )
+    : Noise()
+{
+    this->seed = seed;
+    p.resize( 256 );
+    std::iota( p.begin(), p.end(), 0 );
+    std::default_random_engine engine( seed );
+    std::shuffle( p.begin(), p.end(), engine );
+    p.insert( p.end(), p.begin(), p.end() );
+}
+
+
+int PerlinNoise::getSeed() const
+{
+    return seed;
+}
+
+double PerlinNoise::getNoise( double x, double y, double z ) const
+{
+    // Find the unit cube that contains the point
+    int X = (int)floor( x ) & 255;
+    int Y = (int)floor( y ) & 255;
+    int Z = (int)floor( z ) & 255;
+
+    // Find relative x, y,z of point in cube
+    x -= floor( x );
+    y -= floor( y );
+    z -= floor( z );
+
+    // Compute fade curves for each of x, y, z
+    double u = fade( x );
+    double v = fade( y );
+    double w = fade( z );
+
+    // Hash coordinates of the 8 cube corners
+    int A = p[ X ] + Y;
+    int AA = p[ A ] + Z;
+    int AB = p[ A + 1 ] + Z;
+    int B = p[ X + 1 ] + Y;
+    int BA = p[ B ] + Z;
+    int BB = p[ B + 1 ] + Z;
+
+    // Add blended results from 8 corners of cube
+    double res = lerp( w, lerp( v, lerp( u, grad( p[ AA ], x, y, z ), grad( p[ BA ], x - 1, y, z ) ), lerp( u, grad( p[ AB ], x, y - 1, z ), grad( p[ BB ], x - 1, y - 1, z ) ) ), lerp( v, lerp( u, grad( p[ AA + 1 ], x, y, z - 1 ), grad( p[ BA + 1 ], x - 1, y, z - 1 ) ), lerp( u, grad( p[ AB + 1 ], x, y - 1, z - 1 ), grad( p[ BB + 1 ], x - 1, y - 1, z - 1 ) ) ) );
+    return ( res + 1.0 ) / 2.0;
+}
+
+double PerlinNoise::fade( double t ) const
+{
+    return t * t * t * ( t * ( t * 6 - 15 ) + 10 );
+}
+
+double PerlinNoise::lerp( double t, double a, double b ) const
+{
+    return a + t * ( b - a );
+}
+
+double PerlinNoise::grad( int hash, double x, double y, double z ) const
+{
+    int h = hash & 15;
+    // Convert lower 4 bits of hash into 12 gradient directions
+    double u = h < 8 ? x : y,
+        v = h < 4 ? y : h == 12 || h == 14 ? x : z;
+    return ( ( h & 1 ) == 0 ? u : -u ) + ( ( h & 2 ) == 0 ? v : -v );
+}

+ 22 - 0
FactoryCraft/PerlinNoise.h

@@ -0,0 +1,22 @@
+#pragma once
+
+#include "Noise.h"
+#include <vector>
+
+class PerlinNoise : public Noise
+{
+private:
+    std::vector<int> p;
+    int seed;
+
+public:
+    PerlinNoise( int seed );
+
+    int getSeed() const override;
+    double getNoise( double x, double y, double z ) const override;
+
+private:
+    inline double fade( double t ) const;
+    inline double lerp( double t, double a, double b ) const;
+    inline double grad( int hash, double x, double y, double z ) const;
+};

+ 12 - 0
FactoryCraft/Player.h

@@ -0,0 +1,12 @@
+#pragma once
+
+#include "Entity.h"
+
+class Player : public Entity
+{
+private:
+
+
+public:
+
+};

+ 728 - 0
FactoryCraft/Server.cpp

@@ -0,0 +1,728 @@
+#include "Server.h"
+#include <iostream>
+#include <Klient.h>
+#include <Globals.h>
+
+// Inhalt der LoginServer Klasse aus LoginServer.h
+// Konstruktor 
+FactoryCraftServer::FactoryCraftServer( InitDatei *zIni )
+    : Thread()
+{
+    Network::Start( 100 );
+    std::cout << "FC: Verbindung mit Datenbank wird hergestellt...\n";
+    db = new LSDatenbank( zIni );
+    klientAnzahl = 0;
+    klients = new RCArray< FCKlient >();
+    empfangen = 0;
+    gesendet = 0;
+    fehler = new Text();
+    ini = dynamic_cast<InitDatei *>( zIni->getThis() );
+    id = *zIni->zWert( "ServerId" );
+    server = new Server();
+    aServer = new SSLServer();
+    aServer->setPrivateKeyPassword( zIni->zWert( "SSLPasswort" )->getText() );
+    aServer->setCertificateFile( zIni->zWert( "SSLCert" )->getText() );
+    aServer->setPrivateKeyFile( zIni->zWert( "SSLKey" )->getText() );
+    std::cout << "FC: Starten des Admin Servers...\n";
+    if( !aServer->verbinde( (unsigned short)TextZuInt( ini->zWert( "AdminServerPort" )->getText(), 10 ), 10 ) )
+    {
+        std::cout << "FC: Der Admin Server konnte nicht gestartet werden. Das Programm wird beendet.\n";
+        exit( 1 );
+    }
+    db->setServerStatus( id, 2 );
+    end = 0;
+    nichtPausiert = 0;
+    InitializeCriticalSection( &cs );
+    if( zIni->zWert( "Aktiv" )->istGleich( "TRUE" ) )
+    {
+        serverStarten();
+        serverFortsetzen();
+    }
+}
+
+// Destruktor 
+FactoryCraftServer::~FactoryCraftServer()
+{
+    fehler->release();
+    server->trenne();
+    server->release();
+    aServer->trenne();
+    aServer->release();
+    if( klients )
+        klients->release();
+    ini->release();
+    db->release();
+    DeleteCriticalSection( &cs );
+}
+
+// nicht constant 
+void FactoryCraftServer::runn()
+{
+    while( !end && aServer->isConnected() )
+    {
+        SSLSKlient *klient;
+        klient = aServer->getKlient();
+        if( end && klient )
+        {
+            klient->trenne();
+            klient = (SSLSKlient *)klient->release();
+            Sleep( 1000 );
+            return;
+        }
+        if( !klient )
+            continue;
+        FCAKlient *clHandle = new FCAKlient( klient, dynamic_cast<FactoryCraftServer *>( getThis() ) );
+        clHandle->start();
+    }
+}
+
+void FactoryCraftServer::thread()
+{
+    while( server->isConnected() )
+    {
+        SKlient *klient;
+        klient = server->getKlient();
+        if( !klient )
+            continue;
+        Framework::getThreadRegister()->cleanUpClosedThreads();
+        FCKlient *clHandle = new FCKlient( klient, dynamic_cast<FactoryCraftServer *>( getThis() ) );
+        EnterCriticalSection( &cs );
+        klients->set( clHandle, klientAnzahl );
+        klientAnzahl++;
+        LeaveCriticalSection( &cs );
+        clHandle->start();
+    }
+}
+
+void FactoryCraftServer::close()
+{
+    db->setServerStatus( id, 1 );
+    server->trenne();
+#ifdef WIN32
+    warteAufThread( 1000 );
+#endif
+    EnterCriticalSection( &cs );
+    for( int i = 0; i < klientAnzahl; i++ )
+        klients->z( i )->absturz();
+    klients = ( RCArray< FCKlient > * )klients->release();
+    klientAnzahl = 0;
+    LeaveCriticalSection( &cs );
+    ende();
+    run = 0;
+    end = 1;
+    Klient *klient = new Klient();
+    klient->verbinde( aServer->getPort(), "127.0.0.1" );
+    Sleep( 500 );
+    aServer->trenne();
+    klient->release();
+}
+
+bool FactoryCraftServer::serverStarten()
+{
+    if( nichtPausiert )
+    {
+        fehler->setText( "Der Server konnte nicht gestartet werden: Der Server läuft bereits." );
+        return 0;
+    }
+    if( server )
+        server->release();
+    server = new Server();
+    if( server->verbinde( (unsigned short)TextZuInt( ini->zWert( "ServerPort" )->getText(), 10 ), 10 ) )
+    {
+        nichtPausiert = 1;
+        start();
+        return 1;
+    }
+    else
+    {
+        serverBeenden();
+        fehler->setText( "Der Server konnte nicht gestartet werden: Eventuell ist der Port in benutzung." );
+        return 0;
+    }
+}
+
+bool FactoryCraftServer::serverPause()
+{
+    if( !nichtPausiert )
+    {
+        fehler->setText( "Der Server konnte nicht pausiert werden: Der Server läuft nicht." );
+        return 0;
+    }
+    if( !db->setServerStatus( id, 2 ) )
+    {
+        fehler->setText( "Der Server konnte nicht pausiert werden: " );
+        fehler->append( db->getLetzterFehler() );
+        return 0;
+    }
+    return 1;
+}
+
+bool FactoryCraftServer::serverFortsetzen()
+{
+    if( !nichtPausiert )
+    {
+        fehler->setText( "Der Server konnte nicht fortgesetzt werden: Der Server läuft nicht." );
+        return 0;
+    }
+    if( !db->setServerStatus( id, 3 ) )
+    {
+        fehler->setText( "Der Server konnte nicht fortgesetzt werden: " );
+        fehler->append( db->getLetzterFehler() );
+        return 0;
+    }
+    return 1;
+}
+
+bool FactoryCraftServer::serverBeenden()
+{
+    if( !nichtPausiert )
+    {
+        fehler->setText( "Der Server konnte nicht beendet werden: Der Server läuft nicht." );
+        return 0;
+    }
+    if( db->serverIstNichtPausiert( id ) )
+    {
+        fehler->setText( "Der Server konnte nicht beendet werden: Der Server muss erst pausiert werden." );
+        return 0;
+    }
+    nichtPausiert = 0;
+    ende();
+    if( server )
+        server->trenne();
+    return 1;
+}
+
+bool FactoryCraftServer::setMaxKlients( int mc )
+{
+    if( !db->setMaxClients( id, mc ) )
+    {
+        fehler->setText( "Die maximale Anzahl der Clients konnte nicht gesetzt werden:\n" );
+        fehler->append( db->getLetzterFehler() );
+        return 0;
+    }
+    ini->setWert( "MaxClients", Text() += mc );
+    return 1;
+}
+
+bool FactoryCraftServer::absturzKlient( int klientId )
+{
+    bool gefunden = 0;
+    EnterCriticalSection( &cs );
+    for( int i = 0; i < klientAnzahl; i++ )
+    {
+        if( klients->z( i ) && klients->z( i )->getKlientNummer() == klientId )
+        {
+            klients->z( i )->absturz();
+            klients->remove( i );
+            klientAnzahl--;
+            gefunden = 1;
+            break;
+        }
+    }
+    LeaveCriticalSection( &cs );
+    return gefunden;
+}
+
+bool FactoryCraftServer::removeKlient( FCKlient *zKlient )
+{
+    bool gefunden = 0;
+    EnterCriticalSection( &cs );
+    for( int i = 0; i < klientAnzahl; i++ )
+    {
+        if( klients->z( i ) == zKlient )
+        {
+            klients->remove( i );
+            klientAnzahl--;
+            gefunden = 1;
+            break;
+        }
+    }
+    LeaveCriticalSection( &cs );
+    return gefunden;
+}
+
+void FactoryCraftServer::addGesendet( int bytes )
+{
+    gesendet += bytes;
+}
+
+void FactoryCraftServer::addEmpfangen( int bytes )
+{
+    empfangen += bytes;
+}
+
+// constant
+bool FactoryCraftServer::istAn() const
+{
+    return db->serverIstNichtPausiert( id );
+}
+
+Server *FactoryCraftServer::zServer() const
+{
+    return server;
+}
+
+LSDatenbank *FactoryCraftServer::zDB() const
+{
+    return db;
+}
+
+bool FactoryCraftServer::hatClients() const
+{
+    return klientAnzahl > 0;
+}
+
+int FactoryCraftServer::getId() const
+{
+    return id;
+}
+
+char *FactoryCraftServer::getLetzterFehler() const
+{
+    return fehler->getText();
+}
+
+
+// Inhalt der LSAKlient Klasse aus LoginServer.h
+// Konstruktor 
+FCAKlient::FCAKlient( SSLSKlient *klient, FactoryCraftServer *ls )
+    : Thread()
+{
+    this->klient = klient;
+    name = new Text( "" );
+    passwort = new Text( "" );
+    adminId = 0;
+    version = 0;
+    this->ls = ls;
+}
+
+// Destruktor 
+FCAKlient::~FCAKlient()
+{
+    klient->trenne();
+    klient->release();
+    ls->release();
+    name->release();
+    passwort->release();
+}
+
+// nicht constant 
+void FCAKlient::thread()
+{
+    while( 1 )
+    {
+        char c = 0;
+        if( !klient->getNachricht( &c, 1 ) )
+            break;
+        else
+        {
+            bool br = 0;
+            switch( c )
+            {
+            case 1: // Login
+                if( 1 )
+                {
+                    klient->sende( "\1", 1 );
+                    unsigned char nLen = 0;
+                    klient->getNachricht( (char *)&nLen, 1 );
+                    char *n = new char[ nLen + 1 ];
+                    n[ (int)nLen ] = 0;
+                    if( nLen )
+                        klient->getNachricht( n, nLen );
+                    unsigned char pLen = 0;
+                    klient->getNachricht( (char *)&pLen, 1 );
+                    char *p = new char[ pLen + 1 ];
+                    p[ (int)pLen ] = 0;
+                    if( pLen )
+                        klient->getNachricht( p, pLen );
+                    int adminId = ls->zDB()->istAdministrator( n, p );
+                    if( adminId )
+                    {
+                        klient->sende( "\1", 1 );
+                        name->setText( n );
+                        passwort->setText( p );
+                        this->adminId = adminId;
+                    }
+                    else
+                        errorZuKlient( "Falsche Kombination aus Name und Passwort." );
+                    delete[] n;
+                    delete[] p;
+                }
+                break;
+            case 2: // Logout
+                adminId = 0;
+                name->setText( "" );
+                passwort->setText( "" );
+                klient->sende( "\1", 1 );
+                break;
+            case 3: // Trennen
+                br = 1;
+                klient->sende( "\1", 1 );
+                break;
+            case 4: // Server starten
+                if( !adminId )
+                    errorZuKlient( "Du musst dich einloggen." );
+                else
+                {
+                    if( ls->zDB()->adminHatRecht( adminId, Admin_Recht::LSStarten ) )
+                    {
+                        if( !ls->serverStarten() )
+                        {
+                            Text *err = new Text();
+                            err->append( ls->getLetzterFehler() );
+                            errorZuKlient( err->getText() );
+                            err->release();
+                        }
+                        else
+                            klient->sende( "\1", 1 );
+                    }
+                    else
+                        errorZuKlient( "Du bist nicht berechtigt den Server zu starten." );
+                }
+                break;
+            case 5: // Server beenden
+                if( !adminId )
+                    errorZuKlient( "Du musst dich einloggen." );
+                else
+                {
+                    if( ls->zDB()->adminHatRecht( adminId, Admin_Recht::LSBeenden ) )
+                    {
+                        if( ls->serverBeenden() )
+                            klient->sende( "\1", 1 );
+                        else
+                        {
+                            Text *err = new Text();
+                            err->append( ls->getLetzterFehler() );
+                            errorZuKlient( err->getText() );
+                            err->release();
+                        }
+                    }
+                    else
+                        errorZuKlient( "Du bist nicht berechtigt den Server zu beenden." );
+                }
+                break;
+            case 6: // Programm Schließen
+                if( !adminId )
+                    errorZuKlient( "Du musst dich einloggen." );
+                else
+                {
+                    bool ok = 0;
+                    if( ls->isRunning() )
+                    {
+                        if( ls->zDB()->adminHatRecht( adminId, Admin_Recht::LSBeenden ) )
+                        {
+                            if( ls->serverBeenden() )
+                                ok = 1;
+                            else
+                            {
+                                Text *err = new Text();
+                                err->append( ls->getLetzterFehler() );
+                                errorZuKlient( err->getText() );
+                                err->release();
+                            }
+                        }
+                        else
+                            errorZuKlient( "Du bist nicht berechtigt den Server zu beenden." );
+                    }
+                    else
+                        ok = 1;
+                    if( ok && ls->hatClients() )
+                    {
+                        errorZuKlient( "Es sind noch Klients Online. Bitte versuche es später erneut." );
+                        break;
+                    }
+                    if( ok )
+                    {
+                        klient->sende( "\1", 1 );
+                        std::cout << "LS: Der Server wird von Benutzer " << adminId << " heruntergefahren.\n";
+                        ls->close();
+                        br = 1;
+                    }
+                }
+                break;
+            case 7: // Progtamm abstürzen
+                if( !adminId )
+                    errorZuKlient( "Du musst dich einloggen." );
+                else
+                {
+                    bool ok = 0;
+                    if( ls->isRunning() )
+                    {
+                        if( ls->zDB()->adminHatRecht( adminId, Admin_Recht::LSBeenden ) )
+                        {
+                            ls->serverBeenden();
+                            ok = 1;
+                        }
+                        else
+                            errorZuKlient( "Du bist nicht berechtigt den Server zu beenden." );
+                    }
+                    else
+                        ok = 1;
+                    if( ok )
+                    {
+                        klient->sende( "\1", 1 );
+                        std::cout << "LS: Der Server wurde von Benutzer " << adminId << " terminiert.\n";
+                        ls->close();
+                        br = 1;
+                    }
+                }
+                break;
+            case 8: // Status Frage
+                if( 1 )
+                {
+                    char status = 0;
+                    if( ls->isRunning() )
+                    {
+                        status = 1;
+                        if( ls->istAn() )
+                            status = 2;
+                    }
+                    klient->sende( "\1", 1 );
+                    klient->sende( &status, 1 );
+                }
+                break;
+            case 9: // Server pausieren
+                if( !adminId )
+                    errorZuKlient( "Du musst dich einloggen." );
+                else
+                {
+                    klient->sende( "\1", 1 );
+                    char pause = 0;
+                    klient->getNachricht( &pause, 1 );
+                    if( ls->zDB()->adminHatRecht( adminId, Admin_Recht::LSPausieren ) )
+                    {
+                        bool ok = 0;
+                        if( pause )
+                            ok = ls->serverPause();
+                        else
+                            ok = ls->serverFortsetzen();
+                        if( ok )
+                            klient->sende( "\1", 1 );
+                        else
+                        {
+                            Text *err = new Text();
+                            err->append( ls->getLetzterFehler() );
+                            errorZuKlient( err->getText() );
+                            err->release();
+                        }
+                    }
+                    else
+                    {
+                        if( pause )
+                            errorZuKlient( "Du bist nicht berechtigt den Server zu pausieren." );
+                        else
+                            errorZuKlient( "Du bist nicht berechtigt den Server fortzusetzen." );
+                    }
+                }
+                break;
+            case 0xA: // maximale Anzahl der Clients setzen
+                if( !adminId )
+                    errorZuKlient( "Du musst dich einloggen." );
+                else
+                {
+                    klient->sende( "\1", 1 );
+                    int maxC = 0;
+                    klient->getNachricht( (char *)&maxC, 4 );
+                    if( ls->zDB()->adminHatRecht( adminId, Admin_Recht::LSMCChange ) )
+                    {
+                        if( ls->setMaxKlients( maxC ) )
+                            klient->sende( "\1", 1 );
+                        else
+                        {
+                            Text *err = new Text();
+                            err->append( ls->getLetzterFehler() );
+                            errorZuKlient( err->getText() );
+                            err->release();
+                        }
+                    }
+                    else
+                        errorZuKlient( "Du bist nicht berechtigt die maximale Anzahl der Clients zu verändern." );
+                }
+                break;
+            case 0xC: // klient absturtz
+                if( 1 )
+                {
+                    klient->sende( "\1", 1 );
+                    int klientId = 0;
+                    klient->getNachricht( (char *)&klientId, 4 );
+                    if( klientId && ls->absturzKlient( klientId ) )
+                        klient->sende( "\1", 1 );
+                    else
+                        klient->sende( "\0", 1 );
+                }
+                break;
+            default:
+                errorZuKlient( "Unbekannte Nachricht!" );
+                break;
+            }
+            if( br )
+                break;
+            ls->addEmpfangen( klient->getDownloadBytes( 1 ) );
+            ls->addGesendet( klient->getUploadBytes( 1 ) );
+        }
+    }
+    ls->addEmpfangen( klient->getDownloadBytes( 1 ) );
+    ls->addGesendet( klient->getUploadBytes( 1 ) );
+    delete this;
+}
+
+void FCAKlient::errorZuKlient( const char *nachricht ) const // sendet eine Fehlernachricht zum Klient
+{
+    klient->sende( "\3", 1 );
+    char len = (char)textLength( nachricht );
+    klient->sende( &len, 1 );
+    klient->sende( nachricht, len );
+}
+
+
+// Inhalt der LSKlient aus LoginServer.h
+// Konstruktor
+FCKlient::FCKlient( SKlient *klient, FactoryCraftServer *ls )
+    : Thread()
+{
+    this->klient = klient;
+    unsigned char key[ 20 ] = { 143, 166, 245, 235, 76, 75, 116, 80, 26, 178, 142, 176, 109, 53, 106, 222, 223, 55, 139, 111 };
+    klient->setSendeKey( (char *)key, 20 );
+    klient->setEmpfangKey( (char *)key, 20 );
+    klientNummer = 0;
+    this->ls = ls;
+}
+
+// Destruktor 
+FCKlient::~FCKlient()
+{
+    klient->release();
+    ls->release();
+}
+
+// nicht constant 
+void FCKlient::absturz()
+{
+    ende();
+    klient->trenne();
+    ls->zDB()->unregisterKlient( klientNummer, ls->getId() );
+}
+
+void FCKlient::thread()
+{
+    while( 1 )
+    {
+        char c = 0;
+        if( !klient->getNachrichtEncrypted( &c, 1 ) )
+            break;
+        else
+        {
+            bool br = 0;
+            switch( c )
+            {
+            case 1: // Klient identifikation
+                klient->getNachrichtEncrypted( (char *)&klientNummer, 4 );
+                if( !ls->zDB()->proveKlient( klientNummer, ls->getId() ) )
+                {
+                    klientNummer = 0;
+                    errorZuKlient( "Du bist nicht für diesen Server eingetragen" );
+                }
+                else
+                {
+                    Text *key = ls->zDB()->getKlientKey( klientNummer );
+                    if( !key )
+                        errorZuKlient( "Es konnte kein Schlüssel ermittelt werden." );
+                    else
+                    {
+                        klient->sendeEncrypted( "\1", 1 );
+                        klient->setEmpfangKey( *key, key->getLength() );
+                        klient->setSendeKey( *key, key->getLength() );
+                        key->release();
+                    }
+                }
+                break;
+            case 2: // Main / Erhaltung Server message
+                if( 1 )
+                {
+                    char befehl = 0;
+                    klient->getNachrichtEncrypted( &befehl, 1 );
+                    switch( befehl )
+                    {
+                    case 2: // klient absturtz
+                        if( 1 )
+                        {
+                            int klientId = 0;
+                            klient->getNachrichtEncrypted( (char *)&klientId, 4 );
+                            if( klientId && ls->absturzKlient( klientId ) )
+                                klient->sendeEncrypted( "\1", 1 );
+                            else
+                                klient->sendeEncrypted( "\0", 1 );
+                        }
+                        break;
+                    default:
+                        errorZuKlient( "Befehl nicht bekannt!" );
+                        break;
+                    }
+                }
+                break;
+            case 3: // Verbindungsende
+                br = 1;
+                klient->sendeEncrypted( "\1", 1 );
+                break;
+            case 4: // unregister Klient
+                if( !klientNummer )
+                {
+                    errorZuKlient( "Du bist nicht Identifiziert." );
+                    break;
+                }
+                ls->zDB()->unregisterKlient( klientNummer, ls->getId() );
+                klient->sendeEncrypted( "\1", 1 );
+                break;
+            case 0x7: // ping
+                if( 1 )
+                {
+                    if( !klientNummer )
+                    {
+                        errorZuKlient( "Du bist nicht Identifiziert." );
+                        break;
+                    }
+                    klient->sendeEncrypted( "\1", 1 );
+                }
+                break;
+            default:
+                errorZuKlient( "Unbekannte Nachricht!" );
+                break;
+            }
+            if( br )
+                break;
+            ls->addEmpfangen( klient->getDownloadBytes( 1 ) );
+            ls->addGesendet( klient->getUploadBytes( 1 ) );
+        }
+    }
+    ls->addEmpfangen( klient->getDownloadBytes( 1 ) );
+    ls->addGesendet( klient->getUploadBytes( 1 ) );
+    ls->removeKlient( this ); // delete this
+}
+
+// constant
+void FCKlient::errorZuKlient( const char *nachricht ) const // sendet eine Fehlernachricht zum Klient
+{
+    klient->sendeEncrypted( "\3", 1 );
+    char len = (char)textLength( nachricht );
+    klient->sendeEncrypted( &len, 1 );
+    klient->sendeEncrypted( nachricht, len );
+}
+
+int FCKlient::getKlientNummer() const // gibt die KlientId zurück
+{
+    return klientNummer;
+}
+
+// Inhalt der MSGWeiterleitung Klasse aus LoginServer.h
+// Konstruktor
+MSGWeiterleitung::MSGWeiterleitung( FactoryCraftServer *ls )
+    : ReferenceCounter()
+{
+    this->ls = ls;
+}
+
+// Destruktor
+MSGWeiterleitung::~MSGWeiterleitung()
+{
+    ls->release();
+}

+ 109 - 0
FactoryCraft/Server.h

@@ -0,0 +1,109 @@
+#pragma once
+
+#include <Server.h>
+#include <Thread.h>
+#include <Datei.h>
+#include <Text.h>
+#include <InitDatei.h>
+#include "Datenbank.h"
+
+using namespace Framework;
+using namespace Network;
+
+class FCKlient;
+
+class FactoryCraftServer : public Thread
+{
+private:
+    Server *server;
+    SSLServer *aServer;
+    InitDatei *ini;
+    LSDatenbank *db;
+    CRITICAL_SECTION cs;
+    RCArray< FCKlient > *klients;
+    Text *fehler;
+    int klientAnzahl;
+    int id;
+    bool nichtPausiert;
+    int empfangen;
+    int gesendet;
+    bool end;
+
+public:
+    // Konstruktor 
+    FactoryCraftServer( InitDatei *zIni );
+    // Destruktor 
+    virtual ~FactoryCraftServer();
+    // nicht constant
+    void runn();
+    void thread();
+    void close();
+    bool serverStarten();
+    bool serverPause();
+    bool serverFortsetzen();
+    bool serverBeenden();
+    bool setMaxKlients( int mc );
+    bool absturzKlient( int klientId );
+    bool removeKlient( FCKlient *zKlient );
+    void addGesendet( int bytes );
+    void addEmpfangen( int bytes );
+    // conatant 
+    bool istAn() const;
+    Server *zServer() const;
+    LSDatenbank *zDB() const;
+    bool hatClients() const;
+    int getId() const;
+    char *getLetzterFehler() const;
+};
+
+class FCAKlient : public Thread
+{
+private:
+    SSLSKlient *klient;
+    Text *name;
+    Text *passwort;
+    int adminId;
+    FactoryCraftServer *ls;
+    int version;
+
+public:
+    // Konstruktor 
+    FCAKlient( SSLSKlient *klient, FactoryCraftServer *ls );
+    // Destruktor 
+    virtual ~FCAKlient();
+    // nicht constant
+    void thread();
+    void errorZuKlient( const char *nachricht ) const; // sendet eine Fehlernachricht zum AKlient
+};
+
+class FCKlient : public Thread
+{
+private:
+    SKlient *klient;
+    unsigned int klientNummer;
+    FactoryCraftServer *ls;
+
+public:
+    // Konstruktor 
+    FCKlient( SKlient *klient, FactoryCraftServer *ls );
+    // Destruktor 
+    virtual ~FCKlient();
+    // nicht constant 
+    void absturz();
+    void thread();
+    // constant
+    void errorZuKlient( const char *nachricht ) const; // sendet eine Fehlernachricht zum Klient
+    int getKlientNummer() const;
+};
+
+class MSGWeiterleitung : public virtual ReferenceCounter
+{
+private:
+    FactoryCraftServer *ls;
+
+public:
+    // Konstruktor
+    MSGWeiterleitung( FactoryCraftServer *ls );
+    // Destruktor
+    ~MSGWeiterleitung();
+};

+ 66 - 0
FactoryCraft/Start.cpp

@@ -0,0 +1,66 @@
+#include <iostream>
+#include <fstream>
+#include <Zeit.h>
+#include <Datei.h>
+#include <Text.h>
+#include <Globals.h>
+#include <sys/resource.h>
+#include <Klient.h>
+
+#include "Server.h"
+
+int main()
+{
+    struct rlimit core_limits;
+    core_limits.rlim_cur = core_limits.rlim_max = RLIM_INFINITY;
+    setrlimit( RLIMIT_CORE, &core_limits );
+
+    Framework::initFramework();
+    Zeit *z = getZeit();
+    Text *pfad = new Text( "../log/main/" );
+    pfad->append( z->getZeit( "y-m-d h-i-s.log" ) );
+    z->release();
+    DateiPfadErstellen( pfad->getText() );
+    std::ofstream file;
+    file.open( pfad->getText() );
+    std::streambuf *sbuf = std::cout.rdbuf();
+    std::cout.rdbuf( file.rdbuf() );
+    pfad->release();
+
+    std::cout << "MS: Startet...\n";
+    std::cout << "MS: Lese init Datei ../data/msInit.ini ...\n";
+
+    InitDatei *dat = new InitDatei( "../data/msInit.ini" );
+    if( !dat->laden() )
+    {
+        std::cout << "MS: error: Datei konnte nicht gelesen werden. Das Programm wird geschlossen.\n";
+        dat->release();
+        exit( 1 );
+    }
+    const char *wichtig[] = { "ServerId", "DBBenutzer", "DBPasswort", "DBName", "DBIP", "DBPort", "Aktiv", "SSLPort", "SSLCert", "SSLKey", "SSLPasswort" };
+    for( const char *w : wichtig )
+    {
+        if( !dat->wertExistiert( w ) )
+        {
+            std::cout << "MS: error: Der Wert '" << w << "' wurde nicht gefunden. Das Programm wird geschlossen.\n";
+            dat->release();
+            exit( 1 );
+        }
+    }
+
+    FactoryCraftServer *mserver = new FactoryCraftServer( dat );
+
+    std::cout << "MS: Der Admin Server läuft. Startforgang beendet.\n";
+    mserver->runn();
+    SSLKlient exitClient;
+    exitClient.verbinde( (unsigned short)(int)*dat->zWert( "SSLPort" ), "127.0.0.1" );
+
+    mserver->ende();
+    mserver->release();
+    dat->release();
+    std::cout << "MS: Der Server ist heruntergefahren.\n";
+    file.close();
+    std::cout.rdbuf( sbuf );
+    Framework::releaseFramework();
+    return 0;
+}

+ 8 - 0
FactoryCraft/StaticInitializerOrder.cpp

@@ -0,0 +1,8 @@
+#include "StaticRegistry.h"
+#include "BlockType.h"
+#include "ItemType.h"
+
+#define REGISTER(x) const x* x::INSTANCE = new x();
+
+#include "BasicBlocks.h"
+

+ 71 - 0
FactoryCraft/StaticRegistry.h

@@ -0,0 +1,71 @@
+#pragma once
+
+#define REGISTRABLE(x)            \
+public:                           \
+    static const x *INSTANCE;           \
+                                  \
+private:
+
+
+template<typename T>
+class StaticRegistry
+{
+public:
+    static StaticRegistry<T> INSTANCE;
+
+private:
+    T **registry;
+    int count;
+
+    StaticRegistry()
+    {
+        count = 100;
+        registry = new T * [ count ];
+        memset( registry, 0, sizeof( T * ) * count );
+    }
+
+    ~StaticRegistry()
+    {
+        for( int index = 0; index < count; index++ )
+        {
+            if( registry[ index ] )
+            {
+                registry[ index ]->release();
+                registry[ index ] = 0;
+            }
+        }
+        delete[]registry;
+    }
+
+    void registerT( T *type, int id )
+    {
+        if( id >= count )
+        {
+            T **temp = new T * [ id + 1 ];
+            memcpy( temp, registry, sizeof( T * ) * count );
+            memset( temp + count, 0, sizeof( T * ) * ( id + 1 - count ) );
+            delete[]registry;
+            registry = temp;
+            count = id + 1;
+        }
+        registry[ id ] = type;
+    }
+
+public:
+    T *zElement( int id )
+    {
+        if( id < 0 || id >= count )
+            return 0;
+        return registry[ id ];
+    }
+
+    int getCount() const
+    {
+        return count;
+    }
+
+    friend T;
+};
+
+template <typename T>
+StaticRegistry<T> StaticRegistry<T>::INSTANCE;

+ 67 - 0
FactoryCraft/WorldGenerator.cpp

@@ -0,0 +1,67 @@
+#include "WorldGenerator.h"
+#include "StaticRegistry.h"
+#include "Game.h"
+#include "PerlinNoise.h"
+
+using namespace Framework;
+
+WorldGenerator::WorldGenerator( int seed, Game *zGame )
+    : Thread(),
+    zGame( zGame ),
+    noise( new PerlinNoise( seed ) ),
+    exit( 0 )
+{
+    start();
+}
+
+WorldGenerator::~WorldGenerator()
+{
+    noise->release();
+}
+
+void WorldGenerator::thread()
+{
+    while( !exit )
+    {
+        cs.Enter();
+        GenerationRequest next;
+        bool hasNext = false;
+        if( requestQueue.getEintragAnzahl() > 0 )
+        {
+            next = requestQueue.get( 0 );
+            requestQueue.remove( 0 );
+        }
+        cs.Leave();
+        if( !hasNext )
+        {
+            sleep( 1 );
+            continue;
+        }
+        Punkt start = zGame->getChunkCenter( next.startX, next.startY );
+        Punkt end = zGame->getChunkCenter( next.endX, next.endY );
+        int xDir = start.x > end.x ? -1 : ( start.x < end.x ? 1 : 0 );
+        int yDir = start.y > end.y ? -1 : ( start.y < end.y ? 1 : 0 );
+        for( int x = start.x; x != end.x; x += CHUNK_SIZE * xDir )
+        {
+            for( int y = start.y; y != end.y; y += CHUNK_SIZE * yDir )
+            {
+                Chunk *generatedChunk = StaticRegistry<DimensionGenerator>::INSTANCE.zElement( next.dimensionId )->generateChunk( noise, zGame, x, y );
+                zGame->addChunck( generatedChunk, next.dimensionId );
+            }
+        }
+    }
+}
+
+void WorldGenerator::requestGeneration( GenerationRequest request )
+{
+    cs.Enter();
+    requestQueue.add( request );
+    cs.Leave();
+}
+
+void WorldGenerator::exitAndWait()
+{
+    exit = 1;
+    warteAufThread( 10000 );
+    ende();
+}

+ 33 - 0
FactoryCraft/WorldGenerator.h

@@ -0,0 +1,33 @@
+#pragma once
+
+#include <Thread.h>
+
+#include "DimensionGenerator.h"
+
+class Game;
+
+struct GenerationRequest
+{
+    int startX;
+    int startY;
+    int endX;
+    int endY;
+    int dimensionId;
+};
+
+class WorldGenerator : public Framework::Thread
+{
+private:
+    CriticalSection cs;
+    Framework::Array<GenerationRequest> requestQueue;
+    Game *zGame;
+    Noise *noise;
+    bool exit;
+
+public:
+    WorldGenerator( int seed, Game *zGame );
+    ~WorldGenerator();
+    void thread() override;
+    void requestGeneration( GenerationRequest request );
+    void exitAndWait();
+};