Пример #1
0
        public static void SendToServer(ModelPlayToServer toServ)
        {
            toServ.LastTick = (long)Find.TickManager.TicksGame;

            //отправка всех новых и измененных объектов игрока
            toServ.WObjects = Find.WorldObjects.AllWorldObjects
                              .Where(o => o.Faction != null && o.Faction.IsPlayer && !(o is CaravanOnline) && !(o is BaseOnline))
                              .Select(o => GetWorldObjectEntry(o))
                              .ToList();

            //свои объекты которые удалил пользователь с последнего обновления
            if (ToDelete != null)
            {
                var toDeleteNewNow = MyWorldObjectEntry
                                     .Where(p => !Find.WorldObjects.AllWorldObjects.Any(wo => wo.ID == p.Key))
                                     .Select(p => p.Value)
                                     .ToList();
                ToDelete.AddRange(toDeleteNewNow);
            }

            toServ.WObjectsToDelete = ToDelete;
        }
        private static void UpdateWorld(bool firstRun = false)
        {
            lock (UpdatingWorld)
            {
                Command((connect) =>
                {
                    //собираем пакет на сервер
                    var toServ = new ModelPlayToServer()
                    {
                        UpdateTime = Data.UpdateTime, //время прошлого запроса
                    };
                    //данные сохранения игры
                    if (Data.SaveFileData != null)
                    {
                        toServ.SaveFileData = Data.SaveFileData;
                        Data.SaveFileData   = null;
                    }

                    //собираем данные с планеты
                    if (!firstRun)
                    {
                        UpdateWorldController.SendToServer(toServ);
                    }

                    //запрос на информацию об игроках. Можно будет ограничить редкое получение для тех кто оффлайн
                    if (Data.Chats != null && Data.Chats[0].PartyLogin != null)
                    {
                        toServ.GetPlayersInfo = Data.Chats[0].PartyLogin;
                    }

                    //отправляем на сервер, получаем ответ
                    ModelPlayToClient fromServ = connect.PlayInfo(toServ);
                    Loger.Log("Client " + My.Login + " UpdateWorld "
                              + string.Format("Отпр. свои {0}, своиDel {1}{5}. Пришло {2}, del {3}, посылок {4}"
                                              , toServ.WObjects == null ? 0 : toServ.WObjects.Count
                                              , toServ.WObjectsToDelete == null ? 0 : toServ.WObjectsToDelete.Count
                                              , fromServ.WObjects == null ? 0 : fromServ.WObjects.Count
                                              , fromServ.WObjectsToDelete == null ? 0 : fromServ.WObjectsToDelete.Count
                                              , fromServ.Mails == null ? 0 : fromServ.Mails.Count
                                              , toServ.SaveFileData == null || toServ.SaveFileData.Length == 0 ? "" : ", сейв"
                                              ));

                    //сохраняем время актуальности данных
                    Data.UpdateTime = fromServ.UpdateTime;

                    //обновляем информацию по игрокам
                    if (fromServ.PlayersInfo != null && fromServ.PlayersInfo.Count > 0)
                    {
                        foreach (var pi in fromServ.PlayersInfo)
                        {
                            if (pi.Login == null)
                            {
                                continue;
                            }
                            if (Data.Players.ContainsKey(pi.Login))
                            {
                                Data.Players[pi.Login] = new PlayerClient()
                                {
                                    Public = pi
                                }
                            }
                            ;
                            else
                            {
                                Data.Players.Add(pi.Login, new PlayerClient()
                                {
                                    Public = pi
                                });
                            }
                        }
                    }
                    var allWObjects = Find.WorldObjects.AllWorldObjects
                                      .Where(o => o is CaravanOnline)
                                      .Select(o => o as CaravanOnline)
                                      .ToList();
                    foreach (var pi in Data.Players)
                    {
                        pi.Value.WObjects = allWObjects.Where(wo => wo.OnlinePlayerLogin == pi.Key).ToList();
                    }

                    //обновляем планету
                    UpdateWorldController.LoadFromServer(fromServ);
                });
            }
        }
