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(); }
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); }
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); }); }
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(); }
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); }
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(); }
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(); }
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); }
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(); }
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"); }
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(); }
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(); }
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); }
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(); }); }
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(); }); }
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(); }
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); }
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); }
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 "); }
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); }
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(); }