using PSO2SERVER.Database; using PSO2SERVER.Models; using PSO2SERVER.Object; using PSO2SERVER.Protocol.Packets; using PSO2SERVER.Zone; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace PSO2SERVER.Protocol.Handlers { [PacketHandlerAttr(0x04, 0x14)] public class ObjectInteract : PacketHandler { public class InteractPacket { // Fields public byte[] Unk1 { get; set; } // [u8; 0xC] public ObjectHeader Object1 { get; set; } public byte[] Unk2 { get; set; } // [u8; 0x4] public ObjectHeader Object3 { get; set; } public byte[] Object4 { get; set; } // [u8; 0x10] public string Action { get; set; } // AsciiString // Constructor public InteractPacket() { Unk1 = new byte[0x0C]; // Initialize arrays with appropriate sizes Unk2 = new byte[0x04]; Object4 = new byte[0x10]; Action = string.Empty; } // Deserialize constructor (for example purposes, if needed) public InteractPacket(byte[] unk1, ObjectHeader object1, byte[] unk2, ObjectHeader object3, byte[] object4, string action) { Unk1 = unk1; Object1 = object1; Unk2 = unk2; Object3 = object3; Object4 = object4; Action = action; } } public override void HandlePacket(Client context, byte flags, byte[] data, uint position, uint size) { var reader = new PacketReader(data, position, size); var pkt = new InteractPacket { Unk1 = reader.ReadBytes(0x0C), Object1 = reader.ReadObjectHeader(), Unk2 = reader.ReadBytes(4), Object3 = reader.ReadObjectHeader(), Object4 = reader.ReadBytes(0x10), Action = reader.ReadAscii(0xD711, 0xCA) }; Logger.Write($"PKT:Object1 {pkt.Object1.ToString()} Object3 {pkt.Object3.ToString()} Action {pkt.Action}"); PSOObject srcObj; if(pkt.Object1.ObjectType == ObjectType.Object) { srcObj = ObjectManager.Instance.getObjectByID(context.CurrentZone.Name, pkt.Object1.ID); } else if(pkt.Object1.ObjectType == ObjectType.Player) { srcObj = new PSOObject { Header = pkt.Object1, Name = "Accounts" }; } else { srcObj = null; } //Logger.WriteInternal("[OBJ] {0} (ID {1}) <{2}> --> Ent {3} (ID {4})", srcObj.name, srcObj.Header.ID, command, (ObjectType)dstObject.ObjectType, dstObject.ID); // TODO: Delete this code and do this COMPLETELY correctly!!! if (pkt.Action == "Transfer" && context.CurrentZone.Name == "lobby") { // Try and get the teleport definition for the object... using (var db = new ServerEf()) { db.Configuration.AutoDetectChangesEnabled = true; var teleporterEndpoint = db.Teleports.Find("lobby", (int)pkt.Object1.ID); if (teleporterEndpoint == null) { Logger.WriteError("[OBJ] 传输 {0} 于 {1} 没有包含一个有效目的地!", srcObj.Header.ID, "lobby"); // Teleport Accounts to default point context.SendPacket(new TeleportTransferPacket(srcObj, new PSOLocation(0f, 1f, 0f, -0.000031f, -0.417969f, 0.000031f, 134.375f))); // Unhide player context.SendPacket(new ObjectActionPacket(pkt.Object3, pkt.Object1, new ObjectHeader(), new ObjectHeader(), "Forwarded")); } else { PSOLocation endpointLocation = new PSOLocation() { RotX = teleporterEndpoint.RotX, RotY = teleporterEndpoint.RotY, RotZ = teleporterEndpoint.RotZ, RotW = teleporterEndpoint.RotW, PosX = teleporterEndpoint.PosX, PosY = teleporterEndpoint.PosY, PosZ = teleporterEndpoint.PosZ, }; // Teleport Accounts context.SendPacket(new TeleportTransferPacket(srcObj, endpointLocation)); // Unhide player context.SendPacket(new ObjectActionPacket(pkt.Object3, pkt.Object1, new ObjectHeader(), new ObjectHeader(), "Forwarded")); } } } if (pkt.Action == "READY") { context.SendPacket(new ObjectActionPacket(new ObjectHeader((uint)context._account.AccountId, ObjectType.Player), srcObj.Header, srcObj.Header, new ObjectHeader(), "FavsNeutral")); context.SendPacket(new ObjectActionPacket(new ObjectHeader((uint)context._account.AccountId, ObjectType.Player), srcObj.Header, srcObj.Header, new ObjectHeader(), "AP")); // Short for Appear, Thanks Zapero! } if (pkt.Action == "Sit") { foreach (var client in Server.Instance.Clients) { if (client.Character == null || client == context) continue; client.SendPacket(new ObjectActionPacket(new ObjectHeader((uint)client._account.AccountId, ObjectType.Player), srcObj.Header, new ObjectHeader(pkt.Object3.ID, ObjectType.Player), new ObjectHeader(), "SitSuccess")); } } } } }