Example #1
0
bool CGameConfig::Reparse(char *error, size_t maxlength)
{
	m_Offsets.clear();
	m_OffsetsByClass.clear();
	m_Keys.clear();
	m_Addresses.clear();

	char path[PLATFORM_MAX_PATH];
	const char *dataDir = get_localinfo("amxx_datadir", "addons/amxmodx/data");

	build_pathname_r(path, sizeof(path), "%s/gamedata/%s/master.games.txt", dataDir, m_File);

	if (!g_LibSys.PathExists(path))
	{
		// Single config file without master
		g_LibSys.PathFormat(path, sizeof(path), "%s.txt", m_File);

		if (!EnterFile(path, error, maxlength))
		{
			return false;
		}

		// Allow customizations of default gamedata files
		build_pathname_r(path, sizeof(path), "%s/gamedata/custom/%s.txt", dataDir, m_File);

		if (g_LibSys.PathExists(path))
		{
			g_LibSys.PathFormat(path, sizeof(path), "custom/%s.txt", m_File);

			auto success = EnterFile(path, error, maxlength);

			if (success)
			{
				AMXXLOG_Log("[AMXX] Parsed custom gamedata override file: %s", path);
			}

			return success;
		}
		return true;
	}

	SMCError err;
	SMCStates state = { 0, 0 };

	ke::Vector<ke::AString> fileList;
	MasterReader.m_FileList = &fileList;

	err = textparsers->ParseSMCFile(path, &MasterReader, &state, error, maxlength);

	if (err != SMCError_Okay)
	{
		const char *msg = textparsers->GetSMCErrorString(err);

		AMXXLOG_Error("Error parsing master gameconf file \"%s\":", path);
		AMXXLOG_Error("Error %d on line %d, col %d: %s", err, state.line, state.col, msg ? msg : "Unknown error");

		return false;
	}

	for (size_t i = 0; i < fileList.length(); ++i)
	{
		g_LibSys.PathFormat(path, sizeof(path), "%s/%s", m_File, fileList[i].chars());

		if (!EnterFile(path, error, maxlength))
		{
			return false;
		}
	}

	build_pathname_r(path, sizeof(path), "%s/gamedata/%s/custom", dataDir, m_File);
	CDirectory *customDir = g_LibSys.OpenDirectory(path);

	if (!customDir)
	{
		return true;
	}

	while (customDir->MoreFiles())
	{
		if (!customDir->IsEntryFile())
		{
			customDir->NextEntry();
			continue;
		}

		const char *currentFile = customDir->GetEntryName();

		size_t length = strlen(currentFile);

		if (length > 4 && strcmp(&currentFile[length - 4], ".txt") != 0)
		{
			customDir->NextEntry();
			continue;
		}

		g_LibSys.PathFormat(path, sizeof(path), "%s/custom/%s", m_File, currentFile);

		if (!EnterFile(path, error, maxlength))
		{
			g_LibSys.CloseDirectory(customDir);
			return false;
		}

		AMXXLOG_Log("[AMXX] Parsed custom gamedata override file: %s", path);

		customDir->NextEntry();
	}

	g_LibSys.CloseDirectory(customDir);

	return true;
}
Example #2
0
// native next_file(dirh, buffer[], length, &FileType:type = FileType_Unknown);
static cell AMX_NATIVE_CALL amx_get_dir(AMX *amx, cell *params)
{
	DirectoryHandle* p = reinterpret_cast<DirectoryHandle*>(params[1]);

	if (!p)
	{
		return 0;
	}

	size_t numParams = *params / sizeof(cell);

	if (p->valvefs)
	{
		FileFindHandle_t* handle = reinterpret_cast<FileFindHandle_t*>(p->handle);

		if (!handle)
		{
			return 0;
		}

		const char* entry = g_FileSystem->FindNext(*handle);

		if (!entry)
		{
			return 0;
		}

		if (numParams >= 4)
		{
			cell* fileType = get_amxaddr(amx, params[4]);
			*fileType = g_FileSystem->FindIsDirectory(*handle) ? FileType_Directory : FileType_File;
		}

		set_amxstring_utf8(amx, params[2], entry, strlen(entry), params[3] + 1);
	}
	else
	{
		CDirectory* handle = reinterpret_cast<CDirectory*>(p->handle);

		if (!handle)
		{
			return 0;
		}

		handle->NextEntry();

		if (!handle->MoreFiles())
		{
			return 0;
		}

		if (numParams >= 4)
		{
			cell* fileType = get_amxaddr(amx, params[4]);
			*fileType = handle->IsEntryDirectory() ? FileType_Directory : FileType_File;
		}

		const char* entry = handle->GetEntryName();

		set_amxstring_utf8(amx, params[2], entry, strlen(entry), params[3] + 1);
	}

	return 1;
}