mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-11-04 01:05:48 +01:00 
			
		
		
		
	Merge pull request #436 from doserj/mod_selection
Fix some crashes and improved behaviour for mod selection gui
This commit is contained in:
		@@ -69,15 +69,13 @@ GUIConfigureWorld::GUIConfigureWorld(gui::IGUIEnvironment* env,
 | 
			
		||||
	m_worldmods = flattenModTree(getModsInPath(worldmods_path));
 | 
			
		||||
 | 
			
		||||
	// fill m_addontree with add-on mods
 | 
			
		||||
	ModSpec addons("Add-Ons");
 | 
			
		||||
	std::set<std::string> paths = m_gspec.addon_mods_paths;
 | 
			
		||||
	for(std::set<std::string>::iterator it=paths.begin();
 | 
			
		||||
		it != paths.end(); ++it)
 | 
			
		||||
	{
 | 
			
		||||
		std::map<std::string,ModSpec> mods = getModsInPath(*it);
 | 
			
		||||
		addons.modpack_content.insert(mods.begin(), mods.end());
 | 
			
		||||
		m_addontree.insert(mods.begin(), mods.end());
 | 
			
		||||
	}
 | 
			
		||||
	m_addontree.insert(std::make_pair(addons.name,addons));
 | 
			
		||||
 | 
			
		||||
	// expand modpacks
 | 
			
		||||
	m_addonmods = flattenModTree(m_addontree);
 | 
			
		||||
@@ -116,7 +114,7 @@ GUIConfigureWorld::GUIConfigureWorld(gui::IGUIEnvironment* env,
 | 
			
		||||
		ModSpec mod = (*it).second;
 | 
			
		||||
		// a mod is new if it is not a modpack, and does not occur in
 | 
			
		||||
		// mod_names
 | 
			
		||||
		if(mod.modpack_content.empty() &&
 | 
			
		||||
		if(!mod.is_modpack &&
 | 
			
		||||
		   mod_names.count(modname) == 0)
 | 
			
		||||
			m_new_mod_names.insert(modname);
 | 
			
		||||
	}
 | 
			
		||||
@@ -253,7 +251,9 @@ void GUIConfigureWorld::regenerateGui(v2u32 screensize)
 | 
			
		||||
		rect += v2s32(220, 0) + topleft;
 | 
			
		||||
		m_treeview = Environment->addTreeView(rect, this,
 | 
			
		||||
											  GUI_ID_MOD_TREEVIEW,true);
 | 
			
		||||
		buildTreeView(m_addontree, m_treeview->getRoot());
 | 
			
		||||
		gui::IGUITreeViewNode* node 
 | 
			
		||||
			= m_treeview->getRoot()->addChildBack(L"Add-Ons");
 | 
			
		||||
		buildTreeView(m_addontree, node);
 | 
			
		||||
	}
 | 
			
		||||
	{
 | 
			
		||||
		core::rect<s32> rect(0, 0, 120, 30);
 | 
			
		||||
@@ -407,8 +407,12 @@ bool GUIConfigureWorld::OnEvent(const SEvent& event)
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
			case GUI_ID_ENABLEALL: {
 | 
			
		||||
				if(selected_node != NULL && selected_node->getText() != NULL)
 | 
			
		||||
				{
 | 
			
		||||
				if(selected_node != NULL && selected_node->getParent() == m_treeview->getRoot())
 | 
			
		||||
				{  
 | 
			
		||||
					enableAllMods(m_addonmods,true);
 | 
			
		||||
				} 
 | 
			
		||||
				else if(selected_node != NULL && selected_node->getText() != NULL)
 | 
			
		||||
				{  
 | 
			
		||||
					std::string modname = wide_to_narrow(selected_node->getText());
 | 
			
		||||
					ModSpec mod = m_addonmods[modname];
 | 
			
		||||
					enableAllMods(mod.modpack_content,true);
 | 
			
		||||
@@ -416,6 +420,10 @@ bool GUIConfigureWorld::OnEvent(const SEvent& event)
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
			case GUI_ID_DISABLEALL: {
 | 
			
		||||
				if(selected_node != NULL && selected_node->getParent() == m_treeview->getRoot())
 | 
			
		||||
				{
 | 
			
		||||
					enableAllMods(m_addonmods,false);
 | 
			
		||||
				} 
 | 
			
		||||
				if(selected_node != NULL && selected_node->getText() != NULL)
 | 
			
		||||
				{
 | 
			
		||||
					std::string modname = wide_to_narrow(selected_node->getText());
 | 
			
		||||
@@ -517,7 +525,7 @@ void GUIConfigureWorld::buildTreeView(std::map<std::string, ModSpec> mods,
 | 
			
		||||
		gui::IGUITreeViewNode* new_node = 
 | 
			
		||||
			node->addChildBack(narrow_to_wide(modname).c_str());
 | 
			
		||||
		m_nodes.insert(std::make_pair(modname, new_node));
 | 
			
		||||
		if(!mod.modpack_content.empty())
 | 
			
		||||
		if(mod.is_modpack)
 | 
			
		||||
			buildTreeView(mod.modpack_content, new_node);
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
@@ -552,23 +560,33 @@ void GUIConfigureWorld::adjustSidebar()
 | 
			
		||||
		modname_w = L"N/A";
 | 
			
		||||
	std::string modname = wide_to_narrow(modname_w);
 | 
			
		||||
 | 
			
		||||
	// if modpack, show enable/disable all buttons. otherwise, show
 | 
			
		||||
	// enabled checkbox
 | 
			
		||||
	if(node->hasChilds())
 | 
			
		||||
	{
 | 
			
		||||
		m_enabled_checkbox->setVisible(false);
 | 
			
		||||
		m_disableall->setVisible(true);
 | 
			
		||||
		m_enableall->setVisible(true);
 | 
			
		||||
		m_modname_text->setText((L"Modpack: "+modname_w).c_str());
 | 
			
		||||
	}	
 | 
			
		||||
	else	
 | 
			
		||||
	// if no mods installed, don't show buttons or checkbox on the sidebar
 | 
			
		||||
	if(node->getParent() == m_treeview->getRoot() && !node->hasChilds())
 | 
			
		||||
	{
 | 
			
		||||
		m_disableall->setVisible(false);
 | 
			
		||||
		m_enableall->setVisible(false);
 | 
			
		||||
		m_enabled_checkbox->setVisible(true);
 | 
			
		||||
		m_modname_text->setText((L"Mod: "+modname_w).c_str());
 | 
			
		||||
		m_enabled_checkbox->setVisible(false);
 | 
			
		||||
	} 
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		// if modpack, show enable/disable all buttons. otherwise, show
 | 
			
		||||
		// enabled checkbox
 | 
			
		||||
		if(node->getParent() == m_treeview->getRoot() ||
 | 
			
		||||
		   m_addonmods[modname].is_modpack)
 | 
			
		||||
		{
 | 
			
		||||
			m_enabled_checkbox->setVisible(false);
 | 
			
		||||
			m_disableall->setVisible(true);
 | 
			
		||||
			m_enableall->setVisible(true);
 | 
			
		||||
			m_modname_text->setText((L"Modpack: "+modname_w).c_str());
 | 
			
		||||
		}	
 | 
			
		||||
		else	
 | 
			
		||||
		{
 | 
			
		||||
			m_disableall->setVisible(false);
 | 
			
		||||
			m_enableall->setVisible(false);
 | 
			
		||||
			m_enabled_checkbox->setVisible(true);
 | 
			
		||||
			m_modname_text->setText((L"Mod: "+modname_w).c_str());
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// the mod is enabled unless it is disabled in the world.mt settings. 
 | 
			
		||||
	bool mod_enabled = true;
 | 
			
		||||
	if(m_settings.exists("load_mod_"+modname))
 | 
			
		||||
@@ -616,7 +634,7 @@ void GUIConfigureWorld::enableAllMods(std::map<std::string, ModSpec> mods,bool e
 | 
			
		||||
		it != mods.end(); ++it)
 | 
			
		||||
	{
 | 
			
		||||
		ModSpec mod = (*it).second;
 | 
			
		||||
		if(!mod.modpack_content.empty()) 
 | 
			
		||||
		if(mod.is_modpack) 
 | 
			
		||||
			// a modpack, recursively enable all mods in it
 | 
			
		||||
			enableAllMods(mod.modpack_content,enable);
 | 
			
		||||
		else // not a modpack
 | 
			
		||||
 
 | 
			
		||||
@@ -1048,12 +1048,12 @@ bool GUIMainMenu::OnEvent(const SEvent& event)
 | 
			
		||||
					GUIConfigureWorld *menu = new GUIConfigureWorld(env, parent,
 | 
			
		||||
										-1, menumgr, wspec);
 | 
			
		||||
					menu->drop();
 | 
			
		||||
					return true;
 | 
			
		||||
				}
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
			case GUI_ID_SERVERLIST_DELETE: {
 | 
			
		||||
				gui::IGUIListBox *serverlist = (gui::IGUIListBox*)getElementFromId(GUI_ID_SERVERLIST);
 | 
			
		||||
				u16 selected = ((gui::IGUIListBox*)serverlist)->getSelected();
 | 
			
		||||
				s32 selected = ((gui::IGUIListBox*)serverlist)->getSelected();
 | 
			
		||||
				if (selected == -1) return true;
 | 
			
		||||
				ServerList::deleteEntry(m_data->servers[selected]);
 | 
			
		||||
				m_data->servers = ServerList::getLocal();
 | 
			
		||||
 
 | 
			
		||||
@@ -46,6 +46,7 @@ std::map<std::string, ModSpec> getModsInPath(std::string path)
 | 
			
		||||
			modpack_is.close(); // We don't actually need the file
 | 
			
		||||
			ModSpec spec(modname,modpath);
 | 
			
		||||
			spec.modpack_content = getModsInPath(modpath);
 | 
			
		||||
			spec.is_modpack = true;
 | 
			
		||||
			result.insert(std::make_pair(modname,spec));
 | 
			
		||||
		}
 | 
			
		||||
		else // not a modpack, add the modspec
 | 
			
		||||
@@ -76,7 +77,7 @@ std::map<std::string, ModSpec> flattenModTree(std::map<std::string, ModSpec> mod
 | 
			
		||||
		it != mods.end(); ++it)
 | 
			
		||||
	{
 | 
			
		||||
		ModSpec mod = (*it).second;
 | 
			
		||||
		if(!mod.modpack_content.empty()) //is a modpack
 | 
			
		||||
		if(mod.is_modpack)
 | 
			
		||||
		{
 | 
			
		||||
			std::map<std::string, ModSpec> content = 
 | 
			
		||||
				flattenModTree(mod.modpack_content);
 | 
			
		||||
@@ -98,7 +99,7 @@ std::vector<ModSpec> flattenMods(std::map<std::string, ModSpec> mods)
 | 
			
		||||
		it != mods.end(); ++it)
 | 
			
		||||
	{
 | 
			
		||||
		ModSpec mod = (*it).second;
 | 
			
		||||
		if(!mod.modpack_content.empty()) //is a modpack
 | 
			
		||||
		if(mod.is_modpack)
 | 
			
		||||
		{
 | 
			
		||||
			std::vector<ModSpec> content = flattenMods(mod.modpack_content);
 | 
			
		||||
			result.reserve(result.size() + content.size());
 | 
			
		||||
 
 | 
			
		||||
@@ -53,6 +53,8 @@ struct ModSpec
 | 
			
		||||
	//if normal mod:
 | 
			
		||||
	std::set<std::string> depends;
 | 
			
		||||
	std::set<std::string> unsatisfied_depends;
 | 
			
		||||
 | 
			
		||||
	bool is_modpack;
 | 
			
		||||
	// if modpack:
 | 
			
		||||
	std::map<std::string,ModSpec> modpack_content;
 | 
			
		||||
	ModSpec(const std::string name_="", const std::string path_="",
 | 
			
		||||
@@ -61,6 +63,7 @@ struct ModSpec
 | 
			
		||||
		path(path_),
 | 
			
		||||
		depends(depends_),
 | 
			
		||||
		unsatisfied_depends(depends_),
 | 
			
		||||
		is_modpack(false),	
 | 
			
		||||
		modpack_content()	
 | 
			
		||||
	{}
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -244,7 +244,9 @@ public:
 | 
			
		||||
 | 
			
		||||
			updated[name] = true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		else //file contains a setting which is not in m_settings
 | 
			
		||||
			value_changed=true;
 | 
			
		||||
			
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user