Official eMule-Board: New Skin Extension Support - Official eMule-Board

Jump to content


Page 1 of 1

New Skin Extension Support easier shell integration and user friendly :)

#1 User is offline   Avi-3k 

  • hebMule [retired] dev
  • PipPipPipPipPipPipPip
  • Group: Members
  • Posts: 1,125
  • Joined: 25-June 03

Posted 05 March 2010 - 10:48 PM

in eMule Skinner, i've added support to new extensions *.eMuleSkin, *.eMuleSkinZip/Rar.
this eases the skinning process since all the user has to do is double click the skin in explorer to change it in eMule
because now we can register the extensions in windows shell (without causing problems).
Skinner already registers the extensions for editing

here's the code, you can download the icon from http://hebmule.sf.ne...uleSkinFile.ico (right click & save)
also, the code can be changed so zipped/rarred skins can hide under the *.eMuleSkin extension
and detected using eMule's file type verification code when needed.

(btw, since the code changes the InstallSkin() function, this is the complete body of the function, the rest is an easy merge).


emule.cpp
bool CemuleApp::ProcessCommandline() {
...
		// Avi3k: Ext. Skins
		else if (IsSkinFile(*command))
		{
			sendstruct.cbData = (command->GetLength() + 1)*sizeof(TCHAR);
			sendstruct.dwData = OP_SKINFILE;
			sendstruct.lpData = const_cast<LPTSTR>((LPCTSTR)*command); 
    			if (maininst)
			{
      				SendMessage(maininst, WM_COPYDATA, (WPARAM)0, (LPARAM)(PCOPYDATASTRUCT)&sendstruct);
				delete command;
      				return true; 
			}
			pstrPendingLink=command;
		}
		// end Avi3k: Ext. Skins
...
}


