/// <summary>
 /// Validates this message against the given server support
 /// </summary>
 public override void Validate(ServerSupport serverSupport)
 {
     base.Validate( serverSupport );
     if ( serverSupport != null && serverSupport.MaxWatches <= 0 ) {
         throw new InvalidMessageException( NeboResources.ServerDoesNotSupportWatch );
     }
 }
Exemple #2
0
        public async void NewProfile()
        {
            if (Model.SelectedAutoSelect != null)
            {
                var profile = Model.SelectedAutoSelect;
                var newp    = new NewProfileViewModel()
                {
                    Model       = Model,
                    Title       = "自動選択プロファイル",
                    Operation   = "追加",
                    IsDuplicate = Name => Model.AutoSelectList.Any(
                        s => s.Model.Name.Equals(Name, StringComparison.OrdinalIgnoreCase)),
                    Name = profile.Model.Name + "のコピー"
                };

                await Messenger.RaiseAsync(new TransitionMessage(
                                               typeof(Views.NewProfileWindow), newp, TransitionMode.Modal, "FromProfile"));

                if (newp.Success)
                {
                    var newprofile = ServerSupport.DeepCopy(profile.Model);
                    newprofile.Name = newp.Name;
                    await Model.AddAutoSelect(newprofile);
                }
            }
        }
        public async void NewProfile()
        {
            if (Model.SelectedProfile != null)
            {
                var profile = Model.SelectedProfile;
                var newp    = new NewProfileViewModel()
                {
                    Model       = Model,
                    Title       = "プロファイル",
                    Operation   = "追加",
                    IsDuplicate = Name => Model.ProfileList.Any(
                        s => s.Data.Name.Equals(Name, StringComparison.OrdinalIgnoreCase)),
                    Name = profile.Data.Name + "のコピー"
                };

                await Messenger.RaiseAsync(new TransitionMessage(
                                               typeof(Views.NewProfileWindow), newp, TransitionMode.Modal, "FromProfile"));

                if (newp.Success)
                {
                    var newprofile   = ServerSupport.DeepCopy(profile.Data);
                    var invalidChars = System.IO.Path.GetInvalidFileNameChars();
                    newprofile.Name = new string(newp.Name.ToCharArray()
                                                 .Where(c => Array.IndexOf(invalidChars, c) == -1).ToArray());
                    await Model.AddProfile(newprofile);
                }
            }
        }
 public void Initialize()
 {
     if (Item.Outputs[0].DstPath == null)
     {
         ResetOutPath();
     }
     if (Item.Outputs[0].Profile == null)
     {
         // 設定なしなら「デフォルト」を使う
         SelectedProfile = Model.ProfileList.FirstOrDefault(s => s.Data.Name == "デフォルト");
     }
     else
     {
         bool isAuto      = false;
         var  profileName = ServerSupport.ParseProfileName(Item.Outputs[0].Profile, out isAuto);
         SelectedProfile = isAuto
             ? (object)Model.AutoSelectList.FirstOrDefault(s => s.Model.Name == profileName)
             : Model.ProfileList.FirstOrDefault(s => s.Data.Name == profileName);
     }
     OutPathHistory = Model.UIState.Model.OutputPathHistory.Select(
         path => new OutPathHistoryViewModel()
     {
         OutPathVM = this, Path = path
     }).ToList();
 }
 /// <summary>
 /// Validates this message against the given server support
 /// </summary>
 public override void Validate( ServerSupport serverSupport )
 {
     base.Validate( serverSupport );
     if ( serverSupport != null && !serverSupport.CallerId )
     {
         throw new InvalidMessageException( NeboResources.ServerDoesNotSupportAccept );
     }
 }
 /// <summary>
 ///   Validates this message against the given server support
 /// </summary>
 public override void Validate(ServerSupport serverSupport)
 {
     base.Validate(serverSupport);
     if (serverSupport != null && serverSupport.MaxMonitors == 0)
     {
         throw new InvalidMessageException(Resources.ServerDoesNotSupportMonitor);
     }
 }
Exemple #7
0
 /// <summary>
 ///   Validates this message against the given server support
 /// </summary>
 public override void Validate(ServerSupport serverSupport)
 {
     base.Validate(serverSupport);
     for (int i = 0; i < this.Channels.Count; i++)
     {
         this.Channels[i] = MessageUtil.EnsureValidChannelName(this.Channels[i], serverSupport);
     }
 }
        public void EnsureValidChannelName()
        {
            var defaultSupport = new ServerSupport();

            Assert.AreEqual("#foo", MessageUtil.EnsureValidChannelName("#foo", defaultSupport));
            Assert.AreEqual("#foo", MessageUtil.EnsureValidChannelName("foo", defaultSupport));
            Assert.AreEqual("#", MessageUtil.EnsureValidChannelName("#", defaultSupport));
            Assert.AreEqual("#irc", MessageUtil.EnsureValidChannelName("", defaultSupport));
        }
 /// <summary>
 /// Validates this message's properties according to the given <see cref="ServerSupport"/>.
 /// </summary>
 public override void Validate( ServerSupport serverSupport )
 {
     base.Validate( serverSupport );
     if ( serverSupport == null )
     {
         return;
     }
     this.Channel = MessageUtil.EnsureValidChannelName( this.Channel, serverSupport );
     if ( !serverSupport.Knock )
     {
         System.Diagnostics.Trace.WriteLine( "Knock Is Not Supported On This Server" );
     }
 }
        public byte[] GetMacAddress()
        {
            // リモートのクライアントを見つけて、
            // 接続に使っているNICのMACアドレスを取得する
            IPHostEntry iphostentry = Dns.GetHostEntry(Dns.GetHostName());

            foreach (var client in ClientList)
            {
                if (IsRemoteHost(iphostentry, client.RemoteIP.Address))
                {
                    return(ServerSupport.GetMacAddress(client.LocalIP.Address));
                }
            }
            return(null);
        }
Exemple #11
0
        private void DuplicateItem(QueueItem item, List <Task> waits)
        {
            var newItem = ServerSupport.DeepCopy(item);

            newItem.Id = nextItemId++;
            Queue.Add(newItem);

            // 状態はリセットしておく
            newItem.Reset();
            UpdateQueueItem(newItem, null);

            waits.Add(ClientQueueUpdate(new QueueUpdate()
            {
                Type = UpdateType.Add,
                Item = newItem
            }));
        }
Exemple #12
0
        static void Main(string[] args)
        {
            try
            {
                // ログパスを設定
                log4net.GlobalContext.Properties["Root"] = Directory.GetCurrentDirectory();
                log4net.Config.XmlConfigurator.Configure(new FileInfo(
                                                             Path.GetDirectoryName(typeof(ServerCLI).Assembly.Location) + "\\Log4net.Config.xml"));

                TaskSupport.SetSynchronizationContext();
                GUIOPtion option = new GUIOPtion(args);
                using (var lockFile = ServerSupport.GetLock())
                {
                    log4net.ILog LOG = log4net.LogManager.GetLogger("Server");
                    Util.LogHandlers.Add(text => LOG.Info(text));
                    using (var server = new EncodeServer(option.ServerPort, null, () =>
                    {
                        TaskSupport.Finish();
                    }))
                    {
                        var task = server.Init();

                        // この時点でtaskが完了していなくてもEnterMessageLoop()で続きが処理される

                        TaskSupport.EnterMessageLoop();

                        // この時点では"継続"を処理する人がいないので、
                        // task.Wait()はデッドロックするので呼べないことに注意
                        // あとはプログラムが終了するだけなのでWait()しても意味がない
                    }
                }
            }
            catch (MultipleInstanceException)
            {
                Console.WriteLine("多重起動を検知しました");
                return;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                return;
            }
        }
