Procházet zdrojové kódy

add server selection menu and do not require login anymore

Kolja Strohm před 2 roky
rodič
revize
6dd41e132a

+ 1 - 1
FactoryCraft/AddEntityUpdate.cpp

@@ -14,5 +14,5 @@ void AddEntityUpdateType::applyUpdate(Framework::StreamReader* zReader)
 	int type;
 	zReader->lese((char*)&type, 4);
 	Entity* entity = entityTypes[type]->loadEntity(zReader);
-	currentGame->zDimension()->addEntity(entity);
+	World::INSTANCE->zDimension()->addEntity(entity);
 }

+ 115 - 0
FactoryCraft/AddServerMenu.cpp

@@ -0,0 +1,115 @@
+#include "AddServerMenu.h"
+#include "Initialisierung.h"
+#include "Globals.h"
+#include "ServerSelection.h"
+
+AddServerMenu::AddServerMenu(Bildschirm* zScreen)
+	: Menu(zScreen)
+{
+	Punkt center = zScreen->getBackBufferSize() / 2;
+	TextFeld* nameLabel = initTextFeld(center.x - 150, center.y - 50, 100, 20, TextFeld::Style::Text | TextFeld::Style::VCenter, "Name:");
+	elements.add(nameLabel);
+	name = initTextFeld(nameLabel->getPosition().x + nameLabel->getBreite(), nameLabel->getPosition().y, 200, 20, TextFeld::Style::TextFeld, "");
+	name->setTastaturEreignis([this](void* p, void* o, TastaturEreignis te)
+		{
+			if (te.id == TE_Release && te.virtualKey == T_Tab)
+			{
+				name->removeStyle(Zeichnung::Style::Fokus);
+				address->addStyle(Zeichnung::Style::Fokus);
+			}
+			return te.virtualKey != T_Tab;
+		});
+	elements.add(name);
+
+	TextFeld* addressLabel = initTextFeld(center.x - 150, center.y - 25, 100, 20, TextFeld::Style::Text | TextFeld::Style::VCenter, "Server Address:");
+	elements.add(addressLabel);
+	address = initTextFeld(addressLabel->getPosition().x + addressLabel->getBreite(), addressLabel->getPosition().y, 200, 20, TextFeld::Style::TextFeld, "");
+	address->setTastaturEreignis([this](void* p, void* o, TastaturEreignis te)
+		{
+			if (te.id == TE_Release && te.virtualKey == T_Tab)
+			{
+				address->removeStyle(Zeichnung::Style::Fokus);
+				sslPort->addStyle(Zeichnung::Style::Fokus);
+			}
+			return te.virtualKey != T_Tab;
+		});
+	elements.add(address);
+
+	TextFeld* sslPortLabel = initTextFeld(center.x - 150, center.y, 100, 20, TextFeld::Style::Text | TextFeld::Style::VCenter, "SSL Server Port:");
+	elements.add(sslPortLabel);
+	sslPort = initTextFeld(sslPortLabel->getPosition().x + sslPortLabel->getBreite(), sslPortLabel->getPosition().y, 200, 20, TextFeld::Style::TextFeld, "");
+	sslPort->setTastaturEreignis([this](void* p, void* o, TastaturEreignis te)
+		{
+			if (te.id == TE_Release && te.virtualKey == T_Tab)
+			{
+				sslPort->removeStyle(Zeichnung::Style::Fokus);
+				port->addStyle(Zeichnung::Style::Fokus);
+			}
+			return te.virtualKey != T_Tab && _nurNummernTE(p, o, te);
+		});
+	elements.add(sslPort);
+	TextFeld* portLabel = initTextFeld(center.x - 150, center.y + 25, 100, 20, TextFeld::Style::Text | TextFeld::Style::VCenter, "Server Port:");
+	elements.add(portLabel);
+	port = initTextFeld(portLabel->getPosition().x + portLabel->getBreite(), portLabel->getPosition().y, 200, 20, TextFeld::Style::TextFeld, "");
+	port->setTastaturEreignis(_nurNummernTE);
+	elements.add(port);
+
+	add = initKnopf(center.x + 50, center.y + 50, 100, 20, Knopf::Style::Normal, "Add");
+	add->setMausEreignis([this](void* p, void* o, MausEreignis me)
+		{
+			if (me.id == ME_RLinks)
+			{
+				if (name->zText()->getLength() && address->zText()->getLength() && port->zText()->getLength())
+				{
+					if (!((ServerSelectionMenu*)(Menu*)menuRegister->get("serverSelection"))->hasServer(name->zText()->getText()))
+					{
+						hide();
+						menuRegister->get("serverSelection")->show();
+						((ServerSelectionMenu*)(Menu*)menuRegister->get("serverSelection"))->addServer(name->zText()->getText(), address->zText()->getText(), (unsigned short)(int)*sslPort->zText(), (unsigned short)(int)*port->zText());
+						name->zText()->setText("");
+						address->zText()->setText("");
+						port->zText()->setText("");
+						sslPort->zText()->setText("");
+						name->setAlphaFeldFarbe(0xFF3d3d3d);
+						address->setAlphaFeldFarbe(0xFF3d3d3d);
+						port->setAlphaFeldFarbe(0xFF3d3d3d);
+						sslPort->setAlphaFeldFarbe(0xFF3d3d3d);
+					}
+					else
+						name->setAlphaFeldFarbe(0xFF3d0000);
+				}
+				else
+				{
+					if(!name->zText()->getLength())
+						name->setAlphaFeldFarbe(0xFF3d0000);
+					if (!address->zText()->getLength())
+						address->setAlphaFeldFarbe(0xFF3d0000);
+					if (!port->zText()->getLength())
+						port->setAlphaFeldFarbe(0xFF3d0000);
+					if (!sslPort->zText()->getLength())
+						sslPort->setAlphaFeldFarbe(0xFF3d0000);
+				}
+			}
+			return 1;
+		});
+	elements.add(add);
+
+	abort = initKnopf(center.x - 150, center.y + 50, 100, 20, Knopf::Style::Normal, "Abort");
+	abort->setMausEreignis([this](void* p, void* o, MausEreignis me)
+		{
+			if (me.id == ME_RLinks)
+			{
+				hide();
+				menuRegister->get("serverSelection")->show();
+				name->zText()->setText("");
+				address->zText()->setText("");
+				port->zText()->setText("");
+				name->setAlphaFeldFarbe(0xFF3d3d3d);
+				address->setAlphaFeldFarbe(0xFF3d3d3d);
+				port->setAlphaFeldFarbe(0xFF3d3d3d);
+				sslPort->setAlphaFeldFarbe(0xFF3d3d3d);
+			}
+			return 1;
+		});
+	elements.add(abort);
+}

+ 19 - 0
FactoryCraft/AddServerMenu.h

@@ -0,0 +1,19 @@
+#pragma once
+
+#include <TextFeld.h>
+#include <Knopf.h>
+#include "Menu.h"
+
+class AddServerMenu : public Menu
+{
+private:
+	Framework::TextFeld* name;
+	Framework::TextFeld* address;
+	Framework::TextFeld* sslPort;
+	Framework::TextFeld* port;
+	Framework::Knopf* add;
+	Framework::Knopf* abort;
+
+public:
+	AddServerMenu(Framework::Bildschirm* zScreen);
+};

+ 5 - 5
FactoryCraft/Chunk.cpp

@@ -20,7 +20,7 @@ Chunk::Chunk(Framework::Punkt location, Framework::StreamReader* zReader)
 Chunk::~Chunk()
 {
 	char msg = 1; // remove observer
-	network->zFactoryClient()->chunkAPIRequest(location, &msg, 1);
+	World::INSTANCE->zClient()->chunkAPIRequest(location, &msg, 1);
 }
 
 void Chunk::api(char* message)