emuleDlg.cpp
LRESULT CemuleDlg::OnWMData(WPARAM /*wParam*/, LPARAM lParam) {
...
	// Avi3k: Ext. Skins
	else if (data->dwData == OP_SKINFILE)
	{
		static const TCHAR _pszSkinSuffix[] = _T(".") EMULSKIN_BASEEXT;
		static const TCHAR _pszSkinZipSuffix[] = _T(".") EMULSKIN_BASEEXT _T("zip");
		static const TCHAR _pszSkinRarSuffix[] = _T(".") EMULSKIN_BASEEXT _T("rar");
		CString strSkinPath((LPCTSTR)data->lpData), strSkin;
		if (!strSkinPath.Right(ARRSIZE(_pszSkinSuffix)-1).CompareNoCase(_pszSkinSuffix) && thePrefs.GetSkinProfile().CompareNoCase(strSkinPath))
			theApp.ApplySkin(strSkinPath);
		else if ((!strSkinPath.Right(ARRSIZE(_pszSkinZipSuffix)-1).CompareNoCase(_pszSkinZipSuffix) ||
			!strSkinPath.Right(ARRSIZE(_pszSkinRarSuffix)-1).CompareNoCase(_pszSkinRarSuffix)) &&
			InstallSkin(strSkinPath, &strSkin) && !strSkin.IsEmpty() && thePrefs.GetSkinProfile().CompareNoCase(strSkin))
				theApp.ApplySkin(strSkin);
	}
	// end Avi3k: Ext. Skins
...
	else if (data->dwData == OP_CLCOMMAND){
		...
		// Avi3k: Ext. Skins (support skin=path_or_name for default skin, etc...)
		if (clcommand.Left(5).MakeLower() == _T("skin="))
		{
			theApp.ApplySkin(clcommand.Mid(5));
			return true;
		}
		// end Avi3k: Ext. Skins
...
}


emuleDlg.h
...
#define OP_SKINFILE			12003 // Avi3k: Ext. Skins
...


otherfunctions.cpp
...
bool InstallSkin(LPCTSTR pszSkinPackage, CString* psSkinPath) // Avi3k: Ext. Skins (modified)
{
	if (thePrefs.GetMuleDirectory(EMULE_SKINDIR).IsEmpty() || _taccess(thePrefs.GetMuleDirectory(EMULE_SKINDIR), 0) != 0) {
		AfxMessageBox(GetResString(IDS_INSTALL_SKIN_NODIR), MB_IConerror);
		return false; // Avi3k: Ext. Skins (modified)
	}

	static const TCHAR _szSkinSuffix[] = _T(".") EMULSKIN_BASEEXT _T(".ini");
	static const TCHAR _szSkinSuffixNew[] = _T(".") EMULESKIN_BASEEXT; // Avi3k: Ext. Skins

	TCHAR szExt[_MAX_EXT];
	_tsplitpath(pszSkinPackage, NULL, NULL, NULL, szExt);
	_tcslwr(szExt);

	if (_tcscmp(szExt, _T(".zip")) == 0 || _tcscmp(szExt, _T(".emuleskinzip")) == 0) // Avi3k: Ext. Skins (modified)
	{
		CZIPFile zip;
		if (zip.Open(pszSkinPackage))
		{
			// Search the "*.eMuleSkin.ini" file..
			CZIPFile::File* zfIniFile = NULL;
			for (int i = 0; i < zip.GetCount(); i++)
			{
				CZIPFile::File* zf = zip.GetFile(i);
				// Avi3k: Ext. Skins
				if (zf && (zf->m_sName.Right(_countof(_szSkinSuffix)-1).CompareNoCase(_szSkinSuffix) == 0) ||
					!zf->m_sName.Right(ARRSIZE(_szSkinSuffixNew)-1).CompareNoCase(_szSkinSuffixNew)))
				// end Avi3k: Ext. Skins
				{
					zfIniFile = zf;
					break;
				}
			}

			if (zfIniFile)
			{
				// Avi3k: Ext. Skins
				if (psSkinPath)
					*psSkinPath = thePrefs.GetMuleDirectory(EMULE_SKINDIR) + _T('\\') + zfIniFile->m_sName;
				// end Avi3k: Ext. Skins
				for (int i = 0; i < zip.GetCount(); i++)
				{
					CZIPFile::File* zf = zip.GetFile(i);
					if (zf)
					{
						if (zf->m_sName.IsEmpty())
							continue;
						if (zf->m_sName[0] == _T('\\') || zf->m_sName[0] == _T('/'))
							continue;
						if (zf->m_sName.Find(_T(':')) != -1)
							continue;
						if (zf->m_sName.Find(_T("..\\")) != -1 || zf->m_sName.Find(_T("../")) != -1)
							continue;
						if (zf->m_sName[zf->m_sName.GetLength()-1] == _T('/'))
						{
							CString strDstDirPath;
							PathCanonicalize(strDstDirPath.GetBuffer(MAX_PATH), thePrefs.GetMuleDirectory(EMULE_SKINDIR) + _T('\\') + zf->m_sName.Left(zf->m_sName.GetLength()-1));
							strDstDirPath.ReleaseBuffer();
							if (!CreateDirectory(strDstDirPath, NULL)){
								DWORD dwError = GetLastError();
								CString strError;
								strError.Format(GetResString(IDS_INSTALL_SKIN_DIR_ERROR), strDstDirPath, GetErrorMessage(dwError));
								AfxMessageBox(strError, MB_IConerror);
								break;
							}
						}
						else
						{
							CString strDstFilePath;
							PathCanonicalize(strDstFilePath.GetBuffer(MAX_PATH), thePrefs.GetMuleDirectory(EMULE_SKINDIR) + _T('\\') + zf->m_sName);
							strDstFilePath.ReleaseBuffer();
							SetLastError(0);
							if (!zf->Extract(strDstFilePath)){
								DWORD dwError = GetLastError();
								CString strError;
								strError.Format(GetResString(IDS_INSTALL_SKIN_FILE_ERROR), zf->m_sName, strDstFilePath, GetErrorMessage(dwError));
								AfxMessageBox(strError, MB_IConerror);
								break;
							}
						}
					}
				}
			}
			else {
				AfxMessageBox(GetResString(IDS_INSTALL_SKIN_PKG_ERROR), MB_IConerror);
				return false; // Avi3k: Ext. Skins
			}
			zip.Close();
			return true; // Avi3k: Ext. Skins
		}
		else {
			AfxMessageBox(GetResString(IDS_INSTALL_SKIN_PKG_ERROR), MB_IConerror);
			return false; // Avi3k: Ext. Skins
		}
	}
	else if (_tcscmp(szExt, _T(".rar")) == 0 || _tcscmp(szExt, _T(".emuleskinrar")) == 0) // Avi3k: Ext. Skins (modified)
	{
		CRARFile rar;
		if (rar.Open(pszSkinPackage))
		{
			bool bError = false;
			bool bFoundSkinINIFile = false;
			CString strFileName;
			while (rar.GetNextFile(strFileName))
			{
				if (strFileName.IsEmpty()) {
					rar.Skip();
					continue;
				}
				if (strFileName[0] == _T('\\') || strFileName[0] == _T('/')) {
					rar.Skip();
					continue;
				}
				if (strFileName.Find(_T(':')) != -1) {
					rar.Skip();
					continue;
				}
				if (strFileName.Find(_T("..\\")) != -1 || strFileName.Find(_T("../")) != -1) {
					rar.Skip();
					continue;
				}

				// Avi3k: Ext. Skins
				if (!bFoundSkinINIFile && (strFileName.Right(_countof(_szSkinSuffix)-1).CompareNoCase(_szSkinSuffix) == 0 ||
					!strFileName.Right(ARRSIZE(_szSkinSuffixNew)-1).CompareNoCase(_szSkinSuffixNew)))
				// end Avi3k: Ext. Skins
				{
					bFoundSkinINIFile = true;
					// Avi3k: Ext. Skins
					if (psSkinPath)
						*psSkinPath = thePrefs.GetMuleDirectory(EMULE_SKINDIR) + _T('\\') + strFileName;
					// end Avi3k: Ext. Skins
				}

				// No need to care about possible available sub-directories. UnRAR.DLL cares about that automatically.
				CString strDstFilePath;
				PathCanonicalize(strDstFilePath.GetBuffer(MAX_PATH), thePrefs.GetMuleDirectory(EMULE_SKINDIR) + _T('\\') + strFileName);
				strDstFilePath.ReleaseBuffer();
				SetLastError(0);
				if (!rar.Extract(strDstFilePath)) {
					DWORD dwError = GetLastError();
					CString strError;
					strError.Format(GetResString(IDS_INSTALL_SKIN_FILE_ERROR), strFileName, strDstFilePath, GetErrorMessage(dwError));
					AfxMessageBox(strError, MB_IConerror);
					bError = true;
					break;
				}
			}

			if (!bError && !bFoundSkinINIFile)
				AfxMessageBox(GetResString(IDS_INSTALL_SKIN_PKG_ERROR), MB_IConerror);

			rar.Close();
			return (!bError && bFoundSkinINIFile); // Avi3k: Ext. Skins
		}
		else {
			CString strError;
			strError.Format(_T("%s\r\n\r\nDownload latest version of UNRAR.DLL from http://www.rarlab.com and copy UNRAR.DLL into eMule installation folder."), GetResString(IDS_INSTALL_SKIN_PKG_ERROR));
			AfxMessageBox(strError, MB_IConerror);
			return false; // Avi3k: Ext. Skins
		}
	}
	// Avi3k: Ext. Skins (assume installation failed)
	if (psSkinPath)
		return (!psSkinPath->IsEmpty());
	return false;
	// end Avi3k: Ext. Skins
}
...

