Index: code/branches/objecthierarchy/src/orxonox/objects/infos/LevelInfo.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/infos/LevelInfo.cc	(revision 1993)
+++ code/branches/objecthierarchy/src/orxonox/objects/infos/LevelInfo.cc	(revision 2006)
@@ -31,13 +31,23 @@
 
 #include <OgreSceneManager.h>
+#include <OgreLight.h>
 
 #include "core/CoreIncludes.h"
 #include "core/XMLPort.h"
 #include "core/Core.h"
+#include "core/ConsoleCommand.h"
+#include "core/Loader.h"
+#include "core/Template.h"
 
 #include "GraphicsEngine.h"
+#include "Settings.h"
+#include "PlayerInfo.h"
+
+#include "util/Math.h"
 
 namespace orxonox
 {
+    SetConsoleCommand(LevelInfo, listPlayers, true);
+
     CreateFactory(LevelInfo);
 
@@ -46,10 +56,91 @@
         RegisterObject(LevelInfo);
 
-        this->gametypeInstance_ = 0;
+        this->rootGametype_ = 0;
         this->registerVariables();
 
+        // test test test
+        {
+            Ogre::Light* light;
+            light = GraphicsEngine::getInstance().getLevelSceneManager()->createLight("Light0");
+            light->setType(Ogre::Light::LT_DIRECTIONAL);
+            light->setDiffuseColour(ColourValue(1.0, 0.9, 0.6, 1.0));
+            light->setSpecularColour(ColourValue(1.0, 0.9, 0.6, 1.0));
+            light->setDirection(1, -0.2, 0.2);
+        }
+        // test test test
+
         COUT(0) << "created LevelInfo" << std::endl;
     }
 
