Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_PrefabValidatorPlugin.c
Go to the documentation of this file.
1#ifdef WORKBENCH
3 name: "Validate Prefabs",
4 wbModules: { "ResourceManager" },
5 category: SCR_PluginCategory.RESOURCEMANAGER_PREFABS,
6 awesomeFontCode: 0xF5BF)]
7class SCR_PrefabValidatorPlugin : WorkbenchPlugin
8{
9 protected static const ref array<string> UNIQUE_COMPONENTS = { "SCR_DestructionMultiPhaseComponent", "MeshObject", "RigidBody", "RplComponent", "Hierarchy" };
10 protected static const ref array<string> REPLICATED_COMPONENTS = { "RplComponent", "Hierarchy" };
11
12 //------------------------------------------------------------------------------------------------
13 protected void ValidatePrefabs(notnull array<ResourceName> prefabs)
14 {
15 ResourceManager resourceManager = Workbench.GetModule(ResourceManager);
16 WBProgressDialog progress = new WBProgressDialog("Validating Prefabs...", resourceManager);
17
18 int count = prefabs.Count();
19 int countInvalid;
20 string message;
21 Resource prefabResource;
22 IEntitySource prefabEntity;
23 float prevProgress;
24 float currProgress;
25 foreach (int i, ResourceName prefab : prefabs)
26 {
27 message = string.Format("@\"%1\"", prefab.GetPath());
28
29 prefabResource = Resource.Load(prefab);
30 if (prefabResource.IsValid())
31 {
32 prefabEntity = prefabResource.GetResource().ToEntitySource();
33 if (prefabEntity)
34 {
35 if (!ValidateEntitySource(prefabEntity, message))
36 countInvalid++;
37 }
38 }
39
40 currProgress = i / count;
41 if (currProgress - prevProgress >= 0.01) // min 1%
42 {
43 progress.SetProgress(currProgress); // expensive
44 prevProgress = currProgress;
45 }
46 }
47
48 Print(string.Format("%1 prefab(s) validated, %2 invalid ones found.", count, countInvalid), LogLevel.NORMAL);
49 }
50
51 //------------------------------------------------------------------------------------------------
52 protected bool ValidateEntitySource(IEntitySource entitySource, string message, int isReplicated = -1)
53 {
54 bool valid = true;
55
56 //--- Find duplicate components
57 array<int> componentCounts = {};
58 for (int i, count = UNIQUE_COMPONENTS.Count(); i < count; i++)
59 {
60 componentCounts.Insert(0);
61 }
62
63 bool isReplicatedCompatible;
64 IEntityComponentSource componentSource;
65 string componentSourceClassName;
66 for (int i, count = entitySource.GetComponentCount(); i < count; i++)
67 {
68 componentSource = entitySource.GetComponent(i);
69 componentSourceClassName = componentSource.GetClassName();
70
71 //--- Check if the prefab is replicated (runs once on root entity)
72 if (isReplicated == -1 && componentSourceClassName == "RplComponent")
73 {
74 bool enabled;
75 componentSource.Get("Enabled", enabled);
76 if (enabled)
77 isReplicated = 1;
78 }
79
80 //--- Check if child entity in replicated prefab has required components
81 if (isReplicated == 1 && REPLICATED_COMPONENTS.Contains(componentSourceClassName))
82 isReplicatedCompatible = true;
83
84 //--- Check if some unqiue components are not duplicated
85 int uniqueIndex = UNIQUE_COMPONENTS.Find(componentSourceClassName);
86 if (uniqueIndex >= 0)
87 {
88 bool enabled;
89 componentSource.Get("Enabled", enabled);
90 if (enabled)
91 componentCounts[uniqueIndex] = componentCounts[uniqueIndex] + 1;
92 }
93 }
94
95 //--- No RplComponent detect in root, mark as not replicated
96 if (isReplicated == -1)
97 isReplicated = 0;
98
99 //--- Show error when duplicates were found
100 foreach (int componentIndex, int componentCount : componentCounts)
101 {
102 if (componentCount > 1)
103 {
104 Print(string.Format("Duplicate component '%1' in prefab %2!", UNIQUE_COMPONENTS[componentIndex], message), LogLevel.ERROR);
105 valid = false;
106 }
107 }
108
109 //--- Show errir when the root is replicated and of of the children is missing required component
110 if (isReplicated && !isReplicatedCompatible)
111 {
112 Print(string.Format("Entity %1 is in replicated prefab, but is missing 'RplComponent' or 'Hierarchy'!", message), LogLevel.ERROR);
113 valid = false;
114 }
115
116 //--- Scan children
117 IEntitySource child;
118 for (int i, count = entitySource.GetNumChildren(); i < count; i++)
119 {
120 child = entitySource.GetChild(i);
121 valid &= ValidateEntitySource(child, message + string.Format("[%1]", i, child.GetClassName()), isReplicated);
122 }
123 return valid;
124 }
125
126 //------------------------------------------------------------------------------------------------
127 override void Run()
128 {
129 ResourceManager resourceManager = Workbench.GetModule(ResourceManager);
130
131 array<ResourceName> selection = {};
132 resourceManager.GetResourceBrowserSelection(selection.Insert, true);
133
134 ValidatePrefabs(selection);
135 }
136
137 //------------------------------------------------------------------------------------------------
138 // -wbmodule=ResourceManager -plugin=PrefabValidatorPlugin -run -validatePaths="$ArmaReforger:AI,$ArmaReforger:PrefabsEditable/Auto/Props"
139 override void RunCommandline()
140 {
141 ResourceManager resourceManager = Workbench.GetModule(ResourceManager);
142 string pathsCLI;
143 resourceManager.GetCmdLine("-validatePaths", pathsCLI);
144
145 array<string> paths = {};
146 pathsCLI.Split(",", paths, true);
147
148 array<ResourceName> prefabs = {};
150 filter.fileExtensions = { "et" };
151 foreach (string path : paths)
152 {
153 filter.rootPath = path;
154 ResourceDatabase.SearchResources(filter, prefabs.Insert);
155 }
156
157 ValidatePrefabs(prefabs);
158
159 Workbench.Exit(0);
160 }
161}
162#endif // WORKBENCH
string path
override void RunCommandline()
Definition FlowmapTool.c:60
GenerateFlowMaps WorkbenchPlugin WorkbenchPluginAttribute("Regenerate river flow-maps", "Generate and save/overwrite river flow-maps", "", "", {"WorldEditor"}, "", 0xf773)
Definition FlowmapTool.c:59
override void Run()
Object holding reference to resource. In destructor release the resource.
Definition Resource.c:25
Object used for holding filtering params for ResourceDatabase.SearchResources() method.
Definition System.c:9
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