aboutsummaryrefslogtreecommitdiff
path: root/build/android
Commit message (Expand)AuthorAge
* Android: Update build system for ndk-r15xstujones112017-12-04
* Move files to subdirectories (#6599)Vitaliy2017-11-08
* FormSpec : Add an auto vertical scrollbar to the textareaadelcoding12017-10-09
* Mapgen: Add Carpathian mapgen (#6015)Vaughan Lapsley2017-07-06
* Isolate irrlicht references and use a singleton (#6041)Loïc Blot2017-06-26
* Remove legacy content_abm.{cpp,h}Loïc Blot2017-06-14
* Improve the path select GUI (#5852)red-0012017-06-11
* Revert "Remove deprecated code segments (#5891)"Loïc Blot2017-06-06
* Remove deprecated code segments (#5891)Thomas--S2017-06-04
* Android: update build tools version + versionCode bump for releaseLoic Blot2017-06-03
* Android dependencies updates (#5755)Loïc Blot2017-05-13
* Move KeyList & InputHandler from game.h to client/inputhandler.h (#5752)Loïc Blot2017-05-13
* Clean up numeric.h and split FacePositionCache from itShadowNinja2017-05-06
* [CSM] Add camera API (#5609)bigfoot5472017-05-05
* Fix Android build since 2818d3f2244d2146a5cdb61cd41f6561c514f97cLoic Blot2017-04-26
* Player data to Database (#5475)Loïc Blot2017-04-23
* MeshUpdateQueue: Add a MapBlock cache that minimizes the amount of MapBlock c...Perttu Ahola2017-04-17
* Disable android leveldb by default (#5596)Nathanaël Courant2017-04-16
* Fix android buildLoic Blot2017-04-14
* Update embedded jsoncpp from unk version to 0.10.6 + move libs to lib/ instea...Loïc Blot2017-04-02
* Add missing source to android build (#5496)Uwe Koloska2017-04-01
* Fix undefined references (#5400)Wayward One2017-03-15
* Fix android buildLoic Blot2017-02-08
* Add ItemStack key-value meta storagerubenwardy2017-02-04
* Derive NodeMetaRef from MetaDataRefrubenwardy2017-02-04
* Derive NodeMetadata from Metadatarubenwardy2017-02-04
* Environment & IGameDef code refactoring (#4985)Ner'zhul2017-01-09
* Add raycast.cpp and tileanimation.cpp to Android.mkWayward12017-01-05
* Add gradle wrapper (#4954)Ner'zhul2016-12-24
* Update Android build tools to latest version (#4872)rubenwardy2016-12-24
* Bump version to 0.4.15sfan52016-12-22
* Android: Workarounds for Googles completely broken NDKsfan52016-12-22
* Android: update curl and libgmpest312016-12-21
* Fix sqlite databases being read-only on 64bit Android by patching sqlite (#4871)rubenwardy2016-12-09
* Android: fix build and update depsest312016-12-07
* Add missing remoteplayer.cpp to Android buildNer'zhul2016-10-28
* Fix for failure to find jsoncpp in android build (#4456)Rogier-52016-08-19
* Increase android versionCode (#4350)Ner'zhul2016-07-28
* Add MapSettingsManager and new mapgen setting script API functionskwolekr2016-07-03
* Fix android buildest312016-06-11
* Tell irrlicht if we handle a key or not.est312016-05-26
* Android: enable parallelism for main target tooest312016-05-16
* Bump version to 0.4.14sfan52016-05-15
* Fix android build by fixing patch line endingsest312016-05-14
* Fix locked hardware buttons on AndroidMaksim Gamarnik2016-05-14
* Android: download deps using httpsest312016-05-12
* Android: update openssl to 1.0.2hest312016-05-12
* Upgrade Android build to Gradle build systemShadowNinja2016-04-28
* Android: Update dependencies, GMP was required as a dependencyMaksim Gamarnik2016-04-26
* Move AreaStore to utilShadowNinja2016-03-07
pan class="hl kwc">std::set<char> &symbols) { std::getline(is, dep); dep = trim(dep); symbols.clear(); size_t pos = dep.size(); while(pos > 0 && !string_allowed(dep.substr(pos-1, 1), MODNAME_ALLOWED_CHARS)){ // last character is a symbol, not part of the modname symbols.insert(dep[pos-1]); --pos; } dep = trim(dep.substr(0, pos)); return dep != ""; } void parseModContents(ModSpec &spec) { // NOTE: this function works in mutual recursion with getModsInPath spec.depends.clear(); spec.optdepends.clear(); spec.is_modpack = false; spec.modpack_content.clear(); // Handle modpacks (defined by containing modpack.txt) std::ifstream modpack_is((spec.path+DIR_DELIM+"modpack.txt").c_str()); if(modpack_is.good()){ //a modpack, recursively get the mods in it modpack_is.close(); // We don't actually need the file spec.is_modpack = true; spec.modpack_content = getModsInPath(spec.path, true); // modpacks have no dependencies; they are defined and // tracked separately for each mod in the modpack } else{ // not a modpack, parse the dependencies std::ifstream is((spec.path+DIR_DELIM+"depends.txt").c_str()); while(is.good()){ std::string dep; std::set<char> symbols; if(parseDependsLine(is, dep, symbols)){ if(symbols.count('?') != 0){ spec.optdepends.insert(dep); } else{ spec.depends.insert(dep); } } } } } std::map<std::string, ModSpec> getModsInPath(std::string path, bool part_of_modpack) { // NOTE: this function works in mutual recursion with parseModContents std::map<std::string, ModSpec> result; std::vector<fs::DirListNode> dirlist = fs::GetDirListing(path); for(u32 j=0; j<dirlist.size(); j++){ if(!dirlist[j].dir) continue; std::string modname = dirlist[j].name; // Ignore all directories beginning with a ".", especially // VCS directories like ".git" or ".svn" if(modname[0] == '.') continue; std::string modpath = path + DIR_DELIM + modname; ModSpec spec(modname, modpath); spec.part_of_modpack = part_of_modpack; parseModContents(spec); result.insert(std::make_pair(modname, spec)); } return result; } std::map<std::string, ModSpec> flattenModTree(std::map<std::string, ModSpec> mods) { std::map<std::string, ModSpec> result; for(std::map<std::string,ModSpec>::iterator it = mods.begin(); it != mods.end(); ++it) { ModSpec mod = (*it).second; if(mod.is_modpack) { std::map<std::string, ModSpec> content = flattenModTree(mod.modpack_content); result.insert(content.begin(),content.end()); result.insert(std::make_pair(mod.name,mod)); } else //not a modpack { result.insert(std::make_pair(mod.name,mod)); } } return result; } std::vector<ModSpec> flattenMods(std::map<std::string, ModSpec> mods) { std::vector<ModSpec> result; for(std::map<std::string,ModSpec>::iterator it = mods.begin(); it != mods.end(); ++it) { ModSpec mod = (*it).second; if(mod.is_modpack) { std::vector<ModSpec> content = flattenMods(mod.modpack_content); result.reserve(result.size() + content.size()); result.insert(result.end(),content.begin(),content.end()); } else //not a modpack { result.push_back(mod); } } return result; } ModConfiguration::ModConfiguration(std::string worldpath) { SubgameSpec gamespec = findWorldSubgame(worldpath); // Add all game mods and all world mods addModsInPath(gamespec.gamemods_path); addModsInPath(worldpath + DIR_DELIM + "worldmods"); // check world.mt file for mods explicitely declared to be // loaded or not by a load_mod_<modname> = ... line. std::string worldmt = worldpath+DIR_DELIM+"world.mt"; Settings worldmt_settings; worldmt_settings.readConfigFile(worldmt.c_str()); std::vector<std::string> names = worldmt_settings.getNames(); std::set<std::string> include_mod_names; for(std::vector<std::string>::iterator it = names.begin(); it != names.end(); ++it) { std::string name = *it; // for backwards compatibility: exclude only mods which are // explicitely excluded. if mod is not mentioned at all, it is // enabled. So by default, all installed mods are enabled. if (name.compare(0,9,"load_mod_") == 0 && worldmt_settings.getBool(name)) { include_mod_names.insert(name.substr(9)); } } // Collect all mods that are also in include_mod_names std::vector<ModSpec> addon_mods; for(std::set<std::string>::const_iterator it_path = gamespec.addon_mods_paths.begin(); it_path != gamespec.addon_mods_paths.end(); ++it_path) { std::vector<ModSpec> addon_mods_in_path = flattenMods(getModsInPath(*it_path)); for(std::vector<ModSpec>::iterator it = addon_mods_in_path.begin(); it != addon_mods_in_path.end(); ++it) { ModSpec& mod = *it; if(include_mod_names.count(mod.name) != 0) addon_mods.push_back(mod); else worldmt_settings.setBool("load_mod_" + mod.name, false); } } worldmt_settings.updateConfigFile(worldmt.c_str()); addMods(addon_mods); // report on name conflicts if(!m_name_conflicts.empty()){ std::string s = "Unresolved name conflicts for mods "; for(std::set<std::string>::const_iterator it = m_name_conflicts.begin(); it != m_name_conflicts.end(); ++it) { if(it != m_name_conflicts.begin()) s += ", "; s += std::string("\"") + (*it) + "\""; } s += "."; throw ModError(s); } // get the mods in order resolveDependencies(); } void ModConfiguration::addModsInPath(std::string path) { addMods(flattenMods(getModsInPath(path))); } void ModConfiguration::addMods(std::vector<ModSpec> new_mods) { // Maintain a map of all existing m_unsatisfied_mods. // Keys are mod names and values are indices into m_unsatisfied_mods. std::map<std::string, u32> existing_mods; for(u32 i = 0; i < m_unsatisfied_mods.size(); ++i){ existing_mods[m_unsatisfied_mods[i].name] = i; } // Add new mods for(int want_from_modpack = 1; want_from_modpack >= 0; --want_from_modpack){ // First iteration: // Add all the mods that come from modpacks // Second iteration: // Add all the mods that didn't come from modpacks std::set<std::string> seen_this_iteration; for(std::vector<ModSpec>::const_iterator it = new_mods.begin(); it != new_mods.end(); ++it){ const ModSpec &mod = *it; if(mod.part_of_modpack != want_from_modpack) continue; if(existing_mods.count(mod.name) == 0){ // GOOD CASE: completely new mod. m_unsatisfied_mods.push_back(mod); existing_mods[mod.name] = m_unsatisfied_mods.size() - 1; } else if(seen_this_iteration.count(mod.name) == 0){ // BAD CASE: name conflict in different levels. u32 oldindex = existing_mods[mod.name]; const ModSpec &oldmod = m_unsatisfied_mods[oldindex]; actionstream<<"WARNING: Mod name conflict detected: \"" <<mod.name<<"\""<<std::endl <<"Will not load: "<<oldmod.path<<std::endl <<"Overridden by: "<<mod.path<<std::endl; m_unsatisfied_mods[oldindex] = mod; // If there was a "VERY BAD CASE" name conflict // in an earlier level, ignore it. m_name_conflicts.erase(mod.name); } else{ // VERY BAD CASE: name conflict in the same level. u32 oldindex = existing_mods[mod.name]; const ModSpec &oldmod = m_unsatisfied_mods[oldindex]; errorstream<<"WARNING: Mod name conflict detected: \"" <<mod.name<<"\""<<std::endl <<"Will not load: "<<oldmod.path<<std::endl <<"Will not load: "<<mod.path<<std::endl; m_unsatisfied_mods[oldindex] = mod; m_name_conflicts.insert(mod.name); } seen_this_iteration.insert(mod.name); } } } void ModConfiguration::resolveDependencies() { // Step 1: Compile a list of the mod names we're working with std::set<std::string> modnames; for(std::vector<ModSpec>::iterator it = m_unsatisfied_mods.begin(); it != m_unsatisfied_mods.end(); ++it){ modnames.insert((*it).name); } // Step 2: get dependencies (including optional dependencies) // of each mod, split mods into satisfied and unsatisfied std::list<ModSpec> satisfied; std::list<ModSpec> unsatisfied; for(std::vector<ModSpec>::iterator it = m_unsatisfied_mods.begin(); it != m_unsatisfied_mods.end(); ++it){ ModSpec mod = *it; mod.unsatisfied_depends = mod.depends; // check which optional dependencies actually exist for(std::set<std::string>::iterator it_optdep = mod.optdepends.begin(); it_optdep != mod.optdepends.end(); ++it_optdep){ std::string optdep = *it_optdep; if(modnames.count(optdep) != 0) mod.unsatisfied_depends.insert(optdep); } // if a mod has no depends it is initially satisfied if(mod.unsatisfied_depends.empty()) satisfied.push_back(mod); else unsatisfied.push_back(mod); } // Step 3: mods without unmet dependencies can be appended to // the sorted list. while(!satisfied.empty()){ ModSpec mod = satisfied.back(); m_sorted_mods.push_back(mod); satisfied.pop_back(); for(std::list<ModSpec>::iterator it = unsatisfied.begin(); it != unsatisfied.end(); ){ ModSpec& mod2 = *it; mod2.unsatisfied_depends.erase(mod.name); if(mod2.unsatisfied_depends.empty()){ satisfied.push_back(mod2); it = unsatisfied.erase(it); } else{ ++it; } } } // Step 4: write back list of unsatisfied mods m_unsatisfied_mods.assign(unsatisfied.begin(), unsatisfied.end()); } #if USE_CURL Json::Value getModstoreUrl(std::string url) { std::vector<std::string> extra_headers; bool special_http_header = true; try { special_http_header = g_settings->getBool("modstore_disable_special_http_header"); } catch (SettingNotFoundException) {} if (special_http_header) { extra_headers.push_back("Accept: application/vnd.minetest.mmdb-v1+json"); } return fetchJsonValue(url, special_http_header ? &extra_headers : NULL); } #endif