From 1beebe629c094cdafaf2d8d2da0f9f19337dc673 Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Mon, 17 Jan 2022 18:38:00 -0600 Subject: [PATCH] Server packet handling cleaned up. --- client/client.pro | 2 + client/src/login.c | 5 +- client/src/menu.c | 27 ++++ client/src/menu.h | 31 +++++ server/server.pro | 10 ++ server/src/client.c | 244 ++++------------------------------- server/src/client/login.c | 65 ++++++++++ server/src/client/login.h | 32 +++++ server/src/client/pong.c | 55 ++++++++ server/src/client/pong.h | 32 +++++ server/src/client/shutdown.c | 30 +++++ server/src/client/shutdown.h | 32 +++++ server/src/client/signup.c | 68 ++++++++++ server/src/client/signup.h | 32 +++++ server/src/client/version.c | 132 +++++++++++++++++++ server/src/client/version.h | 33 +++++ shared/packets.h | 36 ++++-- 17 files changed, 632 insertions(+), 234 deletions(-) create mode 100644 client/src/menu.c create mode 100644 client/src/menu.h create mode 100644 server/src/client/login.c create mode 100644 server/src/client/login.h create mode 100644 server/src/client/pong.c create mode 100644 server/src/client/pong.h create mode 100644 server/src/client/shutdown.c create mode 100644 server/src/client/shutdown.h create mode 100644 server/src/client/signup.c create mode 100644 server/src/client/signup.h create mode 100644 server/src/client/version.c create mode 100644 server/src/client/version.h diff --git a/client/client.pro b/client/client.pro index 3119489..d6cc631 100644 --- a/client/client.pro +++ b/client/client.pro @@ -70,6 +70,7 @@ HEADERS = \ $$SHARED/util.h \ src/gui/msgbox.h \ src/login.h \ + src/menu.h \ src/network.h \ src/runtime.h \ src/signup.h \ @@ -118,6 +119,7 @@ SOURCES = \ $$SHARED/memory.c \ src/gui/msgbox.c \ src/login.c \ + src/menu.c \ src/network.c \ src/settings.c \ src/signup.c \ diff --git a/client/src/login.c b/client/src/login.c index a3422d5..530e937 100644 --- a/client/src/login.c +++ b/client/src/login.c @@ -33,6 +33,7 @@ #include "login.h" #include "signup.h" #include "welcome.h" +#include "menu.h" static WindowT *_winLogin = NULL; @@ -47,7 +48,6 @@ static void btnCancelClick(WidgetT *widget); static void btnSignUpClick(WidgetT *widget); static void btnMsgBoxCancel(MsgBoxButtonT button); static void btnMsgBoxContinue(MsgBoxButtonT button); -static void btnMsgBoxFinish(MsgBoxButtonT button); static void setButtons(uint8_t enabled); static void taskDisconnect(void *data); static void taskLoginClick(void *data); @@ -208,9 +208,8 @@ static void taskLoginClick(void *data) { packetContentUnpack(decoded->data, "is", &success, &packetData); logWrite("Login: %d %s\n", success, packetData); if (success) { - // ***TODO*** Start Main Menu guiDelete(D(_winLogin)); - // taskCreate(taskLogin, NULL); + taskCreate(taskMenu, NULL); } else { msgBoxOne("Uh Oh!", MSGBOX_ICON_ERROR, packetData, "Okay", btnMsgBoxContinue); } diff --git a/client/src/menu.c b/client/src/menu.c new file mode 100644 index 0000000..f504656 --- /dev/null +++ b/client/src/menu.c @@ -0,0 +1,27 @@ +/* + * Kangaroo Punch MultiPlayer Game Server Mark II + * Copyright (C) 2020-2021 Scott Duensing + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +#include "menu.h" + + +void taskMenu(void *data) { + (void)data; + +} diff --git a/client/src/menu.h b/client/src/menu.h new file mode 100644 index 0000000..738a4ce --- /dev/null +++ b/client/src/menu.h @@ -0,0 +1,31 @@ +/* + * Kangaroo Punch MultiPlayer Game Server Mark II + * Copyright (C) 2020-2021 Scott Duensing + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +#ifndef MENU_H +#define MENU_H + + +#include "os.h" + + +void taskMenu(void *data); + + +#endif // MENU_H diff --git a/server/server.pro b/server/server.pro index 7edd1cf..74ecb02 100644 --- a/server/server.pro +++ b/server/server.pro @@ -50,6 +50,11 @@ HEADERS = \ $$SHARED/thirdparty/tiny-AES-c/aes.h \ $$SHARED/thirdparty/tiny-AES128-C/pkcs7_padding.h \ src/client.h \ + src/client/login.h \ + src/client/pong.h \ + src/client/shutdown.h \ + src/client/signup.h \ + src/client/version.h \ src/console.h \ src/network.h \ src/os.h \ @@ -67,6 +72,11 @@ SOURCES = \ $$SHARED/thirdparty/tiny-AES-c/aes.c \ $$SHARED/thirdparty/tiny-AES128-C/pkcs7_padding.c \ src/client.c \ + src/client/login.c \ + src/client/pong.c \ + src/client/shutdown.c \ + src/client/signup.c \ + src/client/version.c \ src/console.c \ src/main.c \ src/network.c \ diff --git a/server/src/client.c b/server/src/client.c index 4f0fd86..da5b584 100644 --- a/server/src/client.c +++ b/server/src/client.c @@ -26,9 +26,28 @@ #include "server.h" #include "rest.h" +#include "client/login.h" +#include "client/signup.h" +#include "client/pong.h" +#include "client/version.h" +#include "client/shutdown.h" + + +typedef void (*clientApi)(ClientThreadT *client, PacketDecodeDataT *data); + + +// Also update enum in packets.h! +clientApi clientApiMethod[PACKET_END_OF_SERVER_PACKETS - PACKET_END_OF_DUAL_PACKETS] = { + clientApiClientShutdown, + clientApiLogin, + clientApiPong, + clientApiSignup, + clientApiVersionBad, + clientApiVersionOkay +}; + static uint8_t clientDequeuePacket(ClientThreadT *client); -static void clientProcessPacket(ClientThreadT *client, PacketDecodeDataT *data); static uint8_t clientDequeuePacket(ClientThreadT *client) { @@ -49,7 +68,11 @@ static uint8_t clientDequeuePacket(ClientThreadT *client) { // New data or not, process anything in the queue. if (packetDecode(client->packetThreadData, &decode, data, length)) { - clientProcessPacket(client, &decode); + if ((decode.packetType > PACKET_END_OF_DUAL_PACKETS) && (decode.packetType < PACKET_END_OF_SERVER_PACKETS)) { + clientApiMethod[decode.packetType - (PACKET_END_OF_DUAL_PACKETS + 1)](client, &decode); + } else { + consoleMessageQueue("%ld: Channel %d Unknown Packet %d\n", client->threadIndex, decode.channel, decode.packetType); + } if (decode.data) DEL(decode.data); if (packet) { DEL(packet->data); @@ -63,214 +86,6 @@ static uint8_t clientDequeuePacket(ClientThreadT *client) { } -static void clientProcessPacket(ClientThreadT *client, PacketDecodeDataT *data) { - uint64_t i = 0; - uint64_t x = 0; - uint32_t y = 0; - uint16_t length = 0; - char *buffer = NULL; - char *packetData = NULL; - char *user = NULL; - char *pass = NULL; - char *first = NULL; - char *last = NULL; - char *email = NULL; - PacketEncodeDataT encoded = { 0 }; - json_object *response = NULL; - RestStringMapT *strings = NULL; - RestIntegerMapT *integers = NULL; - struct timespec timer = { 0 }; - double d = 0; - uint8_t result = 0; - char *string = NULL; - - switch (data->packetType) { - case PACKET_TYPE_CLIENT_SHUTDOWN: - serverDisconnectClient(client); - break; - - case PACKET_TYPE_LOGIN: - packetContentUnpack(data->data, "ss", &user, &pass); - response = restRequest("USER_LOGIN", "ss", - "user", user, - "pass", pass - ); - DEL(user); - DEL(pass); - if (response) { - string = (char *)json_object_get_string(json_object_object_get(response, "result")); - result = (string[0] == 't' || string[0] == 'T') ? 1 : 0; - buffer = (char *)json_object_get_string(json_object_object_get(response, "reason")); - } else { - // Something bad happened. - result = 0; - buffer = "Unknown error. Sorry."; - } - logWrite("Login: %d %s\r\n", result, buffer); - packetData = packetContentPack(&length, "is", result, buffer); - if (response) restRelease(response); - // Build packet. - encoded.control = PACKET_CONTROL_DAT; - encoded.packetType = PACKET_TYPE_LOGIN_RESULT; - encoded.channel = 0; - encoded.encrypt = 0; - packetEncode(client->packetThreadData, &encoded, packetData, length); - // Send it. - packetSend(client->packetThreadData, &encoded); - DEL(packetData); - break; - - case PACKET_TYPE_PONG: - // Time round-trip. - clock_gettime(CLOCK_MONOTONIC_RAW, &timer); - d = (timer.tv_sec - client->pingStart.tv_sec) * 1e9; - d = (d + (timer.tv_nsec - client->pingStart.tv_nsec)) * 1e-9; - client->pingStats[client->pingHead] = d; - client->pingHead++; - if (client->pingHead >= PING_STATS_SIZE) client->pingHead = 0; - // ***TODO*** Probably need a mutex here. - if (d > client->pingHigh) client->pingHigh = d; - if (d < client->pingLow) client->pingLow = d; - client->pingAverage = 0; - x = 0; - for (i=0; ipingStats[i] != 0) { - x++; - client->pingAverage += client->pingStats[i]; - } - } - client->pingAverage /= (double)x; - consoleMessageQueue("%ld: Ping: %f Low: %f Average: %f High: %f\n", client->threadIndex, d, client->pingLow, client->pingAverage, client->pingHigh); - break; - - case PACKET_TYPE_SIGNUP: - packetContentUnpack(data->data, "sssss", &email, &first, &last, &pass, &user); - response = restRequest("USER_CREATE", "sssss", - "first", first, - "last", last, - "user", user, - "pass", pass, - "email", email - ); - if (response) { - string = (char *)json_object_get_string(json_object_object_get(response, "result")); - result = (string[0] == 't' || string[0] == 'T') ? 1 : 0; - buffer = (char *)json_object_get_string(json_object_object_get(response, "reason")); - } else { - // Something bad happened. - result = 0; - buffer = "Unknown error. Sorry."; - } - packetData = packetContentPack(&length, "is", result, buffer); - if (response) restRelease(response); - // Build packet. - encoded.control = PACKET_CONTROL_DAT; - encoded.packetType = PACKET_TYPE_SIGNUP_RESULT; - encoded.channel = 0; - encoded.encrypt = 0; - packetEncode(client->packetThreadData, &encoded, packetData, length); - // Send it. - packetSend(client->packetThreadData, &encoded); - DEL(packetData); - break; - - case PACKET_TYPE_VERSION_BAD: - //***TODO*** - break; - - case PACKET_TYPE_VERSION_OKAY: - // Fetch string table from REST. - response = restRequest("CONFIG_GET_STRINGS", NULL); - if (!response) { - consoleMessageQueue("%ld: Unable to fetch strings!\n", client->threadIndex); - break; - } - strings = restHelperConfigStringMapGet(response); - if (!strings) { - consoleMessageQueue("%ld: Unable to map strings!\n", client->threadIndex); - break; - } - restRelease(response); - // Send string table to client. - for (i=0; i<(unsigned)shlen(strings); i++) { - // Strings are encoded in a single buffer as: KEY\0DATA\0 - x = strlen(strings[i].key); - y = strlen(strings[i].value); - length = x + y + 2; - buffer = (char *)malloc(length); - if (!buffer) { - consoleMessageQueue("%ld: Unable to allocate buffer for string packet!\n", client->threadIndex); - break; - } - memcpy(buffer, strings[i].key, x + 1); - memcpy(&buffer[x + 1], strings[i].value, y + 1); - //consoleMessageQueue("[%s]=[%s]\n", strings[i].key, strings[i].value); - // Build packet. - encoded.control = PACKET_CONTROL_DAT; - encoded.packetType = PACKET_TYPE_STRING; - encoded.channel = 0; - encoded.encrypt = 0; - packetEncode(client->packetThreadData, &encoded, buffer, length); - // Send it. - packetSend(client->packetThreadData, &encoded); - DEL(buffer); - } - restHelperConfigStringMapRelease(strings); - // Fetch number table from REST. - response = restRequest("CONFIG_GET_NUMBERS", NULL); - if (!response) { - consoleMessageQueue("%ld: Unable to fetch numbers!\n", client->threadIndex); - break; - } - integers = restHelperConfigIntegerMapGet(response); - if (!integers) { - consoleMessageQueue("%ld: Unable to map numbers!\n", client->threadIndex); - break; - } - restRelease(response); - // Send number table to client. - for (i=0; i<(unsigned)shlen(integers); i++) { - // Integers are encoded in a single buffer as: 1234DATA\0 - // Integers are 64 bit until sent to the client when they are truncated to 32. - x = strlen(integers[i].key); - y = integers[i].value; // 64->32 - length = x + 5; - buffer = (char *)malloc(length); - if (!buffer) { - consoleMessageQueue("%ld: Unable to allocate buffer for number packet!\n\r", client->threadIndex); - break; - } - memcpy(buffer, &y, 4); - memcpy(&buffer[4], integers[i].key, x + 1); - // Build packet. - encoded.control = PACKET_CONTROL_DAT; - encoded.packetType = PACKET_TYPE_NUMBER; - encoded.channel = 0; - encoded.encrypt = 0; - packetEncode(client->packetThreadData, &encoded, buffer, length); - // Send it. - packetSend(client->packetThreadData, &encoded); - DEL(buffer); - //logWrite("[%s] = [%d]\r\n", integers[i].key, integers[i].value); - } - restHelperConfigIntegerMapRelease(integers); - // Build PROCEED packet. - encoded.control = PACKET_CONTROL_DAT; - encoded.packetType = PACKET_TYPE_PROCEED; - encoded.channel = 0; - encoded.encrypt = 0; - packetEncode(client->packetThreadData, &encoded, NULL, 0); - // Send it. - packetSend(client->packetThreadData, &encoded); - break; - - default: - consoleMessageQueue("%ld: Channel %d Unknown Packet %d\n", client->threadIndex, data->channel, data->packetType); - break; - } -} - - void clientQueuePacket(ClientThreadT *client, uint8_t *data, uint32_t length) { ClientRawPacketT *packet = NULL; @@ -281,15 +96,6 @@ void clientQueuePacket(ClientThreadT *client, uint8_t *data, uint32_t length) { memcpy(packet->data, data, length); packet->length = length; } - - //consoleMessageQueue("%ld: Channel %d Bytes in %d\n", client->threadIndex, length); - /* - logWrite("Bytes %d\n\r", length); - for (size_t x=0; xpacketQueueMutex); arrput(client->packetQueue, packet); pthread_mutex_unlock(&client->packetQueueMutex); diff --git a/server/src/client/login.c b/server/src/client/login.c new file mode 100644 index 0000000..6dc221d --- /dev/null +++ b/server/src/client/login.c @@ -0,0 +1,65 @@ +/* + * Kangaroo Punch MultiPlayer Game Server Mark II + * Copyright (C) 2020-2021 Scott Duensing + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +#include "rest.h" + +#include "login.h" + + +void clientApiLogin(ClientThreadT *client, PacketDecodeDataT *data) { + char *packetData = NULL; + char *user = NULL; + char *pass = NULL; + PacketEncodeDataT encoded = { 0 }; + json_object *response = NULL; + uint8_t result = 0; + char *string = NULL; + char *buffer = NULL; + uint16_t length = 0; + + packetContentUnpack(data->data, "ss", &user, &pass); + response = restRequest("USER_LOGIN", "ss", + "user", user, + "pass", pass + ); + DEL(user); + DEL(pass); + if (response) { + string = (char *)json_object_get_string(json_object_object_get(response, "result")); + result = (string[0] == 't' || string[0] == 'T') ? 1 : 0; + buffer = (char *)json_object_get_string(json_object_object_get(response, "reason")); + } else { + // Something bad happened. + result = 0; + buffer = "Unknown error. Sorry."; + } + logWrite("Login: %d %s\r\n", result, buffer); + packetData = packetContentPack(&length, "is", result, buffer); + if (response) restRelease(response); + // Build packet. + encoded.control = PACKET_CONTROL_DAT; + encoded.packetType = PACKET_TYPE_LOGIN_RESULT; + encoded.channel = 0; + encoded.encrypt = 0; + packetEncode(client->packetThreadData, &encoded, packetData, length); + // Send it. + packetSend(client->packetThreadData, &encoded); + DEL(packetData); +} diff --git a/server/src/client/login.h b/server/src/client/login.h new file mode 100644 index 0000000..f4d4dd2 --- /dev/null +++ b/server/src/client/login.h @@ -0,0 +1,32 @@ +/* + * Kangaroo Punch MultiPlayer Game Server Mark II + * Copyright (C) 2020-2021 Scott Duensing + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +#ifndef LOGIN_H +#define LOGIN_H + + +#include "os.h" +#include "client.h" + + +void clientApiLogin(ClientThreadT *client, PacketDecodeDataT *data); + + +#endif // LOGIN_H diff --git a/server/src/client/pong.c b/server/src/client/pong.c new file mode 100644 index 0000000..ab15435 --- /dev/null +++ b/server/src/client/pong.c @@ -0,0 +1,55 @@ +/* + * Kangaroo Punch MultiPlayer Game Server Mark II + * Copyright (C) 2020-2021 Scott Duensing + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +#include "console.h" + +#include "pong.h" + + +void clientApiPong(ClientThreadT *client, PacketDecodeDataT *data) { + struct timespec timer = { 0 }; + double d = 0; + uint64_t i = 0; + uint64_t x = 0; + + (void)data; + + // Time round-trip. + clock_gettime(CLOCK_MONOTONIC_RAW, &timer); + d = (timer.tv_sec - client->pingStart.tv_sec) * 1e9; + d = (d + (timer.tv_nsec - client->pingStart.tv_nsec)) * 1e-9; + client->pingStats[client->pingHead] = d; + client->pingHead++; + if (client->pingHead >= PING_STATS_SIZE) client->pingHead = 0; + // ***TODO*** Probably need a mutex here. + if (d > client->pingHigh) client->pingHigh = d; + if (d < client->pingLow) client->pingLow = d; + client->pingAverage = 0; + x = 0; + for (i=0; ipingStats[i] != 0) { + x++; + client->pingAverage += client->pingStats[i]; + } + } + client->pingAverage /= (double)x; + + consoleMessageQueue("%ld: Ping: %f Low: %f Average: %f High: %f\n", client->threadIndex, d, client->pingLow, client->pingAverage, client->pingHigh); +} diff --git a/server/src/client/pong.h b/server/src/client/pong.h new file mode 100644 index 0000000..4719ae2 --- /dev/null +++ b/server/src/client/pong.h @@ -0,0 +1,32 @@ +/* + * Kangaroo Punch MultiPlayer Game Server Mark II + * Copyright (C) 2020-2021 Scott Duensing + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +#ifndef PONG_H +#define PONG_H + + +#include "os.h" +#include "client.h" + + +void clientApiPong(ClientThreadT *client, PacketDecodeDataT *data); + + +#endif // PONG_H diff --git a/server/src/client/shutdown.c b/server/src/client/shutdown.c new file mode 100644 index 0000000..300c88e --- /dev/null +++ b/server/src/client/shutdown.c @@ -0,0 +1,30 @@ +/* + * Kangaroo Punch MultiPlayer Game Server Mark II + * Copyright (C) 2020-2021 Scott Duensing + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +#include "server.h" + +#include "shutdown.h" + + +void clientApiClientShutdown(ClientThreadT *client, PacketDecodeDataT *data) { + (void)data; + + serverDisconnectClient(client); +} diff --git a/server/src/client/shutdown.h b/server/src/client/shutdown.h new file mode 100644 index 0000000..e242985 --- /dev/null +++ b/server/src/client/shutdown.h @@ -0,0 +1,32 @@ +/* + * Kangaroo Punch MultiPlayer Game Server Mark II + * Copyright (C) 2020-2021 Scott Duensing + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +#ifndef SHUTDOWN_H +#define SHUTDOWN_H + + +#include "os.h" +#include "client.h" + + +void clientApiClientShutdown(ClientThreadT *client, PacketDecodeDataT *data); + + +#endif // SHUTDOWN_H diff --git a/server/src/client/signup.c b/server/src/client/signup.c new file mode 100644 index 0000000..8d41f3e --- /dev/null +++ b/server/src/client/signup.c @@ -0,0 +1,68 @@ +/* + * Kangaroo Punch MultiPlayer Game Server Mark II + * Copyright (C) 2020-2021 Scott Duensing + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +#include "rest.h" + +#include "signup.h" + + +void clientApiSignup(ClientThreadT *client, PacketDecodeDataT *data) { + json_object *response = NULL; + char *user = NULL; + char *pass = NULL; + char *first = NULL; + char *last = NULL; + char *email = NULL; + uint8_t result = 0; + char *string = NULL; + char *buffer = NULL; + char *packetData = NULL; + PacketEncodeDataT encoded = { 0 }; + uint16_t length = 0; + + packetContentUnpack(data->data, "sssss", &email, &first, &last, &pass, &user); + response = restRequest("USER_CREATE", "sssss", + "first", first, + "last", last, + "user", user, + "pass", pass, + "email", email + ); + if (response) { + string = (char *)json_object_get_string(json_object_object_get(response, "result")); + result = (string[0] == 't' || string[0] == 'T') ? 1 : 0; + buffer = (char *)json_object_get_string(json_object_object_get(response, "reason")); + } else { + // Something bad happened. + result = 0; + buffer = "Unknown error. Sorry."; + } + packetData = packetContentPack(&length, "is", result, buffer); + if (response) restRelease(response); + // Build packet. + encoded.control = PACKET_CONTROL_DAT; + encoded.packetType = PACKET_TYPE_SIGNUP_RESULT; + encoded.channel = 0; + encoded.encrypt = 0; + packetEncode(client->packetThreadData, &encoded, packetData, length); + // Send it. + packetSend(client->packetThreadData, &encoded); + DEL(packetData); +} diff --git a/server/src/client/signup.h b/server/src/client/signup.h new file mode 100644 index 0000000..c30f844 --- /dev/null +++ b/server/src/client/signup.h @@ -0,0 +1,32 @@ +/* + * Kangaroo Punch MultiPlayer Game Server Mark II + * Copyright (C) 2020-2021 Scott Duensing + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +#ifndef SIGNUP_H +#define SIGNUP_H + + +#include "os.h" +#include "client.h" + + +void clientApiSignup(ClientThreadT *client, PacketDecodeDataT *data); + + +#endif // SIGNUP_H diff --git a/server/src/client/version.c b/server/src/client/version.c new file mode 100644 index 0000000..3558f32 --- /dev/null +++ b/server/src/client/version.c @@ -0,0 +1,132 @@ +/* + * Kangaroo Punch MultiPlayer Game Server Mark II + * Copyright (C) 2020-2021 Scott Duensing + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +#include "rest.h" +#include "console.h" +#include "array.h" + +#include "version.h" + + +void clientApiVersionBad(ClientThreadT *client, PacketDecodeDataT *data) { + // ***TODO*** +} + + +void clientApiVersionOkay(ClientThreadT *client, PacketDecodeDataT *data) { + json_object *response = NULL; + RestStringMapT *strings = NULL; + RestIntegerMapT *integers = NULL; + uint64_t i = 0; + uint64_t x = 0; + uint32_t y = 0; + uint16_t length = 0; + char *buffer = NULL; + PacketEncodeDataT encoded = { 0 }; + + (void)data; + + // Fetch string table from REST. + response = restRequest("CONFIG_GET_STRINGS", NULL); + if (!response) { + consoleMessageQueue("%ld: Unable to fetch strings!\n", client->threadIndex); + return; + } + strings = restHelperConfigStringMapGet(response); + if (!strings) { + consoleMessageQueue("%ld: Unable to map strings!\n", client->threadIndex); + return; + } + restRelease(response); + + // Send string table to client. + for (i=0; i<(unsigned)shlen(strings); i++) { + // Strings are encoded in a single buffer as: KEY\0DATA\0 + x = strlen(strings[i].key); + y = strlen(strings[i].value); + length = x + y + 2; + buffer = (char *)malloc(length); + if (!buffer) { + consoleMessageQueue("%ld: Unable to allocate buffer for string packet!\n", client->threadIndex); + break; + } + memcpy(buffer, strings[i].key, x + 1); + memcpy(&buffer[x + 1], strings[i].value, y + 1); + // Build packet. + encoded.control = PACKET_CONTROL_DAT; + encoded.packetType = PACKET_TYPE_STRING; + encoded.channel = 0; + encoded.encrypt = 0; + packetEncode(client->packetThreadData, &encoded, buffer, length); + // Send it. + packetSend(client->packetThreadData, &encoded); + DEL(buffer); + } + restHelperConfigStringMapRelease(strings); + + // Fetch number table from REST. + response = restRequest("CONFIG_GET_NUMBERS", NULL); + if (!response) { + consoleMessageQueue("%ld: Unable to fetch numbers!\n", client->threadIndex); + return; + } + integers = restHelperConfigIntegerMapGet(response); + if (!integers) { + consoleMessageQueue("%ld: Unable to map numbers!\n", client->threadIndex); + return; + } + restRelease(response); + + // Send number table to client. + for (i=0; i<(unsigned)shlen(integers); i++) { + // Integers are encoded in a single buffer as: 1234DATA\0 + // Integers are 64 bit until sent to the client when they are truncated to 32. + x = strlen(integers[i].key); + y = integers[i].value; // 64->32 + length = x + 5; + buffer = (char *)malloc(length); + if (!buffer) { + consoleMessageQueue("%ld: Unable to allocate buffer for number packet!\n\r", client->threadIndex); + break; + } + memcpy(buffer, &y, 4); + memcpy(&buffer[4], integers[i].key, x + 1); + // Build packet. + encoded.control = PACKET_CONTROL_DAT; + encoded.packetType = PACKET_TYPE_NUMBER; + encoded.channel = 0; + encoded.encrypt = 0; + packetEncode(client->packetThreadData, &encoded, buffer, length); + // Send it. + packetSend(client->packetThreadData, &encoded); + DEL(buffer); + } + restHelperConfigIntegerMapRelease(integers); + + // Build PROCEED packet. + encoded.control = PACKET_CONTROL_DAT; + encoded.packetType = PACKET_TYPE_PROCEED; + encoded.channel = 0; + encoded.encrypt = 0; + packetEncode(client->packetThreadData, &encoded, NULL, 0); + // Send it. + packetSend(client->packetThreadData, &encoded); + +} diff --git a/server/src/client/version.h b/server/src/client/version.h new file mode 100644 index 0000000..6de6e20 --- /dev/null +++ b/server/src/client/version.h @@ -0,0 +1,33 @@ +/* + * Kangaroo Punch MultiPlayer Game Server Mark II + * Copyright (C) 2020-2021 Scott Duensing + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +#ifndef VERSION_H +#define VERSION_H + + +#include "os.h" +#include "client.h" + + +void clientApiVersionBad(ClientThreadT *client, PacketDecodeDataT *data); +void clientApiVersionOkay(ClientThreadT *client, PacketDecodeDataT *data); + + +#endif // VERSION_H diff --git a/shared/packets.h b/shared/packets.h index cd6bf9e..9bf55db 100644 --- a/shared/packets.h +++ b/shared/packets.h @@ -29,24 +29,36 @@ // This enum is treated as BYTES in the code. Do not go over 255 entries. +// Also update array in client.c! typedef enum PacketTypeE { + // Packets that can received by both server and client: PACKET_TYPE_NONE = 0, // No packet. - PACKET_TYPE_PING, - PACKET_TYPE_PONG, - PACKET_TYPE_SERVER_SHUTDOWN, - PACKET_TYPE_CLIENT_SHUTDOWN, PACKET_TYPE_DH_REQUEST, PACKET_TYPE_DH_RESPONSE, - PACKET_TYPE_VERSION, - PACKET_TYPE_VERSION_OKAY, - PACKET_TYPE_VERSION_BAD, - PACKET_TYPE_STRING, - PACKET_TYPE_NUMBER, - PACKET_TYPE_PROCEED, - PACKET_TYPE_SIGNUP, - PACKET_TYPE_SIGNUP_RESULT, + + PACKET_END_OF_DUAL_PACKETS, + + // Packets received by only the server: + PACKET_TYPE_CLIENT_SHUTDOWN, PACKET_TYPE_LOGIN, + PACKET_TYPE_PONG, + PACKET_TYPE_SIGNUP, + PACKET_TYPE_VERSION_BAD, + PACKET_TYPE_VERSION_OKAY, + + PACKET_END_OF_SERVER_PACKETS, + + // Packets received by only the client: PACKET_TYPE_LOGIN_RESULT, + PACKET_TYPE_NUMBER, + PACKET_TYPE_PING, + PACKET_TYPE_PROCEED, + PACKET_TYPE_SERVER_SHUTDOWN, + PACKET_TYPE_SIGNUP_RESULT, + PACKET_TYPE_STRING, + PACKET_TYPE_VERSION, + + // How many packet types do we recognize? PACKET_TYPE_COUNT } PacketTypeT;