@@ -89,14 +89,14 @@ void Chunk::api(char* message)
 				{
 					pos.x += this->location.x - CHUNK_SIZE / 2;
 					pos.y += this->location.y - CHUNK_SIZE / 2;
-					Block* zB = currentGame->zBlockAt(pos);
+					Block* zB = World::INSTANCE->zBlockAt(pos);
 					if (zB)
 					{
 						bool visible = zB->isVisible();
 						zB->setLightData(getOppositeDirection(getDirectionFromIndex(i)), (unsigned char*)(message + 5));
 						if (zB->isVisible() != visible)
 						{
-							Chunk* c = currentGame->zChunk(currentGame->getChunkCenter(pos.x, pos.y));
+							Chunk* c = World::INSTANCE->zChunk(World::INSTANCE->getChunkCenter(pos.x, pos.y));
 							c->vcs.lock();
 							if (zB->isVisible())
 								c->visibleBlocks.add(zB);
@@ -232,14 +232,14 @@ void Chunk::load(Framework::StreamReader* zReader)
 				{
 					pos.x += this->location.x - CHUNK_SIZE / 2;
 					pos.y += this->location.y - CHUNK_SIZE / 2;
-					Block* zB = currentGame->zBlockAt(pos);
+					Block* zB = World::INSTANCE->zBlockAt(pos);
 					if (zB)
 					{
 						bool visible = zB->isVisible();
 						zB->setLightData(getOppositeDirection(getDirectionFromIndex(i)), (unsigned char*)lightData);
 						if (zB->isVisible() && !visible)
 						{
-							Chunk* c = currentGame->zChunk(currentGame->getChunkCenter(pos.x, pos.y));
+							Chunk* c = World::INSTANCE->zChunk(World::INSTANCE->getChunkCenter(pos.x, pos.y));
 							c->vcs.lock();
 							c->visibleBlocks.add(zB);
 							c->vcs.unlock();

+ 5 - 5
FactoryCraft/CraftingGrid.cpp

@@ -80,7 +80,7 @@ CraftingGridView::CraftingGridView(Text id, int rowSize, int colSize, int numOut
 					*(int*)(msg + 10) = this->target.getB()[2];
 					*(int*)(msg + 14) = this->target.getB()[3];
 				}
-				network->zFactoryClient()->sendPlayerAction(msg, 2 + (this->target.isA() ? 4 : 16));
+				World::INSTANCE->zClient()->sendPlayerAction(msg, 2 + (this->target.isA() ? 4 : 16));
 				delete[] msg;
 			}
 			return 1;
@@ -92,7 +92,7 @@ CraftingGridView::CraftingGridView(Text id, int rowSize, int colSize, int numOut
 	memcpy(msg + 2, id.getText(), id.getLength());
 	msg[2 + id.getLength()] = (char)12;
 	memcpy(msg + 3 + id.getLength(), "CraftingGrid", 12);
-	network->zFactoryClient()->inventoryAPIRequest(target, msg, id.getLength() + 12 + 3);
+	World::INSTANCE->zClient()->inventoryAPIRequest(target, msg, id.getLength() + 12 + 3);
 	delete[] msg;
 	setNeedToolTipEvent([this](Zeichnung* z, Punkt p)
 		{
@@ -112,7 +112,7 @@ CraftingGridView::CraftingGridView(Text id, int rowSize, int colSize, int numOut
 				msg[1] = (char)this->id.getLength();
 				memcpy(msg + 2, this->id.getText(), this->id.getLength());
 				*(int*)(msg + 2 + this->id.getLength()) = slot;
-				network->zFactoryClient()->inventoryAPIRequest(this->target, msg, this->id.getLength() + 6);
+				World::INSTANCE->zClient()->inventoryAPIRequest(this->target, msg, this->id.getLength() + 6);
 			}
 		});
 }
@@ -130,7 +130,7 @@ CraftingGridView::~CraftingGridView()
 	msg[0] = 1;
 	msg[1] = (char)id.getLength();
 	memcpy(msg + 2, id.getText(), id.getLength());
-	network->zFactoryClient()->inventoryAPIRequest(target, msg, id.getLength() + 2);
+	World::INSTANCE->zClient()->inventoryAPIRequest(target, msg, id.getLength() + 2);
 	delete[] msg;
 	craft->release();
 }
@@ -416,7 +416,7 @@ void CraftingGridView::doMausEreignis(MausEreignis& me, bool userRet)
 						index += 16;
 					}
 					*(int*)(msg + index) = info.id;
-					network->zFactoryClient()->sendPlayerAction(msg, len);
+					World::INSTANCE->zClient()->sendPlayerAction(msg, len);
 					delete[] msg;
 				}
 			}

+ 20 - 20
FactoryCraft/CustomUIDX11PixelShader.h

@@ -373,10 +373,10 @@ ret
 
 const BYTE CustomUIDX11PixelShader[] =
 {
-     68,  88,  66,  67, 106, 225, 
-    185, 123,  45, 143, 202, 134, 
-     48, 116,  50, 123,  61, 214, 
-      0, 179,   1,   0,   0,   0, 
+     68,  88,  66,  67, 240, 110, 
+     62, 120, 122, 104, 111,  40, 
+    233,  16,  99,  29, 131,  30, 
+    100, 217,   1,   0,   0,   0, 
      16, 135,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
     192,   6,   0,   0, 104,   7, 
@@ -1869,11 +1869,11 @@ const BYTE CustomUIDX11PixelShader[] =
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
-    148,  46,  49,   1,  76, 230, 
-    173,  98,   1,   0,   0,   0, 
-    101, 231,   8, 104, 190, 233, 
-    161,  79, 170,  94,  31, 240, 
-    101, 252, 195, 219,   0,   0, 
+    148,  46,  49,   1, 216, 104, 
+    176,  98,   1,   0,   0,   0, 
+    143, 255, 215, 214, 111,  99, 
+      3,  67, 146, 164,  42,   2, 
+     60, 158, 177, 248,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       1,   0,   0,   0,   1,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -2045,9 +2045,9 @@ const BYTE CustomUIDX11PixelShader[] =
       1,   0,  43, 236,   3,   0, 
      28,  19,   2,   0,  65,  36, 
       1,   0, 236, 179,   1,   0, 
-    130,  86,   0,   0, 125,  10, 
+    198, 234,   0,   0, 125,  10, 
       2,   0, 125, 181,   2,   0, 
-      8, 246,   1,   0, 193,  33, 
+    204,  36,   1,   0, 193,  33, 
       3,   0,  65, 185,   2,   0, 
       9, 241,   2,   0, 146, 230, 
       3,   0, 125, 218,   1,   0, 
@@ -2979,8 +2979,8 @@ const BYTE CustomUIDX11PixelShader[] =
      32,  32,  32,  32,  32,  32, 
      32,  32,  32,  32,  32,  32, 
      32,  32,  27, 226,  48,   1, 
-    128,   0,   0,   0, 150,  50, 
-    193, 206,  34, 131, 216,   1, 
+    128,   0,   0,   0,  99, 186, 
+    127, 203, 161, 132, 216,   1, 
       1,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -4310,14 +4310,14 @@ const BYTE CustomUIDX11PixelShader[] =
       6,  16,   0,   0,  23,   0, 
       1,   0,   5,  16,   0,   0, 
      14,   0,  23,  21,   0,  16, 
-      0,   0,   3,   2,   0, 168, 
+      0,   0,   3,   2, 144, 199, 
       0,   0, 242, 241,  10,   0, 
      24,  21,   8,  16,   0,   0, 
       1,   0,   1,   0,  10,   0, 
      24,  21,   9,  16,   0,   0, 
       1,   0,   0,   2,  14,   0, 
      23,  21,   0,   0,   0,   0, 
-     10,   2,   0, 168,   0,   0, 
+     10,   2, 144, 199,   0,   0, 
     242, 241,  10,   0,  24,  21, 
      11,  16,   0,   0,   1,   0, 
       1,   0,  10,   0,  24,  21, 
@@ -5539,10 +5539,10 @@ const BYTE CustomUIDX11PixelShader[] =
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0, 148,  46,  49,   1, 
-     76, 230, 173,  98,   1,   0, 
-      0,   0, 101, 231,   8, 104, 
-    190, 233, 161,  79, 170,  94, 
-     31, 240, 101, 252, 195, 219, 
+    216, 104, 176,  98,   1,   0, 
+      0,   0, 143, 255, 215, 214, 
+    111,  99,   3,  67, 146, 164, 
+     42,   2,  60, 158, 177, 248, 
     174,   0,   0,   0,  47,  76, 
     105, 110, 107,  73, 110, 102, 
     111,   0,  47, 110,  97, 109, 
@@ -5642,7 +5642,7 @@ const BYTE CustomUIDX11PixelShader[] =
       0,   0,   0,   0,   2,   0, 
       9,   0,  80,   9,   0,   0, 
       0,   0,   0,   0, 124,  15, 
-      0,   0,   1,   0, 230, 162, 
+      0,   0,   1,   0,  40,  27, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
      84, 101, 120, 116, 117, 114, 

+ 16 - 16
FactoryCraft/CustomUIDX11VertexShader.h

@@ -204,10 +204,10 @@ ret
 
 const BYTE CustomUIDX11VertexShader[] =
 {
-     68,  88,  66,  67, 143, 216, 
-     40, 130, 135, 133, 159,  47, 
-     80,  61, 122, 110, 122,  63, 
-    233,  71,   1,   0,   0,   0, 
+     68,  88,  66,  67, 201,  47, 
+    225, 150, 137,  76, 119,  98, 
+    239, 248, 100, 115,  60,  68, 
+     42, 228,   1,   0,   0,   0, 
     252,  91,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
      84,   3,   0,   0,  12,   4, 
@@ -1228,10 +1228,10 @@ const BYTE CustomUIDX11VertexShader[] =
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0, 148,  46,  49,   1, 
-     77, 230, 173,  98,   1,   0, 
-      0,   0,  31, 211,  72,  14, 
-    223,  99, 248,  65, 178, 123, 
-    161, 152, 215, 128, 184,  34, 
+    217, 104, 176,  98,   1,   0, 
+      0,   0,  13, 221, 122,  36, 
+    251,  72, 225,  71, 167,   0, 
+    209, 121,  43, 253, 133, 175, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   1,   0,   0,   0, 
       1,   0,   0,   0,   0,   0, 
@@ -1996,8 +1996,8 @@ const BYTE CustomUIDX11VertexShader[] =
      10, 125,  13,  10,  13,  10, 
      99,  98, 117, 102, 102, 101, 
     114,  32,  27, 226,  48,   1, 
-    128,   0,   0,   0, 123, 219, 
-      0, 207,  34, 131, 216,   1, 
+    128,   0,   0,   0, 142,  33, 
+    206, 203, 161, 132, 216,   1, 
       1,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -3702,11 +3702,11 @@ const BYTE CustomUIDX11VertexShader[] =
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
-    148,  46,  49,   1,  77, 230, 
-    173,  98,   1,   0,   0,   0, 
-     31, 211,  72,  14, 223,  99, 
-    248,  65, 178, 123, 161, 152, 
-    215, 128, 184,  34, 175,   0, 
+    148,  46,  49,   1, 217, 104, 
+    176,  98,   1,   0,   0,   0, 
+     13, 221, 122,  36, 251,  72, 
+    225,  71, 167,   0, 209, 121, 
+     43, 253, 133, 175, 175,   0, 
       0,   0,  47,  76, 105, 110, 
     107,  73, 110, 102, 111,   0, 
      47, 110,  97, 109, 101, 115, 
@@ -3806,7 +3806,7 @@ const BYTE CustomUIDX11VertexShader[] =
       0,   0,   2,   0,   9,   0, 
      64,   6,   0,   0,   0,   0, 
       0,   0, 244,   6,   0,   0, 
-      1,   0, 199, 222,   0,   0, 
+      1,   0, 182,  10,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,  84, 101, 
     120, 116, 117, 114, 101,  86, 

+ 13 - 13
FactoryCraft/Dimension.cpp

@@ -79,7 +79,7 @@ void Dimension::api(char* message)
 		zm.messungEnde();
 		std::cout << "chunk loading took " << zm.getSekunden() << " seconds\n";
 		setChunk(chunk, center);
-		currentGame->onChunkAdded(center);
+		World::INSTANCE->onChunkAdded(center);
 		break;
 	}
 	}
@@ -94,7 +94,7 @@ Chunk* Dimension::zChunk(Punkt wPos) const
 
 Block* Dimension::zBlock(Vec3<int> location)
 {
-	Chunk* c = zChunk(currentGame->getChunkCenter(location.x, location.y));
+	Chunk* c = zChunk(World::INSTANCE->getChunkCenter(location.x, location.y));
 	if (c)
 		return c->zBlockAt(location);
 	return 0;
@@ -103,7 +103,7 @@ Block* Dimension::zBlock(Vec3<int> location)
 Block* Dimension::getBlock(Vec3<int> location)
 {
 	cs.lock();
-	Chunk* c = zChunk(currentGame->getChunkCenter(location.x, location.y));
+	Chunk* c = zChunk(World::INSTANCE->getChunkCenter(location.x, location.y));
 	if (c)
 	{
 		Block* b = c->zBlockAt(location);
@@ -118,7 +118,7 @@ Block* Dimension::getBlock(Vec3<int> location)
 void Dimension::addEntity(Entity* entity)
 {
 	entities->add(entity);
-	currentGame->setVisibility(entity, 1);
+	World::INSTANCE->setVisibility(entity, 1);
 }
 
 void Dimension::setChunk(Chunk* chunk, Punkt center)
@@ -129,7 +129,7 @@ void Dimension::setChunk(Chunk* chunk, Punkt center)
 	cs.lock();
 	if (old)
 	{
-		currentGame->setVisibility(old, 0);
+		World::INSTANCE->setVisibility(old, 0);
 		int index = 0;
 		for (auto iterator = chunkList.begin(); iterator; ++iterator, ++index)
 		{
@@ -151,7 +151,7 @@ void Dimension::setChunk(Chunk* chunk, Punkt center)
 	cs.unlock();
 	if (chunk)
 	{
-		currentGame->setVisibility(chunk, 1);
+		World::INSTANCE->setVisibility(chunk, 1);
 		chunk->release();
 	}
 }
@@ -174,7 +174,7 @@ void Dimension::removeDistantChunks(Punkt wPos)
 	for (int i : removed)
 	{
 		Chunk* chunk = chunkList.get(i);
-		currentGame->setVisibility(chunk, 0);
+		World::INSTANCE->setVisibility(chunk, 0);
 		setChunk(0, chunk->getCenter());
 	}
 }
@@ -182,7 +182,7 @@ void Dimension::removeDistantChunks(Punkt wPos)
 void Dimension::setBlock(Block* block)
 {
 	cs.lock();
-	Chunk* c = zChunk(currentGame->getChunkCenter((int)floor(block->getPos().x), (int)floor(block->getPos().y)));
+	Chunk* c = zChunk(World::INSTANCE->getChunkCenter((int)floor(block->getPos().x), (int)floor(block->getPos().y)));
 	if (c)
 		c->setBlock(block);
 	else
@@ -193,7 +193,7 @@ void Dimension::setBlock(Block* block)
 void Dimension::removeBlock(Block* zBlock)
 {
 	cs.lock();
-	Chunk* c = zChunk(currentGame->getChunkCenter((int)floor(zBlock->getPos().x), (int)floor(zBlock->getPos().y)));
+	Chunk* c = zChunk(World::INSTANCE->getChunkCenter((int)floor(zBlock->getPos().x), (int)floor(zBlock->getPos().y)));
 	if (c)
 		c->removeBlock(zBlock);
 	cs.unlock();
@@ -232,21 +232,21 @@ Entity* Dimension::getEntity(int id)
 
 void Dimension::removeEntity(int id)
 {
-	currentGame->lockWorld();
+	World::INSTANCE->lockWorld();
 	cs.lock();
 	int index = 0;
 	for (Entity* e : *entities)
 	{
 		if (e->getId() == id)
 		{
-			currentGame->setVisibility(e, 0);
+			World::INSTANCE->setVisibility(e, 0);
 			entities->remove(index);
 			cs.unlock();
-			currentGame->unlockWorld();
+			World::INSTANCE->unlockWorld();
 			return;
 		}
 		index++;
 	}
 	cs.unlock();
-	currentGame->unlockWorld();
+	World::INSTANCE->unlockWorld();
 }

+ 0 - 37
FactoryCraft/DirectConnect.cpp

@@ -1,37 +0,0 @@
-#include "DirectConnect.h"
-#include "Initialisierung.h"
-#include "Globals.h"
-
-DirectConnect::DirectConnect(Bildschirm* zScreen)
-	: Menu(zScreen)
-{
-	elements.add(initTextFeld(10, 10, 90, 20, TextFeld::Style::Text, "Adresse: "));
-	elements.add(initTextFeld(10, 35, 90, 20, TextFeld::Style::Text, "Port: "));
-	address = initTextFeld(100, 10, 200, 20, TextFeld::Style::TextFeld, "koljastrohm-games.com");
-	port = initTextFeld(100, 35, 200, 20, TextFeld::Style::TextFeld, "5425");
-	port->setTastaturEreignis(_nurNummernTE);
-	elements.add(address);
-	elements.add(port);
-	Knopf* login = initKnopf(200, 60, 100, 20, Knopf::Style::Normal, "Beitreten");
-	login->setMausEreignis([this, login, zScreen](void* p, void* o, MausEreignis me)
-		{
-			if (me.id == ME_RLinks)
-			{
-				login->removeStyle(Knopf::Style::Erlaubt);
-				address->removeStyle(TextFeld::Style::Erlaubt);
-				port->removeStyle(TextFeld::Style::Erlaubt);
-				if (network->connect(address->zText()->getText(), (short)(int)*port->zText()))
-				{
-					currentGame = new World(dynamic_cast<Bildschirm3D*>(zScreen));
-					hide();
-					menuRegister->get("game")->show();
-					network->zFactoryClient()->sendPlayerAction("\5", 1);
-				}
-				address->addStyle(TextFeld::Style::Erlaubt);
-				port->addStyle(TextFeld::Style::Erlaubt);
-				login->addStyle(Knopf::Style::Erlaubt);
-			}
-			return 1;
-		});
-	elements.add(login);
-}

+ 0 - 14
FactoryCraft/DirectConnect.h

@@ -1,14 +0,0 @@
-#pragma once
-
-#include <TextFeld.h>
-#include "Menu.h"
-
-class DirectConnect : public Menu
-{
-private:
-	TextFeld* address;
-	TextFeld* port;
-
-public:
-	DirectConnect(Bildschirm* zScreen);
-};

+ 13 - 13
FactoryCraft/Entity.cpp

@@ -16,7 +16,7 @@ Entity::Entity(const EntityType* zType, Framework::Model3DData* model, Framework
 	pos = position;
 	setModelDaten(model);
 	setModelTextur(texture);
-	lastDirection = currentGame->zKamera()->getDirection();
+	lastDirection = World::INSTANCE->zKamera()->getDirection();
 	currentFrame.duration = 0;
 	rend = 1;
 }
@@ -55,7 +55,7 @@ void Entity::api(char* message)
 			pos.x = *(float*)(message += 1);
 			pos.y = *(float*)(message += 4);
 			pos.z = *(float*)(message += 4);
-			lastDirection = currentGame->zKamera()->getDirection();
+			lastDirection = World::INSTANCE->zKamera()->getDirection();
 			lastFlags = 0;
 		}
 		break;
@@ -67,7 +67,7 @@ bool Entity::tick(double time)
 {
 	if (playerControlled && GetForegroundWindow() == window->getFensterHandle())
 	{
-		Vec3<float> direction = currentGame->zKamera()->getDirection();
+		Vec3<float> direction = World::INSTANCE->zKamera()->getDirection();
 		Vec3<float> lastPos = pos;
 		int flags = 0;
 		speed = { 0, 0, speed.z };
@@ -151,7 +151,7 @@ bool Entity::tick(double time)
 						Vec3<float> tmp = worldBoundingBox[i] + frameSpeed * xt;
 						if (tmp.y >= worldBoundingBoxFloor[i].y && tmp.y < worldBoundingBoxFloor[i].y + 1.f && tmp.z >= worldBoundingBoxFloor[i].z && tmp.z < worldBoundingBoxFloor[i].z + 1.f)
 						{
-							Block* b = currentGame->zBlockAt(Vec3<int>{ (int)worldBoundingBoxFloor[i].x + 1, (int)worldBoundingBoxFloor[i].y, (int)worldBoundingBoxFloor[i].z });
+							Block* b = World::INSTANCE->zBlockAt(Vec3<int>{ (int)worldBoundingBoxFloor[i].x + 1, (int)worldBoundingBoxFloor[i].y, (int)worldBoundingBoxFloor[i].z });
 							if (b) // TODO: ignore passable blocks
 							{
 								if (xt < tf)
@@ -186,7 +186,7 @@ bool Entity::tick(double time)
 						Vec3<float> tmp = worldBoundingBox[i] + frameSpeed * xt;
 						if (tmp.y >= worldBoundingBoxFloor[i].y && tmp.y < worldBoundingBoxFloor[i].y + 1.f && tmp.z >= worldBoundingBoxFloor[i].z && tmp.z < worldBoundingBoxFloor[i].z + 1.f)
 						{
-							Block* b = currentGame->zBlockAt(Vec3<int>{ (int)worldBoundingBoxFloor[i].x - 1, (int)worldBoundingBoxFloor[i].y, (int)worldBoundingBoxFloor[i].z });
+							Block* b = World::INSTANCE->zBlockAt(Vec3<int>{ (int)worldBoundingBoxFloor[i].x - 1, (int)worldBoundingBoxFloor[i].y, (int)worldBoundingBoxFloor[i].z });
 							if (b) // TODO: ignore passable blocks
 							{
 								if (xt < tf)
@@ -221,7 +221,7 @@ bool Entity::tick(double time)
 						Vec3<float> tmp = worldBoundingBox[i] + frameSpeed * yt;
 						if (tmp.x >= worldBoundingBoxFloor[i].x && tmp.x < worldBoundingBoxFloor[i].x + 1.f && tmp.z >= worldBoundingBoxFloor[i].z && tmp.z < worldBoundingBoxFloor[i].z + 1.f)
 						{
-							Block* b = currentGame->zBlockAt(Vec3<int>{ (int)worldBoundingBoxFloor[i].x, (int)worldBoundingBoxFloor[i].y + 1, (int)worldBoundingBoxFloor[i].z });
+							Block* b = World::INSTANCE->zBlockAt(Vec3<int>{ (int)worldBoundingBoxFloor[i].x, (int)worldBoundingBoxFloor[i].y + 1, (int)worldBoundingBoxFloor[i].z });
 							if (b) // TODO: ignore passable blocks
 							{
 								if (yt < tf)
@@ -256,7 +256,7 @@ bool Entity::tick(double time)
 						Vec3<float> tmp = worldBoundingBox[i] + frameSpeed * yt;
 						if (tmp.x >= worldBoundingBoxFloor[i].x && tmp.x < worldBoundingBoxFloor[i].x + 1.f && tmp.z >= worldBoundingBoxFloor[i].z && tmp.z < worldBoundingBoxFloor[i].z + 1.f)
 						{
-							Block* b = currentGame->zBlockAt(Vec3<int>{ (int)worldBoundingBoxFloor[i].x, (int)worldBoundingBoxFloor[i].y - 1, (int)worldBoundingBoxFloor[i].z });
+							Block* b = World::INSTANCE->zBlockAt(Vec3<int>{ (int)worldBoundingBoxFloor[i].x, (int)worldBoundingBoxFloor[i].y - 1, (int)worldBoundingBoxFloor[i].z });
 							if (b) // TODO: ignore passable blocks
 							{
 								if (yt < tf)
@@ -291,7 +291,7 @@ bool Entity::tick(double time)
 						Vec3<float> tmp = worldBoundingBox[i] + frameSpeed * zt;
 						if (zt <= 1.f && tmp.x >= worldBoundingBoxFloor[i].x && tmp.x < worldBoundingBoxFloor[i].x + 1.f && tmp.y >= worldBoundingBoxFloor[i].y && tmp.y < worldBoundingBoxFloor[i].y + 1.f)
 						{
-							Block* b = currentGame->zBlockAt(Vec3<int>{ (int)worldBoundingBoxFloor[i].x, (int)worldBoundingBoxFloor[i].y, (int)worldBoundingBoxFloor[i].z + 1 });
+							Block* b = World::INSTANCE->zBlockAt(Vec3<int>{ (int)worldBoundingBoxFloor[i].x, (int)worldBoundingBoxFloor[i].y, (int)worldBoundingBoxFloor[i].z + 1 });
 							if (b) // TODO: ignore passable blocks
 							{
 								if (zt < tf)
@@ -325,7 +325,7 @@ bool Entity::tick(double time)
 						Vec3<float> tmp = worldBoundingBox[i] + frameSpeed * zt;
 						if (tmp.x >= worldBoundingBoxFloor[i].x && tmp.x < worldBoundingBoxFloor[i].x + 1.f && tmp.y >= worldBoundingBoxFloor[i].y && tmp.y < worldBoundingBoxFloor[i].y + 1)
 						{
-							Block* b = currentGame->zBlockAt(Vec3<int>{ (int)worldBoundingBoxFloor[i].x, (int)worldBoundingBoxFloor[i].y, (int)worldBoundingBoxFloor[i].z - 1 });
+							Block* b = World::INSTANCE->zBlockAt(Vec3<int>{ (int)worldBoundingBoxFloor[i].x, (int)worldBoundingBoxFloor[i].y, (int)worldBoundingBoxFloor[i].z - 1 });
 							if (b) // TODO: ignore passable blocks
 							{
 								if (zt < tf)
@@ -382,8 +382,8 @@ bool Entity::tick(double time)
 			break;
 		}
 		pos += frameSpeed;
-		currentGame->zKamera()->setPosition(pos + Vec3<float>(0.f, 0.f, 1.5f));
-		Model3D* target = currentGame->getCurrentTarget();
+		World::INSTANCE->zKamera()->setPosition(pos + Vec3<float>(0.f, 0.f, 1.5f));
+		Model3D* target = World::INSTANCE->getCurrentTarget();
 		Block* b = target ? dynamic_cast<Block*>(target) : 0;
 		((Game*)(Menu*)menuRegister->get("game"))->updatePosition(pos, b != 0, b ? b->getLocation() : Vec3<int>(0, 0, 0));
 		if(target)
@@ -397,7 +397,7 @@ bool Entity::tick(double time)
 				frame.targetPosition = lastPos;
 				frame.movementFlags = lastFlags;
 				frame.duration = timeSinceSync;
-				network->zFactoryClient()->sendPlayerMovement(frame);
+				World::INSTANCE->zClient()->sendPlayerMovement(frame);
 			}
 			lastFlags = flags;
 			lastDirection = direction;
@@ -462,5 +462,5 @@ void Entity::unlock()
 void Entity::setPlayerControlled()
 {
 	playerControlled = 1;
-	currentGame->zKamera()->setPosition(pos + Vec3<float>(0.f, 0.f, 1.5f));
+	World::INSTANCE->zKamera()->setPosition(pos + Vec3<float>(0.f, 0.f, 1.5f));
 }

+ 1 - 1
FactoryCraft/EntityRemovedUpdate.cpp

@@ -10,5 +10,5 @@ void EntityRemovedUpdateType::applyUpdate(Framework::StreamReader* zReader)
 {
 	int id;
 	zReader->lese((char*)&id, 4);
-	currentGame->removeEntity(id);
+	World::INSTANCE->removeEntity(id);
 }

+ 1 - 1
FactoryCraft/EntityType.cpp

@@ -31,7 +31,7 @@ Entity* EntityType::loadEntity(Framework::StreamReader* zReader) const
 	{
 		e = new Entity(this, model.getModel(), model.getTexture(), id, position, maxSpeed);
 	}
-	if (currentGame->zKamera()->getEntityId() == id)
+	if (World::INSTANCE->zKamera()->getEntityId() == id)
 	{
 		e->setPlayerControlled();
 	}

+ 139 - 52
FactoryCraft/FactoryClient.cpp

@@ -24,58 +24,8 @@ FactoryClient::~FactoryClient()
 		disconnect();
 }
 
-bool FactoryClient::connect(Text ip, short port, int accountId, Text secret)
+void FactoryClient::loadServerInfo()
 {
-	if (client)
-		disconnect();
-	client = new SSLKlient();
-	if (!client->verbinde(port, ip))
-		return false;
-	if (!client->sende("\1", 1))
-		return false;
-	if (!client->sende((char*)&accountId, 4))
-		return false;
-	unsigned char len = (unsigned char)secret.getLength();
-	if (!client->sende((char*)&len, 1))
-		return false;
-	if (!client->sende(secret, len))
-		return false;
-	char result = 0;
-	if (!client->getNachricht(&result, 1) || result != 1)
-		return false;
-	int keyLen;
-	if (!client->getNachricht((char*)&keyLen, 4))
-		return false;
-	char* key = new char[keyLen];
-	if (!client->getNachricht(key, keyLen))
-		return false;
-	int p;
-	if (!client->getNachricht((char*)&p, 4))
-		return false;
-	foreground = new Klient();
-	if (!foreground->verbinde(p, ip))
-		return false;
-	unsigned short l = (unsigned short)keyLen;
-	if (!foreground->sende((char*)&l, 2))
-		return false;
-	if (!foreground->sende(key, keyLen))
-		return false;
-	bool bg = 0;
-	if (!foreground->sende((char*)&bg, 1))
-		return false;
-	foregroundReader = new NetworkReader(foreground);
-	background = new Klient();
-	if (!background->verbinde(p, ip))
-		return false;
-	if (!background->sende((char*)&l, 2))
-		return false;
-	if (!background->sende(key, keyLen))
-		return false;
-	bg = 1;
-	if (!background->sende((char*)&bg, 1))
-		return false;
-	backgroundReader = new NetworkReader(background);
-	client->trenne();
 	// receive type information
 	for (int i = 0; i < blockTypeCount; i++)
 		blockTypes[i]->release();
@@ -146,7 +96,144 @@ bool FactoryClient::connect(Text ip, short port, int accountId, Text secret)
 	}
 	b->release();
 	kam->release();
-	return true;
+}
+
+bool FactoryClient::connect(Text ip, unsigned short sslPort)
+{
+	if (client)
+		disconnect();
+	client = new SSLKlient();
+	if (!client->verbinde(sslPort, ip))
+		return false;
+	this->ip = ip;
+	return 1;
+}
+
+int FactoryClient::ping()
+{
+	ZeitMesser zm;
+	zm.messungStart();
+	if (!client->sende("\3", 1))
+		return -1;
+	char c;
+	client->getNachricht(&c, 1);
+	zm.messungEnde();
+	return (int)(zm.getSekunden() * 1000);
+}
+
+int FactoryClient::status(Framework::Text name, Framework::Text secret)
+{
+	if (!client->sende("\4", 1))
+		return 404;
+	char c;
+	client->getNachricht(&c, 1);
+	if (c == 1)
+	{
+		char len = (char)name.getLength();
+		client->sende(&len, 1);
+		client->sende(name, len);
+		short sLen = (short)secret.getLength();
+		client->sende((char*)&sLen, 2);
+		client->sende(secret, sLen);
+		char res;
+		client->getNachricht(&res, 1);
+		if (res == 1)
+			return 200;
+		if (res == 0)
+			return 403;
+	}
+	return 404;
+}
+
+int FactoryClient::join(Framework::Text name, Framework::Text &secret, unsigned short port)
+{
+	client->sende("\1", 1);
+	char len = (char)name.getLength();
+	client->sende(&len, 1);
+	client->sende(name, len);
+	short sLen = (short)secret.getLength();
+	client->sende((char*)&sLen, 2);
+	client->sende(secret, sLen);
+	char res;
+	client->getNachricht(&res, 1);
+	if (res == 1 || res == 2)
+	{
+		if (res == 2)
+		{
+			client->getNachricht((char*)&sLen, 2);
+			char* buffer = new char[sLen + 1];
+			client->getNachricht(buffer, sLen);
+			buffer[sLen] = 0;
+			secret = buffer;
+			delete[] buffer;
+		}
+		int keyLen;
+		client->getNachricht((char*)&keyLen, 4);
+		char* key = new char[keyLen];
+		client->getNachricht(key, keyLen);
+		foreground = new Klient();
+		if (!foreground->verbinde(port, ip))
+		{
+			delete[] key;
+			return false;
+		}
+		if (!foreground->sende((char*)&keyLen, 2))
+		{
+			delete[] key;
+			return false;
+		}
+		if (!foreground->sende(key, keyLen))
+		{
+			delete[] key;
+			return false;
+		}
+		background = new Klient();
+		if (!background->verbinde(port, ip))
+		{
+			delete[] key;
+			foreground->release();
+			foreground = 0;
+			background->release();
+			background = 0;
+			return false;
+		}
+		if (!background->sende((char*)&keyLen, 2))
+		{
+			delete[] key;
+			foreground->release();
+			foreground = 0;
+			background->release();
+			background = 0;
+			return false;
+		}
+		if (!background->sende(key, keyLen))
+		{
+			delete[] key;
+			foreground->release();
+			foreground = 0;
+			background->release();
+			background = 0;
+			return false;
+		}
+		delete[] key;
+		bool bg = 0;
+		if (!foreground->sende((char*)&bg, 1))
+		{
+			delete[] key;
+			return 201;
+		}
+		foregroundReader = new NetworkReader(foreground);
+		bg = 1;
+		if (!background->sende((char*)&bg, 1))
+			return 201;
+		backgroundReader = new NetworkReader(background);
+		client->trenne();
+		loadServerInfo();
+		return 200;
+	}
+	if (res == 0)
+		return 403;
+	return 500;
 }
 
 void FactoryClient::disconnect()

+ 6 - 1
FactoryCraft/FactoryClient.h

@@ -20,16 +20,21 @@ private:
 	Network::NetworkReader* foregroundReader;
 	Network::NetworkReader* backgroundReader;
 	Framework::Critical cs;
+	Framework::Text ip;
 	int bgReaderUsage;
 	int fgReaderUsage;
 
 	void disconnect();
+	void loadServerInfo();
 
 public:
 	FactoryClient();
 	~FactoryClient();
 
-	bool connect(Text ip, short port, int accountId, Text secret);
+	bool connect(Framework::Text ip, unsigned short sslPort);
+	int ping();
+	int status(Framework::Text name, Framework::Text secret);
+	int join(Framework::Text name, Framework::Text &secret, unsigned short port);
 	Network::NetworkReader* getNextForegroundMessage();
 	Network::NetworkReader* getNextBackgroundMessage();
 	void endMessageReading(bool bg);

+ 4 - 6
FactoryCraft/FactoryCraft.vcxproj

@@ -179,7 +179,7 @@ copy "..\..\..\..\..\Allgemein\Network\x64\Release\Network.dll" "network.dll"</C
     <ClCompile Include="CustomDX11API.cpp" />
     <ClCompile Include="Dialog.cpp" />
     <ClCompile Include="Dimension.cpp" />
-    <ClCompile Include="DirectConnect.cpp" />
+    <ClCompile Include="AddServerMenu.cpp" />
     <ClCompile Include="DragElement.cpp" />
     <ClCompile Include="Entity.cpp" />
     <ClCompile Include="EntityRemovedUpdate.cpp" />
@@ -193,11 +193,10 @@ copy "..\..\..\..\..\Allgemein\Network\x64\Release\Network.dll" "network.dll"</C
     <ClCompile Include="ItemBar.cpp" />
     <ClCompile Include="ItemType.cpp" />
     <ClCompile Include="Load.cpp" />
-    <ClCompile Include="Login.cpp" />
+    <ClCompile Include="ServerSelection.cpp" />
     <ClCompile Include="Main.cpp" />
     <ClCompile Include="Menu.cpp" />
     <ClCompile Include="ModelInfo.cpp" />
-    <ClCompile Include="NetworkHandler.cpp" />
     <ClCompile Include="PlayerKam.cpp" />
     <ClCompile Include="StaticInitializerOrder.cpp" />
     <ClCompile Include="UIMLToolTip.cpp" />
@@ -215,7 +214,7 @@ copy "..\..\..\..\..\Allgemein\Network\x64\Release\Network.dll" "network.dll"</C
     <ClInclude Include="CustomDX11API.h" />
     <ClInclude Include="Dialog.h" />
     <ClInclude Include="Dimension.h" />
-    <ClInclude Include="DirectConnect.h" />
+    <ClInclude Include="AddServerMenu.h" />
     <ClInclude Include="DragController.h" />
     <ClInclude Include="DragElement.h" />
     <ClInclude Include="Entity.h" />
@@ -230,10 +229,9 @@ copy "..\..\..\..\..\Allgemein\Network\x64\Release\Network.dll" "network.dll"</C
     <ClInclude Include="ItemBar.h" />
     <ClInclude Include="ItemType.h" />
     <ClInclude Include="Load.h" />
-    <ClInclude Include="Login.h" />
+    <ClInclude Include="ServerSelection.h" />
     <ClInclude Include="Menu.h" />
     <ClInclude Include="ModelInfo.h" />
-    <ClInclude Include="NetworkHandler.h" />
     <ClInclude Include="PlayerKam.h" />
     <ClInclude Include="Registries.h" />
     <ClInclude Include="StaticRegistry.h" />

+ 4 - 10
FactoryCraft/FactoryCraft.vcxproj.filters

@@ -94,10 +94,10 @@
     <ClCompile Include="Game.cpp">
       <Filter>Menu</Filter>
     </ClCompile>
-    <ClCompile Include="Login.cpp">
+    <ClCompile Include="ServerSelection.cpp">
       <Filter>Menu</Filter>
     </ClCompile>
-    <ClCompile Include="DirectConnect.cpp">
+    <ClCompile Include="AddServerMenu.cpp">
       <Filter>Menu</Filter>
     </ClCompile>
     <ClCompile Include="Menu.cpp">
@@ -106,9 +106,6 @@
     <ClCompile Include="FactoryClient.cpp">
       <Filter>Network</Filter>
     </ClCompile>
-    <ClCompile Include="NetworkHandler.cpp">
-      <Filter>Network</Filter>
-    </ClCompile>
     <ClCompile Include="Load.cpp">
       <Filter>Menu</Filter>
     </ClCompile>
@@ -195,7 +192,7 @@
     <ClInclude Include="Load.h">
       <Filter>Menu</Filter>
     </ClInclude>
-    <ClInclude Include="Login.h">
+    <ClInclude Include="ServerSelection.h">
       <Filter>Menu</Filter>
     </ClInclude>
     <ClInclude Include="Menu.h">
@@ -204,12 +201,9 @@
     <ClInclude Include="Game.h">
       <Filter>Menu</Filter>
     </ClInclude>
-    <ClInclude Include="DirectConnect.h">
+    <ClInclude Include="AddServerMenu.h">
       <Filter>Menu</Filter>
     </ClInclude>
-    <ClInclude Include="NetworkHandler.h">
-      <Filter>Network</Filter>
-    </ClInclude>
     <ClInclude Include="FactoryClient.h">
       <Filter>Network</Filter>
     </ClInclude>

+ 9 - 8
FactoryCraft/Game.cpp

@@ -18,15 +18,16 @@ Game::Game(Bildschirm* zScreen)
 				logout->removeStyle(Knopf::Style::Erlaubt);
 				new AsynchronCall([this, zScreen]()
 					{
-						if (network->leaveGame())
+						// TODO
+						/*if (World::INSTANCE->zClient()->leaveGame())
 						{
-							currentGame->release();
-							currentGame = 0;
+							World::INSTANCE->release();
+							World::INSTANCE = 0;
 							zScreen->lock();
 							hide();
 							menuRegister->get("directConnect")->show();
 							zScreen->unlock();
-						}
+						}*/ 
 						logout->addStyle(Knopf::Style::Erlaubt);
 					});
 			}
@@ -66,7 +67,7 @@ void Game::updatePosition(Vec3<float> position, bool target, Vec3<int> targetPos
 		txt += ", ";
 		txt += targetPos.z;
 		txt += ")\n";
-		Block* b = currentGame->zBlockAt(targetPos);
+		Block* b = World::INSTANCE->zBlockAt(targetPos);
 		if (b)
 		{
 			txt += "TargetLight: \n";
@@ -113,7 +114,7 @@ void Game::api(char* data)
 								{
 									dialogs.remove(index);
 									window->zBildschirm()->removeMember(d);
-									currentGame->zKamera()->setControlEnabled(dialogs.getEintragAnzahl() == 0);
+									World::INSTANCE->zKamera()->setControlEnabled(dialogs.getEintragAnzahl() == 0);
 									break;
 								}
 								index++;
@@ -121,7 +122,7 @@ void Game::api(char* data)
 						});
 				});
 			dialogs.add(dialog);
-			currentGame->zKamera()->setControlEnabled(0);
+			World::INSTANCE->zKamera()->setControlEnabled(0);
 			window->zBildschirm()->addMember(dialog);
 			delete[]uiml;
 		}
@@ -163,7 +164,7 @@ void Game::closeCurrentDialog()
 		UIMLDialog* d = dialogs.get(dialogs.getEintragAnzahl() - 1);
 		window->zBildschirm()->removeMember(d);
 		dialogs.remove(dialogs.getEintragAnzahl() - 1);
-		currentGame->zKamera()->setControlEnabled(dialogs.getEintragAnzahl() == 0);
+		World::INSTANCE->zKamera()->setControlEnabled(dialogs.getEintragAnzahl() == 0);
 	}
 }
 

+ 6 - 9
FactoryCraft/Globals.cpp

@@ -1,8 +1,8 @@
 #define variable
 #include <Text.h>
 #include "Globals.h"
-#include "Login.h"
-#include "DirectConnect.h"
+#include "ServerSelection.h"
+#include "AddServerMenu.h"
 #include "Game.h"
 #include "Load.h"
 
@@ -18,8 +18,6 @@ void initVariables()
 		{
 			return txt.hashCode();
 		});
-	network = new NetworkHandler();
-	currentGame = 0;
 	window = 0;
 	itemIcons = new RCArray<Bild>();
 	blockTypes = 0;
@@ -33,8 +31,8 @@ void initVariables()
 void initMenus()
 {
 	menuRegister->put("load", RCPointer<Menu>::of(new LoadMenu(uiFactory.initParam.bildschirm)));
-	menuRegister->put("login", RCPointer<Menu>::of(new LoginMenu(uiFactory.initParam.bildschirm)));
-	menuRegister->put("directConnect", RCPointer<Menu>::of(new DirectConnect(uiFactory.initParam.bildschirm)));
+	menuRegister->put("serverSelection", RCPointer<Menu>::of(new ServerSelectionMenu(uiFactory.initParam.bildschirm)));
+	menuRegister->put("addServer", RCPointer<Menu>::of(new AddServerMenu(uiFactory.initParam.bildschirm)));
 	menuRegister->put("game", RCPointer<Menu>::of(new Game(uiFactory.initParam.bildschirm)));
 
 	menuRegister->get("load")->show();
@@ -42,11 +40,10 @@ void initMenus()
 
 void releaseVariables()
 {
-	if (currentGame)
-		currentGame->release();
+	if (World::INSTANCE)
+		World::INSTANCE->release();
 	menuRegister->release();
 	fontRegister->release();
-	network->release();
 	dlls->release();
 	itemIcons->release();
 	for (int i = 0; i < blockTypeCount; i++)

+ 0 - 3
FactoryCraft/Globals.h

@@ -9,7 +9,6 @@
 #include <Fenster.h>
 
 #include "Menu.h"
-#include "NetworkHandler.h"
 #include "World.h"
 
 #ifndef variable
@@ -19,9 +18,7 @@
 variable Framework::HashMap<Framework::Text, Framework::RCPointer<Menu>>* menuRegister;
 variable UIInit uiFactory;
 variable Framework::HashMap<Framework::Text, Framework::RCPointer<Schrift>>* fontRegister;
-variable NetworkHandler* network;
 variable DLLRegister* dlls;
-variable World* currentGame;
 variable Framework::WFenster* window;
 variable RCArray<Bild>* itemIcons;
 variable BlockType** blockTypes;

+ 11 - 1
FactoryCraft/Initialisierung.cpp

@@ -15,6 +15,12 @@ Knopf* initKnopf(int x, int y, int br, int h
 	ret->setPosition(x, y);
 	ret->setSize(br, hö);
 	ret->setText(titel);
+	ret->setHintergrundFarbe(0xFF000000);
+	ret->setRahmenFarbe(0xFF2E6DA4);
+	ret->setSchriftFarbe(0xFFFFFFFF);
+	ret->setRahmenBreite(1);
+	ret->setAlphaFeldStrength(10);
+	ret->setAlphaFeldFarbe(0xFF337AB7);
 	return ret;
 }
 
@@ -45,10 +51,14 @@ Fenster* initFenster(int x, int y, int br, int h
 TextFeld* initTextFeld(int x, int y, int br, int hö, __int64 style, char* txt)
 {
 	TextFeld* ret = uiFactory.createTextFeld(uiFactory.initParam);
-	ret->addStyle(style);
+	ret->setStyle(style);
 	ret->setText(txt);
 	ret->setPosition(x, y);
 	ret->setSize(br, hö);
+	ret->setRahmenFarbe(0xFF6d6d6d);
+	ret->setHintergrundFarbe(0xFF000000);
+	ret->setAlphaFeldFarbe(0xFF3d3d3d);
+	ret->setAlphaFeldStrength(10);
 	return ret;
 }
 

+ 4 - 4
FactoryCraft/InventoryView.cpp

@@ -98,7 +98,7 @@ InventoryView::InventoryView(Text id, Either<int, VecN<int, 4>> target, int rowS
 	memcpy(msg + 2, id.getText(), id.getLength());
 	msg[2 + id.getLength()] = (char)slotNameFilter.getLength();
 	memcpy(msg + 3 + id.getLength(), slotNameFilter.getText(), slotNameFilter.getLength());
-	network->zFactoryClient()->inventoryAPIRequest(target, msg, id.getLength() + slotNameFilter.getLength() + 3);
+	World::INSTANCE->zClient()->inventoryAPIRequest(target, msg, id.getLength() + slotNameFilter.getLength() + 3);
 	delete[] msg;
 	setNeedToolTipEvent([this](Zeichnung* z, Punkt p)
 		{
@@ -118,7 +118,7 @@ InventoryView::InventoryView(Text id, Either<int, VecN<int, 4>> target, int rowS
 				msg[1] = (char)this->id.getLength();
 				memcpy(msg + 2, this->id.getText(), this->id.getLength());
 				*(int*)(msg + 2 + this->id.getLength()) = slot;
-				network->zFactoryClient()->inventoryAPIRequest(this->target, msg, this->id.getLength() + 6);
+				World::INSTANCE->zClient()->inventoryAPIRequest(this->target, msg, this->id.getLength() + 6);
 			}
 		});
 }
@@ -134,7 +134,7 @@ InventoryView::~InventoryView()
 	msg[0] = 1;
 	msg[1] = (char)id.getLength();
 	memcpy(msg + 2, id.getText(), id.getLength());
-	network->zFactoryClient()->inventoryAPIRequest(target, msg, id.getLength() + 2);
+	World::INSTANCE->zClient()->inventoryAPIRequest(target, msg, id.getLength() + 2);
 	delete[] msg;
 }
 
@@ -365,7 +365,7 @@ void InventoryView::doMausEreignis(MausEreignis& me, bool userRet)
 						index += 16;
 					}
 					*(int*)(msg + index) = info.id;
-					network->zFactoryClient()->sendPlayerAction(msg, len);
+					World::INSTANCE->zClient()->sendPlayerAction(msg, len);
 					delete[] msg;
 				}
 			}

+ 2 - 2
FactoryCraft/ItemBar.cpp

@@ -44,7 +44,7 @@ ItemBarView::ItemBarView(Framework::Text id, int rowSize, int targetEntity, Fram
 	memcpy(msg + 2, id.getText(), id.getLength());
 	msg[2 + id.getLength()] = (char)slotNameFilter.getLength();
 	memcpy(msg + 3 + id.getLength(), slotNameFilter.getText(), slotNameFilter.getLength());
-	network->zFactoryClient()->inventoryAPIRequest(targetEntity, msg, id.getLength() + slotNameFilter.getLength() + 3);
+	World::INSTANCE->zClient()->inventoryAPIRequest(targetEntity, msg, id.getLength() + slotNameFilter.getLength() + 3);
 	delete[] msg;
 }
 
@@ -57,7 +57,7 @@ ItemBarView::~ItemBarView()
 	msg[1] = (char)id.getLength();
 	memcpy(msg + 2, id.getText(), id.getLength());
 	msg[2 + id.getLength()] = (char)slotNameFilter.getLength();
-	network->zFactoryClient()->inventoryAPIRequest(targetEntity, msg, id.getLength() + 2);
+	World::INSTANCE->zClient()->inventoryAPIRequest(targetEntity, msg, id.getLength() + 2);
 	delete[] msg;
 }
 

+ 6 - 6
FactoryCraft/Load.cpp

@@ -10,7 +10,7 @@
 #include "Load.h"
 #include "Initialisierung.h"
 #include "Globals.h"
-#include "Login.h"
+#include "ServerSelection.h"
 
 void createDefaultCube(Bildschirm* zScreen)
 {
@@ -466,9 +466,10 @@ void createModels(Bildschirm* zScreen)
 LoadMenu::LoadMenu(Bildschirm* zScreen)
 	: Menu(zScreen)
 {
-	step = initFBalken(10, 90, 200, 30, FBalken::Style::normal);
-	stage = initFBalken(10, 50, 200, 30, FBalken::Style::normal);
-	all = initFBalken(10, 10, 200, 30, FBalken::Style::normal);
+	Punkt center = zScreen->getBackBufferSize() / 2;
+	step = initFBalken(center.x - 100, center.y + 25, 200, 30, FBalken::Style::normal);
+	stage = initFBalken(center.x - 100, center.y - 15, 200, 30, FBalken::Style::normal);
+	all = initFBalken(center.x - 100, center.y - 55, 200, 30, FBalken::Style::normal);
 	elements.add(step);
 	elements.add(stage);
 	elements.add(all);
@@ -546,8 +547,7 @@ LoadMenu::LoadMenu(Bildschirm* zScreen)
 			stage->reset();
 			zScreen->lock();
 			hide();
-			((LoginMenu*)(Menu*)menuRegister->get("login"))->onLoadingFinished();
-			menuRegister->get("login")->show();
+			menuRegister->get("serverSelection")->show();
 			zScreen->unlock();
 		});
 }

+ 0 - 38
FactoryCraft/Login.cpp

@@ -1,38 +0,0 @@
-#include "Login.h"
-#include "Initialisierung.h"
-#include "Globals.h"
-
-LoginMenu::LoginMenu(Bildschirm* zScreen)
-	: Menu(zScreen)
-{
-	elements.add(initTextFeld(10, 10, 90, 20, TextFeld::Style::Text, "Name: "));
-	elements.add(initTextFeld(10, 35, 90, 20, TextFeld::Style::Text, "Passwort: "));
-	name = initTextFeld(100, 10, 200, 20, TextFeld::Style::TextFeld, "Kolja");
-	password = initTextFeld(100, 35, 200, 20, TextFeld::Style::TextFeld, "1rg3ndw13");
-	password->setSchowChar('*');
-	elements.add(name);
-	elements.add(password);
-	Knopf* login = initKnopf(200, 60, 100, 20, Knopf::Style::Normal, "Login");
-	login->setMausEreignis([this, login](void* p, void* o, MausEreignis me)
-		{
-			if (me.id == ME_RLinks)
-			{
-				login->removeStyle(Knopf::Style::Erlaubt);
-				name->removeStyle(TextFeld::Style::Erlaubt);
-				password->removeStyle(TextFeld::Style::Erlaubt);
-				if (network->login(name->zText()->getText(), password->zText()->getText()))
-				{
-					hide();
-					menuRegister->get("directConnect")->show();
-				}
-				name->addStyle(TextFeld::Style::Erlaubt);
-				password->addStyle(TextFeld::Style::Erlaubt);
-				login->addStyle(Knopf::Style::Erlaubt);
-			}
-			return 1;
-		});
-	elements.add(login);
-}
-
-void LoginMenu::onLoadingFinished()
-{}

+ 0 - 16
FactoryCraft/Login.h

@@ -1,16 +0,0 @@
-#pragma once
-
-#include <TextFeld.h>
-
-#include "Menu.h"
-
-class LoginMenu : public Menu
-{
-private:
-	TextFeld* name;
-	TextFeld* password;
-
-public:
-	LoginMenu(Bildschirm* zScreen);
-	void onLoadingFinished();
-};

+ 0 - 129
FactoryCraft/NetworkHandler.cpp

@@ -1,129 +0,0 @@
-#include <InitDatei.h>
-
-#include "NetworkHandler.h"
-#include "Globals.h"
-
-NetworkHandler::NetworkHandler()
-	: ReferenceCounter()
-{
-	HINSTANCE dll = dlls->ladeDLL("KSGClient", "data/bin/KSGNetwork.dll");
-	if (!dll)
-		throw "DLL not found: 'data/bin/KSGNetwork.dll'";
-	KSGClient::KSGNetworkCreateMain getMainClient = (KSGClient::KSGNetworkCreateMain)GetProcAddress(dll, KSGNETWORK_CREATE_MAIN);
-	if (!getMainClient)
-		throw "Entry point '" KSGNETWORK_CREATE_MAIN "' not found in DLL 'data/bin/KSGNetwork.dll'";
-	msc = getMainClient();
-	if (!msc)
-		throw "Could not create Main Server Client from DLL 'data/bin/KSGNetwork.dll'";
-	InitDatei* iDat = new InitDatei("data/optionen.ini");
-	iDat->laden();
-	if (!iDat->zWert("ServerIP"))
-		iDat->addWert("ServerIP", "127.0.0.1");
-	if (!iDat->zWert("ServerPort"))
-		iDat->addWert("ServerPort", "4225");
-	iDat->speichern();
-	Text* ipT = iDat->zWert("ServerIP");
-	unsigned short port = (unsigned short)TextZuInt(iDat->zWert("ServerPort")->getText(), 10);
-	esc = 0;
-	if (msc->registerSSL(ipT->getText(), port))
-	{
-		//esc = msc->createErhaltungServerClient();
-		//esc->verbinde();
-	}
-	iDat->release();
-	fc = 0;
-	lsc = 0;
-	gsc = 0;
-}
-
-NetworkHandler::~NetworkHandler()
-{
-	if (gsc)
-	{
-		gsc->release();
-		gsc = 0;
-	}
-	if (fc)
-		fc->release();
-	if (esc)
-	{
-		esc->abmelden();
-		esc->release();
-	}
-	if (lsc)
-	{
-		lsc->verbinde();
-		lsc->logout();
-		lsc->trenne(1);
-		lsc->release();
-	}
-	if (msc)
-	{
-		msc->unregister();
-		msc->release();
-	}
-}
-
-bool NetworkHandler::login(Framework::Text name, Framework::Text password)
-{
-	if (!lsc)
-		lsc = msc->createLoginServerClient();
-	else
-	{
-		if (gsc)
-		{
-			gsc->release();
-			gsc = 0;
-		}
-		lsc->logout();
-	}
-	if (!lsc)
-		return 0;
-	lsc->verbinde();
-	bool ok = lsc->login(name, password);
-	lsc->trenne(ok);
-	if (ok)
-	{
-		accountId = lsc->getAccountId();
-		lsc->release();
-		lsc = 0;
-	}
-	return ok;
-}
-
-bool NetworkHandler::connect(Text ip, short port)
-{
-	if (!gsc)
-		gsc = msc->createMinigameServerClient();
-	if (!gsc)
-	{
-		std::cout << "could not create minigame server client.\n";
-		return 0;
-	}
-	Text* secret = gsc->getSecret();
-	if (!secret)
-	{
-		std::cout << "could not get secret from minigame server.\n";
-		return 0;
-	}
-	if (!fc)
-		fc = new FactoryClient();
-	bool ok = fc->connect(ip, port, accountId, *secret);
-	secret->release();
-	return ok;
-}
-
-FactoryClient* NetworkHandler::zFactoryClient() const
-{
-	return fc;
-}
-
-bool NetworkHandler::leaveGame()
-{
-	if (fc)
-	{
-		fc->release();
-		fc = 0;
-	}
-	return 1;
-}

+ 0 - 25
FactoryCraft/NetworkHandler.h

@@ -1,25 +0,0 @@
-#pragma once
-
-#include <ReferenceCounter.h>
-#include "KSGNetwork.h"
-#include "FactoryClient.h"
-
-class NetworkHandler : public virtual Framework::ReferenceCounter
-{
-private:
-	KSGClient::MainServerClient* msc;
-	KSGClient::LoginServerClient* lsc;
-	KSGClient::MinigameServerClient* gsc;
-	KSGClient::ErhaltungServerClient* esc;
-	FactoryClient* fc;
-	int accountId;
-
-public:
-	NetworkHandler();
-	~NetworkHandler();
-
-	bool login(Framework::Text name, Framework::Text password);
-	bool connect(Text ip, short port);
-	FactoryClient* zFactoryClient() const;
-	bool leaveGame();
-};

+ 10 - 10
FactoryCraft/PlayerKam.cpp

@@ -28,19 +28,19 @@ void PlayerKam::doTastaturEreignis(Framework::TastaturEreignis& te)
 {
 	if (te.id == TE_Press)
 	{
-		if (te.taste >= '0' && te.taste <= '9')
+		if (te.taste[0] >= '0' && te.taste[0] <= '9')
 		{
 			char action[5];
 			action[0] = 3;
-			*(int*)(action + 1) = te.taste - '1';
+			*(int*)(action + 1) = te.taste[0] - '1';
 			if (*(int*)(action + 1) < 0)
 				*(int*)(action + 1) = 9;
-			network->zFactoryClient()->sendPlayerAction(action, 5);
+			World::INSTANCE->zClient()->sendPlayerAction(action, 5);
 		}
 	}
 	if (te.id == TE_Release)
 	{
-		if (te.taste == T_Esc)
+		if (te.virtualKey == T_Esc)
 		{
 			bool oldControl = kameraControll;
 			kameraControll = 0;
@@ -48,10 +48,10 @@ void PlayerKam::doTastaturEreignis(Framework::TastaturEreignis& te)
 			if (!oldControl)
 				((Game*)(Menu*)menuRegister->get("game"))->closeCurrentDialog();
 		}
-		if (te.taste == T_Tab)
+		if (te.virtualKey == T_Tab)
 		{
 			char action = 4;
-			network->zFactoryClient()->sendPlayerAction(&action, 1);
+			World::INSTANCE->zClient()->sendPlayerAction(&action, 1);
 		}
 	}
 }
@@ -77,22 +77,22 @@ void PlayerKam::doMausEreignis(Framework::MausEreignis& me)
 				if (me.id == ME_PLinks)
 				{
 					char action[2] = { 1, 8 };
-					network->zFactoryClient()->sendPlayerAction(action, 2);
+					World::INSTANCE->zClient()->sendPlayerAction(action, 2);
 				}
 				if (me.id == ME_RLinks)
 				{
 					char action[2] = { 0, 8 };
-					network->zFactoryClient()->sendPlayerAction(action, 2);
+					World::INSTANCE->zClient()->sendPlayerAction(action, 2);
 				}
 				if (me.id == ME_PRechts)
 				{
 					char action[2] = { 1, 9 };
-					network->zFactoryClient()->sendPlayerAction(action, 2);
+					World::INSTANCE->zClient()->sendPlayerAction(action, 2);
 				}
 				if (me.id == ME_RRechts)
 				{
 					char action[2] = { 0, 9 };
-					network->zFactoryClient()->sendPlayerAction(action, 2);
+					World::INSTANCE->zClient()->sendPlayerAction(action, 2);
 				}
 			}
 

+ 438 - 0
FactoryCraft/ServerSelection.cpp

@@ -0,0 +1,438 @@
+#include <AsynchronCall.h>
+#include <Schrift.h>
+#include <Bild.h>
+#include <AlphaFeld.h>
+#include <Knopf.h>
+#include <Datei.h>
+#include <JSON.h>
+#include <Base64.h>
+
+#include "ServerSelection.h"
+#include "FactoryClient.h"
+#include "Globals.h"
+#include "Initialisierung.h"
+
+using namespace Framework;
+
+ServerStatus::ServerStatus(Framework::Text name, Framework::Text ip, unsigned short sslPort,  unsigned short port, Framework::HashMap<Framework::Text, Framework::Text>* secrets)
+	: ZeichnungHintergrund(),
+	name(name),
+	ip(ip),
+	sslPort(sslPort),
+	port(port),
+	playerName(""),
+	ping(-1),
+	status("..."),
+	requestId(0),
+	secrets(secrets),
+	closeAF(new AlphaFeld()),
+	join(initKnopf(0, 0, 55, 20, Knopf::Style::Normal, "join"))
+{
+	closeAF->setSize(20, 20);
+	closeAF->setFarbe(0x00FF0000);
+	setMausEreignis(_ret1ME);
+	setStyle(Style::Erlaubt | Style::Sichtbar | Style::Rahmen);
+	setRahmenBreite(1);
+	setRahmenFarbe(0xFF3d3d3d);
+	join->setMausEreignis([this](void* p, void* o, MausEreignis me)
+		{
+			if (me.id == ME_RLinks)
+			{
+				FactoryClient* client = new FactoryClient();
+				if (!client->connect(getIp(), getSSLPort()))
+				{
+					lockZeichnung();
+					status = "The Server is currently not reachable";
+					statusId = 404;
+					ping = -1;
+					rend = 1;
+					unlockZeichnung();
+					client->release();
+				}
+				else
+				{
+					Text secret = "";
+					if (this->secrets->has(playerName))
+						secret = this->secrets->get(playerName);
+					bool isNew = secret.getLength() == 0;
+					int stId = client->join(playerName, secret, getPort());
+					lockZeichnung();
+					statusId = stId;
+					if (statusId == 403)
+						status = "The name is already in use";
+					if (statusId == 500)
+						status = "Unknown Server message received";
+					if (statusId == 201)
+						status = "Please try again";
+					unlockZeichnung();
+					if (statusId == 200 || statusId == 201)
+					{
+						if(statusId == 200)
+							((ServerSelectionMenu*)(Menu*)menuRegister->get("serverSelection"))->hide();
+						if (isNew)
+						{
+							this->secrets->put(playerName, secret);
+							((ServerSelectionMenu*)(Menu*)menuRegister->get("serverSelection"))->saveServers();
+						}
+						if (statusId == 200)
+						{
+							World::INSTANCE = new World(dynamic_cast<Bildschirm3D*>(window->zBildschirm()), client);
+							((ServerSelectionMenu*)(Menu*)menuRegister->get("game"))->show();
+						}
+					}
+					else
+						client->release();
+				}
+			}
+			return 1;
+		});
+}
+
+ServerStatus::~ServerStatus()
+{
+	secrets->release();
+	closeAF->release();
+	join->release();
+}
+
+void ServerStatus::updatePlayerName(Framework::Text playerName)
+{
+	lockZeichnung();
+	status = "";
+	this->playerName = playerName;
+	ServerStatus* tmp = dynamic_cast<ServerStatus*>(getThis());
+	int id = ++requestId;
+	unlockZeichnung();
+	new AsynchronCall([tmp, id]()
+		{
+			FactoryClient* client = new FactoryClient();
+			if (!client->connect(tmp->getIp(), tmp->getSSLPort()))
+			{
+				tmp->lockZeichnung();
+				if (tmp->requestId == id)
+				{
+					tmp->status = "The Server is currently not reachable";
+					tmp->statusId = 404;
+					tmp->ping = -1;
+					tmp->rend = 1;
+				}
+				tmp->unlockZeichnung();
+			}
+			else
+			{
+				tmp->lockZeichnung();
+				if (tmp->requestId == id)
+				{
+					Text secret = "";
+					if (tmp->secrets->has(tmp->playerName))
+						secret = tmp->secrets->get(tmp->playerName);
+					tmp->unlockZeichnung();
+					int ping = client->ping();
+					int statusId = client->status(tmp->playerName, secret);
+					tmp->lockZeichnung();
+					if (tmp->requestId == id)
+					{
+						tmp->ping = ping;
+						tmp->statusId = statusId;
+						if (tmp->statusId == 200)
+							tmp->status = "The Server is reachable";
+						if (tmp->statusId == 403)
+							tmp->status = "The name is already in use";
+						tmp->rend = 1;
+					}
+				}
+				tmp->unlockZeichnung();
+			}
+			client->release();
+			tmp->release();
+		});
+}
+
+void ServerStatus::doMausEreignis(Framework::MausEreignis& me, bool userRet)
+{
+	if (me.id == ME_Leaves)
+	{
+		closeAF->setStrength(0);
+		closeAF->setFarbe(0x00FF0000);
+	}
+	else if (me.id == ME_Bewegung)
+	{
+		if (me.mx >= gr.x - 20 && me.mx < gr.x && me.my >= 0 && me.my <= 20)
+		{
+			if (closeAF->getStrength() == 0)
+			{
+				closeAF->setStrength(-5);
+				closeAF->setFarbe(0x30FF0000);
+			}
+		}
+		else
+		{
+			if (closeAF->getStrength() != 0)
+			{
+				closeAF->setStrength(0);
+				closeAF->setFarbe(0x00FF0000);
+			}
+		}
+	}
+	if (me.id == ME_RLinks)
+	{
+		if (me.mx >= gr.x - 20 && me.mx < gr.x && me.my >= 0 && me.my <= 20)
+		{
+			((ServerSelectionMenu*)(Menu*)menuRegister->get("serverSelection"))->removeServer(name);
+			return;
+		}
+	}
+	if (canConnect())
+		join->doPublicMausEreignis(me);
+}
+
+bool ServerStatus::tick(double time)
+{
+	join->setPosition(gr.x - 60, gr.y - 25);
+	closeAF->setPosition(gr.x - 20, 0);
+	return ZeichnungHintergrund::tick(time) || join->tick(time) || closeAF->tick(time);
+}
+
+void ServerStatus::render(Framework::Bild& rObj)
+{
+	ZeichnungHintergrund::render(rObj);
+	if (rObj.setDrawOptions(pos, gr))
+	{
+		TextRenderer tr(dynamic_cast<Schrift*>(uiFactory.initParam.schrift->getThis()));
+		tr.setSchriftSize(12);
+		tr.renderText(5, 5, name, rObj, 0xFFFFFFFF);
+		tr.renderText(5, 25, ip + ":" + sslPort + " (" + port + ")", rObj, 0xFF808080);
+		if (requestId && requestId != 404)
+		{
+			int tbr = tr.getTextBreite(Text("ping: ") + ping);
+			if (ping >= 0)
+			{
+				tr.renderText(getBreite() - 25 - tbr, 5, Text("ping: ") + ping, rObj, 0xFFFFFFFF);
+			}
+		}
+		if (statusId == 404 || statusId == 500)
+			tr.renderText(5, 45, status, rObj, 0xFFFF0000);
+		if (statusId == 403 || statusId == 201)
+			tr.renderText(5, 45, status, rObj, 0xFFFFA500);
+		if (statusId == 200)
+			tr.renderText(5, 45, status, rObj, 0xFF00FF00);
+		closeAF->render(rObj);
+		rObj.drawLinie(Punkt(gr.x - 20, 0), Punkt(gr.x, 20), 0xFFFF0000);
+		rObj.drawLinie(Punkt(gr.x - 20, 20), Punkt(gr.x, 0), 0xFFFF0000);
+		if (canConnect())
+			join->render(rObj);
+		rObj.releaseDrawOptions();
+	}
+}
+
+Framework::Text ServerStatus::getName() const
+{
+	return name;
+}
+
+Framework::Text ServerStatus::getIp() const
+{
+	return ip;
+}
+
+unsigned short ServerStatus::getSSLPort() const
+{
+	return sslPort;
+}
+
+unsigned short ServerStatus::getPort() const
+{
+	return port;
+}
+
+Framework::HashMap<Framework::Text, Framework::Text>* ServerStatus::zSecrets() const
+{
+	return secrets;
+}
+
+bool ServerStatus::canConnect() const
+{
+	return statusId == 200 || statusId == 201;
+}
+
+
+ServerSelectionMenu::ServerSelectionMenu(Bildschirm* zScreen)
+	: Menu(zScreen)
+{
+	playerNameLabel = initTextFeld(zScreen->getBackBufferSize().x / 2 - 150, zScreen->getBackBufferSize().y / 2 - 300, 85, 20, TextFeld::Style::Text | TextFeld::Style::VCenter, "Player Name:");
+	elements.add(playerNameLabel);
+	playerName = initTextFeld(zScreen->getBackBufferSize().x / 2 - 150 + 85, zScreen->getBackBufferSize().y / 2 - 300, 215, 20, TextFeld::Style::TextFeld, "");
+	playerName->setNTastaturEreignis([this](void* p, void* o, TastaturEreignis te)
+		{
+			// set player names of each server
+			for (int i = 0; i < serverList->getEintragAnzahl(); i++)
+				((ServerStatus*)serverList->zEintrag(i))->updatePlayerName(playerName->zText()->getText());
+			saveServers();
+			return 1;
+		});
+	elements.add(playerName);
+	serverLabel = initTextFeld(zScreen->getBackBufferSize().x / 2 - 150, zScreen->getBackBufferSize().y / 2 - 275, 100, 20, TextFeld::Style::Text | TextFeld::Style::VCenter, "Server:");
+	elements.add(serverLabel);
+	refresh = initKnopf(zScreen->getBackBufferSize().x / 2 + 80, zScreen->getBackBufferSize().y / 2 - 275, 70, 20, Knopf::Style::Normal, "Refresh");
+	refresh->setMausEreignis([this](void* p, void* o, Framework::MausEreignis me)
+		{
+			if (me.id == ME_RLinks)
+			{
+				if (playerName->zText()->getLength() > 0)
+				{
+					for (int i = 0; i < serverList->getEintragAnzahl(); i++)
+						((ServerStatus*)serverList->zEintrag(i))->updatePlayerName(playerName->zText()->getText());
+				}
+			}
+			return 1;
+		});
+	elements.add(refresh);
+	serverList = new ZListe();
+	serverList->setSize(300, 480);
+	serverList->setRahmenBreite(1);
+	serverList->setRahmenFarbe(0xFF6d6d6d);
+	serverList->setPosition(zScreen->getBackBufferSize().x / 2 - 150, zScreen->getBackBufferSize().y / 2 - 250);
+	serverList->setStyle(ZListe::Style::Normal | ZListe::Style::VScroll);
+	serverList->setMausEreignis(_ret1ME);
+	serverList->setVertikalScrollPos(0);
+	serverList->setEntrySeperatorSize(1);
+	serverList->setEntrySeperatorColor(0xFF6d6d6d);
+	elements.add(serverList);
+	add = initKnopf(zScreen->getBackBufferSize().x / 2 - 50, zScreen->getBackBufferSize().y / 2 + 235, 100, 20, Knopf::Style::Normal, "Add Server");
+	elements.add(add);
+	add->setMausEreignis([this](void* p, void* o, Framework::MausEreignis me)
+		{
+			if (me.id == ME_RLinks)
+			{
+				hide();
+				menuRegister->get("addServer")->show();
+			}
+			return 1;
+		});
+	// load server json
+	JSON::JSONValue* json = JSON::loadJSONFromFile("data/server.json");
+	if (json)
+	{
+		// build validator
+		JSON::Validator::JSONValidator* validator = JSON::Validator::JSONValidator::buildForObject()
+			->withRequiredString("playerName")->withDefault("")->finishString()
+			->withRequiredAttribute("server", JSON::Validator::JSONValidator::buildForArray()
+				->withDefault(new JSON::JSONArray())
+				->removeInvalidEntries()
+				->addAcceptedTypeInArray(JSON::Validator::JSONValidator::buildForObject()
+					->withRequiredString("name")->finishString()
+					->withRequiredString("ip")->finishString()
+					->withRequiredNumber("sslPort")->whichIsGreaterOrEqual(0)->whichIsLessOrEqual((double)0xFFFF)->finishNumber()
+					->withRequiredNumber("port")->whichIsGreaterOrEqual(0)->whichIsLessOrEqual((double)0xFFFF)->finishNumber()
+					->withRequiredAttribute("secrets", JSON::Validator::JSONValidator::buildForArray()
+						->addAcceptedObjectInArray()
+						->withRequiredString("secret")->finishString()
+						->withRequiredString("playerName")->finishString()
+						->finishObject()->finishArray())
+					->finishObject())
+				->finishArray())
+			->finishObject();
+		JSON::JSONValue* validJson = validator->getValidParts(json);
+		json->release();
+		if (validJson)
+		{
+			JSON::JSONArray* arr = validJson->asObject()->zValue("server")->asArray();
+			for (int i = 0; i < arr->getLength(); i++)
+			{
+				JSON::JSONObject* obj = arr->zValue(i)->asObject();
+				Framework::HashMap<Framework::Text, Framework::Text>* secrets = new Framework::HashMap<Framework::Text, Framework::Text>(10, [](Text t) { return t.hashCode(); });
+				JSON::JSONArray* secretsJson = obj->zValue("secrets")->asArray();
+				for (int j = 0; j < secretsJson->getLength(); j++)
+				{
+					JSON::JSONObject* obj2 = secretsJson->zValue(j)->asObject();
+					//decode base64 secret
+					char* secretBuffer = 0;
+					int length;
+					Framework::base64Decode(obj2->zValue("secret")->asString()->getString(), &secretBuffer, &length);
+					secrets->put(obj2->zValue("playerName")->asString()->getString(), Framework::Text(secretBuffer));
+					delete[] secretBuffer;
+				}
+				ServerStatus* s = new ServerStatus(obj->zValue("name")->asString()->getString(), obj->zValue("ip")->asString()->getString(), (unsigned short)obj->zValue("sslPort")->asNumber()->getNumber(), (unsigned short)obj->zValue("port")->asNumber()->getNumber(), secrets);
+				s->setSize(300, 65);
+				serverList->addEintrag(s);
+			}
+			playerName->setText(validJson->asObject()->zValue("playerName")->asString()->getString());
+			if (playerName->zText()->getLength() > 0)
+			{
+				for (int i = 0; i < serverList->getEintragAnzahl(); i++)
+					((ServerStatus*)serverList->zEintrag(i))->updatePlayerName(playerName->zText()->getText());
+			}
+			serverList->updateVScroll();
+			validJson->release();
+		}
+		validator->release();
+	}
+}
+
+void ServerSelectionMenu::addServer(Framework::Text name, Framework::Text ip, unsigned short sslPort, unsigned short port)
+{
+	ServerStatus* tmp = new ServerStatus(name, ip, sslPort, port, new HashMap< Framework::Text, Framework::Text>(10, [](Text t)
+		{
+			return t.hashCode();
+		}));
+	tmp->setSize(300, 65);
+	serverList->addEintrag(tmp);
+	tmp->updatePlayerName(playerName->zText()->getText());
+	serverList->updateVScroll();
+	saveServers();
+}
+
+bool ServerSelectionMenu::hasServer(Framework::Text name) const
+{
+	for (int i = 0; i < serverList->getEintragAnzahl(); i++)
+	{
+		if (((ServerStatus*)serverList->zEintrag(i))->getName() == name)
+			return 1;
+	}
+	return 0;
+}
+
+void ServerSelectionMenu::removeServer(Framework::Text name) const
+{
+	for (int i = 0; i < serverList->getEintragAnzahl(); i++)
+	{
+		if (((ServerStatus*)serverList->zEintrag(i))->getName() == name)
+			serverList->removeEintrag(i);
+	}
+	serverList->updateVScroll();
+	saveServers();
+}
+
+void ServerSelectionMenu::saveServers() const
+{
+	Datei file;
+	file.setDatei("data/server.json");
+	file.open(Datei::Style::schreiben);
+	JSON::JSONObject root;
+	JSON::JSONArray* servers = new JSON::JSONArray();
+	for (int i = 0; i < serverList->getEintragAnzahl(); i++)
+	{
+		JSON::JSONObject* server = new JSON::JSONObject();
+		server->addValue("name", new JSON::JSONString(((ServerStatus*)serverList->zEintrag(i))->getName()));
+		server->addValue("ip", new JSON::JSONString(((ServerStatus*)serverList->zEintrag(i))->getIp()));
+		server->addValue("sslPort", new JSON::JSONNumber(((ServerStatus*)serverList->zEintrag(i))->getSSLPort()));
+		server->addValue("port", new JSON::JSONNumber(((ServerStatus*)serverList->zEintrag(i))->getPort()));
+		JSON::JSONArray* secrets = new JSON::JSONArray();
+		for (auto secretEntry : *((ServerStatus*)serverList->zEintrag(i))->zSecrets())
+		{
+			JSON::JSONObject* secret = new JSON::JSONObject();
+			secret->addValue("playerName", new JSON::JSONString(secretEntry.getKey()));
+			// base64 encode secret
+			Framework::Text secretBase64 = Framework::base64Encode(secretEntry.getValue(), secretEntry.getValue().getLength());
+			secret->addValue("secret", new JSON::JSONString(secretBase64));
+			secrets->addValue(secret);
+		}
+		server->addValue("secrets", secrets);
+		servers->addValue(server);
+	}
+	root.addValue("server", servers);
+	root.addValue("playerName", new JSON::JSONString(playerName->zText()->getText()));
+	Framework::Text json = root.toString();
+	file.schreibe(json, json.getLength());
+	file.close();
+}

+ 59 - 0
FactoryCraft/ServerSelection.h

@@ -0,0 +1,59 @@
+#pragma once
+
+#include <TextFeld.h>
+#include <Liste.h>
+#include <HashMap.h>
+
+#include "Menu.h"
+
+class ServerStatus : public ZeichnungHintergrund
+{
+private:
+	Framework::Text name;
+	Framework::Text ip;
+	unsigned short sslPort;
+	unsigned short port;
+	Framework::Text playerName;
+	int ping;
+	Framework::Text status;
+	int statusId;
+	int requestId;
+	Framework::HashMap<Framework::Text, Framework::Text> *secrets;
+	Framework::AlphaFeld *closeAF;
+	Framework::Knopf* join;
+
+public:
+	ServerStatus(Framework::Text name, Framework::Text ip, unsigned short sslPort, unsigned short port, Framework::HashMap<Framework::Text, Framework::Text> *secrets);
+	~ServerStatus();
+
+	virtual void updatePlayerName(Framework::Text playerName);
+	
+	virtual void doMausEreignis(Framework::MausEreignis& me, bool userRet) override;
+	virtual bool tick(double time) override;
+	virtual void render(Framework::Bild& rObj) override;
+
+	Framework::Text getName() const;
+	Framework::Text getIp() const;
+	unsigned short getSSLPort() const;
+	unsigned short getPort() const;
+	Framework::HashMap<Framework::Text, Framework::Text>* zSecrets() const;
+	bool canConnect() const;
+};
+
+class ServerSelectionMenu : public Menu
+{
+private:
+	Framework::TextFeld* playerName;
+	Framework::TextFeld* playerNameLabel;
+	Framework::TextFeld* serverLabel;
+	Framework::ZListe* serverList;
+	Framework::Knopf* add;
+	Framework::Knopf* refresh;
+
+public:
+	ServerSelectionMenu(Framework::Bildschirm* zScreen);
+	void addServer(Framework::Text name, Framework::Text ip, unsigned short sslPort, unsigned short port);
+	bool hasServer(Framework::Text name) const;
+	void removeServer(Framework::Text name) const;
+	void saveServers() const;
+};

+ 16 - 8
FactoryCraft/World.cpp

@@ -13,9 +13,11 @@
 using namespace Network;
 using namespace Framework;
 
+World* World::INSTANCE = 0;
 
-World::World(Bildschirm3D* zScreen)
-	: Thread()
+World::World(Bildschirm3D* zScreen, FactoryClient* client)
+	: Thread(),
+	client(client)
 {
 	renderedWorld = new Welt3D();
 	renderedWorld->addDiffuseLight(DiffuseLight{ Vec3<float>(0.5f, 0.5f, -1.f), Vec3<float>(1.f, 1.f, 1.f) });
@@ -36,13 +38,14 @@ World::~World()
 	currentDimension->release();
 	if (currentTarget)
 		currentTarget->release();
+	client->release();
 }
 
 void World::update(bool background)
 {
 	NetworkReader* serverMessageReader = 0;
 	unsigned char type = 0;
-	while (background ? serverMessageReader = network->zFactoryClient()->getNextBackgroundMessage() : serverMessageReader = network->zFactoryClient()->getNextForegroundMessage())
+	while (background ? serverMessageReader = client->getNextBackgroundMessage() : serverMessageReader = client->getNextForegroundMessage())
 	{
 		serverMessageReader->lese((char*)&type, 1);
 		if (type == 2) // WORLD UPDATE
@@ -97,9 +100,9 @@ void World::update(bool background)
 				p->setPlayerControlled();
 			}
 		}
-		network->zFactoryClient()->endMessageReading(background);
+		client->endMessageReading(background);
 	}
-	network->zFactoryClient()->endMessageReading(background);
+	client->endMessageReading(background);
 	Entity* player = getCurrentPlayerEntity();
 	if (player)
 	{
@@ -130,7 +133,7 @@ void World::update(bool background)
 						}
 						if (!found)
 						{
-							network->zFactoryClient()->chunkAPIRequest(pos, msg, 1);
+							client->chunkAPIRequest(pos, msg, 1);
 							subscriptions.add(pos);
 						}
 						subLock.unlock();
@@ -167,7 +170,7 @@ void World::thread()
 			while (true)
 			{
 				zScreenPtr->lock();
-				if (currentGame != this)
+				if (World::INSTANCE != this)
 				{
 					zScreenPtr->unlock();
 					return;
@@ -180,7 +183,7 @@ void World::thread()
 	while (true)
 	{
 		zScreenPtr->lock();
-		if (currentGame != this)
+		if (World::INSTANCE != this)
 		{
 			zScreenPtr->unlock();
 			return;
@@ -326,4 +329,9 @@ Framework::Model3D* World::getCurrentTarget() const
 Chunk* World::zChunk(Punkt center)
 {
 	return currentDimension->zChunk(center);
+}
+
+FactoryClient* World::zClient() const
+{
+	return client;
 }

+ 7 - 1
FactoryCraft/World.h

@@ -7,9 +7,13 @@
 
 #include "Dimension.h"
 #include "PlayerKam.h"
+#include "FactoryClient.h"
 
 class World : public Framework::Thread
 {
+public:
+	static World* INSTANCE;
+	
 private:
 	Dimension* currentDimension;
 	Framework::Welt3D* renderedWorld;
@@ -19,11 +23,12 @@ private:
 	int ownEntityId;
 	Framework::Model3D* currentTarget;
 	Array<Punkt> subscriptions;
+	FactoryClient* client;
 	Critical subLock;
 	Critical targetLock;
 
 public:
-	World(Framework::Bildschirm3D* zScreen);
+	World(Framework::Bildschirm3D* zScreen, FactoryClient* client);
 	~World();
 	void update(bool background);
 	void setChunk(Chunk* chunk);
@@ -47,4 +52,5 @@ public:
 	void onChunkAdded(Punkt pos);
 	Chunk* zChunk(Punkt center);
 	Framework::Model3D* getCurrentTarget() const;
+	FactoryClient* zClient() const;
 };