public Map GetMapWithMapName(string name) { Map map = Maps.Find(x => x.GetMapName == name); if (map == null) { Debug.LogWarning(name + " Map not found."); return(null); } return(map); }
private void AddPlaceBtn_Click(object sender, EventArgs e) { var map = Maps.Find(m => m.Name == manageMapBox.Text); if (map.Id == 0) { return; } var addplaceForm = new AddPlace(this, Settings, metroStyleManager.Theme, metroStyleManager.Style, Maps, map.Id, "", engine.GetPlayerInfo().PosX, engine.GetPlayerInfo().PosY, engine.GetPlayerInfo().PosZ); addplaceForm.ShowDialog(); RefreshPlaces(); }
/// <summary> /// Gets the time and estimated remaining time before a plane arrives /// </summary> /// <param name="id">Flight ID</param> /// <returns>JSON response with error, distance and time</returns> public IActionResult GetFlightRemaining(string id) { // Temporary variable FlightInfo info; // Try to find flight using (var context = new ApplicationDbContext()) info = context.FlightInfos.FirstOrDefault(f => f.Id == id || f.RegistrationNumber == id); // Check if it returned a value and that Departure and Destination is set if (info?.Departure == null || info.Destination == null) { return(new JsonResult(new { error = true, message = info == default(FlightInfo) ? "No flight info found" : info.Departure == null ? "No departure" : info.Destination == null ? "No destination" : "Unknown error" })); } // Calculate remaining distance (divided to get km instead of m) var destination = Maps.Find(info.Destination); if (Math.Abs(destination.Longitude) < 0.001f || Math.Abs(destination.Latitude) < 0.001f) { return(new JsonResult(new { error = true, message = "Destination not found" })); } var distance = Maps.GetDistance(new Coordinate(info.Longitude, info.Latitude), Maps.Find(info.Destination)) / 1000f; var hours = distance / info.SpeedKm; return(new JsonResult(new { error = false, distance, time = hours < 24 ? TimeSpan.FromHours(hours).ToString(@"hh\:mm") : "24:00+" // TODO: TimeSpan can get too large })); }
private void ManagePlacesBox_DoubleClick(object sender, EventArgs e) { if (managePlacesBox.SelectedIndex == -1) { return; } float[] coordiantes; var map = Maps.Find(m => m.Name == manageMapBox.Text); var place = map.Places.Find(p => p.Name == managePlacesBox.SelectedItem.ToString()); coordiantes = place.Coordinates; var editForm = new EditPlace(this, Settings, metroStyleManager.Theme, metroStyleManager.Style, Maps, map.Id, managePlacesBox.SelectedItem.ToString(), coordiantes, engine.GetPlayerInfo().PosX, engine.GetPlayerInfo().PosY, engine.GetPlayerInfo().PosZ); editForm.ShowDialog(); RefreshPlaces(); }
private void MapID_TextChanged(object sender, EventArgs e) { if (ImAlive()) { // Place box placeBox.Items.Clear(); placeBox.ResetText(); placeBox.Refresh(); Console.WriteLine(engine.GetMapInfo().Name); var map = Maps.Find(m => m.Id == engine.GetMapInfo().Id); if (map.Places == null) { return; } foreach (var place in map.Places) { placeBox.Items.Add(place.Name); } } }
//Process any server event override protected async Task ProcessEvent(GameEvent E) { if (E.Type == GameEvent.EventType.Connect) { // special case for IW5 when connect is from the log if (E.Extra != null) { var logClient = (Player)E.Extra; var client = (await this.GetStatusAsync()) .Single(c => c.ClientNumber == logClient.ClientNumber && c.Name == logClient.Name); client.NetworkId = logClient.NetworkId; await AddPlayer(client); // hack: to prevent plugins from registering it as a real connect E.Type = GameEvent.EventType.Unknown; } else { ChatHistory.Add(new ChatInfo() { Name = E.Origin.Name, Message = "CONNECTED", Time = DateTime.UtcNow }); if (E.Origin.Level > Player.Permission.Moderator) { await E.Origin.Tell(string.Format(loc["SERVER_REPORT_COUNT"], E.Owner.Reports.Count)); } } } else if (E.Type == GameEvent.EventType.Disconnect) { ChatHistory.Add(new ChatInfo() { Name = E.Origin.Name, Message = "DISCONNECTED", Time = DateTime.UtcNow }); } else if (E.Type == GameEvent.EventType.Script) { await ExecuteEvent(new GameEvent(GameEvent.EventType.Kill, E.Data, E.Origin, E.Target, this)); } if (E.Type == GameEvent.EventType.Say && E.Data.Length >= 2) { if (E.Data.Substring(0, 1) == "!" || E.Data.Substring(0, 1) == "@" || E.Origin.Level == Player.Permission.Console) { Command C = null; try { C = await ValidateCommand(E); } catch (CommandException e) { Logger.WriteInfo(e.Message); } if (C != null) { if (C.RequiresTarget && E.Target == null) { Logger.WriteWarning("Requested event (command) requiring target does not have a target!"); } try { if (!E.Remote && E.Origin.Level != Player.Permission.Console) { await ExecuteEvent(new GameEvent() { Type = GameEvent.EventType.Command, Data = string.Empty, Origin = E.Origin, Target = E.Target, Owner = this, Extra = C, Remote = E.Remote }); } await C.ExecuteAsync(E); } catch (AuthorizationException e) { await E.Origin.Tell($"{loc["COMMAND_NOTAUTHORIZED"]} - {e.Message}"); } catch (Exception Except) { Logger.WriteError(String.Format("A command request \"{0}\" generated an error.", C.Name)); Logger.WriteDebug(String.Format("Error Message: {0}", Except.Message)); Logger.WriteDebug(String.Format("Error Trace: {0}", Except.StackTrace)); await E.Origin.Tell("^1An internal error occured while processing your command^7"); #if DEBUG await E.Origin.Tell(Except.Message); #endif } } } else // Not a command { E.Data = E.Data.StripColors(); ChatHistory.Add(new ChatInfo() { Name = E.Origin.Name, Message = E.Data, Time = DateTime.UtcNow }); } } if (E.Type == GameEvent.EventType.MapChange) { Logger.WriteInfo($"New map loaded - {ClientNum} active players"); var dict = (Dictionary <string, string>)E.Extra; Gametype = dict["g_gametype"].StripColors(); Hostname = dict["sv_hostname"].StripColors(); string mapname = dict["mapname"].StripColors(); CurrentMap = Maps.Find(m => m.Name == mapname) ?? new Map() { Alias = mapname, Name = mapname }; } if (E.Type == GameEvent.EventType.MapEnd) { Logger.WriteInfo("Game ending..."); } //todo: move while (ChatHistory.Count > Math.Ceiling((double)ClientNum / 2)) { ChatHistory.RemoveAt(0); } // the last client hasn't fully disconnected yet // so there will still be at least 1 client left if (ClientNum < 2) { ChatHistory.Clear(); } }
public async Task Initialize() { RconParser = ServerConfig.UseT6MParser ? (IRConParser) new T6MRConParser() : new IW4RConParser(); if (ServerConfig.UseIW5MParser) { RconParser = new IW5MRConParser(); } var version = await this.GetDvarAsync <string>("version"); GameName = Utilities.GetGame(version.Value); if (GameName == Game.IW4) { EventParser = new IW4EventParser(); } else if (GameName == Game.IW5) { EventParser = new IW5EventParser(); } else if (GameName == Game.T6M) { EventParser = new T6MEventParser(); } else if (GameName == Game.UKN) { Logger.WriteWarning($"Game name not recognized: {version}"); } else { EventParser = new IW4EventParser(); } var shortversion = await this.GetDvarAsync <string>("shortversion"); var hostname = await this.GetDvarAsync <string>("sv_hostname"); var mapname = await this.GetDvarAsync <string>("mapname"); var maxplayers = (GameName == Game.IW4) ? // gotta love IW4 idiosyncrasies await this.GetDvarAsync <int>("party_maxplayers") : await this.GetDvarAsync <int>("sv_maxclients"); var gametype = await this.GetDvarAsync <string>("g_gametype"); var basepath = await this.GetDvarAsync <string>("fs_basepath"); WorkingDirectory = basepath.Value; var game = await this.GetDvarAsync <string>("fs_game"); var logfile = await this.GetDvarAsync <string>("g_log"); var logsync = await this.GetDvarAsync <int>("g_logsync"); try { var website = await this.GetDvarAsync <string>("_website"); Website = website.Value; } catch (DvarException) { Website = loc["SERVER_WEBSITE_GENERIC"]; } InitializeMaps(); this.Hostname = hostname.Value.StripColors(); this.CurrentMap = Maps.Find(m => m.Name == mapname.Value) ?? new Map() { Alias = mapname.Value, Name = mapname.Value }; this.MaxClients = maxplayers.Value; this.FSGame = game.Value; this.Gametype = gametype.Value; //wait this.SetDvarAsync("sv_kickbantime", 60); if (logsync.Value == 0 || logfile.Value == string.Empty) { // this DVAR isn't set until the a map is loaded await this.SetDvarAsync("logfile", 2); await this.SetDvarAsync("g_logsync", 2); // set to 2 for continous in other games, clamps to 1 for IW4 await this.SetDvarAsync("g_log", "games_mp.log"); Logger.WriteWarning("Game log file not properly initialized, restarting map..."); await this.ExecuteCommandAsync("map_restart"); logfile = await this.GetDvarAsync <string>("g_log"); } CustomCallback = await ScriptLoaded(); string mainPath = EventParser.GetGameDir(); #if DEBUG basepath.Value = @"\\192.168.88.253\Call of Duty Black Ops II"; #endif string logPath; if (GameName == Game.IW5) { logPath = ServerConfig.ManualLogPath; } else { logPath = game.Value == string.Empty ? $"{basepath.Value.Replace('\\', Path.DirectorySeparatorChar)}{Path.DirectorySeparatorChar}{mainPath}{Path.DirectorySeparatorChar}{logfile.Value}" : $"{basepath.Value.Replace('\\', Path.DirectorySeparatorChar)}{Path.DirectorySeparatorChar}{game.Value.Replace('/', Path.DirectorySeparatorChar)}{Path.DirectorySeparatorChar}{logfile.Value}"; } // hopefully fix wine drive name mangling if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { logPath = Regex.Replace(logPath, @"[A-Z]:", ""); } if (!File.Exists(logPath)) { Logger.WriteError($"Gamelog {logPath} does not exist!"); #if !DEBUG throw new ServerException($"Invalid gamelog file {logPath}"); #endif } else { LogFile = new IFile(logPath); } Logger.WriteInfo($"Log file is {logPath}"); #if DEBUG // LogFile = new RemoteFile("https://raidmax.org/IW4MAdmin/getlog.php"); #else await Broadcast(loc["BROADCAST_ONLINE"]); #endif }
public async Task Initialize() { RconParser = Manager.AdditionalRConParsers .FirstOrDefault(_parser => _parser.Version == ServerConfig.RConParserVersion); EventParser = Manager.AdditionalEventParsers .FirstOrDefault(_parser => _parser.Version == ServerConfig.EventParserVersion); RconParser = RconParser ?? new BaseRConParser(); EventParser = EventParser ?? new BaseEventParser(); RemoteConnection.SetConfiguration(RconParser.Configuration); var version = await this.GetDvarAsync <string>("version"); Version = version.Value; GameName = Utilities.GetGame(version?.Value ?? RconParser.Version); if (GameName == Game.UKN) { GameName = RconParser.GameName; } if (version?.Value?.Length != 0) { RconParser = Manager.AdditionalRConParsers.FirstOrDefault(_parser => _parser.Version == version.Value) ?? RconParser; EventParser = Manager.AdditionalEventParsers.FirstOrDefault(_parser => _parser.Version == version.Value) ?? EventParser; Version = RconParser.Version; } var infoResponse = RconParser.Configuration.CommandPrefixes.RConGetInfo != null ? await this.GetInfoAsync() : null; // this is normally slow, but I'm only doing it because different games have different prefixes var hostname = infoResponse == null ? (await this.GetDvarAsync <string>("sv_hostname")).Value : infoResponse.Where(kvp => kvp.Key.Contains("hostname")).Select(kvp => kvp.Value).First(); var mapname = infoResponse == null ? (await this.GetDvarAsync <string>("mapname")).Value : infoResponse["mapname"]; int maxplayers = (GameName == Game.IW4) ? // gotta love IW4 idiosyncrasies (await this.GetDvarAsync <int>("party_maxplayers")).Value : infoResponse == null ? (await this.GetDvarAsync <int>("sv_maxclients")).Value : Convert.ToInt32(infoResponse["sv_maxclients"]); var gametype = infoResponse == null ? (await this.GetDvarAsync <string>("g_gametype")).Value : infoResponse.Where(kvp => kvp.Key.Contains("gametype")).Select(kvp => kvp.Value).First(); var basepath = await this.GetDvarAsync <string>("fs_basepath"); var game = infoResponse == null || !infoResponse.ContainsKey("fs_game") ? (await this.GetDvarAsync <string>("fs_game")).Value : infoResponse["fs_game"]; var logfile = await this.GetDvarAsync <string>("g_log"); var logsync = await this.GetDvarAsync <int>("g_logsync"); var ip = await this.GetDvarAsync <string>("net_ip"); WorkingDirectory = basepath.Value; try { var website = await this.GetDvarAsync <string>("_website"); Website = website.Value; } catch (DvarException) { Website = loc["SERVER_WEBSITE_GENERIC"]; } InitializeMaps(); this.Hostname = hostname.StripColors(); this.CurrentMap = Maps.Find(m => m.Name == mapname) ?? new Map() { Alias = mapname, Name = mapname }; this.MaxClients = maxplayers; this.FSGame = game; this.Gametype = gametype; this.IP = ip.Value == "localhost" ? ServerConfig.IPAddress : ip.Value ?? ServerConfig.IPAddress; if ((logsync.Value == 0 || logfile.Value == string.Empty) && RconParser.CanGenerateLogPath) { // this DVAR isn't set until the a map is loaded await this.SetDvarAsync("logfile", 2); await this.SetDvarAsync("g_logsync", 2); // set to 2 for continous in other games, clamps to 1 for IW4 //await this.SetDvarAsync("g_log", "games_mp.log"); Logger.WriteWarning("Game log file not properly initialized, restarting map..."); await this.ExecuteCommandAsync("map_restart"); logfile = await this.GetDvarAsync <string>("g_log"); } CustomCallback = await ScriptLoaded(); // they've manually specified the log path if (!string.IsNullOrEmpty(ServerConfig.ManualLogPath)) { LogPath = ServerConfig.ManualLogPath; } else { string mainPath = EventParser.Configuration.GameDirectory; LogPath = string.IsNullOrEmpty(game) ? $"{basepath?.Value?.Replace('\\', Path.DirectorySeparatorChar)}{Path.DirectorySeparatorChar}{mainPath}{Path.DirectorySeparatorChar}{logfile?.Value}" : $"{basepath?.Value?.Replace('\\', Path.DirectorySeparatorChar)}{Path.DirectorySeparatorChar}{game?.Replace('/', Path.DirectorySeparatorChar)}{Path.DirectorySeparatorChar}{logfile?.Value}"; // fix wine drive name mangling if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { LogPath = Regex.Replace($"{Path.DirectorySeparatorChar}{LogPath}", @"[A-Z]:/", ""); } if (!File.Exists(LogPath) && ServerConfig.GameLogServerUrl == null) { Logger.WriteError(loc["SERVER_ERROR_DNE"].FormatExt(LogPath)); throw new ServerException(loc["SERVER_ERROR_DNE"].FormatExt(LogPath)); } } LogEvent = new GameLogEventDetection(this, LogPath, ServerConfig.GameLogServerUrl); Logger.WriteInfo($"Log file is {LogPath}"); _ = Task.Run(() => LogEvent.PollForChanges()); #if !DEBUG Broadcast(loc["BROADCAST_ONLINE"]); #endif }
/// <summary> /// Perform the server specific tasks when an event occurs /// </summary> /// <param name="E"></param> /// <returns></returns> override protected async Task <bool> ProcessEvent(GameEvent E) { if (E.Type == GameEvent.EventType.ConnectionLost) { var exception = E.Extra as Exception; Logger.WriteError(exception.Message); if (exception.Data["internal_exception"] != null) { Logger.WriteDebug($"Internal Exception: {exception.Data["internal_exception"]}"); } Logger.WriteInfo("Connection lost to server, so we are throttling the poll rate"); Throttled = true; } if (E.Type == GameEvent.EventType.ConnectionRestored) { if (Throttled) { Logger.WriteVerbose(loc["MANAGER_CONNECTION_REST"].FormatExt($"[{IP}:{Port}]")); } Logger.WriteInfo("Connection restored to server, so we are no longer throttling the poll rate"); Throttled = false; } if (E.Type == GameEvent.EventType.ChangePermission) { var newPermission = (Permission)E.Extra; if (newPermission < Permission.Moderator) { // remove banned or demoted privileged user Manager.GetPrivilegedClients().Remove(E.Target.ClientId); } else { if (Manager.GetPrivilegedClients().ContainsKey(E.Target.ClientId)) { Manager.GetPrivilegedClients()[E.Target.ClientId] = E.Target; } else { Manager.GetPrivilegedClients().Add(E.Target.ClientId, E.Target); } } Logger.WriteInfo($"{E.Origin} is setting {E.Target} to permission level {newPermission}"); await Manager.GetClientService().UpdateLevel(newPermission, E.Target, E.Origin); } else if (E.Type == GameEvent.EventType.PreConnect) { // we don't want to track bots in the database at all if ignore bots is requested if (E.Origin.IsBot && Manager.GetApplicationSettings().Configuration().IgnoreBots) { return(false); } var existingClient = GetClientsAsList().FirstOrDefault(_client => _client.Equals(E.Origin)); // they're already connected if (existingClient != null) { Logger.WriteWarning($"detected preconnect for {E.Origin}, but they are already connected"); return(false); } CONNECT: if (Clients[E.Origin.ClientNumber] == null) { #if DEBUG == true Logger.WriteDebug($"Begin PreConnect for {E.Origin}"); #endif // we can go ahead and put them in so that they don't get re added Clients[E.Origin.ClientNumber] = E.Origin; await OnClientConnected(E.Origin); ChatHistory.Add(new ChatInfo() { Name = E.Origin.Name, Message = "CONNECTED", Time = DateTime.UtcNow }); if (E.Origin.Level > EFClient.Permission.Moderator) { E.Origin.Tell(string.Format(loc["SERVER_REPORT_COUNT"], E.Owner.Reports.Count)); } } // for some reason there's still a client in the spot else { Logger.WriteWarning($"{E.Origin} is connecteding but {Clients[E.Origin.ClientNumber]} is currently in that client slot"); await OnClientDisconnected(Clients[E.Origin.ClientNumber]); goto CONNECT; } } else if (E.Type == GameEvent.EventType.Flag) { // todo: maybe move this to a seperate function Penalty newPenalty = new Penalty() { Type = Penalty.PenaltyType.Flag, Expires = DateTime.UtcNow, Offender = E.Target, Offense = E.Data, Punisher = E.Origin, When = DateTime.UtcNow, Link = E.Target.AliasLink }; var addedPenalty = await Manager.GetPenaltyService().Create(newPenalty); E.Target.SetLevel(Permission.Flagged, E.Origin); } else if (E.Type == GameEvent.EventType.Unflag) { var unflagPenalty = new Penalty() { Type = Penalty.PenaltyType.Unflag, Expires = DateTime.UtcNow, Offender = E.Target, Offense = E.Data, Punisher = E.Origin, When = DateTime.UtcNow, Link = E.Target.AliasLink }; await Manager.GetPenaltyService().Create(unflagPenalty); E.Target.SetLevel(Permission.User, E.Origin); } else if (E.Type == GameEvent.EventType.Report) { Reports.Add(new Report() { Origin = E.Origin, Target = E.Target, Reason = E.Data }); } else if (E.Type == GameEvent.EventType.TempBan) { await TempBan(E.Data, (TimeSpan)E.Extra, E.Target, E.Origin);; } else if (E.Type == GameEvent.EventType.Ban) { bool isEvade = E.Extra != null ? (bool)E.Extra : false; await Ban(E.Data, E.Target, E.Origin, isEvade); } else if (E.Type == GameEvent.EventType.Unban) { await Unban(E.Data, E.Target, E.Origin); } else if (E.Type == GameEvent.EventType.Kick) { await Kick(E.Data, E.Target, E.Origin); } else if (E.Type == GameEvent.EventType.Warn) { await Warn(E.Data, E.Target, E.Origin); } else if (E.Type == GameEvent.EventType.Disconnect) { ChatHistory.Add(new ChatInfo() { Name = E.Origin.Name, Message = "DISCONNECTED", Time = DateTime.UtcNow }); await new MetaService().AddPersistentMeta("LastMapPlayed", CurrentMap.Alias, E.Origin); await new MetaService().AddPersistentMeta("LastServerPlayed", E.Owner.Hostname, E.Origin); } else if (E.Type == GameEvent.EventType.PreDisconnect) { // predisconnect comes from minimal rcon polled players and minimal log players // so we need to disconnect the "full" version of the client var client = GetClientsAsList().FirstOrDefault(_client => _client.Equals(E.Origin)); if (client != null) { #if DEBUG == true Logger.WriteDebug($"Begin PreDisconnect for {client}"); #endif await OnClientDisconnected(client); #if DEBUG == true Logger.WriteDebug($"End PreDisconnect for {client}"); #endif } else if (client?.State != ClientState.Disconnecting) { Logger.WriteWarning($"Client {E.Origin} detected as disconnecting, but could not find them in the player list"); Logger.WriteDebug($"Expected {E.Origin} but found {GetClientsAsList().FirstOrDefault(_client => _client.ClientNumber == E.Origin.ClientNumber)}"); return(false); } } else if (E.Type == GameEvent.EventType.Update) { #if DEBUG == true Logger.WriteDebug($"Begin Update for {E.Origin}"); #endif await OnClientUpdate(E.Origin); } if (E.Type == GameEvent.EventType.Say) { E.Data = E.Data.StripColors(); if (E.Data?.Length > 0) { string message = E.Data; if (E.Data.IsQuickMessage()) { try { message = Manager.GetApplicationSettings().Configuration() .QuickMessages .First(_qm => _qm.Game == GameName) .Messages[E.Data.Substring(1)]; } catch { } } ChatHistory.Add(new ChatInfo() { Name = E.Origin.Name, Message = message, Time = DateTime.UtcNow }); } } if (E.Type == GameEvent.EventType.MapChange) { Logger.WriteInfo($"New map loaded - {ClientNum} active players"); // iw4 doesn't log the game info if (E.Extra == null) { var dict = await this.GetInfoAsync(); if (dict == null) { Logger.WriteWarning("Map change event response doesn't have any data"); } else { Gametype = dict["gametype"].StripColors(); Hostname = dict["hostname"]?.StripColors(); string mapname = dict["mapname"]?.StripColors() ?? CurrentMap.Name; CurrentMap = Maps.Find(m => m.Name == mapname) ?? new Map() { Alias = mapname, Name = mapname }; } } else { var dict = (Dictionary <string, string>)E.Extra; Gametype = dict["g_gametype"].StripColors(); Hostname = dict["sv_hostname"].StripColors(); MaxClients = int.Parse(dict["sv_maxclients"]); string mapname = dict["mapname"].StripColors(); CurrentMap = Maps.Find(m => m.Name == mapname) ?? new Map() { Alias = mapname, Name = mapname }; } } if (E.Type == GameEvent.EventType.MapEnd) { Logger.WriteInfo("Game ending..."); SessionStart = DateTime.UtcNow; } if (E.Type == GameEvent.EventType.Tell) { await Tell(E.Message, E.Target); } if (E.Type == GameEvent.EventType.Broadcast) { #if DEBUG == false // this is a little ugly but I don't want to change the abstract class if (E.Data != null) { await E.Owner.ExecuteCommandAsync(E.Data); } #endif } lock (ChatHistory) { while (ChatHistory.Count > Math.Ceiling(ClientNum / 2.0)) { ChatHistory.RemoveAt(0); } } // the last client hasn't fully disconnected yet // so there will still be at least 1 client left if (ClientNum < 2) { ChatHistory.Clear(); } return(true); }
public async Task Initialize() { var version = await this.GetDvarAsync<string>("version"); GameName = Utilities.GetGame(version.Value); if (GameName == Game.UKN) Logger.WriteWarning($"Game name not recognized: {version}"); var shortversion = await this.GetDvarAsync<string>("shortversion"); var hostname = await this.GetDvarAsync<string>("sv_hostname"); var mapname = await this.GetDvarAsync<string>("mapname"); var maxplayers = (GameName == Game.IW4) ? // gotta love IW4 idiosyncrasies await this.GetDvarAsync<int>("party_maxplayers") : await this.GetDvarAsync<int>("sv_maxclients"); var gametype = await this.GetDvarAsync<string>("g_gametype"); var basepath = await this.GetDvarAsync<string>("fs_basepath"); var game = await this.GetDvarAsync<string>("fs_game"); var logfile = await this.GetDvarAsync<string>("g_log"); var logsync = await this.GetDvarAsync<int>("g_logsync"); DVAR<int> onelog = null; if (GameName == Game.IW4) onelog = await this.GetDvarAsync<int>("iw4x_onelog"); try { var website = await this.GetDvarAsync<string>("_website"); Website = website.Value; } catch (SharedLibrary.Exceptions.DvarException) { Website = "this server's website"; } this.Hostname = hostname.Value.StripColors(); this.CurrentMap = Maps.Find(m => m.Name == mapname.Value) ?? new Map(mapname.Value, mapname.Value); this.MaxClients = maxplayers.Value; this.FSGame = game.Value; await this.SetDvarAsync("sv_kickbantime", 60); await this.SetDvarAsync("sv_network_fps", 1000); await this.SetDvarAsync("com_maxfps", 1000); if (logsync.Value == 0 || logfile.Value == string.Empty) { // this DVAR isn't set until the a map is loaded await this.SetDvarAsync("logfile", 2); await this.SetDvarAsync("g_logsync", 2); // set to 2 for continous in other games, clamps to 1 for IW4 await this.SetDvarAsync("g_log", "games_mp.log"); Logger.WriteWarning("Game log file not properly initialized, restarting map..."); await this.ExecuteCommandAsync("map_restart"); logfile = await this.GetDvarAsync<string>("g_log"); } CustomCallback = await ScriptLoaded(); #if DEBUG { basepath.Value = (GameName == Game.IW4) ? @"\\tsclient\J\WIN7_10.25\MW2" : @"\\tsclient\G\Program Files (x86)\Steam\SteamApps\common\Call of Duty 4"; } #endif string mainPath = (GameName == Game.IW4) ? "userraw" : "main"; string logPath = (game.Value == "" || onelog?.Value == 1) ? $"{ basepath.Value.Replace("\\", "/")}/{mainPath}/{logfile.Value}" : $"{basepath.Value.Replace("\\", "/")}/{game.Value}/{logfile.Value}"; if (!File.Exists(logPath)) { Logger.WriteError($"Gamelog {logPath} does not exist!"); #if !DEBUG throw new SharedLibrary.Exceptions.ServerException($"Invalid gamelog file {logPath}"); #endif } else { #if !DEBUG LogFile = new IFile(logPath); #else } LogFile = new RemoteFile("https://raidmax.org/IW4MAdmin/getlog.php"); #endif Logger.WriteInfo($"Log file is {logPath}"); #if !DEBUG await Broadcast("IW4M Admin is now ^2ONLINE"); }