예제 #1
0
        public MapWalkData(string name)
        {
            if (!DataManager.TryGetConfigValue("WalkPathData", out var walkPath))
            {
                throw new Exception("Configuration did not have section for WalkPathData!");
            }

            var path = Path.Combine(walkPath, name);


            //ServerLogger.Log("Loading path data from " + name);

            try
            {
                using var fs = new FileStream(path, FileMode.Open);
                using var br = new BinaryReader(fs);

                Width  = br.ReadInt32();
                Height = br.ReadInt32();

                cellData = br.ReadBytes(Width * Height);
            }
            catch (Exception)
            {
                ServerLogger.LogError($"Failed to load map data for file {name}");
                throw;
            }
        }
예제 #2
0
        public static void HandleMessage(NetIncomingMessage msg)
        {
            var type = (PacketType)msg.ReadByte();

#if DEBUG
            if (State.ConnectionLookup.TryGetValue(msg.SenderConnection, out var connection) && connection.Entity.IsAlive())
            {
                ServerLogger.Debug($"Received message of type: {System.Enum.GetName(typeof(PacketType), type)} from entity {connection.Entity}.");
            }
            else
            {
                ServerLogger.Debug($"Received message of type: {System.Enum.GetName(typeof(PacketType), type)} from entity-less connection.");
            }

            State.LastPacketType = type;
            State.PacketHandlers[(int)type](msg);
#endif
#if !DEBUG
            try
            {
                State.LastPacketType = type;
                State.PacketHandlers[(int)type](msg);
            }
            catch (Exception)
            {
                ServerLogger.LogError($"Error executing packet handler for packet type {type}");
                throw;
            }
#endif
        }
예제 #3
0
 public void Add(WorldObject obj)
 {
     if (!_objects.TryAdd(obj.Guid, obj))
     {
         ServerLogger.LogError($"{_server.Name}({_mapID}): Duplicate guid {obj.Guid}");
     }
 }
예제 #4
0
 private void View_Destroyed()
 {
     if ((m_state & SpawnedFlag) != 0)
     {
         Dispose();
         ServerLogger.LogError($"{Guid} view suddenly destroyed");
     }
 }
예제 #5
0
 public static bool SaveCharacter(Character entry)
 {
     if (ServerDB.UpdateCharacter(entry))
     {
         return(true);
     }
     ServerLogger.LogError($"Couldn't save character {entry.ID}");
     return(false);
 }
예제 #6
0
 public void ReleaseGuid(uint guid)
 {
     if (_released.Contains((ushort)guid))
     {
         ServerLogger.LogError($"{_server.Name}({_mapID}): attempt to release already released guid {guid & 0xFFFF}");
     }
     else
     {
         _released.Enqueue((ushort)(guid & 0xFFFF));
     }
 }
예제 #7
0
 public WO_NPC(DB_WorldObject data, ObjectsMgr manager)
     : base(manager.GetNewGuid() | Constants.ReleaseGuide, manager)
 {
     _data = data;
     if (!DataMgr.Select(data.ObjectID, out _npc))
     {
         ServerLogger.LogError($"NPC id {data.ObjectID} doesn't exist");
     }
     if ((_npc.Flags & NPCFlags.Dialog) > 0)
     {
         _dialog = _server.Dialogs.GetDialog(_npc.Dialog);
     }
     if ((_npc.Flags & NPCFlags.Trader) > 0)
     {
         shop_ser = new SER_Shop(_npc.Items, $"{_npc.Pony.Name}'s shop");
     }
     if ((_npc.Flags & NPCFlags.Wears) > 0)
     {
         DB_Item entry; byte slot;
         _wears    = new Dictionary <int, InventoryItem>();
         wears_ser = new SER_Wears(_wears);
         foreach (var item in _npc.Wears)
         {
             if (item > 0 && DataMgr.Select(item, out entry))
             {
                 slot = entry.Slot.ToWearableIndex();
                 if (_wears.ContainsKey(slot))
                 {
                     ServerLogger.LogWarn($"NPC id {data.ObjectID} duplicate wear slot {entry.Slot}");
                 }
                 else
                 {
                     _wears[slot] = new InventoryItem(item);
                 }
             }
         }
     }
     OnSpawn   += WO_NPC_OnSpawn;
     OnDespawn += WO_NPC_OnDespawn;
     OnDestroy += WO_NPC_OnDestroy;
     if ((_npc.Flags & NPCFlags.ScriptedMovement) > 0)
     {
         AddComponent(new ScriptedMovement(_npc.Movement, this));
     }
     else
     {
         AddComponent(new NullMovement(this));
     }
     m_char = new Character(_npc.ID, -1, _npc.Level, -1, _npc.Pony, null);
     Spawn();
 }
