예제 #1
0
        private async Task Test_Nested_Scope_Update_Async(ManualResetEvent e)
        {
            Guid id;
            var  methodName = MethodBase.GetCurrentMethod().Name;

            using (var scope = new DataAccessScope())
            {
                var child = this.model.Children.Create();

                await scope.FlushAsync().ContinueOnAnyContext();

                id = child.Id;

                using (var inner = new DataAccessScope())
                {
                    child.Nickname = methodName;

                    await inner.CompleteAsync().ContinueOnAnyContext();
                }

                await scope.FlushAsync();

                Assert.AreEqual(child.Id, this.model.Children.Single(c => c.Nickname == methodName).Id);

                await scope.CompleteAsync().ContinueOnAnyContext();
            }

            Assert.AreEqual(id, this.model.Children.Single(c => c.Nickname == methodName).Id);

            e.Set();
        }
예제 #2
0
        public async Task <bool> SendAsync(string receiver, string title, string message)
        {
            // ToDo consume pen
            // ToDo check for ignore

            var accDto = await AuthDatabase.Instance.Accounts
                         .FirstOrDefaultAsync(acc => acc.Nickname == receiver)
                         .ConfigureAwait(false);

            if (accDto == null)
            {
                return(false);
            }

            using (var scope = new DataAccessScope())
            {
                var mailDto = GameDatabase.Instance.Players
                              .GetReference(accDto.Id)
                              .Inbox.Create();
                mailDto.SenderPlayer  = GameDatabase.Instance.Players.GetReference((int)Player.Account.Id);
                mailDto.SentDate      = DateTimeOffset.Now.ToUnixTimeSeconds();
                mailDto.Title         = title;
                mailDto.Message       = message;
                mailDto.IsMailNew     = true;
                mailDto.IsMailDeleted = false;

                await scope.CompleteAsync()
                .ConfigureAwait(false);

                var plr = GameServer.Instance.PlayerManager.Get(receiver);
                plr?.Mailbox.Add(new Mail(mailDto));
                return(true);
            }
        }
예제 #3
0
        public void Test_DeleteAsync()
        {
            Func <Task> func = async delegate
            {
                using (var scope = new DataAccessScope())
                {
                    var school = this.model.Schools.Create();

                    await scope.FlushAsync();

                    var id = school.Id;

                    var item = await this.model.Schools.FirstOrDefaultAsync(c => c.Id == id);

                    Assert.IsNotNull(item);

                    await this.model.Schools.Where(c => c.Id == id).DeleteAsync();

                    item = await this.model.Schools.FirstOrDefaultAsync(c => c.Id == id);

                    Assert.IsNull(item);

                    await scope.CompleteAsync();
                }
            };

            var task = Task.Run(func);

            task.GetAwaiter().GetResult();
        }
예제 #4
0
        internal async void UpdateCharacter(int charId, string objeto, string value = null)
        {
            using (var scope = new DataAccessScope())
            {
                var character = Model.Characters.GetReference(charId);

                // Define Online/Offline
                if (objeto == "online" && character.is_online)
                {
                    character.is_online = false;
                }
                else
                {
                    character.is_online = true;
                }

                // Define primeiro Login
                if (objeto == "firstlogin")
                {
                    character.is_movie_played = true;
                }

                // Define primeiro Login
                if (objeto == "watchFaction" && value != null)
                {
                    character.watched_faction = int.Parse(value);
                }

                await scope.CompleteAsync();
            }
        }
예제 #5
0
        public async Task LoseDurabilityAsync(int loss)
        {
            if (loss < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(loss));
            }

            if (Inventory.Player.Room == null)
            {
                throw new InvalidOperationException("Player is not inside a room");
            }

            if (Durability == -1)
            {
                return;
            }

            Durability -= loss;
            if (Durability < 0)
            {
                Durability = 0;
            }

            using (var scope = new DataAccessScope())
            {
                var dto = GameDatabase.Instance.PlayerItems.GetReference((int)Id);
                dto.Durability = Durability;

                await scope.CompleteAsync()
                .ConfigureAwait(false);
            }

            await Inventory.Player.Session.SendAsync(new SItemDurabilityInfoAckMessage(new[] { this.Map <PlayerItem, ItemDurabilityInfoDto>() }))
            .ConfigureAwait(false);
        }
