private void OnUserChat(InPacket packet)
        {
            packet.Decode <int>();

            var message     = packet.Decode <string>();
            var onlyBalloon = packet.Decode <bool>();

            if (message.StartsWith("!"))
            {
                try
                {
                    Socket.WvsGame.CommandRegistry.Process(
                        this,
                        message.Substring(1)
                        );
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.ToString());
                    Message("An error has occured while executing that command.");
                }

                return;
            }

            using (var p = new OutPacket(GameSendOperations.UserChat))
            {
                p.Encode <int>(ID);
                p.Encode <bool>(false);
                p.Encode <string>(message);
                p.Encode <bool>(onlyBalloon);
                Field.BroadcastPacket(p);
            }
        }
예제 #2
0
        private void OnMigrationRegistryRequest(InPacket packet)
        {
            using (var p = new OutPacket(InteropRecvOperations.MigrationRegisterResult))
            {
                p.Encode <string>(packet.Decode <string>());
                p.Encode <string>(packet.Decode <string>());

                var characterID = packet.Decode <int>();

                _wvsGame.PendingMigrations.Add(characterID);
                p.Encode <bool>(true);
                p.Encode <int>(characterID);

                var endpoint = _wvsGame.GameServer.Channel.LocalAddress as IPEndPoint;
                var address  = endpoint.Address.MapToIPv4().GetAddressBytes();
                var port     = endpoint.Port;

                foreach (var b in address)
                {
                    p.Encode <byte>(b);
                }
                p.Encode <short>((short)port);

                SendPacket(p);
            }
        }
