I am programming a discord bot in Discord .NET 0.9 and I get a stack overflow error when I try to run it. The problem a occurs when I make a instance of my Program.cs in my Functions.cs
My Program.cs:
using System;
using System.Linq;
using Discord;
using Discord.Commands;
using System.IO;
using fatobg;
namespace fatobg
{
class Program
{
CommandManager cm = new CommandManager();
public static Program _instance = new Program();
static void Main(string[] args)
{
new Program().Start();
}
public DiscordClient _client;
public void Start()
{
Console.Title = "Matchmaking Discord BOT";
_client = new DiscordClient(x =>
{
x.AppName = "Gerry";
x.AppUrl = "www.google.com";
x.LogLevel = LogSeverity.Info;
x.LogHandler = Log;
});
_client.UsingCommands(x =>
{
x.PrefixChar = '?';
x.AllowMentionPrefix = true;
x.HelpMode = HelpMode.Public;
});
var token = "Changed";
cm.Commands(_client);
onJoin();
_client.ExecuteAndWait(async () =>
{
await _client.Connect(token, TokenType.Bot);
setGame(_client, "?help");
});
}
public void setGame(DiscordClient _client, string game)
{
_client.SetGame(game);
}
public void onJoin()
{
_client.UserJoined += async (s, e) =>
{
await e.Server.GetChannel(318558393759694849).SendMessage($":loudspeaker: | Everyone welcome {e.User.Mention} to the server!");
};
}
public void Log(Object sender, LogMessageEventArgs e)
{
Console.WriteLine($"[{e.Severity}] [{e.Source}] {e.Message}");
}
}
}
My CommandManager.cs:
using System;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading.Tasks;
using Discord;
using System.Net.Http;
using Discord.Commands;
using System.Text.RegularExpressions;
using System.Xml.Serialization;
using System.IO;
using System.Threading;
using MySql.Data;
using MySql.Data.MySqlClient;
namespace fatobg
{
class CommandManager
{
public static CommandManager _instance = new CommandManager();
Functions function = new Functions();
public void Commands(DiscordClient _client)
{
var cService = _client.GetService<CommandService>();
cService.CreateCommand("say")
.Description("returns commands")
.Parameter("message", ParameterType.Unparsed)
.Do(async (e) =>
{
Message[] messageToDelete;
int deleteNumber = 1;
messageToDelete = await e.Channel.DownloadMessages(deleteNumber);
await e.Channel.DeleteMessages(messageToDelete);
var toReturn = $":envelope: | {e.GetArg("message")}";
await e.Channel.SendMessage(toReturn);
Console.WriteLine(toReturn);
});
cService.CreateCommand("updatedb")
.Description("updates database")
.Do(async (e) =>
{
Message[] messageToDelete; //deletes command
int deleteNumber = 1;
messageToDelete = await e.Channel.DownloadMessages(deleteNumber);
await e.Channel.DeleteMessages(messageToDelete);
try
{
if (e.User.ServerPermissions.Administrator)
{
foreach (User user in e.Server.Users)
{
if(!user.IsBot)
function.UpdateDB(user);
}
var toReturn = $":white_check_mark: | Done updateing the database. {e.User.Mention}";
await e.Channel.SendMessage(toReturn);
Console.WriteLine(toReturn);
}
else
{
var toReturn = $":exclamation: | Get out of here {e.User.Mention} you have no power over me!";
await e.Channel.SendMessage(toReturn);
Console.WriteLine(toReturn);
}
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex);
}
});
cService.CreateCommand("duo")
.Description("returns commands")
.Do(async (e) =>
{
Message[] messageToDelete;
int deleteNumber = 1;
messageToDelete = await e.Channel.DownloadMessages(deleteNumber);
await e.Channel.DeleteMessages(messageToDelete);
});
cService.CreateCommand("yamikage")
.Description("Animated gingy")
.Do(async (e) =>
{
Message[] messageToDelete;
int deleteNumber = 1;
messageToDelete = await e.Channel.DownloadMessages(deleteNumber);
await e.Channel.DeleteMessages(messageToDelete);
await e.Channel.SendFile("Gifs/gingy.gif");
Console.WriteLine("Send epic gingy meme");
});
}
}
}
My Functions.cs:
using Discord;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace fatobg
{
class Functions
{
Program main = new Program();
public void UpdateDB(User user)
{
if (File.Exists(#"D:\Databases\DiscordUsers\" + user.Id + ".duser"))
{
System.IO.File.Delete(#"D:\Databases\DiscordUsers\" + user.Id + ".duser");
string[] Data = { user.Name, Roles(user) };
System.IO.File.WriteAllLines(#"D:\Databases\DiscordUsers\" + user.Id + ".duser", Data);
}
else
{
string[] Data = { user.Name, Roles(user) };
System.IO.File.WriteAllLines(#"D:\Databases\DiscordUsers\" + user.Id + ".duser", Data);
}
}
public string Roles(User user)
{
string toreturn = string.Empty;
foreach (Role role in user.Roles)
{
if (role.Name!="Admin"||role.Name!="Mod"||role.Name!="#everyone")
{
toreturn += role.Name + "|";
}
}
return toreturn;
}
public string GetUsername(string uid)
{
if (File.Exists(#"D:\Databases\DiscordUsers\" + uid + ".duser"))
{
string[] Data = File.ReadAllLines(#"D:\Databases\DiscordUsers\" + uid + ".duser");
return Data[0];
}
else
{
return null;
}
}
public void AddToQueue(User user)
{
List<User> NA = new List<User>();
List<User> EU = new List<User>();
List<User> OC = new List<User>();
List<User> AS = new List<User>();
List<User> SA = new List<User>();
Server server = main._client.FindServers("Find A Team On Battlegrounds (Bot Testing)").FirstOrDefault();
User usr = server.FindUsers(user.Name).FirstOrDefault();
if (File.Exists(#"D:\Databases\Duo.queue"))
{
string[] UData = System.IO.File.ReadAllLines(#"D:\Databases\Duo.queue");
System.IO.File.Delete(#"D:\Databases\Duo.queue");
foreach(String uid in UData)
{
User tempuser = user.Server.FindUsers(GetUsername(uid)).FirstOrDefault();
List<Role> roles = tempuser.Roles.ToList();
foreach(Role role in roles)
{
if (role.Name == "[NA]")
NA.Add(tempuser);
else if (role.Name == "[EU]")
EU.Add(tempuser);
else if (role.Name == "[OC]")
OC.Add(tempuser);
else if (role.Name == "[AS]")
AS.Add(tempuser);
else if (role.Name == "[SA]")
SA.Add(tempuser);
}
}
List<Role> uroles = usr.Roles.ToList();
foreach (Role role in uroles)
{
if (role.Name == "[NA]")
NA.Add(usr);
else if (role.Name == "[EU]")
EU.Add(usr);
else if (role.Name == "[OC]")
OC.Add(usr);
else if (role.Name == "[AS]")
AS.Add(usr);
else if (role.Name == "[SA]")
SA.Add(usr);
}
File.WriteAllLines(#"D:\Databases\Duo.queue", UData);
File.AppendAllText(#"D:\Databases\Duo.queue", usr.Id.ToString() + Environment.NewLine);
if (NA.Count == 2)
{
server.GetChannel(319281246746312714).SendMessage($":exclamation: | A new team has been found for NA servers. {NA[0].Mention} and {NA[1].Mention} prepare to fight.");
string[] Data = System.IO.File.ReadAllLines(#"D:\Databases\Duo.queue");
System.IO.File.Delete(#"D:\Databases\Duo.queue");
foreach (String id in Data)
{
if(id!=NA[0].Id.ToString()&&id!=NA[1].Id.ToString())
File.AppendAllText(#"D:\Databases\Duo.queue", id + Environment.NewLine);
}
NA.Clear();
}
else if (EU.Count == 2){
server.GetChannel(319281246746312714).SendMessage($":exclamation: | A new team has been found for EU servers. {EU[0].Mention} and {EU[1].Mention} prepare to fight.");
string[] Data = System.IO.File.ReadAllLines(#"D:\Databases\Duo.queue");
System.IO.File.Delete(#"D:\Databases\Duo.queue");
foreach (String id in Data)
{
if (id!=EU[0].Id.ToString()&&id!=EU[1].Id.ToString())
File.AppendAllText(#"D:\Databases\Duo.queue", id + Environment.NewLine);
}
EU.Clear();
}
else if (OC.Count == 2)
{
server.GetChannel(319281246746312714).SendMessage($":exclamation: | A new team has been found for OC servers. {OC[0].Mention} and {OC[1].Mention} prepare to fight.");
string[] Data = System.IO.File.ReadAllLines(#"D:\Databases\Duo.queue");
System.IO.File.Delete(#"D:\Databases\Duo.queue");
foreach (String id in Data)
{
if (id!=OC[0].Id.ToString()&&id!=OC[1].Id.ToString())
File.AppendAllText(#"D:\Databases\Duo.queue", id + Environment.NewLine);
}
OC.Clear();
}
else if (AS.Count == 2)
{
server.GetChannel(319281246746312714).SendMessage($":exclamation: | A new team has been found for AS servers. {AS[0].Mention} and {AS[1].Mention} prepare to fight.");
string[] Data = System.IO.File.ReadAllLines(#"D:\Databases\Duo.queue");
System.IO.File.Delete(#"D:\Databases\Duo.queue");
foreach (String id in Data)
{
if (id != AS[0].Id.ToString() && id != AS[1].Id.ToString())
File.AppendAllText(#"D:\Databases\Duo.queue", id + Environment.NewLine);
}
AS.Clear();
}
else if (SA.Count == 2)
{
server.GetChannel(319281246746312714).SendMessage($":exclamation: | A new team has been found for SA servers. {SA[0].Mention} and {SA[1].Mention} prepare to fight.");
string[] Data = System.IO.File.ReadAllLines(#"D:\Databases\Duo.queue");
System.IO.File.Delete(#"D:\Databases\Duo.queue");
foreach (String id in Data)
{
if (id != SA[0].Id.ToString()&&id!=SA[1].Id.ToString())
File.AppendAllText(#"D:\Databases\Duo.queue", id + Environment.NewLine);
}
SA.Clear();
}
}
else
{
File.AppendAllText(#"D:\Databases\Duo.queue", usr.Id.ToString() + Environment.NewLine);
}
}
}
}
This is what happens:
Instantiate Program;
Program instantiates CommandManager;
CommandManager instantiates Functions;
Functions instantiates Program;
Return to 1.
What you should do:
Pass along an instance of Program to CommandManager and Functions. In that way, you have no circular reference any more.
For example your Functions class should start with this:
class Functions
{
Program main;
public Functions(Program p)
{
this.main = p;
}
And your CommandManager:
class CommandManager
{
Program main;
Functions function;
public CommandManager(Program p)
{
this.main = p;
this.function = new Function(p);
}
Related
I have an app with two HamburgerMenuButtons: TYMLY and NEWTYMLY. TYMLY is the mainpage. I am using the Template10 MVVM. On the startup It navigates to the TYMLY page as required, I tap on the NEWTYMLY page and proceed to carryout some tasks to create a Object that is meant to be added to the Griview in the TYMLY mainpage. In the PageHeader section I have a button that is meant to save this object and proceed to Navigate to the TYMLY mainpage and add the object to the Gridview.
Anytime I press this button I get the System.NullException on the following line:
public void SaveNewTymly() =>
NavigationService.Navigate(typeof(Views.MainPage), New_Tymly);
I also noticed the System.NullException als ooccures if I press other buttons that come with the template like Settings, Privacy and About Us;
public void GotoSettings() =>
NavigationService.Navigate(typeof(Views.SettingsPage), 0);
public void GotoPrivacy() =>
NavigationService.Navigate(typeof(SettingsPage), 1);
public void GotoAbout() =>
NavigationService.Navigate(typeof(Views.SettingsPage), 2);
I want to know how I am to handle Navigation in this case.
Thank you.
MainPage
NewPage to create object to add to the gridview in the mainpage
NewTymlyModel.cs
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using Template10.Mvvm;
using Template10.Services.NavigationService;
using Tymly_Revamped.Models;
using Tymly_Revamped.Views;
using Windows.UI.Xaml.Navigation;
namespace Tymly_Revamped.ViewModels
{
class NewTymlyViewModel : ViewModelBase
{
private Tymly newTymly;
public Tymly New_Tymly { get { return newTymly; } set { Set(ref newTymly, value); } }
bool trafficFlow;
public NewTymlyViewModel()
{
newTymly = new Tymly();
}
public override async Task OnNavigatedToAsync(object parameter, NavigationMode mode, IDictionary<string, object> suspensionState)
{
New_Tymly = (suspensionState.ContainsKey(nameof(New_Tymly))) ? suspensionState[nameof(New_Tymly)] as Tymly : parameter as Tymly;
await Task.CompletedTask;
}
public override async Task OnNavigatedFromAsync(IDictionary<string, object> suspensionState, bool suspending)
{
if (suspending)
{
suspensionState[nameof(New_Tymly)] = New_Tymly;
}
await Task.CompletedTask;
}
public bool TrafficFlow
{
get { return trafficFlow; Debug.WriteLine(trafficFlow); }
set { trafficFlow = !trafficFlow; }
}
public override async Task OnNavigatingFromAsync(NavigatingEventArgs args)
{
args.Cancel = false;
await Task.CompletedTask;
}
public void SaveNewTymly() =>
NavigationService.Navigate(typeof(Views.MainPage), New_Tymly);
public void GotoSettings() =>
NavigationService.Navigate(typeof(Views.SettingsPage), 0);
public void GotoPrivacy() =>
NavigationService.Navigate(typeof(SettingsPage), 1);
public void GotoAbout() =>
NavigationService.Navigate(typeof(Views.SettingsPage), 2);
}
}
using NodaTime.TimeZones;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Windows.Devices.Geolocation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Maps;
using Tymly_Revamped.Models;
using Tymly_Revamped.ViewModels;
using Tymly_Revamped.Views;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Markup;
using System.Collections.ObjectModel;
using Windows.ApplicationModel.Contacts;
using System.IO;
using System.Diagnostics;
using Windows.Storage.Streams;
using Windows.UI.Xaml.Media.Imaging;
namespace Tymly_Revamped.Views
{
public sealed partial class NewTymly : Page
{
private uint desiredAccuracy_meters = 0;
private CancellationTokenSource cancelTokenSrc = null;
private IEnumerable<string> zonalIds;
IReadOnlyList<GetContactDetails> condetails;
public IReadOnlyList<GetContactDetails> ConDetails { get { return condetails; } set { condetails = value; } }
ObservableCollection<GetContactDetails> contacts;
public ObservableCollection<GetContactDetails> Contacts { get { return contacts; } set { contacts = value; } }
public NewTymly()
{
this.InitializeComponent();
NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled;
DataContext = new NewTymlyViewModel();
searchLocation.Loaded += Map_Loaded;
searchLocation.MapTapped += Map_Tapped;
searchLocation.MapDoubleTapped += Map_DoubledTapped;
searchLocation.Style = MapStyle.Road;
}
private void Map_DoubledTapped(MapControl sender, MapInputEventArgs args)
{
throw new NotImplementedException();
}
private void Map_Tapped(MapControl sender, MapInputEventArgs args)
{
var tappedPositon = args.Location.Position;
if (sender.ZoomLevel < 20)
{
sender.ZoomLevel += 2;
}
else if (sender.ZoomLevel >= 20)
{
sender.ZoomLevel = 12;
}
}
private async void Map_Loaded(object sender, RoutedEventArgs e)
{
try
{
var requestLocationAccess = await Geolocator.RequestAccessAsync();
switch (requestLocationAccess)
{
case GeolocationAccessStatus.Allowed:
cancelTokenSrc = new CancellationTokenSource();
CancellationToken token = cancelTokenSrc.Token;
Geolocator geolocator = new Geolocator { DesiredAccuracyInMeters = desiredAccuracy_meters };
Geoposition pos = await geolocator.GetGeopositionAsync().AsTask(token);
searchLocation.Center =
new Geopoint(new BasicGeoposition()
{
Latitude = pos.Coordinate.Point.Position.Latitude,
Longitude = pos.Coordinate.Point.Position.Longitude
});
searchLocation.ZoomLevel = 1;
break;
}
}
catch (TaskCanceledException)
{
throw new TaskCanceledException();
}
finally
{
cancelTokenSrc = null;
}
}
private async void ShowOnMap(double lati, double longi)
{
try
{
var accessLocation = await Geolocator.RequestAccessAsync();
switch (accessLocation)
{
case GeolocationAccessStatus.Allowed:
cancelTokenSrc = new CancellationTokenSource();
CancellationToken token = cancelTokenSrc.Token;
Geolocator geolocator = new Geolocator { DesiredAccuracyInMeters = desiredAccuracy_meters };
Geoposition pos = await geolocator.GetGeopositionAsync().AsTask(token);
searchLocation.Center =
new Geopoint(new BasicGeoposition()
{
Latitude = lati,
Longitude = longi,
});
searchLocation.ZoomLevel = 5;
break;
}
}
catch (TaskCanceledException)
{
}
finally
{
cancelTokenSrc = null;
}
}
private void styleCombobox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
switch (mapStyle.SelectedIndex)
{
case 0:
searchLocation.Style = MapStyle.None;
break;
case 1:
searchLocation.Style = MapStyle.Road;
break;
case 2:
searchLocation.Style = MapStyle.Aerial;
break;
case 3:
searchLocation.Style = MapStyle.AerialWithRoads;
break;
case 4:
searchLocation.Style = MapStyle.Terrain;
break;
}
}
public void InputLocation_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
{
if (args.Reason == AutoSuggestionBoxTextChangeReason.UserInput)
{
zonalIds = TzdbDateTimeZoneSource.Default.ZoneLocations.
Where(loc => loc.CountryName.IndexOf(sender.Text, StringComparison.CurrentCultureIgnoreCase) > -1).
Select(loc => loc.ZoneId);
sender.ItemsSource = zonalIds.ToList();
}
}
public void InputLocation_QuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
{
MapGlyphs mapGlyph = new MapGlyphs();
if (args.ChosenSuggestion != null)
{
var selectedZonalId = args.ChosenSuggestion as string;
string state = selectedZonalId.Remove(0, selectedZonalId.IndexOf("/") + 1).Replace("_", " ");
var country = TzdbDateTimeZoneSource.Default.ZoneLocations.
Where(zoneloc => zoneloc.ZoneId == selectedZonalId).Select(zoneloc => zoneloc.CountryName).
ElementAtOrDefault(0);
var timeZone = TzdbDateTimeZoneSource.Default.ZoneLocations.
Where(tym => tym.ZoneId == selectedZonalId).Select(tymZone => TzdbDateTimeZoneSource.Default.WindowsMapping.
MapZones.FirstOrDefault(tym => tym.TzdbIds.Contains(selectedZonalId))).
Where(tym => tym != null).Select(tym => tym.WindowsId).Distinct();
var lattitude = TzdbDateTimeZoneSource.Default.ZoneLocations.
Where(lat => lat.ZoneId == selectedZonalId).Select(tym => tym.Latitude);
var longitude = TzdbDateTimeZoneSource.Default.ZoneLocations.
Where(lon => lon.ZoneId == selectedZonalId).Select(tym => tym.Longitude);
if (timeZone.Count() != 0)
{
var dateTime = TimeZoneInfo.ConvertTime(
DateTime.Now, TimeZoneInfo.FindSystemTimeZoneById(timeZone.ElementAt(0)));
if (mapGlyph.PlaceIcon.ContainsKey(state))
{
locationText.Text = state;
ViewModel.New_Tymly.Location = state;
ViewModel.New_Tymly.MapIcon = mapGlyph.MapLocationIcon(state);
}
else
{
locationText.Text = country;
ViewModel.New_Tymly.Location = country;
ViewModel.New_Tymly.MapIcon = mapGlyph.MapLocationIcon(country);
}
dateText.Text = dateTime.ToString("D");
timeText.Text = dateTime.ToString("T");
ViewModel.New_Tymly.Datetime = dateTime;
IconPath.Data = PathMarkupToGeometry(ViewModel.New_Tymly.MapIcon);
}
else
{
}
ShowOnMap(lattitude.ElementAt(0), longitude.ElementAt(0));
}
}
public void InputLocation_SuggestionChosen(AutoSuggestBox sender, AutoSuggestBoxSuggestionChosenEventArgs args)
{
MapGlyphs mapGlyph = new MapGlyphs();
var place = args.SelectedItem as string;
string state = place.Remove(0, place.IndexOf("/") + 1).Replace("_", " ");
var country = TzdbDateTimeZoneSource.Default.ZoneLocations.
Where(zoneloc => zoneloc.ZoneId == place).Select(zoneloc => zoneloc.CountryName).
ElementAtOrDefault(0);
var timeZone = TzdbDateTimeZoneSource.Default.ZoneLocations.
Where(x => x.ZoneId == place).Select(tz => TzdbDateTimeZoneSource.Default.WindowsMapping.
MapZones.FirstOrDefault(x => x.TzdbIds.Contains(place))).
Where(x => x != null).Select(x => x.WindowsId).Distinct();
var latitude = TzdbDateTimeZoneSource.Default.ZoneLocations.
Where(x => x.ZoneId == place).Select(tz => tz.Latitude);
var longitude = TzdbDateTimeZoneSource.Default.ZoneLocations.
Where(x => x.ZoneId == place).Select(tz => tz.Longitude);
if (timeZone.Count() != 0)
{
var dateTime = TimeZoneInfo.ConvertTime(
DateTime.Now, TimeZoneInfo.FindSystemTimeZoneById(timeZone.ElementAt(0)));
if (mapGlyph.PlaceIcon.ContainsKey(state))
{
locationText.Text = state;
ViewModel.New_Tymly.Location = state;
ViewModel.New_Tymly.MapIcon = mapGlyph.MapLocationIcon(state);
}
else
{
locationText.Text = country;
ViewModel.New_Tymly.Location = country;
ViewModel.New_Tymly.MapIcon = mapGlyph.MapLocationIcon(country);
}
dateText.Text = dateTime.ToString("D");
timeText.Text = dateTime.ToString("T");
ViewModel.New_Tymly.Datetime = dateTime;
IconPath.Data = PathMarkupToGeometry(ViewModel.New_Tymly.MapIcon);
}
else
{
}
ShowOnMap(latitude.ElementAt(0), longitude.ElementAt(0));
}
Geometry PathMarkupToGeometry(string pathMarkup)
{
string xaml =
"<Path " +
"xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>" +
"<Path.Data>" + pathMarkup + "</Path.Data></Path>";
var path = XamlReader.Load(xaml) as Windows.UI.Xaml.Shapes.Path;
// Detach the PathGeometry from the Path
Geometry geometry = path.Data;
path.Data = null;
return geometry;
}
private async void AddContacts(object sender, RoutedEventArgs e)
{
var contactPicker = new ContactPicker();
contactPicker.DesiredFieldsWithContactFieldType.Add(ContactFieldType.Email);
contactPicker.DesiredFieldsWithContactFieldType.Add(ContactFieldType.PhoneNumber);
var selectedContacts = await contactPicker.PickContactsAsync();
ContactStore contactStore = await ContactManager.RequestStoreAsync(ContactStoreAccessType.AllContactsReadOnly);
if (selectedContacts != null && selectedContacts.Count > 0)
{
foreach (var item in selectedContacts)
{
Contact realContact = await contactStore.GetContactAsync(item.Id);
ViewModel.New_Tymly.ContactList.Add(new ContactItemAdapter(realContact));
var t = new ContactItemAdapter(realContact).Thumbnail;
Debug.WriteLine(t);
}
}
}
private void DeleteContact(object sender, RoutedEventArgs e)
{
ContactItemAdapter item = (ContactItemAdapter)(sender as Button).DataContext;
Debug.WriteLine(item.Name);
if (addContacts.Items.Contains(item))
{
ViewModel.New_Tymly.ContactList.Remove(item);
}
}
}
}
I'm making an internal user inactivity monitor for work, and I'm using a windows form in conjunction with a topshelf service to do this, the code will write to a RabbitMQ Server and the service will consume the messages and forward them to a database, my code as it stands is throwing an exception with the following error;
Missing type map configuration or unsupported mapping.
Mapping types:
LogData -> DbLogData
AccessEye.LogData -> AccessEye.DbLogData
this is the code for my service
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using NLog;
using IWshRuntimeLibrary;
using Topshelf;
using System.Data.Odbc;
using EasyNetQ;
using RabbitMQ;
using EasyNetQ.Topology;
using System.Threading.Tasks;
using System.Windows.Forms;
using AccessEye;
using System.ComponentModel;
namespace LogService
{
public class WindowsServiceHost : ServiceControl, ServiceShutdown
{
public static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public static void WriteLogDataToDb(LogData data)
{
using (var db = new LogService.UserActivityDataContext())
{
DbLogData logData = AutoMapper.Mapper.Map<LogData, DbLogData>(data);
int t = (int)data.EventType;
EventType eventType = db.EventTypes.FirstOrDefault(r => r.Id == t);
if (eventType == null)
{
eventType = db.EventTypes.Add(new EventType
{
Event = GetEnumDescriptionAttributeValue(data.EventType),
Id = (int)data.EventType
});
db.SaveChanges();
}
logData.EventTypeId = eventType.Id;
db.LogEvents.Add(logData);
db.SaveChanges();
}
}
public static string GetEnumDescriptionAttributeValue(Enum value)
{
var fieldInfo = value.GetType().GetField(value.ToString());
var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
return attributes.Length > 0 ? attributes[0].Description : value.ToString();
}
public bool Start(HostControl hostControl)
{
Program.bus = RabbitHutch.CreateBus("host=*****;virtualHost=*****;username=***;password=***").Advanced;
//var bus = RabbitHutch.CreateBus("host=*******;virtualHost=******;username=****;password=******").Advanced;
var queue = Queue.Declare(true, false, true, null);
var exchange = Exchange.DeclareFanout("UserActivityFanout", true, false, null);
var exchangeTopic = Exchange.DeclareTopic("UserActivity", true, false, null);
queue.BindTo(exchange, "#");
exchange.BindTo(exchangeTopic, "#");
Program.bus.Subscribe<AccessEye.LogData>(queue, (msg, messageRecInfo) => Task.Factory.StartNew(() =>
{
var data2 = LogDataFactory.CollectData();
data2.EventType = AccessEye.UserStateEvents.Logon;
WriteLogDataToDb(data2);
//AppForm.WriteLogDataToDb(data);
//Console.WriteLine(msg.Body.UserName + " -- " + msg.Body.ComputerName + " -- " + msg.Body.EventType + " -- " + msg.Body.TeamviewerId);
}));
return true;
}
public bool Stop(HostControl hostControl)
{
Logger.Trace("STOP");
Program.bus.Dispose();
return true;
}
public void Shutdown(HostControl hostControl)
{
Logger.Trace("SHUTDOWN");
Program.bus.Dispose();
}
}
}
and for the form
using System;
using System.IO;
using System.Windows.Forms;
using System.ComponentModel;
using AccessEye;
using System.Linq;
using EasyNetQ;
using EasyNetQ.Topology;
using Microsoft.Win32;
using MySql.Data.MySqlClient;
using NLog;
using ProtoBuf;
using System.Threading;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Runtime.InteropServices;
using System.Reflection;
namespace LogProgram
{
public partial class AppForm : Form
{
public static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private Screensaver watcher;
public Inactivity inactivity;
IAdvancedBus bus;
IExchange exchange;
public AppForm()
{
InitializeComponent();
ConfigureForm();
// todo: should be in setting
int pollingInterval = 5000;
inactivity = new Inactivity(pollingInterval);
inactivity.Inactive += inactivity_Inactive;
inactivity.Active += inactivity_Active;
inactivity.InactivityThresholdMs = 5 * 1000; // todo: should be in setting
inactivity.Start();
watcher = new Screensaver(pollingInterval);
watcher.ScreensaverOff += watcher_ScreensaverOff;
watcher.ScreensaverOn += watcher_ScreensaverOn;
watcher.Start();
SystemEvents.SessionEnding += SystemEvents_SessionEnding;
SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
LogManager.ThrowExceptions = true;
// todo: connection string should be in setting
bus = RabbitHutch.CreateBus("host=as01.access.local;virtualHost=DEV-Reece;username=reece;password=reece").Advanced;
exchange = Exchange.DeclareTopic("UserActivity", true, false, null);
var fanout = Exchange.DeclareFanout("FanoutExchange", true, false, null);
fanout.BindTo(exchange, new[] { "#" });
}
public void ConfigureForm()
{
this.Hide();
TrayDisplayer.Visible = false;
}
public static void WriteLogDataToDb(LogData data)
{
using (var db = new LogService.UserActivityDataContext())
{
DbLogData logData = AutoMapper.Mapper.Map<LogData, DbLogData>(data);
int t = (int)data.EventType;
EventType eventType = db.EventTypes.FirstOrDefault(r => r.Id == t);
if (eventType == null)
{
eventType = db.EventTypes.Add(new EventType
{
Event = GetEnumDescriptionAttributeValue(data.EventType),
Id = (int)data.EventType
});
db.SaveChanges();
}
logData.EventTypeId = eventType.Id;
db.LogEvents.Add(logData);
db.SaveChanges();
}
}
public static string GetEnumDescriptionAttributeValue(Enum value)
{
var fieldInfo = value.GetType().GetField(value.ToString());
var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
return attributes.Length > 0 ? attributes[0].Description : value.ToString();
}
private void AppForm_Load(object sender, EventArgs e)
{
}
void watcher_ScreensaverOn(object sender, EventArgs e)
{
var data = LogDataFactory.CollectData();
data.EventType = AccessEye.UserStateEvents.ScreensaverOn;
PublishLogData(data);
}
void watcher_ScreensaverOff(object sender, EventArgs e)
{
var data = LogDataFactory.CollectData();
data.EventType = AccessEye.UserStateEvents.ScreensaverOff;
PublishLogData(data);
}
void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e)
{
var data = LogDataFactory.CollectData();
switch (e.Reason)
{
case SessionSwitchReason.SessionLock:
data.EventType = UserStateEvents.Lock;
break;
case SessionSwitchReason.SessionUnlock:
data.EventType = UserStateEvents.Unlock;
break;
}
PublishLogData(data);
}
public void PublishLogData(AccessEye.LogData LogData)
{
WriteLogDataToDb(LogData);
if (!bus.IsConnected) return;
try
{
using (var publishChannel = bus.OpenPublishChannel())
{
publishChannel.Publish(exchange, LogData.EventType.ToString(), new Message<LogData>(LogData));
}
}
catch (EasyNetQException)
{
//todo: handle
}
}
public static byte[] Serialize<T>(T instance)
{
using (var stream = new MemoryStream())
{
Serializer.Serialize(stream, instance);
return stream.ToArray();
}
}
private static T DeSerialize<T>(byte[] data)
{
using (var stream = new MemoryStream(data))
{
return Serializer.Deserialize<T>(stream);
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
bus.Dispose();
}
public void inactivity_Active(object sender, EventArgs e)
{
inactivity.Stop();
var data = LogDataFactory.CollectData();
data.EventType = UserStateEvents.Active;
PublishLogData(data);
inactivity.Start();
}
public void inactivity_Inactive(object sender, EventArgs e)
{
inactivity.Stop();
var data = LogDataFactory.CollectData();
data.EventType = UserStateEvents.Inactive;
PublishLogData(data);
inactivity.Start();
}
public void SystemEvents_SessionEnding(object sender, EventArgs e)
{
var data = LogDataFactory.CollectData();
data.EventType = UserStateEvents.Logoff;
PublishLogData(data);
Logger.Trace("Logged off");
}
}
}
LogData Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ProtoBuf;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace AccessEye
{
public class DbLogData : LogData
{
[Key]
public int Id { get; set; }
public int? EventTypeId { get; set; }
[ForeignKey("EventTypeId")]
public virtual EventType EventTypeTest { get; set; }
}
}
Don't you need to create a map before you can use one;
AutoMapper.Mapper.CreateMap<LogData, DbLogData>();
For my class on Web Services I am trying to create an EXTREMELY simple login system. I ham having a problem where createAccounts() keeps getting infinite times whenever checkCredentials is called. Any idea why?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.IO;
public class Service : IService
{
static String path = #"PATH REMOVED";
List<Account> accounts = new List<Account>();
StreamWriter sw = null;
private void createAccounts()
{
String data = File.ReadAllText(path);
string[] data2 = data.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
string[] temp;
for (int i = 0; i < data2.Length; i++)
{
temp = data2[i].Split(',');
if(!usernameExists(temp[0]) && temp[0] != "")
{
accounts.Add(new Account(temp[0],temp[1]));
}
}
}
public bool CreateAccount(String username, String password)
{
createAccounts();
sw = File.AppendText(path);
if (!usernameExists(username))
{
sw.WriteLine(username + "," + password + "\n");
sw.Close();
sw = null;
return true;
}
else
{
sw.Close();
sw = null;
return false;
}
}
public bool usernameExists(String username)
{
createAccounts();
if(accounts.Exists(a => a.username == username))
return true;
else
return false;
}
public bool CheckCredentials(String username, String password)
{
createAccounts();
if (usernameExists(username))
{
if(accounts.Find(a => a.username == username).username == username && accounts.Find(a => a.username == username).password == password)
return true;
else
return false;
}
else
return false;
}
}
class Account
{
public String username;
public String password;
public Account(String u, String p)
{
username = u;
password = p;
}
}
You have a loop between createAccounts and usernameExists. As long as data2.Length is non-zero you'll loop endlessly.
you save data in a file,you should not write it in infinite times.when you request frequently,it will write the file in muliththreading,a thread will lock the file.
i suggest you use try...catch...write the file to find problem:
public bool CreateAccount(String username, String password)
{
createAccounts();
try
{
sw = File.AppendText(path);
}
catch (Exception ex)
{
throw ex;
}
if (!usernameExists(username))
{
sw.WriteLine(username + "," + password + "\n");
sw.Close();
sw = null;
return true;
}
else
{
sw.Close();
sw = null;
return false;
}
}
I have the email address of a Lync user and want to send him an instant message.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Lync.Model;
using Microsoft.Lync.Model.Conversation;
namespace Build_Server_Lync_Notifier
{
class Program
{
static void Main(string[] args)
{
if (args.Length != 2)
{
Console.WriteLine("Usage: bsln.exe <uri> <message>");
return;
}
LyncClient client = Microsoft.Lync.Model.LyncClient.GetClient();
Contact contact = client.ContactManager.GetContactByUri(args[0]);
Conversation conversation = client.ConversationManager.AddConversation();
conversation.AddParticipant(contact);
Dictionary<InstantMessageContentType, String> messages = new Dictionary<InstantMessageContentType, String>();
messages.Add(InstantMessageContentType.PlainText, args[1]);
InstantMessageModality m = (InstantMessageModality) conversation.Modalities[ModalityTypes.InstantMessage];
m.BeginSendMessage(messages, null, messages);
//Console.Read();
}
}
}
Screenshot
Link to large screenshot: http://i.imgur.com/LMHEF.png
As you can see in this screenshot, my program doesn't really seem to work, even though I'm able to manually search up the contact and send an instant message manually.
I also tried using ContactManager.BeginSearch() instead of ContactManager.GetContactByUri(), but got the same result (you can see in the screenshot): http://pastie.org/private/o9joyzvux4mkhzsjw1pioa
Ok, so I got it working now. Got it in a working state, although I need to do some serious refactoring.
Program.cs
using System;
namespace Build_Server_Lync_Notifier
{
class Program
{
static void Main(string[] args)
{
if (args.Length != 2)
{
Console.WriteLine("Usage: bsln.exe <uri> <message>");
return;
}
LyncManager lm = new LyncManager(args[0], args[1]);
while (!lm.Done)
{
System.Threading.Thread.Sleep(500);
}
}
}
}
LyncManager.cs
using Microsoft.Lync.Model;
using Microsoft.Lync.Model.Conversation;
using System;
using System.Collections.Generic;
namespace Build_Server_Lync_Notifier
{
class LyncManager
{
private string _uri;
private string _message;
private LyncClient _client;
private Conversation _conversation;
private bool _done = false;
public bool Done
{
get { return _done; }
}
public LyncManager(string arg0, string arg1)
{
_uri = arg0;
_message = arg1;
_client = Microsoft.Lync.Model.LyncClient.GetClient();
_client.ContactManager.BeginSearch(
_uri,
SearchProviders.GlobalAddressList,
SearchFields.EmailAddresses,
SearchOptions.ContactsOnly,
2,
BeginSearchCallback,
new object[] { _client.ContactManager, _uri }
);
}
private void BeginSearchCallback(IAsyncResult r)
{
object[] asyncState = (object[]) r.AsyncState;
ContactManager cm = (ContactManager) asyncState[0];
try
{
SearchResults results = cm.EndSearch(r);
if (results.AllResults.Count == 0)
{
Console.WriteLine("No results.");
}
else if (results.AllResults.Count == 1)
{
ContactSubscription srs = cm.CreateSubscription();
Contact contact = results.Contacts[0];
srs.AddContact(contact);
ContactInformationType[] contactInformationTypes = { ContactInformationType.Availability, ContactInformationType.ActivityId };
srs.Subscribe(ContactSubscriptionRefreshRate.High, contactInformationTypes);
_conversation = _client.ConversationManager.AddConversation();
_conversation.AddParticipant(contact);
Dictionary<InstantMessageContentType, String> messages = new Dictionary<InstantMessageContentType, String>();
messages.Add(InstantMessageContentType.PlainText, _message);
InstantMessageModality m = (InstantMessageModality)_conversation.Modalities[ModalityTypes.InstantMessage];
m.BeginSendMessage(messages, BeginSendMessageCallback, messages);
}
else
{
Console.WriteLine("More than one result.");
}
}
catch (SearchException se)
{
Console.WriteLine("Search failed: " + se.Reason.ToString());
}
_client.ContactManager.EndSearch(r);
}
private void BeginSendMessageCallback(IAsyncResult r)
{
_conversation.End();
_done = true;
}
}
}
Try Below Code its working Fine For me
protected void Page_Load(object sender, EventArgs e)
{
SendLyncMessage();
}
private static void SendLyncMessage()
{
string[] targetContactUris = {"sip:xxxx#domain.com"};
LyncClient client = LyncClient.GetClient();
Conversation conv = client.ConversationManager.AddConversation();
foreach (string target in targetContactUris)
{
conv.AddParticipant(client.ContactManager.GetContactByUri(target));
}
InstantMessageModality m = conv.Modalities[ModalityTypes.InstantMessage] as InstantMessageModality;
m.BeginSendMessage("Test Message", null, null);
}
I'm just trying to do a simple event handler on a string variable, so that if the string changes, it will do a Console.WriteLine (using the new Reactive library from MS (Rx))
The issue that I have is that it will display the first bit when I instantiate the class ("RandomGuid : Mine?"), but after that, none of the stuff I change afterwards spits anything out to the console.
I went through the HOL from the MS website, but it goes straight from defining the Observable into reading values from a textbox, when all I want to do is watch whether a string was changed.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MynahBirds
{
class Program
{
static void Main(string[] args)
{
List<Minah> minahs = new List<Minah>();
for (int i = 0; i < 10; i++) {
minahs.Add(new Minah());
}
foreach (var item in minahs) {
item.peers = minahs;
}
minahs.ForEach(m => m.s = Observable.Return<string>("Mine"));
minahs.ForEach(m => m.s = Observable.Return<string>("Whee"));
minahs.ForEach(m => m.s = Observable.Return<string>("Argh"));
Console.ReadLine();
}
}
class Minah
{
Guid Id;
public List<Minah> peers;
IDisposable subscription;
public IObservable<string> s = Observable.Return<string>("Mine?");
public Minah()
{
try {
this.Id = Guid.NewGuid();
subscription = s.Subscribe((string a) => {
Console.WriteLine("{0} : {1}", this.Id, a);
},
(Exception ex) => {
Console.WriteLine("Error {0} hit", ex.ToString());
},
() => { });
} catch (Exception ex) {
Console.WriteLine(ex.ToString());
Console.ReadLine();
throw;
}
}
}
}
When you assign to m.s in the ForEach you are not updating the existing observable (which you have subscribed to) with a new value, instead you are creating new observables, which is what Observable.Return does. The code below does what I think you expect:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MynahBirds
{
class Program
{
static void Main(string[] args)
{
List<Minah> minahs = new List<Minah>();
for (int i = 0; i < 10; i++)
{
minahs.Add(new Minah());
}
foreach (var item in minahs)
{
item.peers = minahs;
}
minahs.ForEach(m => m.s.OnNext("Mine"));
minahs.ForEach(m => m.s.OnNext("Whee"));
minahs.ForEach(m => m.s.OnNext("Argh"));
Console.ReadLine();
}
}
class Minah
{
Guid Id;
public List<Minah> peers;
IDisposable subscription;
public ISubject<string> s = new Subject<string>();
public Minah()
{
try
{
this.Id = Guid.NewGuid();
subscription = s.Subscribe((string a) =>
{
Console.WriteLine("{0} : {1}", this.Id, a);
},
(Exception ex) =>
{
Console.WriteLine("Error {0} hit", ex.ToString());
},
() => { });
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Console.ReadLine();
throw;
}
}
}
}
Instead of using Observable.Return<T>(), here I use a Subject, which is both an observer and an observable sequence. It updates all its subscriptions with each value it observes. So when OnNext is called on the subject, it is forwarded to all subscriptions.
If you need the initial value (Mine?) you can add s.OnNext("Mine?"); at the end of the Minah constructor.
using System;
using System.Collections.Generic;
using System.Threading;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Collections.Concurrent;
namespace MynahBirds
{
class Program
{
static void Main(string[] args)
{
ThreadPool.SetMaxThreads(100, 100);
ConcurrentBag<Minah> minahs = new ConcurrentBag<Minah>();
Stopwatch ti = new Stopwatch();
ti.Start();
Task.Factory.StartNew(() => {
for (int i = 1; i < 2501; i++) {
minahs.Add(new Minah(i));
};
});
Task.Factory.StartNew(() => {
for (int i = 1; i < 2501; i++) {
minahs.Add(new Minah(i));
};
});
Task.Factory.StartNew(() => {
for (int i = 1; i < 2501; i++) {
minahs.Add(new Minah(i));
};
});
Task.Factory.StartNew(() => {
for (int i = 1; i < 2501; i++) {
minahs.Add(new Minah(i));
};
});
Task.WaitAll();
string[] alpha = { "Alpha", "Bravo", "Charlie", "Delta", "Eagle", "Foxtrot", "Gulf", "Hotel" };
foreach (string s in alpha) {
Console.WriteLine(s);
Task.Factory.StartNew(() => minahs.AsParallel().ForAll(m => m.RepeatWord = s)).Wait();
}
minahs.AsParallel().ForAll(m => m.s.OnCompleted());
ti.Stop();
Console.WriteLine("{1} birds : {0} seconds", ti.Elapsed.TotalSeconds, minahs.Count);
Console.ReadLine();
}
}
class Minah
{
Guid Id;
IDisposable subscription;
public ISubject<string> s = new Subject<string>();
private string _RepeatWord;
public string RepeatWord
{
get
{
return _RepeatWord;
}
set
{
this.s.OnNext(value);
_RepeatWord = value;
}
}
public Minah(int i)
{
try {
this.Id = Guid.NewGuid();
subscription = s.Subscribe((string a) => {
Console.WriteLine("{0} : {1}", i, a);
},
(Exception ex) => {
Console.WriteLine("Error {0} hit", ex.ToString());
},
() => { /* Console.WriteLine("{0} : Completed", this.Id); */ });
} catch (Exception ex) {
Console.WriteLine(ex.ToString());
Console.ReadLine();
throw;
}
}
}
}
This is what I ended up doing with help from Markus. More playing around with parallelism. Interestingly, if I remove the .Wait() from the end of the .ForAll(... RepeatWord = s), it will only do the last word in the sequence. I'm guessing that is a closure thing, but I'm not overly concerned about it.