예제 #1
0
        public void ReadFromPacket(IPacketReader reader)
        {
            MobID = reader.ReadInt();

            HitAction = reader.ReadByte();

            var info = reader.ReadByte();

            ForeAction      = (byte)(info & 0x7F);
            IsMobFacingLeft = (info >> 7 & 1) > 0;
            FrameIdx        = reader.ReadByte();

            _ = reader.ReadByte();  // v258 & 0x7F | v25

            _ = reader.ReadShort(); // dAx[5]
            _ = reader.ReadShort(); // dAx[4]
            _ = reader.ReadShort(); // dAx[3]
            _ = reader.ReadShort(); // dAx[2]

            Delay = reader.ReadShort();

            for (var i = 0; i < Damage.Length; i++)
            {
                Damage[i] = reader.ReadInt();
            }

            _ = reader.ReadInt(); // mob crc
        }
예제 #2
0
        public void ReadFromPacket(IPacketReader reader)
        {
            _ = reader.ReadByte(); // FieldKey

            _ = reader.ReadInt();  // dr0
            _ = reader.ReadInt();  // dr1

            var attackInfo = reader.ReadByte();

            DamagePerMob = attackInfo >> 0 & 0xF;
            MobCount     = attackInfo >> 4 & 0xF;

            _ = reader.ReadInt(); // dr2
            _ = reader.ReadInt(); // dr3

            SkillID = reader.ReadInt();
            _       = reader.ReadBool(); // unk

            _ = reader.ReadInt();        // dr rand
            _ = reader.ReadInt();        // crc

            _ = reader.ReadInt();        // skillLevel crc
            _ = reader.ReadInt();        // skillLevel crc

            Keydown = 0;                 // TODO keydownskill check - int keydown

            var skillFlags = reader.ReadByte();

            IsFinalAfterSlashBlast = (skillFlags & 0x0) > 0;
            IsShadowPartner        = (skillFlags & 8) > 0;
            IsSerialAttack         = (skillFlags & 32) > 0;

            var actionInfo = reader.ReadShort();

            Action       = actionInfo & 0x7FFF;
            IsFacingLeft = (actionInfo >> 15 & 1) > 0;

            _ = reader.ReadInt(); // action crc?

            ActionType  = reader.ReadByte();
            ActionSpeed = reader.ReadByte();
            ActionTime  = reader.ReadInt();

            Phase = reader.ReadInt(); // BattleMage?

            for (var i = 0; i < MobCount; i++)
            {
                Mobs.Add(reader.Read(new ClientAttackMobInfo(DamagePerMob)));
            }

            _ = reader.ReadPoint2D(); // unk

            // TODO grenade readpoint2d
        }
예제 #3
0
        public override async Task Handle(LoginStageUser user, IPacketReader packet)
        {
            _ = packet.ReadByte(); // WorldID
            _ = packet.ReadByte(); // Unknown1

            var response = new UnstructuredOutgoingPacket(PacketSendOperations.CheckUserLimitResult);

            response.WriteByte(0); // TODO: bWarningLevel
            response.WriteByte(0); // TODO: bPopulateLevel

            await user.Dispatch(response);
        }
예제 #4
0
        protected override async Task Handle(GameStageUser stageUser, IFieldObjUser user, IPacketReader packet)
        {
            _ = packet.ReadInt();

            var type = (GroupMessageType)packet.ReadByte();

            var recipientCount = packet.ReadByte();
            var recipients     = new int[recipientCount];

            for (var i = 0; i < recipientCount; i++)
            {
                recipients[i] = packet.ReadInt();
            }

            var text = packet.ReadString();

            switch (type)
            {
            case GroupMessageType.Party:
            {
                if (user.Party == null)
                {
                    return;
                }

                var partyChat = new UnstructuredOutgoingPacket(PacketSendOperations.GroupMessage);

                partyChat.WriteByte((byte)GroupMessageType.Party);
                partyChat.WriteString(user.Character.Name);
                partyChat.WriteString(text);

                var dispatchRequest = new DispatchToCharactersRequest {
                    Data = ByteString.CopyFrom(partyChat.Buffer)
                };

                dispatchRequest.Characters.Add(user.Party.Members
                                               .Select(m => m.ID)
                                               .Where(m => m != user.ID)
                                               );

                await stageUser.Stage.DispatchService.DispatchToCharacters(dispatchRequest);

                break;
            }

            default:
                stageUser.Stage.Logger.LogWarning($"Unhandled group message type: {type}");
                break;
            }
        }
예제 #5
0
        public bool GetBit()
        {
            if (Position == 8)
            {
                Buffer   = _packetReader.ReadByte();
                Position = 0;
            }

            int value = Buffer;

            Buffer = (byte)(2 * value);
            Position++;

            return((value >> 7) != 0);
        }