예제 #8
0
 public static void Add(IServer server)
 {
     if (s_servers.TryAdd(server.Guid, server))
     {
         if (server is MasterServer master)
         {
             s_master = master;
         }
     }
     else
     {
         ServerLogger.LogError($"Duplicate entry guid {server.Guid} name {server.Name}");
     }
 }
예제 #9
0
 public void Add(WorldObject obj)
 {
     lock (_objects)
     {
         if (_objects.ContainsKey(obj.Guid))
         {
             ServerLogger.LogError($"{_server.Name}({_mapID}): Duplicate guid {obj.Guid}");
         }
         else
         {
             _objects[obj.Guid] = obj;
         }
     }
 }
예제 #10
0
 private bool Load()
 {
     if (ServerDB.Connected && ServerDB.Ping())
     {
         ServerLogger.LogInfo($"Connected to database");
     }
     else
     {
         ServerLogger.LogError($"Couldn't connect to database: {Environment.NewLine}{ServerDB.ConnectionString}");
         return(false);
     }
     ServerLogger.LogInfo($"Data loaded: {DataMgr.Info}");
     return(true);
 }
예제 #11
0
 public WO_Switch(DB_WorldObject data, ObjectsMgr manager)
     : base(data, manager)
 {
     if (!DataMgr.Select(data.Data01, out m_map))
     {
         ServerLogger.LogError($"Map Switch {data.Guid} map {data.Data01} doesn't exist");
     }
     else
     {
         m_view = _server.Room.SceneViewManager.CreateNetworkedSceneObjectView(_data.Guid);
         m_view.SubscribeToRpc(1, RPC_001);
         OnDestroy += WO_Switch_OnDestroy;
     }
     Spawn();
 }
예제 #12
0
        private async Task <bool> LoadAsync()
        {
            if (await ServerDB.PingAsync())
            {
                ServerLogger.LogInfo($"Connected to database");
            }
            else
            {
                ServerLogger.LogError($"Couldn't connect to database: {Environment.NewLine}{ServerDB.ConnectionString}");
                return(false);
            }
            await DataMgr.LoadAllAsync();

            ServerLogger.LogInfo($"Data loaded: {DataMgr.Info}");
            return(true);
        }
예제 #13
0
 public WO_Pet(int id, WO_Player owner)
     : base(owner.Manager.GetNewGuid() | Constants.DRObject, owner.Manager)
 {
     _owner = owner;
     if (!DataMgr.Select(id, out _creature))
     {
         ServerLogger.LogError($"Creature id {id} doesn't exist");
     }
     else if (string.IsNullOrEmpty(_resource = DataMgr.SelectResource(_creature.Resource)))
     {
         ServerLogger.LogError($"Resource id {_creature.Resource} doesn't exist");
     }
     OnSpawn   += WO_Pet_OnSpawn;
     OnDestroy += WO_Pet_OnDestroy;
     AddComponent(new PetMovement(this));
     Spawn();
 }
예제 #14
0
 public static void Add(IRoom server)
 {
     lock (_servers)
     {
         if (_servers.Contains(server.Guid))
         {
             ServerLogger.LogError($"Duplicate entry guid {server.Guid} name {server.Name}");
         }
         else if (server is MapServer)
         {
             _mServers.Add(server.Guid, server as MapServer);
         }
         else if (server is CharServer)
         {
             _cServers.Add(server.Guid, server as CharServer);
         }
         _servers.Add(server.Guid);
     }
 }
예제 #15
0
 public WO_Pickup(DB_WorldObject data, ObjectsMgr manager)
     : base(manager.GetNewGuid() | Constants.IRObject, manager)
 {
     _data = data;
     if (data.Data01 <= 0)
     {
         ServerLogger.LogWarn($"Pickup {data.Guid} on map {data.Map} has negative or zero amount {data.Data01} of {data.ObjectID}");
     }
     if ((_data.Flags & 1) == 1 && data.Time.TotalSeconds <= 0)
     {
         ServerLogger.LogWarn($"Pickup {data.Guid} on map {data.Map} has respawn flag but negative or zero respawn time {data.Time}");
         _data.Flags &= 254;
     }
     if (!DataMgr.Select(data.ObjectID, out _item))
     {
         ServerLogger.LogError($"Item id {data.ObjectID} doesn't exist");
     }
     _resource  = DataMgr.SelectResource(data.Data02);
     OnSpawn   += WO_Pickup_OnSpawn;
     OnDespawn += WO_Pickup_OnDespawn;
     OnDestroy += WO_Pickup_OnDestroy;
     Spawn();
 }
