public void CharacterListPacket_Initialization() { const OutgoingPacketType ExpectedPacketType = OutgoingPacketType.CharacterList; const ushort ExpectedPremiumDays = 7; ExceptionAssert.Throws <ArgumentException>(() => new CharacterListPacket(null, ExpectedPremiumDays), "Value cannot be null. (Parameter 'characters')"); var expectedCharList = new List <CharacterInfo>() { new CharacterInfo() { Name = "Char 1", Ip = IPAddress.Loopback.GetAddressBytes(), Port = 123, World = "Fibula" }, new CharacterInfo() { Name = "Char 2", Ip = IPAddress.Any.GetAddressBytes(), Port = 321, World = "Fibula 2" }, }; var packet = new CharacterListPacket(expectedCharList, ExpectedPremiumDays); Assert.AreEqual(ExpectedPacketType, packet.PacketType, $"Expected {nameof(packet.PacketType)} to match {ExpectedPacketType}."); Assert.IsNotNull(packet.Characters); CollectionAssert.AreEqual(expectedCharList, packet.Characters.ToArray(), $"Expected {nameof(packet.Characters)} to match {expectedCharList}."); Assert.AreEqual(ExpectedPremiumDays, packet.PremiumDaysLeft, $"Expected {nameof(packet.PremiumDaysLeft)} to match {ExpectedPremiumDays}."); }
/// <summary> /// Selects the most appropriate packet writer for the specified type. /// </summary> /// <param name="forPacketType">The type of packet.</param> /// <returns>An instance of an <see cref="IPacketWriter"/> implementation.</returns> public IPacketWriter SelectPacketWriter(OutgoingPacketType forPacketType) { if (this.packetWritersMap.TryGetValue(forPacketType, out IPacketWriter writer)) { return(writer); } return(null); }
/// <summary> /// Registers a packet writer to this protocol. /// </summary> /// <param name="forType">The type of packet to register for.</param> /// <param name="packetWriter">The packet writer to register.</param> public void RegisterPacketWriter(OutgoingPacketType forType, IPacketWriter packetWriter) { packetWriter.ThrowIfNull(nameof(packetWriter)); if (this.packetWritersMap.ContainsKey(forType)) { throw new InvalidOperationException($"There is already a writer registered for the packet type: {forType}."); } this.logger.LogTrace($"Registered packet writer for type {forType}."); this.packetWritersMap[forType] = packetWriter; }
/// <summary> /// Initializes a new instance of the <see cref="MapPartialDescriptionPacket"/> class. /// </summary> /// <param name="mapDescriptionType">The type of map description.</param> /// <param name="descriptionBytes">The description bytes.</param> public MapPartialDescriptionPacket(OutgoingPacketType mapDescriptionType, ReadOnlySequence <byte> descriptionBytes) { if (mapDescriptionType != OutgoingPacketType.MapSliceEast && mapDescriptionType != OutgoingPacketType.MapSliceNorth && mapDescriptionType != OutgoingPacketType.MapSliceSouth && mapDescriptionType != OutgoingPacketType.MapSliceWest && mapDescriptionType != OutgoingPacketType.FloorChangeUp && mapDescriptionType != OutgoingPacketType.FloorChangeDown) { throw new ArgumentException(nameof(mapDescriptionType)); } this.PacketType = mapDescriptionType; this.DescriptionBytes = descriptionBytes; }
public void AddCreaturePacket_Initialization() { const OutgoingPacketType ExpectedPacketType = OutgoingPacketType.AddThing; const bool ExpectedAsKnownValue = true; const uint ExpectedCreatureIdToRemove = 1; ExceptionAssert.Throws <ArgumentException>(() => new AddCreaturePacket(null, ExpectedAsKnownValue, ExpectedCreatureIdToRemove), "Value cannot be null. (Parameter 'creature')"); var creatureMock = new Mock <ICreature>(); var packet = new AddCreaturePacket(creatureMock.Object, ExpectedAsKnownValue, ExpectedCreatureIdToRemove); Assert.AreEqual(ExpectedPacketType, packet.PacketType, $"Expected {nameof(packet.PacketType)} to match {ExpectedPacketType}."); Assert.AreSame(creatureMock.Object, packet.Creature, $"Expected {nameof(packet.Creature)} to be the same instance as {creatureMock.Object}."); Assert.AreEqual(ExpectedAsKnownValue, packet.AsKnown, $"Expected {nameof(packet.AsKnown)} to match {ExpectedAsKnownValue}."); Assert.AreEqual(ExpectedCreatureIdToRemove, packet.RemoveThisCreatureId, $"Expected {nameof(packet.RemoveThisCreatureId)} to match {ExpectedCreatureIdToRemove}."); }
public void AnimatedTextPacket_Initialization() { const OutgoingPacketType ExpectedPacketType = OutgoingPacketType.AnimatedText; const TextColor ExpectedTextColor = TextColor.Green; const string ExpectedText = "this is a test!"; Location expectedLocation = new Location() { X = 100, Y = 150, Z = 7 }; var packet = new AnimatedTextPacket(expectedLocation, ExpectedTextColor, ExpectedText); Assert.AreEqual(ExpectedPacketType, packet.PacketType, $"Expected {nameof(packet.PacketType)} to match {ExpectedPacketType}."); Assert.AreEqual(expectedLocation, packet.Location, $"Expected {nameof(packet.Location)} to match {expectedLocation}."); Assert.AreEqual(ExpectedTextColor, packet.Color, $"Expected {nameof(packet.Color)} to match {ExpectedTextColor}."); Assert.AreEqual(ExpectedText, packet.Text, $"Expected {nameof(packet.Text)} to match {ExpectedText}."); }
/// <summary> /// Attempts to convert an <see cref="OutgoingPacketType"/> value into a byte value. /// </summary> /// <param name="packetType">The packet type to convert.</param> /// <returns>The byte value converted to.</returns> public static byte ToByte(this OutgoingPacketType packetType) { return(packetType switch { OutgoingPacketType.GatewayDisconnect => 0x0A, OutgoingPacketType.MessageOfTheDay => 0x14, OutgoingPacketType.CharacterList => 0x64, OutgoingPacketType.PlayerLogin => 0x0A, OutgoingPacketType.GamemasterFlags => 0x0B, OutgoingPacketType.GameDisconnect => 0x14, OutgoingPacketType.WaitingList => 0x16, OutgoingPacketType.HeartbeatResponse => 0x1D, OutgoingPacketType.Heartbeat => 0x1E, OutgoingPacketType.Death => 0x28, OutgoingPacketType.AddUnknownCreature => 0x61, OutgoingPacketType.AddKnownCreature => 0x62, OutgoingPacketType.MapDescription => 0x64, OutgoingPacketType.MapSliceNorth => 0x65, OutgoingPacketType.MapSliceEast => 0x66, OutgoingPacketType.MapSliceSouth => 0x67, OutgoingPacketType.MapSliceWest => 0x68, OutgoingPacketType.TileUpdate => 0x69, OutgoingPacketType.AddThing => 0x6A, OutgoingPacketType.UpdateThing => 0x6B, OutgoingPacketType.RemoveThing => 0x6C, OutgoingPacketType.CreatureMoved => 0x6D, OutgoingPacketType.ContainerOpen => 0x6E, OutgoingPacketType.ContainerClose => 0x6F, OutgoingPacketType.ContainerAddItem => 0x70, OutgoingPacketType.ContainerUpdateItem => 0x71, OutgoingPacketType.ContainerRemoveItem => 0x72, OutgoingPacketType.InventoryItem => 0x78, OutgoingPacketType.InventoryEmpty => 0x79, OutgoingPacketType.WorldLight => 0x82, OutgoingPacketType.MagicEffect => 0x83, OutgoingPacketType.AnimatedText => 0x84, OutgoingPacketType.ProjectileEffect => 0x85, OutgoingPacketType.Square => 0x86, OutgoingPacketType.CreatureHealth => 0x8C, OutgoingPacketType.CreatureLight => 0x8D, OutgoingPacketType.CreatureOutfit => 0x8E, OutgoingPacketType.CreatureSpeedChange => 0x8F, OutgoingPacketType.CreatureSkull => 0x90, OutgoingPacketType.CreatureShield => 0x91, OutgoingPacketType.TextWindow => 0x96, OutgoingPacketType.HouseWindow => 0x97, OutgoingPacketType.PlayerStats => 0xA0, OutgoingPacketType.PlayerSkills => 0xA1, OutgoingPacketType.PlayerConditions => 0xA2, OutgoingPacketType.CancelAttack => 0xA3, OutgoingPacketType.PlayerModes => 0xA7, OutgoingPacketType.CreatureSpeech => 0xAA, OutgoingPacketType.TextMessage => 0xB4, OutgoingPacketType.CancelWalk => 0xB5, OutgoingPacketType.FloorChangeUp => 0xBE, OutgoingPacketType.FloorChangeDown => 0xBF, OutgoingPacketType.OutfitWindow => 0xC8, OutgoingPacketType.VipDetails => 0xD2, OutgoingPacketType.VipOnline => 0xD3, OutgoingPacketType.VipOffline => 0xD4, _ => throw new NotSupportedException($"Outgoing packet type {packetType} is not supported in this client version.") });
private void ParseFirstClientMsg() { try { clientRecvMsg.Position = clientRecvMsg.GetPacketHeaderSize(); OutgoingPacketType protocolId = (OutgoingPacketType)clientRecvMsg.GetByte(); int position; switch (protocolId) { case OutgoingPacketType.LoginServerRequest: protocol = Protocol.Login; clientRecvMsg.GetUInt16(); ushort clientVersion = clientRecvMsg.GetUInt16(); clientRecvMsg.GetUInt32(); clientRecvMsg.GetUInt32(); clientRecvMsg.GetUInt32(); position = clientRecvMsg.Position; clientRecvMsg.RsaOTDecrypt(); if (clientRecvMsg.GetByte() != 0) { Restart(); return; } xteaKey[0] = clientRecvMsg.GetUInt32(); xteaKey[1] = clientRecvMsg.GetUInt32(); xteaKey[2] = clientRecvMsg.GetUInt32(); xteaKey[3] = clientRecvMsg.GetUInt32(); if (Version.CurrentVersion >= 830) { clientRecvMsg.GetString(); // account name } else { clientRecvMsg.GetUInt32(); // account number } clientRecvMsg.GetString(); // password if (isOtServer) { clientRecvMsg.RsaOTEncrypt(position); } else { clientRecvMsg.RsaCipEncrypt(position); } if (Version.CurrentVersion >= 830) { clientRecvMsg.AddAdler32(); } clientRecvMsg.InsertPacketHeader(); serverTcp = new TcpClient(loginServers[selectedLoginServer].Server, loginServers[selectedLoginServer].Port); serverStream = serverTcp.GetStream(); serverStream.Write(clientRecvMsg.GetBuffer(), 0, clientRecvMsg.Length); serverStream.BeginRead(serverRecvMsg.GetBuffer(), 0, 2, new AsyncCallback(ServerReadCallBack), null); //clientStream.BeginRead(clientRecvMsg.GetBuffer(), 0, 2, new AsyncCallback(ClientReadCallBack), null); break; case OutgoingPacketType.GameServerRequest: protocol = Protocol.World; clientRecvMsg.GetUInt16(); clientRecvMsg.GetUInt16(); position = clientRecvMsg.Position; clientRecvMsg.RsaOTDecrypt(); if (clientRecvMsg.GetByte() != 0) { Restart(); return; } xteaKey[0] = clientRecvMsg.GetUInt32(); xteaKey[1] = clientRecvMsg.GetUInt32(); xteaKey[2] = clientRecvMsg.GetUInt32(); xteaKey[3] = clientRecvMsg.GetUInt32(); clientRecvMsg.GetByte(); // GM mode if (Version.CurrentVersion >= 830) { clientRecvMsg.GetString(); // account name } else { clientRecvMsg.GetUInt32(); // account number } string characterName = clientRecvMsg.GetString(); clientRecvMsg.GetString(); // password if (isOtServer) { clientRecvMsg.RsaOTEncrypt(position); } else { clientRecvMsg.RsaCipEncrypt(position); } if (Version.CurrentVersion >= 830) { clientRecvMsg.AddAdler32(); } clientRecvMsg.InsertPacketHeader(); int index = GetSelectedIndex(characterName); if (Version.CurrentVersion < 854) { serverTcp = new TcpClient(BitConverter.GetBytes(charList[index].WorldIP).ToIPString(), charList[index].WorldPort); serverStream = serverTcp.GetStream(); } serverStream.Write(clientRecvMsg.GetBuffer(), 0, clientRecvMsg.Length); serverStream.BeginRead(serverRecvMsg.GetBuffer(), 0, 2, new AsyncCallback(ServerReadCallBack), null); clientStream.BeginRead(clientRecvMsg.GetBuffer(), 0, 2, new AsyncCallback(ClientReadCallBack), null); break; default: break; } } catch (Exception ex) { WriteDebug(ex.ToString()); Restart(); } }
/// <summary> /// Creates a new Authentication Request Packet /// </summary> /// <param name="authenticator">The SaveData that needs to be compared to the online version for authentication</param> public OutgoingPacket(SaveData authenticator) { Type = OutgoingPacketType.AUTH; PacketContainer = new OAuthenticatePacket(authenticator); }
/// <summary> /// Creates a new Outgoing Trade Packet with the SET_POKEMON Trade Command /// </summary> /// <param name="pokemonToTrade">The SeriPokemon that needs to be set (visible to the other player)</param> public OutgoingPacket(TradeCommand command, SeriPokemon pokemonToTrade) { Type = OutgoingPacketType.TRADE; PacketContainer = new OTradePacket(command, pokemonToTrade); }
/// <summary> /// Creates a new empty Outgoing Trade Packet with the set TradeCommand /// </summary> /// <param name="tradeCommand"></param> public OutgoingPacket(TradeCommand tradeCommand) { Type = OutgoingPacketType.TRADE; PacketContainer = new OTradePacket(tradeCommand, ""); }