예제 #6
0
        public static byte[] LogonChallenge(IPacketReader packet)
        {
            packet.ReadBytes(32);                            //Skip to username
            BUsername = packet.ReadBytes(packet.ReadByte()); //Read username
            string username = Encoding.ASCII.GetString(BUsername);

            byte[] x;
            using (SHA1 sha = new SHA1CryptoServiceProvider())
            {
                byte[] user = Encoding.ASCII.GetBytes(username.ToUpper() + ":" + Password.ToUpper());
                byte[] res  = Salt.Concat(sha.ComputeHash(user, 0, user.Length)).ToArray();
                x = sha.ComputeHash(res, 0, res.Length).Reverse().ToArray();
            }

            byte[] b = new byte[20];
            new Random().NextBytes(b);
            RB = b.Reverse().ToArray();

            G = new BigInteger(new byte[] { 7 });
            V = G.ModPow(new BigInteger(x), new BigInteger(RN));

            K = new BigInteger(new byte[] { 3 });
            BigInteger temp = (K * V) + G.ModPow(new BigInteger(RB), new BigInteger(RN));

            B = temp % new BigInteger(RN);

            IEnumerable <byte> result = new byte[3]; //Opcode, 0, Success

            result = result.Concat(B.GetBytes(32).Reverse());
            result = result.Concat(new byte[] { 1, 7, 32 }); //1, G, 32
            result = result.Concat(N);
            result = result.Concat(Salt);
            result = result.Concat(new byte[16]); //unknown, Security Flag
            return(result.ToArray());
        }
        protected override async Task Handle(GameStageUser stageUser, IFieldObjUser user, IPacketReader packet)
        {
            _ = packet.ReadInt();
            var type     = (ItemInventoryType)packet.ReadByte();
            var response = new UnstructuredOutgoingPacket(PacketSendOperations.GatherItemResult);

            response.WriteBool(false);
            response.WriteByte((byte)type);

            await user.ModifyInventory(i => i[type].Gather(), true);

            await user.Dispatch(response);
        }
예제 #8
0
        protected override async Task Handle(
            GameStageUser stageUser,
            IFieldObjUser controller,
            IFieldObjNPC controlled,
            IPacketReader packet
            )
        {
            var movement = new UnstructuredOutgoingPacket(PacketSendOperations.NpcMove);

            movement.WriteInt(controlled.ID);
            movement.WriteByte(packet.ReadByte()); // TODO: actions
            movement.WriteByte(packet.ReadByte());

            if (controlled.Info.Move)
            {
                var path = packet.Read(new MovePath());

                movement.Write(path);
                await controlled.Move(path);
            }

            await controlled.FieldSplit.Dispatch(movement);
        }
예제 #9
0
        public void HandleCharCreate(ref IPacketReader packet, ref IWorldManager manager)
        {
            string name = packet.ReadString();

            Character cha = new Character()
            {
                Name       = name.ToUpperFirst(),
                Race       = packet.ReadByte(),
                Class      = packet.ReadByte(),
                Gender     = packet.ReadByte(),
                Skin       = packet.ReadByte(),
                Face       = packet.ReadByte(),
                HairStyle  = packet.ReadByte(),
                HairColor  = packet.ReadByte(),
                FacialHair = packet.ReadByte()
            };

            // HACK neutral panda faction template doesn't work
            if (cha.Race == (byte)Races.PANDAREN_NEUTRAL)
            {
                cha.Race = (byte)Races.PANDAREN_ALLI;
            }

            var          result = manager.Account.Characters.Where(x => x.Build == Sandbox.Instance.Build);
            PacketWriter writer = new PacketWriter(Sandbox.Instance.Opcodes[global::Opcodes.SMSG_CHAR_CREATE], "SMSG_CHAR_CREATE");

            if (result.Any(x => x.Name.Equals(cha.Name, StringComparison.CurrentCultureIgnoreCase)))
            {
                writer.WriteUInt8(0x32); // Duplicate name
                manager.Send(writer);
                return;
            }

            cha.Guid        = (ulong)(manager.Account.Characters.Count + 1);
            cha.Location    = new Location(-8949.95f, -132.493f, 83.5312f, 0, 0);
            cha.RestedState = (byte)new Random().Next(1, 2);
            cha.SetDefaultValues();

            manager.Account.Characters.Add(cha);
            manager.Account.Save();

            // Success
            writer.WriteUInt8(0x2F);
            manager.Send(writer);
        }
예제 #10
0
        protected override async Task Handle(GameStageUser stageUser, IFieldObjUser user, IPacketReader packet)
        {
            _ = packet.ReadInt();
            var type   = (ItemInventoryType)packet.ReadByte();
            var from   = packet.ReadShort();
            var to     = packet.ReadShort();
            var number = packet.ReadShort();

            if (to == 0)
            {
                await user.ModifyInventory(exclRequest : true); // TODO: drops

                return;
            }

            // TODO: checks
            await user.ModifyInventory(i => i[type].Move(from, to), true);
        }
