Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_WorldFilesHelper.c
Go to the documentation of this file.
1#ifdef WORKBENCH
2class SCR_WorldFilesHelper
3{
4 // protected static const string GENERIC_WORLD_ENTITY_CLASS = ((typename)GenericWorldEntity).ToString();
5 protected static const string GENERIC_WORLD_ENTITY_CLASS = "GenericWorldEntity";
6 protected static const string LAYERS_DIR = "%1_Layers"; // %1 being world name, without extension
7 protected static const string DEFAULT_LAYER = "default.layer";
8
9 protected static const ref array<string> COPY_SUB_DIRECTORIES = { ".Rivers", ".Shore", "SurfaceMasks", "Terrain", "%1", LAYERS_DIR };
10
11 protected static const ref array<string> COPY_DIR_FILES = { "%1.ent", "%1.smap", "%1.smd", "%1.topo", "%1_SMD.conf" };
12 protected static const ref array<bool> COPY_DIR_FILES_REGISTER = { 1, 1, 0, 1, 1 };
13
14 //------------------------------------------------------------------------------------------------
22 static string CreateWorld(string relativeWorldDirectory, string worldName, array<ResourceName> defaultLayerEntities = null, bool overwriteWorldFile = false, bool overwriteDefaultLayerFile = false)
23 {
24 if (SCR_StringHelper.IsEmptyOrWhiteSpace(relativeWorldDirectory))
25 {
26 Print("Empty world directory provided", LogLevel.WARNING);
27 return string.Empty;
28 }
29
30 if (SCR_StringHelper.IsEmptyOrWhiteSpace(worldName))
31 {
32 Print("Empty world name provided", LogLevel.WARNING);
33 return string.Empty;
34 }
35
36 string absoluteWorldDirectory;
37 if (!Workbench.GetAbsolutePath(relativeWorldDirectory, absoluteWorldDirectory, false))
38 {
39 Print("Wrong relative world directory provided: " + relativeWorldDirectory, LogLevel.WARNING);
40 return string.Empty;
41 }
42
43 string worldFilePath = FilePath.Concat(absoluteWorldDirectory, worldName + ".ent");
44 string layersDirectory = FilePath.Concat(absoluteWorldDirectory, worldName + "_Layers");
45 string defaultLayerFilePath = FilePath.Concat(layersDirectory, "default.layer");
46
47 if (!FileIO.FileExists(absoluteWorldDirectory))
48 FileIO.MakeDirectory(absoluteWorldDirectory);
49
50 // create world and layers directory
51 if (!FileIO.FileExists(layersDirectory))
52 {
53 if (!FileIO.MakeDirectory(layersDirectory))
54 {
55 Print("Cannot create " + layersDirectory, LogLevel.WARNING);
56 return string.Empty;
57 }
58 }
59
60 // create .ent file
61 if (overwriteWorldFile || !FileIO.FileExists(worldFilePath))
62 {
63 FileHandle fileHandle = FileIO.OpenFile(worldFilePath, FileMode.WRITE);
64 if (!fileHandle)
65 {
66 Print("Cannot write world file " + worldFilePath, LogLevel.WARNING);
67 return string.Empty;
68 }
69
70 fileHandle.WriteLine("Layer default {");
71 fileHandle.WriteLine(" Index 0");
72 fileHandle.WriteLine("}");
73 fileHandle.Close();
74 }
75 else
76 {
77 Print("File already exists, skipping " + worldFilePath, LogLevel.WARNING);
78 }
79
80 // create default.layer file
81 if (overwriteDefaultLayerFile || !FileIO.FileExists(defaultLayerFilePath))
82 {
83 FileHandle fileHandle = FileIO.OpenFile(defaultLayerFilePath, FileMode.WRITE);
84 if (!fileHandle)
85 {
86 Print("Cannot write default layer file " + defaultLayerFilePath, LogLevel.WARNING);
87 return string.Empty;
88 }
89
90 ResourceName foundWorldEntity;
91 if (defaultLayerEntities)
92 {
93 foreach (ResourceName resourceName : defaultLayerEntities)
94 {
95 if (SCR_BaseContainerTools.GetContainerClassName(resourceName) == GENERIC_WORLD_ENTITY_CLASS)
96 {
97 foundWorldEntity = resourceName;
98 break;
99 }
100 }
101 }
102
103 // done this way to write it first
104 if (foundWorldEntity.IsEmpty())
105 {
106 fileHandle.WriteLine(GENERIC_WORLD_ENTITY_CLASS + " world {");
107 fileHandle.WriteLine("}");
108 }
109 else
110 {
111 fileHandle.WriteLine(GENERIC_WORLD_ENTITY_CLASS + " world : \"" + foundWorldEntity + "\" {");
112 fileHandle.WriteLine("}");
113 }
114
115 if (defaultLayerEntities)
116 {
117 foreach (ResourceName resourceName : defaultLayerEntities)
118 {
119 if (resourceName == foundWorldEntity)
120 continue;
121
122 fileHandle.WriteLine(string.Format("%1 : \"%2\" {", SCR_BaseContainerTools.GetContainerClassName(resourceName), resourceName));
123 fileHandle.WriteLine("}");
124 }
125 }
126
127 fileHandle.Close();
128 }
129 else
130 {
131 Print("File already exists, skipping " + defaultLayerFilePath, LogLevel.WARNING);
132 }
133
134 return relativeWorldDirectory + "/" + worldName + ".ent";
135 }
136
137 //------------------------------------------------------------------------------------------------
142 static bool DuplicateWorld(string absoluteSourceFilePath, string absoluteDestinationFilePath)
143 {
144 PrintFormat("[SCR_WorldFilesHelper.DuplicateWorld] STARTED", level: LogLevel.NORMAL);
145 PrintFormat("Duplicating %1 to %2", absoluteSourceFilePath, absoluteDestinationFilePath, level: LogLevel.NORMAL);
146
147 ResourceManager resourceManager = Workbench.GetModule(ResourceManager);
148
149 if (SCR_StringHelper.IsEmptyOrWhiteSpace(absoluteSourceFilePath) || !absoluteSourceFilePath.EndsWith(".ent"))
150 {
151 Print("Provided source world file is empty", LogLevel.WARNING);
152 return false;
153 }
154
155 if (SCR_StringHelper.IsEmptyOrWhiteSpace(absoluteDestinationFilePath) || !absoluteDestinationFilePath.EndsWith(".ent"))
156 {
157 Print("Provided destination world file is empty", LogLevel.WARNING);
158 return false;
159 }
160
161 if (!FileIO.FileExists(absoluteSourceFilePath))
162 {
163 Print("Provided source world file does not exist", LogLevel.WARNING);
164 return false;
165 }
166
167 if (FileIO.FileExists(absoluteDestinationFilePath))
168 {
169 Print("Provided destination world file exists", LogLevel.WARNING);
170 return false;
171 }
172
173 string absoluteSourceDirPath = FilePath.StripFileName(absoluteSourceFilePath);
174 string absoluteDestinationDirPath = FilePath.StripFileName(absoluteDestinationFilePath);
175
176 if (!FileIO.FileExists(FilePath.Concat(absoluteSourceDirPath, "Terrain")))
177 {
178 Print("The 'Terrain' subdirectory does not exist in the source world's directory", LogLevel.WARNING);
179 return false;
180 }
181
182 string sourceWorldName = FilePath.StripExtension(FilePath.StripPath(absoluteSourceFilePath));
183 string destinationWorldName = FilePath.StripExtension(FilePath.StripPath(absoluteDestinationFilePath));
184
185 foreach (int fileIndex, string dirFile : COPY_DIR_FILES)
186 {
187 string sourceDirFile = FilePath.Concat(absoluteSourceDirPath, string.Format(dirFile, sourceWorldName));
188 if (!FileIO.FileExists(sourceDirFile))
189 {
190 Print(sourceDirFile + " not found, skipping", LogLevel.NORMAL);
191 continue;
192 }
193
194 string destinationDirFile = FilePath.Concat(absoluteDestinationDirPath, string.Format(dirFile, destinationWorldName));
195 // if (!FileIO.CopyFile(sourceDirFile, destinationDirFile))
196 if (!SCR_FileIOHelper.CopyFile(sourceDirFile, destinationDirFile))
197 {
198 PrintFormat("Cannot copy %1 to %2", sourceDirFile, destinationDirFile, level: LogLevel.ERROR);
199 continue;
200 }
201
202 PrintFormat("Copied %1 to %2", string.Format(dirFile, sourceWorldName), string.Format(dirFile, destinationWorldName), level: LogLevel.NORMAL);
203
204 if (COPY_DIR_FILES_REGISTER[fileIndex]) // do I register?
205 {
206 Print("Re-registering " + destinationDirFile, LogLevel.NORMAL);
207 resourceManager.RegisterResourceFile(destinationDirFile, false);
208 }
209 }
210
211 foreach (string subDirectory : COPY_SUB_DIRECTORIES)
212 {
213 string sourceSubDir = FilePath.Concat(absoluteSourceDirPath, string.Format(subDirectory, sourceWorldName));
214 if (!FileIO.FileExists(sourceSubDir))
215 {
216 Print(sourceSubDir + " not found, skipping", LogLevel.NORMAL);
217 continue;
218 }
219
220 string destinationSubDir = FilePath.Concat(absoluteDestinationDirPath, string.Format(subDirectory, destinationWorldName));
221 if (!SCR_FileIOHelper.CopyDirectory(sourceSubDir, destinationSubDir))
222 {
223 PrintFormat("Cannot copy %1 to %2" + subDirectory, sourceWorldName, LogLevel.ERROR);
224 continue;
225 }
226
227 PrintFormat("Copied %1 to %2", string.Format(subDirectory, sourceWorldName), string.Format(subDirectory, destinationWorldName), level: LogLevel.NORMAL);
228
229 ReRegisterMetaFiles(resourceManager, destinationSubDir);
230 }
231
232
233 PrintFormat("[SCR_WorldFilesHelper.DuplicateWorld] FINISHED", level: LogLevel.NORMAL);
234
235 return true;
236 }
237
238 //------------------------------------------------------------------------------------------------
239 protected static void ReRegisterMetaFiles(notnull ResourceManager resourceManager, string dir)
240 {
241 array<string> filesToRegister = {};
242 array<ref SCR_FileInfo> metaFiles = SCR_FileIOHelper.GetDirectoryContent(dir, "meta");
243 foreach (SCR_FileInfo fileInfo : metaFiles)
244 {
245 if ((fileInfo.m_eAttributes | FileAttribute.DIRECTORY) == FileAttribute.DIRECTORY)
246 continue;
247
248 Print("Deleting " + fileInfo.m_sFilePath, LogLevel.NORMAL);
249 if (!FileIO.DeleteFile(fileInfo.m_sFilePath))
250 {
251 Print("Cannot delete " + fileInfo.m_sFilePath, LogLevel.ERROR);
252 continue;
253 }
254
255 string fileFromMeta = FilePath.StripExtension(fileInfo.m_sFilePath);
256 if (FileIO.FileExists(fileFromMeta))
257 filesToRegister.Insert(fileFromMeta);
258 }
259
260 foreach (string fileToRegister : filesToRegister)
261 {
262 Print("Re-registering " + fileToRegister, LogLevel.NORMAL);
263 resourceManager.RegisterResourceFile(fileToRegister, false);
264 }
265 }
266
267 //------------------------------------------------------------------------------------------------
272 static bool ReplaceWorldEntity(string relativeWorldFilePath, ResourceName newWorldEntityPrefab)
273 {
274 if (!relativeWorldFilePath)
275 {
276 Print("Provided world file is empty", LogLevel.WARNING);
277 return false;
278 }
279
280 if (!newWorldEntityPrefab)
281 newWorldEntityPrefab = GENERIC_WORLD_ENTITY_CLASS;
282
283 string absoluteWorldFilePath;
284 if (!Workbench.GetAbsolutePath(relativeWorldFilePath, absoluteWorldFilePath, true))
285 {
286 Print("Provided world file does not exist: " + relativeWorldFilePath, LogLevel.WARNING);
287 return false;
288 }
289
290 string defaultLayerAbsFilePath = GetDefaultLayerAbsoluteFilePath(relativeWorldFilePath);
291 if (!defaultLayerAbsFilePath || !FileIO.FileExists(defaultLayerAbsFilePath))
292 {
293 Print("Cannot find default layer's location: \"" + defaultLayerAbsFilePath + "\"", LogLevel.WARNING);
294 return false;
295 }
296
297 Print("Reading " + defaultLayerAbsFilePath, LogLevel.NORMAL);
298 array<string> lines = SCR_FileIOHelper.ReadFileContent(defaultLayerAbsFilePath);
299
300 bool found;
301 for (int i, count = lines.Count(); i < count; i++)
302 {
303 if (lines[i].EndsWith(" {") && lines[i].StartsWith(GENERIC_WORLD_ENTITY_CLASS + " "))
304 {
305 lines[i] = GENERIC_WORLD_ENTITY_CLASS + " world : \"" + newWorldEntityPrefab + "\" {"; // }
306 found = true;
307 break;
308 }
309 }
310
311 if (!found)
312 {
313 PrintFormat("No %1 class can be found in %2", GENERIC_WORLD_ENTITY_CLASS, defaultLayerAbsFilePath, level: LogLevel.WARNING);
314 return false;
315 }
316
317 bool result = SCR_FileIOHelper.WriteFileContent(defaultLayerAbsFilePath, lines);
318 if (result)
319 Print("File written successfully: " + defaultLayerAbsFilePath, LogLevel.NORMAL);
320 else
321 Print("File cannot be written: " + defaultLayerAbsFilePath, LogLevel.WARNING);
322
323 return result;
324 }
325
326 //------------------------------------------------------------------------------------------------
330 protected static string GetDefaultLayerAbsoluteFilePath(string relativeWorldFilePath)
331 {
332 string defaultLayerAbsFilePath;
333 if (!Workbench.GetAbsolutePath(relativeWorldFilePath, defaultLayerAbsFilePath))
334 {
335 Print("Cannot get absolute path for " + relativeWorldFilePath, LogLevel.WARNING);
336 return string.Empty;
337 }
338
339 string layerAbsDir = FilePath.StripFileName(defaultLayerAbsFilePath);
340 if (!layerAbsDir.EndsWith("/"))
341 layerAbsDir += "/";
342
343 string worldName = FilePath.StripExtension(FilePath.StripPath(relativeWorldFilePath));
344
345 return layerAbsDir + string.Format(LAYERS_DIR, worldName) + "/" + DEFAULT_LAYER;
346 }
347}
348#endif // WORKBENCH
ResourceName resourceName
Definition SCR_AIGroup.c:66
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
Definition LogLevel.c:14
proto void PrintFormat(string fmt, void param1=NULL, void param2=NULL, void param3=NULL, void param4=NULL, void param5=NULL, void param6=NULL, void param7=NULL, void param8=NULL, void param9=NULL, LogLevel level=LogLevel.NORMAL)
FileMode
Mode for opening file. See FileSystem::Open.
Definition FileMode.c:14
FileAttribute
File attributes. See FileDescription.