/** * void CBasePlayer::Observer_SetMode(int mode) * * @param mode Observer mode. * @noreturn */ DETOUR_DECL_MEMBER1(Observer_SetMode, void, int, mode) { auto pvPlayer = reinterpret_cast<void*>(this); #if defined(KE_LINUX) asm volatile ( "movl %%edx, %0;" "movl %%eax, %1;" : "=d" (mode), "=a" (pvPlayer) : : ); #endif if (Util::ShouldRunCode()) { auto pPlayer = TypeConversion.cbase_to_edict(pvPlayer); if (Util::IsAdmin(pPlayer)) { g_pengfuncsTable->pfnCVarGetFloat = CVarGetFloat; } else { auto numFlags = 0; auto userFlags = Util::GetUserMode(&numFlags); if (numFlags) { g_pengfuncsTable->pfnCVarGetFloat = CVarGetFloat; mode = (numFlags == 1) ? Util::GetFlagPosition(userFlags) : Util::GetNextUserMode(pPlayer, userFlags); if (pPlayer->v.iuser1 == OBS_NONE) // When starting to observe, force to update target. { get_pdata<EHANDLE>(pPlayer, m_hObserverTarget).Set(nullptr); } } } } #if defined(KE_WINDOWS) || defined(KE_MACOSX) DETOUR_MEMBER_CALL(Observer_SetMode)(mode); #elif defined(KE_LINUX) ObserverSetModeDetour->DisableDetour(); SetModePart2(reinterpret_cast<void*>(pvPlayer), mode); ObserverSetModeDetour->EnableDetour(); #endif if (g_pengfuncsTable->pfnCVarGetFloat) { g_pengfuncsTable->pfnCVarGetFloat = nullptr; } }
/** * BOOL CBasePlayer::Observer_IsValidTarget(int index, bool checkteam) * * @param index Player's index to check validity. * @param checkteam Whether player's team should be checked. * * @return True on success, otherwise false. */ DETOUR_DECL_MEMBER2(Observer_IsValidTarget, void*, int, index, bool, checkteam) { if (Util::ShouldRunCode()) { auto pPlayer = reinterpret_cast<void*>(this); if (checkteam && Util::IsAdmin(TypeConversion.cbase_to_edict(pPlayer))) { checkteam = false; // We are admin and any targets are valid. } else if (!checkteam && Util::GetUserMode() && get_pdata<int>(pPlayer, m_iTeam) != TEAM_SPECTATOR) { checkteam = true; // We override normal users mode and target should be always a teammate. } if (g_pengfuncsTable->pfnCVarGetFloat) { g_pengfuncsTable->pfnCVarGetFloat = nullptr; } } return DETOUR_MEMBER_CALL(Observer_IsValidTarget)(index, checkteam); }
void OnPluginsLoaded() { TypeConversion.init(); }
// Very first point at map load // Load AMX modules for new native functions // Initialize AMX stuff and load it's plugins from plugins.ini list // Call precache forward function from plugins int C_Spawn(edict_t *pent) { if (g_initialized) { RETURN_META_VALUE(MRES_IGNORED, 0); } g_activated = false; g_initialized = true; g_forcedmodules = false; g_forcedsounds = false; g_srvindex = IS_DEDICATED_SERVER() ? 0 : 1; hostname = CVAR_GET_POINTER("hostname"); mp_timelimit = CVAR_GET_POINTER("mp_timelimit"); // Fix for crashing on mods that do not have mp_timelimit if (mp_timelimit == NULL) { static cvar_t timelimit_holder; timelimit_holder.name = "mp_timelimit"; timelimit_holder.string = "0"; timelimit_holder.flags = 0; timelimit_holder.value = 0.0; CVAR_REGISTER(&timelimit_holder); mp_timelimit = &timelimit_holder; } g_forwards.clear(); g_log.MapChange(); // ###### Initialize task manager g_tasksMngr.registerTimers(&gpGlobals->time, &mp_timelimit->value, &g_game_timeleft); // ###### Initialize commands prefixes g_commands.registerPrefix("amx"); g_commands.registerPrefix("amxx"); g_commands.registerPrefix("say"); g_commands.registerPrefix("admin_"); g_commands.registerPrefix("sm_"); g_commands.registerPrefix("cm_"); // make sure localinfos are set get_localinfo("amxx_basedir", "addons/amxmodx"); get_localinfo("amxx_pluginsdir", "addons/amxmodx/plugins"); get_localinfo("amxx_modulesdir", "addons/amxmodx/modules"); get_localinfo("amxx_configsdir", "addons/amxmodx/configs"); get_localinfo("amxx_customdir", "addons/amxmodx/custom"); // make sure bcompat localinfos are set get_localinfo("amx_basedir", "addons/amxmodx"); get_localinfo("amx_configdir", "addons/amxmodx/configs"); get_localinfo("amx_langdir", "addons/amxmodx/data/amxmod-lang"); get_localinfo("amx_modulesdir", "addons/amxmodx/modules"); get_localinfo("amx_pluginsdir", "addons/amxmodx/plugins"); get_localinfo("amx_logdir", "addons/amxmodx/logs"); FlagMan.LoadFile(); ArrayHandles.clear(); TrieHandles.clear(); TrieSnapshotHandles.clear(); DataPackHandles.clear(); TextParsersHandles.clear(); GameConfigHandle.clear(); char map_pluginsfile_path[256]; char prefixed_map_pluginsfile[256]; char configs_dir[256]; // ###### Load modules loadModules(get_localinfo("amxx_modules", "addons/amxmodx/configs/modules.ini"), PT_ANYTIME); get_localinfo_r("amxx_configsdir", "addons/amxmodx/configs", configs_dir, sizeof(configs_dir)-1); g_plugins.CALMFromFile(get_localinfo("amxx_plugins", "addons/amxmodx/configs/plugins.ini")); LoadExtraPluginsToPCALM(configs_dir); char temporaryMap[64], *tmap_ptr; ke::SafeSprintf(temporaryMap, sizeof(temporaryMap), "%s", STRING(gpGlobals->mapname)); prefixed_map_pluginsfile[0] = '\0'; if ((tmap_ptr = strchr(temporaryMap, '_')) != NULL) { // this map has a prefix *tmap_ptr = '\0'; ke::SafeSprintf(prefixed_map_pluginsfile, sizeof(prefixed_map_pluginsfile), "%s/maps/plugins-%s.ini", configs_dir, temporaryMap); g_plugins.CALMFromFile(prefixed_map_pluginsfile); } ke::SafeSprintf(map_pluginsfile_path, sizeof(map_pluginsfile_path), "%s/maps/plugins-%s.ini", configs_dir, STRING(gpGlobals->mapname)); g_plugins.CALMFromFile(map_pluginsfile_path); int loaded = countModules(CountModules_Running); // Call after attachModules so all modules don't have pending stat // Set some info about amx version and modules CVAR_SET_STRING(init_amxmodx_version.name, AMXX_VERSION); char buffer[32]; sprintf(buffer, "%d", loaded); CVAR_SET_STRING(init_amxmodx_modules.name, buffer); // ###### Load Vault char file[255]; g_vault.setSource(build_pathname_r(file, sizeof(file) - 1, "%s", get_localinfo("amxx_vault", "addons/amxmodx/configs/vault.ini"))); g_vault.loadVault(); // ###### Init time and freeze tasks g_game_timeleft = g_bmod_dod ? 1.0f : 0.0f; g_task_time = gpGlobals->time + 99999.0f; g_auth_time = gpGlobals->time + 99999.0f; #ifdef MEMORY_TEST g_next_memreport_time = gpGlobals->time + 99999.0f; #endif g_players_num = 0; // Set server flags memset(g_players[0].flags, -1, sizeof(g_players[0].flags)); g_opt_level = atoi(get_localinfo("optimizer", "7")); if (!g_opt_level) g_opt_level = 7; // ###### Load AMX Mod X plugins g_plugins.loadPluginsFromFile(get_localinfo("amxx_plugins", "addons/amxmodx/configs/plugins.ini")); LoadExtraPluginsFromDir(configs_dir); g_plugins.loadPluginsFromFile(map_pluginsfile_path, false); if (prefixed_map_pluginsfile[0] != '\0') { g_plugins.loadPluginsFromFile(prefixed_map_pluginsfile, false); } g_plugins.Finalize(); g_plugins.InvalidateCache(); // Register forwards FF_PluginInit = registerForward("plugin_init", ET_IGNORE, FP_DONE); FF_ClientCommand = registerForward("client_command", ET_STOP, FP_CELL, FP_DONE); FF_ClientConnect = registerForward("client_connect", ET_IGNORE, FP_CELL, FP_DONE); FF_ClientDisconnect = registerForward("client_disconnect", ET_IGNORE, FP_CELL, FP_DONE); FF_ClientDisconnected = registerForward("client_disconnected", ET_IGNORE, FP_CELL, FP_CELL, FP_ARRAY, FP_CELL, FP_DONE); FF_ClientRemove = registerForward("client_remove", ET_IGNORE, FP_CELL, FP_CELL, FP_STRING, FP_DONE); FF_ClientInfoChanged = registerForward("client_infochanged", ET_IGNORE, FP_CELL, FP_DONE); FF_ClientPutInServer = registerForward("client_putinserver", ET_IGNORE, FP_CELL, FP_DONE); FF_PluginCfg = registerForward("plugin_cfg", ET_IGNORE, FP_DONE); FF_PluginPrecache = registerForward("plugin_precache", ET_IGNORE, FP_DONE); FF_PluginLog = registerForward("plugin_log", ET_STOP, FP_DONE); FF_PluginEnd = registerForward("plugin_end", ET_IGNORE, FP_DONE); FF_InconsistentFile = registerForward("inconsistent_file", ET_STOP, FP_CELL, FP_STRING, FP_STRINGEX, FP_DONE); FF_ClientAuthorized = registerForward("client_authorized", ET_IGNORE, FP_CELL, FP_STRING, FP_DONE); FF_ChangeLevel = registerForward("server_changelevel", ET_STOP, FP_STRING, FP_DONE); FF_ClientConnectEx = registerForward("client_connectex", ET_STOP, FP_CELL, FP_STRING, FP_STRING, FP_ARRAY, FP_DONE); CoreCfg.OnAmxxInitialized(); #if defined BINLOG_ENABLED if (!g_BinLog.Open()) { LOG_ERROR(PLID, "Binary log failed to open."); } g_binlog_level = atoi(get_localinfo("bin_logging", "17")); g_binlog_maxsize = atoi(get_localinfo("max_binlog_size", "20")); #endif modules_callPluginsLoaded(); TypeConversion.init(); // ###### Call precache forward function g_dontprecache = false; executeForwards(FF_PluginPrecache); g_dontprecache = true; for (CList<ForceObject>::iterator a = g_forcegeneric.begin(); a; ++a) { PRECACHE_GENERIC((char*)(*a).getFilename()); ENGINE_FORCE_UNMODIFIED((*a).getForceType(), (*a).getMin(), (*a).getMax(), (*a).getFilename()); } RETURN_META_VALUE(MRES_IGNORED, 0); }