// Avi3k: Ext. Skins
bool IsSkinFile(const CString& strFilename, bool bOldExts)
{
	static const LPCTSTR _pszSkinsFiles[] = { _T(".") EMULSKIN_BASEEXT, _T(".") EMULSKIN_BASEEXT _T("zip"), _T(".") EMULSKIN_BASEEXT _T("rar") };
	static const LPCTSTR _pszSkinsOldFiles[] = { _T(".") EMULSKIN_BASEEXT _T(".ini"), _T(".") EMULSKIN_BASEEXT _T(".zip"), _T(".") EMULSKIN_BASEEXT _T(".rar") };
	for (int i = 0; i < ARRSIZE(_pszSkinsFiles); i++)
	{
		CString strExt = _pszSkinsFiles[i];
		if (!strFilename.Right(strExt.GetLength()).CompareNoCase(strExt))
			return true;
	}
	if (bOldExts)
	{
		for (int k = 0; k < ARRSIZE(_pszSkinsOldFiles); k++)
		{
			CString strExt = _pszSkinsOldFiles[k];
			if (!strFilename.Right(strExt.GetLength()).CompareNoCase(strExt))
				return true;
		}
	}
	return false;
}

bool HasSkinfileRegAccess()
{
	CRegKey regkey;
	bool bRet = (regkey.Create(HKEY_CLASSES_ROOT, _T("eMuleSkinFile")) == ERROR_SUCCESS);
	regkey.Close();
	return bRet;
}

