public async Task OnLoadAsync(IManager manager) { Config = new BaseConfigurationHandler <DiscordAlertCfg>("DiscordAlertCfg"); if (Config.Configuration() == null) { Config.Set((DiscordAlertCfg) new DiscordAlertCfg().Generate()); await Config.Save(); } }
public async Task OnLoadAsync(IManager manager) { // load custom configuration Config = new BaseConfigurationHandler <WelcomeConfiguration>("WelcomePluginSettings"); if (Config.Configuration() == null) { Config.Set((WelcomeConfiguration) new WelcomeConfiguration().Generate()); await Config.Save(); } }
public async Task OnLoadAsync(IManager manager) { // load custom configuration Settings = new BaseConfigurationHandler <Configuration>("ProfanityDetermentSettings"); if (Settings.Configuration() == null) { Settings.Set((Configuration) new Configuration().Generate()); await Settings.Save(); } ProfanityCounts = new ConcurrentDictionary <int, Tracking>(); Manager = manager; }
public async Task OnLoadAsync(IManager manager) { AuthorizedClients = new ConcurrentDictionary <int, bool>(); var cfg = new BaseConfigurationHandler <Configuration>("LoginPluginSettings"); if (cfg.Configuration() == null) { cfg.Set((Configuration) new Configuration().Generate()); await cfg.Save(); } Config = cfg.Configuration(); }
public async Task OnLoadAsync(IManager manager) { var cfg = new BaseConfigurationHandler <Configuration>("AutomessageFeedPluginSettings"); if (cfg.Configuration() == null) { cfg.Set((Configuration) new Configuration().Generate()); await cfg.Save(); } _configuration = cfg.Configuration(); manager.GetMessageTokens().Add(new MessageToken("FEED", GetNextFeedItem)); }
public async Task Init() { #region DATABASE var ipList = (await ClientSvc.Find(c => c.Level > Player.Permission.Trusted)) .Select(c => new { c.Password, c.PasswordSalt, c.ClientId, c.Level, c.Name }); foreach (var a in ipList) { try { PrivilegedClients.Add(a.ClientId, new Player() { Name = a.Name, ClientId = a.ClientId, Level = a.Level, PasswordSalt = a.PasswordSalt, Password = a.Password }); } catch (ArgumentException) { continue; } } #endregion #region CONFIG var config = ConfigHandler.Configuration(); // copy over default config if it doesn't exist if (config == null) { var defaultConfig = new BaseConfigurationHandler <DefaultConfiguration>("DefaultSettings").Configuration(); ConfigHandler.Set((ApplicationConfiguration) new ApplicationConfiguration().Generate()); var newConfig = ConfigHandler.Configuration(); newConfig.AutoMessagePeriod = defaultConfig.AutoMessagePeriod; newConfig.AutoMessages = defaultConfig.AutoMessages; newConfig.GlobalRules = defaultConfig.GlobalRules; newConfig.Maps = defaultConfig.Maps; if (newConfig.Servers == null) { ConfigHandler.Set(newConfig); newConfig.Servers = new List <ServerConfiguration>(); do { newConfig.Servers.Add((ServerConfiguration) new ServerConfiguration().Generate()); } while (Utilities.PromptBool(Utilities.CurrentLocalization.LocalizationSet["SETUP_SERVER_SAVE"])); config = newConfig; await ConfigHandler.Save(); } } else if (config != null) { if (string.IsNullOrEmpty(config.Id)) { config.Id = Guid.NewGuid().ToString(); await ConfigHandler.Save(); } if (string.IsNullOrEmpty(config.WebfrontBindUrl)) { config.WebfrontBindUrl = "http://127.0.0.1:1624"; await ConfigHandler.Save(); } } else if (config.Servers.Count == 0) { throw new ServerException("A server configuration in IW4MAdminSettings.json is invalid"); } Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); Utilities.EncodingType = Encoding.GetEncoding(!string.IsNullOrEmpty(config.CustomParserEncoding) ? config.CustomParserEncoding : "windows-1252"); #endregion #region PLUGINS SharedLibraryCore.Plugins.PluginImporter.Load(this); foreach (var Plugin in SharedLibraryCore.Plugins.PluginImporter.ActivePlugins) { try { await Plugin.OnLoadAsync(this); } catch (Exception e) { Logger.WriteError($"An error occured loading plugin {Plugin.Name}"); Logger.WriteDebug($"Exception: {e.Message}"); Logger.WriteDebug($"Stack Trace: {e.StackTrace}"); } } #endregion #region COMMANDS if (ClientSvc.GetOwners().Result.Count == 0) { Commands.Add(new COwner()); } Commands.Add(new CQuit()); Commands.Add(new CKick()); Commands.Add(new CSay()); Commands.Add(new CTempBan()); Commands.Add(new CBan()); Commands.Add(new CWhoAmI()); Commands.Add(new CList()); Commands.Add(new CHelp()); Commands.Add(new CFastRestart()); Commands.Add(new CMapRotate()); Commands.Add(new CSetLevel()); Commands.Add(new CUsage()); Commands.Add(new CUptime()); Commands.Add(new CWarn()); Commands.Add(new CWarnClear()); Commands.Add(new CUnban()); Commands.Add(new CListAdmins()); Commands.Add(new CLoadMap()); Commands.Add(new CFindPlayer()); Commands.Add(new CListRules()); Commands.Add(new CPrivateMessage()); Commands.Add(new CFlag()); Commands.Add(new CReport()); Commands.Add(new CListReports()); Commands.Add(new CListBanInfo()); Commands.Add(new CListAlias()); Commands.Add(new CExecuteRCON()); Commands.Add(new CPlugins()); Commands.Add(new CIP()); Commands.Add(new CMask()); Commands.Add(new CPruneAdmins()); Commands.Add(new CKillServer()); Commands.Add(new CSetPassword()); Commands.Add(new CPing()); foreach (Command C in SharedLibraryCore.Plugins.PluginImporter.ActiveCommands) { Commands.Add(C); } #endregion #region INIT async Task Init(ServerConfiguration Conf) { try { var ServerInstance = new IW4MServer(this, Conf); await ServerInstance.Initialize(); lock (_servers) { _servers.Add(ServerInstance); } Logger.WriteVerbose($"Now monitoring {ServerInstance.Hostname}"); // this way we can keep track of execution time and see if problems arise. var Status = new AsyncStatus(ServerInstance, UPDATE_FREQUENCY); lock (TaskStatuses) { TaskStatuses.Add(Status); } } catch (ServerException e) { Logger.WriteError($"Not monitoring server {Conf.IPAddress}:{Conf.Port} due to uncorrectable errors"); if (e.GetType() == typeof(DvarException)) { Logger.WriteDebug($"Could not get the dvar value for {(e as DvarException).Data["dvar_name"]} (ensure the server has a map loaded)"); } else if (e.GetType() == typeof(NetworkException)) { Logger.WriteDebug(e.Message); } // throw the exception to the main method to stop before instantly exiting throw e; } } await Task.WhenAll(config.Servers.Select(c => Init(c)).ToArray()); #endregion Running = true; }
public async Task OnLoadAsync(IManager manager) { // load custom configuration Config = new BaseConfigurationHandler <StatsConfiguration>("StatsPluginSettings"); if (Config.Configuration() == null) { Config.Set((StatsConfiguration) new StatsConfiguration().Generate()); await Config.Save(); } // meta data info async Task <List <ProfileMeta> > getStats(int clientId) { var statsSvc = new GenericRepository <EFClientStatistics>(); var clientStats = await statsSvc.FindAsync(c => c.ClientId == clientId); int kills = clientStats.Sum(c => c.Kills); int deaths = clientStats.Sum(c => c.Deaths); double kdr = Math.Round(kills / (double)deaths, 2); double skill = Math.Round(clientStats.Sum(c => c.Skill) / clientStats.Count, 2); double spm = Math.Round(clientStats.Sum(c => c.SPM), 1); return(new List <ProfileMeta>() { new ProfileMeta() { Key = "Kills", Value = kills }, new ProfileMeta() { Key = "Deaths", Value = deaths }, new ProfileMeta() { Key = "KDR", Value = kdr }, new ProfileMeta() { Key = "Skill", Value = skill }, new ProfileMeta() { Key = "Score Per Minute", Value = spm } }); } async Task <List <ProfileMeta> > getAnticheatInfo(int clientId) { var statsSvc = new GenericRepository <EFClientStatistics>(); var clientStats = await statsSvc.FindAsync(c => c.ClientId == clientId); double headRatio = 0; double chestRatio = 0; double abdomenRatio = 0; double chestAbdomenRatio = 0; double hitOffsetAverage = 0; if (clientStats.Where(cs => cs.HitLocations.Count > 0).FirstOrDefault() != null) { chestRatio = Math.Round(clientStats.Where(c => c.HitLocations.Count > 0).Sum(c => c.HitLocations.First(hl => hl.Location == IW4Info.HitLocation.torso_upper).HitCount) / (double)clientStats.Where(c => c.HitLocations.Count > 0) .Sum(c => c.HitLocations.Where(hl => hl.Location != IW4Info.HitLocation.none).Sum(f => f.HitCount)), 2); abdomenRatio = Math.Round(clientStats.Where(c => c.HitLocations.Count > 0).Sum(c => c.HitLocations.First(hl => hl.Location == IW4Info.HitLocation.torso_lower).HitCount) / (double)clientStats.Where(c => c.HitLocations.Count > 0).Sum(c => c.HitLocations.Where(hl => hl.Location != IW4Info.HitLocation.none).Sum(f => f.HitCount)), 2); chestAbdomenRatio = Math.Round(clientStats.Where(c => c.HitLocations.Count > 0).Sum(cs => cs.HitLocations.First(hl => hl.Location == IW4Info.HitLocation.torso_upper).HitCount) / (double)clientStats.Where(c => c.HitLocations.Count > 0).Sum(cs => cs.HitLocations.First(hl => hl.Location == IW4Info.HitLocation.torso_lower).HitCount), 2); headRatio = Math.Round(clientStats.Where(c => c.HitLocations.Count > 0).Sum(cs => cs.HitLocations.First(hl => hl.Location == IW4Info.HitLocation.head).HitCount) / (double)clientStats.Where(c => c.HitLocations.Count > 0) .Sum(c => c.HitLocations.Where(hl => hl.Location != IW4Info.HitLocation.none).Sum(f => f.HitCount)), 2); hitOffsetAverage = clientStats.Sum(c => c.AverageHitOffset) / Math.Max(1, clientStats.Where(c => c.AverageHitOffset > 0).Count()); } return(new List <ProfileMeta>() { new ProfileMeta() { Key = "Chest Ratio", Value = chestRatio, Sensitive = true }, new ProfileMeta() { Key = "Abdomen Ratio", Value = abdomenRatio, Sensitive = true }, new ProfileMeta() { Key = "Chest To Abdomen Ratio", Value = chestAbdomenRatio, Sensitive = true }, new ProfileMeta() { Key = "Headshot Ratio", Value = headRatio, Sensitive = true }, new ProfileMeta() { Key = "Hit Offset Average", Value = $"{Math.Round(((float)hitOffsetAverage).ToDegrees(), 4)}°", Sensitive = true } }); } async Task <List <ProfileMeta> > getMessages(int clientId) { var messageSvc = new GenericRepository <EFClientMessage>(); var messages = await messageSvc.FindAsync(m => m.ClientId == clientId); var messageMeta = messages.Select(m => new ProfileMeta() { Key = "EventMessage", Value = m.Message, When = m.TimeSent }).ToList(); messageMeta.Add(new ProfileMeta() { Key = "Messages", Value = messages.Count }); return(messageMeta); } MetaService.AddMeta(getStats); if (Config.Configuration().EnableAntiCheat) { MetaService.AddMeta(getAnticheatInfo); } MetaService.AddMeta(getMessages); string totalKills() { var serverStats = new GenericRepository <EFServerStatistics>(); return(serverStats.Find(s => s.Active) .Sum(c => c.TotalKills).ToString("#,##0")); } string totalPlayTime() { var serverStats = new GenericRepository <EFServerStatistics>(); return(Math.Ceiling((serverStats.GetQuery(s => s.Active) .Sum(c => c.TotalPlayTime) / 3600.0)).ToString("#,##0")); } manager.GetMessageTokens().Add(new MessageToken("TOTALKILLS", totalKills)); manager.GetMessageTokens().Add(new MessageToken("TOTALPLAYTIME", totalPlayTime)); ServerManager = manager; Manager = new StatManager(manager); }
public async Task OnLoadAsync(IManager manager) { // load custom configuration Config = new BaseConfigurationHandler <StatsConfiguration>("StatsPluginSettings"); if (Config.Configuration() == null) { Config.Set((StatsConfiguration) new StatsConfiguration().Generate()); await Config.Save(); } // register the topstats page // todo:generate the URL/Location instead of hardcoding manager.GetPageList() .Pages.Add( Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_COMMANDS_TOP_TEXT"], "/Stats/TopPlayersAsync"); // meta data info async Task <List <ProfileMeta> > getStats(int clientId, int offset, int count, DateTime?startAt) { if (count > 1) { return(new List <ProfileMeta>()); } IList <EFClientStatistics> clientStats; using (var ctx = new DatabaseContext(disableTracking: true)) { clientStats = await ctx.Set <EFClientStatistics>().Where(c => c.ClientId == clientId).ToListAsync(); } int kills = clientStats.Sum(c => c.Kills); int deaths = clientStats.Sum(c => c.Deaths); double kdr = Math.Round(kills / (double)deaths, 2); var validPerformanceValues = clientStats.Where(c => c.Performance > 0); int performancePlayTime = validPerformanceValues.Sum(s => s.TimePlayed); double performance = Math.Round(validPerformanceValues.Sum(c => c.Performance * c.TimePlayed / performancePlayTime), 2); double spm = Math.Round(clientStats.Sum(c => c.SPM) / clientStats.Where(c => c.SPM > 0).Count(), 1); return(new List <ProfileMeta>() { new ProfileMeta() { Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_RANKING"], Value = "#" + (await StatManager.GetClientOverallRanking(clientId)).ToString("#,##0", new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)), Column = 0, Order = 0, Type = ProfileMeta.MetaType.Information }, new ProfileMeta() { Key = Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_TEXT_KILLS"], Value = kills.ToString("#,##0", new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)), Column = 0, Order = 1, Type = ProfileMeta.MetaType.Information }, new ProfileMeta() { Key = Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_TEXT_DEATHS"], Value = deaths.ToString("#,##0", new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)), Column = 0, Order = 2, Type = ProfileMeta.MetaType.Information }, new ProfileMeta() { Key = Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_TEXT_KDR"], Value = kdr.ToString(new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)), Column = 0, Order = 3, Type = ProfileMeta.MetaType.Information }, new ProfileMeta() { Key = Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_COMMANDS_PERFORMANCE"], Value = performance.ToString("#,##0", new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)), Column = 0, Order = 4, Type = ProfileMeta.MetaType.Information }, new ProfileMeta() { Key = Utilities.CurrentLocalization.LocalizationIndex["PLUGINS_STATS_META_SPM"], Value = spm.ToString(new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)), Column = 0, Order = 5, Type = ProfileMeta.MetaType.Information } }); } async Task <List <ProfileMeta> > getAnticheatInfo(int clientId, int offset, int count, DateTime?startAt) { if (count > 1) { return(new List <ProfileMeta>()); } IList <EFClientStatistics> clientStats; using (var ctx = new DatabaseContext(disableTracking: true)) { clientStats = await ctx.Set <EFClientStatistics>() .Include(c => c.HitLocations) .Where(c => c.ClientId == clientId) .ToListAsync(); } double headRatio = 0; double chestRatio = 0; double abdomenRatio = 0; double chestAbdomenRatio = 0; double hitOffsetAverage = 0; double maxStrain = clientStats.Count(c => c.MaxStrain > 0) == 0 ? 0 : clientStats.Max(cs => cs.MaxStrain); if (clientStats.Where(cs => cs.HitLocations.Count > 0).FirstOrDefault() != null) { chestRatio = Math.Round((clientStats.Where(c => c.HitLocations.Count > 0).Sum(c => c.HitLocations.First(hl => hl.Location == IW4Info.HitLocation.torso_upper).HitCount) / (double)clientStats.Where(c => c.HitLocations.Count > 0) .Sum(c => c.HitLocations.Where(hl => hl.Location != IW4Info.HitLocation.none).Sum(f => f.HitCount))) * 100.0, 0); abdomenRatio = Math.Round((clientStats.Where(c => c.HitLocations.Count > 0).Sum(c => c.HitLocations.First(hl => hl.Location == IW4Info.HitLocation.torso_lower).HitCount) / (double)clientStats.Where(c => c.HitLocations.Count > 0).Sum(c => c.HitLocations.Where(hl => hl.Location != IW4Info.HitLocation.none).Sum(f => f.HitCount))) * 100.0, 0); chestAbdomenRatio = Math.Round((clientStats.Where(c => c.HitLocations.Count > 0).Sum(cs => cs.HitLocations.First(hl => hl.Location == IW4Info.HitLocation.torso_upper).HitCount) / (double)clientStats.Where(c => c.HitLocations.Count > 0).Sum(cs => cs.HitLocations.First(hl => hl.Location == IW4Info.HitLocation.torso_lower).HitCount)) * 100.0, 0); headRatio = Math.Round((clientStats.Where(c => c.HitLocations.Count > 0).Sum(cs => cs.HitLocations.First(hl => hl.Location == IW4Info.HitLocation.head).HitCount) / (double)clientStats.Where(c => c.HitLocations.Count > 0) .Sum(c => c.HitLocations.Where(hl => hl.Location != IW4Info.HitLocation.none).Sum(f => f.HitCount))) * 100.0, 0); var validOffsets = clientStats.Where(c => c.HitLocations.Count(hl => hl.HitCount > 0) > 0).SelectMany(hl => hl.HitLocations); hitOffsetAverage = validOffsets.Sum(o => o.HitCount * o.HitOffsetAverage) / (double)validOffsets.Sum(o => o.HitCount); } return(new List <ProfileMeta>() { new ProfileMeta() { Key = $"{Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_AC_METRIC"]} 1", Value = chestRatio.ToString(new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)) + '%', Type = ProfileMeta.MetaType.Information, Column = 2, Order = 0, Extra = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_TITLE_ACM1"], Sensitive = true }, new ProfileMeta() { Key = $"{Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_AC_METRIC"]} 2", Value = abdomenRatio.ToString(new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)) + '%', Type = ProfileMeta.MetaType.Information, Column = 2, Order = 1, Extra = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_TITLE_ACM2"], Sensitive = true }, new ProfileMeta() { Key = $"{Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_AC_METRIC"]} 3", Value = chestAbdomenRatio.ToString(new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)) + '%', Type = ProfileMeta.MetaType.Information, Column = 2, Order = 2, Extra = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_TITLE_ACM3"], Sensitive = true }, new ProfileMeta() { Key = $"{Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_AC_METRIC"]} 4", Value = headRatio.ToString(new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)) + '%', Type = ProfileMeta.MetaType.Information, Column = 2, Order = 3, Extra = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_TITLE_ACM4"], Sensitive = true }, new ProfileMeta() { Key = $"{Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_AC_METRIC"]} 5", // todo: make sure this is wrapped somewhere else Value = $"{Math.Round(((float)hitOffsetAverage), 4).ToString(new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName))}°", Type = ProfileMeta.MetaType.Information, Column = 2, Order = 4, Extra = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_TITLE_ACM5"], Sensitive = true }, new ProfileMeta() { Key = $"{Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_AC_METRIC"]} 6", Value = Math.Round(maxStrain, 3).ToString(new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)), Type = ProfileMeta.MetaType.Information, Column = 2, Order = 5, Extra = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_TITLE_ACM6"], Sensitive = true }, }); } async Task <List <ProfileMeta> > getMessages(int clientId, int offset, int count, DateTime?startAt) { if (count <= 1) { using (var ctx = new DatabaseContext(true)) { return(new List <ProfileMeta> { new ProfileMeta() { Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PROFILE_MESSAGES"], Value = (await ctx.Set <EFClientMessage>() .CountAsync(_message => _message.ClientId == clientId)) .ToString("#,##0", new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)), Column = 1, Order = 4, Type = ProfileMeta.MetaType.Information } }); } } List <ProfileMeta> messageMeta; using (var ctx = new DatabaseContext(disableTracking: true)) { var messages = ctx.Set <EFClientMessage>() .Where(m => m.ClientId == clientId) .Where(_message => _message.TimeSent < startAt) .OrderByDescending(_message => _message.TimeSent) .Skip(offset) .Take(count); messageMeta = await messages.Select(m => new ProfileMeta() { Key = null, Value = new { m.Message, m.Server.GameName }, When = m.TimeSent, Extra = m.ServerId.ToString(), Type = ProfileMeta.MetaType.ChatMessage }).ToListAsync(); foreach (var message in messageMeta) { if ((message.Value.Message as string).IsQuickMessage()) { try { var quickMessages = ServerManager.GetApplicationSettings().Configuration() .QuickMessages .First(_qm => _qm.Game == message.Value.GameName); message.Value = quickMessages.Messages[(message.Value.Message as string).Substring(1)]; message.Type = ProfileMeta.MetaType.QuickMessage; } catch { message.Value = message.Value.Message; } } else { message.Value = message.Value.Message; } } } return(messageMeta); } if (Config.Configuration().EnableAntiCheat) { MetaService.AddRuntimeMeta(getAnticheatInfo); } MetaService.AddRuntimeMeta(getStats); MetaService.AddRuntimeMeta(getMessages); async Task <string> totalKills(Server server) { using (var ctx = new DatabaseContext(disableTracking: true)) { long kills = await ctx.Set <EFServerStatistics>().Where(s => s.Active).SumAsync(s => s.TotalKills); return(kills.ToString("#,##0", new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName))); } } async Task <string> totalPlayTime(Server server) { using (var ctx = new DatabaseContext(disableTracking: true)) { long playTime = await ctx.Set <EFServerStatistics>().Where(s => s.Active).SumAsync(s => s.TotalPlayTime); return((playTime / 3600.0).ToString("#,##0", new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName))); } } async Task <string> topStats(Server s) { return(string.Join(Environment.NewLine, await Commands.TopStats.GetTopStats(s))); } async Task <string> mostPlayed(Server s) { return(string.Join(Environment.NewLine, await Commands.MostPlayed.GetMostPlayed(s))); } manager.GetMessageTokens().Add(new MessageToken("TOTALKILLS", totalKills)); manager.GetMessageTokens().Add(new MessageToken("TOTALPLAYTIME", totalPlayTime)); manager.GetMessageTokens().Add(new MessageToken("TOPSTATS", topStats)); manager.GetMessageTokens().Add(new MessageToken("MOSTPLAYED", mostPlayed)); ServerManager = manager; Manager = new StatManager(manager); }
public async Task Init() { Running = true; ExternalIPAddress = await Utilities.GetExternalIP(); #region PLUGINS SharedLibraryCore.Plugins.PluginImporter.Load(this); foreach (var Plugin in SharedLibraryCore.Plugins.PluginImporter.ActivePlugins) { try { await Plugin.OnLoadAsync(this); } catch (Exception ex) { Logger.WriteError($"{Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_PLUGIN"]} {Plugin.Name}"); Logger.WriteDebug(ex.GetExceptionInfo()); } } #endregion #region CONFIG var config = ConfigHandler.Configuration(); // copy over default config if it doesn't exist if (config == null) { var defaultConfig = new BaseConfigurationHandler <DefaultConfiguration>("DefaultSettings").Configuration(); ConfigHandler.Set((ApplicationConfiguration) new ApplicationConfiguration().Generate()); var newConfig = ConfigHandler.Configuration(); newConfig.AutoMessages = defaultConfig.AutoMessages; newConfig.GlobalRules = defaultConfig.GlobalRules; newConfig.Maps = defaultConfig.Maps; newConfig.DisallowedClientNames = defaultConfig.DisallowedClientNames; newConfig.QuickMessages = defaultConfig.QuickMessages; if (newConfig.Servers == null) { ConfigHandler.Set(newConfig); newConfig.Servers = new List <ServerConfiguration>(); do { var serverConfig = new ServerConfiguration(); foreach (var parser in AdditionalRConParsers) { serverConfig.AddRConParser(parser); } foreach (var parser in AdditionalEventParsers) { serverConfig.AddEventParser(parser); } newConfig.Servers.Add((ServerConfiguration)serverConfig.Generate()); } while (Utilities.PromptBool(Utilities.CurrentLocalization.LocalizationIndex["SETUP_SERVER_SAVE"])); config = newConfig; await ConfigHandler.Save(); } } else { if (string.IsNullOrEmpty(config.Id)) { config.Id = Guid.NewGuid().ToString(); await ConfigHandler.Save(); } if (string.IsNullOrEmpty(config.WebfrontBindUrl)) { config.WebfrontBindUrl = "http://0.0.0.0:1624"; await ConfigHandler.Save(); } foreach (var serverConfig in config.Servers) { Migration.ConfigurationMigration.ModifyLogPath020919(serverConfig); if (serverConfig.RConParserVersion == null || serverConfig.EventParserVersion == null) { foreach (var parser in AdditionalRConParsers) { serverConfig.AddRConParser(parser); } foreach (var parser in AdditionalEventParsers) { serverConfig.AddEventParser(parser); } serverConfig.ModifyParsers(); } await ConfigHandler.Save(); } } if (config.Servers.Count == 0) { throw new ServerException("A server configuration in IW4MAdminSettings.json is invalid"); } Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); Utilities.EncodingType = Encoding.GetEncoding(!string.IsNullOrEmpty(config.CustomParserEncoding) ? config.CustomParserEncoding : "windows-1252"); #endregion #region DATABASE using (var db = new DatabaseContext(GetApplicationSettings().Configuration()?.ConnectionString, GetApplicationSettings().Configuration()?.DatabaseProvider)) { await new ContextSeed(db).Seed(); } PrivilegedClients = (await ClientSvc.GetPrivilegedClients()).ToDictionary(_client => _client.ClientId); #endregion #region COMMANDS if (ClientSvc.GetOwners().Result.Count == 0) { Commands.Add(new COwner()); } Commands.Add(new CQuit()); Commands.Add(new CKick()); Commands.Add(new CSay()); Commands.Add(new CTempBan()); Commands.Add(new CBan()); Commands.Add(new CWhoAmI()); Commands.Add(new CList()); Commands.Add(new CHelp()); Commands.Add(new CFastRestart()); Commands.Add(new CMapRotate()); Commands.Add(new CSetLevel()); Commands.Add(new CUsage()); Commands.Add(new CUptime()); Commands.Add(new CWarn()); Commands.Add(new CWarnClear()); Commands.Add(new CUnban()); Commands.Add(new CListAdmins()); Commands.Add(new CLoadMap()); Commands.Add(new CFindPlayer()); Commands.Add(new CListRules()); Commands.Add(new CPrivateMessage()); Commands.Add(new CFlag()); Commands.Add(new CUnflag()); Commands.Add(new CReport()); Commands.Add(new CListReports()); Commands.Add(new CListBanInfo()); Commands.Add(new CListAlias()); Commands.Add(new CExecuteRCON()); Commands.Add(new CPlugins()); Commands.Add(new CIP()); Commands.Add(new CMask()); Commands.Add(new CPruneAdmins()); Commands.Add(new CKillServer()); Commands.Add(new CSetPassword()); Commands.Add(new CPing()); Commands.Add(new CSetGravatar()); Commands.Add(new CNextMap()); Commands.Add(new RequestTokenCommand()); foreach (Command C in SharedLibraryCore.Plugins.PluginImporter.ActiveCommands) { Commands.Add(C); } #endregion #region META async Task <List <ProfileMeta> > getProfileMeta(int clientId, int offset, int count, DateTime?startAt) { var metaList = new List <ProfileMeta>(); // we don't want to return anything because it means we're trying to retrieve paged meta data if (count > 1) { return(metaList); } var lastMapMeta = await _metaService.GetPersistentMeta("LastMapPlayed", new EFClient() { ClientId = clientId }); if (lastMapMeta != null) { metaList.Add(new ProfileMeta() { Id = lastMapMeta.MetaId, Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_LAST_MAP"], Value = lastMapMeta.Value, Show = true, Type = ProfileMeta.MetaType.Information, }); } var lastServerMeta = await _metaService.GetPersistentMeta("LastServerPlayed", new EFClient() { ClientId = clientId }); if (lastServerMeta != null) { metaList.Add(new ProfileMeta() { Id = lastServerMeta.MetaId, Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_LAST_SERVER"], Value = lastServerMeta.Value, Show = true, Type = ProfileMeta.MetaType.Information }); } var client = await GetClientService().Get(clientId); metaList.Add(new ProfileMeta() { Id = client.ClientId, Key = $"{Utilities.CurrentLocalization.LocalizationIndex["GLOBAL_TIME_HOURS"]} {Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PROFILE_PLAYER"]}", Value = Math.Round(client.TotalConnectionTime / 3600.0, 1).ToString("#,##0", new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)), Show = true, Column = 1, Order = 0, Type = ProfileMeta.MetaType.Information }); metaList.Add(new ProfileMeta() { Id = client.ClientId, Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PROFILE_FSEEN"], Value = Utilities.GetTimePassed(client.FirstConnection, false), Show = true, Column = 1, Order = 1, Type = ProfileMeta.MetaType.Information }); metaList.Add(new ProfileMeta() { Id = client.ClientId, Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_PROFILE_LSEEN"], Value = Utilities.GetTimePassed(client.LastConnection, false), Show = true, Column = 1, Order = 2, Type = ProfileMeta.MetaType.Information }); metaList.Add(new ProfileMeta() { Id = client.ClientId, Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_CONNECTIONS"], Value = client.Connections.ToString("#,##0", new System.Globalization.CultureInfo(Utilities.CurrentLocalization.LocalizationName)), Show = true, Column = 1, Order = 3, Type = ProfileMeta.MetaType.Information }); metaList.Add(new ProfileMeta() { Key = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_MASKED"], Value = client.Masked ? Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_TRUE"] : Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CLIENT_META_FALSE"], Sensitive = true, Column = 1, Order = 4, Type = ProfileMeta.MetaType.Information }); return(metaList); } async Task <List <ProfileMeta> > getPenaltyMeta(int clientId, int offset, int count, DateTime?startAt) { if (count <= 1) { return(new List <ProfileMeta>()); } var penalties = await GetPenaltyService().GetClientPenaltyForMetaAsync(clientId, count, offset, startAt); return(penalties.Select(_penalty => new ProfileMeta() { Id = _penalty.Id, Type = _penalty.PunisherId == clientId ? ProfileMeta.MetaType.Penalized : ProfileMeta.MetaType.ReceivedPenalty, Value = _penalty, When = _penalty.TimePunished, Sensitive = _penalty.Sensitive }) .ToList()); } MetaService.AddRuntimeMeta(getProfileMeta); MetaService.AddRuntimeMeta(getPenaltyMeta); #endregion #region INIT int failedServers = 0; int successServers = 0; Exception lastException = null; async Task Init(ServerConfiguration Conf) { // setup the event handler after the class is initialized Handler = new GameEventHandler(this); try { var ServerInstance = new IW4MServer(this, Conf); await ServerInstance.Initialize(); lock (_servers) { _servers.Add(ServerInstance); } Logger.WriteVerbose(Utilities.CurrentLocalization.LocalizationIndex["MANAGER_MONITORING_TEXT"].FormatExt(ServerInstance.Hostname)); // add the start event for this server var e = new GameEvent() { Type = GameEvent.EventType.Start, Data = $"{ServerInstance.GameName} started", Owner = ServerInstance }; Handler.AddEvent(e); successServers++; } catch (ServerException e) { Logger.WriteError(Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_UNFIXABLE"].FormatExt($"[{Conf.IPAddress}:{Conf.Port}]")); if (e.GetType() == typeof(DvarException)) { Logger.WriteDebug($"{Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_DVAR"].FormatExt((e as DvarException).Data["dvar_name"])} ({Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_DVAR_HELP"]})"); } else if (e.GetType() == typeof(NetworkException)) { Logger.WriteDebug(e.Message); } failedServers++; lastException = e; } } await Task.WhenAll(config.Servers.Select(c => Init(c)).ToArray()); if (successServers - failedServers <= 0) { if (!Utilities.PromptBool(Utilities.CurrentLocalization.LocalizationIndex["MANAGER_START_WITH_ERRORS"])) { throw lastException; } } #endregion }
/// <summary> /// Configures the dependency injection services /// </summary> private static IServiceCollection ConfigureServices(string[] args) { // setup the static resources (config/master api/translations) var serviceCollection = new ServiceCollection(); var appConfigHandler = new BaseConfigurationHandler <ApplicationConfiguration>("IW4MAdminSettings"); var defaultConfigHandler = new BaseConfigurationHandler <DefaultSettings>("DefaultSettings"); var defaultConfig = defaultConfigHandler.Configuration(); var appConfig = appConfigHandler.Configuration(); var masterUri = Utilities.IsDevelopment ? new Uri("http://127.0.0.1:8080") : appConfig?.MasterUrl ?? new ApplicationConfiguration().MasterUrl; var httpClient = new HttpClient { BaseAddress = masterUri, Timeout = TimeSpan.FromSeconds(15) }; var masterRestClient = RestClient.For <IMasterApi>(httpClient); var translationLookup = Configure.Initialize(Utilities.DefaultLogger, masterRestClient, appConfig); if (appConfig == null) { appConfig = (ApplicationConfiguration) new ApplicationConfiguration().Generate(); appConfigHandler.Set(appConfig); appConfigHandler.Save(); } // register override level names foreach (var(key, value) in appConfig.OverridePermissionLevelNames) { if (!Utilities.PermissionLevelOverrides.ContainsKey(key)) { Utilities.PermissionLevelOverrides.Add(key, value); } } // build the dependency list HandlePluginRegistration(appConfig, serviceCollection, masterRestClient); serviceCollection .AddBaseLogger(appConfig) .AddSingleton(defaultConfig) .AddSingleton <IServiceCollection>(_serviceProvider => serviceCollection) .AddSingleton <IConfigurationHandler <DefaultSettings>, BaseConfigurationHandler <DefaultSettings> >() .AddSingleton((IConfigurationHandler <ApplicationConfiguration>)appConfigHandler) .AddSingleton( new BaseConfigurationHandler <CommandConfiguration>("CommandConfiguration") as IConfigurationHandler <CommandConfiguration>) .AddSingleton(appConfig) .AddSingleton(_serviceProvider => _serviceProvider.GetRequiredService <IConfigurationHandler <CommandConfiguration> >() .Configuration() ?? new CommandConfiguration()) .AddSingleton <IPluginImporter, PluginImporter>() .AddSingleton <IMiddlewareActionHandler, MiddlewareActionHandler>() .AddSingleton <IRConConnectionFactory, RConConnectionFactory>() .AddSingleton <IGameServerInstanceFactory, GameServerInstanceFactory>() .AddSingleton <IConfigurationHandlerFactory, ConfigurationHandlerFactory>() .AddSingleton <IParserRegexFactory, ParserRegexFactory>() .AddSingleton <IDatabaseContextFactory, DatabaseContextFactory>() .AddSingleton <IGameLogReaderFactory, GameLogReaderFactory>() .AddSingleton <IScriptCommandFactory, ScriptCommandFactory>() .AddSingleton <IAuditInformationRepository, AuditInformationRepository>() .AddSingleton <IEntityService <EFClient>, ClientService>() .AddSingleton <IMetaService, MetaService>() .AddSingleton <ClientService>() .AddSingleton <PenaltyService>() .AddSingleton <ChangeHistoryService>() .AddSingleton <IMetaRegistration, MetaRegistration>() .AddSingleton <IScriptPluginServiceResolver, ScriptPluginServiceResolver>() .AddSingleton <IResourceQueryHelper <ClientPaginationRequest, ReceivedPenaltyResponse>, ReceivedPenaltyResourceQueryHelper>() .AddSingleton <IResourceQueryHelper <ClientPaginationRequest, AdministeredPenaltyResponse>, AdministeredPenaltyResourceQueryHelper>() .AddSingleton <IResourceQueryHelper <ClientPaginationRequest, UpdatedAliasResponse>, UpdatedAliasResourceQueryHelper>() .AddSingleton <IResourceQueryHelper <ChatSearchQuery, MessageResponse>, ChatResourceQueryHelper>() .AddSingleton <IResourceQueryHelper <ClientPaginationRequest, ConnectionHistoryResponse>, ConnectionsResourceQueryHelper>() .AddTransient <IParserPatternMatcher, ParserPatternMatcher>() .AddSingleton <IRemoteAssemblyHandler, RemoteAssemblyHandler>() .AddSingleton <IMasterCommunication, MasterCommunication>() .AddSingleton <IManager, ApplicationManager>() .AddSingleton <SharedLibraryCore.Interfaces.ILogger, Logger>() .AddSingleton <IClientNoticeMessageFormatter, ClientNoticeMessageFormatter>() .AddSingleton <IClientStatisticCalculator, HitCalculator>() .AddSingleton <IServerDistributionCalculator, ServerDistributionCalculator>() .AddSingleton <IWeaponNameParser, WeaponNameParser>() .AddSingleton <IHitInfoBuilder, HitInfoBuilder>() .AddSingleton(typeof(ILookupCache <>), typeof(LookupCache <>)) .AddSingleton(typeof(IDataValueCache <,>), typeof(DataValueCache <,>)) .AddSingleton <IServerDataViewer, ServerDataViewer>() .AddSingleton <IServerDataCollector, ServerDataCollector>() .AddSingleton <IEventPublisher, EventPublisher>() .AddSingleton(translationLookup) .AddDatabaseContextOptions(appConfig); if (args.Contains("serialevents")) { serviceCollection.AddSingleton <IEventHandler, SerialGameEventHandler>(); } else { serviceCollection.AddSingleton <IEventHandler, GameEventHandler>(); } serviceCollection.AddSource(); return(serviceCollection); }