Mostly Harmless
Legacy:AutoLoader
From Unreal Wiki, The Unreal Engine Documentation Site
Here's an Legacy:AutoLoader/Example on how to use this class
-
//-----------------------------------------------------------
-
// ConfigManager.AutoLoader
-
//
-
// This class has two functions:
-
// 1. Perform all required ini changes needed for your mod. Will also UNDO
-
// any changes made to the ini if your mod is deactivated.
-
// Additional benefit of auto-installation of your mutator on a dedicated
-
// server (to enable set bEnableMyLoader=True in defaultproperties)
-
//
-
// 2. Pass FillPlayInfo() calls to mutators which are not part of the game's
-
// mutator list (such as mutators which only require ServerActors= lines in ini)
-
//
-
//-----------------------------------------------------------
-
class AutoLoader extends Info
-
abstract;
-
-
// Quick note about debugging - By setting DEBUG=True in defaultproperties of your
-
// AutoLoader subclass when compiling, you can receive large amounts of debug data.
-
// However, you will quickly encounter the 1024 byte limit if you use ucc.exe to
-
// start the testing server. By starting a server using the "ut2003 -server" command,
-
// you will bypass this limit, since ut2003.exe does not have these limitations.
-
-
var const bool DEBUG;
-
var const bool DEBUGPROPS;
-
-
var ConfigMaster Manager; // Pointer to ConfigMaster mutator
-
var string Interaction${1}< ${3} > // Not yet implemented
-
-
//=======================================
-
// Loading ServerActors
-
//=======================================
-
// Pointer to GameEngine
-
var GameEngine GE;
-
-
// This loader includes a server-side only mutator or server actor
-
// that will not be part of the mutator chain (will receive FillPlayInfo() calls)
-
var() bool bIncludeServerActor;
-
-
// Classname of the ServerActor this loader loads
-
// Same value as what would otherwise be your mod's
-
// ServerActors= line in the .ini file.
-
var() string Actor${1}< ${3} >
-
-
// Friendly Name of the Server Actor class
-
// Used by webadmin/adminmenu as the name of the server actor
-
var() localized string FriendlyName;
-
var() localized string ActorDescription;
-
-
// Lock this loader to a certain version (or higher) of your mod
-
var() string RequiredVersion; // Required version of actor
-
var() localized string VersionWarning; // Message to write to server log if version not enough
-
var() localized string DownloadMsg; // Message to write to log
-
-
//=======================================
-
// Automatic configuration changes
-
//=======================================
-
// A single ini change
-
struct IniEntry
-
{
-
var() string ClassFrom; // Class which contains the setting we want to change
-
var() string PropName; // Name of the variable we're trying to change
-
var() string PropValue; // Value to apply
-
};
-
-
// Array of ini settings required by this mod
-
var() array<IniEntry> RequiredIniEntries;
-
var array<Property> Properties;
-
-
-
//###################################################################
-
//###################################################################
-
//
-
// Public methods - should be subclassed to customize loader's response
-
-
// if return true, loader class will be spawned
-
static function bool IsActive()
-
{
-
return false;
-
}
-
-
// should be subclassed - set loader to active/will be included next match
-
static function bool EnableLoader(optional string SpecialActor)
-
{
-
return false;
-
}
-
-
// should be subclassed
-
static function bool DisableLoader(optional string SpecialActor)
-
{
-
return true;
-
}
-
-
// called on all loader classes - used to activate loader based on active mutators
-
static function bool CheckCurrentMutators(string URL)
-
{
-
return false;
-
}
-
-
// called on all loader classes which have bIncludeServerActor=True - used to activate loader based on manual ServerActor entry
-
static function bool CheckStrayActors(string ServerActors)
-
{
-
local int i;
-
local bool bAddMe;
-
-
if (default.bIncludeServerActor)
-
if (InStr(ServerActors,default.ActorClass) != -1)
-
bAddMe = EnableLoader();
-
-
for (i = 0; i < default.RequiredIniEntries.Length; i++)
-
if (!bAddMe && default.RequiredIniEntries[i].ClassFrom ~= "Engine.GameEngine" && default.RequiredIniEntries[i].PropName ~= "ServerActors")
-
if (InStr(ServerActors,default.RequiredIniEntries[i].PropValue) != -1)
-
bAddMe = EnableLoader();
-
-
if (default.DEBUG)
-
{
-
log(default.Class@"Received string value:"$ServerActors,'CheckStrayActors');
-
log(default.Class@"Returning"@bAddMe,'CheckStrayActors');
-
}
-
return bAddMe;
-
}
-
-
// Only managed actors can be added to Ladder profiles
-
// Normally, only the ActorClass of your loader (if bIncludeServerActor=True) would be need to be managed
-
static function array<string> GetManagedActors()
-
{
-
local int i;
-
local string A, B, C;
-
local array<string> ABC;
-
-
i = -1;
-
while (static.AddManagedActor(i++,A,B,C))
-
ABC[ABC.Length] = A$","$B$","$C;
-
-
return ABC;
-
}
-
-
// Managed actors will be passed FillPlayInfo() calls
-
static function bool AddManagedActor(int Idx, out string ActorClassName, out string ActorName, out string ActorDesc)
-
{
-
if (Idx == -1 && default.bIncludeServerActor)
-
{
-
ActorClassName = default.Actor${1}< ${3} >
-
ActorName = default.FriendlyName;
-
ActorDesc = default.ActorDescription;
-
return true;
-
}
-
-
return false;
-
}
-
-
// Optional hook for version filtering
-
static function bool MatchesVersion(float ActorVersion, optional bool bExact, optional string NewURL)
-
{
-
local float CurrentVersion;
-
local string LogText;
-
-
if (default.RequiredVersion == "")
-
return true;
-
-
CurrentVersion = float(default.RequiredVersion);
-
-
// Return false if loader version is higher than actor version
-
// Return false if loader version is lower than actor version and bExact=True
-
if ((ActorVersion < CurrentVersion) || (ActorVersion > CurrentVersion && bExact))
-
{
-
if (default.VersionWarning != "")
-
{
-
LogText = static.ReplaceTag(default.VersionWarning,"%CurVer%",CurrentVersion);
-
LogText = static.ReplaceTag(LogText,"%ReqVer%",ActorVersion);
-
log(LogText);
-
}
-
-
if (NewURL != "")
-
log(static.ReplaceTag(default.DownloadMsg,"%URL%",NewURL));
-
-
return false;
-
}
-
-
return true;
-
}
-
-
// To prevent your loader from causing a server crash, add your checks here
-
// return false to prevent your loader from being loaded
-
-
// You only need to override this function if bIncludeServerActor=False in your loader,
-
// or if you have RequiredIniChanges that reference additional custom packages
-
static function bool ValidateLoader()
-
{
-
local class<Info> MyActor;
-
-
if (default.bIncludeServerActor && default.ActorClass != "")
-
{
-
// Specify True for 3rd param in DynamicLoadObject to prevent log spam if MyActor isn't on server
-
MyActor = class<Info>(DynamicLoadObject(default.ActorClass,class'Class',True));
-
if (MyActor == None)
-
return false;
-
}
-
-
return true;
-
}
-
-
// Hook for loader to cancel external removal request, or effect any specialized ini changes to make before removal
-
function bool AcceptRemoval(optional array<Property> Props)
-
{
-
if (Props.Length > 0)
-
Properties = Props;
-
-
RemoveMe();
-
return true;
-
}
-
-
// should be subclassed
-
// always use "return !bEnableMyLoader;"
-
// see LadderLoader.LadderLoader or TeamBalanceLoader.BalanceLoader for examples
-
function bool WantsToBeDisabled()
-
{
-
return false;
-
}
-
-
// called for each RequiredIniEntry
-
// return true to apply the RequiredIniEntry.PropValue
-
function bool ObjectNeedsUpdate(Object O, string PropName, string PropValue)
-
{
-
local string Temp;
-
-
Temp = O.GetPropertyText(PropName);
-
if ( InStr(Caps(Temp),Caps(PropValue)) < 0 )
-
return true;
-
-
return false;
-
}
-
-
// notification of pending update - return false to skip update for loader
-
function bool ApplyUpdate()
-
{
-
if (DEBUG) log(class@"Returning"@IsActive(),'ApplyUpdate');
-
return IsActive();
-
}
-
-
// return -1 if want to simply add entry
-
// return index of array entry if want to overwrite
-
function int CheckArrayEntry(string PropName, array<string> PropArray)
-
{
-
return -1;
-
}
-
-
// To maintain consistency, always add to "Server Actors" page
-
// static function FillPlayInfo(PlayInfo PI)
-
// {
-
// Super.FillPlayInfo(PI);
-
// PI.AddSetting("ServerActors",....
-
// }
-
//
-
//###################################################################
-
//###################################################################
-
//
-
// Public Final Methods
-
// These are used to operate the internal mechanisms of the auto loader system.
-
//
-
//
-
-
// Called by ConfigMaster when Level.ServerTravel is called
-
-
// Removes loader if WantsToBeDisabled() returns True
-
// Applies value for RequiredIniProperties if ObjectNeedsUpdate returns true
-
final function UpdateConfiguration(array<Property> Props)
-
{
-
local Object O;
-
local Property P;
-
-
local string N,V;
-
local int i, j;
-
-
local array<string> Arr;
-
local string ArrS;
-
-
if (DEBUG)
-
log("Update configuration in"@class,'UpdateConfiguration');
-
-
ResetConfig();
-
Properties = Props;
-
-
if (WantsToBeDisabled())
-
{
-
RemoveMe();
-
return;
-
}
-
-
if (bIncludeServerActor && ActorClass != "")
-
{
-
O = GetObjectOfClass(class'Engine.GameEngine');
-
if (O != None)
-
{
-
if (ObjectNeedsUpdate(O, "ServerActors", ActorClass))
-
{
-
ArrS = O.GetPropertyText("ServerActors");
-
if (ArrS != "")
-
Arr = GenerateArray(ArrS);
-
-
j = -1;
-
if (Arr.Length > 0)
-
j = CheckArrayEntry("ServerActors", Arr);
-
-
if (j < 0)
-
O.SetPropertyText("ServerActors",AddDynArrayMember(O,"ServerActors",ActorClass));
-
-
else O.SetPropertyText("ServerActors",InsertArrayMember(O, "ServerActors", ActorClass, j));
-
O.SaveConfig();
-
}
-
}
-
}
-
-
for (i = 0;i<RequiredIniEntries.Length;i++)
-
{
-
O = GetObjectForEntry(RequiredIniEntries[i]);
-
if (O == None) continue;
-
-
if (!ObjectNeedsUpdate(O, RequiredIniEntries[i].PropName, RequiredIniEntries[i].PropValue)) continue;
-
-
N = RequiredIniEntries[i].PropName;
-
V = RequiredIniEntries[i].PropValue;
-
P = GetProperty(O, N);
-
if (DEBUG)
-
log(class@"got property"@p,'UpdateConfiguration');
-
-
if (P == None) continue;
-
-
j = -1;
-
-
if (PropIsArray(P))
-
{
-
ArrS = O.GetPropertyText(N);
-
if (ArrS != "")
-
Arr = GenerateArray(ArrS);
-
-
if (Arr.Length > 0)
-
j = CheckArrayEntry(N, Arr);
-
-
if (j < 0)
-
O.SetPropertyText(N,AddDynArrayMember(O,N,V));
-
-
else O.SetPropertyText(N,InsertArrayMember(O, N, V, j));
-
}
-
-
else
-
{
-
StoreDefaultValue(O, N);
-
O.SetPropertyText(N,V);
-
}
-
-
O.SaveConfig();
-
}
-
}
-
-
// Regarding OriginalValues
-
final function StoreDefaultValue(Object O, string PropName)
-
{
-
local int i, idx;
-
local IniEntry NewDefault;
-
local string CurrentValue, Quote;
-
local array<string> Ar;
-
-
if (DEBUG)
-
log(class@"storing default"@o@propname,'StoreDefaultValue');
-
-
for (i = 0; i < ConfigMaster(Owner).OriginalValues.Length; i++)
-
if (ConfigMaster(Owner).OriginalValues[i].ClassFrom == string(O.Class) && ConfigMaster(Owner).OriginalValues[i].PropName == PropName)
-
return;
-
-
NewDefault.ClassFrom = string(O.Class);
-
// Check if this property name is a single array member
-
i = -1; idx = -1;
-
i = InStr(PropName, "§");
-
if (i != -1)
-
{
-
idx = int(Left(PropName, i));
-
PropName = Mid(PropName, i + 1);
-
CurrentValue = O.GetPropertyText(PropName);
-
Ar = GenerateArray(CurrentValue);
-
CurrentValue = Ar[idx];
-
-
// Remove literal string wrapper
-
if (Left(CurrentValue,1) == "\"")
-
{
-
CurrentValue = Mid(CurrentValue,1,Len(CurrentValue) - 2);
-
Quote = "¶";
-
}
-
CurrentValue = idx $ "§" $ CurrentValue $ Quote;
-
}
-
-
else CurrentValue = O.GetPropertyText(PropName);
-
-
NewDefault.PropName = PropName;
-
NewDefault.PropValue = CurrentValue;
-
if (DEBUG)
-
log(class@"old value:"@NewDefault.PropValue,'StoreDefaultValue');
-
-
ConfigMaster(Owner).OriginalValues[ConfigMaster(Owner).OriginalValues.Length] = NewDefault;
-
ConfigMaster(Owner).SaveConfig();
-
}
-
-
final function bool RestoreOriginalValue(Object O, string PropName)
-
{
-
local int i, j, idx;
-
local string CurrentValue, StoredValue;
-
local array<string> Ar;
-
-
for (i = 0; i < ConfigMaster(Owner).OriginalValues.Length; i++)
-
{
-
if (ConfigMaster(Owner).OriginalValues[i].ClassFrom ~= string(O.Class) && ConfigMaster(Owner).OriginalValues[i].PropName ~= PropName)
-
{
-
StoredValue = ConfigMaster(Owner).OriginalValues[i].PropValue;
-
// First check if this was a single array member
-
j = InStr(StoredValue, "§");
-
if (j != -1)
-
{
-
idx = int(Left(StoredValue, j));
-
StoredValue = Mid(StoredValue, j + 1);
-
if (Right(StoredValue, 1) == "¶")
-
{
-
StoredValue = Left(StoredValue, Len(StoredValue) - 1);
-
StoredValue = "\"" $ StoredValue $ "\"";
-
}
-
CurrentValue = O.GetPropertyText(PropName);
-
Ar = GenerateArray(CurrentValue);
-
Ar[idx] = StoredValue;
-
StoredValue = "(" $ Join(Ar,",",True) $")";
-
}
-
-
if (DEBUG)
-
log(class@"Assigning"@StoredValue@"to property"@string(O.Class)$"."$PropName,'RestoreOriginalValue');
-
O.SetPropertyText(PropName, StoredValue);
-
O.SaveConfig();
-
break;
-
}
-
}
-
-
if (i < ConfigMaster(Owner).OriginalValues.Length)
-
{
-
ConfigMaster(Owner).OriginalValues.Remove(i, 1);
-
ConfigMaster(Owner).SaveConfig();
-
return true;
-
}
-
-
return false;
-
}
-
-
//###################################################################
-
//###################################################################
-
//
-
// Internal Methods
-
// These are used to control the internal operation of the loader itself.
-
// These methods may only be called by other methods within the loader.
-
//
-
-
protected final function RemoveMe()
-
{
-
local int i;
-
local Object O;
-
local Property P;
-
-
if (DEBUG)
-
log(class@"being removed.",'RemoveMe');
-
-
if (bIncludeServerActor && ActorClass != "")
-
{
-
O = GetObjectOfClass(class'Engine.GameEngine');
-
if (O != None)
-
RemoveArrayEntry(O, "ServerActors", ActorClass);
-
}
-
-
for (i = 0; i < RequiredIniEntries.Length; i++)
-
{
-
O = GetObjectForEntry(RequiredIniEntries[i]);
-
if (O == None) continue;
-
-
P = GetProperty(O,RequiredIniEntries[i].PropName);
-
if (P != None && PropIsArray(P))
-
RemoveArrayEntry(O,RequiredIniEntries[i].PropName,RequiredIniEntries[i].PropValue);
-
-
else RestoreOriginalValue(O, RequiredIniEntries[i].PropName);
-
}
-
-
DisableLoader();
-
}
-
-
protected final function string InsertArrayMember(Object Obj, string PropName, string NewValue, int Pos)
-
{
-
local string CurValue, Quote, Tmp;
-
local array<string> Members;
-
local bool bStatic;
-
-
if (Obj == None)
-
{
-
Warn("Object is None");
-
return "";
-
}
-
-
CurValue = Obj.GetPropertyText(PropName);
-
Members = GenerateArray(CurValue);
-
-
if (DEBUG)
-
{
-
log(class$":Inserting new member at position"@Pos@"to"@Obj$"."$PropName$":"@NewValue,'InsertArrayMember');
-
log(class$":Current Value:"$CurValue,'InsertArrayMember');
-
}
-
-
// Check for literal string
-
if (InStr(Caps(CurValue), Caps(NewValue)) < 0 && Members.Length > 0)
-
{
-
bStatic = Left(Members[pos], Len(PropName) + 1) ~= (PropName $ "[");
-
Tmp = StringIf(bStatic, Mid(Members[pos],InStr(Members[pos],"=") + 1), Members[0]);
-
Quote = StringIf(Left(Tmp,1) == "\"" && Left(NewValue,1) != "\"","\"","");
-
-
NewValue = StringIf(bStatic, PropName $ "=" $ Quote $ NewValue $ Quote, Quote $ NewValue $ Quote);
-
if (DEBUG)
-
log(InStr(Caps(CurValue),Caps(NewValue))@InStr(Caps(CurValue),Caps(NewValue))<0@Caps(CurValue)@"||"@Caps(NewValue),'AddDynArrayMember');
-
-
if (NewValue != "" && Pos > -1)
-
{
-
StoreDefaultValue(Obj, Pos$"§"$PropName);
-
Members[Pos] = NewValue;
-
}
-
-
CurValue = "(" $ Join(Members,",",True) $ ")";
-
}
-
-
if (DEBUG)
-
{
-
log(class@"Returning:"$CurValue,'InsertArrayMember');
-
log(class@"",'InsertArrayMember');
-
}
-
-
return CurValue;
-
}
-
-
// Currently, UT2003 does not support setting static arrays through the use of SetPropertyText
-
protected final function string AddStaticArrayMember(Object Obj, string PropName, string NewValue)
-
{
-
local int i;
-
local array<string> Members;
-
local string Quote, TempValue, CurValue;
-
-
if (Obj == None)
-
{
-
Warn("Object was None for property"@PropName);
-
return "";
-
}
-
-
CurValue = Obj.GetPropertyText(PropName);
-
Members = GenerateArray(CurValue);
-
-
if (InStr(Caps(CurValue), Caps(NewValue)) < 0)
-
{
-
if (Members.Length > 0)
-
{
-
TempValue = Mid(Members[0],InStr(Members[0],"=")+1);
-
-
// Check for literal string
-
Quote = StringIf(Left(TempValue,1) == "\"" && Left(NewValue,1) != "\"", "\"", "");
-
for (i = 0; i < Members.Length; i++)
-
{
-
if (Members[i] == "")
-
{
-
Members[i] = PropName $ "[" $ i $ "]=" $ Quote $ NewValue $ Quote;
-
break;
-
}
-
}
-
CurValue = "(" $ Join(Members,",") $")";
-
}
-
-
else CurValue = "(" $ PropName $ "[0]=" $ NewValue $ ")";
-
}
-
-
return CurValue;
-
}
-
-
protected final function string AddDynArrayMember(Object Obj, string PropName, string NewValue)
-
{
-
local string CurValue, Quote;
-
local array<string> Members;
-
-
if (Obj == None)
-
{
-
Warn("Object is None");
-
return "";
-
}
-
-
CurValue = Obj.GetPropertyText(PropName);
-
Members = GenerateArray(CurValue);
-
if (DEBUG)
-
{
-
log(class$":Adding new member to"@Obj$"."$PropName$":"@NewValue,'AddDynArrayMember');
-
log(class$":Current Value:"$CurValue,'AddDynArrayMember');
-
}
-
-
// Check for literal string
-
if (InStr(Caps(CurValue), Caps(NewValue)) < 0)
-
{
-
if (Members.Length > 0)
-
{
-
if (DEBUG)
-
log(InStr(Caps(CurValue),Caps(NewValue))@InStr(Caps(CurValue),Caps(NewValue))<0@Caps(CurValue)@"||"@Caps(NewValue),'AddDynArrayMember');
-
-
Quote = StringIf(Left(Members[0],1) == "\"" && Left(NewValue,1) != "\"", "\"", "");
-
Members[Members.Length] = Quote $ NewValue $ Quote;
-
CurValue = "(" $ Join(Members,",",True) $ ")";
-
}
-
else CurValue = "(" $ NewValue $ ")";
-
}
-
-
if (DEBUG)
-
{
-
log(class@"Returning:"$CurValue,'AddDynArrayMember');
-
log(class@"",'AddDynArrayMember');
-
}
-
-
return CurValue;
-
}
-
-
// UT2003 currently does not support setting the value of static arrays
-
protected final function RemoveArrayEntry(Object O, string PropName, string PropValue)
-
{
-
local int i, j;
-
local array<string> Members;
-
local string ArrayString, Quote, Tmp;
-
local bool bStatic;
-
-
if (O == None)
-
{
-
Warn("Object was none for property"@PropName);
-
return;
-
}
-
-
ArrayString = O.GetPropertyText(PropName);
-
if (ArrayString == "")
-
{
-
Warn("Property was not found:"@PropName);
-
return;
-
}
-
-
if (DEBUG)
-
{
-
log(class$": Removing array member"@string(O.Class)$"."$PropName$":"$ArrayString,'RemoveArrayEntry');
-
log(class$": Member to be removed:"$PropValue,'RemoveArrayEntry');
-
}
-
-
Members = GenerateArray(ArrayString);
-
bStatic = Left(Members[0], Len(PropName) + 1) ~= (PropName $ "[");
-
Tmp = StringIf(bStatic, Mid(Members[0],InStr(Members[0],"=") + 1), Members[0]);
-
Quote = StringIf(Left(Tmp,1) == "\"" && Left(PropValue,1) != "\"","\"","");
-
-
PropValue = StringIf(bStatic, PropName $ "=" $ Quote $ PropValue $ Quote, Quote $ PropValue $ Quote);
-
for (i = 0; i < Members.Length; i++)
-
{
-
if (DEBUG)
-
log(class@"Comparing"@i@PropValue@"to"@Members[i],'RemoveArrayEntry');
-
-
if (Members[i] ~= PropValue)
-
break;
-
}
-
-
if (i < Members.Length)
-
{
-
if (DEBUG) log(class@"Removing array member"@i$":"$Members[i],'RemoveArrayEntry');
-
-
// Check if we should restore a previous value
-
for (j = 0; j < ConfigMaster(Owner).OriginalValues.Length; j++)
-
{
-
if (DEBUG)
-
{
-
log(class@"Checking Backup Value"@j@"class:"$ConfigMaster(Owner).OriginalValues[j].ClassFrom@"against"@string(O.Class),'RemoveArrayEntry');
-
log(class@"Checking Backup Value"@j@"Property:"$ConfigMaster(Owner).OriginalValues[j].PropName@"against"@PropName,'RemoveArrayEntry');
-
}
-
-
if (ConfigMaster(Owner).OriginalValues[j].ClassFrom ~= string(O.Class) &&
-
ConfigMaster(Owner).OriginalValues[j].PropName ~= PropName )
-
{
-
RestoreOriginalValue(O, PropName);
-
break;
-
}
-
}
-
-
if (j < ConfigMaster(Owner).OriginalValues.Length)
-
return;
-
-
Members.Remove(i,1);
-
}
-
-
else return;
-
-
PropValue = "(" $ Join(Members,",") $ ")";
-
if (DEBUG)
-
log(class@"Assigning"@PropValue@"to property"@string(O.Class)$"."$PropName,'RemoveArrayEntry');
-
O.SetPropertyText(PropName,PropValue);
-
O.SaveConfig();
-
if (DEBUG)
-
log(class@"Returning"@O.GetPropertyText(PropName),'RemoveArrayEntry');
-
}
-
-
// Just a function to handle safe object creation
-
protected final function Object GetObjectForEntry(IniEntry ThisEntry)
-
{
-
local Object O;
-
local class<Object> O${1}< ${3} >
-
-
if (DEBUG)
-
log(class@"Getting"@ThisEntry.ClassFrom@ThisEntry.PropName@ThisEntry.PropValue,'GetObjectForEntry');
-
-
OClass = class<Object>(DynamicLoadObject(ThisEntry.ClassFrom,class'Class'));
-
if (OClass == None)
-
{
-
Warn("Could not load class"@ThisEntry.ClassFrom);
-
return None;
-
}
-
-
O = GetObjectOfClass(OClass);
-
if (O == None)
-
Warn("Unable to access object for class"@OClass);
-
-
return O;
-
}
-
-
protected final function Object GetObjectOfClass(class<Object> ObjClass)
-
{
-
local Object Obj;
-
local Actor A;
-
-
if (DEBUG)
-
log(class@"Finding"@ObjClass,'GetObjectOfClass');
-
-
// Check for GameEngine
-
if (ObjClass == class'GameEngine')
-
return GE;
-
-
// First try the easy way
-
foreach AllObjects(ObjClass,Obj)
-
return Obj;
-
-
// Object may not be loaded right now, so attempt to load it
-
// If actor, spawn it
-
if (ClassIsChildOf(ObjClass,class'Actor'))
-
{
-
A = Spawn(class<Actor>(ObjClass));
-
A.GoToState('');
-
return A;
-
}
-
-
// if object, new it
-
Obj = new(None) Obj${1}< ${3} >
-
-
// might be property
-
if (Obj == None)
-
Obj = new(Class) Obj${1}< ${3} >
-
-
// Don't know if this will even work ?
-
if (Obj == None)
-
Obj = New(ObjClass.default.Outer) Obj${1}< ${3} >
-
-
if (DEBUG)
-
{
-
log(class@"Could not create new object"@ObjClass,'GetObjectOfClass');
-
log(class@ObjClass@"outer is"@ObjClass.default.Outer,'GetObjectOfClass');
-
log(class@"",'GetObjectOfClass');
-
}
-
-
return Obj;
-
}
-
-
protected final function Property GetProperty(Object O, string PropName)
-
{
-
local int i;
-
local Class ClassOuter;
-
local bool classexact, classchild, propn, seen${1}< ${3} >
-
-
for (i=0;i<Properties.Length;i++)
-
{
-
seenclass = Class(Properties[i].Outer) == ClassOuter;
-
-
ClassOuter = Class(Properties[i].Outer);
-
if (DEBUGPROPS)
-
{
-
if (ClassOuter == None)
-
{
-
log(class@"Property Outer is not a class!",'GetProperty');
-
continue;
-
}
-
-
if (!seenclass)
-
{
-
log(class@"Compare Obj Class"@O.Class@"to"@Properties[i].Outer,'GetProperty');
-
if (O.Class==Properties[i].Outer)
-
classexact = true;
-
}
-
-
if (!classchild && ClassIsChildOf(O.Class,ClassOuter))
-
{
-
log(class@"Obj class"@O.Class@"is child of"@ClassOuter,'GetProperty');
-
classchild = true;
-
}
-
-
else if (!classchild && ClassIsChildOf(ClassOuter,O.Class))
-
{
-
log(class@"Obj class"@O.Class@"is parent of"@ClassOuter,'GetProperty');
-
classchild = true;
-
}
-
-
if (!propn && classexact)
-
{
-
log(class@"Compare Name"@PropName@"to"@Properties[i].Name,'GetProperty');
-
if (PropName == string(Properties[i].Name))
-
propn = true;
-
}
-
}
-
-
if ((ClassIsChildOf(O.Class,ClassOuter)||O.Class == Properties[i].Outer||ClassIsChildOf(ClassOuter,O.Class)) && string(Properties[i].Name) == PropName)
-
{
-
if (DEBUG)
-
{
-
log(class@"Returning Property"@Properties[i],'GetProperty');
-
log(class@"",'GetProperty');
-
}
-
-
return Properties[i];
-
}
-
}
-
-
return None;
-
}
-
-
protected final function bool PropIsArray(Property P)
-
{
-
if (DEBUG)
-
log(class@"Checking Property"@P.Outer$"."$P.Name$":"@P.Class,'PropIsArray');
-
return P.Class == class'ArrayProperty';
-
}
-
-
protected static final function array<string> GenerateArray(string ArrayString)
-
{
-
local array<string> Members;
-
local int i;
-
local string S;
-
-
if (ArrayString != "")
-
{
-
// Remove the array wrapper ( )
-
ArrayString = Mid(ArrayString,1,Len(ArrayString)-2);
-
-
// If string contains internal containers, then have to split differently
-
if (Left(ArrayString,1) == "(")
-
{
-
do {
-
do {
-
if (Left(ArrayString,1) == ")")
-
i--;
-
else if (Left(ArrayString,1) == "(")
-
i++;
-
Eat(S, ArrayString, 1);
-
} until (i == 0);
-
-
Members[Members.Length] = S;
-
S = "";
-
if (ArrayString != "" && Left(ArrayString,1) == ",")
-
ArrayString = Mid(ArrayString,1);
-
} until (ArrayString == "");
-
}
-
-
else Split2(ArrayString,",",Members);
-
}
-
-
return Members;
-
}
-
-
protected static final function bool NotInPlayInfo(PlayInfo PI, class<Info> NewInfo)
-
{
-
local int i;
-
if (PI == None)
-
{
-
Warn("Invalid PlayInfo Object!");
-
return false;
-
}
-
-
for (i=0;i<PI.InfoClasses.Length;i++)
-
{
-
if (PI.InfoClasses[i] == NewInfo)
-
return false;
-
}
-
-
return true;
-
}
-
-
-
//###################################################################
-
//###################################################################
-
//
-
// Utility Methods
-
// These are used perform various tedious operations.
-
//
-
// Moves Num elements from Source to Dest
-
static final function Eat(out string Dest, out string Source, int Num)
-
{
-
Dest = Dest $ Left(Source, Num);
-
Source = Mid(Source, Num);
-
}
-
-
static final function string StringIf(bool Condition, string IfTrue, string IfFalse)
-
{
-
if (Condition) return IfTrue;
-
return IfFalse;
-
}
-
-
// Based on AccessControlIni & Object.ReplaceText()
-
static final function string ReplaceTag(string from, string tag, coerce string with)
-
{
-
local int i;
-
local string t;
-
-
// InStr() is case-sensitive
-
i = InStr(Caps(from), Caps(tag));
-
while (i != -1)
-
{
-
t = t $ Left(from,i) $ with;
-
from = mid(from,i+len(tag));
-
i = InStr(Caps(from), Caps(tag));
-
}
-
-
t = t $ from;
-
return t;
-
}
-
-
// Following functions from wUtils103 by El_Muerte[TDS]
-
// Included by permission (copied to avoid package dependancy)
-
-
// Shifts an element off a string
-
// example (delim = ' '): 'this is a string' -> 'is a string'
-
// if quotechar = " : '"this is" a string' -> 'a string'
-
static final function string StrShift(out string line, string delim, optional string quotechar)
-
{
-
local int delimpos, quotepos;
-
local string result;
-
-
if ( quotechar != "" && Left(line, Len(quotechar)) == quotechar ) {
-
do {
-
quotepos = InstrFrom(line, quotechar, quotepos + 1);
-
} until (quotepos == -1 || quotepos + Len(quotechar) == Len(line)
-
|| Mid(line, quotepos + len(quotechar), len(delim)) == delim);
-
}
-
if ( quotepos != -1 ) {
-
delimpos = InstrFrom(line, delim, quotepos);
-
}
-
else {
-
delimpos = Instr(line, delim);
-
}
-
-
if (delimpos == -1)
-
{
-
result = line;
-
line = "";
-
}
-
else {
-
result = Left(line,delimpos);
-
line = Mid(line,delimpos+len(delim));
-
}
-
if ( quotechar != "" && Left(result, Len(quotechar)) == quotechar ) {
-
result = Mid(result, Len(quotechar), Len(result)-(Len(quotechar)*2));
-
}
-
return result;
-
}
-
-
// Join the elements of a string array to an array
-
static final function string Join(array< string > ar, optional string delim, optional bool bIgnoreEmpty)
-
{
-
local string result;
-
local int i;
-
for (i = 0; i < ar.length; i++)
-
{
-
if (bIgnoreEmpty && ar[i] == "") continue;
-
if (result != "") result = result$delim;
-
result = result$ar[i];
-
}
-
-
return result;
-
}
-
-
// Fixed split method
-
// no problems when it starts with a delim
-
// no problems with ending spaces
-
// delim can be a string
-
static final function int Split2(coerce string src, string delim, out array<string> parts, optional bool ignoreEmpty, optional string quotechar)
-
{
-
local string temp;
-
Parts.Remove(0, Parts.Length);
-
if (delim == "" || Src == "" ) return 0;
-
while (src != "")
-
{
-
temp = StrShift(src, delim, quotechar);
-
if (temp == "")
-
{
-
if (!ignoreEmpty)
-
{
-
parts.length = parts.length+1;
-
parts[parts.length-1] = temp;
-
}
-
}
-
else {
-
parts.length = parts.length+1;
-
parts[parts.length-1] = temp;
-
}
-
}
-
return parts.length;
-
}
-
-
// InStr starting from an offset
-
static final function int InStrFrom(coerce string StrText, coerce string StrPart, optional int OffsetStart)
-
{
-
local int OffsetPart;
-
-
OffsetPart = InStr(Mid(StrText, OffsetStart), StrPart);
-
if (OffsetPart >= 0)
-
OffsetPart += OffsetStart;
-
return OffsetPart;
-
}
Wormbo: Hmm, a little documentation instead of the source code wouldn't hurt. E.g. how can you use this to enable/disable a server actor?
El Muerte TDS: like this: ChatFilter AutoLoader, maybe write a [/example] based on it... first lunch