示例#1
0
        public void Doesnt_block_gump_response_from_client_after_closing_hidden_gump()
        {
            // 1. proxy sends the response to server
            // 2. proxy sends close gump request to client (General information packet 0xBF, subcommand 0x04)
            // 3. game client responds to 0xBF/0x04 by sending gump cancellation request to proxy
            // 4. proxy blocks the gump cancellation request
            // 5. user opens and cancells the same gump

            // Proxy must not block the response in this case and the observer has to reset current gump.

            var testProxy = new InfusionTestProxy();

            var task = Task.Run(() =>
            {
                testProxy.Api.WaitForGump(false);
                testProxy.Api.GumpResponse().Cancel();
            });

            testProxy.Api.WaitForGumpStartedEvent.AssertWaitOneSuccess();

            testProxy.PacketReceivedFromServer(SendGumpMenuDialogPackets.Explevel);
            task.AssertWaitFastSuccess();
            // script closes hidden gump,
            // but no cancellation request from game client, because there is no 0xBF/0x04 sent to the client

            // user opens gump from game client
            testProxy.PacketReceivedFromServer(SendGumpMenuDialogPackets.Explevel);

            // user closes gump from game client
            testProxy.PacketReceivedFromClient(GumpMenuSelectionRequests.CancelExplevel);

            testProxy.Api.CurrentGump.Should().BeNull();
        }
示例#2
0
        public void Keeps_corpse_type_when_server_sends_corpse_name()
        {
            var testProxy = new InfusionTestProxy();

            var corpseObjectInfo = new byte[]
            {
                0x1A, 0x00, 0x11, 0xC0, 0x09, 0x8F, 0xD6, 0x20, 0x06, 0x00, 0xED, 0x8A, 0x44,
                0x0C, 0xDD, 0x07, 0x00,
            };

            testProxy.PacketReceivedFromServer(corpseObjectInfo);


            var corpseNameSpeech = new byte[]
            {
                0x1C, 0x00, 0x3A, 0x40, 0x09, 0x8F, 0xD6, 0x20, 0x06, 0x06, 0x03, 0xB2, 0x00, 0x03, 0x42, 0x6F,
                0x64, 0x79, 0x20, 0x6F, 0x66, 0x20, 0x53, 0x72, 0x6E, 0x65, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x6F, 0x64, 0x79,
                0x20, 0x6F, 0x66, 0x20, 0x53, 0x72, 0x6E, 0x65, 0x63, 0x00,
            };

            testProxy.PacketReceivedFromServer(corpseNameSpeech);

            var corpse = testProxy.Api.Corpses.Single();

            corpse.Name.Should().Be("Body of Srnec");
            corpse.CorpseType.Should().Be((ModelId)0x00ED);
        }
示例#3
0
        public void Can_set_future_autotargets()
        {
            ConcurrencyTester.Run(() =>
            {
                var testProxy = new InfusionTestProxy();
                var targetSet = new AutoResetEvent(false);

                var task = Task.Run(() =>
                {
                    testProxy.Api.WaitTargetObject(0x12345678, 0x87654321);
                    targetSet.Set();
                });

                targetSet.WaitOne();

                testProxy.PacketReceivedFromServer(new Packet(0x6C, new byte[]
                {
                    0x6C, 0x01, 0x00, 0x00, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    0x00, 0x00, 0x00
                }));

                testProxy.PacketReceivedFromServer(new Packet(0x6C, new byte[]
                {
                    0x6C, 0x01, 0x00, 0x00, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    0x00, 0x00, 0x00
                }));

                task.Wait(100).Should().BeTrue();

                testProxy.PacketsSentToServer.Count(x => x.Id == 0x6C).Should().Be(2);
            });
        }
示例#4
0
        public void Can_response_to_gump_and_receive_next_gump_from_server_before_game_client_sends_gump_cancallation_request()
        {
            // 1. proxy sends the response to the server
            // 2. proxy sends close gump request to the game client (General information packet 0xBF, subcommand 0x04)
            // 3. server sends a new gump to proxy
            // 3. game client responds to 0xBF/0x04 by sending gump cancellation request to proxy
            // 4. proxy blocks the gump cancellation request

            // This scenario can happen on slow computers, where server sends another gump before client responds with cancellation request
            // Server sends another gump after response quite frequently, e.g. crafting menus.
            // If proxy doesn't block the gump cancellation request then server receives a response to a gump that was already
            // closed by proxy (step 1) and sends unexpected response error.
            var testProxy = new InfusionTestProxy();

            var task = Task.Run(() =>
            {
                testProxy.Api.WaitForGump();
                // cancellation a special case of gump response
                testProxy.Api.GumpResponse().Cancel();
            });

            testProxy.Api.WaitForGumpStartedEvent.AssertWaitOneSuccess();
            testProxy.PacketReceivedFromServer(SendGumpMenuDialogPackets.Explevel);
            task.AssertWaitFastSuccess();

            // second gump from server comes before client cancellation of the first gump
            // first and second gump can have same ids
            testProxy.PacketReceivedFromServer(SendGumpMenuDialogPackets.Explevel);
            // game client cancellation of the first gump (client is slower than server)
            testProxy.PacketReceivedFromClient(GumpMenuSelectionRequests.CancelExplevel).Should().BeNull();
        }