예제 #11
0
        public static byte[] LogonChallenge(IPacketReader packet)
        {
            packet.Position = 11;
            ClientBuild     = packet.ReadUInt16();

            packet.Position = 33;                                  // Skip to username
            BUsername       = packet.ReadBytes(packet.ReadByte()); // Read username
            string username = Encoding.ASCII.GetString(BUsername);

            byte[] x;
            using (SHA1 sha = new SHA1CryptoServiceProvider())
            {
                byte[] user = Encoding.ASCII.GetBytes(username.ToUpper() + ":" + Password.ToUpper());
                byte[] res  = Salt.Concat(sha.ComputeHash(user, 0, user.Length)).ToArray();
                x = sha.ComputeHash(res, 0, res.Length).Reverse().ToArray();
            }

            byte[] b = new byte[20];
            new Random().NextBytes(b);
            RB = b.Reverse().ToArray();

            G = new BigInteger(new byte[] { 7 });
            V = G.ModPow(new BigInteger(x), new BigInteger(RN));

            K = new BigInteger(new byte[] { 3 });
            BigInteger temp = (K * V) + G.ModPow(new BigInteger(RB), new BigInteger(RN));

            B = temp % new BigInteger(RN);

            int size = ClientBuild < 5428 ? 118 : 119;

            byte[] result = new byte[size];
            Array.Copy(B.GetBytes(32).Reverse().ToArray(), 0, result, 3, 32);
            result[35] = 1;
            result[36] = 7;
            result[37] = 32;
            Array.Copy(N, 0, result, 38, N.Length);
            Array.Copy(Salt, 0, result, 70, Salt.Length);
            return(result);
        }
        protected override async Task Handle(
            GameStageUser stageUser,
            IFieldObjUser user,
            IPacketReader packet
            )
        {
            var channelID = packet.ReadByte();

            // TODO checks, error handling

            var gameServerRequest = new DescribeServerByMetadataRequest();

            gameServerRequest.Metadata.Add("Type", Enum.GetName(ServerStageType.Game));
            gameServerRequest.Metadata.Add("WorldID", stageUser.Stage.WorldID.ToString());

            var gameServers = (await stageUser.Stage.ServerRegistry.DescribeByMetadata(gameServerRequest)).Servers
                              .OrderBy(g => g.Metadata["ChannelID"])
                              .ToList();
            var gameServer = gameServers[channelID];

            await stageUser.MigrateTo(gameServer);
        }
예제 #13
0
        protected override async Task Handle(
            GameStageUser stageUser,
            IFieldObjUser user,
            IPacketReader packet
            )
        {
            _ = packet.ReadLong();
            _ = packet.ReadByte();
            _ = packet.ReadLong();
            _ = packet.ReadInt();
            _ = packet.ReadInt();
            _ = packet.ReadInt();

            var path     = packet.Read(new MovePath());
            var movement = new UnstructuredOutgoingPacket(PacketSendOperations.UserMove);

            movement.WriteInt(user.ID);
            movement.Write(path);

            await user.Move(path);

            await user.FieldSplit.Dispatch(user, movement);
        }
예제 #14
0
        protected override Task Handle(GameStageUser stageUser, IFieldObjUser user, IPacketReader packet)
        {
            var v3 = packet.ReadInt();

            if (v3 > 0)
            {
                return(Task.CompletedTask);
            }
            var count = packet.ReadInt();

            for (var i = 0; i < count; i++)
            {
                var key = packet.ReadInt();

                user.Character.FunctionKeys[key] = new CharacterFunctionKey
                {
                    Type   = packet.ReadByte(),
                    Action = packet.ReadInt()
                };
            }

            return(Task.CompletedTask);
        }
예제 #15
0
        public static byte[] LogonChallenge(IPacketReader packet)
        {
            packet.Position = 11;
            ClientBuild     = packet.ReadUInt16();

            packet.Position = 33;                                  // Skip to username
            BUsername       = packet.ReadBytes(packet.ReadByte()); // Read username

            byte[] credshash;
            using (SHA1 sha = new SHA1CryptoServiceProvider())
            {
                string username    = Encoding.ASCII.GetString(BUsername);
                byte[] credentials = Encoding.ASCII.GetBytes(username.ToUpper() + ":" + Password.ToUpper());
                byte[] tmp         = Salt.Concat(sha.ComputeHash(credentials)).ToArray();
                credshash = sha.ComputeHash(tmp).Reverse().ToArray();
            }

            RB = new byte[20];
            new Random().NextBytes(RB);

            G = new BigInteger(new byte[] { 7 });
            V = G.ModPow(new BigInteger(credshash), new BigInteger(RN));

            K = new BigInteger(new byte[] { 3 });
            B = ((K * V) + G.ModPow(new BigInteger(RB), new BigInteger(RN))) % new BigInteger(RN);

            // create packet data
            byte[] result = new byte[GetLogonChallengeSize()];
            Array.Copy(B.GetBytes(32).Reverse().ToArray(), 0, result, 3, 32);
            result[35] = 1;
            result[36] = 7;
            result[37] = 32;
            Array.Copy(N, 0, result, 38, N.Length);
            Array.Copy(Salt, 0, result, 70, Salt.Length);
            return(result);
        }
