using AcDream.Core.Net.Packets;
namespace AcDream.Core.Net.Messages;
///
/// Outbound GameMessages for the character-select → in-world transition.
/// The client sends two messages in order after receiving
/// :
///
///
/// - CharacterEnterWorldRequest (opcode 0xF7C8) —
/// empty body beyond the 4-byte opcode. "Hi server, I'm about
/// to try to enter the world, anything I should know?"
/// - Server replies with
/// CharacterEnterWorldServerReady (0xF7DF).
/// - CharacterEnterWorld (opcode 0xF657) — u32 GUID
/// of the chosen character + String16L account name. Server
/// validates ownership and begins spawning the player + world
/// entities into our session, which is where the CreateObject
/// flood starts.
///
///
/// Both messages are tiny enough to fit in one fragment each. They go on
/// the queue per ACE's
/// CharacterHandler annotations.
///
public static class CharacterEnterWorld
{
public const uint EnterWorldRequestOpcode = 0xF7C8u;
public const uint EnterWorldOpcode = 0xF657u;
///
/// Build the body bytes for an outbound CharacterEnterWorldRequest.
/// Just the 4-byte opcode, nothing else.
///
public static byte[] BuildEnterWorldRequestBody()
{
var w = new PacketWriter(8);
w.WriteUInt32(EnterWorldRequestOpcode);
return w.ToArray();
}
///
/// Build the body bytes for an outbound CharacterEnterWorld.
/// Layout: opcode(4) + characterGuid(4) + String16L(accountName).
///
public static byte[] BuildEnterWorldBody(uint characterGuid, string accountName)
{
ArgumentNullException.ThrowIfNull(accountName);
var w = new PacketWriter(32);
w.WriteUInt32(EnterWorldOpcode);
w.WriteUInt32(characterGuid);
w.WriteString16L(accountName);
return w.ToArray();
}
}