Exemple #13
0
 public void Initialize()
 {
     if (Item.Outputs[0].DstPath == null)
     {
         ResetOutPath();
     }
     if (Item.Outputs[0].Profile == null)
     {
         // 設定なしなら「デフォルト」を使う
         SelectedProfile = Model.ProfileList.FirstOrDefault(s => s.Data.Name == "デフォルト");
     }
     else
     {
         bool isAuto      = false;
         var  profileName = ServerSupport.ParseProfileName(Item.Outputs[0].Profile, out isAuto);
         SelectedProfile = isAuto
             ? (object)Model.AutoSelectList.FirstOrDefault(s => s.Model.Name == profileName)
             : Model.ProfileList.FirstOrDefault(s => s.Data.Name == profileName);
     }
 }
Exemple #14
0
        public WebServerService(string physicalPath, int port)
        {
            if (port < 0)
            {
                port = GetPort();
            }

            DirectoryInfo webDirectory = new DirectoryInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, physicalPath));
            physicalPath = webDirectory.FullName;
            string serverType = typeof (Server).Assembly.Location;
            DeployAssembly(physicalPath, serverType);
            string serverSideType = typeof (ServerSupport).Assembly.Location;
            DeployAssembly(physicalPath, serverSideType);

            server = new Server(port, "/", physicalPath, false);

            string appId = (server.VirtualPath + server.PhysicalPath).ToLowerInvariant().GetHashCode().ToString("x", CultureInfo.InvariantCulture);
            ApplicationManager appManager = (ApplicationManager) server.GetType().GetField("_appManager", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(server);
            _serverSupport = (ServerSupport) appManager.CreateObject(appId, typeof (ServerSupport), server.VirtualPath, server.PhysicalPath, true, true);

            server.Start();
        }
Exemple #15
0
        private async Task <bool> GetGlobalLock()
        {
            try
            {
                lockFile = ServerSupport.GetLock();
            }
            catch (MultipleInstanceException)
            {
                var message = new InformationMessage(
                    "多重起動を検知しました",
                    "AmatsukazeServer",
                    "Message");

                await Messenger.RaiseAsync(message);

                await RealCloseWindow();

                return(false);
            }

            return(true);
        }
Exemple #16
0
        public async void NewProfile()
        {
            if (Model.SelectedAutoSelect != null)
            {
                var profile = Model.SelectedAutoSelect;
                var newp    = new NewAutoSelectViewModel()
                {
                    Model = Model,
                    Name  = profile.Model.Name + "のコピー"
                };

                await Messenger.RaiseAsync(new TransitionMessage(
                                               typeof(Views.NewAutoSelectWindow), newp, TransitionMode.Modal, "FromProfile"));

                if (newp.Success)
                {
                    var newprofile = ServerSupport.DeepCopy(profile.Model);
                    newprofile.Name = newp.Name;
                    await Model.AddAutoSelect(newprofile);
                }
            }
        }
Exemple #17
0
        public async void StopServer()
        {
            if (ServerSupport.IsLocalIP(Model.ServerIP))
            {
                var message = new ConfirmationMessage(
                    "AmatsukazeServerを終了しますか?",
                    "AmatsukazeServer",
                    System.Windows.MessageBoxImage.Information,
                    System.Windows.MessageBoxButton.OKCancel,
                    "Confirm");

                await Messenger.RaiseAsync(message);

                if (message.Response == true)
                {
                    await Model.Server?.EndServer();
                }
            }
            else
            {
                //
            }
        }
Exemple #18
0
        private bool CheckProfile(QueueItem item, List <Task> waits)
        {
            if (item.Profile != server.PendingProfile)
            {
                // すでにプロファイルが決定済み
                return(true);
            }
            if (item.State == QueueState.PreFailed)
            {
                // TSファイルの情報取得に失敗している
                return(false);
            }

            // ペンディングならプロファイルの決定を試みる
            int itemPriority = 0;
            var profile      = server.SelectProfile(item, out itemPriority);

            if (profile == null)
            {
                return(false);
            }

            item.Profile = ServerSupport.DeepCopy(profile);
            if (itemPriority > 0)
            {
                item.Priority = itemPriority;
            }

            waits?.Add(ClientQueueUpdate(new QueueUpdate()
            {
                Type = UpdateType.Remove,
                Item = item
            }));

            return(true);
        }
Exemple #19
0
        public async void NewProfile()
        {
            if (Model.SelectedProfile != null)
            {
                var profile = Model.SelectedProfile;
                var newp    = new NewProfileViewModel()
                {
                    Model = Model,
                    Name  = profile.Data.Name + "のコピー"
                };

                await Messenger.RaiseAsync(new TransitionMessage(
                                               typeof(Views.NewProfileWindow), newp, TransitionMode.Modal, "FromProfile"));

                if (newp.Success)
                {
                    var newprofile   = ServerSupport.DeepCopy(profile.Data);
                    var invalidChars = System.IO.Path.GetInvalidFileNameChars();
                    newprofile.Name = new string(newp.Name.ToCharArray()
                                                 .Where(c => Array.IndexOf(invalidChars, c) == -1).ToArray());
                    await Model.AddProfile(newprofile);
                }
            }
        }