bool ApplySkinfileReg(bool bReg)
{
	static const LPCTSTR _pszSkinsFiles[] = { _T(".") EMULSKIN_BASEEXT, _T(".") EMULSKIN_BASEEXT _T("zip"), _T(".") EMULSKIN_BASEEXT _T("rar") };
	if (!HasSkinfileRegAccess())
		return false;

	CRegKey regkey;
	if (!bReg)
	{
		regkey.Open(HKEY_CLASSES_ROOT, _T("eMuleSkinFile\\shell\\open"));
		regkey.RecurseDeleteKey(_T("ddexec"));
		regkey.RecurseDeleteKey(_T("ddeexec"));
		regkey.Close();

		return true;
	}
	bool bReturn = true;
	TCHAR sbuffer[MAX_PATH], regbuffer[MAX_PATH];
	::GetModuleFileName(NULL, sbuffer, ARRSIZE(sbuffer));
	CString strCanonFileName = sbuffer;
	strCanonFileName.Replace(_T("%"), _T("%%"));
	if (regkey.Create(HKEY_CLASSES_ROOT, _T("eMuleSkinFile\\shell\\open\\command")) == ERROR_SUCCESS)
	{
		_sntprintf(regbuffer, ARRSIZE(regbuffer), _T("\"%s\" \"%%1\""), strCanonFileName);
		bReturn = (regkey.SetStringValue(NULL, regbuffer) == ERROR_SUCCESS);
	}
	regkey.Close();
	if (regkey.Create(HKEY_CLASSES_ROOT, _T("eMuleSkinFile\\DefaultIcon")) == ERROR_SUCCESS)
	{
		_sntprintf(regbuffer, ARRSIZE(regbuffer), _T("%s,2"), strCanonFileName);
		regkey.SetStringValue(NULL, regbuffer);
	}
	regkey.Close();
	for (int i = 0; i < ARRSIZE(_pszSkinsFiles) && bReturn; i++)
	{
		if (regkey.Create(HKEY_CLASSES_ROOT, _pszSkinsFiles[i]) == ERROR_SUCCESS)
			bReturn &= (regkey.SetStringValue(NULL, _T("eMuleSkinFile")) == ERROR_SUCCESS);
		regkey.Close();
	}
	return bReturn;
}
// end Avi3k: Ext. Skins


otherfunctions.h
...
bool InstallSkin(LPCTSTR pszSkinPackage, CString* psSkinPath = NULL); // Avi3k: Ext. Skins (modified)
...
// Avi3k: Ext. Skins
bool IsSkinFile(const CString& strFilename, bool bOldExts = false);
bool HasSkinfileRegAccess();
bool ApplySkinfileReg(bool bReg = true);
// end Avi3k: Ext. Skins
...


MuleToolBarCtrl.cpp
static const LPCTSTR s_apszSkinFiles[] = 
{
	_T("*.") EMULSKIN_BASEEXT, // Avi3k: Ext. Skins
...
};
...


emule.rc
...
AACSKINFILETYPE                 ICON                "res\\eMuleSkinFile.ico" // Avi3k: Ext. Skins
...



