示例#1
0
        public static async void CharacterDelete(ClientPacketFragment fragment, Session session)
        {
            string account       = fragment.Payload.ReadString16L();
            uint   characterSlot = fragment.Payload.ReadUInt32();

            if (account != session.Account)
            {
                session.SendCharacterError(CharacterError.Delete);
                return;
            }

            var cachedCharacter = session.CachedCharacters.SingleOrDefault(c => c.SlotId == characterSlot);

            if (cachedCharacter == null)
            {
                session.SendCharacterError(CharacterError.Delete);
                return;
            }

            // TODO: check if character is already pending removal

            session.LoginSession.EnqueueSend(new GameMessageCharacterDelete());

            DatabaseManager.Character.DeleteOrRestore(Time.GetUnixTime() + 3600ul, cachedCharacter.Guid.Low);

            var result = await DatabaseManager.Character.GetByAccount(session.Id);

            session.UpdateCachedCharacters(result);
            session.WorldSession.EnqueueSend(new GameMessageCharacterList(result, session.Account));
        }
示例#2
0
        public static void CharacterEnterWorld(ClientPacketFragment fragment, Session session)
        {
            ObjectGuid guid    = fragment.Payload.ReadGuid();
            string     account = fragment.Payload.ReadString16L();

            if (account != session.Account)
            {
                session.SendCharacterError(CharacterError.EnterGameCharacterNotOwned);
                return;
            }

            var cachedCharacter = session.CachedCharacters.SingleOrDefault(c => c.Guid.Full == guid.Full);

            if (cachedCharacter == null)
            {
                session.SendCharacterError(CharacterError.EnterGameCharacterNotOwned);
                return;
            }

            session.CharacterRequested = cachedCharacter;

            // this isn't really that necessary since ACE doesn't split login/world to multiple daemons, handle it anyway
            byte[] connectionKey = new byte[sizeof(ulong)];
            RandomNumberGenerator.Create().GetNonZeroBytes(connectionKey);
            session.WorldConnectionKey = BitConverter.ToUInt64(connectionKey, 0);

            string[] sessionIPAddress = session.EndPoint.Address.ToString().Split('.');

            session.LoginSession.EnqueueSend(new PacketOutboundReferral(session.WorldConnectionKey, sessionIPAddress));

            session.State = SessionState.WorldLoginRequest;
        }
示例#3
0
        public static async void CharacterDelete(ClientPacketFragment fragment, Session session)
        {
            string account       = fragment.Payload.ReadString16L();
            uint   characterSlot = fragment.Payload.ReadUInt32();

            if (account != session.Account)
            {
                session.SendCharacterError(CharacterError.Delete);
                return;
            }

            var cachedCharacter = session.CachedCharacters.SingleOrDefault(c => c.SlotId == characterSlot);

            if (cachedCharacter == null)
            {
                session.SendCharacterError(CharacterError.Delete);
                return;
            }

            // TODO: check if character is already pending removal

            var characterDelete         = new ServerPacket(0x0B, PacketHeaderFlags.EncryptedChecksum);
            var characterDeleteFragment = new ServerPacketFragment(9, GameMessageOpcode.CharacterDelete);

            characterDelete.Fragments.Add(characterDeleteFragment);

            NetworkManager.SendPacket(ConnectionType.Login, characterDelete, session);

            DatabaseManager.Character.DeleteOrRestore(Time.GetUnixTime() + 3600ul, cachedCharacter.Guid.Low);

            var result = await DatabaseManager.Character.GetByAccount(session.Id);

            AuthenticationHandler.CharacterListSelectCallback(result, session);
        }
示例#4
0
        public static void HandleGameAction(ClientPacketFragment fragement, Session session)
        {
            uint sequence = fragement.Payload.ReadUInt32();
            uint opcode   = fragement.Payload.ReadUInt32();

            PacketManager.HandleGameAction((GameActionOpcode)opcode, fragement, session);
        }