Exemple #20
0
        public async void MakeBatchFile()
        {
            string cur    = Directory.GetCurrentDirectory();
            string exe    = Path.GetDirectoryName(GetType().Assembly.Location);
            string dst    = Model.MakeScriptData.OutDir?.TrimEnd(Path.DirectorySeparatorChar);
            string prof   = DisplayProfile.GetProfileName(Model.MakeScriptData.SelectedProfile);
            string bat    = Model.MakeScriptData.Model.AddQueueBat;
            string nas    = null;
            string ip     = "localhost";
            int    port   = Model.ServerPort;
            string subnet = null;
            string mac    = null;
            bool   direct = Model.MakeScriptData.IsDirect;

            if (prof == null)
            {
                Description = "プロファイルを選択してください";
                return;
            }

            if (string.IsNullOrEmpty(dst))
            {
                Description = "出力先が設定されていません";
                return;
            }
            if (Directory.Exists(dst) == false)
            {
                Description = "出力先ディレクトリにアクセスできません";
                return;
            }

            if (Model.MakeScriptData.IsNasEnabled)
            {
                if (string.IsNullOrEmpty(Model.MakeScriptData.NasDir))
                {
                    Description = "NAS保存先を指定してください。";
                    return;
                }
                nas = Model.MakeScriptData.NasDir.TrimEnd(Path.DirectorySeparatorChar);;
            }

            if (IsRemoteClient)
            {
                ip = Model.ServerIP;
                if (Model.MakeScriptData.IsWakeOnLan)
                {
                    var localIP = Model.LocalIP;
                    if (localIP == null)
                    {
                        Description = "IPアドレス取得に失敗";
                        return;
                    }
                    if (localIP.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork)
                    {
                        Description = "IPv4以外の接続には対応していません";
                        return;
                    }
                    var subnetaddr = ServerSupport.GetSubnetMask(((IPEndPoint)localIP).Address);
                    if (subnetaddr == null)
                    {
                        Description = "サブネットマスク取得に失敗";
                        return;
                    }
                    subnet = subnetaddr.ToString();
                    var macbytes = Model.MacAddress;
                    if (macbytes == null)
                    {
                        Description = "MACアドレス取得に失敗";
                        return;
                    }
                    mac = string.Join(":", macbytes.Select(s => s.ToString("X")));
                }
            }

            Description = "";

            var sb = new StringBuilder();

            if (direct)
            {
                sb.Append("rem _EDCBX_DIRECT_\r\n");
            }
            sb.AppendFormat("\"{0}\\AmatsukazeAddTask.exe\"", exe)
            .AppendFormat(" -r \"{0}\"", cur)
            .AppendFormat(" -f \"{0}FilePath{0}\" -ip \"{1}\"", direct ? "%" : "$", ip)
            .AppendFormat(" -p {0}", port)
            .AppendFormat(" -o \"{0}\"", dst)
            .AppendFormat(" -s \"{0}\"", prof)
            .AppendFormat(" --priority {0}", Model.MakeScriptData.Priority);
            if (nas != null)
            {
                sb.AppendFormat(" -d \"{0}\"", nas);
            }
            if (mac != null)
            {
                sb.AppendFormat(" --subnet \"{0}\"", subnet)
                .AppendFormat(" --mac \"{0}\"", mac);
            }
            if (Model.MakeScriptData.MoveAfter == false)
            {
                sb.Append(" --no-move");
            }
            if (Model.MakeScriptData.ClearSucceeded)
            {
                sb.Append(" --clear-succeeded");
            }
            if (Model.MakeScriptData.WithRelated)
            {
                sb.Append(" --with-related");
            }
            if (!string.IsNullOrEmpty(bat))
            {
                sb.AppendFormat(" -b \"{0}\"", bat);
            }

            var saveFileDialog = new SaveFileDialog();

            saveFileDialog.FilterIndex = 1;
            saveFileDialog.Filter      = "バッチファイル(.bat)|*.bat|All Files (*.*)|*.*";
            bool?result = saveFileDialog.ShowDialog();

            if (result != true)
            {
                return;
            }

            try
            {
                File.WriteAllText(saveFileDialog.FileName, sb.ToString(), Encoding.Default);
            }
            catch (Exception e)
            {
                Description = "バッチファイル作成に失敗: " + e.Message;
                return;
            }

            var resvm = new MakeBatchResultViewModel()
            {
                Path = saveFileDialog.FileName
            };

            await Messenger.RaiseAsync(new TransitionMessage(
                                           typeof(Views.MakeBatchResultWindow), resvm, TransitionMode.Modal, "Key"));

            await Model.SendMakeScriptData();
        }
