public void ToggleDLogToCon() { if (dlogregd == false) { DebugLog.AddListener(ConDeLog); dlogregd = true; #if DEBUG Console.WriteLine("DebugLog now outputs here!", Console.ForegroundColor = ConsoleColor.Green); #endif } if (DebugLog.Enabled == false) { DebugLog.Enabled = true; Console.WriteLine("DebugLog enabled!", Console.ForegroundColor = ConsoleColor.Green); } else if (dlogregd) { DebugLog.RemoveListener(ConDeLog); dlogregd = false; #if DEBUG Console.WriteLine( "Console no longer logging DebugLog messages! Check the debug window output instead.", Console.ForegroundColor = ConsoleColor.Green); #elif !DEBUG DebugLog.Enabled = false; Console.WriteLine("DebugLog disabled!", Console.ForegroundColor = ConsoleColor.Green); #endif } }
public static void Main() { var version = Assembly.GetExecutingAssembly().GetName().Version; string date = new DateTime(2000, 01, 01).AddDays(version.Build).AddSeconds(version.Revision * 2).ToUniversalTime().ToString(); Log.WriteInfo("Main", "Built on {0} UTC", date); try { Settings.Load(); } catch (Exception e) { Log.WriteError("Settings", "{0}", e.Message); return; } if (Settings.Current.SteamKitDebug) { DebugLog.AddListener(new Log.SteamKitLogger()); DebugLog.Enabled = true; } AppDomain.CurrentDomain.UnhandledException += OnSillyCrashHandler; Console.CancelKeyPress += delegate { Cleanup(); }; var thread = new Thread(new ThreadStart(Steam.Instance.Init)); thread.Name = "Steam"; thread.Start(); // We don't need GC idlers in full run if (Settings.IsFullRun) { return; } foreach (var appID in Settings.Current.GameCoordinatorIdlers) { var instance = new GCIdler(appID); thread = new Thread(new ThreadStart(instance.Run)); thread.Name = string.Format("GC Idler {0}", appID); thread.Start(); GCIdlers.Add(instance); } if (Settings.CanConnectToIRC()) { SteamProxy.Instance.ReloadImportant(); IRC.Instance.Init(); } }
// // //Below actually runs the program! // // /// <summary> /// Actually starts the program. /// </summary> /// <param name="args"></param> public void BeginClient(string[] args) { if (BotOwnerID == null) { System.Media.SystemSounds.Exclamation.Play(); Debug.Assert(BotOwnerID != null, "SteamID BotOwnerID is not set to a value. Please assign a value to it in SteamMain.cs on ~line 60."); Console.WriteLine("SteamID BotOwnerID is not set to a value. Please assign a value to it in SteamMain.cs.\nPress any key to exit."); Console.WriteLine(Console.ReadKey()); Environment.Exit(0); } #if DEBUG DebugLog.AddListener(new DebugLogListeners.SendToDebug()); DebugLog.Enabled = true; #endif try { if (args[0] == "servermode") { Console.WriteLine("Running as game server!"); ServerMode = true; } } catch { } Console.WriteLine("Ctrl+C Quits the Program", Console.BackgroundColor = ConsoleColor.White); Console.WriteLine("Be aware of what the input line says at the beginning. If you see \"Command>\" at the beginning of the line, even if it gets ammended with something else, be warned that you will have to press enter before anything but commands will be accepted. Oh, and if nothing is displayed on the typing line, then your first keypress will be ignored unless you see something appear on the line. Be aware of this."); Console.ResetColor(); strUser = GetUserName(); strPassword = GetUserPass(UserPassMode.SteamKey, false); RunSteam(); }
public static void Main() { AppDomain.CurrentDomain.UnhandledException += OnSillyCrashHandler; Console.Title = "Steam Database"; // Load settings file before logging as it can be enabled in settings Settings.Load(); Log.WriteInfo("Bootstrapper", "Copyright (c) 2013-2015, SteamDB. See LICENSE file for more information."); // Just create deepest folder we will use in the app var filesDir = Path.Combine(Application.Path, "files", ".support", "chunks"); Directory.CreateDirectory(filesDir); Settings.Initialize(); LocalConfig.Load(); if (Settings.Current.SteamKitDebug) { DebugLog.AddListener(new Log.SteamKitLogger()); DebugLog.Enabled = true; } Console.CancelKeyPress += OnCancelKey; Application.Init(); }
public SMAForm() { InitializeComponent(); StatusLabel.Text = string.Empty; if (!Directory.Exists(ConfigDirectory)) { Directory.CreateDirectory(ConfigDirectory); } if (Directory.Exists(DebugDirectory)) { Directory.Delete(DebugDirectory, true); Thread.Sleep(1000); // Dirty workaround giving Windows some time to sync } if (!Directory.Exists(DebugDirectory)) { Directory.CreateDirectory(DebugDirectory); } if (!Directory.Exists(BotsData)) { Directory.CreateDirectory(BotsData); } DebugLog.AddListener(new Listener(null)); DebugLog.Enabled = true; textBoxCommandLine.AutoCompleteCustomSource.AddRange(Bot.CommandsKeys); notifyIconMain.Icon = System.Drawing.SystemIcons.Application; // TODO: Getting game from gleam.io }
public static async Task Main() { CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture; CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.InvariantCulture; AppDomain.CurrentDomain.UnhandledException += OnSillyCrashHandler; TaskScheduler.UnobservedTaskException += OnUnobservedTaskException; Console.Title = "Steam Database"; // Load settings file before logging as it can be enabled in settings await Settings.Load(); Log.WriteInfo(nameof(Bootstrapper), "Copyright (c) 2013-present, SteamDB. See LICENSE file for more information."); await Settings.Initialize(); DebugLog.AddListener(new Log.SteamKitLogger()); DebugLog.Enabled = true; Console.CancelKeyPress += OnCancelKey; await Application.Init(); Steam.Instance.Tick(); }
public static void Main() { Console.Title = "Steam Database"; var version = Assembly.GetExecutingAssembly().GetName().Version; var date = new DateTime(2000, 01, 01).AddDays(version.Build).AddSeconds(version.Revision * 2).ToUniversalTime().ToString(); Log.WriteInfo("Bootstrapper", "Steam Database backend application. Built on {0} UTC", date); Log.WriteInfo("Bootstrapper", "Copyright (c) 2013-2015, SteamDB. See LICENSE file for more information."); try { Settings.Load(); } catch (Exception e) { Log.WriteError("Settings", "{0}", e.Message); return; } ErrorReporter.Init(Settings.Current.BugsnagApiKey); if (Settings.Current.SteamKitDebug) { DebugLog.AddListener(new Log.SteamKitLogger()); DebugLog.Enabled = true; } AppDomain.CurrentDomain.UnhandledException += OnSillyCrashHandler; Console.CancelKeyPress += OnCancelKey; Application.Init(); }
public static async Task Main() { CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture; CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.InvariantCulture; AppDomain.CurrentDomain.UnhandledException += OnSillyCrashHandler; TaskScheduler.UnobservedTaskException += OnUnobservedTaskException; Console.Title = "Steam Database"; // Load settings file before logging as it can be enabled in settings await Settings.Load(); Log.WriteInfo(nameof(Bootstrapper), "Copyright (c) 2013-present, SteamDB. See LICENSE file for more information."); // Just create deepest folder we will use in the app var filesDir = Path.Combine(Application.Path, "files", ".support", "chunks"); Directory.CreateDirectory(filesDir); await Settings.Initialize(); await LocalConfig.Load(); DebugLog.AddListener(new Log.SteamKitLogger()); DebugLog.Enabled = true; Console.CancelKeyPress += OnCancelKey; await Application.Init(); Steam.Instance.Tick(); }
public static void startSteam(Boolean checkChanges, Boolean debug) { // Debug DebugLog.AddListener(new DebugListener()); DebugLog.Enabled = debug; // Setup client steamClient = new SteamClient(); manager = new CallbackManager(steamClient); steamUser = steamClient.GetHandler <SteamUser>(); steamApps = steamClient.GetHandler <SteamApps>(); steamFriends = steamClient.GetHandler <SteamFriends>(); // Callbacks manager.Subscribe <SteamClient.ConnectedCallback>(OnConnected); manager.Subscribe <SteamClient.DisconnectedCallback>(OnDisconnected); manager.Subscribe <SteamUser.LoggedOnCallback>(OnLoggedOn); manager.Subscribe <SteamUser.LoggedOffCallback>(OnLoggedOff); steamClient.Connect(); timer1 = new System.Timers.Timer(); timer1.Elapsed += RunWaitCallbacks; timer1.Interval = TimeSpan.FromSeconds(Config.isLocal() ? 1 : 10).TotalMilliseconds; timer1.Start(); if (checkChanges) { timer2 = new System.Timers.Timer(); timer2.Elapsed += CheckForChanges; timer2.Interval = TimeSpan.FromSeconds(Config.isLocal() ? 5 : 60).TotalMilliseconds; timer2.Start(); } }
public void WriteTimedLogsToStorage() { using (var stream = new MemoryStream()) { using (var logger = new TextWriterDebugListener(stream, Encoding.UTF8, true)) { DebugLog.AddListener(logger); // print any messages: DebugLog.WriteCoreLine("Message1"); DebugLog.WriteCoreLine("Message2"); logger.Flush(); using (var reader = new StreamReader(stream, Encoding.UTF8)) { stream.Position = 0; var logs = reader.ReadToEnd(); // check if the time info is in place: Assert.AreEqual(2, logs.IndexOf(':')); Assert.AreEqual(8, logs.IndexOf('.')); } } } }
public void DebugLogDebugListenerLogsMessage() { DebugLog.Enabled = true; DebugLog.AddListener(new TestListener()); DebugLog.WriteLine("category", "msg"); }
private static async Task InitGlobalDatabaseAndServices() { string globalDatabaseFile = Path.Combine(SharedInfo.ConfigDirectory, SharedInfo.GlobalDatabaseFileName); if (!File.Exists(globalDatabaseFile)) { ASF.ArchiLogger.LogGenericInfo(Strings.Welcome); await Task.Delay(10 * 1000).ConfigureAwait(false); ASF.ArchiLogger.LogGenericWarning(Strings.WarningPrivacyPolicy); await Task.Delay(5 * 1000).ConfigureAwait(false); } GlobalDatabase = await GlobalDatabase.Load(globalDatabaseFile).ConfigureAwait(false); if (GlobalDatabase == null) { ASF.ArchiLogger.LogGenericError(string.Format(Strings.ErrorDatabaseInvalid, globalDatabaseFile)); await Task.Delay(5 * 1000).ConfigureAwait(false); await Exit(1).ConfigureAwait(false); return; } if (Debugging.IsUserDebugging) { ASF.ArchiLogger.LogGenericDebug(SharedInfo.GlobalDatabaseFileName + ": " + JsonConvert.SerializeObject(GlobalDatabase, Formatting.Indented)); } // If debugging is on, we prepare debug directory prior to running if (GlobalConfig.Debug) { Logging.EnableTraceLogging(); if (Directory.Exists(SharedInfo.DebugDirectory)) { try { Directory.Delete(SharedInfo.DebugDirectory, true); await Task.Delay(1000).ConfigureAwait(false); // Dirty workaround giving Windows some time to sync } catch (IOException e) { ASF.ArchiLogger.LogGenericException(e); } } Directory.CreateDirectory(SharedInfo.DebugDirectory); DebugLog.AddListener(new Debugging.DebugListener()); DebugLog.Enabled = true; } WebBrowser.Init(); WebBrowser = new WebBrowser(ASF.ArchiLogger, GlobalConfig.WebProxy, true); if (GlobalConfig.IPC && (GlobalConfig.IPCPrefixes.Count > 0)) { IPC.Start(GlobalConfig.IPCPrefixes); } }
private static async Task InitGlobalDatabaseAndServices() { string globalDatabaseFile = ASF.GetFilePath(ASF.EFileType.Database); if (string.IsNullOrEmpty(globalDatabaseFile)) { ASF.ArchiLogger.LogNullError(nameof(globalDatabaseFile)); return; } if (!File.Exists(globalDatabaseFile)) { ASF.ArchiLogger.LogGenericInfo(Strings.Welcome); await Task.Delay(10 * 1000).ConfigureAwait(false); ASF.ArchiLogger.LogGenericWarning(Strings.WarningPrivacyPolicy); await Task.Delay(5 * 1000).ConfigureAwait(false); } GlobalDatabase globalDatabase = await GlobalDatabase.CreateOrLoad(globalDatabaseFile).ConfigureAwait(false); if (globalDatabase == null) { ASF.ArchiLogger.LogGenericError(string.Format(Strings.ErrorDatabaseInvalid, globalDatabaseFile)); await Task.Delay(5 * 1000).ConfigureAwait(false); await Exit(1).ConfigureAwait(false); return; } ASF.InitGlobalDatabase(globalDatabase); // If debugging is on, we prepare debug directory prior to running if (Debugging.IsUserDebugging) { ASF.ArchiLogger.LogGenericDebug(globalDatabaseFile + ": " + JsonConvert.SerializeObject(ASF.GlobalDatabase, Formatting.Indented)); Logging.EnableTraceLogging(); if (Directory.Exists(SharedInfo.DebugDirectory)) { try { Directory.Delete(SharedInfo.DebugDirectory, true); await Task.Delay(1000).ConfigureAwait(false); // Dirty workaround giving Windows some time to sync } catch (IOException e) { ASF.ArchiLogger.LogGenericException(e); } } Directory.CreateDirectory(SharedInfo.DebugDirectory); DebugLog.AddListener(new Debugging.DebugListener()); DebugLog.Enabled = true; } WebBrowser.Init(); }
static void Main(string[] args) { // install our debug listeners for this example // install an instance of our custom listener DebugLog.AddListener(new MyListener()); // install a listener as an anonymous method // this call is commented as it would be redundant to install a second listener that also displays messages to the console // DebugLog.AddListener( ( category, msg ) => Console.WriteLine( "AnonymousMethod - {0}: {1}", category, msg ) ); // Enable DebugLog in release builds DebugLog.Enabled = true; if (args.Length < 2) { Console.WriteLine("Sample4: No username and password specified!"); return; } // save our logon details user = args[0]; pass = args[1]; // create our steamclient instance steamClient = new SteamClient(); // create the callback manager which will route callbacks to function calls manager = new CallbackManager(steamClient); // get the steamuser handler, which is used for logging on after successfully connecting steamUser = steamClient.GetHandler <SteamUser>(); // register a few callbacks we're interested in // these are registered upon creation to a callback manager, which will then route the callbacks // to the functions specified new Callback <SteamClient.ConnectedCallback>(OnConnected, manager); new Callback <SteamClient.DisconnectedCallback>(OnDisconnected, manager); new Callback <SteamUser.LoggedOnCallback>(OnLoggedOn, manager); new Callback <SteamUser.LoggedOffCallback>(OnLoggedOff, manager); isRunning = true; Console.WriteLine("Connecting to Steam..."); // initiate the connection steamClient.Connect(); // create our callback handling loop while (isRunning) { // in order for the callbacks to get routed, they need to be handled by the manager manager.RunWaitCallbacks(TimeSpan.FromSeconds(1)); } }
public void DebugLogDoesntLogWhenDisabled() { DebugLog.Enabled = false; DebugLog.AddListener((category, msg) => { Assert.True(false, "Listener action called when it shouldn't have been"); }); DebugLog.WriteLine("category", "msg"); }
public void DebugLogCanWriteSafelyWithoutParams() { DebugLog.Enabled = true; DebugLog.AddListener((category, msg) => { Assert.Equal("category", category); Assert.Equal("msg{0}msg", msg); }); DebugLog.WriteLine("category", "msg{0}msg"); }
private static async Task InitASF(string[] args) { ASF.ArchiLogger.LogGenericInfo("ASF V" + SharedInfo.Version); await InitGlobalConfigAndLanguage().ConfigureAwait(false); if (!Runtime.IsRuntimeSupported) { ASF.ArchiLogger.LogGenericError(Strings.WarningRuntimeUnsupported); await Task.Delay(60 * 1000).ConfigureAwait(false); } await InitGlobalDatabaseAndServices().ConfigureAwait(false); // If debugging is on, we prepare debug directory prior to running if (GlobalConfig.Debug) { Logging.EnableTraceLogging(); if (Directory.Exists(SharedInfo.DebugDirectory)) { try { Directory.Delete(SharedInfo.DebugDirectory, true); await Task.Delay(1000).ConfigureAwait(false); // Dirty workaround giving Windows some time to sync } catch (IOException e) { ASF.ArchiLogger.LogGenericException(e); } } Directory.CreateDirectory(SharedInfo.DebugDirectory); DebugLog.AddListener(new Debugging.DebugListener()); DebugLog.Enabled = true; } // Parse post-init args if (args != null) { await ParsePostInitArgs(args).ConfigureAwait(false); } // If we ran ASF as a client, we're done by now if (Mode.HasFlag(EMode.Client) && !Mode.HasFlag(EMode.Server)) { await Exit().ConfigureAwait(false); } await ASF.CheckForUpdate().ConfigureAwait(false); await ASF.InitBots().ConfigureAwait(false); ASF.InitEvents(); }
public void DebugLogAddsAndRemovesListener() { var testListener = new TestListener(); DebugLog.AddListener(testListener); Assert.Contains(testListener, DebugLog.listeners); DebugLog.RemoveListener(testListener); Assert.DoesNotContain(testListener, DebugLog.listeners); }
public void DebugLogClearsListeners() { var testListener = new TestListener(); DebugLog.AddListener(testListener); Assert.Contains(testListener, DebugLog.listeners); DebugLog.ClearListeners(); Assert.DoesNotContain(testListener, DebugLog.listeners); }
public void DebugLogActionListenerLogsMessage() { DebugLog.Enabled = true; DebugLog.AddListener((category, msg) => { Assert.Equal("category", category); Assert.Equal("msg", msg); }); DebugLog.WriteLine("category", "msg"); }
public void Start(string[] args) { DebugLog.AddListener((category, msg) => Console.WriteLine("AnonymousMethod - {0}: {1}", category, msg)); DebugLog.Enabled = false; if (args.Length < 2) { Console.WriteLine("Sample1: No username and password specified!"); return; } // save our logon details user = args[0]; pass = args[1]; // create our steamclient instance steamClient = new SteamClient(); // create the callback manager which will route callbacks to function calls manager = new CallbackManager(steamClient); // get the steamuser handler, which is used for logging on after successfully connecting steamUser = steamClient.GetHandler <SteamUser>(); // get the steam friends handler, which is used for interacting with friends on the network after logging on steamFriends = steamClient.GetHandler <SteamFriends>(); gameCoordinator = steamClient.GetHandler <SteamGameCoordinator>(); manager.Subscribe <SteamGameCoordinator.MessageCallback>(OnGCMessage); // register a few callbacks we're interested in // these are registered upon creation to a callback manager, which will then route the callbacks // to the functions specified manager.Subscribe <SteamClient.ConnectedCallback>(OnConnected); manager.Subscribe <SteamClient.DisconnectedCallback>(OnDisconnected); manager.Subscribe <SteamUser.LoggedOnCallback>(OnLoggedOn); manager.Subscribe <SteamUser.LoggedOffCallback>(OnLoggedOff); isRunning = true; Console.WriteLine("Connecting to Steam..."); // initiate the connection steamClient.Connect(); // create our callback handling loop while (isRunning) { // in order for the callbacks to get routed, they need to be handled by the manager manager.RunWaitCallbacks(TimeSpan.FromSeconds(1)); } }
public void LoadHttpData() { var request = new HttpDataSource("https://www.google.com?q=a"); var waiter = new AsyncWaiter(); var filter = new FilterDebugListener("Filter HttpDataSource", "Core.HttpDataSource"); DebugLog.AddListener(filter); request.SendRequestAsync(HttpDataSource.MethodGet, HttpDataSourceResponseType.AsString); Assert.AreEqual(WaiterResults.Success, waiter.Wait(10, request), "Couldn't load data"); Assert.AreNotEqual(0, filter.Count, "Invalid number of captured log messages!"); }
public FileTrace() { DebugLog.AddListener(this); try { lock ( logLock ) { File.AppendAllText(LogFile, Environment.NewLine + Environment.NewLine); File.AppendAllText(LogFile, string.Format("New log started on {0} at {1}" + Environment.NewLine, DateTime.Now.ToLongDateString(), DateTime.Now.ToLongTimeString())); } } catch { } }
public void DebugLogFormatsParams() { DebugLog.Enabled = true; DebugLog.AddListener((category, msg) => { Assert.Equal("category", category); Assert.Equal("msg1msg2", msg); }); var msgText = "msg"; var integer = 2; DebugLog.WriteLine("category", "msg{0}{1}{2}", 1, msgText, integer); }
public Steam() { DebugLog.AddListener(new SteamKitLogger()); DebugLog.Enabled = true; Client = new SteamClient(); User = Client.GetHandler <SteamUser>(); Apps = Client.GetHandler <SteamApps>(); CallbackManager = new CallbackManager(Client); CallbackManager.Subscribe <SteamClient.ConnectedCallback>(OnConnected); CallbackManager.Subscribe <SteamClient.DisconnectedCallback>(OnDisconnected); CallbackManager.Subscribe <SteamUser.LoggedOnCallback>(OnLoggedOn); CallbackManager.Subscribe <SteamUser.LoggedOffCallback>(OnLoggedOff); CallbackManager.Subscribe <SteamApps.PICSChangesCallback>(OnPICSChanges); }
public void FilterSelectedLogItems() { var listener1 = new CustomDebugListener(); var listener2 = new CustomDebugListener(); var forward = new ForwardDebugListener("Forward", listener1, null, new[] { "Cat1", "Cat2", "Cat3" }); DebugLog.AddListener(forward); DebugLog.AddListener(listener2); DebugLog.WriteLine("Cat1", "Message1"); DebugLog.WriteLine("Cat1.Sub", "Message2"); DebugLog.WriteLine("Cat3.Send", "Message3"); DebugLog.WriteLine("AnySend", "Message4"); // +1 DebugLog.WriteLine("Core", "Message5"); // +1 Assert.AreEqual(2, listener1.Count); Assert.AreEqual(5, listener2.Count); }
public void CustomCMClientIDPrefixed() { DebugLog.Enabled = true; string category = default; string message = default; DebugLog.AddListener((cat, msg) => { category = cat; message = msg; }); var client = new SteamClient("My Custom Client"); client.LogDebug("MyCategory", "My {0}st message", 1); Assert.Equal("My Custom Client/MyCategory", category); Assert.Equal("My 1st message", message); }
public static void Main() { Console.Title = "Steam Database"; var version = FileVersionInfo.GetVersionInfo(typeof(Steam).Assembly.Location); ProductVersion = version.ProductVersion; Log.WriteInfo("Bootstrapper", "Steam Database, built from commit: {0}", ProductVersion); Log.WriteInfo("Bootstrapper", "Copyright (c) 2013-2015, SteamDB. See LICENSE file for more information."); try { // Just create deepest folder we will use in the app string filesDir = Path.Combine(Application.Path, "files", ".support", "chunks"); Directory.CreateDirectory(filesDir); Settings.Load(); LocalConfig.Load(); } catch (Exception e) { Log.WriteError("Settings", "{0}", e.Message); return; } ErrorReporter.Init(Settings.Current.BugsnagApiKey); if (Settings.Current.SteamKitDebug) { DebugLog.AddListener(new Log.SteamKitLogger()); DebugLog.Enabled = true; } AppDomain.CurrentDomain.UnhandledException += OnSillyCrashHandler; Console.CancelKeyPress += OnCancelKey; Application.Init(); }
public static void Main(string[] args) { if (FindArg(args, "-debug")) { DebugLog.AddListener(new ConsoleDebugListener()); TraceDialog td = new TraceDialog(); td.Show(); FileTrace ft = new FileTrace(); } try { Start(args); } catch (Exception ex) { new ErrorDialog(ex).ShowDialog(); } }
public void FowardSelectedLogItems() { var listener1 = new CustomDebugListener(); var listener2 = new CustomDebugListener(); var forward = new ForwardDebugListener("Forward", listener1, new[] { "Cat1", "Cat2", "Cat3" }); DebugLog.AddListener(forward); DebugLog.AddListener(listener2); DebugLog.WriteLine("Cat1.Send", "Message1"); // +1 DebugLog.WriteLine("Cat2", "Message2"); // +1 DebugLog.WriteLine("Cat3", "Message3"); // +1 DebugLog.WriteLine("Cat3.XRunner", "Message3"); // +1 DebugLog.WriteLine("C1", "Message4"); DebugLog.WriteLine("Cat4", "Message5"); DebugLog.WriteLine("Cat5.Cat1", "Message5"); Assert.AreEqual(4, listener1.Count); Assert.AreEqual(7, listener2.Count); }