Пример #3
0
        public ModelPlayToClient PlayInfo(ModelPlayToServer packet)
        {
            if (Player == null)
            {
                return(null);
            }

            lock (Player)
            {
                var data     = Repository.GetData;
                var timeNow  = DateTime.UtcNow;
                var toClient = new ModelPlayToClient();
                toClient.UpdateTime = timeNow;
                if (packet.GetPlayersInfo != null && packet.GetPlayersInfo.Count > 0)
                {
                    var pSee = PartyLoginSee();
                    var pGet = pSee.Where(s => packet.GetPlayersInfo.Any(p => s == p)).ToList();
                    toClient.PlayersInfo = Repository.GetData.PlayersAll
                                           .Where(p => pGet.Any(g => g == p.Public.Login))
                                           .Select(p => p.Public)
                                           .ToList();
                    if (pGet.Any(p => p == null))
                    {
                        Loger.Log("nulllllll");
                    }
                }
                if (packet.SaveFileData != null && packet.SaveFileData.Length > 0)
                {
                    Player.SaveDataPacket      = packet.SaveFileData;
                    Player.Public.LastSaveTime = timeNow;
                    Repository.Get.ChangeData  = true;
                }
                Player.Public.LastTick = packet.LastTick;

                var pLogin = Player.Public.Login;
                //packet.WObjects тут все объекты этого игрока, добавляем которых у нас нет
                var pWOs = packet.WObjects ?? new List <WorldObjectEntry>();
                //packet.WObjectsToDelete тут те объекты этого игрока, что нужно удалить
                var pDs = packet.WObjectsToDelete ?? new List <WorldObjectEntry>();
                //передаем назад объекты у которых не было ServerId, т.е. они новые для сервера + все с изменениями
                var outWO  = new List <WorldObjectEntry>();
                var outWOD = new List <WorldObjectEntry>();
                //это первое обращение, если не прислали своих объектов
                var first = pWOs.Count == 0;
                lock (data)
                {
                    for (int i = 0; i < pDs.Count; i++)
                    {
                        if (pDs[i].LoginOwner != Player.Public.Login)
                        {
                            continue;
                        }
                        var sid = pDs[i].ServerId;
                        var pD  = data.WorldObjects.FirstOrDefault(p => p.ServerId == sid);
                        if (pD != null)
                        {
                            //удаление из базы
                            pD.UpdateTime = timeNow;
                            data.WorldObjects.Remove(pD);
                            data.WorldObjectsDeleted.Add(pD);
                        }
                    }

                    for (int i = 0; i < pWOs.Count; i++)
                    {
                        if (pWOs[i].LoginOwner != Player.Public.Login)
                        {
                            continue;                                            // <-на всякий случай
                        }
                        var sid = pWOs[i].ServerId;
                        if (sid == 0)
                        {
                            //добавление в базу
                            pWOs[i].UpdateTime = timeNow;
                            pWOs[i].ServerId   = data.GetWorldObjectEntryId();
                            data.WorldObjects.Add(pWOs[i]);
                            outWO.Add(pWOs[i]);
                            continue;
                        }
                        var WO = data.WorldObjects.FirstOrDefault(p => p.ServerId == sid);
                        if (WO != null)
                        {
                            //данный объект уже есть в базу обновляем по нему информкацию
                            if (WO.Name != pWOs[i].Name)
                            {
                                WO.UpdateTime = timeNow;
                                WO.Name       = pWOs[i].Name;
                            }
                            if (WO.FreeWeight != pWOs[i].FreeWeight)
                            {
                                WO.UpdateTime = timeNow;
                                WO.FreeWeight = pWOs[i].FreeWeight;
                            }
                            if (WO.MarketValue != pWOs[i].MarketValue)
                            {
                                WO.UpdateTime  = timeNow;
                                WO.MarketValue = pWOs[i].MarketValue;
                            }
                            if (WO.MarketValuePawn != pWOs[i].MarketValuePawn)
                            {
                                WO.UpdateTime      = timeNow;
                                WO.MarketValuePawn = pWOs[i].MarketValuePawn;
                            }
                            if (WO.Tile != pWOs[i].Tile)
                            {
                                WO.UpdateTime = timeNow;
                                WO.Tile       = pWOs[i].Tile;
                            }
                        }
                        else
                        {
                            Loger.Log("PlayInfo find error add WO: " + pWOs[i].Name + " sid=" + sid);
                        }
                    }

                    //передаем объекты других игроков + при первом обращении first
                    for (int i = 0; i < data.WorldObjects.Count; i++)
                    {
                        if (data.WorldObjects[i].UpdateTime < packet.UpdateTime)
                        {
                            continue;
                        }
                        if (!first && data.WorldObjects[i].LoginOwner == pLogin)
                        {
                            continue;
                        }
                        outWO.Add(data.WorldObjects[i]);
                    }

                    //передаем удаленные объекты других игроков (не для первого запроса)
                    if (packet.UpdateTime > DateTime.MinValue)
                    {
                        for (int i = 0; i < data.WorldObjectsDeleted.Count; i++)
                        {
                            if (data.WorldObjectsDeleted[i].UpdateTime < packet.UpdateTime)
                            {
                                //Удаляем все записи сроком старше 2х минут (их нужно хранить время между тем как игрок у которого удалился караван зальёт это на сервер, и все другие онлайн игроки получат эту инфу, а обновление идет раз в 5 сек)
                                if ((timeNow - data.WorldObjectsDeleted[i].UpdateTime).TotalSeconds > 120000)
                                {
                                    data.WorldObjectsDeleted.RemoveAt(i--);
                                }
                                continue;
                            }
                            if (data.WorldObjectsDeleted[i].LoginOwner == pLogin)
                            {
                                continue;
                            }
                            outWOD.Add(data.WorldObjectsDeleted[i]);
                        }
                    }

                    //завершили сбор информации клиенту
                    toClient.WObjects         = outWO;
                    toClient.WObjectsToDelete = outWOD;
                    Player.LastUpdateTime     = timeNow;
                }

                //прикрепляем письма
                toClient.Mails = Player.Mails;
                Player.Mails   = new List <ModelMailTrade>();

                //флаг, что на клиента кто-то напал и он должен запросить подробности
                toClient.AreAttacking = Player.AttackData != null && Player.AttackData.Host == Player && Player.AttackData.State == 1;

                return(toClient);
            }
        }