예제 #6
0
        public async Task CreateNickHandler(GameServer server, GameSession session, CCreateNickReqMessage message)
        {
            if (session.Player == null || !string.IsNullOrWhiteSpace(session.Player.Account.Nickname))
            {
                session.Dispose();
                return;
            }

            Logger.Info()
            .Account(session)
            .Message("Creating nickname {0}", message.Nickname)
            .Write();

            if (!await IsNickAvailableAsync(message.Nickname).ConfigureAwait(false))
            {
                Logger.Error()
                .Account(session)
                .Message("Nickname not available: {0}", message.Nickname)
                .Write();

                await session.SendAsync(new SCheckNickAckMessage(false))
                .ConfigureAwait(false);

                return;
            }

            session.Player.Account.Nickname = message.Nickname;
            using (var scope = new DataAccessScope())
            {
                var accountDto = AuthDatabase.Instance.Accounts.GetReference((int)session.Player.Account.Id);
                //if (accountDto == null)
                //{
                //    Logger.Error()
                //        .Account(session)
                //        .Message("Account {0} not found", session.Player.Account.Id)
                //        .Write();

                //    await session.SendAsync(new SCheckNickAckMessage(false))
                //        .ConfigureAwait(false);
                //    return;
                //}
                accountDto.Nickname = message.Nickname;

                await scope.CompleteAsync()
                .ConfigureAwait(false);
            }
            //session.Send(new SCreateNickAckMessage { Nickname = msg.Nickname });
            await session.SendAsync(new SServerResultInfoAckMessage(ServerResult.CreateNicknameSuccess))
            .ConfigureAwait(false);

            Logger.Info()
            .Account(session)
            .Message("Created nickname {0}", message.Nickname)
            .Write();

            await LoginAsync(server, session)
            .ConfigureAwait(false);
        }
예제 #7
0
 public async void FactionInative(int characterId, int faction, byte enabled)
 {
     using (var scope = new DataAccessScope())
     {
         var factions = Model.CharactersFactions.GetReference(new { Id = faction, CharacterId = characterId });
         factions.flags = enabled;
         await scope.CompleteAsync();
     }
 }
예제 #8
0
        ///
        internal async void ItemUpdate(int itemId)
        {
            using (var scope = new DataAccessScope())
            {
                var character = Model.CharactersInventorys.First(a => a.Id == 8);
                character.item = (ulong)itemId;

                await scope.CompleteAsync();
            }
        }
예제 #9
0
        /// <summary>
        /// Update character name
        /// </summary>
        /// <param name="handler"></param>
        internal async void UpdateName(CmsgCharRename handler)
        {
            using (var scope = new DataAccessScope())
            {
                var character = Model.Characters.GetByPrimaryKey(handler.Id);
                character.name = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(handler.Name);

                await scope.CompleteAsync();
            }
        }
예제 #10
0
        /// <summary>
        ///     Update realm flag status.
        /// </summary>
        /// <param name="realm">Realms model</param>
        /// <param name="flag">RealmFlag status</param>
        public void UpdateRealmStatus(Realms realm, RealmFlag flag)
        {
            using (var scope = new DataAccessScope())
            {
                var model = Model.Realms.GetReference(realm);
                model.flag = flag;

                scope.CompleteAsync();
            }
        }
예제 #11
0
        /// <summary>
        ///     Sets the authenticated user's sessionkey.
        /// </summary>
        /// <param name="username">string</param>
        /// <param name="key">byte</param>
        /// <returns>null</returns>
        public async void SetSessionKey(string username, byte[] key)
        {
            var account = GetAccount(username);

            using (var scope = new DataAccessScope())
            {
                var user = Model.Users.GetReference(account.Id);
                user.sessionkey = key;
                await scope.CompleteAsync();
            }
        }