예제 #16
0
        public void ReadFromPacket(IPacketReader reader)
        {
            _position  = reader.ReadPoint2D();
            _vPosition = reader.ReadPoint2D();

            var size = reader.ReadByte();

            for (var i = 0; i < size; i++)
            {
                var attribute = (MoveFragmentAttribute)reader.ReadByte();

                switch (attribute)
                {
                case MoveFragmentAttribute.Normal:
                case MoveFragmentAttribute.HangOnBack:
                case MoveFragmentAttribute.FallDown:
                case MoveFragmentAttribute.Wings:
                case MoveFragmentAttribute.MobAttackRush:
                case MoveFragmentAttribute.MobAttackRushStop:
                    _fragments.Add(new NormalMoveFragment(attribute, reader));
                    break;

                case MoveFragmentAttribute.Jump:
                case MoveFragmentAttribute.Impact:
                case MoveFragmentAttribute.StartWings:
                case MoveFragmentAttribute.MobToss:
                case MoveFragmentAttribute.DashSlide:
                case MoveFragmentAttribute.MobLadder:
                case MoveFragmentAttribute.MobRightAngle:
                case MoveFragmentAttribute.MobStopNodeStart:
                case MoveFragmentAttribute.MobBeforeNode:
                    _fragments.Add(new JumpMoveFragment(attribute, reader));
                    break;

                case MoveFragmentAttribute.FlashJump:
                case MoveFragmentAttribute.RocketBooster:
                case MoveFragmentAttribute.BackStepShot:
                case MoveFragmentAttribute.MobPowerKnockBack:
                case MoveFragmentAttribute.VerticalJump:
                case MoveFragmentAttribute.CustomImpact:
                case MoveFragmentAttribute.CombatStep:
                case MoveFragmentAttribute.Hit:
                case MoveFragmentAttribute.TimeBombAttack:
                case MoveFragmentAttribute.SnowballTouch:
                case MoveFragmentAttribute.BuffZoneEffect:
                    _fragments.Add(new ActionMoveFragment(attribute, reader));
                    break;

                case MoveFragmentAttribute.Immediate:
                case MoveFragmentAttribute.Teleport:
                case MoveFragmentAttribute.Assaulter:
                case MoveFragmentAttribute.Assassination:
                case MoveFragmentAttribute.Rush:
                case MoveFragmentAttribute.SitDown:
                    _fragments.Add(new TeleportMoveFragment(attribute, reader));
                    break;

                case MoveFragmentAttribute.StartFallDown:
                    _fragments.Add(new StartFallDownMoveFragment(attribute, reader));
                    break;

                case MoveFragmentAttribute.FlyingBlock:
                    _fragments.Add(new FlyingBlockMoveFragment(attribute, reader));
                    break;

                case MoveFragmentAttribute.StatChange:
                    _fragments.Add(new StatChangeMoveFragment(attribute, reader));
                    break;
                }
            }

            _fragments.ForEach(f => f.Apply(this));
        }
예제 #17
0
 protected override void ReadData(IPacketReader reader)
 {
     _moveAction = (MoveActionType)reader.ReadByte();
     _elapse     = reader.ReadShort();
 }
예제 #18
0
        protected override async Task Handle(
            GameStageUser stageUser,
            IFieldObjUser controller,
            IFieldObjMob controlled,
            IPacketReader packet
            )
        {
            if (controlled.HP <= 0)
            {
                return;
            }

            var mobCtrlSN = packet.ReadShort();
            var v7        = packet.ReadByte();         //v85 = nDistance | 4 * (v184 | 2 * ((unsigned __int8)retaddr | 2 * v72)); [ CONFIRMED ]

            var oldSplit           = (v7 & 0xF0) != 0; //this is a type of CFieldSplit
            var mobMoveStartResult = (v7 & 0xF) != 0;

            var curSplit        = packet.ReadByte();
            var illegalVelocity = packet.ReadInt();
            var v8 = packet.ReadByte();

            var cheatedRandom   = (v8 & 0xF0) != 0;
            var cheatedCtrlMove = (v8 & 0xF) != 0;

            var multiTargetForBall = packet.ReadInt();

            for (var i = 0; i < multiTargetForBall; i++)
            {
                packet.ReadLong();                                          // int, int
            }
            var randTimeForAreaAttack = packet.ReadInt();

            for (var i = 0; i < randTimeForAreaAttack; i++)
            {
                packet.ReadInt();
            }

            packet.ReadInt(); // HackedCode
            packet.ReadInt(); // idk
            packet.ReadInt(); // HackedCodeCrc
            packet.ReadInt(); // idk

            var path = packet.Read(new MovePath());

            await controlled.Move(path);

            var response = new UnstructuredOutgoingPacket(PacketSendOperations.MobCtrlAck);

            response.WriteInt(controlled.ID);
            response.WriteShort(mobCtrlSN);
            response.WriteBool(mobMoveStartResult);
            response.WriteShort((short)controlled.MP); // nMP
            response.WriteByte(0);                     // SkillCommand
            response.WriteByte(0);                     // SLV

            await controller.Dispatch(response);

            var movement = new UnstructuredOutgoingPacket(PacketSendOperations.MobMove);

            movement.WriteInt(controlled.ID);
            movement.WriteBool(false); // NotForceLandingWhenDiscard
            movement.WriteBool(false); // NotChangeAction
            movement.WriteBool(false); // NextAttackPossible
            movement.WriteBool(false); // Left
            movement.WriteInt(illegalVelocity);

            movement.WriteInt(0); // MultiTargetForBall
            movement.WriteInt(0); // RandTimeForAreaAttack

            movement.Write(path);

            await controlled.Field.Dispatch(controller, movement);
        }
