global systempreferencefilename = "\\\Amiga\\3D\\Database\\system\\zs_sys_prefs.ini", --global systempreferencefilename = "c:\\zs_sys_prefs.ini", ProjectPath = (getINISetting systempreferencefilename "Filepath" "ProjectPath") error_list_file = "\\\Amiga\\3D\\Database\\system\\zonefiles_error_list.ini" -- pour faire fichier de report error_array ; if error_array == undefined do error_array = #() rollout dbase_cleaner_rollout "Database Zone Project Cleaner" ( ---------------------------------------------------------------- -- ui elements def ---------------------------------------------------------------- group "The Checker " ( Button CheckTheDatabase "Check the Database" width:110 -- CheckBox CheckOnly "report only please" checked:true -- Label textcheck "(Don't modify Database)" enabled:true -- Label textclean "(Do Clean the Database)" enabled:false progressbar progress_bar color:blue width:588 Label textcurrentproj "Current file : --" enabled:false align:#left ) group "The Files " ( label Count_Files "--" align:#left across:2 button reset_lists "Reset" width:50 listbox Files_listbox "Files with possible errors :" height:10 items:error_array ) group "Manual " ( button load_proj "Load" width:50 across:2 enabled:false button save_proj "Save" width:50 enabled:false button basic_clean "Clean Loaded" width:100 enabled:false ) group "Auto " ( button basic_clean_all "Basic Clean Listed Files " -- enabled:false button test_only_basic_clean_all "Tst Bazc Clean Listd Filz" -- enabled:false button collapse_nel_patch_all "Collapse all listed" progressbar progress_bar2 color:green height:8 width:588 ) group "The objects " ( listbox Objects_listbox "Objects in current File :" height:18 ) ---------------------------------------------------------------- -- Fonctions def ---------------------------------------------------------------- Fn backupfilezone nomdufichierzone = -- backup a file named day and time and oldfilename in a subdir named (the number of the week 0-51) ( local s=localtime , s1 , tabjourdesmois , nb_jours , i , semaineencours , file2backup , nouveaunomdefichier , sfinale="__" , directory4backup , s1= filterstring s "/ :" , tabjourdesmois=#("31","28","31","30","31","30","31","31","30","31","30","31") if s1[3]=="00" or s1[3]=="04" or s1[3]=="08" then tabjourdesmois[2]=((tabjourdesmois[2] as integer) +1) as string -- années bisextiles nb_jours=0 --determiner le numero de la semaine for i=1 to ((s1[2] as integer)-1) do -- ajouter les jours de chaque mois écoulé ( nb_jours=nb_jours + (tabjourdesmois[i] as integer) ) nb_jours=nb_jours + (s1[1] as integer) -- ajouter les jours écoulés du mois courant semaineencours = nb_jours/7 if (getfiles (projectpath + (semaineencours as string) + "\\\\" + nomdufichierzone + ".max")).count == 0 -- creation du repertoire de backup then (makedir (projectpath + (semaineencours as string) + "\\" )) else (print "le repertoire existe déjà, pas besoin de le créer") for i=1 to S1.count do ( sfinale=sfinale + "_" + s1[i]) --determiner le nouveau nom de fichier : date + heure copyfile (projectpath + nomdufichierzone + ".max") (projectpath + (semaineencours as string) + "\\\\" + nomdufichierzone + sfinale + ".max") -- bouger le fichier dans le repertoire de backup print ("fin du backup") ) Fn delete_unwanted_entitys = -- materials / camera / shapes.... ( -- undefined LM_DATA persistent array LM_DATA = undefined print "LM_Data array undefined" -- clean the material editor for i = 1 to meditMaterials.count do (meditMaterials[i]=standard()) -- reset material editor -- delete cameras delete cameras -- delete unwanted names obj_to_delete = #() for i in objects do ( if ((matchpattern (i.name) pattern:"* name")==true) AND ( matchpattern (i.name) pattern:((getfilenamefile maxfilename)+" name"))==false -- l'objet est un nom *ET* n'est pas celui du projet. then ( append obj_to_delete i ) ) print "deleting objects : " print obj_to_delete delete obj_to_delete ) ---------------------------------------------------------------- -- ui process def ---------------------------------------------------------------- on CheckOnly changed arg do ( textcheck.enabled = arg textclean.enabled = NOT arg ) fn lowercase instring = -- beginning of function definition ( local upper, lower, outstring -- declare variables as local upper="ABCDEFGHIJKLMNOPQRSTUVWXYZ" -- set variables to literals lower="abcdefghijklmnopqrstuvwxyz" outstring=instring for i=1 to outstring.count do ( j=findString upper outstring[i] if (j != undefined) do outstring[i]=lower[j] ) return outstring -- value of outstring will be returned as function result ) fn findID node = ( local -- Const alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ" NameTab = filterString node.name "_" if (NameTab != undefined) and (NameTab.count == 2) then ( Z_ID = -1 alpha_letter1 = NameTab[2][1] alpha_letter2 = NameTab[2][2] alpha_letter1_value = findstring alphabet alpha_letter1 alpha_letter2_value = findstring alphabet alpha_letter2 -- Decompose theh name in an array array[1]=numeric string value array[2]=alpha string value -- The index of the engine start at 0 but the script one at 1 so we sub 1 each time alpha_sub_id = (((alpha_letter1_value as integer - 1) * 26 + (alpha_letter2_value as integer)))-1 num_sub_id = (NameTab[1] as integer)-1 -- Array of 256 per 256 --------------------------- -- 0 1 2 3 ... 255 -- 256 257 258 259 ... 511 -- 512 513 514 515 ... 767 -- ... Z_ID = num_sub_id*256 + alpha_sub_id return Z_ID ) else return 0 ) fn idToCoord coord = ( zoneX = floor (coord.x/160) zoneY = floor (-coord.y/160) return zoneY*256 + zoneX; ) fn atTheGoodPosition node = ( -- Get the center center = node.center -- Check position if (findID node) == (idToCoord center) then return true else return false ) -------------------- on CheckTheDatabase pressed do ( --remettre à zero error_array = #() Files_listbox.items = error_array deletefile error_list_file progress_bar.value = 0 -- textcurrentproj.enabled = true project_files = getFiles ( projectpath + "*.max" ) counter = 0 Files_listbox.items = error_array for f in project_files do ( -- Error ? bFound = false bMultiZone = false bWrongName = false bWrongMaterial = false bLoaded = false bWrongPosition = false -- Name of the file fileName = getFilenameFile f -- Load the project try ( if (loadMaxFile f) == true then ( -- Zone loaded bLoaded = true -- Check there is only one zone with the name of the file for node in geometry do ( -- It is a NeL zone ? if (classof node) == RklPatch then ( -- Already a zone ? if bFound == true then bMultiZone = true -- A zone has been found bFound = true -- The same name ? if (lowercase fileName) != (lowercase node.name) then ( bWrongName = true ) -- The position if (atTheGoodPosition node) == false then bWrongPosition = true ) -- The material.. if (classof node.material) == MultiMaterial then ( -- Big material ? if (node.material.numsubs > 20) then ( bWrongMaterial = true ) ) ) ) ) catch ( ) -- Set error bError = (bWrongPosition == true) or (bWrongMaterial == true) or (bWrongName == true) or (bMultiZone == true) or (bFound == false) or (bLoaded == false) -- Set error message errorMessage = fileName if bLoaded == false then ( errorMessage += ", can't load it" ) if bFound == false then ( errorMessage += ", can't found a NeL patch object" ) if bMultiZone == true then ( errorMessage += ", multiple NeL zone" ) if bWrongName == true then ( errorMessage += ", NeL zone has a wrong name" ) if bWrongMaterial == true then ( errorMessage += ", NeL zone has a big material" ) if bWrongPosition == true then ( errorMessage += ", NeL zone position is wrong" ) -- Append error ? if bError == true then ( setinisetting error_list_file "Zone error" fileName errorMessage append error_array errorMessage Count_Files.text = error_array.count as string Files_listbox.items = error_array Files_listbox.selection += 1 print (" ---> project : " + filenamefrompath f) ) progress_bar.value = 100.*counter/project_files.count counter += 1 ) if counter >0 then ( Files_listbox.selection = 1 basic_clean_all.enabled = true test_only_basic_clean_all.enabled = true ) ) on Files_listbox doubleClicked error_list_index do ( -- Load the project fileName = filterString Files_listbox.items[error_list_index] "," if (fileName != undefined) and (fileName.count != 0) then ( -- Make a file name fileName = ProjectPath+"\\"+fileName[1]+".max" loadMaxFile fileName ) ) on Files_listbox selected error_list_index do ( --load_proj.enabled = true --Objects_listbox.enabled = false -- juste pour montrer que ça bosse --Files_listbox.enabled = false -- juste pour montrer que ça bosse --Count_Files.enabled = false -- juste pour montrer que ça bosse --Current_proj = (ProjectPath + Files_listbox.selected ) --Objects_listbox.items = (getMAXFileObjectNames current_proj) --Count_Files.enabled = true -- juste pour montrer que ça bosse --Files_listbox.enabled = true -- juste pour montrer que ça bosse --Objects_listbox.enabled = true -- juste pour montrer que ça bosse ) on reset_lists pressed do ( error_array = #() Files_listbox.items = error_array ) on load_proj pressed do ( loadMaxFile (ProjectPath + Files_listbox.selected ) messagebox ("Loaded project for zone : " + Files_listbox.selected + "\n \n Please Clean the project and save") max unhide all save_proj.enabled = true basic_clean.enabled = true ) on save_proj pressed do ( if (querybox ("Do You Really want to overwrite this ZONE ?\n" + MaxFileName )) == true and querybox "Really sure ?" == true then ( print ("saving zone : " + MaxFileName) save_proj.enabled = false backupfilezone (getfilenameFile MaxFileName) print (" zone backuped : " + MaxFileName) max file save print (" zone saved : " + MaxFileName) ) else ( print ("no save for : " + MaxFileName) ) ) on basic_clean pressed do ( delete_unwanted_entitys() -- basic_clean.enabled = false ) on basic_clean_all pressed do ( compteurdeligne = 0 for proj_file in Files_listbox.items do ( compteurdeligne += 1 progress_bar2.value = 100.*compteurdeligne/Files_listbox.items.count Files_listbox.selection = compteurdeligne print ("processing file : " + proj_file) loadMaxFile (ProjectPath + Files_listbox.selected ) delete_unwanted_entitys() backupfilezone (getfilenameFile MaxFileName) print (" zone backuped : " + MaxFileName) max file save print (" zone saved : " + MaxFileName) ) print ("nombre de projets traités : " + Files_listbox.items.count as string) if (querybox "Do you want to Build an updated list of possible errors ?" ) == true then ( print "faire mise à jour " ) ) ---------------------------------------- on collapse_nel_patch_all pressed do ( compteurdeligne = 0 for proj_file in Files_listbox.items do ( compteurdeligne += 1 progress_bar2.value = 100.*compteurdeligne/Files_listbox.items.count Files_listbox.selection = compteurdeligne print ("processing file : " + proj_file) loadMaxFile (ProjectPath + Files_listbox.selected ) patch_name="$'"+(substring maxfilename 1 (maxfilename.count-4))+"'" execute (" obj_to_check = " + patch_name) if obj_to_check.modifiers.count != 0 then ( collapsestack obj_to_check backupfilezone (getfilenameFile MaxFileName) print (" zone backuped : " + MaxFileName) max file save print (" zone saved : " + MaxFileName) ) else print ("nothing to do with " + proj_file) ) print ("nombre de projets traités : " + Files_listbox.items.count as string) if (querybox "Do you want to Build an updated list of possible errors ?" ) == true then ( print "faire mise à jour " ) ) ---------------------------------------- on test_only_basic_clean_all pressed do ( compteurdeligne = 0 for proj_file in Files_listbox.items do ( compteurdeligne += 1 progress_bar2.value = 100.*compteurdeligne/Files_listbox.items.count Files_listbox.selection = compteurdeligne print ("processing file : " + proj_file) loadMaxFile (ProjectPath + Files_listbox.selected ) delete_unwanted_entitys() print (" zone tested : " + MaxFileName) ) print ("nombre de projets traités : " + Files_listbox.items.count as string) ) on dbase_cleaner_rollout open do ( Count_Files.text = error_array.count as string clearlistener() ) ) --------------------------------------------------- -- Find and log doubling names fileType = #( "Shape", "Animations", "Skeleton", "Swt" ) keyWords = #( #("shape_source_directory"), #("anim_source_directory"), #("skel_source_directory"), #("swt_source_directory") ) checkMeshName = #( true, false, false, false ) checkProjectName = #( true, true, true, true ) objectDouble = #() objectDoubleProject = #() objectArray = #() NEL3D_APPDATA_DONOTEXPORT = 1423062565 -- do not export me : "undefined" = export me -- "0" = export me -- "1" = DONT expo rollout dbase_cleaner_double_rollout "Database Double Detector" ( -- A button to select the config file label ConfigFileLabel "Config files path:" align:#left edittext ConfigFile "" width:588 button SelectConfigFile "Browse for config path" width:588 dropdownlist TypeCheck "Type of project to check:" items:fileType selection:0 listbox DirectoryList "List of directory to check:" width:588 label ExcludeLabel "Excluded names:" align:#left edittext Exclude "" width:588 button Refresh "Refresh list" width:588 button Check "Check for double" width:588 listbox DoubleObject "List of project with same object name:" width:588 listbox DoubleProject "List of project with the same name:" width:588 -- On select the config file on SelectConfigFile pressed do ( -- Open a file browser result = getOpenFileName caption:"Select the build process config file" filename:"config.cfg" types:"Config Files (*.cfg)|*.cfg|All Files (*.*)|*.*||" -- Ok ? if (result != undefined) then ( ConfigFile.text = getFilenamePath result ) ) -- Get a list of options fn getOptions filename keyword array = ( -- Open a file stream stream = openFile filename -- Success ? if (stream != undefined) then ( -- Look for the keyword while (skipToString stream keyword) != undefined do ( -- Remove the '=' caracter skipToString stream "=" -- Get the option line = readLine stream -- Remove spaces while (line.count != 0) and (line[1] == " ") do ( line = substring line 2 (line.count-1) ) -- Remove spaces while (line.count != 0) and (line[line.count] == " ") do ( line = substring line 1 (line.count-1) ) -- Add the options append array line ) -- Close the file close stream -- Ok return true ) else ( return false ) ) fn convertString instring = ( index = findString instring "/" while index != undefined do ( instring[index] = "\\" index = findString instring "/" ) return instring ) -- Add the object fn addObjectToList name path = ( append objectDouble (name + " - " + (filenameFromPath (convertString path)) + " - " + (getFilenamePath (convertString path)) ) append objectDoubleProject path ) -- File type selected on TypeCheck selected selection do ( -- Config file path siteF = ConfigFile.text + "site.cfg" -- Get the database directory databaseDirectory = #() if (getOptions siteF "database_directory" databaseDirectory) == true then ( -- Ok ? if (databaseDirectory.count == 1) then ( -- Clean the directory list copyArray = #() DirectoryList.items = copyArray -- Look for the directories if selection != 0 then ( -- Directory file path directoryFile = ConfigFile.text + "directories.cfg" -- Array of keyword directoriesArray = #() for keyword in keyWords[selection] do ( if (getOptions directoryFile keyword directoriesArray) == false then ( -- Error message Messagebox ("Can't read directory file " + directoryFile) return undefined ) ) -- Add the directory for directory in directoriesArray do append copyArray (databaseDirectory[1] + "/" + directory) -- Set the array DirectoryList.items = copyArray ) ) else ( -- Error message Messagebox ("Syntax error in config file " + configF) ) ) else ( -- Error message Messagebox ("Can't read config file " + configF) ) ) fn lowercase instring = -- beginning of function definition ( local upper, lower, outstring -- declare variables as local upper="ABCDEFGHIJKLMNOPQRSTUVWXYZ" -- set variables to literals lower="abcdefghijklmnopqrstuvwxyz" outstring=instring for i=1 to outstring.count do ( j=findString upper outstring[i] if (j != undefined) do outstring[i]=lower[j] ) return outstring -- value of outstring will be returned as function result ) -- Refresh list fn refreshList = ( objectDouble = #() objectDoubleProject = #() -- Get the keyword list keywords = filterString Exclude.text " " -- Search for double object = 1 while object <= objectArray.count-1 do ( -- First names firstNames = filterString objectArray[object] ";" -- Filter first name same = false for keys in keywords do ( if (findString firstNames[1] keys) != undefined then ( same = true exit ) ) -- Not keyword if same == false then ( -- Second names secondNames = filterString objectArray[object+1] ";" -- Same name ? if firstNames[1] == secondNames[1] then ( -- Add the first addObjectToList firstNames[1] firstNames[2] -- Add the other while (firstNames[1] == secondNames[1]) do ( -- Add the second addObjectToList secondNames[1] secondNames[2] -- Next object = object + 1 -- Last one ? if (object == objectArray.count) then exit -- Get the new second secondNames = filterString objectArray[object+1] ";" ) ) ) object = object + 1 ) -- Copy the array DoubleObject.items = objectDouble ) -- Refresh on Refresh pressed do ( refreshList () ) -- Check on Check pressed do ( -- Check double name in objects if checkMeshName[TypeCheck.selection] == true then ( -- Object array objectArray = #() -- For each directory for folder in DirectoryList.items do ( -- Get the max files files = getFiles (folder+"/*.max") for file in files do ( -- Get the object in the max file objectsMax = getMAXFileObjectNames file -- For each object for object in objectsMax do ( -- Insert a reference append objectArray ( (lowercase (object as string) ) + ";" + file) ) ) ) -- Sort the array sort objectArray -- Refresh list refreshList () ) else DoubleObject.items = #() -- Check double name in prject name if checkProjectName[TypeCheck.selection] == true then ( -- Object array objectArrayProject = #() projectDouble = #() -- For each directory for folder in DirectoryList.items do ( -- Get the max files files = getFiles (folder+"/*.max") for file in files do ( append objectArrayProject ( (filenameFromPath (convertString (lowercase file))) + ";" + (lowercase file) ) ) ) -- Sort the array sort objectArrayProject -- Search for double object = 1 while object <= objectArrayProject.count-1 do ( -- First names firstNames = filterString objectArrayProject[object] ";" -- Second names secondNames = filterString objectArrayProject[object+1] ";" -- Same name ? if firstNames[1] == secondNames[1] then ( -- Add the first append projectDouble firstNames[2] -- Add the other while (firstNames[1] == secondNames[1]) do ( -- Add the second append projectDouble secondNames[2] -- Next object = object + 1 -- Last one ? if (object == objectArrayProject.count) then exit -- Get the new second secondNames = filterString objectArrayProject[object+1] ";" ) ) object = object + 1 ) -- Copy the array DoubleProject.items = projectDouble ) else DoubleProject.items = #() ) -- double click in the window on DoubleObject doubleClicked index do ( -- Check if (index>0) and (index<=objectDoubleProject.count) then loadMaxFile objectDoubleProject[index] ) -- double click in the window on DoubleProject doubleClicked index do ( -- Check if (index>0) and (index<=DoubleProject.items.count) then loadMaxFile DoubleProject.items[index] ) ) ---------------------------------------------------------------- -- macroscript begins ---------------------------------------------------------------- if dbase_cleaner_floater != undefined do ( closerolloutfloater dbase_cleaner_floater ) dbase_cleaner_Floater = newRolloutFloater "Database Cleaner" 640 815 800 200 addrollout dbase_cleaner_rollout dbase_cleaner_Floater rolledUp:true addrollout dbase_cleaner_double_rollout dbase_cleaner_Floater rolledUp:true