예제 #16
0
 public WO_MOB(DB_WorldObject data, ObjectsMgr manager)
     : base(manager.GetNewGuid() | Constants.ReleaseGuide, manager)
 {
     _data = data;
     if (!DataMgr.Select(data.ObjectID, out _creature))
     {
         ServerLogger.LogError($"Creature id {data.ObjectID} doesn't exist");
     }
     else if (string.IsNullOrEmpty(_resource = DataMgr.SelectResource(_creature.Resource)))
     {
         ServerLogger.LogError($"Resource id {_creature.Resource} doesn't exist");
     }
     OnSpawn      += WO_MOB_OnSpawn;
     OnDespawn    += WO_MOB_OnDespawn;
     OnDestroy    += WO_MOB_OnDestroy;
     OnInitialize += WO_MOB_OnInitialize;
     OnKilled     += WO_MOB_OnKilled;
     AddComponent(new BasicAI(this));
     AddComponent(new MobStatsMgr(this));
     AddComponent(new MobMovement(this));
     AddComponent(new MobThreatMgr(this));
     Spawn();
 }
예제 #17
0
        public async Task StartAsync(CancellationToken cancellationToken, bool startThreads = true)
        {
            Debug.Assert(!_isStarting);

            if (_isStarting)
            {
                throw new InvalidOperationException();
            }

            _isStarting = true;
            _factory    = ManagerHost.CreateFactory(HandleException);
            CheckFactory();
            _factory.WinsockStartup();
            var m_masterUserSetting = await _masterSettingsService.GetCachedMasterSettingsAsync(cancellationToken);

            var mt4Accounts = await _mt4AccountService.GetAllMT4Accounts(cancellationToken);

            lock (_mt4LoginsByServerIndex)
                foreach (var mt4Account in mt4Accounts)
                {
                    AddMt4LoginNoLock(mt4Account._mt4ServerIndex, mt4Account._mt4Login);
                }

            m_ptrLogger.LogInfo("Initializng DEMO MT4 Manager");
            Debug.Assert(_demo == null);
            _demo = new WitFXServerConnector(
                eMT4ServerType.SRV_TYPE_DEMO, this, _factory,
                m_masterUserSetting._demoServer, m_masterUserSetting._demoManagerLogin,
                m_masterUserSetting._demoManagerPassword, _baseLogger, true, true,
                startThreads: startThreads);

            CppHelper.memcpy(ref _demo.m_masterUserSetting, m_masterUserSetting);

            //_demo.setMT4SocialUsers(m_mapMT4MasterLogin);
            //_demo.setMT4ResponseFunPtr(onMT4Response);
            //_demo.setMarketDataFunPtr(onMarketData);
            //_demo.setSymbolInfoFunPtr(onSymbolInfo);
            //_demo.setOnTradeFunPtr(onTradeResponse);
            //_demo.setOnMarginFunPtr(onMarginLevelResponse);

            m_ptrLogger.LogInfo("Initializng LIVE MT4 Manager");
            Debug.Assert(_live == null);
            _live = new WitFXServerConnector(
                eMT4ServerType.SRV_TYPE_LIVE, this, _factory,
                m_masterUserSetting._liveServer, m_masterUserSetting._liveManagerLogin,
                m_masterUserSetting._liveManagerPassword, _baseLogger, true, true,
                startThreads: startThreads);

            CppHelper.memcpy(ref _live.m_masterUserSetting, m_masterUserSetting);

            //_live.setMT4SocialUsers(m_mapMT4MasterLogin);
            //_live.setMT4ResponseFunPtr(onMT4Response);
            //_live.setOnTradeFunPtr(onTradeResponse);
            //_live.setOnMarginFunPtr(onMarginLevelResponse);

            if (startThreads)
            {
                if (_demo.IsAPIValid())
                {
                    m_ptrLogger.LogInfo("Starting DEMO MT4 Manager connection...");
                    _demo.startNormalManager();
                }
                else
                {
                    m_ptrLogger.LogError("MT4 MANAGER API IS NOT VALID");
                }
                if (_live.IsAPIValid())
                {
                    m_ptrLogger.LogInfo("Starting LIVE MT4 Manager connection...");
                    _live.startNormalManager();
                }
                else
                {
                    m_ptrLogger.LogError("MT4 MANAGER API IS NOT VALID");
                }

                var demoUpdateWorker = _updateWorkerFactory(eMT4ServerType.SRV_TYPE_DEMO);
                await demoUpdateWorker.ConfigureAsync(cancellationToken);

                _workerManager.StartWorker(demoUpdateWorker);

                var liveUpdateWorker = _updateWorkerFactory(eMT4ServerType.SRV_TYPE_LIVE);
                await liveUpdateWorker.ConfigureAsync(cancellationToken);

                _workerManager.StartWorker(liveUpdateWorker);
            }
        }