예제 #19
0
        protected override async Task Handle(GameStageUser stageUser, IFieldObjUser user, IPacketReader packet)
        {
            var stage = stageUser.Stage;
            var flag  = (WhisperFlags)packet.ReadByte();

            switch (flag)
            {
            case WhisperFlags.Whisper | WhisperFlags.Request:
            {
                _ = packet.ReadInt();
                var name = packet.ReadString();
                var text = packet.ReadString();

                if (name.Equals(user.Character.Name, StringComparison.CurrentCultureIgnoreCase))
                {
                    return;
                }

                var allowed = false;
                var target  = await stage.CharacterRepository.RetrieveByName(name);

                var response = new UnstructuredOutgoingPacket(PacketSendOperations.Whisper);

                if (target != null)
                {
                    var sessionRequest = new DescribeSessionByCharacterRequest {
                        Character = target.ID
                    };
                    var sessionResponse = await stage.SessionRegistry.DescribeByCharacter(sessionRequest);

                    if (sessionResponse.Session.State == SessionState.LoggedIn)
                    {
                        allowed = true;
                    }
                }

                response.WriteByte((byte)(WhisperFlags.Whisper | WhisperFlags.Result));
                response.WriteString(allowed ? target.Name : name);
                response.WriteBool(allowed);

                if (allowed)
                {
                    var whisper = new UnstructuredOutgoingPacket(PacketSendOperations.Whisper)
                                  .WriteByte((byte)(WhisperFlags.Whisper | WhisperFlags.Receive))
                                  .WriteString(user.Character.Name)
                                  .WriteByte((byte)stage.ChannelID)
                                  .WriteBool(false) // bFromAdmin
                                  .WriteString(text);
                    var whisperRequest = new DispatchToCharactersRequest {
                        Data = ByteString.CopyFrom(whisper.Buffer)
                    };

                    whisperRequest.Characters.Add(target.ID);

                    await stage.DispatchService.DispatchToCharacters(whisperRequest);
                }

                await user.Dispatch(response);

                break;
            }

            default:
                stage.Logger.LogWarning($"Unhandled whisper flag: {flag}");
                break;
            }
        }
예제 #20
0
        public override async Task Handle(LoginStageUser user, IPacketReader packet)
        {
            var name      = packet.ReadString();
            var race      = packet.ReadInt();
            var subJob    = packet.ReadShort();
            var face      = packet.ReadInt();
            var hair      = packet.ReadInt();
            var hairColor = packet.ReadInt();
            var skin      = packet.ReadInt();
            var coat      = packet.ReadInt();
            var pants     = packet.ReadInt();
            var shoes     = packet.ReadInt();
            var weapon    = packet.ReadInt();
            var gender    = packet.ReadByte();

            var result   = LoginResultCode.Success;
            var response = new UnstructuredOutgoingPacket(PacketSendOperations.CreateNewCharacterResult);

            var world = await user.Stage.WorldTemplates.Retrieve((int)user.SelectedWorldID);

            if (world.BlockCharCreation)
            {
                result = LoginResultCode.NotConnectableWorld;
            }

            var serverRequest = new DescribeServerByMetadataRequest();

            serverRequest.Metadata.Add("Type", Enum.GetName(ServerStageType.Game));
            serverRequest.Metadata.Add("WorldID", user.SelectedWorldID.ToString());
            serverRequest.Metadata.Add("ChannelID", user.SelectedChannelID.ToString());

            var server = (await user.Stage.ServerRegistry.DescribeByMetadata(serverRequest)).Servers.FirstOrDefault();

            if (server == null)
            {
                result = LoginResultCode.NotConnectableWorld;
            }

            response.WriteByte((byte)result);

            if (result == LoginResultCode.Success)
            {
                var character = new Character
                {
                    AccountWorldID = user.AccountWorld.ID,
                    Name           = name,
                    Job            = 0, // TODO: race -> job
                    Face           = face,
                    Hair           = hair + hairColor,
                    Skin           = (byte)skin,
                    Gender         = gender,
                    FieldID        = 310000000, // TODO: start maps
                    FieldPortal    = 0,
                    SubJob         = 0          // TODO: race -> subjob
                };
                var context = new ModifyMultiInventoryContext(character.Inventories, user.Stage.ItemTemplates);

                context.Set(BodyPart.Clothes, coat);
                context.Set(BodyPart.Shoes, shoes);
                context.Set(BodyPart.Weapon, weapon);
                if (pants > 0)
                {
                    context.Set(BodyPart.Pants, pants);
                }

                await user.Stage.CharacterRepository.Insert(character);

                user.Character = character;
                user.Stage.Logger.LogDebug($"Created new {race} character: {name} (ID: {character.ID})");

                response.WriteCharacterStats(character);
                response.WriteCharacterLook(character);
                response.WriteBool(false);
                response.WriteBool(false);
            }
            else
            {
                response.WriteInt(0);
            }

            await user.Dispatch(response);
        }
