public async Task MainAsync() { this.startTime = DateTime.UtcNow; var settings = JsonConvert.DeserializeObject <Settings>(File.ReadAllText("config.json")); var discordApi = new DiscordApi(); await discordApi.StartAsync(settings.DiscordToken).ConfigureAwait(false); var ssApi = new StarSonataApi(); ssApi.SetServerUrl(settings.ServerUrl); ssApi.Initialise(); this.TryGameLoginAsync(ssApi, discordApi, settings).Forget(); discordApi.WhenMessageRecieved.Subscribe( msg => { if (msg.Author.Id == settings.BotDiscordId) { return; } if (msg.Channel.Id == settings.CommandChannel) { this.HandleCommands(settings, discordApi, ssApi, msg.Text); return; } if (this.AppState != EAppState.Ready) { return; } var channelMapping = settings.ChannelMappings.Discord.FirstOrDefault(c => c.Discord == msg.Channel.Id); if (channelMapping == null) { return; } try { // ssApi.SendImpersonationChatAsync(channelMapping.Game, msg.Author.Name, msg.Text); ssApi.SendChatAsync($"<{msg.Author.Name}>: {msg.Text}", (MessageChannel)Enum.Parse(typeof(MessageChannel), channelMapping.Game)); } catch (Exception) { lock (this) { this.lastError = DateTime.Now; } discordApi.SendMessageAsync( settings.ErrorChannel, "Error: Failed to send a message. Likely disconnected").Forget(); this.TryGameLoginAsync(ssApi, discordApi, settings).Forget(); } }); // Login as the first available character ssApi.WhenMessageReceived.Where(msg => msg is CharacterList).Subscribe( msg => { var characterList = (CharacterList)msg; var character = characterList.Characters.FirstOrDefault(c => c.Name.ToLower() == settings.CharacterName.ToLower()); if (character == null) { character = characterList.Characters.First(); Console.WriteLine($"Could not find character with name {settings.CharacterName}, falling back to first character ({character.Name})"); } Console.WriteLine("Logging in as " + character.Name); ssApi.SendMessage(new SelectCharacter(character)); }); ssApi.WhenMessageReceived.Where(m => !string.IsNullOrEmpty((m as TextMessage)?.Message?.Username)) .Subscribe( m => { var msg = (TextMessage)m; var channelMapping = settings.ChannelMappings.Game.FirstOrDefault( c => c.Game == msg.Message.Channel.ToString()); if (channelMapping == null) { return; } try { discordApi.SendMessageAsync( channelMapping.Discord, msg.Message.Username, msg.Message.Message).Forget(); } catch (Exception e) { Console.Error.WriteLine("Error sending discord message. " + e.Message); } }); await Task.Delay(-1).ConfigureAwait(false); }
//------------------------------------------------ public async Task MainAsync() { this.startTime = DateTime.UtcNow; var settings = JsonConvert.DeserializeObject <Settings>(File.ReadAllText("config.json")); var battleEncounters = new List <BattleEncounter>(); var encounterNotifications = new Dictionary <string, DateTime>(); var warDictionary = new Dictionary <string, WarTimer>(); var spreadsheetClient = new Spreadsheet(settings.SpreadsheetId, settings.SpreadsheetRange); onlineCharacters = new List <string>(); var test = new SocketServer(); test.Start(this); var discordApi = new DiscordApi(); await discordApi.StartAsync(settings.DiscordToken).ConfigureAwait(false); var ssApi = new StarSonataApi(settings.ServerUrl); ssApi.Connect(); this.TryGameLoginAsync(ssApi, discordApi, settings).Forget(); var squad = new Squad(ssApi); discordApi.WhenMessageRecieved.Subscribe( msg => { if (msg.Author.Id == settings.BotDiscordId) { return; } if (msg.Channel.Id == settings.CommandChannel) { this.HandleCommands(settings, discordApi, ssApi, msg.Text, squad); return; } if (this.AppState != EAppState.Ready) { return; } var channelMapping = settings.ChannelMappings.Discord.FirstOrDefault(c => c.Discord == msg.Channel.Id); if (channelMapping == null) { return; } try { // ssApi.SendImpersonationChatAsync(channelMapping.Game, msg.Author.Name, msg.Text); ssApi.SendChatAsync($"<{msg.Author.Name}>: {msg.Text}", (MessageChannel)Enum.Parse(typeof(MessageChannel), channelMapping.Game)); } catch (Exception) { lock (this) { this.lastError = DateTime.Now; } discordApi.SendMessageAsync( settings.ErrorChannel, "Error: Failed to send a message. Exitting.").Forget(); System.Environment.Exit(-1); //this.TryGameLoginAsync(ssApi, discordApi, settings).Forget(); } }); ssApi.WhenMessageReceived.Where(m => !string.IsNullOrEmpty((m as TextMessage)?.Message?.Username)) .Subscribe( m => { var msg = (TextMessage)m; var channelMapping = settings.ChannelMappings.Game.FirstOrDefault( c => c.Game == msg.Message.Channel.ToString()); if (channelMapping == null) { return; } try { discordApi.SendMessageAsync( channelMapping.Discord, msg.Message.Username, msg.Message.Message).Forget(); } catch (Exception e) { Console.Error.WriteLine("Error sending discord message, exitting. " + e.Message); System.Environment.Exit(-1); } }); ssApi.WhenMessageReceived.Where(m => !string.IsNullOrEmpty((m as TextMessage)?.Message?.Username)) .Subscribe(m => { var msg = (TextMessage)m; if (msg.Message.Channel.ToString() == "Team") { if (msg.Message.Message.StartsWith("!")) { if (msg.Message.Message.StartsWith("!squad")) { if (squad.SquadActive) { ssApi.SendChatAsync($"Squad is already active and is currently owned by: {squad.SquadLeader}", MessageChannel.Team); return; } if (msg.Message.Message.Contains("all")) { squad.InviteEveryone = true; } else { squad.InviteEveryone = false; } squad.SquadCreate(msg.Message.Username, onlineCharacters); ssApi.SendChatAsync("Creating new squad", MessageChannel.Team); } if (msg.Message.Message.StartsWith("!invite")) { if (!squad.SquadActive) { ssApi.SendChatAsync("There's no squad to invite you to. Type !squad to create squad", MessageChannel.Team); return; } squad.Invite(msg.Message.Username); } if (msg.Message.Message.StartsWith("!leave")) { if (squad.SquadActive) { if (squad.IsLeader(msg.Message.Username)) { squad.LeaveSquad(); } else { ssApi.SendChatAsync("Only squad leader can do that", MessageChannel.Team); } } } } } }); ssApi.WhenMessageReceived.Where(m => !string.IsNullOrEmpty((m as TextMessage)?.Message?.Message)) .Subscribe(m => { var msg = (TextMessage)m; if (msg.Message.Message.Contains("has joined your squad")) { squad.LeaderJoined(); } }); ssApi.WhenMessageReceived.Where(m => !string.IsNullOrEmpty((m as TextMessage)?.Message?.Message)) .Subscribe( m => { var msg = (TextMessage)m; if (!string.IsNullOrEmpty(msg.Message.Username)) { return; } var channel = msg.Message.Channel.ToString(); //custom messages foreach (var customMessage in settings.CustomMessages) { if (msg.Message.Message.Contains(customMessage.RecievedMessage)) { try { if (customMessage.MessageToSend.Length == 0) { discordApi.SendCustomMessage(customMessage.DiscordChannelID, msg.Message.Message); } else { discordApi.SendCustomMessage(customMessage.DiscordChannelID, customMessage.MessageToSend); } } catch (Exception) { System.Environment.Exit(-1); } } } //team warnings and initializing playerlist if (channel == "Team") { var messageContent = msg.Message.Message; if (messageContent.StartsWith("[WARNING]")) { Regex rx = new Regex(@"\[WARNING\](.*?) in (.*?) is under attack from player (.*?) on team (.*?)$"); MatchCollection matches = rx.Matches(messageContent); matches.ToArray(); var asset = matches[0].Groups[1].Value; var galaxy = matches[0].Groups[2].Value; var player = matches[0].Groups[3].Value; var team = matches[0].Groups[4].Value; if (team == "Star Revolution X" || galaxy == "Galactic Colosseum") { return; } var now = DateTime.Now; var attackedSystem = battleEncounters.FirstOrDefault(s => messageContent.Contains(s.attackedSystem)); if (attackedSystem != null) { if (attackedSystem.IsOver()) { battleEncounters.Remove(attackedSystem); discordApi.SendCustomMessage(settings.WarMessagesChannelID, $"@here -> Galaxy **{galaxy}** is under attack by player **{player}** from team **{team}**"); encounterNotifications.Add(galaxy, DateTime.Now); } else { attackedSystem.AddAttackingTeam(team); attackedSystem.AddAttackingPlayer(player); attackedSystem.UpdateLastNotification(); } } else { if (encounterNotifications.ContainsKey(galaxy)) { var timeStampInSeconds = (DateTime.Now - encounterNotifications.GetValueOrDefault(galaxy)).TotalSeconds; if (timeStampInSeconds > 30 && timeStampInSeconds < 120) { battleEncounters.Add(new BattleEncounter(discordApi, galaxy, settings.WarMessagesChannelID)); encounterNotifications.Remove(galaxy); discordApi.SendCustomMessage(settings.WarMessagesChannelID, $"@everyone -> Galaxy **{galaxy}** is under attack by player **{player}** from team **{team}**"); } if (timeStampInSeconds > 120) { discordApi.SendCustomMessage(settings.WarMessagesChannelID, $"@here -> Galaxy **{galaxy}** is under attack by player **{player}** from team **{team}**"); encounterNotifications[galaxy] = DateTime.Now; } } else { discordApi.SendCustomMessage(settings.WarMessagesChannelID, $"@here -> Galaxy **{galaxy}** is under attack by player **{player}** from team **{team}**"); encounterNotifications.Add(galaxy, DateTime.Now); } } } if (messageContent.Contains("has declared war on") || messageContent.Contains("is no longer at war with")) { if (messageContent.Contains("declared war on")) { Regex rx = new Regex(@"Team (.*?) has declared war on (.*?)\."); MatchCollection matches = rx.Matches(messageContent); matches.ToArray(); var team = matches[0].Groups[1].Value; var target = matches[0].Groups[2].Value; warDictionary.Add(team, new WarTimer(discordApi, team, settings.WarMessagesChannelID)); warDictionary.GetValueOrDefault(team).Notify(target); if (team == "Eminence Front") { for (int i = 0; i < 10; i++) { discordApi.SendCustomMessage(settings.WarMessagesChannelID, "@everyone -> EF WARRED US"); } //new BulkMessageDispatcher(discordApi, "everyone -> EF WARRED US", settings.WarMessagesChannelID, 10, 10); } } if (messageContent.Contains("is no longer at war")) { Regex rx = new Regex(@"Team (.*?) is no longer at war"); MatchCollection matches = rx.Matches(messageContent); matches.ToArray(); var team = matches[0].Groups[1].Value; warDictionary.GetValueOrDefault(team).OnCancelWarMessage(); warDictionary.Remove(team); discordApi.SendCustomMessage(settings.WarMessagesChannelID, $"@everyone -> Team **{team}** has ended the war!"); } } if (messageContent.Contains("Member accounts with")) { Regex rx = new Regex(@"Member accounts with deployed bases expiring \(or already expired\) in the next 24 hours: (.*?)$"); MatchCollection matches = rx.Matches(messageContent); matches.ToArray(); var nicks = matches[0].Groups[1].Value; var discordUsers = spreadsheetClient.GetDiscordCharOwners(nicks.Split(", ")); discordApi.SendCustomMessage(settings.BaseChannelId, $"{messageContent}\n{string.Join(", ", discordUsers.Select(user => $"<@{user}>").ToArray())}"); } } }); ssApi.WhenMessageReceived.Where(m => !string.IsNullOrEmpty((m as TeamCharacterStatus)?.Character?.Name)) .Subscribe( m => { var user = (TeamCharacterStatus)m; var characterName = user.Character.Name; if (user.Character.LastOnline < 0) { onlineCharacters.Add(characterName); //discordApi.SendCustomMessage(settings.ChannelMappings.Game.FirstOrDefault(ch => ch.Game == "Team").Discord, $"**__{characterName}__ is now online**"); } else { if (onlineCharacters.Contains(characterName)) { onlineCharacters.Remove(characterName); //discordApi.SendCustomMessage(settings.ChannelMappings.Game.FirstOrDefault(ch => ch.Game == "Team").Discord, $"**__{characterName}__ is now offline**"); } } }); await Task.Delay(-1).ConfigureAwait(false); }