示例#5
0
        public void Single_skill_0_change_raises_event_as_Alchemy()
        {
            var testProxy = new InfusionTestProxy();
            var journal   = testProxy.Api.CreateEventJournal();

            testProxy.PacketReceivedFromServer(new byte[] { 0x3A, 0x00, 0x0B, 0xFF, 0x00, 0x00, 0x02, 0xC9, 0x02, 0xC9, 0x00, });
            testProxy.PacketReceivedFromServer(new byte[] { 0x3A, 0x00, 0x0B, 0xFF, 0x00, 0x00, 0x02, 0xCA, 0x02, 0xCA, 0x00, });

            journal.OfType <SkillChangedEvent>().Should().NotBeEmpty();
            journal.OfType <SkillChangedEvent>().First().Skill.Should().Be(Skill.Alchemy);
        }
示例#6
0
        public void Doesnt_block_gump_for_client_after_blocked_gump()
        {
            var testProxy = new InfusionTestProxy();

            var task = Task.Run(() => { testProxy.Api.WaitForGump(false); });

            testProxy.Api.WaitForGumpStartedEvent.AssertWaitOneSuccess();

            testProxy.PacketReceivedFromServer(SendGumpMenuDialogPackets.Explevel).Should().BeNull();
            testProxy.PacketReceivedFromServer(SendGumpMenuDialogPackets.Explevel).Should().NotBeNull();

            task.AssertWaitFastSuccess();
        }
示例#7
0
        public void Single_skill_change_raises_event()
        {
            var testProxy = new InfusionTestProxy();
            var journal   = testProxy.Api.CreateEventJournal();

            // initialize skill value, SkillChangedEvent requires it
            testProxy.PacketReceivedFromServer(new byte[] { 0x3A, 0x00, 0x0B, 0xFF, 0x00, 0x02, 0x02, 0xC9, 0x02, 0xC9, 0x00, });

            // now it can be changed and SkillChangedEvent can be raised
            testProxy.PacketReceivedFromServer(new byte[] { 0x3A, 0x00, 0x0B, 0xFF, 0x00, 0x02, 0x02, 0xCA, 0x02, 0xCA, 0x00, });

            journal.OfType <SkillChangedEvent>().Should().NotBeNullOrEmpty();
        }
示例#8
0
        public void Single_skill_0_change_raises_event()
        {
            var testProxy = new InfusionTestProxy();
            var journal   = testProxy.Api.CreateEventJournal();

            // initialize skill value, SkillChangedEvent requires it
            testProxy.PacketReceivedFromServer(new byte[] { 0x3A, 0x00, 0x0B, 0xFF, 0x00, 0x02, 0x02, 0xC9, 0x02, 0xC9, 0x00, });

            testProxy.Api.UseSkill(Skill.AnimalLore);

            // Sphere 0.99gz seems to send skill 0 sometimes, instead of actual skill or the skill mapping is not completely correct
            // in Infusion, not sure...
            testProxy.PacketReceivedFromServer(new byte[] { 0x3A, 0x00, 0x0B, 0xFF, 0x00, 0x00, 0x02, 0xCA, 0x02, 0xCA, 0x00, });

            journal.OfType <SkillChangedEvent>().Should().NotBeEmpty();
            journal.OfType <SkillChangedEvent>().First().Skill.Should().Be(Skill.AnimalLore);
        }
示例#9
0
        public void Resets_layer_when_added_to_container()
        {
            var wornPacket = new Packet(0x2E, new byte[]
            {
                0x2E, 0x40, 0x04, 0xF1, 0x9C, 0x0F, 0x51, 0x00, 0x02, 0x00, 0x06, 0x39, 0x0E, 0x07, 0x63,
            });
            var testProxy = new InfusionTestProxy();

            testProxy.PacketReceivedFromServer(wornPacket);

            var addToContainerPacket = new Packet(0x25, new byte[]
            {
                0x25, 0x40, 0x04, 0xF1, 0x9C, 0x13, 0xF8, 0x00, 0x00, 0x01, 0x00, 0x36, 0x00, 0x7F, 0x40, 0x05,
                0x67, 0x56, 0x00, 0xED,
            });

            testProxy.PacketReceivedFromServer(addToContainerPacket);

            testProxy.Api.Items[0x4004F19C].Layer.HasValue.Should().BeFalse();
        }