Exemple #21
0
        public async Task Exec()
        {
            string srcpath = option.FilePath;

            byte[] hash = null;

            if (string.IsNullOrEmpty(option.NasDir) == false)
            {
                if (File.Exists(option.FilePath) == false)
                {
                    throw new Exception("入力ファイルが見つかりません");
                }

                if (option.ClearSucceeded)
                {
                    // succeededを空にする
                    var succeeded = option.NasDir + Path.DirectorySeparatorChar + "succeeded";
                    if (Directory.Exists(succeeded))
                    {
                        foreach (var file in Directory.GetFiles(succeeded))
                        {
                            File.Delete(file);
                        }
                    }
                }
                // NASにコピー
                var remotepath = option.NasDir + Path.DirectorySeparatorChar + Path.GetFileName(srcpath);
                hash = await HashUtil.CopyWithHash(option.FilePath, remotepath);

                srcpath = remotepath;
                if (option.WithRelated)
                {
                    var body   = Path.GetFileNameWithoutExtension(option.FilePath);
                    var tsext  = Path.GetExtension(option.FilePath);
                    var srcDir = Path.GetDirectoryName(option.FilePath);
                    foreach (var ext in ServerSupport.GetFileExtentions(null, true))
                    {
                        string srcPath = srcDir + Path.DirectorySeparatorChar + body + ext;
                        string dstPath = option.NasDir + Path.DirectorySeparatorChar + body + ext;
                        if (File.Exists(srcPath))
                        {
                            File.Copy(srcPath, dstPath);
                        }
                    }
                }
            }

            if (string.IsNullOrEmpty(option.RemoteDir) == false)
            {
                // これはサーバからのアクセス用パスなので"\\"で区切る
                srcpath = option.RemoteDir + "\\" + Path.GetFileName(srcpath);
            }

            Console.WriteLine(srcpath + " を追加します");

            // リクエストを生成
            request = new AddQueueRequest()
            {
                DirPath = Path.GetDirectoryName(srcpath),
                Outputs = new List <OutputInfo>()
                {
                    new OutputInfo()
                    {
                        DstPath  = option.OutPath,
                        Profile  = option.Profile,
                        Priority = option.Priority,
                    }
                },
                Targets = new List <AddQueueItem>()
                {
                    new AddQueueItem()
                    {
                        Path = srcpath, Hash = hash
                    }
                },
                Mode        = ProcMode.AutoBatch,
                RequestId   = UniqueId(),
                AddQueueBat = option.AddQueueBat
            };

            server = new CUIServerConnection(this);
            bool isLocal  = !IsRunningOnMono() && ServerSupport.IsLocalIP(option.ServerIP);
            int  maxRetry = isLocal ? 3 : 5;

            for (int i = 0; i < maxRetry; ++i)
            {
                if (i > 0)
                {
                    Console.WriteLine("再試行します・・・");
                }

                try
                {
                    // サーバに接続
                    server.Connect(option.ServerIP, option.ServerPort);
                }
                catch (Exception e0)
                {
                    Console.WriteLine(e0.StackTrace);
                    // サーバに繋がらなかった

                    // ローカルの場合は、起動を試みる
                    if (isLocal)
                    {
                        await ServerSupport.TerminateStandalone(option.AmatsukazeRoot);

                        ServerSupport.LaunchLocalServer(option.ServerPort, option.AmatsukazeRoot);

                        // 10秒待つ
                        await Task.Delay(10 * 1000);
                    }
                    else
                    {
                        // リモートの場合は、Wake On Lanする
                        if (option.MacAddress == null)
                        {
                            throw new Exception("リモートサーバへの接続に失敗しました。");
                        }

                        Console.WriteLine("Wake On Lanで起動を試みます。");

                        WakeOnLan.Wake(
                            IPAddress.Parse(option.ServerIP),
                            IPAddress.Parse(option.Subnet),
                            option.MacAddress);

                        // 40秒待つ
                        await Task.Delay(40 * 1000);
                    }

                    continue;
                }

                try
                {
                    // サーバにタスク登録
                    await server.AddQueue(request);

                    // リクエストIDの完了通知ゲット or タイムアウトしたら終了
                    var timeout = Task.Delay(30 * 1000);
                    while (okReceived == false)
                    {
                        var recv = server.ProcOneMessage();
                        if (await Task.WhenAny(recv, timeout) == timeout)
                        {
                            Console.WriteLine("サーバのリクエスト受理を確認できませんでした。");
                            throw new Exception();
                        }
                    }
                }
                catch (Exception e1)
                {
                    Console.WriteLine(e1.StackTrace);
                    // なぜか失敗した
                    continue;
                }

                if (string.IsNullOrEmpty(option.NasDir) == false && !option.NoMove)
                {
                    // NASにコピーしたファイルはtransferredフォルダに移動
                    string trsDir = Path.GetDirectoryName(option.FilePath) + Path.DirectorySeparatorChar + "transferred";
                    Directory.CreateDirectory(trsDir);
                    string trsFile = trsDir + Path.DirectorySeparatorChar + Path.GetFileName(option.FilePath);
                    if (File.Exists(option.FilePath))
                    {
                        if (File.Exists(trsFile))
                        {
                            // 既に存在している同名ファイルは削除
                            File.Delete(trsFile);
                        }
                        File.Move(option.FilePath, trsFile);
                    }
                    if (option.WithRelated)
                    {
                        var body   = Path.GetFileNameWithoutExtension(option.FilePath);
                        var tsext  = Path.GetExtension(option.FilePath);
                        var srcDir = Path.GetDirectoryName(option.FilePath);
                        foreach (var ext in ServerSupport.GetFileExtentions(null, true))
                        {
                            string srcPath = srcDir + Path.DirectorySeparatorChar + body + ext;
                            string dstPath = trsDir + Path.DirectorySeparatorChar + body + ext;
                            if (File.Exists(srcPath))
                            {
                                if (File.Exists(dstPath))
                                {
                                    // 既に存在している同名ファイルは削除
                                    File.Delete(dstPath);
                                }
                                File.Move(srcPath, dstPath);
                            }
                        }
                    }
                }

                break;
            }
            server.Finish();
        }
 /// <summary>
 ///   Validates this message against the given server support
 /// </summary>
 public override void Validate(ServerSupport serverSupport)
 {
     base.Validate(serverSupport);
     MessageUtil.EnsureValidChannelName(this.Channel, serverSupport);
     if (string.IsNullOrEmpty(this.Target))
     {
         throw new InvalidMessageException(Resources.TargetcannotBeEmpty);
     }
     if (string.IsNullOrEmpty(this.Channel))
     {
         throw new InvalidMessageException(Resources.ChannelCannotBeEmpty);
     }
 }
 /// <exclude />
 public override void Validate( ServerSupport serverSupport )
 {
     base.Validate( serverSupport );
     if ( serverSupport != null )
     {
         if ( MaxUsers >= 0 || MinUsers >= 0 )
         {
             VerifySupport( serverSupport, ServerSupport.ExtendedListParameters.UserCount );
         }
         if ( YoungerThan >= 0 || OlderThan >= 0 ) {
             VerifySupport( serverSupport, ServerSupport.ExtendedListParameters.CreationTime );
         }
         if ( !String.IsNullOrEmpty( MatchMask ) ) {
             VerifySupport( serverSupport, ServerSupport.ExtendedListParameters.Mask );
         }
         if ( !String.IsNullOrEmpty( NotMatchMask ) ) {
             VerifySupport( serverSupport, ServerSupport.ExtendedListParameters.NotMask );
         }
         if ( TopicOlderThan >= 0 || TopicYoungerThan >= 0 )
         {
             VerifySupport( serverSupport, ServerSupport.ExtendedListParameters.Topic );
         }
     }
 }
 /// <summary>
 /// Validates this message against the given server support
 /// </summary>
 public override void Validate( ServerSupport serverSupport )
 {
     base.Validate( serverSupport );
     Channel = MessageUtil.EnsureValidChannelName( Channel, serverSupport );
 }
 static void VerifySupport( ServerSupport serverSupport, ServerSupport.ExtendedListParameters parameter )
 {
     if ( ( serverSupport.ExtendedList & parameter ) != parameter )
     {
         throw new InvalidMessageException( String.Format( CultureInfo.InvariantCulture, NeboResources.ServerDoesNotSupportExtendedListParameter, parameter.ToString() ) );
     }
 }
