/************************************************* Function: happen Description: The function of class Event that take the Event::serveFunction to new thread and start the new thread. Calls: std::bind() clown::Event::start() Input: None. Output: None. Return: An integer indicating the result of invocation. 0 is success and other non-zero means failed. Others: None. *************************************************/ int clown::Event::happen() { clown::Thread::ThreadFunction registerFunction = std::bind( &clown::Event::serveFunction, this); clown::Thread eventThread(registerFunction); eventThread.start(); finishedFlag = true; return 0; }
void testNavMesh() { Event::EventManager m; Event::ListenerRegister & reg = m.getListenerRegister(); AI::NavMesh::NavMeshGenerationEngine navMeshGenerationEngine; navMeshGenerationEngine.registerListeners(reg); vector<Threading::ThreadableInterface*> threadables; threadables.push_back(&m); Threading::Thread eventThread(threadables, 2); eventThread.start(); vector<Threading::ThreadableInterface*> threadables2; threadables2.push_back(&navMeshGenerationEngine); Threading::Thread generationThread(threadables2, 2); generationThread.start(); Event::EventQueue & queue = m.getEventQueue(); Geometry::Vec2Df lowerLeftPoint(0.f, 0.f); Geometry::Vec2Df upperRightPoint(128.f,128.f); queue << new AI::NavMesh::AreaCreatedEvent(lowerLeftPoint, upperRightPoint); // Create some obtacles queue << new AI::NavMesh::ObstacleAddedEvent(AI::NavMesh::Obstacle(Geometry::Vec2Df(110.f,110.f), Geometry::Vec2Df(119.f,119.f))); queue << new AI::NavMesh::ObstacleAddedEvent(AI::NavMesh::Obstacle(Geometry::Vec2Df(60.f,60.f), Geometry::Vec2Df(70.f,70.f))); queue << new AI::NavMesh::ObstacleAddedEvent(AI::NavMesh::Obstacle(Geometry::Vec2Df(10.f,10.f), Geometry::Vec2Df(15.f,15.f))); queue << new AI::NavMesh::NavMeshOverEvent(lowerLeftPoint,upperRightPoint); int k = 0; while (k < 20) { k++; Threading::sleep(Core::makeDurationMillis(200)); } eventThread.stop(); generationThread.stop(); // Draw navMesh Test::SvgDrawer drawer(256,256); const AI::NavMesh::NavMeshContainer::NavMeshesList& navMeshes = navMeshGenerationEngine.getNavMeshes().getNavMeshesList(); if(navMeshes.size() > 0) { AI::NavMesh::NavMesh* navMesh = navMeshes.at(0); // Path finding const Graph::PlanarGraph& graph = navMesh->getGraph(); const Graph::PlanarNode& startNode = graph.getNodes().front(); const Graph::PlanarNode& goalNode = graph.getNodes().back(); Graph::PlanarGraph::NodeCollection path; Graph::BasicAStar(graph, startNode, goalNode, path); drawNavMesh(*navMesh, drawer); //drawPath(path, drawer); //std::cout << drawer.getContent().str(); } // Test AI // Create entity Threading::ConcurrentRessource<Ecs::World> w( new Ecs::World(m.getEventQueue()) ); Ecs::Entity e1, e2; { Threading::ConcurrentWriter<Ecs::World> world = w.getWriter(); e1 = createNewCharacter( world, Geometry::Vec3Df(0.0,0.0,0.0), Geometry::Vec3Df(0.0,0.0,0.0), true, queue ); e2 = createNewCharacter( world, Geometry::Vec3Df(80.0,80.0,0.0), Geometry::Vec3Df(0.0,0.0,0.0), false, queue ); } // Create thrads for systems AI::AiSystem aiSystem(w); AI::Sensor::SensorSystem sensorSystem(w); Physics::MovementSystem movementSystem(w, m.getEventQueue()); AI::Subsystem::TargetingSystem targetingSystem(w); vector<Threading::ThreadableInterface*> aiSystemVector; vector<Threading::ThreadableInterface*> movementSystemVector; vector<Threading::ThreadableInterface*> targetingSystemVector; vector<Threading::ThreadableInterface*> sensorSystemVector; aiSystemVector.push_back(&sensorSystem); aiSystemVector.push_back(&targetingSystem); aiSystemVector.push_back(&aiSystem); movementSystemVector.push_back(&movementSystem); Threading::Thread aiThread(aiSystemVector, 20); //Threading::Thread sensorThread(sensorSystemVector, 5); //Threading::Thread targetingThread(targetingSystemVector, 5); Threading::Thread movementThread(movementSystemVector, 20); // Get the position component of e1 Ecs::ComponentGroup::ComponentTypeCollection types; types.insert(Geometry::PositionComponent::Type); Ecs::ComponentGroup prototype(types); Ecs::ComponentGroup componentsE1 = w.getWriter()->getEntityComponents( e1, prototype ); Ecs::ComponentGroup componentsE2 = w.getWriter()->getEntityComponents(e2, prototype); types.insert(AI::Subsystem::TargetingComponent::Type); Ecs::ComponentGroup components = w.getWriter()->getEntityComponents(e1, Ecs::ComponentGroup(types)); //sensorThread.start(); //targetingThread.start(); aiThread.start(); movementThread.start(); std::vector<Geometry::Vec2Df> positions; positions.push_back(Geometry::Vec2Df(0,0)); /* bool b = true; while(b) { Geometry::Vec2Df lastPos = positions.back(); Geometry::Vec3Df pos = positionComponentE1.getPosition(); if((pos -positionComponentE2.getPosition()).getLength() < 2.f) b = false; Threading::sleep(0,20); if(pos.getX() != lastPos.getX() && pos.getY() != lastPos.getY()) positions.push_back(Geometry::Vec2Df(pos.getX(), pos.getY())); } for (int j =0; j < 20; j++) { Threading::sleep(0,100); } */ std::vector<Geometry::Vec2Df> positionsE2; std::vector<Geometry::Vec2Df> targets; // Taget is moving slowly to the upper-right corner of the navMesh Geometry::Vec3Df offset(0.1, -0.2, 0.0); for (int j =0; j < 20*20; j++) { Threading::sleep(Core::makeDurationMillis(50)); ConcurrentReader<Geometry::PositionComponent> positionComponentE1 = getConcurrentReader<Ecs::Component, Geometry::PositionComponent>( componentsE1.getComponent(Geometry::PositionComponent::Type) ); ConcurrentWriter<Geometry::PositionComponent> positionComponentE2 = getConcurrentWriter<Ecs::Component, Geometry::PositionComponent>( componentsE2.getComponent(Geometry::PositionComponent::Type) ); ConcurrentReader<AI::Subsystem::TargetingComponent> targetingComponent = getConcurrentReader<Ecs::Component, AI::Subsystem::TargetingComponent>( components.getComponent(AI::Subsystem::TargetingComponent::Type) ); Geometry::Vec3Df pos1 = positionComponentE1->getPosition(); Geometry::Vec3Df pos2 = positionComponentE2->getPosition(); Geometry::Vec3Df target = targetingComponent->getTargetPosition(); Geometry::Vec3Df newPos = pos2 + offset; positionComponentE2->setPosition(newPos); positionsE2.push_back(Geometry::Vec2Df(newPos.getX(), newPos.getY())); positions.push_back(Geometry::Vec2Df(pos1.getX(), pos1.getY())); targets.push_back(Geometry::Vec2Df(target.getX(), target.getY())); } aiThread.stop(); //sensorThread.stop(); //targetingThread.stop(); movementThread.stop(); if(navMeshes.size() > 0) { ConcurrentWriter<Geometry::PositionComponent> positionComponentE2 = getConcurrentWriter<Ecs::Component, Geometry::PositionComponent>( componentsE2.getComponent(Geometry::PositionComponent::Type) ); AI::NavMesh::NavMesh* navMesh = navMeshes.at(0); // Path finding const Graph::PlanarGraph& graph = navMesh->getGraph(); Geometry::Vec3Df pos2 = positionComponentE2->getPosition(); Graph::PlanarNode startNode; navMesh->getNode( Geometry::Vec2Df(0, 0), startNode); Graph::PlanarNode goalNode; navMesh->getNode( Geometry::Vec2Df(pos2.getX(), pos2.getY()), goalNode); Graph::PlanarGraph::NodeCollection path; Graph::BasicAStar(graph, startNode, goalNode, path); drawPath(path, drawer); } for(unsigned int i = 0; i < positions.size(); i++) { Geometry::Vec2Df pos = positions[i]; drawer.drawCircle(pos.getX(), pos.getY(), 1, "green"); } for(unsigned int i = 0; i < positionsE2.size(); i++) { Geometry::Vec2Df pos = positionsE2[i]; drawer.drawCircle(pos.getX(), pos.getY(), 1, "orange"); Geometry::Vec2Df target = targets[i]; drawer.drawCircle(target.getX(), target.getY(), 1, "purple"); } drawer.end(); std::cout << drawer.getContent().str(); }
int main(int argc, char ** argv) { std::cout << "Battlefield 3 TuxNet (Rcon Service) Rev. " << REVISION << " :: Copyright 2009-2013 (c) Plain-Solution.de" << endl; try { // settings.ini lesen boost::property_tree::ptree pt; boost::property_tree::ini_parser::read_ini(string(argv[0]).append(".ini"), pt); std::cout << "BF3 Server: " << pt.get<string>("Server.Host") << ":" << pt.get<string>("Server.Port") << endl; //// fstream pidfile(string(argv[0]).append(".pid"), ios::out); if(!pidfile) throw string("Could not write pidfile"); pidfile << getpid() << endl; pidfile.close(); RconConnection * rcon = new RconConnection( pt.get<string>("Server.Host"), pt.get<string>("Server.Port"), pt.get<string>("Server.Password") ); rcon->Login(); rcon->EnableEvents(); string msg = "[BF3 TuxNet Rev. "; msg += REVISION; msg += "] by Plain-Solution.de"; rcon->sendRequest(createWords("admin.say", msg.c_str(), "all")); EventHandler * eventHandler = new EventHandler(rcon, &pt); thread eventThread([eventHandler]() { eventHandler->DoWork(); }); while(true) { try { TextRconPacket response = rcon->getResponse(); if(eventHandler->needResponse != 0 && response.isValid() && response.m_isResponse && eventHandler->needResponse == response.m_sequence) { eventHandler->response = new TextRconPacket(response); eventHandler->needResponse = 0; } if(response.isValid() && !response.m_isResponse && response.m_originatedOnServer) eventHandler->AddEvent(response); } catch(string e) { eventHandler->out(e, EventHandler::OUT_TYPE::ERR); } } eventHandler->Disable(); eventThread.join(); } catch(exception & e) { _out(e.what(), EventHandler::OUT_TYPE::ERR); } catch(string & e) { _out(e, EventHandler::OUT_TYPE::ERR); } remove(string(argv[0]).append(".pid").c_str()); return 0; }