예제 #21
0
        protected override async Task Handle(GameStageUser stageUser, IFieldObjUser user, IPacketReader packet)
        {
            var type = (ConversationRequestType)packet.ReadByte();

            if (!user.IsConversing)
            {
                return;
            }

            var context = user.CurrentConversation.Context;

            if (type == ConversationRequestType.AskQuiz ||
                type == ConversationRequestType.AskSpeedQuiz)
            {
                await context.Respond(
                    new ConversationResponse <string>(type, packet.ReadString())
                    );

                return;
            }

            var answer = packet.ReadByte();

            if (
                type != ConversationRequestType.Say &&
                type != ConversationRequestType.AskYesNo &&
                type != ConversationRequestType.AskAccept &&
                answer == byte.MinValue ||
                (type == ConversationRequestType.Say ||
                 type == ConversationRequestType.AskYesNo ||
                 type == ConversationRequestType.AskAccept) && answer == byte.MaxValue
                )
            {
                await user.EndConversation();

                return;
            }

            switch (type)
            {
            case ConversationRequestType.AskText:
            case ConversationRequestType.AskBoxText:
                await context.Respond(
                    new ConversationResponse <string>(type, packet.ReadString())
                    );

                break;

            case ConversationRequestType.AskNumber:
            case ConversationRequestType.AskMenu:
            case ConversationRequestType.AskSlideMenu:
                await context.Respond(
                    new ConversationResponse <int>(type, packet.ReadInt())
                    );

                break;

            case ConversationRequestType.AskAvatar:
            case ConversationRequestType.AskMemberShopAvatar:
                await context.Respond(
                    new ConversationResponse <byte>(type, packet.ReadByte())
                    );

                break;

            case ConversationRequestType.AskYesNo:
            case ConversationRequestType.AskAccept:
                await context.Respond(
                    new ConversationResponse <bool>(type, Convert.ToBoolean(answer))
                    );

                break;

            default:
                await context.Respond(
                    new ConversationResponse <byte>(type, answer)
                    );

                break;
            }
        }