示例#5
0
        public static void CharacterRestore(ClientPacketFragment fragment, Session session)
        {
            ObjectGuid guid = fragment.Payload.ReadGuid();

            var cachedCharacter = session.CachedCharacters.SingleOrDefault(c => c.Guid.Full == guid.Full);

            if (cachedCharacter == null)
            {
                return;
            }

            bool isAvailable = DatabaseManager.Character.IsNameAvailable(cachedCharacter.Name);

            if (!isAvailable)
            {
                SendCharacterCreateResponse(session, CharacterGenerationVerificationResponse.NameInUse);    /* Name already in use. */
                return;
            }
            DatabaseManager.Character.DeleteOrRestore(0, guid.Low);

            var characterRestore         = new ServerPacket(0x0B, PacketHeaderFlags.EncryptedChecksum);
            var characterRestoreFragment = new ServerPacketFragment(9, GameMessageOpcode.CharacterRestoreResponse);

            characterRestoreFragment.Payload.Write(1u /* Verification OK flag */);
            characterRestoreFragment.Payload.WriteGuid(guid);
            characterRestoreFragment.Payload.WriteString16L(cachedCharacter.Name);
            characterRestoreFragment.Payload.Write(0u /* secondsGreyedOut */);
            characterRestore.Fragments.Add(characterRestoreFragment);

            NetworkManager.SendPacket(ConnectionType.Login, characterRestore, session);
        }
示例#6
0
        public static Appearance FromFragment(ClientPacketFragment fragment)
        {
            Appearance appearance = new Appearance()
            {
                Eyes          = fragment.Payload.ReadUInt32(),
                Nose          = fragment.Payload.ReadUInt32(),
                Mouth         = fragment.Payload.ReadUInt32(),
                HairColor     = fragment.Payload.ReadUInt32(),
                EyeColor      = fragment.Payload.ReadUInt32(),
                HairStyle     = fragment.Payload.ReadUInt32(),
                HeadgearStyle = fragment.Payload.ReadUInt32(),
                HeadgearColor = fragment.Payload.ReadUInt32(),
                ShirtStyle    = fragment.Payload.ReadUInt32(),
                ShirtColor    = fragment.Payload.ReadUInt32(),
                PantsStyle    = fragment.Payload.ReadUInt32(),
                PantsColor    = fragment.Payload.ReadUInt32(),
                FootwearStyle = fragment.Payload.ReadUInt32(),
                FootwearColor = fragment.Payload.ReadUInt32(),
                SkinHue       = fragment.Payload.ReadDouble(),
                HairHue       = fragment.Payload.ReadDouble(),
                HeadgearHue   = fragment.Payload.ReadDouble(),
                ShirtHue      = fragment.Payload.ReadDouble(),
                PantsHue      = fragment.Payload.ReadDouble(),
                FootwearHue   = fragment.Payload.ReadDouble()
            };

            return(appearance);
        }
        public static void CharacterEnterWorld(ClientPacketFragment fragment, Session session)
        {
            ObjectGuid guid    = fragment.Payload.ReadGuid();
            string     account = fragment.Payload.ReadString16L();

            if (account != session.Account)
            {
                session.SendCharacterError(CharacterError.EnterGameCharacterNotOwned);
                return;
            }

            var cachedCharacter = session.AccountCharacters.SingleOrDefault(c => c.Guid.Full == guid.Full);

            if (cachedCharacter == null)
            {
                session.SendCharacterError(CharacterError.EnterGameCharacterNotOwned);
                return;
            }

            session.CharacterRequested = cachedCharacter;

            session.InitSessionForWorldLogin();

            session.State = SessionState.WorldConnected;

            // check the value of the welcome message. Only display it if it is not empty
            if (!String.IsNullOrEmpty(ConfigManager.Config.Server.Welcome))
            {
                session.Network.EnqueueSend(new GameEventPopupString(session, ConfigManager.Config.Server.Welcome));
            }

            LandblockManager.PlayerEnterWorld(session);
        }
示例#8
0
        public static void CharacterEnterWorldRequest(ClientPacketFragment fragment, Session session)
        {
            var characterEnterWorldServerReady = new ServerPacket(0x0B, PacketHeaderFlags.EncryptedChecksum);

            characterEnterWorldServerReady.Fragments.Add(new ServerPacketFragment(9, GameMessageOpcode.CharacterEnterWorldServerReady));

            NetworkManager.SendPacket(ConnectionType.Login, characterEnterWorldServerReady, session);
        }