Exemple #26
0
        public Task ChangeItem(ChangeItemData data)
        {
            if (data.ChangeType == ChangeItemType.RemoveCompleted)
            {
                var waits = new List <Task>();
                RemoveCompleted(waits);
                return(Task.WhenAll(waits));
            }

            // アイテム操作
            var target = Queue.FirstOrDefault(s => s.Id == data.ItemId);

            if (target == null)
            {
                return(server.NotifyError(
                           "指定されたアイテムが見つかりません", false));
            }

            if (data.ChangeType == ChangeItemType.ResetState ||
                data.ChangeType == ChangeItemType.UpdateProfile ||
                data.ChangeType == ChangeItemType.Duplicate)
            {
                if (target.State == QueueState.PreFailed)
                {
                    return(server.NotifyError("このアイテムは追加処理に失敗しているため操作できません", false));
                }
                if (data.ChangeType == ChangeItemType.ResetState)
                {
                    // エンコード中は変更できない
                    if (target.State == QueueState.Encoding)
                    {
                        return(server.NotifyError("エンコード中のアイテムはリトライできません", false));
                    }
                }
                else if (data.ChangeType == ChangeItemType.UpdateProfile)
                {
                    // エンコード中は変更できない
                    if (target.State == QueueState.Encoding)
                    {
                        return(server.NotifyError("エンコード中のアイテムはプロファイル更新できません", false));
                    }
                }
                else if (data.ChangeType == ChangeItemType.Duplicate)
                {
                    // バッチモードでアクティブなやつは重複になるのでダメ
                    if (target.IsBatch && target.IsActive)
                    {
                        return(server.NotifyError("通常モードで追加されたアイテムは複製できません", false));
                    }
                }

                var waits = new List <Task>();

                if (target.IsBatch)
                {
                    // バッチモードでfailed/succeededフォルダに移動されていたら戻す
                    if (target.State == QueueState.Failed || target.State == QueueState.Complete)
                    {
                        if (Queue.Where(s => s.SrcPath == target.SrcPath).Any(s => s.IsActive) == false)
                        {
                            var dirPath  = Path.GetDirectoryName(target.SrcPath);
                            var movedDir = (target.State == QueueState.Failed) ?
                                           ServerSupport.FAIL_DIR :
                                           ServerSupport.SUCCESS_DIR;
                            var movedPath = dirPath + "\\" + movedDir + "\\" + Path.GetFileName(target.SrcPath);
                            if (File.Exists(movedPath))
                            {
                                // EDCB関連ファイルも移動したかどうかは分からないが、あれば戻す
                                try
                                {
                                    ServerSupport.MoveTSFile(movedPath, dirPath, true);
                                }
                                catch (Exception e)
                                {
                                    return(server.FatalError(
                                               "ファイルの移動に失敗しました", e));
                                }
                            }
                        }
                    }
                }

                if (data.ChangeType == ChangeItemType.ResetState)
                {
                    // リトライはプロファイル再適用も行う
                    UpdateProfileItem(target, waits);
                    ResetStateItem(target, waits);
                    waits.Add(server.NotifyMessage("リトライします", false));
                }
                else if (data.ChangeType == ChangeItemType.UpdateProfile)
                {
                    if (UpdateProfileItem(target, waits))
                    {
                        waits.Add(server.NotifyMessage("新しいプロファイルが適用されました", false));
                    }
                    else
                    {
                        waits.Add(server.NotifyMessage("すでに最新のプロファイルが適用されています", false));
                    }
                }
                else
                {
                    DuplicateItem(target, waits);
                    waits.Add(server.NotifyMessage("複製しました", false));
                }

                return(Task.WhenAll(waits));
            }
            else if (data.ChangeType == ChangeItemType.Cancel)
            {
                if (server.CancelItem(target) || target.IsActive)
                {
                    target.State = QueueState.Canceled;
                    return(Task.WhenAll(
                               ClientQueueUpdate(new QueueUpdate()
                    {
                        Type = UpdateType.Update,
                        Item = target
                    }),
                               server.NotifyMessage("キャンセルしました", false)));
                }
                else
                {
                    return(server.NotifyError(
                               "このアイテムはアクティブ状態でないため、キャンセルできません", false));
                }
            }
            else if (data.ChangeType == ChangeItemType.Priority)
            {
                target.Priority = data.Priority;
                server.ReScheduleQueue();
                return(Task.WhenAll(
                           ClientQueueUpdate(new QueueUpdate()
                {
                    Type = UpdateType.Update,
                    Item = target
                }),
                           server.NotifyMessage("優先度を変更しました", false)));
            }
            else if (data.ChangeType == ChangeItemType.Profile)
            {
                if (target.State == QueueState.Encoding)
                {
                    return(server.NotifyError("エンコード中はプロファイル変更できません", false));
                }
                if (target.State == QueueState.PreFailed)
                {
                    return(server.NotifyError("このアイテムはプロファイル変更できません", false));
                }

                var waits = new List <Task>();
                target.ProfileName = data.Profile;
                if (UpdateProfileItem(target, waits))
                {
                    waits.Add(server.NotifyMessage("プロファイルを「" + data.Profile + "」に変更しました", false));
                }
                else
                {
                    waits.Add(server.NotifyMessage("既に同じプロファイルが適用されています", false));
                }

                return(Task.WhenAll(waits));
            }
            else if (data.ChangeType == ChangeItemType.RemoveItem)
            {
                server.CancelItem(target);
                target.State = QueueState.Canceled;
                Queue.Remove(target);
                UpdateQueueOrder();
                return(Task.WhenAll(
                           ClientQueueUpdate(new QueueUpdate()
                {
                    Type = UpdateType.Remove,
                    Item = target
                }),
                           server.NotifyMessage("アイテムを削除しました", false)));
            }
            else if (data.ChangeType == ChangeItemType.ForceStart)
            {
                if (target.State != QueueState.Queue)
                {
                    return(server.NotifyError("待ち状態にないアイテムは開始できません", false));
                }
                else
                {
                    server.ForceStartItem(target);
                }
            }
            else if (data.ChangeType == ChangeItemType.RemoveSourceFile)
            {
                if (target.IsBatch == false)
                {
                    return(server.NotifyError("通常or自動追加以外はTSファイル削除ができません", false));
                }
                if (target.State != QueueState.Complete)
                {
                    return(server.NotifyError("完了していないアイテムはTSファイル削除ができません", false));
                }
                if (Queue.Where(s => s.SrcPath == target.SrcPath).Any(s => s.IsActive))
                {
                    return(server.NotifyError("まだ完了していない項目があるため、このTSは削除ができません", false));
                }

                // !!!削除!!!
                var dirPath   = Path.GetDirectoryName(target.SrcPath);
                var movedPath = dirPath + "\\" + ServerSupport.SUCCESS_DIR + "\\" + Path.GetFileName(target.SrcPath);
                if (File.Exists(movedPath))
                {
                    // EDCB関連ファイルも移動したかどうかは分からないが、あれば消す
                    try
                    {
                        ServerSupport.DeleteTSFile(movedPath, true);
                    }
                    catch (Exception e)
                    {
                        return(server.FatalError(
                                   "ファイルの削除に失敗しました", e));
                    }
                }

                // アイテム削除
                Queue.Remove(target);
                UpdateQueueOrder();
                return(Task.WhenAll(
                           ClientQueueUpdate(new QueueUpdate()
                {
                    Type = UpdateType.Remove,
                    Item = target
                }),
                           server.NotifyMessage("TSファイルを削除しました", false)));
            }
            else if (data.ChangeType == ChangeItemType.Move)
            {
                if (data.Position >= Queue.Count)
                {
                    return(server.NotifyError("位置が範囲外です", false));
                }

                Queue.Remove(target);
                Queue.Insert(data.Position, target);
                UpdateQueueOrder();
                return(Task.WhenAll(
                           ClientQueueUpdate(new QueueUpdate()
                {
                    Type = UpdateType.Move,
                    Item = target,
                    Position = data.Position
                })));
            }
            return(Task.FromResult(0));
        }
Exemple #27
0
        // アイテムのProfileNameからプロファイルを決定して、
        // オプションでwaits!=nullのときはクライアントに通知
        // 戻り値: プロファイルが変更された場合(結果、エラーになった場合も含む)
        private bool UpdateProfileItem(QueueItem item, List <Task> waits)
        {
            var getResult = server.GetProfile(item, item.ProfileName);
            var profile   = (getResult != null) ? ServerSupport.DeepCopy(getResult.Profile) : server.PendingProfile;
            var priority  = (getResult != null && getResult.Priority > 0) ? getResult.Priority : item.Priority;

            if (item.Profile == null ||
                item.Profile.Name != profile.Name ||
                item.Profile.LastUpdate != profile.LastUpdate ||
                item.Priority != priority)
            {
                // 変更
                item.Profile  = profile;
                item.Priority = priority;

                // ハッシュリスト取得
                if (profile != server.PendingProfile && // ペンディングの場合は決定したときに実行される
                    item.IsSeparateHashRequired)
                {
                    var hashpath = Path.GetDirectoryName(item.SrcPath) + ".hash";
                    if (hashCache.ContainsKey(hashpath) == false)
                    {
                        if (File.Exists(hashpath) == false)
                        {
                            item.State      = QueueState.LogoPending;
                            item.FailReason = "ハッシュファイルがありません: " + hashpath;
                            return(true);
                        }
                        else
                        {
                            try
                            {
                                hashCache.Add(hashpath, new DirHash()
                                {
                                    DirPath  = hashpath,
                                    HashDict = HashUtil.ReadHashFile(hashpath)
                                });
                            }
                            catch (IOException e)
                            {
                                item.State      = QueueState.LogoPending;
                                item.FailReason = "ハッシュファイルの読み込みに失敗: " + e.Message;
                                return(true);
                            }
                        }
                    }

                    var cacheItem = hashCache[hashpath];
                    var filename  = item.FileName;

                    if (cacheItem.HashDict.ContainsKey(filename) == false)
                    {
                        item.State      = QueueState.LogoPending;
                        item.FailReason = "ハッシュファイルにこのファイルのハッシュがありません";
                        return(true);
                    }

                    item.Hash = cacheItem.HashDict[filename];
                }

                server.ReScheduleQueue();
                UpdateQueueItem(item, waits);

                waits?.Add(ClientQueueUpdate(new QueueUpdate()
                {
                    Type = UpdateType.Add,
                    Item = item
                }));

                return(true);
            }

            return(false);
        }
