Ejemplo n.º 1
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;
            }
        }
        public static Account GetOneAccount(string id, string charfilename)
        {
            var cmd = new SQLiteCommand(@"SELECT * FROM Characters Where ID = '" + id + @"' And CharCode = '" + charfilename + @"'", _conn);

            using (var reader = cmd.ExecuteReader())
            {
                reader.Read();
                var a = new Account
                {
                    CharName     = reader.GetString(0),
                    ID           = reader.GetString(1),
                    CharFileName = reader.GetString(2),
                    Money        = reader.GetInt32(3),
                    Ship         = (uint)reader.GetInt64(4),
                    System       = reader.GetString(5),
                    Location     = reader.GetString(6),
                    LastOnline   = reader.GetDateTime(7),
                    Rank         = reader.GetByte(8),
                    IsBanned     = reader.GetBoolean(9),
                    Settings     = reader.GetString(10),
                    ShipState    = reader.GetString(11),
                    Appearance   = reader.GetString(12),
                    Equipment    = reader.GetString(13),
                    Cargo        = reader.GetString(14),
                    RepList      = reader.GetString(15),
                    Visits       = reader.GetString(16),
                    TimeOnline   = (uint)reader.GetInt32(17),
                    UID          = reader.GetString(18)
                };
                Archetype arch = ArchetypeDB.Find(a.Ship);
                if (!(arch is ShipArchetype))
                {
                    _logiface.AddLog(LogType.ERROR, "Wrong ship archetype: " + a.CharName);
                    return(null);
                }

                return(a);
            }
        }
Ejemplo n.º 3
0
            public override void HandleTimerEvent(double deltaSeconds)
            {
                if (runner.System == UniverseDB.FindSystem("li01"))
                {
                    //TODO: AI debug here
                    for (int i = 0; i < 1; i++)
                    {
                        var npc = new Old.Object.Ship.Ship(runner);
                        npc.AI   = new AI.DebugAI(npc);
                        npc.Arch = ArchetypeDB.Find(FLUtility.CreateID("dsy_csv"));
                        if (npc.Arch == null)
                        {
                            return;
                        }

                        npc.Position = new Vector(-30000 + i * 300, i * 100, -25000);
                        //npc.orientation = ;
                        npc.Rank    = 20;
                        npc.System  = runner.System;
                        npc.Health  = 1.0f;
                        npc.faction = UniverseDB.FindFaction("fc_wild");
                        Loadout loadout = UniverseDB.FindLoadout("fc_j_ge_csv_loadout01");
                        if (loadout != null)
                        {
                            uint hpid = 34;
                            foreach (ShipItem item in loadout.Items)
                            {
                                var new_item = new ShipItem();
                                new_item.arch    = item.arch;
                                new_item.count   = item.count;
                                new_item.health  = 1.0f;
                                new_item.hpid    = hpid++;
                                new_item.hpname  = item.hpname;
                                new_item.mounted = item.mounted;
                                npc.Items.Add(new_item.hpid, new_item);
                            }
                        }
                        npc.InitialiseEquipmentSimulation();
                        runner.CreateSimObject(npc);
                    }
                }
                //    int total = 0;
                //    if (runner.players.Count > 0)
                //    {
                //        if (delta_seconds > 1.5)
                //            runner.log.AddLog(LogType.FL_MSG, "bad delta " + delta_seconds);

                //        // wow, this'll really suck if there are lots of NPCs
                //        foreach (Zone z in runner.system.zones)
                //        {
                //            if (z.shape != null && z.density > 0)
                //            {
                //                while (z.interference < z.density) // borrow this
                //                {
                //                    Ship npc = new Ship(runner);
                //                    npc.position = z.shape.position;
                //                    npc.orientation = z.shape.orientation;
                //                    npc.rank = 20;
                //                    npc.arch = ArchetypeDB.Find(FLUtility.CreateID("dsy_csv"));
                //                    npc.system = runner.system;
                //                    npc.health = 1.0f;
                //                    runner.CreateSimObject(npc);

                //                    z.interference++;
                //                    total++;
                //                }
                //            }
                //        }

                //        int working_npcs = 0;
                //        foreach (SimObject o in runner.objects.Values)
                //        {
                //            if (o.health > 0)
                //            {
                //                working_npcs++;

                //                foreach (Player player in runner.players.Values)
                //                {
                //                    if (player.ship != o)
                //                    {
                //                        Vector position = player.ship.position;
                //                        position.x += rand.Next(100);
                //                        position.z += rand.Next(100);
                //                        o.SetUpdateObject(position, player.ship.orientation, 1.0f, 0);
                //                    }
                //                }
                //            }
                //        }

                //        runner.log.AddLog(LogType.GENERAL, "system={0} npcs={1} objects={2} running={3}",
                //            runner.system.nickname, total, runner.objects.Count, working_npcs));

                //    }

                //    ExpireAfter(1);
            }