示例#9
0
        public static void HandleGameAction(ClientPacketFragment fragement, Session session)
        {
            // TODO: verify sequence
            uint sequence = fragement.Payload.ReadUInt32();
            uint opcode   = fragement.Payload.ReadUInt32();

            InboundMessageManager.HandleGameAction((GameActionType)opcode, fragement, session);
        }
示例#10
0
        public static void TurbineChatReceived(ClientPacketFragment fragment, Session session)
        {
            fragment.Payload.ReadUInt32(); // Bytes to follow
            var turbineChatType = (TurbineChatType)fragment.Payload.ReadUInt32();

            fragment.Payload.ReadUInt32(); // Always 2
            fragment.Payload.ReadUInt32(); // Always 1
            fragment.Payload.ReadUInt32(); // Always 0
            fragment.Payload.ReadUInt32(); // Always 0
            fragment.Payload.ReadUInt32(); // Always 0
            fragment.Payload.ReadUInt32(); // Always 0
            fragment.Payload.ReadUInt32(); // Bytes to follow

            if (turbineChatType == TurbineChatType.OutboundMessage)
            {
                fragment.Payload.ReadUInt32(); // 0x01 - 0x71 (maybe higher), typically though 0x01 - 0x0F
                fragment.Payload.ReadUInt32(); // Always 2
                fragment.Payload.ReadUInt32(); // Always 2
                var channelID = fragment.Payload.ReadUInt32();

                var messageLen   = fragment.Payload.ReadByte();
                var messageBytes = fragment.Payload.ReadBytes(messageLen * 2);
                var message      = Encoding.Unicode.GetString(messageBytes);

                fragment.Payload.ReadUInt32();                                                                           // Always 0x0C
                var senderID = fragment.Payload.ReadUInt32();
                fragment.Payload.ReadUInt32();                                                                           // Always 0
                fragment.Payload.ReadUInt32();                                                                           // Always 1 or 2

                if (channelID == 7)                                                                                      // TODO this is hardcoded right now
                {
                    ChatPacket.SendServerMessage(session, "You do not belong to a society.", ChatMessageType.Broadcast); // I don't know if this is how it was done on the live servers
                    return;
                }

                var gameMessageTurbineChat = new GameMessageTurbineChat(TurbineChatType.InboundMessage, channelID, session.Player.Name, message, senderID);

                // TODO This should check if the recipient is subscribed to the channel
                foreach (var recipient in WorldManager.GetAll())
                {
                    recipient.WorldSession.EnqueueSend(gameMessageTurbineChat);
                }
            }
            else
            {
                Console.WriteLine($"Unhandled TurbineChatHandler TurbineChatType: 0x{(uint)turbineChatType:X4}");
            }
        }
示例#11
0
 public static void HandleGameAction(GameActionOpcode opcode, ClientPacketFragment fragment, Session session)
 {
     if (!actionHandlers.ContainsKey(opcode))
     {
         Console.WriteLine($"Received unhandled action opcode: 0x{(uint)opcode:X4}");
     }
     else
     {
         Type actionType;
         if (actionHandlers.TryGetValue(opcode, out actionType))
         {
             var gameAction = (GameActionPacket)Activator.CreateInstance(actionType, session, fragment);
             gameAction.Read();
             gameAction.Handle();
         }
     }
 }