예제 #22
0
        protected override async Task Handle(GameStageUser stageUser, IFieldObjUser user, IPacketReader packet)
        {
            var stage   = stageUser.Stage;
            var service = stage.PartyService;
            var type    = (PartyRequestCode)packet.ReadByte();

            switch (type)
            {
            case PartyRequestCode.CreateNewParty:
            {
                if (user.Party != null)
                {
                    return;
                }

                var result   = PartyResultCode.CreateNewParty_Done;
                var response = new UnstructuredOutgoingPacket(PacketSendOperations.PartyResult);
                var contract = new PartyCreateRequest
                {
                    Member = new PartyMemberContract
                    {
                        Id      = user.ID,
                        Name    = user.Character.Name,
                        Job     = user.Character.Job,
                        Level   = user.Character.Level,
                        Channel = stage.ChannelID,
                        Field   = user.Field.ID
                    }
                };
                var serviceResponse = await service.Create(contract);

                var serviceResult = serviceResponse.Result;

                if (serviceResult == PartyServiceResult.FailedAlreadyInParty)
                {
                    result = PartyResultCode.CreateNewParty_AlreadyJoined;
                }
                else if (serviceResult != PartyServiceResult.Ok)
                {
                    result = PartyResultCode.CreateNewParty_Unknown;
                }

                response.WriteByte((byte)result);

                if (result == PartyResultCode.CreateNewParty_Done)
                {
                    response.WriteInt(serviceResponse.Party.Id);
                    response.WriteInt(0);                     // TownPortal-TownID
                    response.WriteInt(0);                     // TownPortal-FieldID
                    response.WriteInt(0);                     // TownPortal-SkillID
                    response.WritePoint2D(new Point2D(0, 0)); //TownPortal-Position
                }

                await user.Dispatch(response);

                break;
            }

            case PartyRequestCode.WithdrawParty:
            {
                if (user.Party == null)
                {
                    return;
                }

                var result   = PartyResultCode.WithdrawParty_Done;
                var response = new UnstructuredOutgoingPacket(PacketSendOperations.PartyResult);
                var contract = new PartyWithdrawRequest {
                    Character = user.ID, IsKick = false
                };
                var serviceResponse = await service.Withdraw(contract);

                var serviceResult = serviceResponse.Result;

                if (serviceResult == PartyServiceResult.FailedNotInParty)
                {
                    result = PartyResultCode.WithdrawParty_NotJoined;
                }
                else if (serviceResult != PartyServiceResult.Ok)
                {
                    result = PartyResultCode.WithdrawParty_Unknown;
                }

                response.WriteByte((byte)result);

                if (result == PartyResultCode.WithdrawParty_Done)
                {
                    return;
                }

                await user.Dispatch(response);

                break;
            }

            case PartyRequestCode.InviteParty:
            {
                if (user.Party == null)
                {
                    var contract = new PartyCreateRequest
                    {
                        Member = new PartyMemberContract
                        {
                            Id      = user.ID,
                            Name    = user.Character.Name,
                            Job     = user.Character.Job,
                            Level   = user.Character.Level,
                            Channel = stage.ChannelID,
                            Field   = user.Field.ID
                        }
                    };
                    var serviceResponse = await service.Create(contract);

                    var serviceResult = serviceResponse.Result;

                    if (serviceResult != PartyServiceResult.Ok)
                    {
                        return;
                    }

                    var createResponse = new UnstructuredOutgoingPacket(PacketSendOperations.PartyResult);

                    createResponse.WriteByte((byte)PartyResultCode.CreateNewParty_Done);
                    createResponse.WriteInt(serviceResponse.Party.Id);
                    createResponse.WriteInt(0);                     // TownPortal-TownID
                    createResponse.WriteInt(0);                     // TownPortal-FieldID
                    createResponse.WriteInt(0);                     // TownPortal-SkillID
                    createResponse.WritePoint2D(new Point2D(0, 0)); //TownPortal-Position

                    await user.Dispatch(createResponse);
                }

                if (user?.Party?.Boss != user.ID)
                {
                    return;
                }

                var name      = packet.ReadString();
                var result    = PartyResultCode.InviteParty_Sent;
                var response  = new UnstructuredOutgoingPacket(PacketSendOperations.PartyResult);
                var character = await stage.CharacterRepository.RetrieveByName(name);

                if (character == null || user.Character.ID == character.ID)
                {
                    result = PartyResultCode.InviteParty_BlockedUser;
                }
                if ((await service.LoadByCharacter(new PartyLoadByCharacterRequest {
                        Character = character.ID
                    })).Party != null)
                {
                    result = PartyResultCode.JoinParty_AlreadyJoined;
                }
                else
                {
                    var serviceResponse = await stage.InviteService.Register(new InviteRegisterRequest
                        {
                            Invite = new InviteContract
                            {
                                Type    = InviteType.Party,
                                Invited = character.ID,
                                Inviter = user.ID
                            }
                        });

                    if (serviceResponse.Result != InviteServiceResult.Ok)
                    {
                        result = PartyResultCode.InviteParty_AlreadyInvited;
                    }
                }

                response.WriteByte((byte)result);

                if (result == PartyResultCode.InviteParty_Sent)
                {
                    var invitation        = new UnstructuredOutgoingPacket(PacketSendOperations.PartyResult);
                    var invitationRequest = new DispatchToCharactersRequest();

                    invitation.WriteByte((byte)PartyRequestCode.InviteParty);
                    invitation.WriteInt(user.Character.ID);
                    invitation.WriteString(user.Character.Name);
                    invitation.WriteInt(user.Character.Level);
                    invitation.WriteInt(user.Character.Job);
                    invitation.WriteByte(0);         // PartyOpt

                    invitationRequest.Data = ByteString.CopyFrom(invitation.Buffer);
                    invitationRequest.Characters.Add(character.ID);

                    await stage.DispatchService.DispatchToCharacters(invitationRequest);

                    response.WriteString(character.Name);
                }

                await user.Dispatch(response);

                break;
            }

            case PartyRequestCode.KickParty:
            {
                if (user.Party == null)
                {
                    return;
                }
                if (user.Party.Boss != user.ID)
                {
                    return;
                }

                var id = packet.ReadInt();

                if (!user.Party.Members.Any(m => m.ID == id))
                {
                    return;
                }
                if (id == user.ID)
                {
                    return;
                }

                var result   = PartyResultCode.WithdrawParty_Done;
                var response = new UnstructuredOutgoingPacket(PacketSendOperations.PartyResult);
                var contract = new PartyWithdrawRequest {
                    Character = id, IsKick = true
                };
                var serviceResponse = await service.Withdraw(contract);

                var serviceResult = serviceResponse.Result;

                if (serviceResult == PartyServiceResult.FailedNotInParty)
                {
                    result = PartyResultCode.WithdrawParty_NotJoined;
                }
                else if (serviceResult != PartyServiceResult.Ok)
                {
                    result = PartyResultCode.WithdrawParty_Unknown;
                }

                response.WriteByte((byte)result);

                if (result == PartyResultCode.WithdrawParty_Done)
                {
                    return;
                }

                await user.Dispatch(response);

                break;
            }

            case PartyRequestCode.ChangePartyBoss:
            {
                if (user.Party == null || user.Party.Boss != user.ID)
                {
                    return;
                }

                var id = packet.ReadInt();

                if (!user.Party.Members.Any(m => m.ID == id))
                {
                    return;
                }
                if (id == user.ID)
                {
                    return;
                }

                var result   = PartyResultCode.ChangePartyBoss_Done;
                var response = new UnstructuredOutgoingPacket(PacketSendOperations.PartyResult);
                var contract = new PartyChangeBossRequest {
                    Character = id
                };
                var serviceResponse = await service.ChangeBoss(contract);

                var serviceResult = serviceResponse.Result;

                if (serviceResult != PartyServiceResult.Ok)
                {
                    result = PartyResultCode.WithdrawParty_Unknown;
                }

                response.WriteByte((byte)result);

                if (result == PartyResultCode.ChangePartyBoss_Done)
                {
                    return;
                }

                await user.Dispatch(response);

                break;
            }

            default:
                stage.Logger.LogWarning($"Unhandled party request type: {type}");
                break;
            }
        }
