Files
gtav-src/tools_ng/dcc/current/max2012/scripts/pipeline/util/file.ms
T
2025-09-29 00:52:08 +02:00

400 lines
11 KiB
Plaintext
Executable File

-- Rockstar File Utility
-- Rockstar North
-- 1/3/2005
-- by Greg Smith
-- by Luke Openshaw
-- Set of utility functions for dealing with files
--filein "pipeline/util/string.ms" -- loaded on startup by startup.ms
----------------------------------------------------------------------------------------
-- These old function-names are now aliases of built-in Max functions:
----------------------------------------------------------------------------------------
global RsFileExists = DoesFileExist
global RsRemovePath = FilenameFromPath
global RsRemoveFile = GetFilenamePath
----------------------------------------------------------------------------------------
-- from a full path to a file return just the filename with no extension
----------------------------------------------------------------------------------------
fn RsRemovePathAndExtension path =
(
local outVal = getFilenameFile path
-- getFilenameFile only strips the last extension, it doesn't deal with piled-up extensions:
return (filterString outVal ".")[1]
)
----------------------------------------------------------------------------------------
-- use & - reference for extension
----------------------------------------------------------------------------------------
fn RsRemoveExtension path extension: =
(
local extParts = (filterString path ".")
if unsupplied!=extension then
*extension = extParts[2]
return extParts[1]
)
----------------------------------------------------------------------------------------
-- find the last occurance of a character in a string
----------------------------------------------------------------------------------------
fn RsFindLast searched char = (
retidx = -1
for i = 1 to searched.count do (
if retidx == -1 then (
index = searched.count - (i - 1)
if char == searched[index] then (
retidx = index
)
)
)
retidx
)
--------------------------------------------------------------
-- makes sure that a passed in string is a valid path
--------------------------------------------------------------
fn RsMakeSafeSlashes pathin = (
pathout = ""
if isKindOf pathin String do
(
local c
local prevSlash = False
for i = 1 to pathin.count do
(
c = pathin[i]
if (c == "/") or (c == "\\") then
(
if not prevSlash do
(
pathout += "/"
)
prevSlash = True
)
else
(
prevSlash = False
pathout += c
)
)
)
pathout
)
--------------------------------------------------------------
-- makes sure that a passed in string is a valid path
--------------------------------------------------------------
fn RsMakeBackSlashes pathin = (
pathout = ""
if isKindOf pathin String do
(
local c
local prevSlash = False
for i = 1 to pathin.count do
(
c = pathin[i]
if (c == "/") or (c == "\\") then
(
if not prevSlash do
(
pathout += "\\"
)
prevSlash = True
)
else
(
prevSlash = False
pathout += c
)
)
)
pathout
)
----------------------------------------------------------------------------------------
-- takes the filename of the path, leaving just the directory that the file is in
----------------------------------------------------------------------------------------
fn RsRemoveFilename fullpath =
(
RsMakeSafeSlashes (getFilenamePath fullpath)
)
--------------------------------------------------------------
-- makes sure that a passed in string is a valid path
--------------------------------------------------------------
fn RsMakeSafePath pathin = (
pathout = RsMakeSafeSlashes pathin
if pathout[pathout.count] != "/" then (
pathout = pathout + "/"
)
pathout
)
-------------------------------------------------------------------------------------------------
-- check that all the paths exist for the passed in file path
-------------------------------------------------------------------------------------------------
fn RsMakeSurePathExists filePath =
(
local dirPath = ""
if ( "" == ( getFilenameType filePath ) ) then
dirPath = filePath
else
dirPath = (getFilenamePath filePath)
makedir DirPath
)
-------------------------------------------------------------------------------------------------
-- delete a directory and any files in contains
-------------------------------------------------------------------------------------------------
fn RsDeleteDirectory dir =
(
-- GunnarD found bug 697996, taking out fo now
diruse = RsMakeSafeSlashes dir
return rexDeleteDirectory diruse
)
-------------------------------------------------------------------------------------------------
-- delete all the files of a certain type in a directory
-------------------------------------------------------------------------------------------------
fn RsDeleteFiles wildcard = (
wildcard = RsMakeBackSlashes wildcard
retval = true
files = getfiles wildcard
for file in files do (
if retval == true then (
if deletefile file == false then (
retval = false
)
)
)
retval
)
-------------------------------------------------------------------------------------------------
-- copy all files by wildcard to a target folder
-------------------------------------------------------------------------------------------------
fn RsCopyFiles wildcard targetdir = (
retval = true
files = getfiles wildcard
for file in files do (
if retval == true then (
targetfile = filenameFromPath file
if copyfile file (targetdir + "/" + targetfile) == false then (
retval = false
)
)
)
retval
)
-------------------------------------------------------------------------------------------------
-- returns true if a file exists and is readonly else false
-------------------------------------------------------------------------------------------------
fn RsIsFileReadOnly file = (
if ( doesFileExist file ) then
( getfileattribute file #readOnly )
else
false
)
-------------------------------------------------------------------------------------------------
-- RsFindFilesRecursive
-- Recursively find list of files under rootpath matching wildcard(s)
-- (e.g. "*.ide" or #("*.tga", "*.jpg))
-------------------------------------------------------------------------------------------------
fn RsFindFilesRecursive rootpath wildcards foundFiles:#() =
(
local foundFiles = #()
if not isKindOf wildcards Array do
(
wildcards = #(wildcards)
)
for wildcard in wildcards do
(
join foundFiles (getFiles (rootpath + "/" + wildcard))
)
-- Post process to have consistent file paths
for i = 1 to foundFiles.count do
(
foundFiles[i] = RsMakeSafeSlashes foundFiles[i]
)
for subDir in getDirectories (rootpath + "/*") do
(
join foundFiles (RsFindFilesRecursive subDir wildcards foundFiles:foundFiles)
)
return foundFiles
)
-------------------------------------------------------------------------------------------------
-- name: RsFileExist
-- description: Check if a file exists
-------------------------------------------------------------------------------------------------
global RsFileExist = doesFileExist
-------------------------------------------------------------------------------------------------
-- RsFindDirsRec
-- Do not call this externally, use RsFindDirsRecursive
-------------------------------------------------------------------------------------------------
fn RsFindDirsRec dirpath dirList =
(
dirs = getDirectories (dirpath + "*")
join dirList dirs
for dir in dirs do (
RsFindDirsRec dir dirList
)
)
-------------------------------------------------------------------------------------------------
-- RsFindDirsRecursive
-- Recursively find list of dirs under rootpath with the folder name pattern
-------------------------------------------------------------------------------------------------
fn RsFindDirsRecursive rootpath pattern foundDirs:#() =
(
matchedDirs = #()
RsFindDirsRec rootpath foundDirs
for dir in foundDirs do
(
-- Checks for trailing slash too as that is included in getDirectories incase * is not
-- on the end of the pattern passed in
if ( matchPattern dir pattern:pattern or matchPattern dir pattern:(pattern + "\\") ) do
(
appendIfUnique matchedDirs dir
)
)
matchedDirs
)
--
-- name: RsDirectoryWriteable
-- desc: Check that a directory exists and is writeable
--
fn RsDirectoryWriteable dir = (
-- Because RsConfigGetNetworkStreamDir() returns a path ending with a '/', this should check
-- if the '/' is present and if so remove it.
if (matchPattern dir pattern:"*/" == true) then (
dir = substring dir 1 (dir.count - 1)
)
-- DHM 2/8/10 -- to be blunt "isDirectoryWriteable" doesn't work with our
-- network paths at least. Lets try to write a test file; which is kind of nasty and could
-- leave a temporary file behind; but its got the machine name so its relatively safe.
-- isDirectoryWriteable dir
try
(
local filename = (dir + "\\3dsmax_writeable_" + sysInfo.computername + ".txt")
local fp = openFile filename mode:"w"
format "File created for RsDirectoryWriteable(). Delete if modified date is not now!" to:fp
close fp
deleteFile filename
true
)
catch
(
false
)
)
--
-- name: RsFileModDate
-- desc: Return file modifier date/time as .Net DateTime object
-- (for comparison)
--
fn RsFileModDate filename = (
local fileClass = dotNetClass "System.IO.File"
local md = fileClass.GetLastWriteTime( filename )
md
)
--
-- name: RsFileCreateDate
-- desc: Return file creation date/time as .Net DateTime object
-- (for comparison)
--
fn RsFileCreateDate filename = (
local fileClass = dotNetClass "System.IO.File"
local md = fileClass.GetCreationTime( filename )
md
)
-- Open-dialog to get multiple filenames at once:
fn RSgetOpenFilenames caption:"Open" filename:"" types:"All Files (*.*)|*.*" default:1 =
(
local openDialog = DotNetObject "System.Windows.Forms.OpenFileDialog"
openDialog.multiSelect = true
openDialog.title = caption
local filePath = getFilenamePath filename
if doesFileExist filePath do
(
openDialog.initialDirectory = filePath
)
-- MAXScript getOpenFilename uses trailing |; DotNet's OpenFileDialog filter does not.
if (types[types.count] == "|") do (types = (substring types 1 (types.count - 1)))
openDialog.filter = types
openDialog.filterIndex = default
local result = openDialog.ShowDialog()
if (result.Equals result.OK) then openDialog.filenames else undefined
)
-- Removes any empty directories under path dirPath
fn RsRemoveEmptyFolders dirPath =
(
HiddenDOSCommand ("for /f \"usebackq delims=\" %d in (`\"dir \"" + (RsMakeBackSlashes dirPath) + "\" /ad/b/s | sort /R\"`) do rd \"%d\"")
)
-- Returns hash of dirPath's file-times, allowing for easy change-tracking:
fn RsPathTimeHash dirPath =
(
local dirFilenames = RsFindFilesRecursive dirPath #("*.*")
local fileTimes = for filename in dirFilenames collect (getFileModDate filename)
getHashValue fileTimes 1
)