예제 #12
0
        /// <summary>
        /// Update movement on database
        /// </summary>
        /// <param name="character"></param>
        /// <returns></returns>
        internal async Task UpdateMovement(Characters character)
        {
            using (var scope = new DataAccessScope())
            {
                var update = Model.Characters.GetReference(character.Id);
                update.MapX = character.MapX;
                update.MapY = character.MapY;
                update.MapZ = character.MapZ;
                update.MapO = character.MapO;

                await scope.CompleteAsync();
            }
        }
예제 #13
0
        /// <summary>
        /// Delete character
        /// </summary>
        /// <param name="id"></param>
        internal async void DeleteCharacter(int id)
        {
            // Check if char is own of player
            // if not BAN account and IP

            var Char = Model.Characters.FirstOrDefault(a => a.Id == id);

            using (var scope = new DataAccessScope())
            {
                // DONE: Delete Action Bar
                await Model.CharactersActionBars.Where(a => a.character == Char).DeleteAsync();

                // DONE: Delete Skills
                await Model.CharactersSkills.Where(a => a.character == Char).DeleteAsync();

                // DONE: Delete Spells
                await Model.CharactersSpells.Where(a => a.character == Char).DeleteAsync();

                // DONE: Delete Inventory
                await Model.CharactersInventorys.Where(a => a.character == Char).DeleteAsync();

                // DONE: Delete Reputation
                await Model.CharactersFactions.Where(a => a.character == Char).DeleteAsync();

                // Delete mails +  Delete mail items + Return mails
                // Delete ActionHouse
                // Delete Petitions
                // Delete GM Tickets
                // Delete Corpse
                // DONE: Delete Social
                await Model.CharactersSocials.Where(a => a.character == Char).DeleteAsync();

                // Delete Quests
                // Delete Honor

                // DONE: Delete Character
                await Model.Characters.Where(a => a.Id == id).DeleteAsync();

                await scope.CompleteAsync();
            }
        }