+    LevelInfo* LevelInfo::getActiveLevelInfo()
+    {
+        for (ObjectList<LevelInfo>::iterator it = ObjectList<LevelInfo>::begin(); it != ObjectList<LevelInfo>::end(); ++it)
+            if (it->isActive())
+                return (*it);
+
+        return 0;
+    }
+
+    PlayerInfo* LevelInfo::getClient(unsigned int clientID)
+    {
+        LevelInfo* levelinfo = LevelInfo::getActiveLevelInfo();
+
+        if (levelinfo)
+        {
+            std::map<unsigned int, PlayerInfo*>::const_iterator it = levelinfo->clients_.find(clientID);
+            if (it != levelinfo->clients_.end())
+                return it->second;
+        }
+        else
+        {
+            for (ObjectList<PlayerInfo>::iterator it = ObjectList<PlayerInfo>::begin(); it != ObjectList<PlayerInfo>::end(); ++it)
+                if (it->getClientID() == clientID)
+                    return (*it);
+        }
+        return 0;
+    }
+
+    void LevelInfo::listPlayers()
+    {
+        LevelInfo* levelinfo = LevelInfo::getActiveLevelInfo();
+
+        if (levelinfo->getGametype())
+        {
+            for (std::set<PlayerInfo*>::const_iterator it = levelinfo->getGametype()->getPlayers().begin(); it != levelinfo->getGametype()->getPlayers().end(); ++it)
+                COUT(0) << "ID: " << (*it)->getClientID() << ", Name: " << (*it)->getName() << std::endl;
+        }
+        else
+        {
+            for (ObjectList<PlayerInfo>::iterator it = ObjectList<PlayerInfo>::begin(); it != ObjectList<PlayerInfo>::end(); ++it)
+                COUT(0) << "ID: " << (*it)->getClientID() << ", Name: " << (*it)->getName() << std::endl;
+        }
+    }
+
+    void LevelInfo::clientConnected(unsigned int clientID)
+    {
+        COUT(0) << "client connected" << std::endl;
+
+        // create new PlayerInfo instance
+        PlayerInfo* player = new PlayerInfo();
+        player->setGametype(this->getGametype());
+        player->setClientID(clientID);
+
+        // add to clients-map
+        assert(!this->clients_[clientID]);
+        this->clients_[clientID] = player;
+    }
+
+    void LevelInfo::clientDisconnected(unsigned int clientID)
+    {
+        COUT(0) << "client disconnected" << std::endl;
+
+        // remove from clients-map
+        PlayerInfo* player = this->clients_[clientID];
+        this->clients_.erase(clientID);
+
+        // delete PlayerInfo instance
+        delete player;
+    }
+
     void LevelInfo::XMLPort(Element& xmlelement, XMLPort::Mode mode)
     {
@@ -57,15 +148,31 @@
 
         XMLPortParam(LevelInfo, "description", setDescription, getDescription, xmlelement, mode);
-        XMLPortParam(LevelInfo, "gametype", setGametype, getGametype, xmlelement, mode).defaultValues("Gametype");
+        XMLPortParam(LevelInfo, "gametype", setGametypeString, getGametypeString, xmlelement, mode).defaultValues("Gametype");
         XMLPortParam(LevelInfo, "skybox", setSkybox, getSkybox, xmlelement, mode);
         XMLPortParam(LevelInfo, "ambientlight", setAmbientLight, getAmbientLight, xmlelement, mode).defaultValues(ColourValue(0.2, 0.2, 0.2, 1));
+
+        this->levelfile_ = this->getLevelfile();
     }
 
     void LevelInfo::registerVariables()
     {
-        REGISTERSTRING(name_,         network::direction::toclient, new network::NetworkCallback<LevelInfo>(this, &LevelInfo::changedName));
-        REGISTERSTRING(description_,  network::direction::toclient);
-        REGISTERSTRING(skybox_,       network::direction::toclient, new network::NetworkCallback<LevelInfo>(this, &LevelInfo::applySkybox));
-        REGISTERDATA(ambientLight_, network::direction::toclient, new network::NetworkCallback<LevelInfo>(this, &LevelInfo::applyAmbientLight));
+        REGISTERSTRING(this->levelfile_,    network::direction::toclient, new network::NetworkCallback<LevelInfo>(this, &LevelInfo::applyLevel));
+        REGISTERSTRING(this->name_,         network::direction::toclient, new network::NetworkCallback<LevelInfo>(this, &LevelInfo::changedName));
+        REGISTERSTRING(this->description_,  network::direction::toclient);
+        REGISTERSTRING(this->skybox_,       network::direction::toclient, new network::NetworkCallback<LevelInfo>(this, &LevelInfo::applySkybox));
+        REGISTERDATA(this->ambientLight_, network::direction::toclient, new network::NetworkCallback<LevelInfo>(this, &LevelInfo::applyAmbientLight));
+    }
+
+    void LevelInfo::applyLevel()
+    {
+        COUT(0) << "Loading level \"" << this->levelfile_ << "\"..." << std::endl;
+
+        ClassTreeMask mask;
+        mask.exclude(Class(BaseObject));
+        mask.include(Class(Template));
+
+        Level* level = new Level(Settings::getDataPath() + this->levelfile_, mask);
+
+        Loader::open(level);
     }
 
@@ -87,5 +194,5 @@
     }
 
-    void LevelInfo::setGametype(const std::string& gametype)
+    void LevelInfo::setGametypeString(const std::string& gametype)
     {
         Identifier* identifier = ClassByString(gametype);
@@ -94,5 +201,6 @@
             this->gametype_ = gametype;
             this->gametypeIdentifier_ = identifier;
-            this->gametypeInstance_ = this->gametypeIdentifier_.fabricate();
+            this->rootGametype_ = this->gametypeIdentifier_.fabricate();
+            this->getConnectedClients();
         }
     }
Index: code/branches/objecthierarchy/src/orxonox/objects/infos/LevelInfo.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/infos/LevelInfo.h	(revision 1993)
+++ code/branches/objecthierarchy/src/orxonox/objects/infos/LevelInfo.h	(revision 2006)
@@ -37,8 +37,9 @@
 
 #include "objects/gametypes/Gametype.h"