Пример #4
0
        public ModelPlayToClient PlayInfo(ModelPlayToServer packet)
        {
            if (Player == null)
            {
                return(null);
            }

            lock (Player)
            {
                var data     = Repository.GetData;
                var timeNow  = DateTime.UtcNow;
                var toClient = new ModelPlayToClient();
                toClient.UpdateTime = timeNow;
                if (packet.GetPlayersInfo != null && packet.GetPlayersInfo.Count > 0)
                {
                    var pSee = PartyLoginSee();
                    var pGet = pSee.Where(s => packet.GetPlayersInfo.Any(p => s == p)).ToList();
                    toClient.PlayersInfo = Repository.GetData.PlayersAll
                                           .Where(p => pGet.Any(g => g == p.Public.Login))
                                           .Select(p => p.Public)
                                           .ToList();
                    if (pGet.Any(p => p == null))
                    {
                        Loger.Log("nulllllll");
                    }
                }
                if (packet.SaveFileData != null && packet.SaveFileData.Length > 0)
                {
                    Player.SaveDataPacket      = GZip.ZipByteByte(packet.SaveFileData);
                    Player.Public.ExistMap     = true;
                    Player.Public.LastSaveTime = timeNow;
                    Repository.Get.ChangeData  = true;
                }
                Player.Public.LastTick = packet.LastTick;

                var pLogin = Player.Public.Login;
                //packet.WObjects тут все объекты этого игрока, добавляем которых у нас нет
                var pWOs = packet.WObjects ?? new List <WorldObjectEntry>();
                //packet.WObjectsToDelete тут те объекты этого игрока, что нужно удалить
                var pDs = packet.WObjectsToDelete ?? new List <WorldObjectEntry>();
                //передаем назад объекты у которых не было ServerId, т.е. они новые для сервера + все с изменениями
                var outWO  = new List <WorldObjectEntry>();
                var outWOD = new List <WorldObjectEntry>();
                //это первое обращение, если не прислали своих объектов
                var first = pWOs.Count == 0;
                lock (data)
                {
                    for (int i = 0; i < pDs.Count; i++)
                    {
                        if (pDs[i].LoginOwner != Player.Public.Login)
                        {
                            continue;
                        }
                        var sid = pDs[i].ServerId;
                        var pD  = data.WorldObjects.FirstOrDefault(p => p.ServerId == sid);
                        if (pD != null)
                        {
                            //удаление из базы
                            pD.UpdateTime = timeNow;
                            data.WorldObjects.Remove(pD);
                            data.WorldObjectsDeleted.Add(pD);
                        }
                    }

                    for (int i = 0; i < pWOs.Count; i++)
                    {
                        if (pWOs[i].LoginOwner != Player.Public.Login)
                        {
                            continue;                                            // <-на всякий случай
                        }
                        var sid = pWOs[i].ServerId;
                        if (sid == 0)
                        {
                            //добавление в базу
                            pWOs[i].UpdateTime = timeNow;
                            pWOs[i].ServerId   = data.GetWorldObjectEntryId();
                            data.WorldObjects.Add(pWOs[i]);
                            outWO.Add(pWOs[i]);
                            continue;
                        }
                        var WO = data.WorldObjects.FirstOrDefault(p => p.ServerId == sid);
                        if (WO != null)
                        {
                            //данный объект уже есть в базу обновляем по нему информкацию
                            if (WO.Name != pWOs[i].Name)
                            {
                                WO.UpdateTime = timeNow;
                                WO.Name       = pWOs[i].Name;
                            }
                            if (WO.FreeWeight != pWOs[i].FreeWeight)
                            {
                                WO.UpdateTime = timeNow;
                                WO.FreeWeight = pWOs[i].FreeWeight;
                            }
                            if (WO.MarketValue != pWOs[i].MarketValue)
                            {
                                WO.UpdateTime  = timeNow;
                                WO.MarketValue = pWOs[i].MarketValue;
                            }
                            if (WO.MarketValuePawn != pWOs[i].MarketValuePawn)
                            {
                                WO.UpdateTime      = timeNow;
                                WO.MarketValuePawn = pWOs[i].MarketValuePawn;
                            }
                            if (WO.Tile != pWOs[i].Tile)
                            {
                                WO.UpdateTime = timeNow;
                                WO.Tile       = pWOs[i].Tile;
                            }
                        }
                    }

                    //передаем объекты других игроков + при первом обращении first
                    for (int i = 0; i < data.WorldObjects.Count; i++)
                    {
                        if (data.WorldObjects[i].UpdateTime < packet.UpdateTime)
                        {
                            continue;
                        }
                        if (!first && data.WorldObjects[i].LoginOwner == pLogin)
                        {
                            continue;
                        }
                        outWO.Add(data.WorldObjects[i]);
                    }

                    //передаем удаленные объекты других игроков
                    for (int i = 0; i < data.WorldObjectsDeleted.Count; i++)
                    {
                        if (data.WorldObjectsDeleted[i].UpdateTime < packet.UpdateTime)
                        {
                            continue;
                        }
                        if (data.WorldObjectsDeleted[i].LoginOwner == pLogin)
                        {
                            continue;
                        }
                        outWOD.Add(data.WorldObjectsDeleted[i]);
                    }

                    //завершили сбор информации клиенту
                    toClient.WObjects         = outWO;
                    toClient.WObjectsToDelete = outWOD;
                    Player.LastUpdateTime     = timeNow;

                    //обслуживание data.WorldObjectsDeleted
                    for (int i = 0; i < data.WorldObjectsDeleted.Count; i++)
                    {
                        var delTime = data.WorldObjectsDeleted[i].UpdateTime;
                        if (data.PlayersAll.All(p => p.LastUpdateTime > delTime))
                        {
                            data.WorldObjectsDeleted.RemoveAt(i--);
                        }
                    }
                }

                //прикрепляем письма
                toClient.Mails = Player.Mails;
                Player.Mails   = new List <ModelMailTrade>();

                return(toClient);
            }
        }