예제 #18
0
 protected void LogError(string message, ReturnCode code)
 {
     _logger.LogError($"{message}. {ErrorMessage(code)}");
 }
예제 #19
0
        public World()
        {
            Instance = this;

            var initialMaxEntities = NextPowerOf2(initialEntityCount);

            if (initialMaxEntities < 1024)
            {
                initialMaxEntities = 1024;
            }

            ecsWorld = new EcsWorld(initialMaxEntities);

            ecsSystems = new EcsSystems(ecsWorld)
                         .Inject(this)
                         .Add(new MonsterSystem())
                         .Add(new CharacterSystem())
                         .Add(new PlayerSystem());

            ecsSystems.Init();

            if (DataManager.TryGetConfigValue("SingleMobTest", out var mobName))
            {
                DataManager.DoSingleMobTest(mobName);
            }

            var maps = DataManager.Maps;

            var entities = 0;

            for (var j = 0; j < maps.Count; j++)
            {
                var mapData = maps[j];
                try
                {
                    var map = new Map(this, mapData.Code, mapData.WalkData);
                    map.Id = j;

                    mapIdLookup.Add(mapData.Code, j);

                    var spawns = DataManager.GetSpawnsForMap(mapData.Code);

                    if (spawns != null)
                    {
                        for (var i = 0; i < spawns.Count; i++)
                        {
                            var s     = spawns[i];
                            var mobId = DataManager.GetMonsterIdForCode(s.Class);

                            for (var k = 0; k < s.Count; k++)
                            {
                                var m = CreateMonster(map, mobId, s.X, s.Y, s.Width, s.Height, s);
                                if (!m.IsNull())
                                {
                                    map.AddEntity(ref m);
                                    entities++;
                                }
                            }
                        }
                    }

                    var connectors = DataManager.GetMapConnectors(mapData.Code);

                    if (connectors != null)
                    {
                        for (var i = 0; i < connectors.Count; i++)
                        {
                            var c     = connectors[i];
                            var mobId = 1000;

                            var m = CreateMonster(map, mobId, c.SrcArea.MidX, c.SrcArea.MidY, 0, 0, null);
                            if (!m.IsNull())
                            {
                                map.AddEntity(ref m);
                            }
                        }
                    }

                    Maps.Add(map);
                }
                catch (Exception e)
                {
                    ServerLogger.LogError($"Failed to load map {mapData.Name} ({mapData.Code}) due to error while loading: {e.Message}");
                }
            }

            mapCount = maps.Count;

            ServerLogger.Log($"World started with {entities} entities.");
        }
