예제 #1
0
bool UninstallAllThread::hasPaidBranch(UserCore::Item::ItemInfoI* item)
{
	for (size_t z=0; z<item->getBranchCount(); z++)
	{
		UserCore::Item::BranchInfoI* bi = item->getBranch(z);

		if (HasAllFlags(bi->getFlags(), UserCore::Item::BranchInfoI::BF_ONACCOUNT) && !HasAnyFlags(bi->getFlags(), UserCore::Item::BranchInfoI::BF_FREE|UserCore::Item::BranchInfoI::BF_DEMO|UserCore::Item::BranchInfoI::BF_TEST))
			return true;
	}
	return false;
}
예제 #2
0
void InternalLink::showPreorderPrompt(DesuraId id, bool isPreload)
{
	UserCore::Item::ItemInfoI* item = GetUserCore()->getItemManager()->findItemInfo( id );

	if (!item)
		return;

	UserCore::Item::BranchInfoI* bi = item->getCurrentBranch();

	if (!bi)
	{
		for (size_t x=0; x<item->getBranchCount(); x++)
		{
			UserCore::Item::BranchInfoI *temp = item->getBranch(x);

			if (temp->isPreOrder())
			{
				bi = temp;
				break;
			}
		}
	}

	if (!bi)
		return;

	const char* str = bi->getPreOrderExpDate();

	uint32 days;
	uint32 hours;
	std::string time_available = UTIL::MISC::dateTimeToDisplay(str);

	UTIL::MISC::getTimeDiffFromNow(str, days, hours);

	gcString title(Managers::GetString("#IF_PRELOADLAUNCH_TITLE"), item->getName());
	gcString msg(Managers::GetString("#IF_PRELOADLAUNCH"), item->getName(), 
					days, 
						Managers::GetString(isPreload?"#IF_PRELOADLAUNCH_PRELOADED":"#IF_PRELOADLAUNCH_PREORDERED"), 
							time_available, 
								Managers::GetString(days == 1 ? "#IF_PRELOADLAUNCH_WORD_DAY":"#IF_PRELOADLAUNCH_WORD_DAYS"));

	PreloadButtonHelper pobh(id);

	if (pobh.m_bOtherBranches)
		msg += gcString(Managers::GetString("#IF_PRELOADLAUNCH_INSTALLOTHER_INFO"), item->getName());

	gcMessageBox(g_pMainApp->getMainWindow(), msg, title, wxICON_EXCLAMATION|wxCLOSE, &pobh);
}
예제 #3
0
void CDKInfo::setInfo(DesuraId id, const char* key)
{
	BasePage::setInfo(id);

	UserCore::Item::ItemInfoI *info = getItemInfo();

	if (!info)
	{
		GetParent()->Close();
		return;
	}

	m_butLaunch->Enable(info->isLaunchable());

	if (checkForArma(id, key))
		return;

	m_tbCdKey->ChangeValue(key);
	tokenizeKey(key);

	UserCore::Item::BranchInfoI* cb = info->getCurrentBranch();

	if (cb && cb->isSteamGame())
	{
		m_labInfo->SetLabel(gcWString(Managers::GetString(L"#CDK_INFO_STEAM"), info->getName()));
		m_labInfo->Wrap(360);

		m_butActivate = new gcButton(this, wxID_ANY, Managers::GetString(L"#CDK_ACTIVATE"));

		m_pButtonSizer->Clear(false);
		m_pButtonSizer->Add( 0, 0, 1, wxEXPAND, 5 );
		m_pButtonSizer->Add(m_butActivate, 0, wxTOP|wxBOTTOM|wxLEFT, 5);
		m_pButtonSizer->Add(m_butLaunch, 0, wxTOP|wxBOTTOM|wxLEFT, 5);
		m_pButtonSizer->Add(m_butClose, 0, wxALL, 5);

		Layout();
		Refresh(false);

		setParentSize(-1, 140);
	}
}
예제 #4
0
void InstallBranch::onChoice(wxCommandEvent& event)
{
	MCFBranch b = getBranch();

	if (b == UINT_MAX || b == (UINT_MAX - 1))
	{
		if (b == UINT_MAX)
			m_butInstall->SetLabel(Managers::GetString(L"#PLAY"));
		else
			m_butInstall->SetLabel(Managers::GetString(L"#FIND"));

		m_butInstall->Enable(true);
		return;
	}

	UserCore::Item::ItemInfoI* pItemInfo = GetUserCore()->getItemManager()->findItemInfo(m_Item);

	if ((m_bIsMod || m_bIsExpansion) && !m_bSelectBranch)
		pItemInfo = GetUserCore()->getItemManager()->findItemInfo(pItemInfo->getParentId());

	UserCore::Item::BranchInfoI* bi = pItemInfo->getBranchById(b);

	m_bBuy = (!(bi->getFlags()&UserCore::Item::BranchInfoI::BF_ONACCOUNT) && !(bi->getFlags()&UserCore::Item::BranchInfoI::BF_FREE));

	if (m_bBuy)
		m_butInstall->SetLabel(Managers::GetString(L"#PURCHASE"));
	else
		m_butInstall->SetLabel(Managers::GetString(L"#INSTALL"));

	bool noRelease = HasAllFlags(bi->getFlags(), UserCore::Item::BranchInfoI::BF_NORELEASES);
	bool isPreorder = bi->isPreOrder();
	bool onAccount = HasAllFlags(bi->getFlags(), UserCore::Item::BranchInfoI::BF_ONACCOUNT);

	m_butInstall->Enable(!(noRelease && isPreorder && onAccount));
}
예제 #5
0
void UninstallInfoPage::init()
{
	UserCore::Item::ItemInfoI *info = getItemInfo();

	if (!info)
	{
		Close();
		return;
	}


	bool hasPaidBranch = false;

	for (size_t x=0; x<info->getBranchCount(); x++)
	{
		UserCore::Item::BranchInfoI* b = info->getBranch(x);

		if (b && HasAnyFlags(b->getFlags(), UserCore::Item::BranchInfoI::BF_ONACCOUNT) && !HasAnyFlags(b->getFlags(), UserCore::Item::BranchInfoI::BF_DEMO|UserCore::Item::BranchInfoI::BF_FREE|UserCore::Item::BranchInfoI::BF_TEST))
			hasPaidBranch = true;
	}

	if (hasPaidBranch)
	{
		m_cbAccount->Enable(false);
		m_cbAccount->SetValue(false);
	}

	if (info->getId().getType() == DesuraId::TYPE_LINK)
	{
		m_cbAccount->Enable(false);
		m_cbAccount->SetValue(true);

		m_cbComplete->Enable(false);
		m_cbComplete->SetValue(true);
	}


	m_labInfo->SetLabel(gcWString(Managers::GetString(L"#UNF_CONFIRM"), info->getName()));
	m_labInfo->Wrap( 360 );
}
예제 #6
0
bool VerifyServiceTask::checkBranch()
{
	UserCore::Item::ItemInfo* pItem = getItemInfo();
	UserCore::Item::BranchInfoI* pBranch = pItem->getCurrentBranch();
	
	if (!pBranch)
		return false;

	if (pBranch && pItem->isDownloadable() && !pBranch->isDownloadable())
	{
		finishVerify(UserCore::Misc::VerifyComplete::V_RESET);
		return true;
	}

	if (m_McfBranch != 0 && pBranch && pBranch->getBranchId() != m_McfBranch)
	{
		finishVerify(UserCore::Misc::VerifyComplete::V_SWITCHBRANCH);
		return true;
	}

	m_McfBranch = pItem->getCurrentBranch()->getBranchId();
	return false;
}
예제 #7
0
int InstallBranch::setInfo(DesuraId id, bool selectBranch)
{
	m_bSelectBranch = selectBranch;
	UserCore::Item::ItemInfoI* pItemInfo = GetUserCore()->getItemManager()->findItemInfo(id);

	if (!pItemInfo)
		return 1;

	m_bIsMod = id.getType() == DesuraId::TYPE_MOD;
	m_bIsExpansion = m_bIsMod == false && pItemInfo->getParentId().getType() == DesuraId::TYPE_GAME;

	m_Item = id;

	gcWString parName;
	gcWString itemName = pItemInfo->getName();
	
	DesuraId par = pItemInfo->getParentId();
	UserCore::Item::ItemInfoI *parInfo = NULL;
	if (par.isOk())
	{
		parInfo = GetUserCore()->getItemManager()->findItemInfo(par);

		if (parInfo)
			parName = gcWString(parInfo->getName());
	}

	fixName(parName);
	fixName(itemName);

	if (selectBranch == false && m_bIsMod)
	{
		m_labInfo->SetLabel(gcWString(Managers::GetString(L"#IF_NOTFOUND"), itemName, parName));
		m_labInfo->Wrap( 350 );
	}
	else if (selectBranch == false && m_bIsExpansion)
	{
		m_labInfo->SetLabel(gcWString(Managers::GetString(L"#IF_NOTFOUND_GAME"), itemName, parName));
		m_labInfo->Wrap( 350 );
	}
	else
	{
		m_labInfo->SetLabel(gcWString(Managers::GetString(L"#IF_BRANCHINFO"), itemName));
		m_labInfo->Wrap( 350 );
	}

	uint32 count = 0;
	int32 full = -1;
	uint32 fullReadyCount = 0;
	m_bBuy = true;

	UserCore::Item::ItemInfoI *i = pItemInfo;

	bool isCheckingParent = (m_bIsMod || m_bIsExpansion) && !selectBranch;

	if (isCheckingParent)
	{
		if (!parInfo)
		{
			gcMessageBox(GetParent(), Managers::GetString(L"#IF_IIPARENT"), Managers::GetString(L"#IF_IIERRTITLE"));
			return 1;
		}

		i = parInfo;
	}

	std::vector<UserCore::Item::BranchInfoI*> bList;

	for (uint32 x=0; x<i->getBranchCount(); x++)
	{
		UserCore::Item::BranchInfoI* bi = i->getBranch(x);

		if (!bi)
			continue;

		uint32 flags = bi->getFlags();

		bool noRelease = HasAllFlags(flags, UserCore::Item::BranchInfoI::BF_NORELEASES);
		bool isPreorder = bi->isPreOrder();
		bool isDemo = HasAnyFlags(flags, UserCore::Item::BranchInfoI::BF_DEMO);
		bool onAccount = HasAllFlags(flags, UserCore::Item::BranchInfoI::BF_ONACCOUNT);
		bool locked = HasAnyFlags(flags, UserCore::Item::BranchInfoI::BF_MEMBERLOCK|UserCore::Item::BranchInfoI::BF_REGIONLOCK);
		bool test = HasAnyFlags(flags, UserCore::Item::BranchInfoI::BF_TEST);
		bool free = HasAnyFlags(flags, UserCore::Item::BranchInfoI::BF_FREE);

		if (noRelease && !isPreorder)
			continue;

		if (!onAccount && locked)
			continue;
		
		if (!selectBranch && (isDemo || test))
			continue;

		if ((free || onAccount) && isPreorder && !selectBranch)
			continue;

		bool globalFound = false;

		for (size_t x=0; x<bList.size(); x++)
		{
			if (bList[x]->getGlobalId() == bi->getGlobalId())
			{
				globalFound = true;
				break;
			}
		}

		if (globalFound)
			continue;

		if (isDemo || test)
		{
		}
		else if (full == -1 || ((!m_bBuy || onAccount) && !free))
		{
			if (full == -1 || m_bBuy)
			{
				//if this is the first full game or this is the first full game that you dont have to buy
				m_bBuy = (!onAccount && !free);
				full = count;
			}
			
			if (onAccount || free)
				fullReadyCount++;
		}

		bList.push_back(bi);
		count++;
	}

	for (size_t x=0; x<bList.size(); x++)
	{
		UserCore::Item::BranchInfoI* bi = bList[x];
		gcString name = bi->getName();
		gcWString title;
		
		uint32 flags = bi->getFlags();

		bool noRelease = HasAllFlags(flags, UserCore::Item::BranchInfoI::BF_NORELEASES);
		bool isPreorder = bi->isPreOrder();
		bool onAccount = HasAllFlags(flags, UserCore::Item::BranchInfoI::BF_ONACCOUNT);
		bool free = HasAnyFlags(flags, UserCore::Item::BranchInfoI::BF_FREE);

		if (!free)
			title = gcString("{0} - {1}", name, Managers::GetString("#IF_BROUGHT"));
		else
			title = gcString("{0} - {1}", name, Managers::GetString("#IF_FREE"));
		
		if (!free && !onAccount)
		{
			gcWString cost(bi->getCost());

			if (cost == "")
				cost = gcString(Managers::GetString("#TBA"));

			title = gcString("{0} - {1}", name, cost.c_str());
		}
		else if (isPreorder)
		{
			if (noRelease)
				title = gcString("{0} - {1}", name, Managers::GetString("#IF_PREORDERED_NORELEASE"));
			else
				title = gcString("{0} - {1}", name, Managers::GetString("#IF_PREORDERED"));
		}

		m_cbBranchList->Append(title, new BranchData(bi->getBranchId(), bi->getGlobalId()));
	}

	count = bList.size();

	if (full == -1)
		full = 0;

#ifdef WIN32
	if (HasAnyFlags(i->getStatus(), UserCore::Item::ItemInfoI::STATUS_ONCOMPUTER))
		m_cbBranchList->Append(Managers::GetString("#IF_ONCOMPUTER"), new BranchData(MCFBranch::BranchFromInt(-1), MCFBranch::BranchFromInt(-1)));
	else
		m_cbBranchList->Append(Managers::GetString("#IF_FINDONCOMPUTER"), new BranchData(MCFBranch::BranchFromInt(-2), MCFBranch::BranchFromInt(-2)));
#endif

	m_cbBranchList->SetSelection(full);

	if (pItemInfo->getIcon() && UTIL::FS::isValidFile(UTIL::FS::PathWithFile(pItemInfo->getIcon())))
		setIcon(pItemInfo->getIcon());

	SetTitle(gcWString(Managers::GetString(L"#IF_BRANCHTITLE"), itemName));


	uint32 ret = 0;

	if (count == 0)
	{
		if (!isCheckingParent)
			gcMessageBox(GetParent(), Managers::GetString(L"#IF_IINOBRANCHES"), Managers::GetString(L"#IF_IIERRTITLE"));
		else if (selectBranch)
			ret = 1;
	}
	else if ((count == 1 || fullReadyCount == 1) && !m_bBuy)
	{	
		ret =  1;
	}
	else
	{
		wxCommandEvent e;
		onChoice(e);
	}

	return ret;
}
예제 #8
0
uint32 GatherInfoTask::validate()
{
	UserCore::Item::ItemInfoI* pItemInfo = getItemHandle()->getItemInfo();
	uint32 isValid = 0;

	if (!pItemInfo)
		return UserCore::Item::Helper::V_BADINFO;

	DesuraId par = pItemInfo->getParentId();
	UserCore::Item::ItemInfoI *parInfo = nullptr;

	if (par.isOk())
	{
		parInfo = getUserCore()->getItemManager()->findItemInfo(par);

		if (!parInfo || !(parInfo->getStatus() & UserCore::Item::ItemInfoI::STATUS_INSTALLED))
			isValid |= UserCore::Item::Helper::V_PARENT;
	}

	const char* path = pItemInfo->getPath(getMcfBranch());

	if (!path)
	{
		isValid |= UserCore::Item::Helper::V_BADPATH;
	}
	else
	{
		const char *comAppPath = getUserCore()->getAppDataPath();

		uint64 inFreeSpace = UTIL::OS::getFreeSpace(path);
		uint64 dlFreeSpace = UTIL::OS::getFreeSpace(comAppPath);

		//if they are on the same drive:
		if (strncmp(comAppPath, path, 3) == 0)
		{
			if ((inFreeSpace+dlFreeSpace) < (pItemInfo->getDownloadSize()+pItemInfo->getInstallSize()))
			{
				isValid |= (UserCore::Item::Helper::V_FREESPACE|UserCore::Item::Helper::V_FREESPACE_DL|UserCore::Item::Helper::V_FREESPACE_INS);
			}
		}
		else
		{
			if (dlFreeSpace < pItemInfo->getDownloadSize())
				isValid |= UserCore::Item::Helper::V_FREESPACE|UserCore::Item::Helper::V_FREESPACE_DL;

			if (inFreeSpace < pItemInfo->getInstallSize())
				isValid |= UserCore::Item::Helper::V_FREESPACE|UserCore::Item::Helper::V_FREESPACE_INS;
		}

		if (pItemInfo->getStatus() & UserCore::Item::ItemInfoI::STATUS_INSTALLCOMPLEX)
		{
			const char* primPath = pItemInfo->getInsPrimary();

			if (primPath && strcmp(primPath, "") != 0 && UTIL::FS::isValidFolder(primPath) && !UTIL::FS::isFolderEmpty(primPath))
				isValid |= UserCore::Item::Helper::V_NONEMPTY;
		}
		else if (pItemInfo->getStatus() & UserCore::Item::ItemInfoI::STATUS_DLC)
		{
			if (!parInfo || gcString(path) != gcString(parInfo->getPath()))
			{
				if (!UTIL::FS::isFolderEmpty(path))
					isValid |= UserCore::Item::Helper::V_NONEMPTY;
			}
		}
		else if (!UTIL::FS::isFolderEmpty(path))
		{
			isValid |= UserCore::Item::Helper::V_NONEMPTY;
		}
	}

#ifdef NIX
	UserCore::Item::BranchInfoI* bi = pItemInfo->getBranchById(getMcfBranch());
	
	std::vector<DesuraId> toolList;
	bi->getToolList(toolList);

	uint32 res = getUserCore()->getToolManager()->hasNonInstallableTool(toolList);
	
	switch (res)
	{
	case 0:
		isValid |= UserCore::Item::Helper::V_JAVA_SUN;
		break;		
		
	case 1:
		isValid |= UserCore::Item::Helper::V_JAVA;
		break;		
	
	case 2:
		isValid |= UserCore::Item::Helper::V_MONO;
		break;
		
	case 3:
		isValid |= UserCore::Item::Helper::V_AIR;
		break;		
	};
#endif

	return isValid;
}
예제 #9
0
void GatherInfoTask::checkRequirements()
{
	if (!isValidBranch() && !handleInvalidBranch())
		return;

	MCFBranch branch = getMcfBranch();

	UserCore::Item::BranchInfoI* branchInfo = getItemHandle()->getItemInfo()->getBranchById(branch);
	
	if (!checkNullBranch(branchInfo))
		return;

	if (m_bCanceled)
	{
		completeStage();
		return;
	}

	if (branchInfo->isPreOrderAndNotPreload())
	{
		//show the preorder prompt
		getItemHandle()->getInternal()->goToStageLaunch();
		return;
	}

	uint32 res = validate();
	
#ifdef NIX
	UserCore::Item::Helper::TOOL tool = (UserCore::Item::Helper::TOOL)(res>>28);

	//check tool deps
	if ( (tool > 0) && (!m_pGIHH || !m_pGIHH->showToolPrompt(tool)) )
	{
		completeStage();
		return;				
	}
	
	res = (res<<4)>>4;
#endif
	
	if (res == 0)
	{
		getItemHandle()->getItemInfo()->addToAccount();
		getItemHandle()->getInternal()->goToStageDownload(branch, getMcfBuild(), HasAnyFlags(m_uiFlags, GI_FLAG_TEST));
	}
	else
	{
		if (res == UserCore::Item::Helper::V_NONEMPTY)
		{
			if (HasAnyFlags(m_uiFlags, GI_FLAG_UPDATE))
			{
				getItemHandle()->getInternal()->goToStageDownload(branch, getMcfBuild(), false);
			}
			else if (getItemHandle()->getItemInfo()->getStatus() & UserCore::Item::ItemInfoI::STATUS_INSTALLCOMPLEX)
			{
				if (!m_bCanceled && m_pGIHH && m_pGIHH->showComplexPrompt())
					getItemHandle()->getInternal()->goToStageDownload(branch, getMcfBuild(), HasAnyFlags(m_uiFlags, GI_FLAG_TEST));
				else
					resetStage();
			}
			else
			{
				UserCore::Item::Helper::ACTION promptRes = UserCore::Item::Helper::C_NONE;
				
				if (!m_bCanceled && m_pGIHH)
					promptRes = m_pGIHH->showInstallPrompt(getItemHandle()->getItemInfo()->getPath(getMcfBranch()));

				switch (promptRes)
				{
				case UserCore::Item::Helper::C_REMOVE:
						getItemInfo()->addOFlag(UserCore::Item::ItemInfoI::OPTION_REMOVEFILES);

				case UserCore::Item::Helper::C_INSTALL:
						getItemInfo()->addToAccount();
						getItemHandle()->getInternal()->goToStageDownload(branch, getMcfBuild(), HasAnyFlags(m_uiFlags, GI_FLAG_TEST));
						break;

				case UserCore::Item::Helper::C_VERIFY:
						getItemInfo()->addToAccount();
						getItemInfo()->addSFlag(UserCore::Item::ItemInfoI::STATUS_INSTALLED);
						getItemInfo()->setInstalledMcf(branch, getMcfBuild());
						getItemHandle()->getInternal()->goToStageVerify(branch, getMcfBuild(), true, true, true);
						break;

					default:
						resetStage();
						break;
				}
			}
		}
		else
		{
			if (m_bCanceled || !m_pGIHH || m_pGIHH->showError(res))
			{
				resetStage();
			}
			else
			{
				getItemHandle()->getItemInfo()->addToAccount();
				getItemHandle()->getInternal()->goToStageDownload(branch, getMcfBuild(), HasAnyFlags(m_uiFlags, GI_FLAG_TEST));
			}
		}
	}
}
예제 #10
0
void ItemHandle::doLaunch(bool useXdgOpen, const char* globalExe, const char* globalArgs)
{
	preLaunchCheck();
	
	UserCore::Item::Misc::ExeInfoI* ei = getItemInfo()->getActiveExe();
	
	gcString e(globalExe);
	
	gcString args;
	gcString ea(ei->getExeArgs());
	gcString ua(ei->getUserArgs());
	gcString ga(globalArgs);
	gcString wdp(ei->getExe());
	
	if (!useXdgOpen)
	{
		//if we have a valid global exe need to append the local exe as the first arg
		if (e.size() > 0)
			args += gcString(ei->getExe());
		else
			globalExe = ei->getExe();
	}
	
	auto AppendArgs = [&args](const std::string& a)
	{
		if (a.size() == 0)
			return;
		
		if (args.size() > 0)
			args += " ";
			
		args += a;
	};

	AppendArgs(ea);
	AppendArgs(ua);
	
	if (!useXdgOpen)
		AppendArgs(ga);
	
	bool res = false;

	if (useXdgOpen && args.size() != 0)
		Warning(gcString("Arguments '{1}' are not being passed to non-executable file '{0}'.", ei->getExe(), args));

	UserCore::Item::BranchInfoI* branch = getItemInfo()->getCurrentBranch();

#ifdef NIX64
	if (!useXdgOpen && branch && branch->is32Bit())
	{
		#ifdef USE_BITTEST
			int testRet = system("desura_bittest");
			
			if (testRet != 0)
				throw gcException(ERR_NO32LIBS);
		#else
			throw gcException(ERR_NOBITTEST);
		#endif
		
	}
#endif

	gcString libPathA;
	gcString libPathB;
	gcString libPath;
	
	if (branch)
	{
		libPathA = gcString("{0}/{1}/{2}/lib", UTIL::OS::getAppDataPath(), branch->getItemId().getFolderPathExtension(), (uint32)branch->getBranchId());
		libPathB = gcString("{0}/lib{1}", getItemInfo()->getPath(), branch->is32Bit()?"32":"64");

		libPath = libPathA;
		
		if (UTIL::FS::isValidFolder(libPathB.c_str()))
		{
			libPath += ":";
			libPath += libPathB;
		}
	}

	if (useXdgOpen)
	{
		res = UTIL::LIN::launchProcessXDG(ei->getExe(), libPath.c_str());
	}
	else
	{
		if (libPathA.size() > 0)
		{
			std::vector<DesuraId> toolList;
			branch->getToolList(toolList);
			
			getUserCore()->getToolManager()->symLinkTools(toolList, libPathA.c_str());
		}
	
		std::map<std::string, std::string> info;
		
		info["cla"] = args;
		info["lp"] = libPath;
		info["wd"] = UTIL::FS::PathWithFile(wdp.c_str()).getFolderPath();
		
		res = UTIL::LIN::launchProcess(globalExe, info);
	}

	if (!res)
	{
		ERROR_OUTPUT(gcString("Failed to create {0} process. [{1}: {2}].\n", getItemInfo()->getName(), errno, ei->getExe()).c_str());
		throw gcException(ERR_LAUNCH, errno, gcString("Failed to create {0} process. [{1}: {2}].\n", getItemInfo()->getName(), errno, ei->getExe()));
	}
}
예제 #11
0
void ItemHandle::installLaunchScripts()
{
	UserCore::Item::ItemInfoI* item = getItemInfo();
	
	if (!item)
		return;
		
	UserCore::Item::BranchInfoI* branch = item->getCurrentBranch();
	
	if (!branch)
		return;
		
	std::vector<UserCore::Item::Misc::ExeInfoI*> exeList;
	item->getExeList(exeList);
	
	char* scriptBin = NULL;
	char* scriptXdg = NULL;
	
	try
	{
		UTIL::FS::readWholeFile(UTIL::STRING::toStr(
			UTIL::OS::getDataPath(L"scripts/launch_bin_template.sh")), &scriptBin);
		UTIL::FS::readWholeFile(UTIL::STRING::toStr(
			UTIL::OS::getDataPath(L"scripts/launch_xdg_template.sh")), &scriptXdg);
	}
	catch (gcException &e)
	{
		safe_delete(scriptBin);
		safe_delete(scriptXdg);		
		
		Warning(gcString("Failed to read launch script template: {0}\n", e));
		return;
	}
	
	gcString globalArgs = getUserCore()->getCVarValue("gc_linux_launch_globalargs");
	gcString globalExe = getUserCore()->getCVarValue("gc_linux_launch_globalbin");
	
	if (!UTIL::FS::isValidFile(globalExe.c_str()))
		globalExe = "";
	
	for (size_t x=0; x<exeList.size(); x++)
	{
		UserCore::Item::Misc::ExeInfoI* exe = exeList[x];
		
		if (!exe || !UTIL::FS::isValidFile(exe->getExe()))
			continue;
			
		gcString path("{0}/desura_launch_{1}.sh", item->getPath(), UTIL::LIN::sanitiseFileName(exe->getName()));
			
		char magicBytes[5] = {0};
			
		try
		{
			UTIL::FS::FileHandle fh(exe->getExe(), UTIL::FS::FILE_READ);
			fh.read(magicBytes, 5);
		}
		catch (gcException& e)
		{
			continue;
		}
		
		UTIL::LIN::BinType type = UTIL::LIN::getFileType(magicBytes, 5);
		
		try
		{
			UTIL::FS::FileHandle fh(path.c_str(), UTIL::FS::FILE_WRITE);
			
			if (type == UTIL::LIN::BT_UNKNOWN)
			{
				gcString lcmd(scriptXdg, exe->getExe());
				fh.write(lcmd.c_str(), lcmd.size());
			}
			else
			{
				gcString libPath("\"{0}/{1}/{2}/lib\"", UTIL::OS::getAppDataPath(), branch->getItemId().getFolderPathExtension(), (uint32)branch->getBranchId());
				gcString libPathB("{0}/lib{1}", item->getPath(), branch->is32Bit()?"32":"64");
				
				if (UTIL::FS::isValidFolder(libPathB.c_str()))
				{
					libPath += ":";
					libPath += "\"" + libPathB + "\"";
				}

				const char* exePath = exe->getExe();
				
				gcString args;
				gcString ea(exe->getExeArgs());
				
				if (globalExe.size() > 0)
				{
					args += gcString(exePath);
					exePath = globalExe.c_str();
				}
				
				if (ea.size() > 0)
				{
					if (args.size() > 0)
						args += " ";
						
					args += ea;
				}
				
				if (globalArgs.size() > 0)
				{
					if (args.size() > 0)
						args += " ";
						
					args += globalArgs;
				}			
					
				gcString lcmd(scriptBin, exePath, args, libPath);
				fh.write(lcmd.c_str(), lcmd.size());
			}
		}
		catch (gcException &e)
		{
		}
		
		chmod(path.c_str(), S_IRWXU|S_IRGRP|S_IROTH);
	}
	
	safe_delete(scriptBin);
	safe_delete(scriptXdg);
}