Avi3k

This post has been edited by Avi-3k: 05 March 2010 - 10:50 PM

retired developer of hebMule and eMule Skinner...
hebMule site and topic.
hebMule2 unique features: AntiLeech, AntiVirus, Fake Check, ServerFilter, WebSearches, Export Searches, Relative Priority, ModID and much much more...

eMule Skinner is an application to create/edit skins for eMule,
it's multilingual, supports mods, easy-to-use design, integrates to hebMule & Windows and lots more...

code fixes/improvements: #1, #2, #3, #4, #5, #6, #7, #8, #9, #10, #11 (to check/verify: #12, #13).
1

#2 User is offline   Some Support 

  • Last eMule
  • PipPipPipPipPipPipPip
  • Group: Yes
  • Posts: 3,411
  • Joined: 27-June 03

Posted 06 March 2010 - 12:00 PM

The current skin support is quite rudimentary. As listed in the FAF thread we do intend to rewrite this at some point and i hope maybe in the version after the upcoming one there will be the time for it (if we find a designer to create a test skind during the development). If thats done we will also work on making them easier to install and manage for sure.
For the time beeing however, i don't think that there is much point of adding shell integration and other stuff for skins, as it will have to be rewritten by then anyway and won't be compatible neither.

#3 User is offline   Avi-3k 

  • hebMule [retired] dev
  • PipPipPipPipPipPipPip
  • Group: Members
  • Posts: 1,125
  • Joined: 25-June 03

Posted 06 March 2010 - 10:31 PM

ok, i understand.
if you (the devs) don't mind, i'd liked to be included in this as it affects eMule Skinner :flowers:

regards,
Avi3k
retired developer of hebMule and eMule Skinner...
hebMule site and topic.
hebMule2 unique features: AntiLeech, AntiVirus, Fake Check, ServerFilter, WebSearches, Export Searches, Relative Priority, ModID and much much more...

eMule Skinner is an application to create/edit skins for eMule,
it's multilingual, supports mods, easy-to-use design, integrates to hebMule & Windows and lots more...

code fixes/improvements: #1, #2, #3, #4, #5, #6, #7, #8, #9, #10, #11 (to check/verify: #12, #13).
0

#4 User is offline   lorenzone92 

  • MultiformeIngegno
  • PipPipPipPipPipPip
  • Group: Italian Moderators
  • Posts: 321
  • Joined: 18-January 06

Posted 22 April 2010 - 02:34 PM

View PostSome Support, on 06 March 2010 - 02:00 PM, said:

[...] and i hope maybe in the version after the upcoming one there will be the time for it [...]

What will be the main work for next version?
RockCiclopedia (wiki - forum - extra)
Tutta la storia del rock, scritta da voi ...
Immagine Postata
...iscriviti al feed di RockCiclopedia dedicato alle ultime news del mondo della musica!
...scarica la toolbar, per rimanere sempre aggiornato e partecipare attivamente alla community!

MultiformeIngegno | Blog, Il blog del solito cialtrone di turno..
0

#5 User is offline   Avi-3k 

  • hebMule [retired] dev
  • PipPipPipPipPipPipPip
  • Group: Members
  • Posts: 1,125
  • Joined: 25-June 03

Posted 23 April 2010 - 09:00 PM

lorenzone92, i'm sorry but this is not the place for it...
as you probably know the devs aren't going to talk about future versions
(especially after recently releasing a new version)

Avi3k
retired developer of hebMule and eMule Skinner...
hebMule site and topic.
hebMule2 unique features: AntiLeech, AntiVirus, Fake Check, ServerFilter, WebSearches, Export Searches, Relative Priority, ModID and much much more...

eMule Skinner is an application to create/edit skins for eMule,
it's multilingual, supports mods, easy-to-use design, integrates to hebMule & Windows and lots more...

code fixes/improvements: #1, #2, #3, #4, #5, #6, #7, #8, #9, #10, #11 (to check/verify: #12, #13).
0

  • Member Options

Page 1 of 1

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users