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;