예제 #3
0
        public bool OnPacket(FieldUser user, GameRecvOperations operation, InPacket packet)
        {
            switch (operation)
            {
            case GameRecvOperations.MobMove:
            {
                var objectID = packet.Decode <int>();
                var mob      = Objects
                               .OfType <FieldMob>()
                               .FirstOrDefault(m => m.ID == objectID);
                return(mob?.OnPacket(user, operation, packet) ?? true);
            }

            case GameRecvOperations.NpcMove:
            {
                var objectID = packet.Decode <int>();
                var npc      = Objects
                               .OfType <FieldNPC>()
                               .FirstOrDefault(n => n.ID == objectID);
                return(npc?.OnPacket(user, operation, packet) ?? true);
            }

            case GameRecvOperations.DropPickUpRequest:
                OnDropPickUpRequest(user, packet);
                break;

            default:
                return(user.OnPacket(operation, packet));
            }

            return(true);
        }
        private void OnUserGatherItemRequest(InPacket packet)
        {
            packet.Decode <int>();

            var inventoryType = (ItemInventoryType)packet.Decode <byte>();
            var inventoryCopy = Character.GetInventory(inventoryType).Items
                                .Where(i => i.Position > 0)
                                .OrderBy(i => i.Position)
                                .ToList();
            short pos = 1;

            ModifyInventory(i =>
            {
                inventoryCopy.ForEach(i.Remove);
                inventoryCopy.ForEach(item => item.Position = pos++);
                inventoryCopy.ForEach(i.Set);
            }, true);

            using (var p = new OutPacket(GameSendOperations.GatherItemResult))
            {
                p.Encode <bool>(false);
                p.Encode <byte>((byte)inventoryType);
                SendPacket(p);
            }
        }
        private void OnUserAbilityUpRequest(InPacket packet)
        {
            packet.Decode <int>();
            var type = (ModifyStatType)packet.Decode <int>();

            if (Character.AP > 0)
            {
                ModifyStats(s =>
                {
                    switch (type)
                    {
                    case ModifyStatType.STR:
                        s.STR++;
                        break;

                    case ModifyStatType.DEX:
                        s.DEX++;
                        break;

                    case ModifyStatType.INT:
                        s.INT++;
                        break;

                    case ModifyStatType.LUK:
                        s.LUK++;
                        break;
                    }

                    s.AP--;
                }, true);
            }
        }
        private void OnUserChangeSlotPositionRequest(InPacket packet)
        {
            packet.Decode <int>();

            var inventoryType = (ItemInventoryType)packet.Decode <byte>();
            var fromSlot      = packet.Decode <short>();
            var toSlot        = packet.Decode <short>();

            packet.Decode <short>();

            if (toSlot == 0)
            {
                ModifyInventory(i =>
                {
                    var item = Character.GetInventory(inventoryType).Items
                               .Single(ii => ii.Position == fromSlot);
                    var drop = new FieldDropItem(item)
                    {
                        X = X, Y = Y
                    };

                    i.Remove(item);
                    Field.Enter(drop, () => drop.GetEnterFieldPacket(0x1, this));
                }, true);
                return;
            }

            ModifyInventory(i => i.Move(inventoryType, fromSlot, toSlot), true);
        }
        private void OnDeleteCharacter(InPacket packet)
        {
            var spw         = packet.Decode <string>();
            var characterID = packet.Decode <int>();

            byte result = 0x0;

            if (!BCrypt.Net.BCrypt.Verify(spw, Account.SPW))
            {
                result = 0x14;
            }

            if (result == 0x0)
            {
                using (var db = _container.GetInstance <DataContext>())
                {
                    var data      = Account.Data.Single(a => a.WorldID == _selectedWorld.ID);
                    var character = data.Characters.Single(c => c.ID == characterID);

                    data.Characters.Remove(character);
                    db.Characters.Remove(character);
                    db.Update(Account);
                    db.SaveChanges();
                }
            }

            using (var p = new OutPacket(LoginSendOperations.DeleteCharacterResult))
            {
                p.Encode <int>(characterID);
                p.Encode <byte>(result);
                SendPacket(p);
            }
        }
        private void OnUserSkillUpRequest(InPacket packet)
        {
            packet.Decode <int>();
            var templateID = packet.Decode <int>();
            var template   = Socket.WvsGame.SkillTemplates.Get(templateID);
            var skill      = (Skill)templateID;

            if (template == null)
            {
                return;
            }
            if (Character.SP <= 0)
            {
                return;
            }
            // TODO: hidden skill check

            int maxLevel = template.MaxLevel;

            if (skill.IsSkillNeedMasterLevel())
            {
                maxLevel = Character.GetSkillMasterLevel(skill);
            }

            if (Character.GetSkillLevel(skill) >= maxLevel)
            {
                return;
            }

            ModifyStats(s => s.SP--);
            ModifySkill(s => s.Add(Socket.WvsGame.SkillTemplates.Get(templateID)), true);
        }
 public void Decode(InPacket packet)
 {
     Name         = packet.Decode <string>();
     UserNo       = packet.Decode <int>();
     WorldID      = packet.Decode <byte>();
     ID           = packet.Decode <byte>();
     AdultChannel = packet.Decode <bool>();
 }
        private void OnUserStatChangeItemUseRequest(InPacket packet)
        {
            packet.Decode <int>();

            var position   = packet.Decode <short>();
            var templateID = packet.Decode <int>();
            var template   = Socket.WvsGame.ItemTemplates.Get(templateID);

            var inventory      = Character.GetInventory(ItemInventoryType.Use);
            var inventoryItems = inventory.Items;
            var item           = inventoryItems.SingleOrDefault(i => i.Position == position);

            if (item == null)
            {
                return;
            }
            if (item.TemplateID != templateID)
            {
                return;
            }
            if (!(template is StatChangeItemTemplate scTemplate))
            {
                return;
            }

            var temporaryStats = scTemplate.GetTemporaryStats();

            if (temporaryStats.Count > 0)
            {
                var expire = DateTime.Now.AddMilliseconds(scTemplate.Time);
                ModifyTemporaryStat(ts => temporaryStats.ForEach(t =>
                                                                 ts.Set(t.Key, -templateID, t.Value, expire)
                                                                 ));
            }

            if (!temporaryStats.ContainsKey(TemporaryStatType.Morph))
            {
                var incHP = 0;
                var incMP = 0;

                incHP += scTemplate.HP;
                incMP += scTemplate.MP;
                incHP += BasicStat.MaxHP * (scTemplate.HPr / 100);
                incMP += BasicStat.MaxMP * (scTemplate.MPr / 100);

                if (incHP > 0 || incMP > 0)
                {
                    ModifyStats(s =>
                    {
                        s.HP = Math.Min(BasicStat.MaxHP, s.HP + incHP);
                        s.MP = Math.Min(BasicStat.MaxMP, s.MP + incMP);
                    });
                }
            }

            ModifyInventory(i => i.Remove(item));
            ModifyStats(exclRequest: true);
        }
