CPhysicsSystem::CPhysicsSystem(entityx::ptr<entityx::EntityManager> em) { //ctor emptr = (entityx::EntityManager*)em.get(); }
/** * This function will write into json file */ void JSONReader::update(entityx::ptr<entityx::EntityManager> es, entityx::ptr<entityx::EventManager> events, double dt) { entityx::ptr<Comp::File> file; entityx::ptr<Comp::Read> read; for (auto entity : es->entities_with_components(file, read)) { rapidjson::Document doc; bool fileread = file->read(); //we try to read if (fileread && file->getContents() != "") { doc.Parse<0>(file->getContents().c_str()); if (doc.HasParseError()) { CCLOG("GetParseError %s\n", doc.GetParseError()); //signal error events->emit<Events::Error>(entity, "JSONReader system file read error"); //WHAT TO DO ? } //else everything is ok with this json file } else // read fail : lets create first content { doc.SetObject(); rapidjson::StringBuffer strbuf; rapidjson::Writer<rapidjson::StringBuffer> writer(strbuf); doc.Accept(writer); file->setContents( strbuf.GetString()); //CCLOG("new contents : %s", file->getContents().c_str()); } entity.remove<Comp::Read>(); } }
/** * This function will call the callback with the current progress of the timer. */ void AlarmRinger::update(entityx::ptr<entityx::EntityManager> es, entityx::ptr<entityx::EventManager> events, double dt) { entityx::ptr<Comp::ID> id; entityx::ptr<Comp::Alarm> alarm; for (auto entity : es->entities_with_components(id, alarm)) { time_t start = mktime(&alarm->m_end); time_t nowtime = mktime(&alarm->m_now); // actually returns long long, despite double declaration double delta = difftime(start, nowtime); if (delta < 0) // becomes true when delta is -1, this adds 1 sec to alarm length { events->emit<Events::AlarmOff>(entity); } } };
Entity Factory::createBlock(entityx::ptr<entityx::EntityManager> entityMgr, int x, int y, int z, std::string material) { Entity block = entityMgr->create(); Ogre::SceneManager* sceneMgr = RenderManager::getPtr()->getSceneManager(); Ogre::Entity* wall = sceneMgr->createEntity("Cube.mesh"); wall->setMaterialName(material); Ogre::SceneNode* wallNode = sceneMgr->getRootSceneNode()->createChildSceneNode(); wallNode->attachObject(wall); block.assign<Position>(x,y,z); wallNode->setPosition(x,y,z); block.assign<Orientation>(wallNode->getOrientation()); block.assign<Renderable>(wallNode); block.assign<Name>("Block"); if(material == "Wall"){ block.assign<Destroyable>(200); } return block; }
void Timer::update(entityx::ptr<entityx::EntityManager> entities, entityx::ptr<entityx::EventManager> events, double dt) { entityx::ptr<Comp::ServerTime> st; for (auto entity : entities->entities_with_components(st)) { if (st->done) { entity.remove<Comp::ServerTime>(); //if mask at 0 no request in this entity anymore if (entity.component_mask() == 0) entity.destroy(); } else if (!st->in_progress) { m_timer_service->GetCurrentTimeNoWinBase(st->m_cb); st->in_progress = true; } } }
entityx::Entity Factory::createProjectile(entityx::ptr<EntityManager> where, Ogre::Vector3 pos, Ogre::Quaternion ori, Ogre::Real velocity, std::string materialName) { Ogre::Entity *projMesh; Ogre::SceneManager *sceneMgr = RenderManager::getPtr()->getSceneManager(); projMesh = sceneMgr->createEntity("ProjectileMesh.mesh"); projMesh->setMaterialName(materialName); Entity proj = where->create(); Ogre::SceneNode *projNode = sceneMgr->getRootSceneNode()->createChildSceneNode(); projNode->attachObject(projMesh); Ogre::Light *light = sceneMgr->createLight(); if(materialName == "RedLaser") light->setDiffuseColour(Ogre::ColourValue(.8, .2, .2)); else light->setDiffuseColour(Ogre::ColourValue(.2, .2, .8)); light->setType(Ogre::Light::LT_POINT); projNode->attachObject(light); projNode->setPosition(pos); projNode->setOrientation(ori); //projNode->translate(0, 0, -2, Ogre::SceneNode::TS_LOCAL); proj.assign<Position>(projNode->getPosition()); proj.assign<Orientation>(ori); proj.assign<Velocity>(0, 0, velocity); proj.component<Velocity>()->direction.z = -1; proj.assign<Renderable>(projNode); proj.assign<AngularVelocity>(0, 0, 10); proj.assign<Name>("proiettile"); proj.assign<LightComponent>(light); return proj; }
void DLCchecking::update(entityx::ptr<entityx::EntityManager> es, entityx::ptr<entityx::EventManager> events, double dt) { for (auto entity : es->entities_with_components<Comp::DataVerCheck>()) { entityx::ptr<Comp::DataVerCheck> dllist = entity.component<Comp::DataVerCheck>(); std::string url = dllist->m_url; if (!dllist->m_verlist.empty()) { //we need to check if the version url is valid ( contains a manifest.json ) url += "/" + dllist->m_verlist.back() + "/manifest.json"; m_manifest = ""; CCLOG("DLCchecking reading from %s", url.c_str()); //list all files at given url CURLcode res; curl_easy_setopt(_curl, CURLOPT_URL, url.c_str()); #ifdef _DEBUG curl_easy_setopt(_curl, CURLOPT_VERBOSE, 1L); #endif curl_easy_setopt(_curl, CURLOPT_WRITEFUNCTION, write_data); curl_easy_setopt(_curl, CURLOPT_WRITEDATA, &m_manifest); if (_connectionTimeout) curl_easy_setopt(_curl, CURLOPT_CONNECTTIMEOUT, _connectionTimeout); curl_easy_setopt(_curl, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt(_curl, CURLOPT_LOW_SPEED_LIMIT, LOW_SPEED_LIMIT); curl_easy_setopt(_curl, CURLOPT_LOW_SPEED_TIME, LOW_SPEED_TIME); res = curl_easy_perform(_curl); CCLOG("DLCchecking read from %s", url.c_str()); if (res != 0) { CCLOG("DLCchecking can not read from %s, error code is %d", url.c_str(), res); dllist->m_retries--; if (0 == dllist->m_retries) { CCLOGERROR("DLCchecking can not read from %s, error code is %d", url.c_str(), res); //signal error events->emit<Events::Error>(entity, "DLCchecking system"); //we give up on this entity entity.destroy(); } } else { //read the downloaded manifest to compare md5 rapidjson::Document json; json.Parse<0>(m_manifest.c_str()); if (json.HasParseError()) { CCLOG("GetParseError %s\n", json.GetParseError()); //version will be removed from the list later. } else { //is it possible to update ? bool dlc_update_allowed = false; //do we need to update ? bool dlc_update_required = false; std::string version = cocostudio::DictionaryHelper::getInstance()->getStringValue_json(json, "version", ""); if (version == dllist->m_current_version) //if we have the exact same string : developer update or current version hotfix. { dlc_update_required = true; } else if (version.length() > 0 ) //we need to compare string to find if the online version is more recent { unsigned long lver = 0; try { lver = ToolBox::stoul(version); CCLOG("DLC at %s has Manifest version %lu", url.c_str(), lver); } catch (std::out_of_range oor) { lver = 0; //disabling update if online version is too high ( developer version ) } unsigned long lcver = 0; try { lcver = ToolBox::stoul(dllist->m_current_version); CCLOG("Local DLC has Manifest version %lu", url.c_str(), lcver); } catch (std::out_of_range oor) { lcver = LONG_MAX; // if local version is too high, update should have been done before } if (lver > lcver) //not == to prevent LONG_MAX == LONG_MAX { dlc_update_required = true; } } std::string minAppVersion = cocostudio::DictionaryHelper::getInstance()->getStringValue_json(json, "minAppVersion", "error"); if (minAppVersion != "error" && dllist->m_current_minAppVersion != "" ) { //CAREFUL HERE with version comparison std::vector<unsigned long> mav = splitVersion(minAppVersion); std::vector<unsigned long> cmav = splitVersion(dllist->m_current_minAppVersion); dlc_update_allowed = true; while ( mav.size() < cmav.size() ) { mav.push_back(0); } for (unsigned int i = 0; i < cmav.size(); ++i) { if (mav.at(i) > cmav.at(i)) { dlc_update_allowed = false; break; } } }//if we cannot read the minimum app version. we dont download. better safe than sorry. if (dlc_update_allowed && dlc_update_required) { //prepare the list of downloads const rapidjson::Value & assets = cocostudio::DictionaryHelper::getInstance()->getSubDictionary_json(json, "assets"); for (rapidjson::Value::ConstMemberIterator m = assets.MemberonBegin(); m != assets.MemberonEnd(); ++m) { std::string filename = m->name.GetString(); std::string filehash = cocostudio::DictionaryHelper::getInstance()->getStringValue_json(m->value, "md5", "error"); //lowering filehash to be sure std::transform(filehash.begin(), filehash.end(), filehash.begin(), ::tolower); //std::cout << filename << " : " << filehash << std::endl; entityx::Entity newentity = es->create(); newentity.assign<Comp::LocalFile>(filename); newentity.assign<Comp::RemoteMD5>(filehash); newentity.assign<Comp::RemoteFile>(dllist->m_url + "/" + dllist->m_verlist.back(), filename); newentity.assign<Comp::ProgressValue>(1); } //downloading only the last verison should always be enough ( avoiding too many downloads - keeping all data for one version in same place ) //if (dllist->m_verlist.empty()) //if we checked all versions //{ entity.remove<Comp::DataVerCheck>(); //} //we dont need to do anything more with this entity entity.destroy(); } } //remove the version checked from the list dllist->m_verlist.pop_back(); //In case of error, we should check the next version in stack on next update. //If success this will not be done ( entity destroyed ) //TODO : check behavior } //exit this loop. one per update is enough break; } else //no version left to check { //we dont need to do anything more with this entity entity.destroy(); } } };
Entity Factory::createTank(entityx::ptr<entityx::EntityManager> entityMgr, std::string prefix,Ogre::Real velocity,Ogre::Real angularVelocity ,Ogre::Vector3 overHating,int health,bool ai) { DotSceneLoader loader; Ogre::SceneManager* sceneMgr = RenderManager::getPtr()->getSceneManager(); loader.parseDotScene("tank.scene", "General", sceneMgr, 0, prefix); Ogre::SceneNode* ctl = sceneMgr->getSceneNode(prefix + "TankControl"); Ogre::SceneNode* body = sceneMgr->getSceneNode(prefix + "TankBody"); Ogre::SceneNode* turret = sceneMgr->getSceneNode(prefix + "TankTurret"); Ogre::SceneNode* cannon = sceneMgr->getSceneNode(prefix +"TankCannon"); Entity tankEmptyControl = entityMgr->create(); Entity tankTurret = entityMgr->create(); Entity tankBody = entityMgr->create(); Entity tankCannon = entityMgr->create(); tankEmptyControl.assign<Position>(ctl->getPosition()); tankEmptyControl.assign<Orientation>(ctl->getOrientation()); tankEmptyControl.assign<Velocity>(0, 0, velocity); tankEmptyControl.assign<AngularVelocity>(0, angularVelocity, 0); tankEmptyControl.assign<Renderable>(ctl); tankEmptyControl.assign<OverHeating>(overHating.x,overHating.y,overHating.z); tankEmptyControl.assign<Destroyable>(health,health); tankEmptyControl.assign<Collidable>(); tankEmptyControl.assign<Name>(prefix); if(ai){ tankEmptyControl.assign<AI>(); Ogre::Entity *model = static_cast<Ogre::Entity*>(body->getAttachedObject(0)); model->getSubEntity(1)->setMaterialName("Red"); model = static_cast<Ogre::Entity*>(turret->getAttachedObject(0)); model->getSubEntity(1)->setMaterialName("Red"); model = static_cast<Ogre::Entity*>(cannon->getAttachedObject(0)); model->getSubEntity(1)->setMaterialName("Red"); } ptr<Children> child = tankEmptyControl.assign<Children>(); child->children["body"] = tankBody; child->children["turret"] = tankTurret; //child->children.push_back(tankBody); //child->children.push_back(tankTurret); tankTurret.assign<Position>(turret->getPosition()); tankTurret.assign<Orientation>(turret->getOrientation()); tankTurret.assign<Renderable>(turret); child = tankTurret.assign<Children>(); child->children["cannon"] = tankCannon; tankBody.assign<Position>(body->getPosition()); tankBody.assign<Orientation>(body->getOrientation()); tankBody.assign<Renderable>(body); tankCannon.assign<Position>(cannon->getPosition()); tankCannon.assign<Renderable>(cannon); tankCannon.assign<Orientation>(cannon->getOrientation()); ctl->scale(.35, .55, .35); return tankEmptyControl; }
/** * This function will write into json file */ void JSONPlayerData::update(entityx::ptr<entityx::EntityManager> es, entityx::ptr<entityx::EventManager> events, double dt) { entityx::ptr<Comp::File> file; entityx::ptr<Comp::PlayerData_v1> playerData; for (auto entity : es->entities_with_components(file, playerData)) { if (!entity.component<Comp::Read>()) { rapidjson::Document doc; doc.Parse<0>(file->getContents().c_str()); if (doc.HasParseError()) { CCLOG("GetParseError %s\n", doc.GetParseError()); //callback empty on invalid json if (playerData->m_load_cb) { playerData->m_load_cb(""); } } else if (playerData->m_load_cb) //if we want to load data { if (doc.HasMember(playerData->m_name.c_str())) { rapidjson::Value& playerdatavalue = doc[playerData->m_name.c_str()]; //writing json structure in a string rapidjson::StringBuffer strbuf; rapidjson::Writer<rapidjson::StringBuffer> writer(strbuf); playerdatavalue.Accept(writer); //passing the string to the callback playerData->m_data = strbuf.GetString(); playerData->m_load_cb(playerData->m_data); } else { playerData->m_load_cb(""); } } else //write request { //clearing original saved data doc.SetObject(); rapidjson::Document data; data.Parse<0>(playerData->m_data.c_str()); if (data.HasParseError()) { CCLOG("GetParseError %s\n", data.GetParseError()); //signal error events->emit<Events::Error>(entity, "JSONPlayerData system parse error"); //WHAT TO DO ? } else { rapidjson::Value vholder; vholder.SetObject(); for (auto dm = data.MemberonBegin(); dm != data.MemberonEnd(); ++dm) { vholder.AddMember(dm->name, dm->value, doc.GetAllocator()); } doc.AddMember(playerData->m_name.c_str(), vholder, doc.GetAllocator()); //TMP debug rapidjson::StringBuffer strbuf; rapidjson::Writer<rapidjson::StringBuffer> writer(strbuf); doc.Accept(writer); file->setContents( strbuf.GetString()); //CCLOG("new contents : %s", file->getContents().c_str()); } } //we finished working with this component. entity.remove<Comp::PlayerData_v1>(); } } };
/** * This function will write into json file */ void JSONLoginID::update(entityx::ptr<entityx::EntityManager> es, entityx::ptr<entityx::EventManager> events, double dt) { entityx::ptr<Comp::File> file; entityx::ptr<Comp::LoginID_v1> loginid; for (auto entity : es->entities_with_components(file, loginid)) { if (!entity.component<Comp::Read>()) { rapidjson::Document doc; doc.Parse<0>(file->getContents().c_str()); if (loginid->m_load_cb)//if we want to load data { if (doc.HasParseError()) { CCLOG("GetParseError %s\n", doc.GetParseError()); events->emit<Events::Error>(entity, "JSONLogin system parse error"); loginid->m_load_cb("",""); } else { rapidjson::Value& loginvalue = doc[loginid->m_name.c_str()]; if (!loginvalue.IsNull()){ if (loginvalue.HasMember("user")) { loginid->m_user = loginvalue["user"].GetString(); } if (loginvalue.HasMember("passwd")) { loginid->m_passwd = loginvalue["passwd"].GetString(); } } loginid->m_load_cb(loginid->m_user, loginid->m_passwd); } } else //write request { // must pass an allocator when the object may need to allocate memory rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); if (!doc.HasParseError() && doc.HasMember(loginid->m_name.c_str())) { //if we already have a login value in the file, we need to replace it rapidjson::Value& vholder = doc[loginid->m_name.c_str()]; if (vholder.HasMember("user")) { vholder["user"] = loginid->m_user.c_str(); } if (vholder.HasMember("passwd")) { vholder["passwd"] = loginid->m_passwd.c_str(); } } else { if (doc.HasParseError()) { //CCLOG("GetParseError %s\n", doc.GetParseError()); //no big deal we replace everything. doc.SetObject(); } rapidjson::Value vholder; vholder.SetObject(); vholder.AddMember("user", loginid->m_user.c_str(), allocator); vholder.AddMember("passwd", loginid->m_passwd.c_str(), allocator); doc.AddMember(loginid->m_name.c_str(), vholder, allocator); } //TMP debug rapidjson::StringBuffer strbuf; rapidjson::Writer<rapidjson::StringBuffer> writer(strbuf); doc.Accept(writer); file->setContents(strbuf.GetString()); //CCLOG("new contents : %s", file->getContents().c_str()); } //we finished working with this component. entity.remove<Comp::LoginID_v1>(); } } };
void DLCchecking::update(entityx::ptr<entityx::EntityManager> es, entityx::ptr<entityx::EventManager> events, double dt) { for (auto entity : es->entities_with_components<Comp::DataVerCheck>()) { entityx::ptr<Comp::DataVerCheck> dllist = entity.component<Comp::DataVerCheck>(); std::string url = dllist->m_url; CCLOG("Comp::DataVerCheck detected for %s", url.c_str()); if (!dllist->m_verlist.empty()) { //order the list of versions ascendantly std::sort(dllist->m_verlist.begin(), dllist->m_verlist.end()); //needed to make sure we should check from the last one first. //we need to check if the version url is valid ( contains a manifest.json ) std::string manifest_path = "manifest.json"; url += "/" + to_string(dllist->m_verlist.back()) + "/" + manifest_path; m_manifest = ""; CCLOG("DLCchecking reading from %s", url.c_str()); //list all files at given url CURLcode res; curl_easy_setopt(_curl, CURLOPT_URL, url.c_str()); #ifdef _DEBUG //curl_easy_setopt(_curl, CURLOPT_VERBOSE, 1L); #endif curl_easy_setopt(_curl, CURLOPT_WRITEFUNCTION, write_data); curl_easy_setopt(_curl, CURLOPT_WRITEDATA, &m_manifest); if (_connectionTimeout) curl_easy_setopt(_curl, CURLOPT_CONNECTTIMEOUT, _connectionTimeout); curl_easy_setopt(_curl, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt(_curl, CURLOPT_LOW_SPEED_LIMIT, LOW_SPEED_LIMIT); curl_easy_setopt(_curl, CURLOPT_LOW_SPEED_TIME, LOW_SPEED_TIME); res = curl_easy_perform(_curl); CCLOG("DLCchecking read from %s", url.c_str()); if (res != 0) { CCLOG("DLCchecking can not read from %s, error code is %d", url.c_str(), res); dllist->m_retries--; if (0 == dllist->m_retries) { CCLOGERROR("DLCchecking can not read from %s, error code is %d", url.c_str(), res); //signal error events->emit<Events::Error>(entity, "DLCchecking system"); //we give up on this entity entity.destroy(); } } else { //read the downloaded manifest to compare versions rapidjson::Document json; json.Parse<0>(m_manifest.c_str()); if (json.HasParseError()) { CCLOG("GetParseError %s\n", json.GetParseError()); //version will be removed from the list later. } else { //is it possible to update ? bool dlc_update_allowed = false; //do we need to update ? bool dlc_update_required = false; std::string minAppVersionstr = cocostudio::DictionaryHelper::getInstance()->getStringValue_json(json, "minAppVersion", ""); std::string dataVersionstr = cocostudio::DictionaryHelper::getInstance()->getStringValue_json(json, "dataVersion", ""); if ( minAppVersionstr != "" && dataVersionstr != "") //if we cannot read the version. we dont download. better safe than sorry. { Version version(dataVersionstr); Version maversion(minAppVersionstr); //guarantee same major + minor version number if (version[0] == dllist->m_current_dataVersion[0] && version[1] == dllist->m_current_dataVersion[1] ) { if(dllist->m_current_dataVersion <= version) //if we have the exact same data version : developer update or current version hotfix. { dlc_update_required = true; if (maversion <= dllist->m_currentAppVersion) // instead of minAppVersion we could use the current app version name from APK { dlc_update_allowed = true; } } } } // ( version != "") if (dlc_update_required && dlc_update_allowed) { //We found the advised download. we emit event and start downloading already. events->emit<Events::DownloadAdvised>(dllist->m_url , dllist->m_verlist.back(), manifest_path , true); //prepare the list of downloads const rapidjson::Value & assets = cocostudio::DictionaryHelper::getInstance()->getSubDictionary_json(json, "assets"); for (rapidjson::Value::ConstMemberIterator m = assets.MemberonBegin(); m != assets.MemberonEnd(); ++m) { std::string filename = m->name.GetString(); std::string filehash = cocostudio::DictionaryHelper::getInstance()->getStringValue_json(m->value, "md5", "error"); //lowering filehash to be sure std::transform(filehash.begin(), filehash.end(), filehash.begin(), ::tolower); //std::cout << filename << " : " << filehash << std::endl; entityx::Entity newentity = es->create(); newentity.assign<Comp::LocalFile>(filename); newentity.assign<Comp::RemoteMD5>(filehash); newentity.assign<Comp::RemoteFile>(dllist->m_url + "/" + to_string(dllist->m_verlist.back()), filename); newentity.assign<Comp::ProgressValue>(1); } //downloading only the last version should always be enough ( avoiding too many downloads - keeping all data for one version in same place ) //if (dllist->m_verlist.empty()) //if we checked all versions //{ entity.remove<Comp::DataVerCheck>(); //} //we dont need to do anything more with this entity //updating from the latest data url is enough. entity.destroy(); } } //remove the version checked from the list dllist->m_verlist.pop_back(); //In case of error, we should check the next version in stack on next update. //If success this will not be done ( entity destroyed ) } //exit this loop. one per update is enough. //The remaining versions will be checked on next update. break; } else //no version left to check { //we dont need to do anything more with this entity entity.destroy(); } } };