public static BlastLayer GenerateLayer(string note, string domain, long stepSize, long startAddress, long endAddress, ulong param1, ulong param2, int precision, int lifetime, int executeFrame, bool loop, int seed, BGStoreModes mode) { BlastLayer bl = new BlastLayer(); Random rand = new Random(seed); //We subtract 1 at the end as precision is 1,2,4, and we need to go 0,1,3 for (long address = startAddress; address < endAddress; address = address + stepSize + precision - 1) { BlastUnit bu = GenerateUnit(domain, address, param1, param2, stepSize, precision, lifetime, executeFrame, loop, mode, note, rand); if (bu != null) { bl.Layer.Add(bu); } } return(bl); }
public static void AddBlastUnit(BlastUnit bu) { lock (executeLock) { bool UseRealtime = (AllSpec.VanguardSpec[VSPEC.SUPPORTS_REALTIME] as bool? ?? true); if (!UseRealtime) { bu.Working.ExecuteFrameQueued = 0; bu.Working.LastFrame = 1; } else { bu.Working.ExecuteFrameQueued = bu.ExecuteFrame + currentFrame; //We subtract 1 here as we want lifetime to be exclusive. 1 means 1 apply, not applies 0 > applies 1 > done bu.Working.LastFrame = bu.Working.ExecuteFrameQueued + bu.Lifetime - 1; } var collection = GetBatchedLayer(bu); collection.Add(bu); } }
/* * Iterate over all the existing batches. * If a batch that matches all the params already exists, return that. otherwise, create and return a new batch. */ public static List <BlastUnit> GetBatchedLayer(BlastUnit bu) { List <BlastUnit> collection = null; foreach (List <BlastUnit> it in buListCollection) { if ((it[0].Working.ExecuteFrameQueued == bu.Working.ExecuteFrameQueued) && (it[0].Lifetime == bu.Lifetime) && (it[0].Loop == bu.Loop) && CheckLimitersMatch(it[0], bu)) { //We found one that matches so return that collection = it; break; } } //Checks that the limiters match bool CheckLimitersMatch(BlastUnit bu1, BlastUnit bu2) { //We only care if it's pre-execute because otherwise its limiter is independent from batching if (bu1.LimiterTime != LimiterTime.PREEXECUTE) { return(true); } if (bu1.LimiterListHash == bu2.LimiterListHash && bu1.LimiterTime == bu2.LimiterTime && bu1.InvertLimiter == bu2.InvertLimiter) { if (bu.Source == BlastUnitSource.STORE) { switch (bu1.StoreLimiterSource) { case StoreLimiterSource.ADDRESS: return(bu1.Address == bu2.Address && bu1.Domain == bu2.Domain ); case StoreLimiterSource.SOURCEADDRESS: return(bu1.SourceAddress == bu2.SourceAddress && bu1.SourceDomain == bu2.SourceDomain ); case StoreLimiterSource.BOTH: return(bu1.Address == bu2.Address && bu1.Domain == bu2.Domain && bu1.SourceAddress == bu2.SourceAddress && bu1.SourceDomain == bu2.SourceDomain ); } } else // It's VALUE so check the domain and address are the same { return(bu1.Address == bu2.Address && bu1.Domain == bu2.Domain ); } } return(false); } //No match so make a new list if (collection == null) { collection = new List <BlastUnit>(); buListCollection.Add(collection); } return(collection); }
//As the param is a long, it's little endian. We have to account for this whenever the param is going to be used as a value for a byte array //If it's an address, we can leave it as is. //If it's something such as SET or Replace X with Y, we always flip as we need to go to big endian //If it's something like a bitwise operation, we read the values from left to right when pulling them from memory. As such, we also always convert to big endian private static BlastUnit GenerateUnit(string domain, long address, long param1, long param2, int precision, int lifetime, int executeFrame, bool loop, BGValueModes mode, string note, Random rand) { try { MemoryInterface mi = null; if (domain.Contains("[V]")) { if (!MemoryDomains.VmdPool.ContainsKey(domain)) { return(null); } mi = MemoryDomains.VmdPool[domain]; } else { if (!MemoryDomains.MemoryInterfaces.ContainsKey(domain)) { return(null); } mi = MemoryDomains.MemoryInterfaces[domain]; } byte[] value = new byte[precision]; byte[] _temp = new byte[precision]; BigInteger tiltValue = 0; if (param1Bytes == null) { param1Bytes = CorruptCore_Extensions.GetByteArrayValue(precision, param1, true); } if (param2Bytes == null) { param2Bytes = CorruptCore_Extensions.GetByteArrayValue(precision, param2, true); } //Use >= as Size is 1 indexed whereas address is 0 indexed if (address + value.Length > mi.Size) { return(null); } switch (mode) { case BGValueModes.ADD: tiltValue = new BigInteger(param1Bytes); break; case BGValueModes.SUBTRACT: tiltValue = new BigInteger(param1Bytes) * -1; break; case BGValueModes.RANDOM: for (int i = 0; i < value.Length; i++) { value[i] = (byte)rand.Next(0, 255); } break; case BGValueModes.RANDOM_RANGE: long temp = rand.NextLong(param1, param2); value = CorruptCore_Extensions.GetByteArrayValue(precision, temp, true); break; case BGValueModes.REPLACE_X_WITH_Y: if (mi.PeekBytes(address, address + precision, mi.BigEndian) .SequenceEqual(param1Bytes)) { value = param2Bytes; } else { return(null); } break; case BGValueModes.SET: value = CorruptCore_Extensions.GetByteArrayValue(precision, param1, true); break; case BGValueModes.SHIFT_RIGHT: value = mi.PeekBytes(address, address + precision, mi.BigEndian); address += param1; if (address >= mi.Size) { return(null); } break; case BGValueModes.SHIFT_LEFT: value = mi.PeekBytes(address, address + precision, mi.BigEndian); address -= param1; if (address < 0) { return(null); } break; //Bitwise operations case BGValueModes.BITWISE_AND: _temp = param1Bytes; value = mi.PeekBytes(address, address + precision, mi.BigEndian); for (int i = 0; i < value.Length; i++) { value[i] = (byte)(value[i] & _temp[i]); } break; case BGValueModes.BITWISE_COMPLEMENT: _temp = param1Bytes; value = mi.PeekBytes(address, address + precision, mi.BigEndian); for (int i = 0; i < value.Length; i++) { value[i] = (byte)(value[i] & _temp[i]); } break; case BGValueModes.BITWISE_OR: _temp = param1Bytes; value = mi.PeekBytes(address, address + precision, mi.BigEndian); for (int i = 0; i < value.Length; i++) { value[i] = (byte)(value[i] | _temp[i]); } break; case BGValueModes.BITWISE_XOR: _temp = param1Bytes; value = mi.PeekBytes(address, address + precision, mi.BigEndian); for (int i = 0; i < value.Length; i++) { value[i] = (byte)(value[i] ^ _temp[i]); } break; case BGValueModes.BITWISE_SHIFT_LEFT: value = mi.PeekBytes(address, address + precision, mi.BigEndian); for (int i = 0; i < param1; i++) { CorruptCore_Extensions.ShiftLeft(value); } break; case BGValueModes.BITWISE_SHIFT_RIGHT: value = mi.PeekBytes(address, address + precision, mi.BigEndian); for (int i = 0; i < param1; i++) { CorruptCore_Extensions.ShiftRight(value); } break; case BGValueModes.BITWISE_ROTATE_LEFT: value = mi.PeekBytes(address, address + precision, mi.BigEndian); for (int i = 0; i < param1; i++) { CorruptCore_Extensions.RotateLeft(value); } break; case BGValueModes.BITWISE_ROTATE_RIGHT: value = mi.PeekBytes(address, address + precision, mi.BigEndian); for (int i = 0; i < param1; i++) { CorruptCore_Extensions.RotateRight(value); } break; default: throw new ArgumentOutOfRangeException(nameof(mode), mode, null); } var bu = new BlastUnit(value, domain, address, precision, mi.BigEndian, executeFrame, lifetime, note) { TiltValue = tiltValue, Loop = loop }; return(bu); } catch (Exception ex) { throw new NetCore.CustomException("Something went wrong in the RTC ValueGenerator Generator. " + ex.Message, ex.StackTrace); } }
private static BlastUnit GenerateUnit(string domain, long address, ulong param1, ulong param2, long stepSize, int precision, int lifetime, int executeFrame, bool loop, BGStoreModes mode, string note, Random rand) { try { MemoryInterface mi = null; if (domain.Contains("[V]")) { if (!MemoryDomains.VmdPool.ContainsKey(domain)) { return(null); } mi = MemoryDomains.VmdPool[domain]; } else { if (!MemoryDomains.MemoryInterfaces.ContainsKey(domain)) { return(null); } mi = MemoryDomains.MemoryInterfaces[domain]; } byte[] value = new byte[precision]; long destAddress = 0; StoreType storeType = StoreType.CONTINUOUS; if (address + value.Length > mi.Size) { return(null); } switch (mode) { case BGStoreModes.CHAINED: long temp = address + stepSize; if (temp <= mi.Size) { destAddress = temp; } else { destAddress = mi.Size - 1; } break; case BGStoreModes.SOURCE_RANDOM: destAddress = address; address = rand.Next(0, Convert.ToInt32(mi.Size - 1)); break; case BGStoreModes.SOURCE_SET: destAddress = address; address = (long)param1; break; case BGStoreModes.DEST_RANDOM: destAddress = rand.Next(0, Convert.ToInt32(mi.Size - 1)); break; case BGStoreModes.SELF: destAddress = address; break; default: throw new ArgumentOutOfRangeException(nameof(mode), mode, null); } if (destAddress >= mi.Size) { return(null); } var bu = new BlastUnit(storeType, StoreTime.PREEXECUTE, domain, destAddress, domain, address, precision, mi.BigEndian, executeFrame, lifetime, note) { Loop = loop }; return(bu); } catch (Exception ex) { throw new NetCore.CustomException("Something went wrong in the RTC StoreGenerator Generator. " + ex.Message, ex.StackTrace); } }