예제 #11
0
        private void OnMigrationRegisterResult(InPacket packet)
        {
            var sessionKey = packet.Decode <string>();
            var server     = _wvsCenter.InteropServer.Sockets.Single(s => s.SessionKey == sessionKey);

            using (var p = new OutPacket(InteropSendOperations.MigrationResult))
            {
                p.Encode <string>(packet.Decode <string>());

                var result = packet.Decode <bool>();

                p.Encode <bool>(result);

                if (!result)
                {
                    return;
                }

                p.Encode <int>(packet.Decode <int>());

                p.Encode <byte>(packet.Decode <byte>());
                p.Encode <byte>(packet.Decode <byte>());
                p.Encode <byte>(packet.Decode <byte>());
                p.Encode <byte>(packet.Decode <byte>());
                p.Encode <short>(packet.Decode <short>());

                server.SendPacket(p);
            }
        }
        private void OnUserTransferFieldRequest(InPacket packet)
        {
            packet.Decode <byte>();
            packet.Decode <int>();

            var portalName   = packet.Decode <string>();
            var portal       = Field.Template.Portals.Values.Single(p => p.Name.Equals(portalName));
            var targetField  = Socket.WvsGame.FieldFactory.Get(portal.ToMap);
            var targetPortal = targetField.Template.Portals.Values.Single(p => p.Name.Equals(portal.ToName));

            Character.FieldPortal = (byte)targetPortal.ID;
            targetField.Enter(this);
        }
        private void OnUserEmotion(InPacket packet)
        {
            var emotion      = packet.Decode <int>();
            var duration     = packet.Decode <int>();
            var byItemOption = packet.Decode <bool>();

            using (var p = new OutPacket(GameSendOperations.UserEmotion))
            {
                p.Encode <int>(ID);
                p.Encode <int>(emotion);
                p.Encode <int>(duration);
                p.Encode <bool>(byItemOption);
                Field.BroadcastPacket(this, p);
            }
        }
        private void OnUserAbilityMassUpRequest(InPacket packet)
        {
            packet.Decode <int>();
            var count = packet.Decode <int>();
            var inc   = new Dictionary <int, int>();

            for (var i = 0; i < count; i++)
            {
                inc.Add(packet.Decode <int>(), packet.Decode <int>());
            }

            var total = inc.Values.Sum();

            if (Character.AP < total)
            {
                return;
            }

            ModifyStats(s =>
            {
                inc.ForEach(p =>
                {
                    var type  = (ModifyStatType)p.Key;
                    var value = p.Value;

                    switch (type)
                    {
                    case ModifyStatType.STR:
                        s.STR += Convert.ToInt16(value);
                        break;

                    case ModifyStatType.DEX:
                        s.DEX += Convert.ToInt16(value);
                        break;

                    case ModifyStatType.INT:
                        s.INT += Convert.ToInt16(value);
                        break;

                    case ModifyStatType.LUK:
                        s.LUK += Convert.ToInt16(value);
                        break;
                    }
                });

                s.AP -= Convert.ToInt16(total);
            }, true);
        }
        private void OnUserSitRequest(InPacket packet)
        {
            var id = packet.Decode <short>();

            using (var p = new OutPacket(GameSendOperations.UserSitResult))
            {
                if (id < 0)
                {
                    PortableChairID = null;
                    p.Encode <byte>(0);
                }
                else
                {
                    p.Encode <byte>(1);
                    p.Encode <short>(id); // TODO: proper checks for this
                }

                SendPacket(p);
            }

            if (PortableChairID != null)
            {
                return;
            }

            using (var p = new OutPacket(GameSendOperations.UserSetActivePortableChair))
            {
                p.Encode <int>(ID);
                p.Encode <int>(0);
                Field.BroadcastPacket(this, p);
            }
        }
        private void OnUserBodyAttack(InPacket packet)
        {
            packet.Decode <byte>();
            var attackInfo = new BodyAttackInfo(Character);

            attackInfo.Decode(packet);
            OnUserAttack(attackInfo);
        }
