Exemple #1
0
 private static void LoadBase(string fldatapath, string path, BaseData basedata, ILogController log)
 {
     try
     {
         var ini = new FLDataFile(path, true);
         foreach (FLDataFile.Section sec in ini.Sections)
         {
             string sectionName = sec.SectionName.ToLowerInvariant();
             if (sectionName == "baseinfo")
             {
                 basedata.StartRoom = String.Format("{0:x}_{1}", basedata.BaseID,
                                                    sec.GetSetting("start_room").Str(0));
                 basedata.StartRoomID = FLUtility.CreateID(basedata.StartRoom);
             }
             else if (sectionName == "room")
             {
                 var room = new Room {
                     Nickname = sec.GetSetting("nickname").Str(0).ToLowerInvariant()
                 };
                 room.RoomID = FLUtility.CreateID(room.Nickname);
                 path        = fldatapath + Path.DirectorySeparatorChar + sec.GetSetting("file").Str(0);
                 //I don't need room data at the moment. Yay.
                 //TODO: make LoadRoom?
                 //LoadRoom(fldatapath, path, basedata, room, log);
                 basedata.Rooms[room.Nickname] = room;
             }
         }
     }
     catch (Exception e)
     {
         log.AddLog(LogType.ERROR, "error: '" + e.Message + "' when parsing '" + path);
     }
 }
Exemple #2
0
        //TODO: <s>use LoadRoom</s>
        private static void LoadRoom(string fldatapath, string path, BaseData basedata, Room room, ILogController log)
        {
            try
            {
                var ini = new FLDataFile(path, true);
                foreach (var sec in ini.Sections)
                {
                    var sectionName = sec.SectionName.ToLowerInvariant();
                    if (sectionName != "room_info")
                    {
                        continue;
                    }
                    if (!sec.SettingExists("set_script"))
                    {
                        continue;
                    }
                    var setScript = sec.GetSetting("set_script").Str(0);
                    var thnText   = File.ReadAllText(fldatapath + Path.DirectorySeparatorChar + setScript);

                    var thn = new ThnParse();
                    thn.Parse(thnText);
                    foreach (var e in thn.entities.Where(e => e.type.ToLowerInvariant() == "marker"))
                    {
                        //TODO: so what
                    }
                }
            }
            catch (Exception e)
            {
                log.AddLog(LogType.ERROR, "error: '" + e.Message + "' when parsing '" + path);
            }
        }
Exemple #3
0
        /// <summary>
        ///     Load base market data and setup the prices for goods at each base.
        /// </summary>
        /// <param name="path"></param>
        private static void LoadBaseMarketData(string path, ILogController log)
        {
            var ini = new FLDataFile(path, true);

            foreach (var sec in ini.Sections)
            {
                string sectionName = sec.SectionName.ToLowerInvariant();

                if (sectionName != "basegood")
                {
                    continue;
                }

                var basedata = FindBase(sec.GetSetting("base").Str(0));
                if (basedata == null)
                {
                    log.AddLog(LogType.ERROR, "error: " + sec.Desc);
                    continue;
                }

                foreach (FLDataFile.Setting set in sec.Settings)
                {
                    var settingName = set.SettingName.ToLowerInvariant();
                    if (settingName != "marketgood")
                    {
                        continue;
                    }
                    var nickname                 = set.Str(0);
                    var level_needed_to_buy      = set.Float(1);
                    var reputation_needed_to_buy = set.Float(2);
                    var baseSells                = (set.UInt(5) == 1);
                    var basePriceMultiplier      = 1.0f;
                    if (set.NumValues() > 6)
                    {
                        basePriceMultiplier = set.Float(6);
                    }

                    var goodid = FLUtility.CreateID(nickname);
                    var good   = FindGood(goodid);
                    if (good == null)
                    {
                        log.AddLog(LogType.ERROR, "error: " + set.Desc);
                        continue;
                    }

                    if (baseSells)
                    {
                        basedata.GoodsForSale[goodid] = good.BasePrice * basePriceMultiplier;
                    }

                    basedata.GoodsToBuy[goodid] = good.BasePrice * basePriceMultiplier;
                }
            }
        }