Пример #5
0
        public ModelPlayToClient playInfo(ModelPlayToServer packet, ServiceContext context)
        {
            if (Repository.CheckIsBanIP(context.AddrIP))
            {
                context.Disconnect("New BanIP " + context.AddrIP);
                return(null);
            }
            if (context.PossiblyIntruder)
            {
                context.Disconnect("Possibly intruder");
                return(null);
            }
            lock (context.Player)
            {
                var data     = Repository.GetData;
                var timeNow  = DateTime.UtcNow;
                var toClient = new ModelPlayToClient();
                toClient.UpdateTime = timeNow;
                if (packet.GetPlayersInfo != null && packet.GetPlayersInfo.Count > 0)
                {
                    var pSee = StaticHelper.PartyLoginSee(context.Player);
                    var pGet = new HashSet <string>(packet.GetPlayersInfo);
                    pGet.IntersectWith(pSee);

                    toClient.PlayersInfo = pGet
                                           .Where(l => Repository.GetData.PlayersAllDic.ContainsKey(l))
                                           .Select(l => Repository.GetData.PlayersAllDic[l].Public)
                                           .ToList();
                }
                if (packet.SaveFileData != null && packet.SaveFileData.Length > 0)
                {
                    Repository.GetSaveData.SavePlayerData(context.Player.Public.Login, packet.SaveFileData, packet.SingleSave);
                    context.Player.Public.LastSaveTime = timeNow;

                    //Действия при сохранении, оно происодит только здесь!
                    context.Player.MailsConfirmationSave = new List <ModelMail>();

                    Repository.Get.ChangeData = true;
                }
                if (context.Player.GetKeyReconnect())
                {
                    toClient.KeyReconnect = context.Player.KeyReconnect1;
                }

                var pLogin = context.Player.Public.Login;
                //packet.WObjects тут все объекты этого игрока, добавляем которых у нас нет
                var pWOs = packet.WObjects ?? new List <WorldObjectEntry>();
                //packet.WObjectsToDelete тут те объекты этого игрока, что нужно удалить
                var pDs = packet.WObjectsToDelete ?? new List <WorldObjectEntry>();
                //передаем назад объекты у которых не было ServerId, т.е. они новые для сервера + все с изменениями
                var outWO  = new List <WorldObjectEntry>();
                var outWOD = new List <WorldObjectEntry>();
                //это первое обращение, если не прислали своих объектов
                var first = pWOs.Count == 0;
                lock (data)
                {
                    for (int i = 0; i < pDs.Count; i++)
                    {
                        if (pDs[i].LoginOwner != context.Player.Public.Login)
                        {
                            continue;
                        }
                        var sid = pDs[i].ServerId;
                        var pD  = data.WorldObjects.FirstOrDefault(p => p.ServerId == sid);
                        if (pD != null)
                        {
                            //удаление из базы
                            pD.UpdateTime = timeNow;
                            data.WorldObjects.Remove(pD);
                            data.WorldObjectsDeleted.Add(pD);
                        }
                    }

                    for (int i = 0; i < pWOs.Count; i++)
                    {
                        if (pWOs[i].LoginOwner != context.Player.Public.Login)
                        {
                            continue;                                                    // <-на всякий случай
                        }
                        var sid = pWOs[i].ServerId;
                        if (sid == 0)
                        {
                            //добавление в базу
                            pWOs[i].UpdateTime = timeNow;
                            pWOs[i].ServerId   = data.GetWorldObjectEntryId();
                            data.WorldObjects.Add(pWOs[i]);
                            outWO.Add(pWOs[i]);
                            continue;
                        }
                        var WO = data.WorldObjects.FirstOrDefault(p => p.ServerId == sid);
                        if (WO != null)
                        {
                            //данный объект уже есть в базу обновляем по нему информкацию
                            if (WO.Name != pWOs[i].Name)
                            {
                                WO.UpdateTime = timeNow;
                                WO.Name       = pWOs[i].Name;
                            }
                            if (WO.FreeWeight != pWOs[i].FreeWeight)
                            {
                                WO.UpdateTime = timeNow;
                                WO.FreeWeight = pWOs[i].FreeWeight;
                            }
                            if (WO.MarketValue != pWOs[i].MarketValue)
                            {
                                WO.UpdateTime  = timeNow;
                                WO.MarketValue = pWOs[i].MarketValue;
                            }
                            if (WO.MarketValuePawn != pWOs[i].MarketValuePawn)
                            {
                                WO.UpdateTime      = timeNow;
                                WO.MarketValuePawn = pWOs[i].MarketValuePawn;
                            }
                            if (WO.Tile != pWOs[i].Tile)
                            {
                                WO.UpdateTime = timeNow;
                                WO.Tile       = pWOs[i].Tile;
                            }
                        }
                        else
                        {
                            Loger.Log("PlayInfo find error add WO: " + pWOs[i].Name + " sid=" + sid);
                        }
                    }

                    //передаем объекты других игроков + при первом обращении first
                    for (int i = 0; i < data.WorldObjects.Count; i++)
                    {
                        if (data.WorldObjects[i].UpdateTime < packet.UpdateTime)
                        {
                            continue;
                        }
                        if (!first && data.WorldObjects[i].LoginOwner == pLogin)
                        {
                            continue;
                        }
                        outWO.Add(data.WorldObjects[i]);
                    }

                    //передаем удаленные объекты других игроков (не для первого запроса)
                    if (packet.UpdateTime > DateTime.MinValue)
                    {
                        for (int i = 0; i < data.WorldObjectsDeleted.Count; i++)
                        {
                            if (data.WorldObjectsDeleted[i].UpdateTime < packet.UpdateTime)
                            {
                                //Удаляем все записи сроком старше 2х минут (их нужно хранить время между тем как игрок у которого удалился караван зальёт это на сервер, и все другие онлайн игроки получат эту инфу, а обновление идет раз в 5 сек)
                                if ((timeNow - data.WorldObjectsDeleted[i].UpdateTime).TotalSeconds > 120000)
                                {
                                    data.WorldObjectsDeleted.RemoveAt(i--);
                                }
                                continue;
                            }
                            if (data.WorldObjectsDeleted[i].LoginOwner == pLogin)
                            {
                                continue;
                            }
                            outWOD.Add(data.WorldObjectsDeleted[i]);
                        }
                    }

                    //World Object Online
                    if (ServerManager.ServerSettings.GeneralSettings.EquableWorldObjects)
                    {
                        //World Object Online
                        try
                        {
                            if (packet.WObjectOnlineToDelete != null && packet.WObjectOnlineToDelete.Count > 0)
                            {
                                data.WorldObjectOnlineList.RemoveAll(data => packet.WObjectOnlineToDelete.Any(pkt => ValidateWorldObject(pkt, data)));
                            }
                            if (packet.WObjectOnlineToAdd != null && packet.WObjectOnlineToAdd.Count > 0)
                            {
                                data.WorldObjectOnlineList.AddRange(packet.WObjectOnlineToAdd);
                            }
                            if (packet.WObjectOnlineList != null && packet.WObjectOnlineList.Count > 0)
                            {
                                if (data.WorldObjectOnlineList.Count == 0)
                                {
                                    data.WorldObjectOnlineList = packet.WObjectOnlineList;
                                }
                                else if (data.WorldObjectOnlineList != null && data.WorldObjectOnlineList.Count > 0)
                                {
                                    toClient.WObjectOnlineToDelete = packet.WObjectOnlineList.Where(pkt => !data.WorldObjectOnlineList.Any(data => ValidateWorldObject(pkt, data))).ToList();
                                    toClient.WObjectOnlineToAdd    = data.WorldObjectOnlineList.Where(data => !packet.WObjectOnlineList.Any(pkt => ValidateWorldObject(pkt, data))).ToList();
                                }
                            }
                            toClient.WObjectOnlineList = data.WorldObjectOnlineList;
                        }
                        catch
                        {
                            Loger.Log("ERROR PLAYINFO World Object Online");
                        }

                        //Faction Online
                        try
                        {
                            if (packet.FactionOnlineToDelete != null && packet.FactionOnlineToDelete.Count > 0)
                            {
                                data.FactionOnlineList.RemoveAll(data => packet.FactionOnlineToDelete.Any(pkt => ValidateFaction(pkt, data)));
                            }
                            if (packet.FactionOnlineToAdd != null && packet.FactionOnlineToAdd.Count > 0)
                            {
                                data.FactionOnlineList.AddRange(packet.FactionOnlineToAdd);
                            }
                            if (packet.FactionOnlineList != null && packet.FactionOnlineList.Count > 0)
                            {
                                if (data.FactionOnlineList.Count == 0)
                                {
                                    data.FactionOnlineList = packet.FactionOnlineList;
                                }
                                else if (data.FactionOnlineList != null && data.FactionOnlineList.Count > 0)
                                {
                                    toClient.FactionOnlineToDelete = packet.FactionOnlineList.Where(pkt => !data.FactionOnlineList.Any(data => ValidateFaction(pkt, data))).ToList();
                                    toClient.FactionOnlineToAdd    = data.FactionOnlineList.Where(data => !packet.FactionOnlineList.Any(pkt => ValidateFaction(pkt, data))).ToList();
                                }
                            }
                            toClient.FactionOnlineList = data.FactionOnlineList;
                        }
                        catch
                        {
                            Loger.Log("ERROR PLAYINFO Faction Online");
                        }
                    }

                    //завершили сбор информации клиенту
                    toClient.WObjects         = outWO;
                    toClient.WObjectsToDelete = outWOD;

                    context.Player.WLastUpdateTime = timeNow;
                    context.Player.WLastTick       = packet.LastTick;

                    //обновляем статистические поля
                    var costAll = context.Player.CostWorldObjects();
                    if (context.Player.StartMarketValuePawn == 0)
                    {
                        context.Player.StartMarketValue     = costAll.MarketValue;
                        context.Player.StartMarketValuePawn = costAll.MarketValuePawn;

                        context.Player.DeltaMarketValue     = 0;
                        context.Player.DeltaMarketValuePawn = 0;
                    }
                    else if (context.Player.LastUpdateIsGood && (costAll.MarketValue > 0 || costAll.MarketValuePawn > 0))
                    {
                        //считаем дельту
                        context.Player.DeltaMarketValue     = (costAll.MarketValue - context.Player.LastMarketValue);
                        context.Player.DeltaMarketValuePawn = (costAll.MarketValuePawn - context.Player.LastMarketValuePawn);

                        context.Player.SumDeltaGameMarketValue     += context.Player.DeltaMarketValue;
                        context.Player.SumDeltaGameMarketValuePawn += context.Player.DeltaMarketValuePawn;
                        context.Player.SumDeltaRealMarketValue     += context.Player.DeltaMarketValue;
                        context.Player.SumDeltaRealMarketValuePawn += context.Player.DeltaMarketValuePawn;

                        if (packet.LastTick - context.Player.StatLastTick > 15 * 60000) // сбор раз в 15 дней
                        {
                            if (context.Player.StatMaxDeltaGameMarketValue < context.Player.SumDeltaGameMarketValue)
                            {
                                context.Player.StatMaxDeltaGameMarketValue = context.Player.SumDeltaGameMarketValue;
                            }
                            if (context.Player.StatMaxDeltaGameMarketValuePawn < context.Player.SumDeltaGameMarketValuePawn)
                            {
                                context.Player.StatMaxDeltaGameMarketValuePawn = context.Player.SumDeltaGameMarketValuePawn;
                            }

                            context.Player.SumDeltaGameMarketValue     = 0;
                            context.Player.SumDeltaGameMarketValuePawn = 0;
                            context.Player.StatLastTick = packet.LastTick;
                        }

                        if (context.Player.SumDeltaRealSecond > 60 * 60) //сбор раз в час
                        {
                            if (context.Player.StatMaxDeltaRealMarketValue < context.Player.SumDeltaRealMarketValue)
                            {
                                context.Player.StatMaxDeltaRealMarketValue = context.Player.SumDeltaRealMarketValue;
                            }
                            if (context.Player.StatMaxDeltaRealMarketValuePawn < context.Player.SumDeltaRealMarketValuePawn)
                            {
                                context.Player.StatMaxDeltaRealMarketValuePawn = context.Player.SumDeltaRealMarketValuePawn;
                            }
                            if (context.Player.StatMaxDeltaRealTicks < context.Player.SumDeltaRealTicks)
                            {
                                context.Player.StatMaxDeltaRealTicks = context.Player.SumDeltaRealTicks;
                            }

                            context.Player.SumDeltaRealMarketValue     = 0;
                            context.Player.SumDeltaRealMarketValuePawn = 0;
                            context.Player.SumDeltaRealTicks           = 0;
                            context.Player.SumDeltaRealSecond          = 0;
                        }
                    }
                    context.Player.LastUpdateIsGood = costAll.MarketValue > 0 || costAll.MarketValuePawn > 0;
                    if (context.Player.LastUpdateIsGood)
                    {
                        context.Player.LastMarketValue     = costAll.MarketValue;
                        context.Player.LastMarketValuePawn = costAll.MarketValuePawn;
                    }
                    var dt = packet.LastTick - context.Player.Public.LastTick;
                    context.Player.SumDeltaRealTicks += dt;
                    if (dt > 0)
                    {
                        var ds = (long)(timeNow - context.Player.LastUpdateTime).TotalSeconds;
                        context.Player.SumDeltaRealSecond += ds;
                        context.Player.TotalRealSecond    += ds;
                    }

                    context.Player.WLastUpdateTime = context.Player.LastUpdateTime;
                    context.Player.WLastTick       = context.Player.Public.LastTick;
                    context.Player.LastUpdateTime  = timeNow;
                    context.Player.Public.LastTick = packet.LastTick;
                }

                //обновляем состояние отложенной отправки писем
                if (context.Player.FunctionMails.Count > 0)
                {
                    for (int i = 0; i < context.Player.FunctionMails.Count; i++)
                    {
                        var needRemove = context.Player.FunctionMails[i].Run(context);
                        if (needRemove)
                        {
                            context.Player.FunctionMails.RemoveAt(i--);
                        }
                    }
                }

                //прикрепляем письма
                //если есть команда на отключение без сохранения, то посылаем только одно это письмо
                var md = context.Player.Mails.FirstOrDefault(m => m is ModelMailAttackCancel);
                if (md == null)
                {
                    toClient.Mails = context.Player.Mails;
                    context.Player.MailsConfirmationSave.AddRange(context.Player.Mails.Where(m => m.NeedSaveGame).ToList());
                    context.Player.Mails = new List <ModelMail>();
                }
                else
                {
                    toClient.Mails = new List <ModelMail>()
                    {
                        md
                    };
                    context.Player.Mails.Remove(md);
                }

                //команда выполнить сохранение и отключиться
                toClient.NeedSaveAndExit = !context.Player.IsAdmin && data.EverybodyLogoff;

                //флаг, что на клиента кто-то напал и он должен запросить подробности
                toClient.AreAttacking = context.Player.AttackData != null && context.Player.AttackData.Host == context.Player && context.Player.AttackData.State == 1;

                if (toClient.Mails.Count > 0)
                {
                    foreach (var mail in toClient.Mails)
                    {
                        Loger.Log($"DownloadMail {mail.GetType().Name} {mail.From.Login}->{mail.To.Login} {mail.ContentString()}");
                    }
                }

                return(toClient);
            }
        }