예제 #20
0
        //TODO: handleSSPFollowerRequest
        public async Task <AddSSPFollowerResponse> AddSSPFollower(
            AddSSPFollowerRequest ptr, CancellationToken cancellationToken)
        {
            AddSSPFollowerResponse ptrResp = null;

            m_ptrLogger.LogOk("START");

            if (ptr._dataTransMode == DT_TRANS_ADD)
            {
                await _followerService.InsertSSPFollower(ptr._sspfollower, cancellationToken);

                bool ret = true;
                ptrResp                = new AddSSPFollowerResponse(); //MT_AddSSPFollowerResponse_ID
                ptrResp._retCode       = ret == true ? RC_OK : RC_ERROR;
                ptrResp._dataTransMode = ptr._dataTransMode;
                CppHelper.memcpy(ref ptrResp._sspfollower, ptr._sspfollower);
                //SentDataUsingSocketID(ptrResp, MT_AddSSPFollowerResponse_ID, ptr._header._socketID);
                if (ret)
                {
                    //await AddFollowerAsync(ptr._sspfollower._sspMT4Login, ptr._sspfollower._followerMT4Login,
                    //    ptr._sspfollower._followerMT4ServerIndex, cancellationToken);
                    //await AddFollowerVolumeAsync(ptr._sspfollower._sspSignalIndex,
                    //    ptr._sspfollower._followerMT4ServerIndex, ptr._sspfollower._followerMT4Login,
                    //    ptr._sspfollower._followervolume, cancellationToken);

                    m_ptrLogger.LogInfo(
                        "SSP follower added. Follower master login: %d SSP master login : %d SignalIndex: %d",
                        ptr._sspfollower._followerMasterLogin, ptr._sspfollower._sspMasterLogin, ptr._sspfollower._sspSignalIndex);
                }
                else
                {
                    m_ptrLogger.LogError(
                        "Unable to add SSP follower. Follower master login: %d SSP master login : %d SignalIndex: %d",
                        ptr._sspfollower._followerMasterLogin, ptr._sspfollower._sspMasterLogin, ptr._sspfollower._sspSignalIndex);
                }
            }
            else if (ptr._dataTransMode == DT_TRANS_MODIFY)
            {
                await _followerService.ModifySSPFollower(ptr._sspfollower, cancellationToken);

                bool ret = true;
                ptrResp                = new AddSSPFollowerResponse(); // MT_AddSSPFollowerResponse_ID
                ptrResp._retCode       = ret == true ? RC_OK : RC_ERROR;
                ptrResp._dataTransMode = ptr._dataTransMode;
                CppHelper.memcpy(ref ptrResp._sspfollower, ptr._sspfollower);
                //SentDataUsingSocketID(ptrResp, MT_AddSSPFollowerResponse_ID, ptr._header._socketID);
                if (ret)
                {
                    //await UpdateFollowerVolumeAsync(ptr._sspfollower._sspSignalIndex, ptr._sspfollower._followerMT4ServerIndex,
                    //    ptr._sspfollower._followerMT4Login, ptr._sspfollower._followervolume, cancellationToken);

                    m_ptrLogger.LogInfo(
                        "SSP follower modified. Follower master login: %d SSP master login : %d SignalIndex: %d",
                        ptr._sspfollower._followerMasterLogin, ptr._sspfollower._sspMasterLogin, ptr._sspfollower._sspSignalIndex);
                }
                else
                {
                    m_ptrLogger.LogError(
                        "Unable to modify SSP follower. Follower master login: %d SSP master login : %d SignalIndex: %d",
                        ptr._sspfollower._followerMasterLogin, ptr._sspfollower._sspMasterLogin, ptr._sspfollower._sspSignalIndex);
                }
            }
            else if (ptr._dataTransMode == DT_TRANS_DELETE)
            {
                await _followerService.DeleteSSPFollower(ptr._sspfollower, cancellationToken);

                bool ret = true;
                ptrResp                = new AddSSPFollowerResponse(); // MT_AddSSPFollowerResponse_ID
                ptrResp._retCode       = ret == true ? RC_OK : RC_ERROR;
                ptrResp._dataTransMode = ptr._dataTransMode;
                CppHelper.memcpy(ref ptrResp._sspfollower, ptr._sspfollower);
                //SentDataUsingSocketID(ptrResp, MT_AddSSPFollowerResponse_ID, ptr._header._socketID);
                if (ret)
                {
                    //await RemoveFollowerAsync(ptr._sspfollower._sspMT4Login,
                    //    ptr._sspfollower._followerMT4Login,
                    //    ptr._sspfollower._followerMT4ServerIndex, cancellationToken);
                    //await RemoveFollowerVolumeAsync(ptr._sspfollower._sspSignalIndex,
                    //    ptr._sspfollower._followerMT4ServerIndex, ptr._sspfollower._followerMT4Login,
                    //    ptr._sspfollower._followervolume, cancellationToken);

                    m_ptrLogger.LogInfo(
                        "SSP follower deleted. Follower master login: %d SSP master login : %d SignalIndex: %d",
                        ptr._sspfollower._followerMasterLogin, ptr._sspfollower._sspMasterLogin, ptr._sspfollower._sspSignalIndex);
                }
                else
                {
                    m_ptrLogger.LogError(
                        "Unable to delete SSP follower. Follower master login: %d SSP master login : %d SignalIndex: %d",
                        ptr._sspfollower._followerMasterLogin, ptr._sspfollower._sspMasterLogin, ptr._sspfollower._sspSignalIndex);
                }
            }

            m_ptrLogger.LogOk("END");
            return(ptrResp);
        }