Exemple #4
0
        /// <summary>
        ///     Load shop information for equipment and commodities.
        /// </summary>
        /// <param name="path"></param>
        private static void LoadGoodData(string path, ILogController log)
        {
            var ini = new FLDataFile(path, true);

            foreach (FLDataFile.Section sec in ini.Sections)
            {
                var sectionName = sec.SectionName.ToLowerInvariant();
                if (sectionName != "good")
                {
                    continue;
                }
                var good = new Good {
                    Nickname = sec.GetSetting("nickname").Str(0)
                };
                good.GoodID = FLUtility.CreateID(good.Nickname);
                string category = sec.GetSetting("category").Str(0);
                if (category == "equipment")
                {
                    good.category  = Good.Category.Equipment;
                    good.BasePrice = sec.GetSetting("price").Float(0);
                    uint archid = FLUtility.CreateID(sec.GetSetting("equipment").Str(0));
                    good.EquipmentOrShipArch = ArchetypeDB.Find(archid);
                }
                else if (category == "commodity")
                {
                    good.category  = Good.Category.Commodity;
                    good.BasePrice = sec.GetSetting("price").Float(0);
                    uint archid = FLUtility.CreateID(sec.GetSetting("equipment").Str(0));
                    good.EquipmentOrShipArch = ArchetypeDB.Find(archid);
                }
                else if (category == "shiphull")
                {
                    good.category  = Good.Category.ShipHull;
                    good.BasePrice = sec.GetSetting("price").Float(0);
                    uint archid = FLUtility.CreateID(sec.GetSetting("ship").Str(0));
                    good.EquipmentOrShipArch = ArchetypeDB.Find(archid);
                }
                else if (category == "ship")
                {
                    good.category = Good.Category.ShipPackage;
                    uint goodid = FLUtility.CreateID(sec.GetSetting("hull").Str(0));
                    good.Shiphull = Goods[goodid];
                }
                else
                {
                    log.AddLog(LogType.ERROR, "error: unknown category " + sec.Desc);
                }

                Goods[good.GoodID] = good;
            }
        }
Exemple #5
0
        // <summary>
        /// Load the factions from initial world.
        /// </summary>
        /// <param name="path"></param>
        private static void LoadFactions(string path, ILogController log)
        {
            var ini = new FLDataFile(path, true);

            foreach (FLDataFile.Section sec in ini.Sections)
            {
                string sectionName = sec.SectionName.ToLowerInvariant();
                if (sectionName == "group")
                {
                    var faction = new Faction {
                        Nickname = sec.GetSetting("nickname").Str(0)
                    };
                    faction.FactionID          = FLUtility.CreateFactionID(faction.Nickname);
                    Factions[faction.Nickname] = faction;
                }
            }
        }
Exemple #6
0
        public static void Load(string flPath, ILogController log)
        {
            // Load the universe and systems and all other static data
            string flIniPath = flPath + Path.DirectorySeparatorChar + "EXE" + Path.DirectorySeparatorChar +
                               "Freelancer.ini";

            try
            {
                var    flIni    = new FLDataFile(flIniPath, true);
                string dataPath =
                    Path.GetFullPath(Path.Combine(flPath + Path.DirectorySeparatorChar + "EXE",
                                                  flIni.GetSetting("Freelancer", "data path").Str(0)));

                log.AddLog(LogType.GENERAL, "Loading loadouts");
                foreach (var entry in flIni.GetSettings("Data", "loadouts"))
                {
                    LoadLoadout(dataPath + Path.DirectorySeparatorChar + entry.Str(0), log);
                }
                log.AddLog(LogType.GENERAL, "Loading factions");
                foreach (var entry in flIni.GetSettings("Data", "groups"))
                {
                    LoadFactions(dataPath + Path.DirectorySeparatorChar + entry.Str(0), log);
                }
                log.AddLog(LogType.GENERAL, "Loading universe");
                foreach (var entry in flIni.GetSettings("Data", "universe"))
                {
                    LoadUniverse(dataPath + Path.DirectorySeparatorChar + entry.Str(0), log);
                }
                log.AddLog(LogType.GENERAL, "Loading goods");
                foreach (var entry in flIni.GetSettings("Data", "goods"))
                {
                    LoadGoodData(dataPath + Path.DirectorySeparatorChar + entry.Str(0), log);
                }
                log.AddLog(LogType.GENERAL, "Loading markets");
                foreach (var entry in flIni.GetSettings("Data", "markets"))
                {
                    LoadBaseMarketData(dataPath + Path.DirectorySeparatorChar + entry.Str(0), log);
                }
            }
            catch (Exception e)
            {
                log.AddLog(LogType.ERROR, "error: '" + e.Message + "' when parsing '" + flIniPath);
            }
        }