예제 #14
0
        public async Task LoginHandler(GameServer server, GameSession session, CLoginReqMessage message)
        {
            Logger.Info()
            .Account(message.AccountId, message.Username)
            .Message("Login from {0}", ((TcpTransport)session.Transport).Socket.RemoteEndPoint)
            .Write();

            if (message.Version != s_version)
            {
                Logger.Error()
                .Account(message.AccountId, message.Username)
                .Message("Invalid client version {0}", message.Version)
                .Write();

                await session.SendAsync(new SLoginAckMessage { Result = GameLoginResult.WrongVersion })
                .ConfigureAwait(false);

                return;
            }

            if (server.PlayerManager.Count >= Config.Instance.PlayerLimit)
            {
                Logger.Error()
                .Account(message.AccountId, message.Username)
                .Message("Server is full")
                .Write();

                await session.SendAsync(new SLoginAckMessage { Result = GameLoginResult.ServerFull })
                .ConfigureAwait(false);

                return;
            }

            #region Validate Login

            var accountDto = await AuthDatabase.Instance.Accounts
                             .FirstOrDefaultAsync(acc => acc.Id == (int)message.AccountId)
                             .ConfigureAwait(false);

            if (accountDto == null)
            {
                Logger.Error()
                .Account(message.AccountId, message.Username)
                .Message("Wrong login")
                .Write();

                await session.SendAsync(new SLoginAckMessage { Result = GameLoginResult.SessionTimeout })
                .ConfigureAwait(false);

                return;
            }

            uint inputSessionId;
            if (!uint.TryParse(message.SessionId, out inputSessionId))
            {
                Logger.Error()
                .Account(message.AccountId, message.Username)
                .Message("Wrong login")
                .Write();

                await session.SendAsync(new SLoginAckMessage { Result = GameLoginResult.SessionTimeout })
                .ConfigureAwait(false);

                return;
            }

            var sessionId = Hash.GetUInt32 <CRC32>($"<{accountDto.Username}+{accountDto.Password}>");
            if (sessionId != inputSessionId)
            {
                Logger.Error()
                .Account(message.AccountId, message.Username)
                .Message("Wrong login")
                .Write();

                await session.SendAsync(new SLoginAckMessage { Result = GameLoginResult.SessionTimeout })
                .ConfigureAwait(false);

                return;
            }

            var now = DateTimeOffset.Now.ToUnixTimeSeconds();
            var ban = await accountDto.Bans.FirstOrDefaultAsync(b => b.Date + b.Duration > now)
                      .ConfigureAwait(false);

            if (ban != null)
            {
                var unbanDate = DateTimeOffset.FromUnixTimeSeconds(ban.Date + ban.Duration);
                Logger.Error()
                .Account(message.AccountId, message.Username)
                .Message("Banned until {0}", unbanDate)
                .Write();

                await session.SendAsync(new SLoginAckMessage { Result = GameLoginResult.SessionTimeout })
                .ConfigureAwait(false);

                return;
            }

            var account = new Account(accountDto);

            #endregion

            if (account.SecurityLevel < Config.Instance.SecurityLevel)
            {
                Logger.Error()
                .Account(account)
                .Message("No permission to enter this server({0} or above required)", Config.Instance.SecurityLevel)
                .Write();

                await session.SendAsync(new SLoginAckMessage { Result = (GameLoginResult)9 })
                .ConfigureAwait(false);

                return;
            }

            if (message.KickConnection)
            {
                Logger.Info()
                .Account(account)
                .Message("Kicking old connection")
                .Write();

                var oldPlr = server.PlayerManager.Get(account.Id);
                oldPlr?.Disconnect();
            }

            if (server.PlayerManager.Contains(account.Id))
            {
                Logger.Error()
                .Account(account)
                .Message("Already online")
                .Write();

                await session.SendAsync(new SLoginAckMessage { Result = GameLoginResult.TerminateOtherConnection })
                .ConfigureAwait(false);

                return;
            }

            using (var scope = new DataAccessScope())
            {
                var plrDto = await GameDatabase.Instance.Players
                             .FirstOrDefaultAsync(p => p.Id == (int)account.Id)
                             .ConfigureAwait(false);

                if (plrDto == null)
                {
                    // first time connecting to this server
                    plrDto        = GameDatabase.Instance.Players.Create((int)account.Id);
                    plrDto.Level  = Config.Instance.Game.StartLevel;
                    plrDto.PEN    = Config.Instance.Game.StartPEN;
                    plrDto.AP     = Config.Instance.Game.StartAP;
                    plrDto.Coins1 = Config.Instance.Game.StartCoins1;
                    plrDto.Coins2 = Config.Instance.Game.StartCoins2;

                    await scope.CompleteAsync()
                    .ConfigureAwait(false);
                }

                session.Player = new Player(session, account, plrDto);
            }

            if (server.PlayerManager.Contains(session.Player))
            {
                session.Player = null;
                Logger.Error()
                .Account(account)
                .Message("Already online")
                .Write();

                await session.SendAsync(new SLoginAckMessage { Result = GameLoginResult.TerminateOtherConnection })
                .ConfigureAwait(false);

                return;
            }

            server.PlayerManager.Add(session.Player);

            Logger.Info()
            .Account(account)
            .Message("Login success")
            .Write();

            await session.SendAsync(new SLoginAckMessage
            {
                Result    = string.IsNullOrWhiteSpace(account.Nickname) ? GameLoginResult.ChooseNickname : GameLoginResult.OK,
                AccountId = session.Player.Account.Id
            }).ConfigureAwait(false);

            if (!string.IsNullOrWhiteSpace(account.Nickname))
            {
                await LoginAsync(server, session).ConfigureAwait(false);
            }
        }