+#include "network/ClientConnectionListener.h"
 
 namespace orxonox
 {
-    class _OrxonoxExport LevelInfo : public Info
+    class _OrxonoxExport LevelInfo : public Info, public network::ClientConnectionListener
     {
         public:
@@ -48,4 +49,7 @@
             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
             void registerVariables();
+
+            inline const std::map<unsigned int, PlayerInfo*>& getClients() const
+                { return this->clients_; }
 
             inline void setDescription(const std::string& description)
@@ -62,9 +66,20 @@
                 { return this->ambientLight_; }
 
-            void setGametype(const std::string& gametype);
-            inline const std::string& getGametype() const
+            void setGametypeString(const std::string& gametype);
+            inline const std::string& getGametypeString() const
                 { return this->gametype_; }
+            inline Gametype* getGametype() const
+                { return this->rootGametype_; }
+
+            static LevelInfo* getActiveLevelInfo();
+            static void listPlayers();
+            static PlayerInfo* getClient(unsigned int clientID);
 
         private:
+            virtual void clientConnected(unsigned int clientID);
+            virtual void clientDisconnected(unsigned int clientID);
+
+            void applyLevel();
+
             void applySkybox()
                 { this->setSkybox(this->skybox_); }
@@ -72,4 +87,5 @@
                 { this->setAmbientLight(this->ambientLight_); }
 
+            std::map<unsigned int, PlayerInfo*> clients_;
             std::string description_;
             std::string skybox_;
@@ -77,5 +93,6 @@
             std::string gametype_;
             SubclassIdentifier<Gametype> gametypeIdentifier_;
-            Gametype* gametypeInstance_;
+            Gametype* rootGametype_;
+            std::string levelfile_;
     };
 }
Index: code/branches/objecthierarchy/src/orxonox/objects/infos/PlayerInfo.cc
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/infos/PlayerInfo.cc	(revision 1993)
+++ code/branches/objecthierarchy/src/orxonox/objects/infos/PlayerInfo.cc	(revision 2006)
@@ -38,4 +38,5 @@
 
 #include "network/Host.h"
+#include "network/ClientInformation.h"
 
 #include "GraphicsEngine.h"
@@ -57,4 +58,5 @@
         this->bHumanPlayer_ = false;
         this->bFinishedSetup_ = false;
+        this->gametype_ = 0;
 
         this->pawn_ = 0;
@@ -71,7 +73,6 @@
         if (this->isInitialized())
         {
-            Gametype* gametype = Gametype::getCurrentGametype();
-            if (gametype)
-                gametype->removePlayer(this);
+            if (this->gametype_)
+                this->gametype_->removePlayer(this);
 
             if (this->controller_)
@@ -101,7 +102,6 @@
     void PlayerInfo::changedName()
     {
-        Gametype* gametype = Gametype::getCurrentGametype();
-        if (gametype)
-            gametype->playerChangedName(this);
+        if (this->gametype_)
+            this->gametype_->playerChangedName(this);
     }
 
@@ -147,7 +147,6 @@
         else if (this->bFinishedSetup_)
         {
-            Gametype* gametype = Gametype::getCurrentGametype();
-            if (gametype)
-                gametype->addPlayer(this);
+            if (this->gametype_)
+                this->gametype_->addPlayer(this);
         }
     }
@@ -165,5 +164,6 @@
     void PlayerInfo::stopControl()
     {
-        this->pawn_->removePlayer();
+        if (this->pawn_)
+            this->pawn_->removePlayer();
         this->pawn_ = 0;
         this->pawnID_ = network::OBJECTID_UNKNOWN;
Index: code/branches/objecthierarchy/src/orxonox/objects/infos/PlayerInfo.h
===================================================================
--- code/branches/objecthierarchy/src/orxonox/objects/infos/PlayerInfo.h	(revision 1993)
+++ code/branches/objecthierarchy/src/orxonox/objects/infos/PlayerInfo.h	(revision 2006)
@@ -71,4 +71,9 @@
                 { return this->controller_; }
 */
+            inline void setGametype(Gametype* gametype)
+                { this->gametype_ = gametype; }
+            inline Gametype* getGametype() const
+                { return this->gametype_; }
+
         protected:
             inline void setDefaultController(Identifier* identifier)
@@ -98,4 +103,5 @@
             Controller* controller_;
             SubclassIdentifier<Controller> defaultController_;
+            Gametype* gametype_;
     };
 }