示例#10
0
        public void Can_handle_compressed_gump()
        {
            var testProxy = new InfusionTestProxy();

            testProxy.PacketReceivedFromServer(SendGumpMenuDialogPackets.Compressed);

            testProxy.Api.CurrentGump.Should().NotBeNull();
            testProxy.Api.CurrentGump.Commands.Should().Contain("{ ButtonTileArt 266 113 129 129 1 0 2 6571 0 0 0 }");
            testProxy.Api.CurrentGump.TextLines.Should().HaveCount(3);
            testProxy.Api.CurrentGump.TextLines[0].Should().Contain("Forja Pequena");
        }
示例#11
0
        public void Can_block_gump_for_client()
        {
            var testProxy = new InfusionTestProxy();

            var task = Task.Run(() => { testProxy.Api.WaitForGump(false); });

            testProxy.Api.WaitForGumpStartedEvent.WaitOne(100).Should().BeTrue();

            testProxy.PacketReceivedFromServer(SendGumpMenuDialogPackets.Explevel).Should().BeNull();

            task.Wait(100).Should().BeTrue();
        }
示例#12
0
        public void Can_wait_for_gump()
        {
            var  testProxy  = new InfusionTestProxy();
            Gump resultGump = null;

            var task = Task.Run(() => { resultGump = testProxy.Api.WaitForGump(); });

            testProxy.Api.WaitForGumpStartedEvent.AssertWaitOneSuccess();

            testProxy.PacketReceivedFromServer(SendGumpMenuDialogPackets.Explevel).Should().NotBeNull();

            task.AssertWaitFastSuccess();
            resultGump.Should().NotBeNull();
        }
示例#13
0
        public void Sets_layer_when_item_worn()
        {
            var wornPacket = new Packet(0x2E, new byte[]
            {
                0x2E,                   // packet id
                0x40, 0x04, 0xF1, 0x9C, // item id
                0x0F, 0x51, 0x00,
                0x02,                   // layer
                0x00, 0x06, 0x39, 0x0E, 0x07, 0x63,
            });
            var testProxy = new InfusionTestProxy();

            testProxy.PacketReceivedFromServer(wornPacket);

            testProxy.Api.Items[0x4004F19C].Layer.HasValue.Should().BeTrue();
            testProxy.Api.Items[0x4004F19C].Layer.Should().Be(Layer.TwoHandedWeapon);
        }
示例#14
0
        public void Cancels_AskForMobile_When_server_requests_target()
        {
            ConcurrencyTester.Run(() =>
            {
                var testProxy = new InfusionTestProxy();

                var task = Task.Run(() => { testProxy.Api.AskForMobile().Should().BeNull(); });

                testProxy.Api.AskForTargetStartedEvent.WaitOne(100).Should().BeTrue();
                testProxy.PacketReceivedFromServer(new Packet(0x6C, new byte[]
                {
                    0x6C, 0x01, 0x00, 0x00, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    0x00, 0x00, 0x00
                }));

                task.Wait(100).Should().BeTrue();
            });
        }
示例#15
0
        public void Cancels_AfkForItem_When_server_requests_target()
        {
            ConcurrencyTester.Run(() =>
            {
                var testProxy = new InfusionTestProxy();

                var task = Task.Run(() => { testProxy.Api.AskForItem().Should().BeNull(); });

                testProxy.Api.AskForTargetStartedEvent.AssertWaitOneSuccess();
                testProxy.PacketReceivedFromServer(new Packet(0x6C, new byte[]
                {
                    0x6C, 0x01, 0x00, 0x00, 0x00, 0x25, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    0x00, 0x00, 0x00
                }));

                task.AssertWaitFastSuccess();
            });
        }
示例#16
0
        public void Can_publish_event_after_receiving_gump()
        {
            var  testProxy  = new InfusionTestProxy();
            var  journal    = testProxy.Api.CreateEventJournal();
            Gump resultGump = null;

            var task = Task.Run(() =>
            {
                journal.When <Events.GumpReceivedEvent>(e => resultGump = e.Gump)
                .WaitAny();
            });

            journal.AwaitingStarted.AssertWaitOneSuccess();
            testProxy.PacketReceivedFromServer(SendGumpMenuDialogPackets.Explevel);
            task.AssertWaitFastSuccess();

            resultGump.Should().NotBeNull();
        }