예제 #15
0
        public async Task LoginHandler(ISession session, CAuthInEUReqMessage message)
        {
            var ip = ((IPEndPoint)((TcpProcessor)session.Processor).Socket.RemoteEndPoint).Address.ToString();

            _logger.Debug()
            .Message("Login from {0} with username {1}", ip, message.Username)
            .Write();

            var db      = AuthDatabase.Instance;
            var account = await db.Accounts.FirstOrDefaultAsync(acc => acc.Username == message.Username)
                          .ConfigureAwait(false);

            if (account == null)
            {
                if (Config.Instance.NoobMode)
                {
                    // NoobMode: Create a new account if non exists
                    using (var scope = new DataAccessScope())
                    {
                        account          = db.Accounts.Create();
                        account.Username = message.Username;

                        var bytes = new byte[16];
                        using (var rng = new RNGCryptoServiceProvider())
                            rng.GetBytes(bytes);

                        account.Salt     = Hash.GetString <SHA1CryptoServiceProvider>(bytes);
                        account.Password = Hash.GetString <SHA1CryptoServiceProvider>(message.Password + "+" + account.Salt);

                        await scope.CompleteAsync()
                        .ConfigureAwait(false);
                    }
                }
                else
                {
                    _logger.Error()
                    .Message("Wrong login for {0}", message.Username)
                    .Write();
                    await session.SendAsync(new SAuthInEuAckMessage(AuthLoginResult.WrongIdorPw))
                    .ConfigureAwait(false);

                    return;
                }
            }

            var password = Hash.GetString <SHA1CryptoServiceProvider>(message.Password + "+" + account.Salt);

            if (!account.Password.Equals(password, StringComparison.InvariantCultureIgnoreCase))
            {
                if (Config.Instance.NoobMode)
                {
                    // Noob Mode: Save new password
                    using (var scope = new DataAccessScope())
                    {
                        var acc   = db.Accounts.GetReference(account.Id);
                        var bytes = new byte[16];
                        using (var rng = new RNGCryptoServiceProvider())
                            rng.GetBytes(bytes);

                        var salt = Hash.GetString <SHA1CryptoServiceProvider>(bytes);
                        password     = Hash.GetString <SHA1CryptoServiceProvider>(message.Password + "+" + salt);
                        acc.Password = password;
                        acc.Salt     = salt;

                        await scope.CompleteAsync()
                        .ConfigureAwait(false);
                    }
                }
                else
                {
                    _logger.Error()
                    .Message("Wrong login for {0}", message.Username)
                    .Write();
                    await session.SendAsync(new SAuthInEuAckMessage(AuthLoginResult.WrongIdorPw))
                    .ConfigureAwait(false);

                    return;
                }
            }

            var now = DateTimeOffset.Now.ToUnixTimeSeconds();
            var ban = await account.Bans.FirstOrDefaultAsync(b => b.Date + b.Duration > now)
                      .ConfigureAwait(false);

            if (ban != null)
            {
                var unbanDate = DateTimeOffset.FromUnixTimeSeconds(ban.Date + ban.Duration);
                _logger.Error()
                .Message("{0} is banned until {1}", message.Username, unbanDate)
                .Write();
                await session.SendAsync(new SAuthInEuAckMessage(unbanDate))
                .ConfigureAwait(false);

                return;
            }

            _logger.Info()
            .Message("Login success for {0}", message.Username)
            .Write();

            using (var scope = new DataAccessScope())
            {
                var entry = account.LoginHistory.Create();
                entry.Date = DateTimeOffset.Now.ToUnixTimeSeconds();
                entry.IP   = ip;

                await scope.CompleteAsync()
                .ConfigureAwait(false);
            }

            // ToDo proper session generation
            var sessionId = Hash.GetUInt32 <CRC32>($"<{account.Username}+{password}>");
            await session.SendAsync(new SAuthInEuAckMessage(AuthLoginResult.OK, (ulong)account.Id, sessionId))
            .ConfigureAwait(false);
        }
        public async Task RepairItemHandler(GameSession session, CRepairItemReqMessage message)
        {
            var shop = GameServer.Instance.ResourceCache.GetShop();

            foreach (var id in message.Items)
            {
                var item = session.Player.Inventory[id];
                if (item == null)
                {
                    _logger.Error()
                    .Account(session)
                    .Message("Item {0} not found", id)
                    .Write();
                    await session.SendAsync(new SRepairItemAckMessage { Result = ItemRepairResult.Error0 })
                    .ConfigureAwait(false);

                    return;
                }
                if (item.Durability == -1)
                {
                    _logger.Error()
                    .Account(session)
                    .Message("Item {0} {1} {2} {3} can not be repaired", item.ItemNumber, item.PriceType, item.PeriodType, item.Period)
                    .Write();
                    await session.SendAsync(new SRepairItemAckMessage { Result = ItemRepairResult.Error1 })
                    .ConfigureAwait(false);

                    return;
                }

                var cost = item.CalculateRepair();
                if (session.Player.PEN < cost)
                {
                    await session.SendAsync(new SRepairItemAckMessage { Result = ItemRepairResult.NotEnoughMoney })
                    .ConfigureAwait(false);

                    return;
                }

                var price = shop.GetPrice(item);
                if (price == null)
                {
                    _logger.Error()
                    .Account(session)
                    .Message("No shop entry found for {0} {1} {2} {3}", item.ItemNumber, item.PriceType, item.PeriodType, item.Period)
                    .Write();
                    await session.SendAsync(new SRepairItemAckMessage { Result = ItemRepairResult.Error4 })
                    .ConfigureAwait(false);

                    return;
                }
                if (item.Durability >= price.Durability)
                {
                    await session.SendAsync(new SRepairItemAckMessage { Result = ItemRepairResult.OK, ItemId = item.Id })
                    .ConfigureAwait(false);

                    continue;
                }

                item.Durability     = price.Durability;
                session.Player.PEN -= cost;

                using (var scope = new DataAccessScope())
                {
                    var playerDto = GameDatabase.Instance.Players.GetReference((int)session.Player.Account.Id);
                    playerDto.PEN = (int)session.Player.PEN;

                    var itemDto = GameDatabase.Instance.PlayerItems.GetReference((int)item.Id);
                    itemDto.Durability = item.Durability;

                    await scope.CompleteAsync()
                    .ConfigureAwait(false);
                }

                await session.SendAsync(new SRepairItemAckMessage { Result = ItemRepairResult.OK, ItemId = item.Id })
                .ConfigureAwait(false);

                await session.SendAsync(new SRefreshCashInfoAckMessage { PEN = session.Player.PEN, AP = session.Player.AP })
                .ConfigureAwait(false);
            }
        }
        public async Task RefundItemHandler(GameSession session, CRefundItemReqMessage message)
        {
            var shop = GameServer.Instance.ResourceCache.GetShop();

            var item = session.Player.Inventory[message.ItemId];

            if (item == null)
            {
                _logger.Error()
                .Account(session)
                .Message("Item {0} not found", message.ItemId)
                .Write();
                await session.SendAsync(new SRefundItemAckMessage { Result = ItemRefundResult.Failed })
                .ConfigureAwait(false);

                return;
            }

            var price = shop.GetPrice(item);

            if (price == null)
            {
                _logger.Error()
                .Account(session)
                .Message("No shop entry found for {0} {1} {2} {3}", item.ItemNumber, item.PriceType, item.PeriodType, item.Period)
                .Write();
                await session.SendAsync(new SRefundItemAckMessage { Result = ItemRefundResult.Failed })
                .ConfigureAwait(false);

                return;
            }
            if (!price.CanRefund)
            {
                _logger.Error()
                .Account(session)
                .Message("Cannot refund {0} {1} {2} {3}", item.ItemNumber, item.PriceType, item.PeriodType, item.Period)
                .Write();
                await session.SendAsync(new SRefundItemAckMessage { Result = ItemRefundResult.Failed })
                .ConfigureAwait(false);

                return;
            }

            session.Player.PEN += item.CalculateRefund();
            session.Player.Inventory.Remove(item);


            using (var scope = new DataAccessScope())
            {
                var playerDto = GameDatabase.Instance.Players.GetReference((int)session.Player.Account.Id);
                playerDto.PEN = (int)session.Player.PEN;

                await scope.CompleteAsync()
                .ConfigureAwait(false);
            }

            await session.SendAsync(new SRefundItemAckMessage { Result = ItemRefundResult.OK, ItemId = item.Id })
            .ConfigureAwait(false);

            await session.SendAsync(new SRefreshCashInfoAckMessage { PEN = session.Player.PEN, AP = session.Player.AP })
            .ConfigureAwait(false);
        }