예제 #17
0
        private void OnMigrationRequest(InPacket packet)
        {
            var serverType = (ServerType)packet.Decode <byte>();
            var serverID   = packet.Decode <byte>();

            var server = _wvsCenter.InteropServer.Sockets
                         .Single(s => s.ServerType == serverType &&
                                 s.ServerID == serverID);

            using (var p = new OutPacket(InteropSendOperations.MigrationRegistryRequest))
            {
                p.Encode <string>(SessionKey);
                p.Encode <string>(packet.Decode <string>());
                p.Encode <int>(packet.Decode <int>());
                server.SendPacket(p);
            }
        }
        private void OnCheckSPWRequest(InPacket packet, bool vac)
        {
            var spw         = packet.Decode <string>();
            var characterID = packet.Decode <int>();

            packet.Decode <string>(); // sMacAddress
            packet.Decode <string>(); // sMacAddressWithHDDSerial

            if (string.IsNullOrEmpty(Account.SPW))
            {
                return;
            }
            if (!BCrypt.Net.BCrypt.Verify(spw, Account.SPW))
            {
                using (var p = new OutPacket(LoginSendOperations.CheckSPWResult))
                {
                    p.Encode <bool>(false); // Unused byte
                    SendPacket(p);
                }

                return;
            }

            if (vac)
            {
                var character = Account.Data
                                .SelectMany(a => a.Characters)
                                .Single(c => c.ID == characterID);
                _selectedWorld = _wvsLogin.InteropClients
                                 .Select(c => c.Socket.WorldInformation)
                                 .SingleOrDefault(w => w.ID == character.Data.WorldID);
                _selectedChannel = _selectedWorld.Channels.First();
            }

            var world = _wvsLogin.InteropClients.Single(c => c.Socket.WorldInformation.ID == _selectedWorld.ID);

            using (var p = new OutPacket(InteropRecvOperations.MigrationRequest))
            {
                p.Encode <byte>((byte)ServerType.Game);
                p.Encode <byte>(_selectedChannel.ID);
                p.Encode <string>(SessionKey);
                p.Encode <int>(characterID);
                world.Socket.SendPacket(p);
            }
        }
        private void OnUserCharacterInfoRequest(InPacket packet)
        {
            packet.Decode <int>();
            var user = Field.GetUser(packet.Decode <int>());

            if (user == null)
            {
                return;
            }

            using (var p = new OutPacket(GameSendOperations.CharacterInfo))
            {
                var c = user.Character;

                p.Encode <int>(user.ID);
                p.Encode <byte>(c.Level);
                p.Encode <Job>(c.Job);
                p.Encode <short>(c.POP);

                p.Encode <byte>(0);

                p.Encode <string>(""); // sCommunity
                p.Encode <string>(""); // sAlliance

                p.Encode <byte>(0);
                p.Encode <byte>(0);
                p.Encode <byte>(0); // TamingMobInfo
                p.Encode <byte>(0); // WishItemInfo

                p.Encode <int>(0);  // MedalAchievementInfo
                p.Encode <short>(0);

                var chairs = c.Inventories
                             .SelectMany(i => i.Items)
                             .Select(i => i.TemplateID)
                             .Where(i => i / 10000 == 301)
                             .ToList();
                p.Encode <int>(chairs.Count);
                chairs.ForEach(i => p.Encode <int>(i));
                SendPacket(p);
            }
        }
