public NativeTableItem( UFunction function ) { if( function.IsOperator() ) { Type = FunctionType.Operator; } else if( function.IsPost() ) { Type = FunctionType.PostOperator; } else if( function.IsPre() ) { Type = FunctionType.PreOperator; } else { Type = FunctionType.Function; } OperPrecedence = function.OperPrecedence; ByteToken = function.NativeToken; Name = Type == FunctionType.Function ? function.Name : function.FriendlyName; }
public NativeTableItem(UFunction function) { if (function.IsOperator()) { Type = FunctionType.Operator; } else if (function.IsPost()) { Type = FunctionType.PostOperator; } else if (function.IsPre()) { Type = FunctionType.PreOperator; } else { Type = FunctionType.Function; } OperPrecedence = function.OperPrecedence; ByteToken = function.NativeToken; Name = Type == FunctionType.Function ? function.Name : function.FriendlyName; }
public static void Run() { UDelegateFunction unrealFunction = UFunction.GetDelegateSignature <Test_SimpleMulticastDelegate>(); Tests.Assert(unrealFunction != null, "Test_SimpleMulticastDelegate"); Tests.AssertProperty <UUInt64Property>(unrealFunction, "param1", EPropertyFlags.Parm); Tests.AssertProperty <UStrProperty>(unrealFunction, "param2", EPropertyFlags.Parm); }
public async Task <UEFunctionFlags> GetFunctionFlags() { if (ObjFunction.Empty()) { ObjFunction = await Object.Cast <UFunction>(); } return((UEFunctionFlags)ObjFunction.FunctionFlags); }
public static void Run() { UDelegateFunction unrealFunction = UFunction.GetDelegateSignature <Test_SimpleDelegate>(); Tests.Assert(unrealFunction != null, "Test_SimpleDelegate"); Tests.AssertProperty <USoftClassProperty>(unrealFunction, UFunction.ReturnValuePropName, EPropertyFlags.Parm | EPropertyFlags.OutParm | EPropertyFlags.ReturnParm); Tests.AssertProperty <UIntProperty>(unrealFunction, "param1", EPropertyFlags.Parm); Tests.AssertProperty <UStrProperty>(unrealFunction, "param2", EPropertyFlags.Parm); Tests.AssertProperty <UDoubleProperty>(unrealFunction, "param3", EPropertyFlags.Parm | EPropertyFlags.OutParm | EPropertyFlags.ReferenceParm); Tests.AssertProperty <UStrProperty>(unrealFunction, "param4", EPropertyFlags.Parm | EPropertyFlags.OutParm); }
private static T TestResultFuncX <T>(Test_SimpleFuncs obj, int func, bool isNullResult) { string funcName = "ResultFunc" + func; if (isNullResult) { funcName += "_Null"; } UFunction func1 = obj.GetClass().FindFunctionByName(new FName(funcName)); Tests.AssertNotNull(func1, obj.GetClass(), funcName); return((T)UObject.DynamicInvoke(obj, funcName)); }
private static void TestResultFuncXEquals <T>(T value, Test_SimpleFuncs obj, int func, bool isNullResult) { UClass unrealClass = obj.GetClass(); string funcName = "ResultFunc" + func; if (isNullResult) { funcName += "_Null"; } UFunction func1 = unrealClass.FindFunctionByName(new FName(funcName)); Tests.AssertNotNull(func1, unrealClass, funcName); Tests.AssertEqual((T)UObject.DynamicInvoke(obj, funcName), value, unrealClass, funcName); }
public void InfiniteGaussKronrodTest() { for (int i = -10; i < 10; i++) { Func <double, double> pdf = (x) => Normal.Derivative(x - i); Func <double, double> E = (x) => x *pdf(x); UFunction UE = (x) => x *pdf(x); double expected = Quadpack.Integrate(UE, Double.NegativeInfinity, Double.PositiveInfinity); double actual = InfiniteAdaptiveGaussKronrod.Integrate(E, Double.NegativeInfinity, Double.PositiveInfinity); Assert.AreEqual(expected, actual, 1e-3); Assert.AreEqual(i, actual, 1e-3); } }
public void InfiniteGaussKronrodTest() { NormalDistribution norm; for (int i = -10; i < 10; i++) { norm = new NormalDistribution(i, 1); Func <double, double> E = (x) => x *norm.ProbabilityDensityFunction(x); UFunction UE = (x) => x *norm.ProbabilityDensityFunction(x); double expected = Quadpack.Integrate(UE, Double.NegativeInfinity, Double.PositiveInfinity); double actual = InfiniteAdaptiveGaussKronrod.Integrate(E, Double.NegativeInfinity, Double.PositiveInfinity); Assert.AreEqual(expected, actual, 1e-3); Assert.AreEqual(norm.Mean, actual, 1e-3); } }
public static bool RunPlotManagerUpdate(GameTarget target) { Log.Information($@"Updating PlotManager for game: {target.TargetPath}"); var supercedances = M3Directories.GetFileSupercedances(target, new[] { @".pmu" }); Dictionary <string, string> funcMap = new(); List <string> combinedNames = new List <string>(); if (supercedances.TryGetValue(@"PlotManagerUpdate.pmu", out var supercedanes)) { supercedanes.Reverse(); // list goes from highest to lowest. We want to build in lowest to highest StringBuilder sb = null; string currentFuncNum = null; var metaMaps = M3Directories.GetMetaMappedInstalledDLC(target, false); foreach (var pmuDLCName in supercedanes) { var uiName = metaMaps[pmuDLCName]?.ModName ?? ThirdPartyServices.GetThirdPartyModInfo(pmuDLCName, target.Game)?.modname ?? pmuDLCName; combinedNames.Add(uiName); var text = File.ReadAllLines(Path.Combine(M3Directories.GetDLCPath(target), pmuDLCName, target.Game.CookedDirName(), @"PlotManagerUpdate.pmu")); foreach (var line in text) { if (line.StartsWith(@"public function bool F")) { if (sb != null) { funcMap[currentFuncNum] = sb.ToString(); Log.Information($@"PlotSync: Adding function {currentFuncNum} from {pmuDLCName}"); currentFuncNum = null; } sb = new StringBuilder(); sb.AppendLine(line); // Method name currentFuncNum = line.Substring(22); currentFuncNum = currentFuncNum.Substring(0, currentFuncNum.IndexOf('(')); if (int.TryParse(currentFuncNum, out var num)) { if (num <= 0) { Log.Error($@"Skipping plot manager update: Conditional {num} is not a valid number for use. Values must be greater than 0 and less than 2 billion."); Analytics.TrackEvent(@"Bad plot manager function", new Dictionary <string, string>() { { @"FunctionName", $@"F{currentFuncNum}" }, { @"DLCName", pmuDLCName } }); sb = null; return(false); } else if (num.ToString().Length != currentFuncNum.Length) { Log.Error($@"Skipping plot manager update: Conditional {currentFuncNum} is not a valid number for use. Values must not contain leading zeros"); Analytics.TrackEvent(@"Bad plot manager function", new Dictionary <string, string>() { { @"FunctionName", $@"F{currentFuncNum}" }, { @"DLCName", pmuDLCName } }); sb = null; return(false); } } else { Log.Error($@"Skipping plot manager update: Conditional {currentFuncNum} is not a valid number for use. Values must be greater than 0 and less than 2 billion."); Analytics.TrackEvent(@"Bad plot manager function", new Dictionary <string, string>() { { @"FunctionName", $@"F{currentFuncNum}" }, { @"DLCName", pmuDLCName } }); sb = null; return(false); } } else { sb?.AppendLine(line); } } // Add final, if any was found if (sb != null) { funcMap[currentFuncNum] = sb.ToString(); Log.Information($@"PlotSync: Adding function {currentFuncNum} from {pmuDLCName}"); } } } var pmPath = GetPlotManagerPath(target); var vpm = Utilities.ExtractInternalFileToStream($@"MassEffectModManagerCore.modmanager.plotmanager.{target.Game}.PlotManager.{(target.Game == MEGame.ME1 ? @"u" : @"pcc")}"); // do not localize if (funcMap.Any()) { var plotManager = MEPackageHandler.OpenMEPackageFromStream(vpm, $@"PlotManager.{(target.Game == MEGame.ME1 ? @"u" : @"pcc")}"); // do not localize var clonableFunction = plotManager.Exports.FirstOrDefault(x => x.ClassName == @"Function"); // STEP 1: ADD ALL NEW FUNCTIONS BEFORE WE INITIALIZE THE FILELIB. foreach (var v in funcMap) { var pmKey = $@"BioAutoConditionals.F{v.Key}"; var exp = plotManager.FindExport(pmKey); if (exp == null) { // Adding a new conditional exp = EntryCloner.CloneEntry(clonableFunction); exp.ObjectName = new NameReference($@"F{v.Key}", 0); exp.FileRef.InvalidateLookupTable(); // We changed the name. // Reduces trash UFunction uf = ObjectBinary.From <UFunction>(exp); uf.Children = 0; uf.ScriptBytes = Array.Empty <byte>(); // No script data exp.WriteBinary(uf); Log.Information($@"Generated new blank conditional function export: {exp.UIndex} {exp.InstancedFullPath}", Settings.LogModInstallation); } } // Relink child chain UClass uc = ObjectBinary.From <UClass>(plotManager.FindExport(@"BioAutoConditionals")); uc.UpdateChildrenChain(); uc.UpdateLocalFunctions(); uc.Export.WriteBinary(uc); // STEP 2: UPDATE FUNCTIONS Stopwatch sw = Stopwatch.StartNew(); var fl = new FileLib(plotManager); bool initialized = fl.Initialize(new RelativePackageCache() { RootPath = M3Directories.GetBioGamePath(target) }, target.TargetPath, canUseBinaryCache: false); if (!initialized) { Log.Error(@"Error initializing FileLib for plot manager sync:"); foreach (var v in fl.InitializationLog.AllErrors) { Log.Error(v.Message); } throw new Exception(M3L.GetString(M3L.string_interp_fileLibInitFailedPlotManager, string.Join(Environment.NewLine, fl.InitializationLog.AllErrors.Select(x => x.Message)))); //force localize } sw.Stop(); Debug.WriteLine($@"Took {sw.ElapsedMilliseconds}ms to load filelib"); bool relinkChain = false; foreach (var v in funcMap) { var pmKey = $@"BioAutoConditionals.F{v.Key}"; Log.Information($@"Updating conditional entry: {pmKey}", Settings.LogModInstallation); var exp = plotManager.FindExport(pmKey); (_, MessageLog log) = UnrealScriptCompiler.CompileFunction(exp, v.Value, fl); if (log.AllErrors.Any()) { Log.Error($@"Error compiling function {exp.InstancedFullPath}:"); foreach (var l in log.AllErrors) { Log.Error(l.Message); } throw new Exception(M3L.GetString(M3L.string_interp_errorCompilingFunctionReason, exp, string.Join('\n', log.AllErrors.Select(x => x.Message)))); } } if (plotManager.IsModified) { plotManager.Save(pmPath, true); // Update local file DB var bgfe = new BasegameFileIdentificationService.BasegameCloudDBFile(pmPath.Substring(target.TargetPath.Length + 1), (int)new FileInfo(pmPath).Length, target.Game, M3L.GetString(M3L.string_interp_plotManagerSyncForX, string.Join(@", ", combinedNames)), Utilities.CalculateMD5(pmPath)); BasegameFileIdentificationService.AddLocalBasegameIdentificationEntries(new List <BasegameFileIdentificationService.BasegameCloudDBFile>(new[] { bgfe })); } } else { // Just write out vanilla. vpm.WriteToFile(pmPath); } return(true); }
private static void TestFuncX(Test_SimpleFuncs obj, UClass unrealClass, int func) { string funcName = "Func" + func; UFunction func1 = unrealClass.FindFunctionByName(new FName(funcName)); Tests.AssertNotNull(func1, unrealClass, funcName); Test_SimpleDelegate simpleDelegate = new Test_SimpleDelegate(); simpleDelegate.Bind(obj.BindMe); Test_SimpleMulticastDelegate multicastDelegate = new Test_SimpleMulticastDelegate(); multicastDelegate.Bind(obj.BindMeMulti1); multicastDelegate.Bind(obj.BindMeMulti2); // Use dynamic invoke so that all parameters go through a full marshal between C#/native code object[] parameters = { (sbyte)2, //sbyte (byte)3, //byte, (short)4, //short (ushort)5, //ushort (int)6, //int (uint)7, //uint (long)8, //long (ulong)9, //ulong (float)10.2f, //float (double)11.5, //double simpleDelegate, //delegate multicastDelegate, //multicast delegate obj, Test_SimpleEnum.Val3, new Test_FixedArrayInStruct() { Array1 = new sbyte[2] { 2, 5 } }, new TSubclassOf <UObject>(obj.GetClass()), new TLazyObject <UObject>(obj), TWeakObject <UObject> .Null, new TSoftClass <UObject>(obj.GetClass()), new TSoftObject <UObject>(obj), "Test123", new FName("321Test") }; long result = (long)UObject.DynamicInvoke(obj, funcName, parameters); Tests.AssertEqual(result, 13232, unrealClass, funcName + " result"); if (func > 1) { sbyte p1 = (sbyte)parameters[0]; byte p2 = (byte)parameters[1]; short p3 = (short)parameters[2]; ushort p4 = (ushort)parameters[3]; int p5 = (int)parameters[4]; uint p6 = (uint)parameters[5]; long p7 = (long)parameters[6]; ulong p8 = (ulong)parameters[7]; float p9 = (float)parameters[8]; double p10 = (double)parameters[9]; Test_SimpleDelegate p11 = (Test_SimpleDelegate)parameters[10]; Test_SimpleMulticastDelegate p12 = (Test_SimpleMulticastDelegate)parameters[11]; UObject p13 = (UObject)parameters[12]; Test_SimpleEnum p14 = (Test_SimpleEnum)parameters[13]; Test_FixedArrayInStruct p15 = (Test_FixedArrayInStruct)parameters[14]; TSubclassOf <UObject> p16 = (TSubclassOf <UObject>)parameters[15]; TLazyObject <UObject> p17 = (TLazyObject <UObject>)parameters[16]; TWeakObject <UObject> p18 = (TWeakObject <UObject>)parameters[17]; TSoftClass <UObject> p19 = (TSoftClass <UObject>)parameters[18]; TSoftObject <UObject> p20 = (TSoftObject <UObject>)parameters[19]; string p21 = (string)parameters[20]; FName p22 = (FName)parameters[21]; UClass actorClass = GetActorClass(); Tests.AssertEqual(p1, 3, unrealClass, funcName + ".p1"); Tests.AssertEqual(p2, 4, unrealClass, funcName + ".p2"); Tests.AssertEqual(p3, 5, unrealClass, funcName + ".p3"); Tests.AssertEqual(p4, 6, unrealClass, funcName + ".p4"); Tests.AssertEqual(p5, 7, unrealClass, funcName + ".p5"); Tests.AssertEqual(p6, 8u, unrealClass, funcName + ".p6"); Tests.AssertEqual(p7, 9, unrealClass, funcName + ".p7"); Tests.AssertEqual(p8, 10u, unrealClass, funcName + ".p8"); Tests.AssertEqual(p9, 11.2f, unrealClass, funcName + ".p9"); Tests.AssertEqual(p10, 12.5, unrealClass, funcName + ".p10"); Tests.Assert(!p11.IsBound, unrealClass, funcName + ".p11"); Tests.Assert(p12.IsBound, unrealClass, funcName + ".p12"); Tests.AssertEqual(p12.Count, 3, unrealClass, funcName + ".p12"); Tests.AssertEqual(p13, actorClass, unrealClass, funcName + ".p13"); Tests.AssertEqual(p14, Test_SimpleEnum.Val2, unrealClass, funcName + ".p14"); Tests.AssertEqual(p15.Array1[0], 2, unrealClass, funcName + ".p15"); Tests.AssertEqual(p15.Array1[1], 5, unrealClass, funcName + ".p15"); Tests.AssertEqual(p15.Array1[2], 100, unrealClass, funcName + ".p15"); Tests.AssertEqual(p16.Value, actorClass, unrealClass, funcName + ".p16"); Tests.AssertEqual(p17.Value, actorClass, unrealClass, funcName + ".p17"); Tests.AssertEqual(p18.Value, actorClass, unrealClass, funcName + ".p18"); Tests.AssertEqual(p19.Value, actorClass, unrealClass, funcName + ".p19"); Tests.AssertEqual(p20.Value, actorClass, unrealClass, funcName + ".p20"); Tests.AssertEqual(p21, "changed123", unrealClass, funcName + ".p21"); Tests.AssertEqual(p22, new FName("321changed"), unrealClass, funcName + ".p22"); } }