示例#12
0
        public static async void CharacterCreate(ClientPacketFragment fragment, Session session)
        {
            // known issues:
            // 1. getting the "next" character id is not thread-safe

            string account = fragment.Payload.ReadString16L();

            if (account != session.Account)
            {
                return;
            }

            Character character = Character.CreateFromClientFragment(fragment.Payload, session.Id);

            // TODO: profanity filter
            // sendCharacterCreateResponse(session, 4);

            bool isAvailable = DatabaseManager.Character.IsNameAvailable(character.Name);

            if (!isAvailable)
            {
                SendCharacterCreateResponse(session, CharacterGenerationVerificationResponse.NameInUse);
                return;
            }

            uint lowGuid = DatabaseManager.Character.GetMaxId();

            character.Id        = lowGuid;
            character.AccountId = session.Id;

            if (!await DatabaseManager.Character.CreateCharacter(character))
            {
                SendCharacterCreateResponse(session, CharacterGenerationVerificationResponse.DatabaseDown);
                return;
            }

            CharacterCreateSetDefaultCharacterOptions(character);
            DatabaseManager.Character.SaveCharacterOptions(character);

            var guid = new ObjectGuid(lowGuid, GuidType.Player);

            session.CachedCharacters.Add(new CachedCharacter(guid, (byte)session.CachedCharacters.Count, character.Name, 0));

            SendCharacterCreateResponse(session, CharacterGenerationVerificationResponse.Ok, guid, character.Name);
        }
示例#13
0
        public static void CharacterEnterWorld(ClientPacketFragment fragment, Session session)
        {
            ObjectGuid guid    = fragment.Payload.ReadGuid();
            string     account = fragment.Payload.ReadString16L();

            if (account != session.Account)
            {
                session.SendCharacterError(CharacterError.EnterGameCharacterNotOwned);
                return;
            }

            var cachedCharacter = session.CachedCharacters.SingleOrDefault(c => c.Guid.Full == guid.Full);

            if (cachedCharacter == null)
            {
                session.SendCharacterError(CharacterError.EnterGameCharacterNotOwned);
                return;
            }

            session.CharacterRequested = cachedCharacter;

            // this isn't really that necessary since ACE doesn't split login/world to multiple daemons, handle it anyway
            byte[] connectionKey = new byte[sizeof(ulong)];
            RandomNumberGenerator.Create().GetNonZeroBytes(connectionKey);

            session.WorldConnectionKey = BitConverter.ToUInt64(connectionKey, 0);

            var referralPacket = new ServerPacket(0x0B, PacketHeaderFlags.EncryptedChecksum | PacketHeaderFlags.Referral);

            referralPacket.Payload.Write(session.WorldConnectionKey);
            referralPacket.Payload.Write((ushort)2);
            referralPacket.Payload.WriteUInt16BE((ushort)ConfigManager.Config.Server.Network.WorldPort);
            referralPacket.Payload.Write(ConfigManager.Host);
            referralPacket.Payload.Write(0ul);
            referralPacket.Payload.Write((ushort)0x18);
            referralPacket.Payload.Write((ushort)0);
            referralPacket.Payload.Write(0u);

            NetworkManager.SendPacket(ConnectionType.Login, referralPacket, session);

            session.State = SessionState.WorldLoginRequest;
        }
示例#14
0
        public static void HandleClientFragment(ClientPacketFragment fragment, Session session)
        {
            var opcode = (GameMessageOpcode)fragment.Payload.ReadUInt32();

            if (!fragmentHandlers.ContainsKey(opcode))
            {
                Console.WriteLine($"Received unhandled fragment opcode: 0x{(uint)opcode:X4}");
            }
            else
            {
                MessageHandlerInfo fragmentHandlerInfo;
                if (fragmentHandlers.TryGetValue(opcode, out fragmentHandlerInfo))
                {
                    if (fragmentHandlerInfo.Attribute.State == session.State)
                    {
                        fragmentHandlerInfo.Handler.Invoke(fragment, session);
                    }
                }
            }
        }