Ejemplo n.º 4
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);
                }
            }
        }
Ejemplo n.º 5
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;
            }
        }
Ejemplo n.º 7
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;
                }
            }
        }
        /// <summary>
        ///     Load the specified character file, resetting all character specific
        ///     content for this player and notifying all players of the name.
        /// </summary>
        /// <param name="account">Player account</param>
        /// <param name="log"></param>
        /// <returns>Returns null on successful load otherwise returns error message as a string.</returns>
        public string LoadCharFile(Account account, ILogController log)
        {
            if (account == null)
            {
                log.AddLog(LogType.ERROR, "Broken account found!");
                return("Account is null!");
            }
            //null checks made earlier
            // ReSharper disable once PossibleInvalidOperationException
            PlayerAccount = account;
            Wgrp          = new WeaponGroup();

// ReSharper disable once PossibleNullReferenceException
            Name  = PlayerAccount.CharName;
            Money = PlayerAccount.Money;

            var arch = ArchetypeDB.Find(PlayerAccount.Ship);

            if (arch is ShipArchetype)
            {
                Ship.Arch = arch;
            }
            else
            {
                return("invalid ship");
            }

            if (ShipState.RepGroup == "")
            {
                Ship.faction = new Faction();
            }
            else
            {
                Ship.faction = UniverseDB.FindFaction(ShipState.RepGroup);
                if (Ship.faction == null)
                {
                    return("invalid faction");
                }
            }

            Ship.System = UniverseDB.FindSystem(PlayerAccount.System);
            if (Ship.System == null)
            {
                return("invalid system");
            }

            if (ShipState.Base == null)
            {
                Ship.Basedata = null;
            }
            else
            {
                Ship.Basedata = UniverseDB.FindBase(ShipState.Base);
                if (Ship.Basedata == null)
                {
                    return("invalid base");
                }
            }

            if (ShipState.LastBase == "")
            {
                Ship.RespawnBasedata = null;
                return("no respawn base");
            }

            Ship.RespawnBasedata = UniverseDB.FindBase(ShipState.LastBase);
            if (Ship.RespawnBasedata == null)
            {
                return("invalid respawn base");
            }



            if (Ship.Basedata == null)
            {
                if (ShipState.Position != null)
                {
                    Ship.Position = ShipState.Position;
                }

                if (ShipState.Rotate != null)
                {
                    Ship.Orientation = Matrix.EulerDegToMatrix(ShipState.Rotate);
                }
            }

            //TODO: why ShipState.Hull is always true
            Ship.Health = ShipState.Hull;
            if (Ship.Health <= 0)
            {
                Ship.Health = 0.05f;
            }

            Ship.voiceid = FLUtility.CreateID(Appearance.Voice);

            //TODO: calculate rank
// ReSharper disable once PossibleNullReferenceException
            Ship.Rank = PlayerAccount.Rank;

            Ship.com_body      = Appearance.Body;
            Ship.com_head      = Appearance.Head;
            Ship.com_lefthand  = Appearance.LeftHand;
            Ship.com_righthand = Appearance.RightHand;

            Ship.Items.Clear();

            uint hpid = 34;

            foreach (var set in Equipment)
            {
                var si = new ShipItem
                {
                    arch    = ArchetypeDB.Find(set.Arch),
                    hpname  = set.HpName,
                    health  = set.Health,
                    count   = 1,
                    mission = false,
                    mounted = true,
                    hpid    = hpid++
                };
                Ship.Items[si.hpid] = si;
            }

            foreach (var set in Cargo)
            {
                var si = new ShipItem
                {
                    arch    = ArchetypeDB.Find(set.Arch),
                    hpname  = "",
                    count   = set.Count,
                    health  = 1.0f,
                    mission = false,
                    mounted = false,
                    hpid    = hpid++
                };
                Ship.Items[si.hpid] = si;
            }

            Ship.Reps.Clear();


            foreach (var set in RepDictionary)
            {
                float rep     = set.Value;
                var   faction = UniverseDB.FindFaction(set.Key);
                if (faction == null)
                {
// ReSharper disable once PossibleNullReferenceException
                    log.AddLog(LogType.ERROR, "error: faction not found char={0} faction={1}", account.CharName,
                               set.Value);
                }
                else
                {
                    Ship.Reps[faction] = rep;
                }
            }


            //Visits.Clear();
            //foreach (var set in Visits)
            //{
            //    Visits[set.Key] = set.Value;
            //}

            Ship.CurrentAction = null;

            return(null);
        }