Exemple #28
0
        public async Task AddQueue(AddQueueRequest req)
        {
            List <Task> waits = new List <Task>();

            addQueueCanceled = false;

            // ユーザ操作でない場合はログを記録する
            bool enableLog = (req.Mode == ProcMode.AutoBatch);

            if (req.Outputs.Count == 0)
            {
                await server.NotifyError("出力が1つもありません", enableLog);

                return;
            }

            // 既に追加されているファイルは除外する
            // バッチのときは全ファイルが対象だが、バッチじゃなければバッチのみが対象
            var ignores = req.IsBatch ? Queue : Queue.Where(t => t.IsBatch);

            var ignoreSet = new HashSet <string>(
                ignores.Where(item => item.IsActive)
                .Select(item => item.SrcPath));

            var items = ((req.Targets != null)
                ? req.Targets
                : Directory.GetFiles(req.DirPath)
                         .Where(s =>
            {
                string lower = s.ToLower();
                return(lower.EndsWith(".ts") || lower.EndsWith(".m2t"));
            })
                         .Select(f => new AddQueueItem()
            {
                Path = f
            }))
                        .Where(f => !ignoreSet.Contains(f.Path)).ToList();

            waits.Add(WriteLine("" + items.Count + "件を追加処理します"));

            var map      = server.ServiceMap;
            var numItems = 0;
            var progress = 0;

            // TSファイル情報を読む
            foreach (var additem in items)
            {
                waits.Add(WriteLine("(" + (++progress) + "/" + items.Count + ") " + Path.GetFileName(additem.Path) + " を処理中"));

                using (var info = new TsInfo(amtcontext))
                {
                    var failReason = "";
                    var addItems   = new List <QueueItem>();
                    if (await Task.Run(() => info.ReadFile(additem.Path)) == false)
                    {
                        failReason = "TS情報取得に失敗: " + amtcontext.GetError();
                    }
                    else
                    {
                        failReason = "TSファイルに映像が見つかりませんでした";
                        var list      = info.GetProgramList();
                        var videopids = new List <int>();
                        int numFiles  = 0;
                        for (int i = 0; i < list.Length; ++i)
                        {
                            var prog = list[i];
                            if (prog.HasVideo &&
                                videopids.Contains(prog.VideoPid) == false)
                            {
                                videopids.Add(prog.VideoPid);

                                var serviceName = "不明";
                                var tsTime      = DateTime.MinValue;
                                if (info.HasServiceInfo)
                                {
                                    var service = info.GetServiceList().Where(s => s.ServiceId == prog.ServiceId).FirstOrDefault();
                                    if (service.ServiceId != 0)
                                    {
                                        serviceName = service.ServiceName;
                                    }
                                    tsTime = info.GetTime();
                                }

                                var outname = Path.GetFileNameWithoutExtension(additem.Path);
                                if (numFiles > 0)
                                {
                                    outname += "-マルチ" + numFiles;
                                }

                                Debug.Print("解析完了: " + additem.Path);

                                foreach (var outitem in req.Outputs)
                                {
                                    var genre = prog.Content.Select(s => ServerSupport.GetGenre(s)).ToList();

                                    var item = new QueueItem()
                                    {
                                        Id          = nextItemId++,
                                        Mode        = req.Mode,
                                        SrcPath     = additem.Path,
                                        Hash        = additem.Hash,
                                        DstPath     = outitem.DstPath + "\\" + outname,
                                        ServiceId   = prog.ServiceId,
                                        ImageWidth  = prog.Width,
                                        ImageHeight = prog.Height,
                                        TsTime      = tsTime,
                                        ServiceName = serviceName,
                                        EventName   = prog.EventName,
                                        State       = QueueState.LogoPending,
                                        Priority    = outitem.Priority,
                                        AddTime     = DateTime.Now,
                                        ProfileName = outitem.Profile,
                                        Genre       = genre,
                                        Tags        = new List <string>()
                                    };

                                    if (item.IsOneSeg)
                                    {
                                        item.State      = QueueState.PreFailed;
                                        item.FailReason = "映像が小さすぎます(" + prog.Width + "," + prog.Height + ")";
                                    }
                                    else
                                    {
                                        // ロゴファイルを探す
                                        if (req.Mode != ProcMode.DrcsCheck && map.ContainsKey(item.ServiceId) == false)
                                        {
                                            // 新しいサービスを登録
                                            waits.Add(server.AddService(new ServiceSettingElement()
                                            {
                                                ServiceId    = item.ServiceId,
                                                ServiceName  = item.ServiceName,
                                                LogoSettings = new List <LogoSetting>()
                                            }));
                                        }

                                        // 追加時バッチ
                                        if (string.IsNullOrEmpty(req.AddQueueBat) == false)
                                        {
                                            waits.Add(WriteLine("追加時バッチ起動"));
                                            using (var scriptExecuter = new UserScriptExecuter()
                                            {
                                                Server = server,
                                                Phase = ScriptPhase.OnAdd,
                                                ScriptPath = server.GetBatDirectoryPath() + "\\" + req.AddQueueBat,
                                                Item = item,
                                                Prog = prog,
                                                OnOutput = WriteTextBytes
                                            })
                                            {
                                                process = scriptExecuter;
                                                await scriptExecuter.Execute();

                                                process = null;
                                            }

                                            if (addQueueCanceled)
                                            {
                                                break;
                                            }
                                        }

                                        ++numFiles;
                                    }

                                    addItems.Add(item);
                                }
                            }
                        }
                    }

                    if (addQueueCanceled)
                    {
                        break;
                    }

                    if (addItems.Count == 0)
                    {
                        // アイテムが1つもないときはエラー項目として追加
                        foreach (var outitem in req.Outputs)
                        {
                            bool isAuto      = false;
                            var  profileName = ServerSupport.ParseProfileName(outitem.Profile, out isAuto);
                            var  profile     = isAuto ? null : ServerSupport.DeepCopy(server.GetProfile(profileName));

                            var item = new QueueItem()
                            {
                                Id          = nextItemId++,
                                Mode        = req.Mode,
                                Profile     = profile,
                                SrcPath     = additem.Path,
                                Hash        = additem.Hash,
                                DstPath     = "",
                                ServiceId   = -1,
                                ImageWidth  = -1,
                                ImageHeight = -1,
                                TsTime      = DateTime.MinValue,
                                ServiceName = "不明",
                                State       = QueueState.PreFailed,
                                FailReason  = failReason,
                                AddTime     = DateTime.Now,
                                ProfileName = outitem.Profile,
                                Tags        = new List <string>()
                            };

                            addItems.Add(item);
                        }
                    }

                    // 1ソースファイルに対するaddはatomicに実行したいので、
                    // このループではawaitしないこと
                    foreach (var item in addItems)
                    {
                        if (item.State != QueueState.PreFailed)
                        {
                            // プロファイルを設定
                            UpdateProfileItem(item, null);
                        }
                        // 追加
                        item.Order = Queue.Count;
                        Queue.Add(item);
                        // まずは内部だけで状態を更新
                        UpdateQueueItem(item, null);
                        // 状態が決まったらクライアント側に追加通知
                        waits.Add(ClientQueueUpdate(new QueueUpdate()
                        {
                            Type = UpdateType.Add,
                            Item = item
                        }));
                    }

                    numItems += addItems.Count;

                    UpdateProgress();
                    waits.Add(server.RequestState());
                }

                if (addQueueCanceled)
                {
                    break;
                }
            }

            if (addQueueCanceled)
            {
                waits.Add(WriteLine("キャンセルされました"));
            }

            waits.Add(WriteLine("" + numItems + "件追加しました"));

            if (addQueueCanceled == false && numItems == 0)
            {
                waits.Add(server.NotifyError(
                              "エンコード対象ファイルがありませんでした。パス:" + req.DirPath, enableLog));

                await Task.WhenAll(waits);

                return;
            }
            else
            {
                waits.Add(server.NotifyMessage("" + numItems + "件追加しました", false));
            }

            if (req.Mode != ProcMode.AutoBatch)
            {
                // 最後に使った設定を記憶しておく
                server.LastUsedProfile = req.Outputs[0].Profile;
                server.AddOutPathHistory(req.Outputs[0].DstPath);
                server.LastAddQueueBat = req.AddQueueBat;
                waits.Add(server.RequestUIState());
            }

            waits.Add(server.RequestFreeSpace());

            await Task.WhenAll(waits);
        }
 /// <summary>
 /// Validates this message against the given server support
 /// </summary>
 public override void Validate( ServerSupport serverSupport )
 {
     base.Validate( serverSupport );
     if ( serverSupport == null )
     {
         return;
     }
     if ( Reason.Length > serverSupport.MaxKickCommentLength )
     {
         Reason = Reason.Substring( 0, serverSupport.MaxKickCommentLength );
     }
     for ( Int32 i = 0; i < Channels.Count; i++ )
     {
         Channels[ i ] = MessageUtil.EnsureValidChannelName( Channels[ i ], serverSupport );
     }
 }