Пример #6
0
        private static void UpdateWorld(bool firstRun = false)
        {
            lock (UpdatingWorld)
            {
                Command((connect) =>
                {
                    //собираем пакет на сервер
                    var toServ = new ModelPlayToServer()
                    {
                        UpdateTime = Data.UpdateTime, //время прошлого запроса
                    };
                    //данные сохранения игры
                    if (Data.SaveFileData != null)
                    {
                        toServ.SaveFileData = Data.SaveFileData;
                        toServ.SingleSave   = Data.SingleSave;
                        Data.SaveFileData   = null;
                    }

                    //собираем данные с планеты
                    if (!firstRun)
                    {
                        UpdateWorldController.SendToServer(toServ);
                    }

                    if (firstRun)
                    {
                        GetPlayersInfoCountRequest = 0;
                    }

                    //запрос на информацию об игроках. Можно будет ограничить редкое получение для тех кто оффлайн
                    if (Data.Chats != null && Data.Chats[0].PartyLogin != null)
                    {
                        if (Data.Players == null || Data.Players.Count == 0 ||
                            GetPlayersInfoCountRequest % 5 == 0)
                        {
                            //в начале и раз в пол минуты (5 сек между UpdateWorld * 5) получаем инфу обо всех
                            toServ.GetPlayersInfo = Data.Chats[0].PartyLogin;
                        }
                        else
                        {
                            //в промежутках о тех кто онлайн
                            toServ.GetPlayersInfo = Data.Players.Values.Where(p => p.Online).Select(p => p.Public.Login).ToList();
                        }
                        GetPlayersInfoCountRequest++;
                        //Loger.Log("Client " + My.Login + " UpdateWorld* " + (toServ.GetPlayersInfo.Count.ToString())
                        //    + " " + (toServ.GetPlayersInfo.Any(p => p == SessionClientController.My.Login) ? "1" : "0"));
                    }

                    //отправляем на сервер, получаем ответ
                    ModelPlayToClient fromServ = connect.PlayInfo(toServ);

                    //Loger.Log("Client UpdateWorld 5 ");
                    Loger.Log("Client " + My.Login + " UpdateWorld "
                              + string.Format("Отпр. свои {0}, своиDel {1}{5}. Пришло {2}, del {3}, игроков {8}, посылок {4}{6}{7}"
                                              , toServ.WObjects == null ? 0 : toServ.WObjects.Count
                                              , toServ.WObjectsToDelete == null ? 0 : toServ.WObjectsToDelete.Count
                                              , fromServ.WObjects == null ? 0 : fromServ.WObjects.Count
                                              , fromServ.WObjectsToDelete == null ? 0 : fromServ.WObjectsToDelete.Count
                                              , fromServ.Mails == null ? 0 : fromServ.Mails.Count
                                              , toServ.SaveFileData == null || toServ.SaveFileData.Length == 0 ? "" : ", сейв"
                                              , fromServ.AreAttacking ? " Атакуют!" : ""
                                              , fromServ.NeedSaveAndExit ? " Команда на отключение" : ""
                                              , fromServ.PlayersInfo == null ? "null" : fromServ.PlayersInfo.Count.ToString()
                                              ));

                    //сохраняем время актуальности данных
                    Data.UpdateTime = fromServ.UpdateTime;
                    if (!string.IsNullOrEmpty(fromServ.KeyReconnect))
                    {
                        Data.KeyReconnect = fromServ.KeyReconnect;
                    }

                    //обновляем информацию по игрокам
                    if (fromServ.PlayersInfo != null && fromServ.PlayersInfo.Count > 0)
                    {
                        foreach (var pi in fromServ.PlayersInfo)
                        {
                            if (pi.Login == null)
                            {
                                continue;
                            }
                            Data.Players[pi.Login] = new PlayerClient()
                            {
                                Public = pi
                            };
                            if (pi.Login == My.Login)
                            {
                                My        = pi;
                                Data.MyEx = Data.Players[pi.Login];
                                //Loger.Log("Client " + My.Login + " UpdateWorld* " + My.LastOnlineTime.ToString("o") + " " + DateTime.UtcNow.ToString("o")
                                //   + " " + (toServ.GetPlayersInfo.Any(p => p == My.Login) ? "1" : "0"));
                            }
                        }
                    }

                    //обновляем планету
                    UpdateWorldController.LoadFromServer(fromServ, firstRun);

                    //обновляем инфу по поселениям
                    var allWObjects = Find.WorldObjects.AllWorldObjects
                                      .Select(o => o as CaravanOnline)
                                      .Where(o => o != null)
                                      .ToList();
                    foreach (var pi in Data.Players)
                    {
                        if (pi.Value.Public.Login == My.Login)
                        {
                            continue;
                        }
                        pi.Value.WObjects = allWObjects.Where(wo => wo.OnlinePlayerLogin == pi.Key).ToList();
                    }

                    //Сохраняем и выходим
                    if (fromServ.NeedSaveAndExit)
                    {
                        if (!SessionClientController.Data.BackgroundSaveGameOff)
                        {
                            SessionClientController.SaveGameNow(false, () =>
                            {
                                SessionClientController.Disconnected("OCity_SessionCC_Shutdown_Command_ProgressSaved".Translate());
                            });
                        }
                        else
                        {
                            SessionClientController.Disconnected("OCity_SessionCC_Shutdown_Command".Translate());
                        }
                    }

                    //если на нас напали запускаем процесс
                    if (fromServ.AreAttacking && GameAttackHost.AttackMessage())
                    {
                        GameAttackHost.Get.Start(connect);
                    }
                });
            }
        }
        public static void SendToServer(ModelPlayToServer toServ, bool firstRun, ModelGameServerInfo modelGameServerInfo)
        {
            //Loger.Log("Empire=" + Find.FactionManager.FirstFactionOfDef(FactionDefOf.Empire)?.GetUniqueLoadID());

            toServ.LastTick = (long)Find.TickManager.TicksGame;
            var gameProgress = new PlayerGameProgress();

            var allWorldObjectsArr = new WorldObject[Find.WorldObjects.AllWorldObjects.Count];

            Find.WorldObjects.AllWorldObjects.CopyTo(allWorldObjectsArr);

            var            allWorldObjects = allWorldObjectsArr.Where(wo => wo != null).ToList();
            List <Faction> factionList     = Find.FactionManager.AllFactionsListForReading;

            if (SessionClientController.Data.GeneralSettings.EquableWorldObjects)
            {
                #region Send to Server: firstRun EquableWorldObjects
                try
                {
                    // Game on init
                    if (firstRun && modelGameServerInfo != null)
                    {
                        if (modelGameServerInfo.WObjectOnlineList.Count > 0)
                        {
                            toServ.WObjectOnlineList = allWorldObjectsArr.Where(wo => wo is Settlement)
                                                       .Where(wo => wo.HasName && !wo.Faction.IsPlayer).Select(obj => GetWorldObjects(obj)).ToList();
                        }

                        if (modelGameServerInfo.FactionOnlineList.Count > 0)
                        {
                            List <Faction> factions = Find.FactionManager.AllFactionsListForReading;
                            toServ.FactionOnlineList = factions.Select(obj => GetFactions(obj)).ToList();
                        }
                        return;
                    }
                }
                catch (Exception e)
                {
                    Loger.Log("Exception >> " + e);
                    Log.Error("SendToServer FirstRun error");
                    return;
                }
                #endregion
            }

            if (!firstRun)
            {
                //Loger.Log("Client TestBagSD 035");
                Dictionary <Map, List <Pawn> > cacheColonists = new Dictionary <Map, List <Pawn> >();
                //отправка всех новых и измененных объектов игрока
                toServ.WObjects = allWorldObjects
                                  .Where(o => o.Faction?.IsPlayer == true && //o.Faction != null && o.Faction.IsPlayer
                                         (o is Settlement || o is Caravan)) //Чтобы отсеч разные карты событий
                                  .Select(o => GetWorldObjectEntry(o, gameProgress, cacheColonists))
                                  .ToList();
                LastSendMyWorldObjects = toServ.WObjects;

                //Loger.Log("Client TestBagSD 036");
                //свои объекты которые удалил пользователь с последнего обновления
                if (ToDelete != null)
                {
                    var toDeleteNewNow = WorldObjectEntrys
                                         .Where(p => !allWorldObjects.Any(wo => wo.ID == p.Key))
                                         .Select(p => p.Value)
                                         .ToList();
                    ToDelete.AddRange(toDeleteNewNow);
                }

                toServ.WObjectsToDelete = ToDelete;
            }
            toServ.GameProgress = gameProgress;

            if (SessionClientController.Data.GeneralSettings.EquableWorldObjects)
            {
                #region Send to Server: Non-Player World Objects
                //  Non-Player World Objects
                try
                {
                    var OnlineWObjArr = allWorldObjectsArr.Where(wo => wo is Settlement)
                                        .Where(wo => wo.HasName && !wo.Faction.IsPlayer);
                    if (!firstRun)
                    {
                        if (LastWorldObjectOnline != null && LastWorldObjectOnline.Count > 0)
                        {
                            toServ.WObjectOnlineToDelete = LastWorldObjectOnline.Where(WOnline => !OnlineWObjArr.Any(wo => ValidateOnlineWorldObject(WOnline, wo))).ToList();

                            toServ.WObjectOnlineToAdd = OnlineWObjArr.Where(wo => !LastWorldObjectOnline.Any(WOnline => ValidateOnlineWorldObject(WOnline, wo)))
                                                        .Select(obj => GetWorldObjects(obj)).ToList();
                        }
                    }

                    toServ.WObjectOnlineList = OnlineWObjArr.Select(obj => GetWorldObjects(obj)).ToList();
                    LastWorldObjectOnline    = toServ.WObjectOnlineList;
                }
                catch (Exception e)
                {
                    Loger.Log("Exception >> " + e);
                    Log.Error("ERROR SendToServer WorldObject Online");
                }
                #endregion

                #region Send to Server: Non-Player Factions
                // Non-Player Factions
                try
                {
                    if (!firstRun)
                    {
                        if (LastFactionOnline != null && LastFactionOnline.Count > 0)
                        {
                            toServ.FactionOnlineToDelete = LastFactionOnline.Where(FOnline => !factionList.Any(f => ValidateFaction(FOnline, f))).ToList();

                            toServ.FactionOnlineToAdd = factionList.Where(f => !LastFactionOnline.Any(FOnline => ValidateFaction(FOnline, f)))
                                                        .Select(obj => GetFactions(obj)).ToList();
                        }
                    }

                    toServ.FactionOnlineList = factionList.Select(obj => GetFactions(obj)).ToList();
                    LastFactionOnline        = toServ.FactionOnlineList;
                }
                catch (Exception e)
                {
                    Loger.Log("Exception >> " + e);
                    Log.Error("ERROR SendToServer Faction Online");
                }
                #endregion
            }
        }