Exemple #7
0
        /// <summary>
        ///     Load a single system
        /// </summary>
        /// <param name="path"></param>
        /// <param name="system"></param>
        /// <param name="log"></param>
        private static void LoadSystem(string path, StarSystem system, ILogController log)
        {
            try
            {
                var ini = new FLDataFile(path, true);
                foreach (FLDataFile.Section sec in ini.Sections)
                {
                    string sectionName = sec.SectionName.ToLowerInvariant();
                    if (sectionName == "zone")
                    {
                        var zone = new Zone {
                            shape = null, nickname = sec.GetSetting("nickname").Str(0)
                        };
                        zone.zoneid = FLUtility.CreateID(zone.nickname);

                        Vector position    = sec.GetSetting("pos").Vector();
                        var    orientation = new Matrix();

                        double[] size = null;

                        string shape = sec.GetSetting("shape").Str(0).ToLowerInvariant();

                        foreach (FLDataFile.Setting set in sec.Settings)
                        {
                            string settingName = set.SettingName.ToLowerInvariant();
                            switch (settingName)
                            {
                            case "rotation":
                                orientation = Matrix.EulerDegToMatrix(set.Vector());
                                break;

                            case "size":
                                size = new double[set.NumValues()];
                                for (int a = 0; a < size.Length; a++)
                                {
                                    size[a] = set.Float(a);
                                }
                                break;

                            case "damage":
                                zone.damage = set.Float(0);
                                break;

                            case "interference":
                                zone.interference = set.Float(0);
                                break;

                            case "encounter":
                                break;

                            case "faction":
                                break;

                            case "density":
                                zone.density = set.Float(0);
                                break;
                            }
                        }

                        if (size != null)
                        {
                            if (shape == "sphere" && size.Length == 1)
                            {
                                zone.shape = new Sphere(position, orientation, size[0]);
                            }
                            else if (shape == "cylinder" && size.Length == 2)
                            {
                                zone.shape = new Cylinder(position, orientation, size[0], size[1]);
                            }
                            else if (shape == "ellipsoid" && size.Length == 3)
                            {
                                zone.shape = new Ellipsoid(position, orientation, new Vector(size[0], size[1], size[2]));
                            }
                            else if (shape == "box" && size.Length == 3)
                            {
                                zone.shape = new Box(position, orientation, new Vector(size[0], size[1], size[2]));
                            }
                            else if (shape == "ring" && size.Length == 3)
                            {
                                zone.shape = new Ring(position, orientation, size[0], size[1], size[2]);
                            }
                        }

                        system.Zones.Add(zone);
                    }
                    else if (sectionName == "object")
                    {
                        var solar = new Object.Solar.Solar(system, sec.GetSetting("nickname").Str(0));

                        if (sec.SettingExists("pos"))
                        {
                            solar.Position = sec.GetSetting("pos").Vector();
                        }

                        if (sec.SettingExists("rotate"))
                        {
                            Vector euler = sec.GetSetting("rotate").Vector();
                            solar.Orientation = Matrix.EulerDegToMatrix(euler);
                        }

                        if (sec.SettingExists("base"))
                        {
                            // When a ship undocks, it undocks from the solar specified by baseid.
                            // uint baseid = FLUtility.CreateID(sec.GetSetting("base").Str(0));
                            // FIXME: check base exists
                            // solar.base_data = bases[baseid];
                            // bases[baseid].solar = solar;
                        }

                        if (sec.SettingExists("archetype"))
                        {
                            uint archetypeid = FLUtility.CreateID(sec.GetSetting("archetype").Str(0));
                            solar.Arch = ArchetypeDB.Find(archetypeid);
                            solar.GetLoadout();
                            // FIXME: check archetype exists
                        }

                        if (sec.SettingExists("dock_with"))
                        {
                            uint baseid = FLUtility.CreateID(sec.GetSetting("dock_with").Str(0));
                            solar.BaseData = Bases[baseid];
                        }

                        if (sec.SettingExists("goto"))
                        {
                            solar.DestinationObjid    = FLUtility.CreateID(sec.GetSetting("goto").Str(1));
                            solar.DestinationSystemid = FLUtility.CreateID(sec.GetSetting("goto").Str(0));
                        }

                        if (sec.SettingExists("prev_ring"))
                        {
                            solar.PrevRing = FLUtility.CreateID(sec.GetSetting("prev_ring").Str(0));
                        }

                        if (sec.SettingExists("next_ring"))
                        {
                            solar.NextRing = FLUtility.CreateID(sec.GetSetting("next_ring").Str(0));
                        }

                        if (sec.SettingExists("reputation"))
                        {
                            Faction faction = FindFaction(sec.GetSetting("reputation").Str(0));
                            if (faction == null)
                            {
                                log.AddLog(LogType.ERROR, "error: not valid faction={0}",
                                           sec.GetSetting("reputation").Str(0));
                            }
                            else
                            {
                                solar.Faction = faction;
                            }
                        }

                        // Rebuild the docking points from the archetype
                        // to the solar position and rotation.
                        foreach (DockingPoint dockingPoint in solar.Arch.DockingPoints)
                        {
                            var dockingObj = new DockingObject
                            {
                                Type          = dockingPoint.Type,
                                Solar         = solar,
                                Index         = (uint)solar.Arch.DockingPoints.IndexOf(dockingPoint),
                                DockingRadius = dockingPoint.DockingRadius,
                                Position      = solar.Orientation * dockingPoint.Position
                            };

                            // rotate the hardpoint by the base orientation and then
                            dockingObj.Position += solar.Position;

                            // the ship launch rotation is the base rotation rotated by the hardpoint rotation
                            dockingObj.Rotation = dockingPoint.Rotation * solar.Orientation;

                            if (solar.BaseData != null)
                            {
                                solar.BaseData.LaunchObjs.Add(dockingObj);
                            }

                            solar.DockingObjs.Add(dockingObj);
                        }


                        // Store the solar.
                        system.Solars[solar.Objid] = solar;
                        Solars[solar.Objid]        = solar;

                        if (solar.Arch.Type == Archetype.ObjectType.JUMP_GATE ||
                            solar.Arch.Type == Archetype.ObjectType.JUMP_HOLE)
                        {
                            system.Gates.Add(solar);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                log.AddLog(LogType.ERROR, "error: '" + e.Message + "' when parsing '" + path);
                if (e.InnerException != null)
                {
                    log.AddLog(LogType.ERROR, "error: '" + e.InnerException.Message + "' when parsing '" + path);
                }
            }
        }
Exemple #8
0
        /// <summary>
        ///     Load the universe
        /// </summary>
        /// <param name="path"></param>
        /// <param name="log"></param>
        private static void LoadUniverse(string path, ILogController log)
        {
            var universePath = Path.GetDirectoryName(path);
            var fldatapath   = Directory.GetParent(universePath).FullName;

            var ini = new FLDataFile(path, true);

            foreach (FLDataFile.Section sec in ini.Sections)
            {
                string sectionName = sec.SectionName.ToLowerInvariant();
                if (sectionName == "system")
                {
                    var system = new StarSystem {
                        Nickname = sec.GetSetting("nickname").Str(0)
                    };
                    system.SystemID = FLUtility.CreateID(system.Nickname);
                    LoadSystem(universePath + Path.DirectorySeparatorChar + sec.GetSetting("file").Str(0), system, log);
                    Systems[system.SystemID] = system;
                }
                else if (sectionName == "base")
                {
                    var basedata = new BaseData {
                        Nickname = sec.GetSetting("nickname").Str(0)
                    };
                    basedata.BaseID   = FLUtility.CreateID(basedata.Nickname);
                    basedata.SystemID = FLUtility.CreateID(sec.GetSetting("system").Str(0));
                    LoadBase(fldatapath, fldatapath + Path.DirectorySeparatorChar + sec.GetSetting("file").Str(0),
                             basedata, log);
                    Bases[basedata.BaseID] = basedata;
                }
            }

            // FIXME: Might want to dump this information to disk

            foreach (var syspair1 in Systems)
            {
                var systemMinDist = new Dictionary <uint, PathData>();
                var systemNext    = new Dictionary <uint, PathData>();
                foreach (var syspair2 in Systems)
                {
                    systemMinDist.Add(syspair2.Key, syspair1.Key == syspair2.Key ? 0 : ((uint)Systems.Count + 1));
                    systemNext.Add(syspair2.Key, 0);
                }
                MinimumDistances.Add(syspair1.Key, systemMinDist);
                NextIndex.Add(syspair1.Key, systemNext);

                syspair1.Value.CalculatePathfinding();
            }

            foreach (var syspair in Systems)
            {
                foreach (Object.Solar.Solar s in syspair.Value.Gates)
                {
                    PathData pd = MinimumDistances[syspair.Key][s.DestinationSystemid];
                    if (s.Arch.Type == Archetype.ObjectType.JUMP_GATE)
                    {
                        pd.Shortest = pd.Legal = 1;
                    }
                    else
                    {
                        pd.Shortest = pd.Illegal = 1;
                    }
                    MinimumDistances[syspair.Key][s.DestinationSystemid] = pd;
                }
            }

            foreach (var k in Systems)
            {
                foreach (var i in Systems)
                {
                    foreach (var j in Systems)
                    {
                        for (int x = -1; x <= 1; x++)
                        {
                            uint testDistance = MinimumDistances[i.Key][k.Key][x] + MinimumDistances[k.Key][j.Key][x];
                            if (testDistance < MinimumDistances[i.Key][j.Key][x])
                            {
                                PathData min = MinimumDistances[i.Key][j.Key];
                                min[x] = testDistance;
                                MinimumDistances[i.Key][j.Key] = min;

                                PathData index = NextIndex[i.Key][j.Key];
                                index[x] = k.Key;
                                NextIndex[i.Key][j.Key] = index;
                            }
                        }
                    }
                }
            }
        }
Exemple #9
0
        private static void LoadLoadout(string path, ILogController log)
        {
            var ini = new FLDataFile(path, true);

            foreach (FLDataFile.Section sec in ini.Sections)
            {
                string sectionName = sec.SectionName.ToLowerInvariant();
                if (sectionName == "loadout")
                {
                    var  loadout = new Loadout();
                    uint hpid    = 34;
                    foreach (FLDataFile.Setting set in sec.Settings)
                    {
                        if (set.SettingName == "nickname")
                        {
                            loadout.Nickname  = set.Str(0);
                            loadout.LoadoutID = FLUtility.CreateID(loadout.Nickname);
                        }
                        else if (set.SettingName == "equip")
                        {
                            var item = new ShipItem {
                                arch = ArchetypeDB.Find(FLUtility.CreateID(set.Str(0)))
                            };
                            if (item.arch == null)
                            {
                                continue; // TODO: log
                            }
                            item.hpname = "";
                            if (set.NumValues() > 1)
                            {
                                item.hpname = set.Str(1);
                            }
                            item.health  = 1.0f;
                            item.mission = false;
                            item.mounted = true;
                            item.count   = 1;
                            item.hpid    = hpid++;
                            loadout.Items.Add(item);
                        }
                        else if (set.SettingName == "cargo")
                        {
                            var item = new ShipItem {
                                arch = ArchetypeDB.Find(FLUtility.CreateID(set.Str(0)))
                            };
                            if (item.arch == null)
                            {
                                continue; // TODO: log
                            }
                            item.hpname  = "";
                            item.health  = 1.0f;
                            item.mission = false;
                            item.mounted = false;
                            item.count   = set.UInt(1);
                            item.hpid    = hpid++;
                            loadout.Items.Add(item);
                        }
                    }
                    Loadouts[loadout.LoadoutID] = loadout;
                }
            }
        }
        public void ThreadRun()
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

            try
            {
                _cfgFile = new FLDataFile("flopenserver.cfg", false);
                FLPath   = _cfgFile.GetSetting("server", "fl_path").Str(0);
                AcctPath = _cfgFile.GetSetting("server", "acct_path").Str(0);

                if (AcctPath == "")
                {
                    AcctPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) +
                               @"\My Games\Freelancer\Accts\MultiPlayer";
                }

                if (_cfgFile.SettingExists("server", "server_id"))
                {
                    ServerID = _cfgFile.GetSetting("server", "server_id").Str(0);
                }

                if (_cfgFile.SettingExists("server", "version"))
                {
                    server_version = _cfgFile.GetSetting("server", "version").Str(0);
                }

                if (server_version == "")
                {
                    FileVersionInfo myFileVersionInfo = FileVersionInfo.GetVersionInfo(FLPath + @"\EXE\Freelancer.exe");
                    var             ver = new int[4];
                    ver[0] = myFileVersionInfo.FileMajorPart;
                    ver[1] = myFileVersionInfo.FileMinorPart;
                    ver[2] = myFileVersionInfo.FileBuildPart;
                    ver[3] = myFileVersionInfo.FilePrivatePart;

                    var sb = new StringBuilder();
                    foreach (var num in ver)
                    {
                        sb.Append(".");
                        if (num < 10)
                        {
                            sb.Append("0");
                        }
                        sb.Append(num);
                    }

                    server_version = sb.ToString().Substring(1);
                }


                ServerDescription = _cfgFile.GetSetting("server", "description").Str(0);
                server_news       = _cfgFile.GetSetting("server", "news").Str(0);

                foreach (FLDataFile.Setting set in _cfgFile.GetSettings("intro_msg"))
                {
                    IntroMsg += set.Line;
                }

                foreach (FLDataFile.Setting set in _cfgFile.GetSettings("banner_msg"))
                {
                    BannerMsg += set.Line;
                }

                foreach (FLDataFile.Setting set in _cfgFile.GetSettings("user_help_msg"))
                {
                    UserHelpMsg += set.Line;
                }

                foreach (FLDataFile.Setting set in _cfgFile.GetSettings("admin_help_msg"))
                {
                    AdminHelpMsg += set.Line;
                }
            }
            catch (Exception e)
            {
                _log.AddLog(LogType.ERROR, "error: flopenserver.cfg not found or missing parameter " + e.Message);
                return;
            }

            string name        = _cfgFile.GetSetting("server", "name").Str(0);
            uint   port        = _cfgFile.GetSetting("server", "port").UInt(0);
            var    max_players = (int)_cfgFile.GetSetting("server", "max_players").UInt(0);

            if (ServerID == null)
            {
                ReadFLDefaults();
            }

            _log.AddLog(LogType.GENERAL, "cfg_file = " + _cfgFile.FilePath);
            _log.AddLog(LogType.GENERAL, "fl_path = " + FLPath);
            _log.AddLog(LogType.GENERAL, "acct_path = " + AcctPath);
            _log.AddLog(LogType.GENERAL, "server_id = " + ServerID);
            _log.AddLog(LogType.GENERAL, "version = " + server_version);
            _log.AddLog(LogType.GENERAL, "name = " + name);
            _log.AddLog(LogType.GENERAL, "port = " + port);
            _log.AddLog(LogType.GENERAL, "max_players = " + max_players);


            ArchetypeDB.Load(FLPath, _log);
            UniverseDB.Load(FLPath, _log);
            News.Load(FLPath, _log);
            _log.AddLog(LogType.GENERAL, "Ready to start");

            try
            {
                string[] arg     = server_version.Split('.');
                uint     major   = uint.Parse(arg[0]) & 0xFF;
                uint     minor   = uint.Parse(arg[1]) & 0xFF;
                uint     patch   = uint.Parse(arg[2]) & 0xFF;
                uint     build   = uint.Parse(arg[3]) & 0xFF;
                uint     version = (major << 24) | (minor << 16) | (patch << 8) | build;
                server_version = version.ToString(CultureInfo.InvariantCulture);
            }
            catch
            {
                _log.AddLog(LogType.ERROR, "invalid server version string");
                server_version = "0";
            }

            // Try to start the direct play server. Complain if it fails but don't pass the exception on.
            try
            {
                _dplay = new DirectPlayServer(this, _log, (int)port)
                {
                    server_name        = name + "\0",
                    server_id          = ServerID,
                    server_description = ServerDescription + "\0",
                    server_version     = server_version,
                    max_players        = (uint)max_players
                };
                _log.AddLog(LogType.GENERAL, "Server started");
            }
            catch (Exception e)
            {
                _log.AddLog(LogType.ERROR, "Cannot open socket reason={0}", e.Message);
            }

            _dplay.GotMessage      += _dplay_GotMessage;
            _dplay.PlayerConnected += _dplay_PlayerConnected;
            _dplay.PlayerDestroyed += _dplay_PlayerDestroyed;

            // Kick off the game runner threads. We have one thread per system. New
            // players who have not selected a character are assigned to a random
            // runner thread.
            uint baseObjid = 1;

            foreach (var starSystem in UniverseDB.Systems.Values)
            {
                _runners[starSystem] = new DPGameRunner(this, _log, baseObjid, starSystem);
                baseObjid           += 10000;
            }
        }
Exemple #11
0
        public void ThreadRun()
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

            try
            {
                _cfgFile = new FLDataFile("flopenserver.cfg", false);
                FLPath   = _cfgFile.GetSetting("server", "fl_path").Str(0);
                AcctPath = _cfgFile.GetSetting("server", "acct_path").Str(0);

                if (AcctPath == "")
                {
                    AcctPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) +
                               @"\My Games\Freelancer\Accts\MultiPlayer";
                }

                if (_cfgFile.SettingExists("server", "server_id"))
                {
                    ServerID = _cfgFile.GetSetting("server", "server_id").Str(0);
                }

                if (_cfgFile.SettingExists("server", "version"))
                {
                    server_version = _cfgFile.GetSetting("server", "version").Str(0);
                }

                if (server_version == "")
                {
                    FileVersionInfo myFileVersionInfo = FileVersionInfo.GetVersionInfo(FLPath + @"\EXE\Freelancer.exe");
                    var             ver = new int[4];
                    ver[0] = myFileVersionInfo.FileMajorPart;
                    ver[1] = myFileVersionInfo.FileMinorPart;
                    ver[2] = myFileVersionInfo.FileBuildPart;
                    ver[3] = myFileVersionInfo.FilePrivatePart;

                    var sb = new StringBuilder();
                    foreach (var num in ver)
                    {
                        sb.Append(".");
                        if (num < 10)
                        {
                            sb.Append("0");
                        }
                        sb.Append(num);
                    }

                    server_version = sb.ToString().Substring(1);
                }


                ServerDescription = _cfgFile.GetSetting("server", "description").Str(0);
                server_news       = _cfgFile.GetSetting("server", "news").Str(0);

                foreach (FLDataFile.Setting set in _cfgFile.GetSettings("intro_msg"))
                {
                    IntroMsg += set.Line;
                }

                foreach (FLDataFile.Setting set in _cfgFile.GetSettings("banner_msg"))
                {
                    BannerMsg += set.Line;
                }

                foreach (FLDataFile.Setting set in _cfgFile.GetSettings("user_help_msg"))
                {
                    UserHelpMsg += set.Line;
                }

                foreach (FLDataFile.Setting set in _cfgFile.GetSettings("admin_help_msg"))
                {
                    AdminHelpMsg += set.Line;
                }
            }
            catch (Exception e)
            {
                _log.AddLog(LogType.ERROR, "error: flopenserver.cfg not found or missing parameter " + e.Message);
                return;
            }

            string name        = _cfgFile.GetSetting("server", "name").Str(0);
            uint   port        = _cfgFile.GetSetting("server", "port").UInt(0);
            var    max_players = (int)_cfgFile.GetSetting("server", "max_players").UInt(0);

            if (ServerID == null)
            {
                ReadFLDefaults();
            }

            _log.AddLog(LogType.GENERAL, "cfg_file = " + _cfgFile.FilePath);
            _log.AddLog(LogType.GENERAL, "fl_path = " + FLPath);
            _log.AddLog(LogType.GENERAL, "acct_path = " + AcctPath);
            _log.AddLog(LogType.GENERAL, "server_id = " + ServerID);
            _log.AddLog(LogType.GENERAL, "version = " + server_version);
            _log.AddLog(LogType.GENERAL, "name = " + name);
            _log.AddLog(LogType.GENERAL, "port = " + port);
            _log.AddLog(LogType.GENERAL, "max_players = " + max_players);


            ArchetypeDB.Load(FLPath, _log);
            UniverseDB.Load(FLPath, _log);
            News.Load(FLPath, _log);
            _log.AddLog(LogType.GENERAL, "Ready to start");

            try
            {
                string[] arg     = server_version.Split('.');
                uint     major   = uint.Parse(arg[0]) & 0xFF;
                uint     minor   = uint.Parse(arg[1]) & 0xFF;
                uint     patch   = uint.Parse(arg[2]) & 0xFF;
                uint     build   = uint.Parse(arg[3]) & 0xFF;
                uint     version = (major << 24) | (minor << 16) | (patch << 8) | build;
                server_version = version.ToString(CultureInfo.InvariantCulture);
            }
            catch
            {
                _log.AddLog(LogType.ERROR, "invalid server version string");
                server_version = "0";
            }

            // Try to start the direct play server. Complain if it fails but don't pass the exception on.
            try
            {
                _dplay = new DirectPlayServer(this, _log, (int)port)
                {
                    server_name        = name + "\0",
                    server_id          = ServerID,
                    server_description = ServerDescription + "\0",
                    server_version     = server_version,
                    max_players        = (uint)max_players
                };
                _log.AddLog(LogType.GENERAL, "Server started");
            }
            catch (Exception e)
            {
                _log.AddLog(LogType.ERROR, "Cannot open socket reason={0}", e.Message);
            }

            // Kick off the game runner threads. We have one thread per system. New
            // players who have not selected a character are assigned to a random
            // runner thread.
            uint baseObjid = 1;

            foreach (var starSystem in UniverseDB.Systems.Values)
            {
                _runners[starSystem] = new DPGameRunner(this, _log, baseObjid, starSystem);
                baseObjid           += 10000;
            }

            // Run the event/timer processing loop for this thread.
            var currentTime = Utilities.GetTime();
            var running     = true;

            while (running)
            {
                // Calculate the delta time.
                var delta = Utilities.GetTime() - currentTime;
                currentTime += delta;

                // Call the reactor to return the next event the process
                // and run any timer functions.
                var nextEvent = Run(currentTime, delta);

                if (nextEvent is DPSessionConnectedEvent)
                {
                    // On receipt of a new connection, create a new player assigning it to a
                    // random game thread. Notify all game threads of the new player.
                    var serverEvent = nextEvent as DPSessionConnectedEvent;

                    var defaultRunner = _runners.ElementAt(_rand.Next(_runners.Count - 1)).Value;

                    var player = new Player.Player(serverEvent.dplayid, _log, NewPlayerID(), defaultRunner);
                    Players[serverEvent.dplayid] = player;

                    foreach (var runner in _runners.Values)
                    {
                        runner.AddEvent(new DPGameRunnerPlayerUpdateEvent(player));
                    }
                }
                else if (nextEvent is DPSessionTerminatedEvent)
                {
                    // The session has died. Tell all game threads that it is dead and the player
                    // is gone.
                    // TODO: save player?
                    var serverEvent = nextEvent as DPSessionTerminatedEvent;
                    if (Players.ContainsKey(serverEvent.dplayid))
                    {
                        var player = Players[serverEvent.dplayid];
                        Players.Remove(serverEvent.dplayid);

                        foreach (var runner in _runners.Values)
                        {
                            runner.AddEvent(new DPGameRunnerPlayerDeletedEvent(player.FLPlayerID));
                        }
                    }

                    // Kill the dplay connection if it is not already dead
                    try
                    {
                        /* fixme: dplay.DestroyClient(server_event.dplayid, null); */
                    }
                    catch
                    {
                    }
                }
                else if (nextEvent is DPGameRunnerPlayerUpdateEvent)
                {
                    // A game thread has sent a notification to say that the player has changed - either
                    // name, rank or system. We might change the assigned thread as a result.
                    // In any case, we notify all game threads of the current name, rank and system.
                    var serverEvent = nextEvent as DPGameRunnerPlayerUpdateEvent;

                    // Find runner for this system and if it's changed tell the old and new runners
                    // of the change in ownership.
                    var currRunner = serverEvent.runner;
                    var newRunner  = _runners[serverEvent.system];
                    if (newRunner != currRunner)
                    {
                        serverEvent.runner = newRunner;
                    }

                    // Notify all game threads of the current player info so they can update their
                    // player lists.
                    foreach (var runner in _runners.Values)
                    {
                        runner.AddEvent(serverEvent);
                    }
                }
                else if (nextEvent is DPSessionRxMessageFromClient)
                {
                    var server_event = nextEvent as DPSessionRxMessageFromClient;
                    if (Players.ContainsKey(server_event.dplayid))
                    {
                        Player.Player player = Players[server_event.dplayid];
                        player.Runner.AddEvent(new DPGameRunnerRxMsgEvent(player, server_event.msg));
                    }
                }
                else if (nextEvent is ReactorShutdownEvent)
                {
                    foreach (DPGameRunner runner in _runners.Values)
                    {
                        runner.AddEvent(new ReactorShutdownEvent());
                    }
                    running = false;
                }
            }
        }