Esempio n. 1
0
    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);
    }
Esempio n. 2
0
        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();
        }
Esempio n. 3
0
        /// <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
            }));
        }
Esempio n. 4
0
        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();
        }
Esempio n. 5
0
        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);
                }
            }
        }
Esempio n. 6
0
        //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();
            }
        }
Esempio n. 7
0
        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
        }
Esempio n. 8
0
        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
        }
Esempio n. 9
0
        /// <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);
        }
Esempio n. 10
0
        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");
            }