示例#17
0
        public void Doesnt_cancel_hidden_gump_on_game_client()
        {
            var testProxy = new InfusionTestProxy();

            var task = Task.Run(() =>
            {
                testProxy.Api.WaitForGump(false); // next gump is hidden
                testProxy.Api.GumpResponse().Cancel();
            });

            testProxy.Api.WaitForGumpStartedEvent.AssertWaitOneSuccess();

            testProxy.PacketReceivedFromServer(SendGumpMenuDialogPackets.Explevel);
            task.AssertWaitFastSuccess();

            testProxy.PacketsSentToClient.Should()
            .NotContain(packet => packet.Id == PacketDefinitions.GeneralInformationPacket.Id);
        }
示例#18
0
        public void Amount_is_corpse_type()
        {
            var payload = new byte[]
            {
                0x1A, 0x00, 0x11, 0xC0, 0x0B, 0x7E, 0x06,
                0x20, 0x06, // corpse type
                0x00, 0x05, // amount, has to be interpreted as corpse type
                0x8A, 0x3B, 0x0C, 0x20, 0x03, 0x01,
            };

            var testProxy = new InfusionTestProxy();

            testProxy.PacketReceivedFromServer(payload);

            var corpse = testProxy.Api.Corpses.Single();

            corpse.CorpseType.Should().Be((ModelId)0x0005);
        }
示例#19
0
        public void Can_translate_cliloc_message_with_arguments()
        {
            var proxy = new InfusionTestProxy();

            proxy.ClilocSource.Add(0x001005BD, "~1_PREFIX~~2_NAME~~3_SUFFIX~");

            proxy.PacketReceivedFromServer(new byte[]
            {
                0xC1, 0x00, 0x60, 0x02, 0x70, 0x72, 0x62, 0x01, 0x90, 0x06, 0x00, 0x35, 0x00, 0x03, 0x00, 0x10,
                0x05, 0xBD, 0x4B, 0x75, 0x72, 0x74, 0x20, 0x50, 0x6F, 0x6E, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20,
                0x4D, 0x69, 0x6E, 0x65, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x20, 0x00, 0x09, 0x00, 0x4B, 0x00, 0x75, 0x00, 0x72, 0x00, 0x74, 0x00, 0x20, 0x00, 0x50, 0x00,
                0x6F, 0x00, 0x6E, 0x00, 0x64, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00,
                0x4D, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x65, 0x00, 0x72, 0x00, 0x09, 0x00, 0x20, 0x00, 0x00, 0x00,
            });

            var message = proxy.Api.Journal.First().Message;

            message.Should().Be(" Kurt Pond the Miner ");
        }
示例#20
0
        public void Publishes_event_When_map_message_packet_received()
        {
            var testProxy = new InfusionTestProxy();
            var journal   = testProxy.Api.CreateEventJournal();

            testProxy.PacketReceivedFromServer(new byte[]
            {
                0x90, 0x40, 0x09, 0x73, 0x5C,
                0x13, 0x9D,
                0x10, 0xD4, 0x08, 0x44,
                0x12, 0x3C, 0x09, 0xAC,
                0x00, 0xC8,
                0x00, 0xC8,
            });

            journal.OfType <MapMessageEvent>().Any().Should().BeTrue();
            var ev = journal.OfType <MapMessageEvent>().First();

            ev.UpperLeft.Should().Be(new Location2D(0x10D4, 0x0844));
            ev.LowerRight.Should().Be(new Location2D(0x123C, 0x09AC));
            ev.Width.Should().Be(0x00C8);
            ev.Height.Should().Be(0x00C8);
        }
示例#21
0
        public void Can_response_to_a_gump_without_provoking_unexpected_response_error_from_server()
        {
            // 1. proxy sends the response to server
            // 2. proxy sends close gump request to client (General information packet 0xBF, subcommand 0x04)
            // 3. game client responds to 0xBF/0x04 by sending gump cancellation request to proxy
            // 4. proxy blocks the gump cancellation request

            // If proxy doesn't block the gump cancellation request then server receives a response to a gump that was already
            // closed by proxy (step 1) and sends unexpected response error.

            var testProxy = new InfusionTestProxy();

            var task = Task.Run(() =>
            {
                testProxy.Api.WaitForGump();
                // cancellation a special case of gump response
                testProxy.Api.GumpResponse().Cancel();
            });

            testProxy.Api.WaitForGumpStartedEvent.AssertWaitOneSuccess();
            testProxy.PacketReceivedFromServer(SendGumpMenuDialogPackets.Explevel);
            task.AssertWaitFastSuccess();
            testProxy.PacketReceivedFromClient(GumpMenuSelectionRequests.CancelExplevel).Should().BeNull();
        }