예제 #23
0
        protected override async Task Handle(GameStageUser stageUser, IFieldObjUser user, IPacketReader packet)
        {
            var stage   = stageUser.Stage;
            var service = stage.PartyService;
            var type    = (PartyResultCode)packet.ReadByte();

            switch (type)
            {
            case PartyResultCode.InviteParty_Sent:
            case PartyResultCode.InviteParty_AlreadyInvited:
            case PartyResultCode.InviteParty_AlreadyInvitedByInviter:
                break;     // Do nothing

            case PartyResultCode.InviteParty_Accepted:
            {
                var serviceRequest = new InviteClaimRequest {
                    Type = InviteType.Party, Invited = user.ID
                };
                var serviceResponse = await stage.InviteService.Claim(serviceRequest);

                if (serviceResponse.Result == InviteServiceResult.Ok)
                {
                    var result   = PartyResultCode.JoinParty_Done;
                    var response = new UnstructuredOutgoingPacket(PacketSendOperations.PartyResult);
                    var party    = stage.GetUser(serviceResponse.Invite.Inviter)?.FieldUser?.Party?.ID;

                    if (party == null)
                    {
                        result = PartyResultCode.JoinParty_UnknownUser;
                    }
                    else
                    {
                        var joinRequest = new PartyJoinRequest
                        {
                            Party  = party.Value,
                            Member = new PartyMemberContract
                            {
                                Id      = user.ID,
                                Name    = user.Character.Name,
                                Job     = user.Character.Job,
                                Level   = user.Character.Level,
                                Channel = stage.ChannelID,
                                Field   = user.Field.ID
                            }
                        };
                        var joinResponse = await service.Join(joinRequest);

                        if (joinResponse.Result == PartyServiceResult.Ok)
                        {
                            return;
                        }
                        if (joinResponse.Result == PartyServiceResult.FailedAlreadyInParty)
                        {
                            result = PartyResultCode.JoinParty_AlreadyJoined;
                        }
                        if (joinResponse.Result == PartyServiceResult.FailedFullParty)
                        {
                            result = PartyResultCode.JoinParty_AlreadyFull;
                        }
                    }

                    response.WriteByte((byte)result);

                    await user.Dispatch(response);
                }
                break;
            }

            case PartyResultCode.InviteParty_Rejected:
            {
                if (user.Party != null)
                {
                    return;
                }

                var serviceRequest = new InviteClaimRequest {
                    Type = InviteType.Party, Invited = user.ID
                };
                var serviceResponse = await stage.InviteService.Claim(serviceRequest);

                if (serviceResponse.Result == InviteServiceResult.Ok)
                {
                    var inviter  = serviceResponse.Invite.Inviter;
                    var dispatch = new UnstructuredOutgoingPacket(PacketSendOperations.PartyResult)
                                   .WriteByte((byte)PartyResultCode.ServerMsg)
                                   .WriteBool(true)
                                   .WriteString($"'{user.Character.Name}' rejected the party invitation request.");
                    var dispatchRequest = new DispatchToCharactersRequest {
                        Data = ByteString.CopyFrom(dispatch.Buffer)
                    };

                    dispatchRequest.Characters.Add(inviter);

                    await stage.DispatchService.DispatchToCharacters(dispatchRequest);
                }
                break;
            }

            default:
                stage.Logger.LogWarning($"Unhandled party result type: {type}");
                break;
            }
        }
예제 #24
0
        public override async Task Handle(LoginStageUser user, IPacketReader packet)
        {
            _ = packet.ReadByte(); // Unknown1

            var worldID   = packet.ReadByte();
            var channelID = packet.ReadByte();

            var result   = LoginResultCode.Success;
            var response = new UnstructuredOutgoingPacket(PacketSendOperations.SelectWorldResult);

            var gameServerRequest = new DescribeServerByMetadataRequest();

            gameServerRequest.Metadata.Add("Type", Enum.GetName(ServerStageType.Game));
            gameServerRequest.Metadata.Add("WorldID", worldID.ToString());

            var gameServers = (await user.Stage.ServerRegistry.DescribeByMetadata(gameServerRequest)).Servers
                              .OrderBy(g => g.Metadata["ChannelID"])
                              .ToList();

            if (channelID > gameServers.Count)
            {
                result = LoginResultCode.NotConnectableWorld;
            }

            response.WriteByte((byte)result);

            if (result == LoginResultCode.Success)
            {
                var gameServer   = gameServers[channelID];
                var accountWorld = await user.Stage.AccountWorldRepository.RetrieveByAccountAndWorld(user.Account.ID, worldID);

                if (accountWorld == null)
                {
                    accountWorld = new AccountWorld
                    {
                        AccountID = user.Account.ID,
                        WorldID   = worldID
                    };

                    await user.Stage.AccountWorldRepository.Insert(accountWorld);
                }

                user.State             = LoginState.SelectCharacter;
                user.AccountWorld      = accountWorld;
                user.SelectedWorldID   = Convert.ToByte(gameServer.Metadata["WorldID"]);
                user.SelectedChannelID = Convert.ToByte(gameServer.Metadata["ChannelID"]);

                var characters = (await user.Stage.CharacterRepository.RetrieveAllByAccountWorld(accountWorld.ID)).ToList();

                response.WriteByte((byte)characters.Count);
                characters.ForEach(c =>
                {
                    response.WriteCharacterStats(c);
                    response.WriteCharacterLook(c);

                    response.WriteBool(false);
                    response.WriteBool(false);
                });

                response.WriteBool(!string.IsNullOrEmpty(user.Account.SPW)); // bLoginOpt TODO: proper bLoginOpt stuff
                response.WriteInt(accountWorld.SlotCount);
                response.WriteInt(0);
            }

            await user.Dispatch(response);
        }