예제 #20
0
        private void OnFuncKeyMappedModified(InPacket packet)
        {
            var v3 = packet.Decode <int>();

            if (v3 > 0)
            {
                return;
            }
            var count = packet.Decode <int>();

            for (var i = 0; i < count; i++)
            {
                var key    = packet.Decode <int>();
                var type   = packet.Decode <byte>();
                var action = packet.Decode <int>();

                var functionKeys = FieldUser.Character.FunctionKeys;
                var functionKey  = functionKeys.SingleOrDefault(f => f.Key == key);

                if (type > 0 || action > 0)
                {
                    if (functionKey != null)
                    {
                        functionKey.Type   = type;
                        functionKey.Action = action;
                    }
                    else
                    {
                        functionKeys.Add(new FunctionKey
                        {
                            Key    = key,
                            Type   = type,
                            Action = action
                        });
                    }
                }
                else
                {
                    functionKeys.Remove(functionKey);
                }
            }
        }
        private void OnUserDropMoneyRequest(InPacket packet)
        {
            packet.Decode <int>();
            var money = packet.Decode <int>();

            ModifyStats(s =>
            {
                if (s.Money < money)
                {
                    return;
                }
                var drop = new FieldDropMoney(money)
                {
                    X = X, Y = Y
                };

                s.Money -= money;
                Field.Enter(drop, () => drop.GetEnterFieldPacket(0x1, this));
            }, true);
        }
예제 #22
0
        private void OnServerRegisterResult(InPacket packet)
        {
            if (packet.Decode <bool>())
            {
                return;                        // TODO: disconnect?
            }
            var worldInformation = new WorldInformation();

            worldInformation.Decode(packet);
            Logger.Info($"Registered Center server, {worldInformation.Name}");
        }
        private void OnUserSkillCancelRequest(InPacket packet)
        {
            var templateID = packet.Decode <int>();
            var template   = Socket.WvsGame.SkillTemplates.Get(templateID);

            if (template == null)
            {
                return;
            }

            ModifyTemporaryStat(ts => ts.Reset(templateID));
        }
        private void OnUserSkillUseRequest(InPacket packet)
        {
            packet.Decode <int>();
            var templateID = packet.Decode <int>();
            var template   = Socket.WvsGame.SkillTemplates.Get(templateID);
            var skillLevel = Character.GetSkillLevel((Skill)templateID);

            if (template == null)
            {
                return;
            }
            if (skillLevel <= 0)
            {
                return;
            }

            var levelTemplate  = template.LevelData[skillLevel];
            var temporaryStats = levelTemplate.GetTemporaryStats();

            if (temporaryStats.Count > 0)
            {
                ModifyTemporaryStat(ts =>
                {
                    if (levelTemplate.Time > 0)
                    {
                        var expire = DateTime.Now.AddSeconds(levelTemplate.Time);
                        temporaryStats.ForEach(t => ts.Set(t.Key, templateID, t.Value, expire));
                    }
                    else
                    {
                        temporaryStats.ForEach(t => ts.Set(t.Key, templateID, t.Value));
                    }
                });
            }

            // TODO: party/map buffs
            // TODO: remote effects
            ModifyStats(exclRequest: true);
        }
        private void OnUserStatChangeItemCancelRequest(InPacket packet)
        {
            var templateID = packet.Decode <int>();
            var template   = Socket.WvsGame.ItemTemplates.Get(-templateID);

            if (template is StatChangeItemTemplate scTemplate &&
                scTemplate.NoCancelMouse)
            {
                return;
            }

            ModifyTemporaryStat(ts => ts.Reset(templateID));
        }