Пример #8
0
        public ModelPlayToClient playInfo(ModelPlayToServer packet, ServiceContext context)
        {
            lock (context.Player)
            {
                var data     = Repository.GetData;
                var timeNow  = DateTime.UtcNow;
                var toClient = new ModelPlayToClient();
                toClient.UpdateTime = timeNow;
                if (packet.GetPlayersInfo != null && packet.GetPlayersInfo.Count > 0)
                {
                    var pSee = StaticHelper.PartyLoginSee(context.Player);
                    var pGet = new HashSet <string>(packet.GetPlayersInfo);
                    pGet.IntersectWith(pSee);

                    toClient.PlayersInfo = pGet
                                           .Where(l => Repository.GetData.PlayersAllDic.ContainsKey(l))
                                           .Select(l => Repository.GetData.PlayersAllDic[l].Public)
                                           .ToList();
                }
                if (packet.SaveFileData != null && packet.SaveFileData.Length > 0)
                {
                    Repository.GetSaveData.SavePlayerData(context.Player.Public.Login, packet.SaveFileData, packet.SingleSave);
                    context.Player.Public.LastSaveTime = timeNow;
                    Repository.Get.ChangeData          = true;
                }
                context.Player.Public.LastTick = packet.LastTick;
                if (context.Player.GetKeyReconnect())
                {
                    toClient.KeyReconnect = context.Player.KeyReconnect1;
                }

                var pLogin = context.Player.Public.Login;
                //packet.WObjects тут все объекты этого игрока, добавляем которых у нас нет
                var pWOs = packet.WObjects ?? new List <WorldObjectEntry>();
                //packet.WObjectsToDelete тут те объекты этого игрока, что нужно удалить
                var pDs = packet.WObjectsToDelete ?? new List <WorldObjectEntry>();
                //передаем назад объекты у которых не было ServerId, т.е. они новые для сервера + все с изменениями
                var outWO  = new List <WorldObjectEntry>();
                var outWOD = new List <WorldObjectEntry>();
                //это первое обращение, если не прислали своих объектов
                var first = pWOs.Count == 0;
                lock (data)
                {
                    for (int i = 0; i < pDs.Count; i++)
                    {
                        if (pDs[i].LoginOwner != context.Player.Public.Login)
                        {
                            continue;
                        }
                        var sid = pDs[i].ServerId;
                        var pD  = data.WorldObjects.FirstOrDefault(p => p.ServerId == sid);
                        if (pD != null)
                        {
                            //удаление из базы
                            pD.UpdateTime = timeNow;
                            data.WorldObjects.Remove(pD);
                            data.WorldObjectsDeleted.Add(pD);
                        }
                    }

                    for (int i = 0; i < pWOs.Count; i++)
                    {
                        if (pWOs[i].LoginOwner != context.Player.Public.Login)
                        {
                            continue;                                                    // <-на всякий случай
                        }
                        var sid = pWOs[i].ServerId;
                        if (sid == 0)
                        {
                            //добавление в базу
                            pWOs[i].UpdateTime = timeNow;
                            pWOs[i].ServerId   = data.GetWorldObjectEntryId();
                            data.WorldObjects.Add(pWOs[i]);
                            outWO.Add(pWOs[i]);
                            continue;
                        }
                        var WO = data.WorldObjects.FirstOrDefault(p => p.ServerId == sid);
                        if (WO != null)
                        {
                            //данный объект уже есть в базу обновляем по нему информкацию
                            if (WO.Name != pWOs[i].Name)
                            {
                                WO.UpdateTime = timeNow;
                                WO.Name       = pWOs[i].Name;
                            }
                            if (WO.FreeWeight != pWOs[i].FreeWeight)
                            {
                                WO.UpdateTime = timeNow;
                                WO.FreeWeight = pWOs[i].FreeWeight;
                            }
                            if (WO.MarketValue != pWOs[i].MarketValue)
                            {
                                WO.UpdateTime  = timeNow;
                                WO.MarketValue = pWOs[i].MarketValue;
                            }
                            if (WO.MarketValuePawn != pWOs[i].MarketValuePawn)
                            {
                                WO.UpdateTime      = timeNow;
                                WO.MarketValuePawn = pWOs[i].MarketValuePawn;
                            }
                            if (WO.Tile != pWOs[i].Tile)
                            {
                                WO.UpdateTime = timeNow;
                                WO.Tile       = pWOs[i].Tile;
                            }
                        }
                        else
                        {
                            Loger.Log("PlayInfo find error add WO: " + pWOs[i].Name + " sid=" + sid);
                        }
                    }

                    //передаем объекты других игроков + при первом обращении first
                    for (int i = 0; i < data.WorldObjects.Count; i++)
                    {
                        if (data.WorldObjects[i].UpdateTime < packet.UpdateTime)
                        {
                            continue;
                        }
                        if (!first && data.WorldObjects[i].LoginOwner == pLogin)
                        {
                            continue;
                        }
                        outWO.Add(data.WorldObjects[i]);
                    }

                    //передаем удаленные объекты других игроков (не для первого запроса)
                    if (packet.UpdateTime > DateTime.MinValue)
                    {
                        for (int i = 0; i < data.WorldObjectsDeleted.Count; i++)
                        {
                            if (data.WorldObjectsDeleted[i].UpdateTime < packet.UpdateTime)
                            {
                                //Удаляем все записи сроком старше 2х минут (их нужно хранить время между тем как игрок у которого удалился караван зальёт это на сервер, и все другие онлайн игроки получат эту инфу, а обновление идет раз в 5 сек)
                                if ((timeNow - data.WorldObjectsDeleted[i].UpdateTime).TotalSeconds > 120000)
                                {
                                    data.WorldObjectsDeleted.RemoveAt(i--);
                                }
                                continue;
                            }
                            if (data.WorldObjectsDeleted[i].LoginOwner == pLogin)
                            {
                                continue;
                            }
                            outWOD.Add(data.WorldObjectsDeleted[i]);
                        }
                    }

                    //завершили сбор информации клиенту
                    toClient.WObjects             = outWO;
                    toClient.WObjectsToDelete     = outWOD;
                    context.Player.LastUpdateTime = timeNow;
                }

                //прикрепляем письма
                //если есть команда на отключение без сохранения, то посылаем только одно это письмо
                var md = context.Player.Mails.FirstOrDefault(m => m.Type == ModelMailTradeType.AttackCancel);
                if (md == null)
                {
                    toClient.Mails       = context.Player.Mails;
                    context.Player.Mails = new List <ModelMailTrade>();
                }
                else
                {
                    toClient.Mails = new List <ModelMailTrade>()
                    {
                        md
                    };
                    context.Player.Mails.Remove(md);
                }

                //команда выполнить сохранение и отключиться
                toClient.NeedSaveAndExit = !context.Player.IsAdmin && data.EverybodyLogoff;

                //флаг, что на клиента кто-то напал и он должен запросить подробности
                toClient.AreAttacking = context.Player.AttackData != null && context.Player.AttackData.Host == context.Player && context.Player.AttackData.State == 1;

                return(toClient);
            }
        }