Rework input packets based on new header knowledge

This commit is contained in:
Cameron Gutman 2021-07-30 00:56:01 -05:00
parent ceafe7897c
commit 74377a061b
2 changed files with 52 additions and 67 deletions

View File

@ -3,50 +3,41 @@
#pragma pack(push, 1)
typedef struct _NV_INPUT_HEADER {
uint32_t packetType;
uint32_t size; // Size of packet (excluding this field) - Big Endian
uint32_t magic; // Packet type - Little Endian
} NV_INPUT_HEADER, PNV_INPUT_HEADER;
#define PACKET_TYPE_HAPTICS 0x06
#define H_MAGIC_A 0x0000000D
#define H_MAGIC_B 0x00000001
#define ENABLE_HAPTICS_MAGIC 0x0000000D
typedef struct _NV_HAPTICS_PACKET {
NV_INPUT_HEADER header;
int magicA;
int magicB;
uint16_t enable;
} NV_HAPTICS_PACKET, *PNV_HAPTICS_PACKET;
#define PACKET_TYPE_KEYBOARD 0x0A
typedef struct _NV_KEYBOARD_PACKET {
NV_INPUT_HEADER header;
char keyAction;
int zero1;
char zero1;
short keyCode;
char modifiers;
short zero2;
} NV_KEYBOARD_PACKET, *PNV_KEYBOARD_PACKET;
#define UTF8_TEXT_EVENT_MAGIC 0x17
#define UTF8_TEXT_EVENT_MAGIC 0x00000017
#define UTF8_TEXT_EVENT_MAX_COUNT 32
typedef struct _NV_UNICODE_PACKET {
unsigned int size;
int magic;
NV_INPUT_HEADER header;
char text[UTF8_TEXT_EVENT_MAX_COUNT];
} NV_UNICODE_PACKET, *PNV_UNICODE_PACKET;
#define PACKET_TYPE_REL_MOUSE_MOVE 0x08
#define MOUSE_MOVE_REL_MAGIC 0x06
#define MOUSE_MOVE_REL_MAGIC 0x00000006
typedef struct _NV_REL_MOUSE_MOVE_PACKET {
NV_INPUT_HEADER header;
int magic;
short deltaX;
short deltaY;
} NV_REL_MOUSE_MOVE_PACKET, *PNV_REL_MOUSE_MOVE_PACKET;
#define PACKET_TYPE_ABS_MOUSE_MOVE 0x0e
#define MOUSE_MOVE_ABS_MAGIC 0x05
#define MOUSE_MOVE_ABS_MAGIC 0x00000005
typedef struct _NV_ABS_MOUSE_MOVE_PACKET {
NV_INPUT_HEADER header;
int magic;
short x;
short y;
@ -59,21 +50,18 @@ typedef struct _NV_ABS_MOUSE_MOVE_PACKET {
short height;
} NV_ABS_MOUSE_MOVE_PACKET, *PNV_ABS_MOUSE_MOVE_PACKET;
#define PACKET_TYPE_MOUSE_BUTTON 0x05
#define MOUSE_BUTTON_MAGIC 0x00000005
typedef struct _NV_MOUSE_BUTTON_PACKET {
NV_INPUT_HEADER header;
char action;
int button;
uint8_t button;
} NV_MOUSE_BUTTON_PACKET, *PNV_MOUSE_BUTTON_PACKET;
#define PACKET_TYPE_CONTROLLER 0x18
#define C_HEADER_A 0x0000000A
#define CONTROLLER_MAGIC 0x0000000A
#define C_HEADER_B 0x1400
#define C_TAIL_A 0x0000009C
#define C_TAIL_B 0x0055
typedef struct _NV_CONTROLLER_PACKET {
NV_INPUT_HEADER header;
int headerA;
short headerB;
short buttonFlags;
unsigned char leftTrigger;
@ -86,15 +74,13 @@ typedef struct _NV_CONTROLLER_PACKET {
short tailB;
} NV_CONTROLLER_PACKET, *PNV_CONTROLLER_PACKET;
#define PACKET_TYPE_MULTI_CONTROLLER 0x1E
#define MC_HEADER_A 0x0000000D
#define MULTI_CONTROLLER_MAGIC 0x0000000D
#define MC_HEADER_B 0x001A
#define MC_MID_B 0x0014
#define MC_TAIL_A 0x0000009C
#define MC_TAIL_B 0x0055
typedef struct _NV_MULTI_CONTROLLER_PACKET {
NV_INPUT_HEADER header;
int headerA;
short headerB;
short controllerNumber;
short activeGamepadMask;
@ -110,13 +96,9 @@ typedef struct _NV_MULTI_CONTROLLER_PACKET {
short tailB;
} NV_MULTI_CONTROLLER_PACKET, *PNV_MULTI_CONTROLLER_PACKET;
#define PACKET_TYPE_SCROLL 0xA
#define MAGIC_A 0x09
#define SCROLL_MAGIC 0x00000009
typedef struct _NV_SCROLL_PACKET {
NV_INPUT_HEADER header;
char magicA;
char zero1;
short zero2;
short scrollAmt1;
short scrollAmt2;
short zero3;

View File

@ -19,6 +19,7 @@ static PLT_THREAD inputSendThread;
typedef struct _PACKET_HOLDER {
int packetLength;
union {
NV_INPUT_HEADER header;
NV_KEYBOARD_PACKET keyboard;
NV_REL_MOUSE_MOVE_PACKET mouseMoveRel;
NV_ABS_MOUSE_MOVE_PACKET mouseMoveAbs;
@ -141,6 +142,8 @@ static PPACKET_HOLDER allocatePacketHolder(void) {
static bool sendInputPacket(PPACKET_HOLDER holder) {
SOCK_RET err;
LC_ASSERT(holder->packet.header.size == BE32(holder->packetLength - sizeof(uint32_t)));
// On GFE 3.22, the entire control stream is encrypted (and support for separate RI encrypted)
// has been removed. We send the plaintext packet through and the control stream code will do
// the encryption.
@ -217,7 +220,7 @@ static void inputSendThreadProc(void* context) {
}
// If it's a multi-controller packet we can do batching
if (holder->packet.multiController.header.packetType == BE32(PACKET_TYPE_MULTI_CONTROLLER)) {
if (holder->packet.header.magic == LE32(MULTI_CONTROLLER_MAGIC)) {
PPACKET_HOLDER controllerBatchHolder;
PNV_MULTI_CONTROLLER_PACKET origPkt;
@ -231,7 +234,7 @@ static void inputSendThreadProc(void* context) {
}
// If it's not a controller packet, we're done
if (controllerBatchHolder->packet.multiController.header.packetType != BE32(PACKET_TYPE_MULTI_CONTROLLER)) {
if (controllerBatchHolder->packet.header.magic != LE32(MULTI_CONTROLLER_MAGIC)) {
break;
}
@ -266,7 +269,7 @@ static void inputSendThreadProc(void* context) {
}
}
// If it's a relative mouse move packet, we can also do batching
else if (holder->packet.mouseMoveRel.header.packetType == BE32(PACKET_TYPE_REL_MOUSE_MOVE)) {
else if (holder->packet.header.magic == LE32(MOUSE_MOVE_REL_MAGIC)) {
PPACKET_HOLDER mouseBatchHolder;
int totalDeltaX = (short)BE16(holder->packet.mouseMoveRel.deltaX);
int totalDeltaY = (short)BE16(holder->packet.mouseMoveRel.deltaY);
@ -281,7 +284,7 @@ static void inputSendThreadProc(void* context) {
}
// If it's not a mouse move packet, we're done
if (mouseBatchHolder->packet.mouseMoveRel.header.packetType != BE32(PACKET_TYPE_REL_MOUSE_MOVE)) {
if (mouseBatchHolder->packet.header.magic != LE32(MOUSE_MOVE_REL_MAGIC)) {
break;
}
@ -314,7 +317,7 @@ static void inputSendThreadProc(void* context) {
holder->packet.mouseMoveRel.deltaY = BE16((short)totalDeltaY);
}
// If it's an absolute mouse move packet, we should only send the latest
else if (holder->packet.mouseMoveAbs.header.packetType == BE32(PACKET_TYPE_ABS_MOUSE_MOVE)) {
else if (holder->packet.header.magic == LE32(MOUSE_MOVE_ABS_MAGIC)) {
for (;;) {
PPACKET_HOLDER mouseBatchHolder;
@ -324,7 +327,7 @@ static void inputSendThreadProc(void* context) {
}
// If it's not a mouse position packet, we're done
if (mouseBatchHolder->packet.mouseMoveAbs.header.packetType != BE32(PACKET_TYPE_ABS_MOUSE_MOVE)) {
if (mouseBatchHolder->packet.header.magic != LE32(MOUSE_MOVE_ABS_MAGIC)) {
break;
}
@ -366,9 +369,9 @@ static int sendEnableHaptics(void) {
}
holder->packetLength = sizeof(NV_HAPTICS_PACKET);
holder->packet.haptics.header.packetType = BE32(PACKET_TYPE_HAPTICS);
holder->packet.haptics.magicA = LE32(H_MAGIC_A);
holder->packet.haptics.magicB = LE32(H_MAGIC_B);
holder->packet.haptics.header.size = BE32(holder->packetLength - sizeof(uint32_t));
holder->packet.haptics.header.magic = LE32(ENABLE_HAPTICS_MAGIC);
holder->packet.haptics.enable = LE16(1);
err = LbqOfferQueueItem(&packetQueue, holder, &holder->entry);
if (err != LBQ_SUCCESS) {
@ -456,13 +459,13 @@ int LiSendMouseMoveEvent(short deltaX, short deltaY) {
}
holder->packetLength = sizeof(NV_REL_MOUSE_MOVE_PACKET);
holder->packet.mouseMoveRel.header.packetType = BE32(PACKET_TYPE_REL_MOUSE_MOVE);
holder->packet.mouseMoveRel.magic = MOUSE_MOVE_REL_MAGIC;
holder->packet.mouseMoveRel.header.size = BE32(holder->packetLength - sizeof(uint32_t));
holder->packet.mouseMoveRel.header.magic = MOUSE_MOVE_REL_MAGIC;
// On Gen 5 servers, the header code is incremented by one
if (AppVersionQuad[0] >= 5) {
holder->packet.mouseMoveRel.magic++;
holder->packet.mouseMoveRel.header.magic++;
}
holder->packet.mouseMoveRel.magic = LE32(holder->packet.mouseMoveRel.magic);
holder->packet.mouseMoveRel.header.magic = LE32(holder->packet.mouseMoveRel.header.magic);
holder->packet.mouseMoveRel.deltaX = BE16(deltaX);
holder->packet.mouseMoveRel.deltaY = BE16(deltaY);
@ -491,8 +494,8 @@ int LiSendMousePositionEvent(short x, short y, short referenceWidth, short refer
}
holder->packetLength = sizeof(NV_ABS_MOUSE_MOVE_PACKET);
holder->packet.mouseMoveAbs.header.packetType = BE32(PACKET_TYPE_ABS_MOUSE_MOVE);
holder->packet.mouseMoveAbs.magic = LE32(MOUSE_MOVE_ABS_MAGIC);
holder->packet.mouseMoveAbs.header.size = BE32(holder->packetLength - sizeof(uint32_t));
holder->packet.mouseMoveAbs.header.magic = LE32(MOUSE_MOVE_ABS_MAGIC);
holder->packet.mouseMoveAbs.x = BE16(x);
holder->packet.mouseMoveAbs.y = BE16(y);
holder->packet.mouseMoveAbs.unused = 0;
@ -530,12 +533,13 @@ int LiSendMouseButtonEvent(char action, int button) {
}
holder->packetLength = sizeof(NV_MOUSE_BUTTON_PACKET);
holder->packet.mouseButton.header.packetType = BE32(PACKET_TYPE_MOUSE_BUTTON);
holder->packet.mouseButton.action = action;
holder->packet.mouseButton.header.size = BE32(holder->packetLength - sizeof(uint32_t));
holder->packet.mouseButton.header.magic = (uint8_t)action;
if (AppVersionQuad[0] >= 5) {
holder->packet.mouseButton.action++;
holder->packet.mouseButton.header.magic++;
}
holder->packet.mouseButton.button = BE32(button);
holder->packet.mouseButton.header.magic = LE32(holder->packet.mouseButton.header.magic);
holder->packet.mouseButton.button = (uint8_t)button;
err = LbqOfferQueueItem(&packetQueue, holder, &holder->entry);
if (err != LBQ_SUCCESS) {
@ -604,8 +608,8 @@ int LiSendKeyboardEvent(short keyCode, char keyAction, char modifiers) {
}
holder->packetLength = sizeof(NV_KEYBOARD_PACKET);
holder->packet.keyboard.header.packetType = BE32(PACKET_TYPE_KEYBOARD);
holder->packet.keyboard.keyAction = keyAction;
holder->packet.keyboard.header.size = BE32(holder->packetLength - sizeof(uint32_t));
holder->packet.keyboard.header.magic = LE32((uint32_t)keyAction);
holder->packet.keyboard.zero1 = 0;
holder->packet.keyboard.keyCode = LE16(keyCode);
holder->packet.keyboard.modifiers = modifiers;
@ -637,10 +641,10 @@ int LiSendUtf8TextEvent(const char *text, unsigned int length) {
return -1;
}
// Size + magic + string length
holder->packetLength = 4 + 4 + length;
holder->packetLength = sizeof(uint32_t) + sizeof(uint32_t) + length;
// Magic + string length
holder->packet.unicode.size = BE32(4 + length);
holder->packet.unicode.magic = LE32(UTF8_TEXT_EVENT_MAGIC);
holder->packet.unicode.header.size = BE32(sizeof(uint32_t) + length);
holder->packet.unicode.header.magic = LE32(UTF8_TEXT_EVENT_MAGIC);
memcpy(holder->packet.unicode.text, text, length);
err = LbqOfferQueueItem(&packetQueue, holder, &holder->entry);
@ -673,8 +677,8 @@ static int sendControllerEventInternal(short controllerNumber, short activeGamep
// Generation 3 servers don't support multiple controllers so we send
// the legacy packet
holder->packetLength = sizeof(NV_CONTROLLER_PACKET);
holder->packet.controller.header.packetType = BE32(PACKET_TYPE_CONTROLLER);
holder->packet.controller.headerA = LE32(C_HEADER_A);
holder->packet.controller.header.size = BE32(holder->packetLength - sizeof(uint32_t));
holder->packet.controller.header.magic = LE32(CONTROLLER_MAGIC);
holder->packet.controller.headerB = LE16(C_HEADER_B);
holder->packet.controller.buttonFlags = LE16(buttonFlags);
holder->packet.controller.leftTrigger = leftTrigger;
@ -689,13 +693,13 @@ static int sendControllerEventInternal(short controllerNumber, short activeGamep
else {
// Generation 4+ servers support passing the controller number
holder->packetLength = sizeof(NV_MULTI_CONTROLLER_PACKET);
holder->packet.multiController.header.packetType = BE32(PACKET_TYPE_MULTI_CONTROLLER);
holder->packet.multiController.headerA = MC_HEADER_A;
holder->packet.multiController.header.size = BE32(holder->packetLength - sizeof(uint32_t));
holder->packet.multiController.header.magic = MULTI_CONTROLLER_MAGIC;
// On Gen 5 servers, the header code is decremented by one
if (AppVersionQuad[0] >= 5) {
holder->packet.multiController.headerA--;
holder->packet.multiController.header.magic--;
}
holder->packet.multiController.headerA = LE32(holder->packet.multiController.headerA);
holder->packet.multiController.header.magic = LE32(holder->packet.multiController.header.magic);
holder->packet.multiController.headerB = LE16(MC_HEADER_B);
holder->packet.multiController.controllerNumber = LE16(controllerNumber);
holder->packet.multiController.activeGamepadMask = LE16(activeGamepadMask);
@ -758,14 +762,13 @@ int LiSendHighResScrollEvent(short scrollAmount) {
}
holder->packetLength = sizeof(NV_SCROLL_PACKET);
holder->packet.scroll.header.packetType = BE32(PACKET_TYPE_SCROLL);
holder->packet.scroll.magicA = MAGIC_A;
holder->packet.scroll.header.size = BE32(holder->packetLength - sizeof(uint32_t));
holder->packet.scroll.header.magic = SCROLL_MAGIC;
// On Gen 5 servers, the header code is incremented by one
if (AppVersionQuad[0] >= 5) {
holder->packet.scroll.magicA++;
holder->packet.scroll.header.magic++;
}
holder->packet.scroll.zero1 = 0;
holder->packet.scroll.zero2 = 0;
holder->packet.scroll.header.magic = LE32(holder->packet.scroll.header.magic);
holder->packet.scroll.scrollAmt1 = BE16(scrollAmount);
holder->packet.scroll.scrollAmt2 = holder->packet.scroll.scrollAmt1;
holder->packet.scroll.zero3 = 0;