예제 #26
0
        private void OnRegisterServer(InPacket packet)
        {
            var    serverType = (ServerType)packet.Decode <byte>();
            string serverName;

            ServerType = serverType;

            switch (serverType)
            {
            case ServerType.Login:
                var loginInformation = new LoginInformation();

                loginInformation.Decode(packet);
                ServerID   = loginInformation.ID;
                serverName = loginInformation.Name;
                break;

            case ServerType.Game:
                var channelInformation = new ChannelInformation();

                channelInformation.Decode(packet);
                _wvsCenter.WorldInformation.Channels.Add(channelInformation);
                ServerID   = channelInformation.ID;
                serverName = channelInformation.Name;
                break;

            default:
                using (var p = new OutPacket(InteropSendOperations.ServerRegisterResult))
                {
                    p.Encode <bool>(true);
                    SendPacket(p);
                }

                return;
            }

            using (var p = new OutPacket(InteropSendOperations.ServerRegisterResult))
            {
                p.Encode <bool>(false);
                _wvsCenter.WorldInformation.Encode(p);
                SendPacket(p);
            }

            using (var p = new OutPacket(InteropSendOperations.ServerInformation))
            {
                _wvsCenter.WorldInformation.Encode(p);
                _wvsCenter.InteropServer.BroadcastPacket(p, new EveryOneBut(Channel.Id));
            }

            Logger.Info($"Registered {Enum.GetName(typeof(ServerType), serverType)} server, {serverName}");
        }
예제 #27
0
        private void OnMigrateIn(InPacket packet)
        {
            var characterID = packet.Decode <int>();

            if (!WvsGame.PendingMigrations.Remove(characterID))
            {
                Channel.CloseAsync();
                return;
            }

            using (var db = _container.GetInstance <DataContext>())
            {
                var character = db.Characters
                                .Include(c => c.Data)
                                .ThenInclude(a => a.Account)
                                .Include(c => c.FunctionKeys)
                                .Include(c => c.Inventories)
                                .ThenInclude(c => c.Items)
                                .Include(c => c.SkillRecords)
                                .Single(c => c.ID == characterID);

                character.Data.Account.State = AccountState.LoggedIn;
                db.Update(character);
                db.SaveChanges();

                var field     = WvsGame.FieldFactory.Get(character.FieldID);
                var fieldUser = new FieldUser(this, character);

                Random    = new Rand32(0x0, 0x0, 0x0);
                FieldUser = fieldUser;
                field.Enter(fieldUser);

                using (var p = new OutPacket(GameSendOperations.FuncKeyMappedInit))
                {
                    var functionKeys = character.FunctionKeys;

                    p.Encode <bool>(false);
                    for (var i = 0; i < 90; i++)
                    {
                        var functionKey = functionKeys.SingleOrDefault(f => f.Key == i);

                        p.Encode <byte>(functionKey?.Type ?? 0);
                        p.Encode <int>(functionKey?.Action ?? 0);
                    }

                    SendPacket(p);
                }
            }
        }
예제 #28
0
        private void OnNpcMove(InPacket packet)
        {
            using (var p = new OutPacket(GameSendOperations.NpcMove))
            {
                p.Encode <int>(ID);
                p.Encode <byte>(packet.Decode <byte>());
                p.Encode <byte>(packet.Decode <byte>());

                if (Template.Move)
                {
                    var movementPath = new MovementPath();

                    movementPath.Decode(packet);

                    X          = movementPath.X;
                    Y          = movementPath.Y;
                    MoveAction = movementPath.MoveActionLast;
                    Foothold   = movementPath.FHLast;
                    movementPath.Encode(p);
                }

                Field.BroadcastPacket(p);
            }
        }
        private void OnCheckDuplicateID(InPacket packet)
        {
            var name = packet.Decode <string>();

            using (var db = _container.GetInstance <DataContext>())
            {
                var isDuplicatedID = db.Characters.Any(c => c.Name.Equals(name));

                using (var p = new OutPacket(LoginSendOperations.CheckDuplicatedIDResult))
                {
                    p.Encode <string>(name);
                    p.Encode <bool>(isDuplicatedID);

                    SendPacket(p);
                }
            }
        }
예제 #30
0
        public void Decode(InPacket packet)
        {
            ID                = packet.Decode <byte>();
            Name              = packet.Decode <string>();
            State             = packet.Decode <byte>();
            EventDesc         = packet.Decode <string>();
            EventEXP          = packet.Decode <short>();
            EventDrop         = packet.Decode <short>();
            BlockCharCreation = packet.Decode <bool>();

            var channelCount = packet.Decode <byte>();

            for (var i = 0; i < channelCount; i++)
            {
                var channelInformation = new ChannelInformation();

                channelInformation.Decode(packet);
                Channels.Add(channelInformation);
            }
        }