示例#15
0
        public static Character CreateFromClientFragment(ClientPacketFragment fragment, uint accountId)
        {
            Character character = new Character();

            fragment.Payload.Skip(4);   /* Unknown constant (1) */

            character.Heritage          = fragment.Payload.ReadUInt32();
            character.Gender            = fragment.Payload.ReadUInt32();
            character.Appearance        = Appearance.FromFragment(fragment);
            character.TemplateOption    = fragment.Payload.ReadUInt32();
            character.Strength.Base     = fragment.Payload.ReadUInt32();
            character.Endurance.Base    = fragment.Payload.ReadUInt32();
            character.Coordination.Base = fragment.Payload.ReadUInt32();
            character.Quickness.Base    = fragment.Payload.ReadUInt32();
            character.Focus.Base        = fragment.Payload.ReadUInt32();
            character.Self.Base         = fragment.Payload.ReadUInt32();
            character.Slot    = fragment.Payload.ReadUInt32();
            character.ClassId = fragment.Payload.ReadUInt32();

            // characters start with max vitals
            character.Health.Current  = character.Health.UnbuffedValue;
            character.Stamina.Current = character.Stamina.UnbuffedValue;
            character.Mana.Current    = character.Mana.UnbuffedValue;

            uint numOfSkills = fragment.Payload.ReadUInt32();

            for (uint i = 0; i < numOfSkills; i++)
            {
                character.AddSkill((Skill)i, (SkillStatus)fragment.Payload.ReadUInt32(), 0);
            }

            character.Name             = fragment.Payload.ReadString16L();
            character.StartArea        = fragment.Payload.ReadUInt32();
            character.IsAdmin          = Convert.ToBoolean(fragment.Payload.ReadUInt32());
            character.IsEnvoy          = Convert.ToBoolean(fragment.Payload.ReadUInt32());
            character.TotalSkillPoints = fragment.Payload.ReadUInt32();

            return(character);
        }
示例#16
0
        public static void CharacterRestore(ClientPacketFragment fragment, Session session)
        {
            ObjectGuid guid = fragment.Payload.ReadGuid();

            var cachedCharacter = session.CachedCharacters.SingleOrDefault(c => c.Guid.Full == guid.Full);

            if (cachedCharacter == null)
            {
                return;
            }

            bool isAvailable = DatabaseManager.Character.IsNameAvailable(cachedCharacter.Name);

            if (!isAvailable)
            {
                SendCharacterCreateResponse(session, CharacterGenerationVerificationResponse.NameInUse);    /* Name already in use. */
                return;
            }
            DatabaseManager.Character.DeleteOrRestore(0, guid.Low);

            session.LoginSession.EnqueueSend(new GameMessageCharacterRestore(guid, cachedCharacter.Name, 0u));
        }
示例#17
0
 public GameActionRemoveAllFriends(Session session, ClientPacketFragment fragment) : base(session, fragment)
 {
 }
示例#18
0
 public static void DDD_EndDDD(ClientPacketFragment fragment, Session session)
 {
     // We don't need to reply to this message.
 }
示例#19
0
 public GameActionPacket(Session session, ClientPacketFragment fragment)
 {
     this.session  = session;
     this.fragment = fragment;
 }
示例#20
0
 public static void DDD_InterrogationResponse(ClientPacketFragment fragment, Session session)
 {
     // Because we're not delivering any content at this time, we can instruct the client to end the DDD session.
 }
示例#21
0
 public static void CharacterEnterWorldRequest(ClientPacketFragment fragment, Session session)
 {
     session.LoginSession.EnqueueSend(new GameMessageCharacterEnterWorldServerReady());
 }
示例#22
0
 public GameActionRaiseVital(Session session, ClientPacketFragment fragment) : base(session, fragment)
 {
 }
示例#23
0
 public GameActionChatChannel(Session session, ClientPacketFragment fragment) : base(session, fragment)
 {
 }
 public GameActionSetCharacterOptions(Session session, ClientPacketFragment fragment) : base(session, fragment)
 {
 }
示例#25
0
 public GameActionSetTitle(Session session, ClientPacketFragment fragment) : base(session, fragment)
 {
 }
示例#26
0
 public GameActionHouseQuery(Session session, ClientPacketFragment fragment) : base(session, fragment)
 {
 }
示例#27
0
 public GameActionAutonomousPosition(Session session, ClientPacketFragment fragment) : base(session, fragment)
 {
 }
示例#28
0
 public GameActionAdvocateTeleport(Session session, ClientPacketFragment fragment) : base(session, fragment)
 {
 }
示例#29
0
 public GameActionTell(Session session, ClientPacketFragment fragment) : base(session, fragment)
 {
 }
示例#30
0
 public GameActionLoginComplete(Session session, ClientPacketFragment fragment) : base(session, fragment)
 {
 }