ConfigMaster
This is a custom class, which is part of the [ConfigManager] for UT2003.
00001 //----------------------------------------------------------- 00002 // ConfigManager.ConfigMaster version 1.8 00003 // Allows for ServerActors & Mutators to add to PlayInfo 00004 // 00005 // The latest version of ConfigManager is always available at 00006 // http://www.organized-evolution.com/ConfigManager/ 00007 //----------------------------------------------------------- 00008 00009 class ConfigMaster extends Mutator DependsOn(AutoLoader) config(ConfigMaster); 00010 00011 // If 2184 or earlier, crash the server 00012 var int GameVersion; 00013 00014 // Contains previous values of modified IniEntries, unless there is already 00015 // a previous value for an IniEntry. When a managed loader is de-activated, 00016 // the original value of the IniEntry is restored. 00017 var config array<AutoLoader.IniEntry> OriginalValues; 00018 00019 // Holder for properties which aren't needed - used by loaders that get activated at the end of the match 00020 var array<Property> IrrelevantProperties; 00021 00022 struct SA 00023 { 00024 var class<Info> SAClass; 00025 var string SAName; 00026 var string SADescription; 00027 }; 00028 00029 struct AL 00030 { 00031 var class<AutoLoader> AutoLoaderClass; 00032 var string AutoLoaderDesc; 00033 }; 00034 00035 var array<SA> ManagedActors; // Info about Loaders' ActorClasses 00036 var array<AL> LoaderClasses; // All Loader Classes found 00037 var array<AutoLoader> Loaders; // Active Loaders 00038 var array<string> ActiveMutators; // Currently active mutator classes 00039 var bool bInitialized; // Initialization 00040 var bool bHangRestart; // Don't let server travel yet 00041 00042 var GameEngine GE; 00043 00044 const VERSION = 1.71; 00045 const LOGNAME = 'Config Manager'; 00046 var const bool DEBUG; 00047 var const bool DEBUGPROPS; 00048 00049 // Localization 00050 var localized string LoadSuccess; 00051 var localized string RequiredVersion; 00052 var localized string UpgradeOrDie; 00053 var localized string RemovalCancelled; 00054 00055 // Errors 00056 var localized string InvalidLoaderClass; 00057 var localized string InvalidPI; 00058 00059 event PreBeginPlay() 00060 { 00061 GameVersion = int(Level.EngineVersion); 00062 00063 log(" -"@LOGNAME@VERSION@LoadSuccess,LOGNAME); 00064 if (GameVersion < 2199) 00065 { 00066 log(RequiredVersion@LOGNAME$".",LOGNAME); 00067 log(UpgradeOrDie,LOGNAME); 00068 log("",'ConfigManager'); 00069 Assert(False); 00070 } 00071 00072 GetGameEngine(); 00073 } 00074 00075 event PostBeginPlay() 00076 { 00077 local int i; 00078 00079 if (DEBUG) 00080 { 00081 log(class@"Beginning initialization",'PostBeginPlay'); 00082 log("START OF GAME SERVERACTORS",'PostBeginPlay'); 00083 for (i = 0; i < GE.ServerActors.Length; i++) 00084 log("ServerActor["$i$"]:"$GE.ServerActors[i],'PostBeginPlay'); 00085 00086 log("START OF GAME SERVERPACKAGES",'PostBeginPlay'); 00087 for (i = 0; i < GE.ServerPackages.Length; i++) 00088 log("ServerPackages["$i$"]:"$GE.ServerPackages[i],'PostBeginPlay'); 00089 00090 log("",'PostBeginPlay'); 00091 } 00092 // Level.Game.AddMutator("ConfigManagerGUI.ConfigManagerGUIMaster"); 00093 00094 InitLoaders(); 00095 if (DEBUG) 00096 log(class@"finished loading all actors and loaders",'PostBeginPlay'); 00097 00098 Super.PostBeginPlay(); 00099 } 00100 00101 // Sends a list of currently active mutators to all loader classes 00102 // Loader classes may want to check if its mutator was loaded without using the loader 00103 // (added at command line, etc.) 00104 function GetGameEngine() 00105 { 00106 foreach AllObjects(class'Engine.GameEngine', GE) 00107 break; 00108 } 00109 00110 function AddMutator(Mutator M) 00111 { 00112 local int i; 00113 00114 for (i = 0; i < ActiveMutators.Length; i++) 00115 if (ActiveMutators[i] ~= string(M.Class)) 00116 break; 00117 00118 if (i == ActiveMutators.Length) 00119 ActiveMutators[ActiveMutators.Length] = string(M.Class); 00120 00121 if (DEBUG) 00122 for (i = 0; i < ActiveMutators.Length; i++) 00123 log("ActiveMutators["$i$"]:"@ActiveMutators[i],'AddMutator'); 00124 00125 Super.AddMutator(M); 00126 } 00127 00128 // Do not show ConfigMaster in server browser as active mutator 00129 function GetServerDetails( out GameInfo.ServerResponseLine ServerState ) 00130 { 00131 } 00132 00133 function InitLoaders() 00134 { 00135 FindAllLoaders(); 00136 CreateLoaders(); 00137 } 00138 00139 function FindAllLoaders() 00140 { 00141 local int i, j; 00142 local AL TempAL; 00143 local SA TempSA; 00144 00145 local class<AutoLoader> LoaderClass; 00146 local class<Info> ServerActorClass; 00147 local string LoaderClassName, LoaderClassDescription, 00148 ActorClass, ServerActorName, ServerActorDesc; 00149 00150 GetNextIntDesc("ConfigManager.AutoLoader",0,LoaderClassName,LoaderClassDescription); 00151 while (LoaderClassName != "") 00152 { 00153 // Hack to prevent Config Loader from being loaded 00154 if (LoaderClassName ~= "ConfigManagerLoader.SampleLoader") 00155 { 00156 GetNextIntDesc("ConfigManager.AutoLoader",++i,LoaderClassName,LoaderClassDescription); 00157 continue; 00158 } 00159 if (DEBUG) 00160 log("Found a new AutoLoader:"@LoaderClassName@LoaderClassDescription,'FindAllLoaders'); 00161 00162 LoaderClass = class<AutoLoader>(DynamicLoadObject(LoaderClassName,Class'Class')); 00163 if (LoaderClass != None) 00164 { 00165 if (ShouldAddLoaderClass(LoaderClass)) 00166 { 00167 TempAL.AutoLoaderClass = LoaderClass; 00168 TempAL.AutoLoaderDesc = LoaderClassDescription; 00169 LoaderClasses[LoaderClasses.Length] = TempAL; 00170 j = -1; 00171 while (LoaderClass.static.AddManagedActor(j++, ActorClass, ServerActorName, ServerActorDesc)) 00172 { 00173 if (ActorClass != "" && ServerActorName != "" && ServerActorDesc != "") 00174 { 00175 ServerActorClass = class<Info>(DynamicLoadObject(ActorClass,class'Class')); 00176 if (ServerActorClass != None) 00177 { 00178 TempSA.SAClass = ServerActorClass; 00179 TempSA.SAName = ServerActorName; 00180 TempSA.SADescription = ServerActorDesc; 00181 00182 ManagedActors[ManagedActors.Length] = TempSA; 00183 } 00184 } 00185 } 00186 } 00187 } 00188 else Warn(InvalidLoaderClass@LoaderClassName); 00189 00190 GetNextIntDesc("ConfigManager.AutoLoader",++i, LoaderClassName, LoaderClassDescription); 00191 } 00192 00193 return; 00194 } 00195 00196 function bool ShouldAddLoaderClass(class<AutoLoader> NewClass) 00197 { 00198 local int i; 00199 00200 if (DEBUG) 00201 log("Loader Class"@NewClass,'ShouldAddLoaderClass'); 00202 00203 // Don't add if it's already in the list 00204 for (i = 0;i < LoaderClasses.Length; i++) 00205 if (LoaderClasses[i].AutoLoaderClass == NewClass) 00206 return false; 00207 00208 return true; 00209 } 00210 00211 function CreateLoaders() 00212 { 00213 local int i; 00214 local AutoLoader Loader; 00215 00216 if (DEBUG) 00217 log("LoaderClasses"@LoaderClasses.Length,'CreateLoaders'); 00218 00219 for (i = 0;i<LoaderClasses.Length;i++) 00220 { 00221 if (ShouldAddLoader(LoaderClasses[i].AutoLoaderClass)) 00222 { 00223 Loader = AddLoader(LoaderClasses[i].AutoLoaderClass); 00224 if (Loader != None) 00225 Loaders[Loaders.Length] = Loader; 00226 } 00227 } 00228 } 00229 00230 function bool LoaderNotActive(class<AutoLoader> NewClass) 00231 { 00232 local int i; 00233 00234 for (i = 0; i < Loaders.Length; i++) 00235 if (Loaders[i].Class == NewClass) 00236 return false; 00237 00238 return true; 00239 } 00240 00241 function bool ShouldAddLoader(class<AutoLoader> NewClass) 00242 { 00243 local bool bShouldAdd; 00244 00245 bShouldAdd = LoaderNotActive(NewClass) && GE != None; 00246 00247 if (bShouldAdd) 00248 bShouldAdd = NewClass.static.CheckStrayActors(GE.GetPropertyText("ServerActors")) || NewClass.static.IsActive(); 00249 00250 bShouldAdd = bShouldAdd && NewClass.static.ValidateLoader(); 00251 00252 if (DEBUG) 00253 log(NewClass@"will be added:"$bShouldAdd,'ShouldAddLoader'); 00254 00255 return bShouldAdd; 00256 } 00257 00258 function AutoLoader AddLoader(class<AutoLoader> NewClass) 00259 { 00260 local AutoLoader Loader; 00261 if (NewClass == None) return None; 00262 00263 Loader = Spawn(NewClass,Self); 00264 if (Loader != None && GE != None) 00265 Loader.GE = GE; 00266 00267 if (DEBUG) 00268 log("Returning"@Loader,'AddLoader'); 00269 00270 return Loader; 00271 } 00272 00273 // Make sure to remain as Game.BaseMutator.NextMutator so we will know about every mutator that is added. 00274 event Tick(float DeltaTime) 00275 { 00276 local int i; 00277 00278 if (bInitialized && Level != None && Level.NextURL != "") 00279 { 00280 if (bHangRestart) 00281 Level.NextSwitchCountdown = 4.0; 00282 00283 else if (Loaders.Length > 0) 00284 { 00285 bHangRestart = True; 00286 SetTimer(0.2,False); 00287 } 00288 } 00289 00290 // Do not replace BaseMutator, or DMMutator will show up in server browser as an active mutator 00291 if (Level != None && Level.Game != None && Level.Game.BaseMutator != None) 00292 { 00293 if (Level.Game.BaseMutator.NextMutator != None) 00294 { 00295 if (Level.Game.BaseMutator.NextMutator != Self) 00296 { 00297 // Some other ConfigManager as BaseMutator.NextMutator, but it isn't me???? 00298 // Maybe added ConfigManager as a serveractor? 00299 // Disable or server will crash 00300 if (!bInitialized && Level.Game.BaseMutator.NextMutator.Class == Class) 00301 { 00302 Destroy(); 00303 return; 00304 } 00305 00306 // We have been replaced by another mutator wanting 00307 // to be the first mutator. 00308 if (Level.Game.BaseMutator.NextMutator.NextMutator == Self) 00309 { 00310 if (NextMutator != None) 00311 Level.Game.BaseMutator.NextMutator.NextMutator = NextMutator; 00312 else Level.Game.BaseMutator.NextMutator.NextMutator = None; 00313 } 00314 00315 NextMutator = Level.Game.BaseMutator.NextMutator; 00316 Level.Game.BaseMutator.NextMutator = Self; 00317 } 00318 } 00319 00320 else Level.Game.BaseMutator.NextMutator = Self; 00321 } 00322 00323 if (!bInitialized) 00324 { 00325 for (i = 0; i < LoaderClasses.Length; i++) 00326 { 00327 if (LoaderNotActive(LoaderClasses[i].AutoLoaderClass) && LoaderClasses[i].AutoLoaderClass.static.CheckCurrentMutators(GetURLOption("Mutator"))) 00328 { 00329 if (DEBUG) 00330 log("Adding previously non-active loader"@LoaderClasses[i].AutoLoaderClass,'Tick'); 00331 Loaders[Loaders.Length] = AddLoader(LoaderClasses[i].AutoLoaderClass); 00332 } 00333 } 00334 00335 bInitialized = True; 00336 } 00337 } 00338 00339 event Timer() 00340 { 00341 Super.Timer(); 00342 ApplyLoaderSettings(); 00343 } 00344 00345 function array<Property> LoadProperties() 00346 { 00347 local array<Property> AllProperties; 00348 local array<class> RelevantActors; 00349 local array<string> RelevantPropNames; 00350 local class RelevantClass; 00351 local Property P; 00352 local int i, j, k; 00353 00354 // Build a array of properties which are relevant to the currently loaded loaders 00355 // so that the amount of time it will take each loader to update their settings will 00356 // be dramatically reduced - 00357 // Typical number of Property objects in the game: 200,000 00358 // Typical number of properties relevant to current loaders: 50 00359 00360 00361 // Start by first getting a list of actors/objects which will be relevant 00362 00363 // All ManagedActors are relevant (Loader's ActorClass) 00364 for (i = 0; i < ManagedActors.Length; i++) 00365 { 00366 for (j = 0; j < RelevantActors.Length; j++) 00367 if (RelevantActors[j] == ManagedActors[i].SAClass) 00368 break; 00369 00370 if (j < RelevantActors.Length) 00371 continue; 00372 00373 RelevantActors[RelevantActors.Length] = ManagedActors[i].SAClass; 00374 } 00375 00376 if (DEBUG) 00377 log("Loaders"@LoaderClasses.Length,'LoadProperties'); 00378 00379 for (i = 0; i < LoaderClasses.Length; i++) 00380 { 00381 // If ActorClass was already added to list, skip it 00382 for (j = 0; j < RelevantActors.Length; j++) 00383 if (string(RelevantActors[j]) ~= LoaderClasses[i].AutoLoaderClass.default.ActorClass) 00384 break; 00385 00386 if (j == RelevantActors.Length) 00387 { 00388 if (LoaderClasses[i].AutoLoaderClass.default.ActorClass != "") 00389 RelevantClass = class(DynamicLoadObject(LoaderClasses[i].AutoLoaderClass.default.ActorClass,class'Class')); 00390 00391 if (RelevantClass != None) 00392 RelevantActors[RelevantActors.Length] = RelevantClass; 00393 } 00394 00395 // Begin building a list of property names to mark as relevant 00396 // We'll match these names to the Property.Name variable later when we iterate AllObjects for class'Property' 00397 for (j = 0; j < LoaderClasses[i].AutoLoaderClass.default.RequiredIniEntries.Length; j++) 00398 { 00399 00400 for (k = 0; k < RelevantPropNames.Length; k++) 00401 { 00402 if (RelevantPropNames[k] == LoaderClasses[i].AutoLoaderClass.default.RequiredIniEntries[j].PropName) 00403 break; 00404 } 00405 00406 if ( k == RelevantPropNames.Length ) 00407 { 00408 RelevantPropNames[RelevantPropNames.Length] = LoaderClasses[i].AutoLoaderClass.default.RequiredIniEntries[j].PropName; 00409 if (DEBUGPROPS) 00410 log("Added new Relevant Property Name:"$RelevantPropNames[k],'LoadProperties'); 00411 } 00412 00413 RelevantClass = class(DynamicLoadObject(LoaderClasses[i].AutoLoaderClass.default.RequiredIniEntries[j].ClassFrom,Class'class',True)); 00414 if (RelevantClass == None) continue; 00415 00416 // Find out if this entry's associated class is already in the relevant actors list 00417 // If not, add it 00418 for (k = 0; k < RelevantActors.Length; k++) 00419 { 00420 if (DEBUGPROPS) 00421 log("Compare"@LoaderClasses[i].AutoLoaderClass.default.RequiredIniEntries[j].ClassFrom@"to Relevant Actor"@k$":"@RelevantActors[k],'LoadProperties'); 00422 00423 if (RelevantActors[k] == RelevantClass) 00424 break; 00425 } 00426 if (DEBUGPROPS) 00427 log("Breaking on"@k$", Total Relevant Actors:"@RelevantActors.Length,'LoadProperties'); 00428 00429 if (k < RelevantActors.Length) 00430 continue; 00431 00432 RelevantActors[RelevantActors.Length] = RelevantClass; 00433 if (DEBUGPROPS) 00434 log("Added new relevant actor:"$LoaderClasses[i].AutoLoaderClass.default.RequiredIniEntries[j].ClassFrom,'LoadProperties'); 00435 } 00436 } 00437 00438 // Finished building relevant actors and relevant names 00439 // Iterate AllObjects, looking for Property objects 00440 foreach AllObjects(class'Property', P) 00441 { 00442 RelevantClass = None; 00443 // Some property types should be skipped 00444 if ( ValidProp(P) ) 00445 { 00446 if (Class(P.Outer) != None) RelevantClass = Class(P.Outer); 00447 if (RelevantClass != None) 00448 { 00449 for (i = 0; i < RelevantActors.Length; i++) 00450 { 00451 // The Outer variable for properties is the class that the property is contained in 00452 // If this property's Outer is an object that is relevant, add it to the list 00453 if (RelevantClass == RelevantActors[i]) 00454 { 00455 for (j = 0; j < RelevantPropNames.Length; j++) 00456 if (RelevantPropNames[j] == string(P.Name)) 00457 { 00458 if (DEBUGPROPS) 00459 log("Adding Initial Relevant Property:"$P.Outer$"."$P.Name,'LoadProperties'); 00460 AllProperties[AllProperties.Length] = P; 00461 break; 00462 } 00463 00464 if (j < RelevantPropNames.Length) 00465 break; 00466 } 00467 } 00468 } 00469 00470 // OK, this property's Outer wasn't relevant 00471 // Check the property against the relevant name list 00472 if (i == RelevantActors.Length) 00473 { 00474 for (i = 0; i < RelevantPropNames.Length; i++) 00475 { 00476 // If we find a match, then we should check the relevant objects list again, 00477 // in case the relevant object is a superclass of the property's Outer 00478 if (RelevantPropNames[i] == string(P.Name)) 00479 { 00480 if (DEBUGPROPS) 00481 log("Compare Property:"@i@RelevantPropNames[i]@"to"@string(P.Name),'LoadProperties'); 00482 00483 for (j = 0; j < RelevantActors.Length; j ++) 00484 { 00485 if (RelevantClass == None) continue; 00486 00487 if (DEBUGPROPS) 00488 log("Relevant Actor Check:"@j@RelevantActors[j]@"is child of"@class(P.Outer)@":"$ClassIsChildOf(RelevantActors[j],Class(P.Outer)),'LoadProperties'); 00489 00490 if (ClassIsChildOf(RelevantActors[j], RelevantClass)) 00491 { 00492 if (DEBUGPROPS) 00493 log("Adding Additional Relevant Property:"$P.Outer$"."$P.Name,'LoadProperties'); 00494 00495 AllProperties[AllProperties.Length] = P; 00496 break; 00497 } 00498 } 00499 00500 if (j < RelevantActors.Length) 00501 break; 00502 } 00503 } 00504 } 00505 } 00506 } 00507 00508 return AllProperties; 00509 } 00510 00511 // Update Properties array with newly loaded loaders 00512 // No longer used 00513 function CheckRelevantProperties(AutoLoader L, out array<Property> Props) 00514 { 00515 local int i, j; 00516 local array<class> Classes, Outers; 00517 00518 local class TempClass; 00519 local Property P; 00520 00521 if (DEBUGPROPS) log("Checking relevant properties for new loader"@L,'CheckRelevantProperties'); 00522 00523 for (i = 0; i < Props.Length; i++) 00524 { 00525 TempClass = Class(Props[i].Outer); 00526 if (TempClass == None) continue; 00527 00528 for (j = 0; j < Outers.Length; j++) 00529 if (TempClass == Outers[j]) 00530 break; 00531 00532 if (j < Outers.Length) continue; 00533 00534 Outers[Outers.Length] = TempClass; 00535 } 00536 00537 if (L.bIncludeServerActor && L.ActorClass != "") 00538 { 00539 if (DEBUGPROPS) log("Checking for existence of"@L.ActorClass@"properties",'CheckRelevantProperties'); 00540 00541 TempClass = class(DynamicLoadObject(L.ActorClass,class'Class',True)); 00542 if (TempClass != None) 00543 { 00544 for (i = 0; i < Outers.Length; i++) 00545 if (TempClass == Outers[i]) 00546 break; 00547 00548 if (i == Outers.Length) 00549 Classes[Classes.Length] = TempClass; 00550 00551 else if (DEBUGPROPS) 00552 log(TempClass@"has already been added to the properties array.",'CheckRelevantProperties'); 00553 } 00554 } 00555 00556 for (i = 0; i < L.RequiredIniEntries.Length; i++) 00557 { 00558 if (DEBUGPROPS) log("Checking for existence of relevant class"@L.RequiredIniEntries[i].ClassFrom,'CheckRelevantProperties'); 00559 00560 TempClass = class(DynamicLoadObject(L.RequiredIniEntries[i].ClassFrom,class'Class',True)); 00561 if (TempClass != None) 00562 { 00563 for (j = 0; j < Classes.Length; j++) 00564 if (Classes[j] == TempClass) break; 00565 00566 if (j < Classes.Length) continue; 00567 00568 for (j = 0; j < Outers.Length; j++) 00569 if (Outers[j] == TempClass) break; 00570 00571 if (j < Outers.Length) continue; 00572 00573 Classes[Classes.Length] = TempClass; 00574 } 00575 else if (DEBUGPROPS) 00576 log("Could not load RequiredIniEntry["$i$"].ClassFrom:"@L.RequiredIniEntries[i].ClassFrom,'CheckRelevantProperties'); 00577 } 00578 00579 if (DEBUGPROPS && Classes.Length == 0) 00580 log("All relevant classes from this loader already existed in properties array",'CheckRelevantProperties'); 00581 00582 for (i = 0; i < Classes.Length; i++) 00583 { 00584 if (DEBUGPROPS) 00585 { 00586 log(""); 00587 log("Adding properties from class"@Classes[i]@"to properties array.",'CheckRelevantProperties'); 00588 } 00589 00590 for (j = 0; j < IrrelevantProperties.Length; j++) 00591 { 00592 P = IrrelevantProperties[j]; 00593 TempClass = Class(P.Outer); 00594 00595 if (TempClass == None || TempClass != Classes[i]) continue; 00596 00597 if (DEBUGPROPS) log(" Adding property"@P.Name,'CheckRelevantProperties'); 00598 00599 Props[Props.Length] = P; 00600 IrrelevantProperties.Remove(j--, 1); 00601 } 00602 } 00603 } 00604 00605 // TODO: Add support for structs 00606 final function bool ValidProp(Property P) 00607 { 00608 return P.Class != class'ObjectProperty' && 00609 P.Class != class'DelegateProperty' && 00610 P.Class != class'PointerProperty' && 00611 P.Class != class'MapProperty' && 00612 P.Class != class'StructProperty'; 00613 } 00614 00615 // Fills PlayInfo for ServerActors 00616 final function CallManagedActorPlayInfo(PlayInfo PI) 00617 { 00618 local int i, j; 00619 00620 for (i = 0; i < LoaderClasses.Length; i++) 00621 { 00622 if (DEBUG) 00623 log("Checking for LoaderClass"@i@"in playinfo:"$loaderclasses[i].autoloaderclass,'ManagedActorFillPlayInfo'); 00624 00625 if (NotInPlayInfo(PI,LoaderClasses[i].AutoLoaderClass)) 00626 { 00627 if (DEBUG) 00628 log("Calling FillPlayInfo() for LoaderClass"@i$":"$loaderclasses[i].autoloaderclass,'ManagedActorFillPlayInfo'); 00629 00630 LoaderClasses[i].AutoLoaderClass.static.FillPlayInfo(PI); 00631 PI.PopClass(); 00632 } 00633 00634 for (j = 0; j < ManagedActors.Length; j++) 00635 { 00636 if (LoaderClasses[i].AutoLoaderClass.default.ActorClass != string(ManagedActors[j].SAClass)) 00637 continue; 00638 00639 if (DEBUG) 00640 log("Checking for ManagedActor"@j@"in playinfo:"$ManagedActors[j].SAClass,'ManagedActorFillPlayInfo'); 00641 00642 if (LoaderClasses[i].AutoLoaderClass.static.IsActive()) 00643 { 00644 ManagedActors[j].SAClass.static.FillPlayInfo(PI); 00645 PI.PopClass(); 00646 } 00647 } 00648 } 00649 } 00650 00651 // Only webadmin calls Mutator.MutatorFillPlayInfo()? 00652 function MutatorFillPlayInfo(PlayInfo PI) 00653 { 00654 if (DEBUG) 00655 log(""); 00656 00657 if (DEBUG) 00658 log("Checking URL Option:"$GetURLOption("Mutator"),'MutatorFillPlayInfo'); 00659 00660 if (NextMutator != None) 00661 NextMutator.MutatorFillPlayInfo(PI); 00662 00663 CallManagedActorPlayInfo(PI); 00664 } 00665 00666 // Allows Loaders to adjust game configuration parameters 00667 // Loaders provide info about which ini changes need to be made for the mod to work 00668 // This allows other programs (such as Ladder) to only include the ini modifications 00669 // which are applicable for the loaded packages 00670 // 00671 // (Ex: ServerActors, ServerPackages, QueryHandlerClasses, Applications) 00672 final function ApplyLoaderSettings() 00673 { 00674 local int i, Index; 00675 local array<Property> CurrentProperties; 00676 local class Temp; 00677 00678 // Checking for any loaders that have been enabled since last check 00679 // Otherwise, must wait 2 server restarts to apply new loader settings 00680 // (One to load loader and apply changes, another for changes to take effect) 00681 FindAllLoaders(); 00682 CurrentProperties = LoadProperties(); 00683 for ( i = 0; i < LoaderClasses.Length; i++) 00684 { 00685 if (DEBUG) 00686 log("LoaderClass"@i$":"@LoaderClasses[i].AutoLoaderClass,'ApplyLoaderSettings'); 00687 00688 if (ShouldAddLoader(LoaderClasses[i].AutoLoaderClass) || (LoaderClasses[i].AutoLoaderClass.static.CheckCurrentMutators(Level.NextURL) && LoaderClasses[i].AutoLoaderClass.static.ValidateLoader())) 00689 Loaders[Loaders.Length] = AddLoader(LoaderClasses[i].AutoLoaderClass); 00690 00691 else if (LoaderNotActive(LoaderClasses[i].AutoLoaderClass)) 00692 AddLoader(LoaderClasses[i].AutoLoaderClass).AcceptRemoval(CurrentProperties); 00693 } 00694 00695 if (DEBUGPROPS) 00696 { 00697 log("*** Relevant Property Listing ***",'ApplyLoaderSettings'); 00698 for (i = 0; i < CurrentProperties.Length;i++) 00699 { 00700 if (Class(CurrentProperties[i].Outer) != None && Temp != Class(CurrentProperties[i].Outer)) 00701 { 00702 Temp = Class(CurrentProperties[i].Outer); 00703 log("",'ApplyLoaderSettings'); 00704 log("Relevant properties from class"@Temp@"-",'ApplyLoaderSettings'); 00705 } 00706 log(" "$currentproperties[i].name,'ApplyLoaderSettings'); 00707 } 00708 } 00709 00710 while (Index < Loaders.Length) 00711 { 00712 if (DEBUG) 00713 log("Loader"@Index$":"@Loaders[Index],'ApplyLoaderSettings'); 00714 00715 if (Loaders[Index].ApplyUpdate()) 00716 Loaders[Index].UpdateConfiguration(CurrentProperties); 00717 00718 else if (!Loaders[Index].AcceptRemoval(CurrentProperties)) 00719 log(RemovalCancelled@Loaders[Index],'ConfigManager'); 00720 00721 Index++; 00722 } 00723 00724 Disable('Tick'); 00725 if (DEBUG) 00726 { 00727 log("",'ApplyLoaderSettings'); 00728 log("END OF GAME SERVERACTORS",'ApplyLoaderSettings'); 00729 for (i = 0; i < GE.ServerActors.Length; i++) 00730 log("ServerActor["$i$"]:"$GE.ServerActors[i],'ApplyLoaderSettings'); 00731 00732 log("END OF GAME SERVERPACKAGES",'ApplyLoaderSettings'); 00733 for (i = 0; i < GE.ServerPackages.Length; i++) 00734 log("ServerPackages["$i$"]:"$GE.ServerPackages[i],'ApplyLoaderSettings'); 00735 00736 log("",'ApplyLoaderSettings'); 00737 } 00738 } 00739 00740 function bool NotInPlayInfo(PlayInfo PI, class<Info> NewInfo) 00741 { 00742 local int i; 00743 if (PI == None) 00744 { 00745 Warn(InvalidPI); 00746 return false; 00747 } 00748 00749 for (i=0;i<PI.InfoClasses.Length;i++) 00750 { 00751 if (PI.InfoClasses[i] == NewInfo) 00752 return false; 00753 } 00754 00755 return true; 00756 } 00757 00758 function array<string> GetAllManagedActors() 00759 { 00760 local int i; 00761 local array<string> Arr; 00762 00763 for (i = 0; i < LoaderClasses.Length; i++) 00764 Arr = AddS(Arr,LoaderClasses[i].AutoLoaderClass.static.GetManagedActors()); 00765 00766 return Arr; 00767 } 00768 00769 static final function float GetConfigMasterVersion() 00770 { 00771 return VERSION; 00772 } 00773 00774 // following function copied from wUtils (El_Muerte[TDS]) 00775 static final function array<string> AddS(array<string> A, array<string> B) 00776 { 00777 local int i; 00778 for (i = 0; i < B.length; i++) 00779 { 00780 A.length = A.length+1; 00781 A[A.length-1] = B[i]; 00782 } 00783 return A; 00784 }