Exemplo n.º 1
0
void CExtensionManager::Shutdown()
{
	List<CExtension *>::iterator iter;

	while ((iter = m_Libs.begin()) != m_Libs.end())
	{
		UnloadExtension((*iter));
	}
}
Exemplo n.º 2
0
void CExtensionManager::OnRootConsoleCommand(const char *cmdname, const CCommand &command)
{
	int argcount = smcore.Argc(command);
	if (argcount >= 3)
	{
		const char *cmd = smcore.Arg(command, 2);
		if (strcmp(cmd, "list") == 0)
		{
			List<CExtension *>::iterator iter;
			CExtension *pExt;
			unsigned int num = 1;
			switch (m_Libs.size())
			{
			case 1:
				{
					rootmenu->ConsolePrint("[SM] Displaying 1 extension:");
					break;
				}
			case 0:
				{
					rootmenu->ConsolePrint("[SM] No extensions are loaded.");
					break;
				}
			default:
				{
					rootmenu->ConsolePrint("[SM] Displaying %d extensions:", m_Libs.size());
					break;
				}
			}
			for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++,num++)
			{
				pExt = (*iter);
				if (pExt->IsLoaded())
				{
					char error[255];
					if (!pExt->IsRunning(error, sizeof(error)))
					{
						rootmenu->ConsolePrint("[%02d] <FAILED> file \"%s\": %s", num, pExt->GetFilename(), error);
					}
					else
					{
						IExtensionInterface *pAPI = pExt->GetAPI();
						const char *name = pAPI->GetExtensionName();
						const char *version = pAPI->GetExtensionVerString();
						const char *descr = pAPI->GetExtensionDescription();
						rootmenu->ConsolePrint("[%02d] %s (%s): %s", num, name, version, descr);
					}
				} else {
					rootmenu->ConsolePrint("[%02d] <FAILED> file \"%s\": %s", num, pExt->GetFilename(), pExt->m_Error.c_str());
				}
			}
			return;
		}
		else if (strcmp(cmd, "load") == 0)
		{
			if (argcount < 4)
			{
				rootmenu->ConsolePrint("[SM] Usage: sm exts load <file>");
				return;
			}

			const char *filename = smcore.Arg(command, 3);
			char path[PLATFORM_MAX_PATH];
			char error[256];

			smcore.Format(path, sizeof(path), "%s%s%s", filename, !strstr(filename, ".ext") ? ".ext" : "",
				!strstr(filename, "." PLATFORM_LIB_EXT) ? "." PLATFORM_LIB_EXT : "");
			
			if (FindExtensionByFile(path) != NULL)
			{
				rootmenu->ConsolePrint("[SM] Extension %s is already loaded.", path);
				return;
			}
			
			if (LoadExtension(path, error, sizeof(error)))
			{
				rootmenu->ConsolePrint("[SM] Loaded extension %s successfully.", path);
			} else
			{
				rootmenu->ConsolePrint("[SM] Extension %s failed to load: %s", path, error);
			}
			
			return;
		}
		else if (strcmp(cmd, "info") == 0)
		{
			if (argcount < 4)
			{
				rootmenu->ConsolePrint("[SM] Usage: sm exts info <#>");
				return;
			}

			const char *sId = smcore.Arg(command, 3);
			unsigned int id = atoi(sId);
			if (id <= 0)
			{
				rootmenu->ConsolePrint("[SM] Usage: sm exts info <#>");
				return;
			}

			if (m_Libs.size() == 0)
			{
				rootmenu->ConsolePrint("[SM] No extensions are loaded.");
				return;
			}

			if (id > m_Libs.size())
			{
				rootmenu->ConsolePrint("[SM] No extension was found with id %d.", id);
				return;
			}

			List<CExtension *>::iterator iter = m_Libs.begin();
			CExtension *pExt = NULL;
			while (iter != m_Libs.end())
			{
				if (--id == 0)
				{
					pExt = (*iter);
					break;
				}
				iter++;
			}
			/* This should never happen */
			if (!pExt)
			{
				rootmenu->ConsolePrint("[SM] No extension was found with id %d.", id);
				return;
			}

			if (!pExt->IsLoaded())
			{
				rootmenu->ConsolePrint(" File: %s", pExt->GetFilename());
				rootmenu->ConsolePrint(" Loaded: No (%s)", pExt->m_Error.c_str());
			}
			else
			{
				char error[255];
				if (!pExt->IsRunning(error, sizeof(error)))
				{
					rootmenu->ConsolePrint(" File: %s", pExt->GetFilename());
					rootmenu->ConsolePrint(" Loaded: Yes");
					rootmenu->ConsolePrint(" Running: No (%s)", error);
				}
				else
				{
					IExtensionInterface *pAPI = pExt->GetAPI();
					rootmenu->ConsolePrint(" File: %s", pExt->GetFilename());
					rootmenu->ConsolePrint(" Loaded: Yes (version %s)", pAPI->GetExtensionVerString());
					rootmenu->ConsolePrint(" Name: %s (%s)", pAPI->GetExtensionName(), pAPI->GetExtensionDescription());
					rootmenu->ConsolePrint(" Author: %s (%s)", pAPI->GetExtensionAuthor(), pAPI->GetExtensionURL());
					rootmenu->ConsolePrint(" Binary info: API version %d (compiled %s)", pAPI->GetExtensionVersion(), pAPI->GetExtensionDateString());

					if (pExt->IsExternal())
					{
						rootmenu->ConsolePrint(" Method: Loaded by Metamod:Source, attached to SourceMod");
					}
					else if (pAPI->IsMetamodExtension())
					{
						rootmenu->ConsolePrint(" Method: Loaded by SourceMod, attached to Metamod:Source");
					}
					else
					{
						rootmenu->ConsolePrint(" Method: Loaded by SourceMod");
					}
				}
			}
			return;
		}
		else if (strcmp(cmd, "unload") == 0)
		{
			if (argcount < 4)
			{
				rootmenu->ConsolePrint("[SM] Usage: sm exts unload <#> [code]");
				return;
			}

			const char *arg = smcore.Arg(command, 3);
			unsigned int num = atoi(arg);
			CExtension *pExt = FindByOrder(num);

			if (!pExt)
			{
				rootmenu->ConsolePrint("[SM] Extension number %d was not found.", num);
				return;
			}

			if (argcount > 4 && pExt->unload_code)
			{
				const char *unload = smcore.Arg(command, 4);
				if (pExt->unload_code == (unsigned)atoi(unload))
				{
					char filename[PLATFORM_MAX_PATH];
					snprintf(filename, PLATFORM_MAX_PATH, "%s", pExt->GetFilename());
					UnloadExtension(pExt);
					rootmenu->ConsolePrint("[SM] Extension %s is now unloaded.", filename);
				}
				else
				{
					rootmenu->ConsolePrint("[SM] Please try again, the correct unload code is \"%d\"", pExt->unload_code);
				}
				return;
			}

			if (!pExt->IsLoaded() 
				|| (!pExt->m_ChildDeps.size() && !pExt->m_Dependents.size()))
			{
				char filename[PLATFORM_MAX_PATH];
				snprintf(filename, PLATFORM_MAX_PATH, "%s", pExt->GetFilename());
				UnloadExtension(pExt);
				rootmenu->ConsolePrint("[SM] Extension %s is now unloaded.", filename);
				return;
			}
			else
			{
				List<CPlugin *> plugins;
				if (pExt->m_ChildDeps.size())
				{
					rootmenu->ConsolePrint("[SM] Unloading %s will unload the following extensions: ", pExt->GetFilename());
					List<CExtension *>::iterator iter;
					CExtension *pOther;
					/* Get list of all extensions */
					for (iter=m_Libs.begin(); iter!=m_Libs.end(); iter++)
					{
						List<IfaceInfo>::iterator i_iter;
						pOther = (*iter);
						if (!pOther->IsLoaded() || pOther == pExt)
						{
							continue;
						}
						/* Get their dependencies */
						for (i_iter=pOther->m_Deps.begin();
							 i_iter!=pOther->m_Deps.end();
							 i_iter++)
						{
							/* Is this dependency to us? */
							if ((*i_iter).owner != pExt)
							{
								continue;
							}
							/* Will our dependent care? */
							if (!pExt->GetAPI()->QueryInterfaceDrop((*i_iter).iface))
							{
								rootmenu->ConsolePrint(" -> %s", pExt->GetFilename());
								/* Add to plugin unload list */
								List<CPlugin *>::iterator p_iter;
								for (p_iter=pOther->m_Dependents.begin();
									 p_iter!=pOther->m_Dependents.end();
									 p_iter++)
								{
									if (plugins.find((*p_iter)) == plugins.end())
									{
										plugins.push_back((*p_iter));
									}
								}
							}
						}
					}
				}
				if (pExt->m_Dependents.size())
				{
					rootmenu->ConsolePrint("[SM] Unloading %s will unload the following plugins: ", pExt->GetFilename());
					List<CPlugin *>::iterator iter;
					CPlugin *pPlugin;
					for (iter = pExt->m_Dependents.begin(); iter != pExt->m_Dependents.end(); iter++)
					{
						pPlugin = (*iter);
						if (plugins.find(pPlugin) == plugins.end())
						{
							plugins.push_back(pPlugin);
						}
					}
					for (iter = plugins.begin(); iter != plugins.end(); iter++)
					{
						pPlugin = (*iter);
						rootmenu->ConsolePrint(" -> %s", pPlugin->GetFilename());
					}
				}
				srand(static_cast<int>(time(NULL)));
				pExt->unload_code = (rand() % 877) + 123;	//123 to 999
				rootmenu->ConsolePrint("[SM] To verify unloading %s, please use the following: ", pExt->GetFilename());
				rootmenu->ConsolePrint("[SM] sm exts unload %d %d", num, pExt->unload_code);

				return;
			}
		}
		else if (strcmp(cmd, "reload") == 0)
		{
			if (argcount < 4)
			{
				rootmenu->ConsolePrint("[SM] Usage: sm exts reload <#>");
				return;
			}
			
			const char *arg = smcore.Arg(command, 3);
			unsigned int num = atoi(arg);
			CExtension *pExt = FindByOrder(num);

			if (!pExt)
			{
				rootmenu->ConsolePrint("[SM] Extension number %d was not found.", num);
				return;
			}
			
			if (pExt->IsLoaded())
			{
				char filename[PLATFORM_MAX_PATH];
				char error[255];
				
				snprintf(filename, PLATFORM_MAX_PATH, "%s", pExt->GetFilename());
				
				if (pExt->Reload(error, sizeof(error)))
				{
					rootmenu->ConsolePrint("[SM] Extension %s is now reloaded.", filename);
				}
				else
				{
					rootmenu->ConsolePrint("[SM] Extension %s failed to reload: %s", filename, error);
				}
					
				return;
			} 
			else
			{
				rootmenu->ConsolePrint("[SM] Extension %s is not loaded.", pExt->GetFilename());
				
				return;
			}
			
		}
	}

	rootmenu->ConsolePrint("SourceMod Extensions Menu:");
	rootmenu->DrawGenericOption("info", "Extra extension information");
	rootmenu->DrawGenericOption("list", "List extensions");
	rootmenu->DrawGenericOption("load", "Load an extension");
	rootmenu->DrawGenericOption("reload", "Reload an extension");
	rootmenu->DrawGenericOption("unload", "Unload an extension");
}
Exemplo n.º 3
0
bool CExtensionManager::UnloadExtension(IExtension *_pExt)
{
	if (!_pExt)
	{
		return false;
	}

	CExtension *pExt = (CExtension *)_pExt;

	if (m_Libs.find(pExt) == m_Libs.end())
	{
		return false;
	}

	/* Tell it to unload */
	if (pExt->IsLoaded())
	{
		IExtensionInterface *pAPI = pExt->GetAPI();
		pAPI->OnExtensionUnload();
	}

	/* First remove us from internal lists */
	g_ShareSys.RemoveInterfaces(_pExt);
	m_Libs.remove(pExt);

	List<CExtension *> UnloadQueue;

	/* Handle dependencies */
	if (pExt->IsLoaded())
	{
		/* Unload any dependent plugins */
		List<CPlugin *>::iterator p_iter = pExt->m_Dependents.begin();
		while (p_iter != pExt->m_Dependents.end())
		{
			/* We have to manually unlink ourselves here, since we're no longer being managed */
			scripts->UnloadPlugin((*p_iter));
			p_iter = pExt->m_Dependents.erase(p_iter);
		}

		List<String>::iterator s_iter;
		for (s_iter = pExt->m_Libraries.begin();
			 s_iter != pExt->m_Libraries.end();
			 s_iter++)
		{
			scripts->OnLibraryAction((*s_iter).c_str(), LibraryAction_Removed);
		}

		/* Notify and/or unload all dependencies */
		List<CExtension *>::iterator c_iter;
		CExtension *pDep;
		IExtensionInterface *pAPI;
		for (c_iter = m_Libs.begin(); c_iter != m_Libs.end(); c_iter++)
		{
			pDep = (*c_iter);
			if ((pAPI=pDep->GetAPI()) == NULL)
			{
				continue;
			}
			if (pDep == pExt)
			{
				continue;
			}
			/* Now, get its dependency list */
			bool dropped = false;
			List<IfaceInfo>::iterator i_iter = pDep->m_Deps.begin();
			while (i_iter != pDep->m_Deps.end())
			{
				if ((*i_iter).owner == _pExt)
				{
					if (!pAPI->QueryInterfaceDrop((*i_iter).iface))
					{
						if (!dropped)
						{
							dropped = true;
							UnloadQueue.push_back(pDep);
						}
					}
					pAPI->NotifyInterfaceDrop((*i_iter).iface);
					i_iter = pDep->m_Deps.erase(i_iter);
				}
				else
				{
					i_iter++;
				}
			}
			/* Flush out any back references to this plugin */
			i_iter = pDep->m_ChildDeps.begin();
			while (i_iter != pDep->m_ChildDeps.end())
			{
				if ((*i_iter).owner == pExt)
				{
					i_iter = pDep->m_ChildDeps.erase(i_iter);
				}
				else
				{
					i_iter++;
				}
			}
		}

		/* Unbind our natives from Core */
		pExt->DropEverything();
	}

	IdentityToken_t *pIdentity;
	if ((pIdentity = pExt->GetIdentity()) != NULL)
	{
		SMGlobalClass *glob = SMGlobalClass::head;
		while (glob)
		{
			glob->OnSourceModIdentityDropped(pIdentity);
			glob = glob->m_pGlobalClassNext;
		}
	}

	pExt->Unload();
	delete pExt;

	List<CExtension *>::iterator iter;
	for (iter=UnloadQueue.begin(); iter!=UnloadQueue.end(); iter++)
	{
		/* NOTE: This is safe because the unload function backs out of anything not present */
		UnloadExtension((*iter));
	}

	return true;
}
Exemplo n.º 4
0
//-------------------------------------------------------
// 
//-------------------------------------------------------
BOOL APIENTRY DllMain(HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					)
{
    switch (ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:
			{
				Loaded = false;
				ConfigOn = false;

				// do a version check to make sure users dont have older versions of HGooey
				if (!HGVersionCheck(HGVersion))
					return FALSE;

				// load and create stuff here (ie load extensions, create textures/images/objects/etc)

				// make sure the no one moved the extension
				if (GetFileAttributes("HGooey Files/XenDLL/Extensions/Frames_Per_Sec/HG_SDK.dll") == 0xFFFFFFFF) return FALSE;

				// make sure the menu item texture exists
				if (GetFileAttributes("HGooey Files/XenDLL/Extensions/Frames_Per_Sec/Frames_Per_Sec.bmp") == 0xFFFFFFFF) return FALSE;

				/* example of creating an extension w/ no menu item to start with
				// create the extension
				Frames_Per_Sec = CreateExtension();

				// set the menu item
				SetExtensionMenuItem(
					Frames_Per_Sec,
					CreateIDDTextureFromFile(64.0f, 64.0f, "HGooey Files/XenDLL/Extensions/Frames_Per_Sec/Frames_Per_Sec.bmp", COLOR_RED));
				*/

				// create the texture for the menu item and create the extension
				IDDTexture* texture = CreateIDDTextureFromFile("HGooey Files/XenDLL/Extensions/Frames_Per_Sec/Frames_Per_Sec.bmp", COLOR_RED);
				
				if (!texture || !(Frames_Per_Sec = CreateExtension(texture))) return FALSE;

				float Scale = 1.0f;
				FPS_Display = CreateTextBar(
					"? Frames Per Second",
					Scale,
					Scale);

				if (!AttachObject(Frames_Per_Sec,FPS_Display))
				{
					UnloadExtension(Frames_Per_Sec);
					Frames_Per_Sec = NULL;

					return FALSE;
				}

				FPS_Display->SetBorderWidth(6.0f * Scale);
				FPS_Display->SetBorderHeight(5.0f * Scale);
				FPS_Display->MoveBySize((ScreenWidth() / GuiScaleX()) - FPS_Display->GetWidth(),0.0f);
				FPS_Display->SetAcceptAction(false);
				FPS_Display->SetCancelClick(false);

				const char* Data;
				bool write = false;

				if (Data = ReadConfigItem("MenuItemIO", "HGooey Files/XenDLL/Extensions/Frames_Per_Sec/Frames_Per_Sec.xml"))
				{
					if (strcmp(Data, "true") == 0)
						SetExtMenuIO(Frames_Per_Sec, true);
					else if (strcmp(Data, "false") == 0)
						SetExtMenuIO(Frames_Per_Sec, false);
					else
					{
						SetExtMenuIO(Frames_Per_Sec, false);
						write = true;
					}
				}
				else
				{
					write = true;
				}

				if (write)
				{
					WriteConfigItem("MenuItemIO", "false", "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml");
					write = false;
				}

				Loaded = true;
			}
			break;
		case DLL_PROCESS_DETACH:
			{
				if (!Loaded) return TRUE;

				Loaded = false;

				// unload and destroy stuff here (ie unload extensions)

				if (CheckExtMenuIO(Frames_Per_Sec))
					WriteConfigItem("MenuItemIO", "true", "HGooey Files/XenDLL/Extensions/Frames_Per_Sec/Frames_Per_Sec.xml");
				else
					WriteConfigItem("MenuItemIO", "false", "HGooey Files/XenDLL/Extensions/Frames_Per_Sec/Frames_Per_Sec.xml");

				UnloadExtension(Frames_Per_Sec);
				Frames_Per_Sec = NULL;
			}
			break;
    }

    return TRUE;
}
Exemplo n.º 5
0
//-------------------------------------------------------
// 
//-------------------------------------------------------
BOOL APIENTRY DllMain(HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					)
{
    switch (ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:
			{
				Loaded = false;
				ConfigOn = false;

				// do a version check to make sure users dont have older versions of HGooey
				if (!HGVersionCheck(HGVersion))
					return FALSE;

				// load and create stuff here (ie load extensions, create textures/images/objects/etc)

				// make sure the no one moved the extension
				if (GetFileAttributes("HGooey Files/XenDLL/Extensions/Night_Vision/HG_SDK.dll") == 0xFFFFFFFF) return FALSE;

				// make sure the menu item texture exists
				if (GetFileAttributes("HGooey Files/XenDLL/Extensions/Night_Vision/Night_Vision.bmp") == 0xFFFFFFFF) return FALSE;

				// create the extension
				Night_Vision = CreateExtension(CreateIDDTextureFromFile("HGooey Files/XenDLL/Extensions/Night_Vision/Night_Vision.bmp", COLOR_RED));

				if (!Night_Vision) return FALSE;

				const char* Data;
				bool write = false;

				if (Data = ReadConfigItem("MenuItemIO", "HGooey Files/XenDLL/Extensions/Night_Vision/Night_Vision.xml"))
				{
					if (strcmp(Data, "true") == 0)
						SetExtMenuIO(Night_Vision, true);
					else if (strcmp(Data, "false") == 0)
						SetExtMenuIO(Night_Vision, false);
					else
					{
						SetExtMenuIO(Night_Vision, false);
						write = true;
					}
				}
				else
				{
					write = true;
				}

				if (write)
				{
					WriteConfigItem("MenuItemIO", "false", "HGooey Files/XenDLL/Extensions/Night_Vision/Night_Vision.xml");
					write = false;
				}

				if (Data = ReadConfigItem("Night Vision", "HGooey Files/XenDLL/Common/Memory.xml"))
				{
					// check the night vision memory address
					try { dNight_Vision = (DWORD*)atoi(Data); }
					catch (...) { return FALSE; }
				}
				else
				{
					return FALSE;
				}

				Loaded = true;
			}
			break;
		case DLL_PROCESS_DETACH:
			{
				if (!Loaded) return TRUE;

				Loaded = false;

				// unload and destroy stuff here (ie unload extensions)

				if (CheckExtMenuIO(Night_Vision))
					WriteConfigItem("MenuItemIO", "true", "HGooey Files/XenDLL/Extensions/Night_Vision/Night_Vision.xml");
				else
					WriteConfigItem("MenuItemIO", "false", "HGooey Files/XenDLL/Extensions/Night_Vision/Night_Vision.xml");

				UnloadExtension(Night_Vision);
				Night_Vision = NULL;
			}
			break;
		
    }

    return TRUE;
}
Exemplo n.º 6
0
//-------------------------------------------------------
// 
//-------------------------------------------------------
BOOL APIENTRY DllMain(HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					)
{
    switch (ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:
			{
				Loaded = false;
				ConfigOn = false;

				// do a version check to make sure users dont have older versions of HGooey
				if (!HGVersionCheck(HGVersion))
					return FALSE;

				// load and create stuff here (ie load extensions, create textures/images/objects/etc)

				// make sure the no one moved the extension
				if (GetFileAttributes("HGooey Files/XenDLL/Extensions/Eye_Map/HG_SDK.dll") == 0xFFFFFFFF) return FALSE;

				// make sure the menu item texture exists
				if (GetFileAttributes("HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.bmp") == 0xFFFFFFFF) return FALSE;

				// make sure the menu memory file exists
				if (GetFileAttributes("HGooey Files/XenDLL/Common/Memory.xml") == 0xFFFFFFFF) return FALSE;

				///
	
				const char* Data;
				bool write = false;
				bool not_found = false;

				if (Data = ReadConfigItem("Location X", "HGooey Files/XenDLL/Common/Memory.xml"))
				{
					// check the location x memory address
					try { Location_X = (DWORD*)atoi(Data); }
					catch (...) { return FALSE; }
				}
				else
				{
					return FALSE;
				}

				if (Data = ReadConfigItem("Location Y", "HGooey Files/XenDLL/Common/Memory.xml"))
				{
					// check the location y memory address
					try { Location_Y = (DWORD*)atoi(Data); }
					catch (...) { return FALSE; }
				}
				else
				{
					return FALSE;
				}

				if (Data = ReadConfigItem("Screen", "HGooey Files/XenDLL/Common/Memory.xml"))
				{
					// check the screen memory address
					try { Screen = (DWORD*)atoi(Data); }
					catch (...) { return FALSE; }
				}
				else
				{
					return FALSE;
				}

				if (Data = ReadConfigItem("Chatmode", "HGooey Files/XenDLL/Common/Memory.xml"))
				{
					// check the chatmode memory address
					try { Chatmode = (DWORD*)atoi(Data); }
					catch (...) { return FALSE; }
				}
				else
				{
					return FALSE;
				}
	
				///
				
				bZoomIN = false;
				bZoomOUT = false;

				Eye_Map = CreateExtension();

				IDDTexture* texture = CreateIDDTextureFromFile("HGooey Files/Images/list.bmp", COLOR_RED);

				// set the menu item
				SetExtensionMenuItem(
					Eye_Map,
					CreateIDDTextureFromFile("HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.bmp", COLOR_RED));

				///

				if (Data = ReadConfigItem("Hide/Show Using DIK_[Key]", "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml"))
				{
					if ((HIDESHOW_KEY = convertDIK_Name(Data)) == 0x00)
							not_found = true;
				}
				else
				{
					not_found = true;
				}

				if (not_found)
				{
					HIDESHOW_KEY = 0x00;
					WriteConfigItem("Hide/Show Using DIK_[Key]", "DIK_", "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml");
				}

				///

				if (Data = ReadConfigItem("MenuItemIO", "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml"))
				{
					if (strcmp(Data, "true") == 0)
						SetExtMenuIO(Eye_Map, true);
					else if (strcmp(Data, "false") == 0)
						SetExtMenuIO(Eye_Map, false);
					else
					{
						SetExtMenuIO(Eye_Map, false);
						write = true;
					}
				}
				else
				{
					write = true;
				}

				if (write)
				{
					WriteConfigItem("MenuItemIO", "false", "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml");
					write = false;
				}

				///

				RECT rect;

				SetRect(&rect, DefaultList_left, DefaultList_top, DefaultList_right, DefaultList_bottom);
				Background = CreateImage(
					1.0f, 
					1.0f,  
					texture, 
					&rect);

				if (!AttachObject(Eye_Map, Background))
				{
					UnloadExtension(Eye_Map);
					Eye_Map = NULL;

					return FALSE;
				}

				///
	
				ZoomIN = CreateButton(" + ", 1.0f);

				if (!AttachObject(Background, ZoomIN))
				{
					UnloadExtension(Eye_Map);
					Eye_Map = NULL;

					return FALSE;
				}

				///

				ZoomOUT = CreateButton(" - ", 1.0f);

				if (!AttachObject(Background, ZoomOUT))
				{
					UnloadExtension(Eye_Map);
					Eye_Map = NULL;

					return FALSE;
				}

				///

				ZoomRESET = CreateButton("reset", 1.0f);

				if (!AttachObject(Background, ZoomRESET))
				{
					UnloadExtension(Eye_Map);
					Eye_Map = NULL;

					return FALSE;
				}

				///

				MapButtonText[0] = "Main";
				MapButtonText[1] = "2";
				MapButtonText[2] = "3";

				///

				// set a default and then read the config file
				bool DisplayMoveAlways = false;

				if (Data = ReadConfigItem("DisplayMoveAlways", "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml"))
				{
					if (_stricmp(Data, "true") == 0)
						DisplayMoveAlways = true;
					else if (_stricmp(Data, "false") != 0)
						write = true;
				}
				else
				{
					write = true;
				}

				if (write)
				{
					WriteConfigItem("DisplayMoveAlways", "false", "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml");
					write = false;
				}

				if (DisplayMoveAlways)
					Background->SetMoveable(MOVE_ALWAYS);
				else
					Background->SetMoveable(MOVE_LIMITED);

				float DisplaySizeOriginal = 128.0f;
				DisplaySize = DisplaySizeOriginal;

				if (Data = ReadConfigItem("DisplaySizeScale", "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml"))
				{
					DisplaySize *= (float)atof(Data) / 100.0f;
				}
				else
				{
					char buffer[64];
					sprintf_s(buffer, 64, "%f", 100.0f);
					WriteConfigItem("DisplaySizeScale", buffer, "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml");
				}

				DisplayInitialScale = DisplaySizeOriginal / DisplaySize;

				///

				if (Data = ReadConfigItem("MapButtonText[0]", "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml"))
				{
					MapButtonText[0] = restring(Data, 0, strlen(Data));
				}
				else
				{
					WriteConfigItem("MapButtonText[0]", MapButtonText[0], "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml");
				}

				MapFile[0] = "xenmap0.bmp";

				if (GetFileAttributes(MapFile[0]) == 0xFFFFFFFF)
					MapFile[0] = "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.bmp";

				if (Data = ReadConfigItem("Map[0] Filename", "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml"))
				{
					if (GetFileAttributes(Data) != 0xFFFFFFFF)
							MapFile[0] = restring(Data, 0, strlen(Data));
				}
				else
				{
					WriteConfigItem("MapFile[0] Filename", MapFile[0], "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml");
				}

				MapF2GX[0] = 6.2890625f;

				if (Data = ReadConfigItem("Map[0] File2Game X", "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml"))
				{
					MapF2GX[0] = (float)atof(Data);
				}
				else
				{
					char buffer[64];
					sprintf_s(buffer, 64, "%f", MapF2GX[0]);
					WriteConfigItem("Map[0] File2Game X", buffer, "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml");
				}

				MapF2GY[0] = 6.2890625f;

				if (Data = ReadConfigItem("Map[0] File2Game Y", "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml"))
				{
					MapF2GY[0] = (float)atof(Data);
				}
				else
				{
					char buffer[64];
					sprintf_s(buffer, 64, "%f", MapF2GY[0]);
					WriteConfigItem("Map[0] File2Game Y", buffer, "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml");
				}

				MapTexture[0] = CreateIDDTextureFromFile(MapFile[0], COLOR_DEFAULT);

				SetRect(&Zoom, 0, 0, (int)(DisplaySize * DisplayInitialScale), (int)(DisplaySize * DisplayInitialScale));
				Map[0] = CreateImage(
					1.0f, 
					1.0f,  
					MapTexture[0], 
					&Zoom);
				
				if (!AttachObject(Background, Map[0]))
				{
					UnloadExtension(Eye_Map);
					Eye_Map = NULL;

					return FALSE;
				}

				///

				for (int i = 1; i < 3; i++)
				{
					char bufffffer[128];
					
					sprintf_s(bufffffer, 128, "MapButtonText[%d]", i);

					if (Data = ReadConfigItem(bufffffer, "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml"))
					{
						MapButtonText[i] = restring(Data, 0, strlen(Data));
					}
					else
					{
						WriteConfigItem(bufffffer, MapButtonText[i], "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml");
					}

					MapFile[i] = "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.bmp";
					
					sprintf_s(bufffffer, 128, "Map[%d] Filename", i);

					if (Data = ReadConfigItem(bufffffer, "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml"))
					{
						if (GetFileAttributes(Data) != 0xFFFFFFFF)
							MapFile[i] = restring(Data, 0, strlen(Data));
					}
					else
					{
						WriteConfigItem(bufffffer, MapFile[i], "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml");
					}

					MapF2GX[i] = 0.0f;
					
					sprintf_s(bufffffer, 128, "Map[%d] File2Game X", i);

					if (Data = ReadConfigItem(bufffffer, "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml"))
					{
						MapF2GX[i] = (float)atof(Data);
					}
					else
					{
						char buffer[64];
						sprintf_s(buffer, 64, "%f", MapF2GX[i]);
						WriteConfigItem(bufffffer, buffer, "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml");
					}

					MapF2GY[i] = 0.0f;
					
					sprintf_s(bufffffer, 128, "Map[%d] File2Game Y", i);

					if (Data = ReadConfigItem(bufffffer, "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml"))
					{
						MapF2GY[i] = (float)atof(Data);
					}
					else
					{
						char buffer[64];
						sprintf_s(buffer, 64, "%f", MapF2GY[i]);
						WriteConfigItem(bufffffer, buffer, "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml");
					}

					MapTexture[i] = CreateIDDTextureFromFile(MapFile[i], COLOR_DEFAULT);

					SetRect(&Zoom, 0, 0, (int)(DisplaySize * DisplayInitialScale), (int)(DisplaySize * DisplayInitialScale));
					Map[i] = CreateImage(
						1.0f, 
						1.0f,  
						MapTexture[i], 
						&Zoom);
					
					if (!AttachObject(Background, Map[i]))
					{
						UnloadExtension(Eye_Map);
						Eye_Map = NULL;

						return FALSE;
					}
				}

				///
				
				for (int i = 0; i < 3; i++)
				{
					MapButton[i] = CreateButton(MapButtonText[i], 1.0f);

					if (!AttachObject(Background, MapButton[i]))
					{
						UnloadExtension(Eye_Map);
						Eye_Map = NULL;

						return FALSE;
					}

					MapButton[i]->SetStickyIO(true);
				}

				MapButton[0]->SetIO(true);

				///

				Location = CreateImage(
					1.0f, 
					1.0f,  
					CreateIDDTextureFromFile("HGooey Files/XenDLL/Extensions/Eye_Map/location.bmp", COLOR_RED));
				
				if (!AttachObject(Background, Location))
				{
					UnloadExtension(Eye_Map);
					Eye_Map = NULL;

					return FALSE;
				}

				Location->SetAcceptAction(false);
				Location->SetCancelClick(false);

				///

				float DisplayBorder = 7.5f * (DisplaySize / DisplaySizeOriginal);
				float MapButtonBorder = 2.5f  * (DisplaySize / DisplaySizeOriginal);

				for (int i = 0; i < 3; i++)
					MapButton[i]->ReScale((DisplaySize / 3.0f) / MapButton[i]->GetWidth(), (DisplaySize / 3.0f) / MapButton[i]->GetWidth());

				ZoomIN->ReScale((DisplaySize / 3.0f) / ZoomIN->GetWidth(), (DisplaySize / 3.0f) / ZoomIN->GetWidth());
				ZoomOUT->ReScale((DisplaySize / 3.0f) / ZoomOUT->GetWidth(), (DisplaySize / 3.0f) / ZoomOUT->GetWidth());
				ZoomRESET->ReScale((DisplaySize / 3.0f) / ZoomRESET->GetWidth(), (DisplaySize / 3.0f) / ZoomRESET->GetWidth());

				// should all be the same, but... whatever...
				float largerHeight0 = MapButton[0]->GetHeight();
				if (MapButton[1]->GetHeight() > largerHeight0) largerHeight0 = MapButton[1]->GetHeight();
				if (MapButton[2]->GetHeight() > largerHeight0) largerHeight0 = MapButton[2]->GetHeight();

				float largerHeight1 = ZoomIN->GetHeight();
				if (ZoomOUT->GetHeight() > largerHeight1) largerHeight1 = ZoomOUT->GetHeight();
				if (ZoomRESET->GetHeight() > largerHeight1) largerHeight1 = ZoomRESET->GetHeight();

				float largerHeight2 = largerHeight0 + largerHeight1;

				Background->ReScale(
					(DisplaySize + (DisplayBorder*2.0f)) / (float)DefaultList_width,
					(DisplaySize + (DisplayBorder*2.0f) + MapButtonBorder + largerHeight2) / (float)DefaultList_height);

				DisplayX = 0.0f;

				if (Data = ReadConfigItem("DisplayX", "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml"))
				{
					DisplayX = (float)atof(Data);

					if (DisplayX < 0.0f)
					{
						DisplayX = 0.0f;
						write = true;
					}
					else if ((DisplayX + Background->GetWidth()) * GuiScaleX() > ScreenWidth())
					{
						DisplayX = (ScreenWidth() / GuiScaleX()) - Background->GetWidth();
						write = true;
					}
				}
				else
				{
					write = true;
				}

				if (write)
				{
					char buffer[64];
					sprintf_s(buffer, 64, "%f", DisplayX);
					WriteConfigItem("DisplayX", buffer, "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml");
					write = false;
				}

				DisplayY = 0.0f;

				if (Data = ReadConfigItem("DisplayY", "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml"))
				{
					DisplayY = (float)atof(Data);

					if (DisplayY < 0.0f)
					{
						DisplayY = 0.0f;
						write = true;
					}
					else if ((DisplayY + Background->GetHeight()) * GuiScaleY() > ScreenHeight())
					{
						DisplayY = (ScreenHeight() / GuiScaleY()) - Background->GetHeight();
						write = true;
					}
				}
				else
				{
					write = true;
				}

				if (write)
				{
					char buffer[64];
					sprintf_s(buffer, 64, "%f", DisplayY);
					WriteConfigItem("DisplayY", buffer, "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml");
					write = false;
				}

				Background->MoveBySize(
					DisplayX, 
					DisplayY);

				MapButton[0]->MoveBySize(
					DisplayBorder, 
					DisplayBorder);

				MapButton[1]->MoveBySize(
					DisplayBorder + (DisplaySize / 2.0f) - (MapButton[1]->GetWidth() / 2.0f), 
					DisplayBorder);

				MapButton[2]->MoveBySize(
					DisplayBorder + DisplaySize - MapButton[2]->GetWidth(), 
					DisplayBorder);

				ZoomIN->MoveBySize(
					DisplayBorder, 
					DisplayBorder + largerHeight0);

				ZoomOUT->MoveBySize(
					DisplayBorder + (DisplaySize / 2.0f) - (ZoomOUT->GetWidth() / 2.0f), 
					DisplayBorder + largerHeight0);

				ZoomRESET->MoveBySize(
					DisplayBorder + DisplaySize - ZoomRESET->GetWidth(), 
					DisplayBorder + largerHeight0);

				for (int i = 0; i < 3; i++)
				{
					Map[i]->MoveBySize(
						DisplayBorder, 
						DisplayBorder + MapButtonBorder + largerHeight2);
				}

				Location->MoveBySize(
					DisplayBorder,
					DisplayBorder + MapButtonBorder + largerHeight2);

				Loaded = true;
			}
			break;
		case DLL_PROCESS_DETACH:
			{
				if (!Loaded) return TRUE;

				Loaded = false;

				// unload and destroy stuff here (ie unload extensions)
				
				char buffer[64];

				sprintf_s(buffer, 64, "%f", Background->GetX() / GuiScaleX());
				WriteConfigItem("DisplayX", buffer, "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml");

				sprintf_s(buffer, 64, "%f", Background->GetY() / GuiScaleY());
				WriteConfigItem("DisplayY", buffer, "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml");

				if (CheckExtMenuIO(Eye_Map))
					WriteConfigItem("MenuItemIO", "true", "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml");
				else
					WriteConfigItem("MenuItemIO", "false", "HGooey Files/XenDLL/Extensions/Eye_Map/Eye_Map.xml");

				UnloadExtension(Eye_Map);
				Eye_Map = NULL;
			}
			break;
		
    }

    return TRUE;
}