Exemple #30
0
 /// <summary>
 ///   Validates this message against the given server support.
 /// </summary>
 public virtual void Validate(ServerSupport serverSupport)
 {
 }
Exemple #31
0
 private static void VerifySupport(ServerSupport serverSupport, ServerSupport.ExtendedListParameters parameter)
 {
     if (!serverSupport.ExtendedList.HasFlag(parameter))
     {
         throw new InvalidMessageException(string.Format(CultureInfo.InvariantCulture, Resources.ServerDoesNotSupportExtendedListParameter, parameter));
     }
 }
Exemple #32
0
 /// <summary>
 ///   Validates this message against the given server support
 /// </summary>
 public override void Validate(ServerSupport serverSupport)
 {
     base.Validate(serverSupport);
     Channels = (from channel in Channels
                 select MessageUtil.EnsureValidChannelName(channel, serverSupport)).ToList();
 }
Exemple #33
0
        public void SupportMessage()
        {
            var raws = new[] {
                ":irc.easynews.com 005 _aLfa_ CHANLIMIT=#&:25 WALLCHOPS KNOCK EXCEPTS INVEX MODES=4 MAXCHANNELS=35 MAXBANS=25 MAXTARGETS=4 NICKLEN=9 TOPICLEN=120 KICKLEN=120 :are supported by this server",
                ":irc.foxlink.net 005 SupayBot STD=i-d STATUSMSG=@+ KNOCK EXCEPTS=e INVEX=I MODES=4 MAXCHANNELS=50 MAXLIST=beI:100 MAXTARGETS=7 NICKLEN=9 TOPICLEN=120 KICKLEN=120 :are supported by this server",
                ":irc.foxlink.net 005 SupayBot CHANTYPES=#& PREFIX=(ov)@+ CHANMODES=eIb,k,l,imnpst NETWORK=EFNet CASEMAPPING=rfc1459 CHARSET=ascii CALLERID ETRACE WALLCHOPS :are supported by this server"
            };

            for (var i = 0; i < raws.Length; i++)
            {
                var msg = MessageAssert.TypeAndRoundTrip<SupportMessage>(raws[i]);
                var support = new ServerSupport();
                support.LoadInfo(msg);

                switch (i)
                {
                    case 0:
                        Assert.AreEqual(12, msg.SupportedItems.Count, "SupportItems Count");
                        Assert.IsNotNull(msg.SupportedItems["CHANLIMIT"], "CHANLIMIT");
                        Assert.IsNotNull(msg.SupportedItems["WALLCHOPS"], "WALLCHOPS");
                        Assert.IsNotNull(msg.SupportedItems["KNOCK"], "KNOCK");
                        Assert.IsNotNull(msg.SupportedItems["EXCEPTS"], "EXCEPTS");
                        Assert.IsNotNull(msg.SupportedItems["INVEX"], "INVEX");
                        Assert.IsNotNull(msg.SupportedItems["MODES"], "MODES");
                        Assert.IsNotNull(msg.SupportedItems["MAXCHANNELS"], "MAXCHANNELS");
                        Assert.IsNotNull(msg.SupportedItems["MAXBANS"], "MAXBANS");
                        Assert.IsNotNull(msg.SupportedItems["MAXTARGETS"], "MAXTARGETS");
                        Assert.IsNotNull(msg.SupportedItems["NICKLEN"], "NICKLEN");
                        Assert.IsNotNull(msg.SupportedItems["TOPICLEN"], "TOPICLEN");
                        Assert.IsNotNull(msg.SupportedItems["KICKLEN"], "KICKLEN");
                        Assert.AreEqual("#&:25", msg.SupportedItems["CHANLIMIT"], "CHANLIMIT");
                        Assert.AreEqual("4", msg.SupportedItems["MODES"], "MODES");
                        Assert.AreEqual("35", msg.SupportedItems["MAXCHANNELS"], "MAXCHANNELS");
                        Assert.AreEqual("25", msg.SupportedItems["MAXBANS"], "MAXBANS");
                        Assert.AreEqual("4", msg.SupportedItems["MAXTARGETS"], "MAXTARGETS");
                        Assert.AreEqual("9", msg.SupportedItems["NICKLEN"], "NICKLEN");
                        Assert.AreEqual("120", msg.SupportedItems["TOPICLEN"], "TOPICLEN");
                        Assert.AreEqual("120", msg.SupportedItems["KICKLEN"], "KICKLEN");

                        Assert.AreEqual(2, support.ChannelLimits.Count, "ChannelLimits");
                        Assert.AreEqual(25, support.ChannelLimits["#"], "ChannelLimits");
                        Assert.AreEqual(25, support.ChannelLimits["&"], "ChannelLimits");
                        Assert.IsTrue(support.MessagesToOperators, "MessagesToOperators");
                        Assert.IsTrue(support.Knock, "Knock");
                        Assert.IsTrue(support.BanExceptions, "BanExceptions");
                        Assert.IsTrue(support.InvitationExceptions, "InvitationExceptions");
                        Assert.AreEqual(4, support.MaxModes, "MaxModes");
                        Assert.AreEqual(35, support.MaxChannels, "MaxChannels");
                        Assert.AreEqual(25, support.MaxBans, "MaxBans");
                        Assert.AreEqual(4, support.MaxMessageTargets[""], "MaxMessageTargets");
                        Assert.AreEqual(9, support.MaxNickLength, "MaxNickLength");
                        Assert.AreEqual(120, support.MaxTopicLength, "MaxTopicLength");
                        Assert.AreEqual(120, support.MaxKickCommentLength, "MaxKickCommentLength");

                        break;

                    case 1:
                        Assert.AreEqual(12, msg.SupportedItems.Count, "SupportedItems Count");
                        Assert.IsNotNull(msg.SupportedItems["STD"], "STD");
                        Assert.IsNotNull(msg.SupportedItems["STATUSMSG"], "STATUSMSG");
                        Assert.IsNotNull(msg.SupportedItems["KNOCK"], "KNOCK");
                        Assert.IsNotNull(msg.SupportedItems["EXCEPTS"], "EXCEPTS");
                        Assert.IsNotNull(msg.SupportedItems["INVEX"], "INVEX");
                        Assert.IsNotNull(msg.SupportedItems["MODES"], "MODES");
                        Assert.IsNotNull(msg.SupportedItems["MAXCHANNELS"], "MAXCHANNELS");
                        Assert.IsNotNull(msg.SupportedItems["MAXLIST"], "MAXLIST");
                        Assert.IsNotNull(msg.SupportedItems["MAXTARGETS"], "MAXTARGETS");
                        Assert.IsNotNull(msg.SupportedItems["NICKLEN"], "NICKLEN");
                        Assert.IsNotNull(msg.SupportedItems["TOPICLEN"], "TOPICLEN");
                        Assert.IsNotNull(msg.SupportedItems["KICKLEN"], "KICKLEN");

                        Assert.AreEqual("i-d", msg.SupportedItems["STD"], "STD");
                        Assert.AreEqual("@+", msg.SupportedItems["STATUSMSG"], "STATUSMSG");
                        Assert.AreEqual("e", msg.SupportedItems["EXCEPTS"], "EXCEPTS");
                        Assert.AreEqual("I", msg.SupportedItems["INVEX"], "INVEX");
                        Assert.AreEqual("4", msg.SupportedItems["MODES"], "MODES");
                        Assert.AreEqual("50", msg.SupportedItems["MAXCHANNELS"], "MAXCHANNELS");
                        Assert.AreEqual("beI:100", msg.SupportedItems["MAXLIST"], "MAXLIST");
                        Assert.AreEqual("7", msg.SupportedItems["MAXTARGETS"], "MAXTARGETS");
                        Assert.AreEqual("9", msg.SupportedItems["NICKLEN"], "NICKLEN");
                        Assert.AreEqual("120", msg.SupportedItems["TOPICLEN"], "TOPICLEN");
                        Assert.AreEqual("120", msg.SupportedItems["KICKLEN"], "KICKLEN");

                        Assert.AreEqual("i-d", support.Standard, "Standard");
                        Assert.AreEqual("@+", support.StatusMessages, "StatusMessages");
                        Assert.IsTrue(support.Knock, "Knock");
                        Assert.IsTrue(support.BanExceptions, "BanExceptions");
                        Assert.IsTrue(support.InvitationExceptions, "InvitationExceptions");
                        Assert.AreEqual(4, support.MaxModes, "MaxModes");
                        Assert.AreEqual(50, support.MaxChannels, "MaxChannels");
                        Assert.AreEqual(100, support.MaxBans, "MaxBans");
                        Assert.AreEqual(100, support.MaxBanExceptions, "MaxBanExceptions");
                        Assert.AreEqual(100, support.MaxInvitationExceptions, "MaxInvitationExceptions");
                        Assert.AreEqual(7, support.MaxMessageTargets[""], "MaxMessageTargets");
                        Assert.AreEqual(9, support.MaxNickLength, "MaxNickLength");
                        Assert.AreEqual(120, support.MaxTopicLength, "MaxTopicLength");
                        Assert.AreEqual(120, support.MaxKickCommentLength, "MaxKickCommentLength");

                        break;

                    case 2:
                        Assert.AreEqual(9, msg.SupportedItems.Count, "SupportedItems Count");
                        Assert.IsNotNull(msg.SupportedItems["CHANTYPES"], "CHANTYPES");
                        Assert.IsNotNull(msg.SupportedItems["PREFIX"], "PREFIX");
                        Assert.IsNotNull(msg.SupportedItems["CHANMODES"], "CHANMODES");
                        Assert.IsNotNull(msg.SupportedItems["NETWORK"], "NETWORK");
                        Assert.IsNotNull(msg.SupportedItems["CASEMAPPING"], "CASEMAPPING");
                        Assert.IsNotNull(msg.SupportedItems["CHARSET"], "CHARSET");
                        Assert.IsNotNull(msg.SupportedItems["CALLERID"], "CALLERID");
                        Assert.IsNotNull(msg.SupportedItems["ETRACE"], "ETRACE");
                        Assert.IsNotNull(msg.SupportedItems["WALLCHOPS"], "WALLCHOPS");

                        Assert.AreEqual("#&", msg.SupportedItems["CHANTYPES"], "CHANTYPES");
                        Assert.AreEqual("(ov)@+", msg.SupportedItems["PREFIX"], "PREFIX");
                        Assert.AreEqual("eIb,k,l,imnpst", msg.SupportedItems["CHANMODES"], "CHANMODES");
                        Assert.AreEqual("EFNet", msg.SupportedItems["NETWORK"], "NETWORK");
                        Assert.AreEqual("rfc1459", msg.SupportedItems["CASEMAPPING"], "CASEMAPPING");
                        Assert.AreEqual("ascii", msg.SupportedItems["CHARSET"], "CHARSET");

                        Assert.IsTrue(support.CallerId, "CallerId");
                        Assert.IsTrue(support.ETrace, "ETrace");
                        Assert.IsTrue(support.MessagesToOperators, "MessagesToOperators");
                        Assert.AreEqual(2, support.ChannelTypes.Count, "ChannelTypes");
                        Assert.AreEqual("(ov)@+", support.ChannelStatuses, "ChannelStatuses");
                        Assert.AreEqual(4, support.ModesWithParameters.Count, "ModesWithParameters");
                        Assert.AreEqual(6, support.ModesWithoutParameters.Count, "ModesWithoutParameters");
                        Assert.AreEqual(1, support.ModesWithParametersWhenSet.Count, "ModesWithParametersWhenSet");
                        Assert.AreEqual("EFNet", support.NetworkName, "NetworkName");
                        Assert.AreEqual("rfc1459", support.CaseMapping, "CaseMapping");
                        Assert.AreEqual("ascii", support.CharacterSet, "CharacterSet");

                        break;
                }
            }
        }