diff --git a/LICENSE b/LICENSE
index 4a316bf..e85ff7d 100644
--- a/LICENSE
+++ b/LICENSE
@@ -95,11 +95,26 @@ ENet
https://github.com/zpl-c/enet
MIT
+GnuTLS
+------
+https://gnutls.org/
+LGPL 2.1
+
ini
---
https://github.com/rxi/ini
MIT
+json-c
+------
+https://github.com/json-c/json-c
+Attribution
+
+MariaDB Client Library
+----------------------
+https://mariadb.org/
+LGPL 2.1
+
MemWatch
--------
http://www.linkdata.se/sourcecode/memwatch/
@@ -119,3 +134,4 @@ tiny-AES128-C
-------------
https://github.com/bonybrown/tiny-AES128-C
Unlicense
+
diff --git a/kanga.world/site/plugins/kangaworld-integration/api.php b/kanga.world/site/plugins/kangaworld-integration/api.php
index 0028c2b..719c7c2 100644
--- a/kanga.world/site/plugins/kangaworld-integration/api.php
+++ b/kanga.world/site/plugins/kangaworld-integration/api.php
@@ -1,6 +1,7 @@
filterBy('type', 'config');
+ $response['result'] = 'true';
+ $response['reason'] = 'Configuration entries returned.';
+}
+
+?>
diff --git a/kanga.world/site/plugins/kangaworld-integration/user.php b/kanga.world/site/plugins/kangaworld-integration/api/user.php
similarity index 100%
rename from kanga.world/site/plugins/kangaworld-integration/user.php
rename to kanga.world/site/plugins/kangaworld-integration/api/user.php
diff --git a/kanga.world/site/plugins/kangaworld-integration/areas.php b/kanga.world/site/plugins/kangaworld-integration/areas.php
index d474bf3..bd86b07 100644
--- a/kanga.world/site/plugins/kangaworld-integration/areas.php
+++ b/kanga.world/site/plugins/kangaworld-integration/areas.php
@@ -1,8 +1,5 @@
__DIR__ . '/classes/KwConfig.php']);
-
-
return [
'kwconfig' => [
diff --git a/kanga.world/site/plugins/kangaworld-integration/collections.php b/kanga.world/site/plugins/kangaworld-integration/collections.php
new file mode 100644
index 0000000..6d782ed
--- /dev/null
+++ b/kanga.world/site/plugins/kangaworld-integration/collections.php
@@ -0,0 +1,11 @@
+ function($site) {
+ return new Collection(KwConfig::list());
+ }
+];
+
+?>
diff --git a/kanga.world/site/plugins/kangaworld-integration/index.php b/kanga.world/site/plugins/kangaworld-integration/index.php
index cd7b56b..250f073 100644
--- a/kanga.world/site/plugins/kangaworld-integration/index.php
+++ b/kanga.world/site/plugins/kangaworld-integration/index.php
@@ -1,9 +1,15 @@
__DIR__ . '/classes/KwConfig.php'
+]);
+
+
Kirby::plugin('kangaroopunch/kangaworld-integration', [
- 'api' => require __DIR__ . '/api.php',
- 'areas' => require __DIR__ . '/areas.php'
+ 'api' => require __DIR__ . '/api.php',
+ 'areas' => require __DIR__ . '/areas.php',
+ 'collections' => require __DIR__ . '/collections.php'
]);
diff --git a/kpmpgsmkii.pro b/kpmpgsmkii.pro
index 00ff9fd..197a241 100644
--- a/kpmpgsmkii.pro
+++ b/kpmpgsmkii.pro
@@ -20,7 +20,7 @@ TEMPLATE = subdirs
CONFIG *= ORDERED
SUBDIRS = \
- client \
+# client \
server
# font \
# primes
diff --git a/server/server.pro b/server/server.pro
index 3facf9a..7edd1cf 100644
--- a/server/server.pro
+++ b/server/server.pro
@@ -51,9 +51,9 @@ HEADERS = \
$$SHARED/thirdparty/tiny-AES128-C/pkcs7_padding.h \
src/client.h \
src/console.h \
- src/database.h \
src/network.h \
src/os.h \
+ src/rest.h \
src/server.h
SOURCES = \
@@ -68,18 +68,19 @@ SOURCES = \
$$SHARED/thirdparty/tiny-AES128-C/pkcs7_padding.c \
src/client.c \
src/console.c \
- src/database.c \
src/main.c \
src/network.c \
+ src/rest.c \
src/server.c
LIBS = \
-L/usr/lib/x86_64-linux-gnu/ \
- -lmariadb \
-ldl \
-lm \
-lpthread \
-lgnutls \
- -lcrypt
+ -lcrypt \
+ -lcurl \
+ -ljson-c
OTHER_FILES =
diff --git a/server/src/database.c b/server/src/database.c
deleted file mode 100644
index 75c76e8..0000000
--- a/server/src/database.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * 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
-#include
-
-#include "database.h"
-
-
-#define STATEMENT_MAX 2048
-
-
-static MYSQL *_sql = NULL;
-static char _statement[STATEMENT_MAX];
-static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER;
-
-
-uint8_t dbConnect(char *host, uint16_t port, char *database, char *user, char *password) {
- uint8_t reconnect = 1;
-
- if (_sql == NULL) {
- _sql = mysql_init(NULL);
- mysql_options(_sql, MYSQL_OPT_RECONNECT, (const void *)&reconnect);
- if (mysql_real_connect(_sql, host, user, password, database, port, NULL, 0) == NULL) {
- logWrite("dbConnect: %s\n", mysql_error(_sql));
- return FAIL;
- }
- if (pthread_mutex_init(&_mutex, NULL)) {
- logWrite("dbConnect: SQL mutex creation failed.\n");
- return FAIL;
- }
- return SUCCESS;
- }
- return FAIL;
-}
-
-
-uint8_t dbDisconnect(void) {
- if (_sql) {
- mysql_close(_sql);
- _sql = NULL;
- pthread_mutex_destroy(&_mutex);
- return SUCCESS;
- }
-
- return FAIL;
-}
-
-
-uint8_t dbSettingsValueGet(char *key, int32_t *value) {
- char *p = _statement;
- MYSQL_RES *result = NULL;
- MYSQL_ROW row;
- int count;
-
- pthread_mutex_lock(&_mutex);
-
- if (!_sql) {
- pthread_mutex_unlock(&_mutex);
- return FAIL;
- }
-
- p += sprintf(p, "SELECT data FROM config where NAME='");
- p += mysql_real_escape_string(_sql, p, key, strlen(key));
- p += sprintf(p, "'");
- if (mysql_real_query(_sql, _statement, p - _statement) != 0) {
- logWrite("dbConfigValueGet: %s\n", mysql_error(_sql));
- pthread_mutex_unlock(&_mutex);
- return FAIL;
- }
-
- result = mysql_store_result(_sql);
- count = mysql_num_rows(result);
- if (count != 1) {
- logWrite("dbConfigValueGet: Too many rows returned: %d.\n", count);
- mysql_free_result(result);
- pthread_mutex_unlock(&_mutex);
- return FAIL;
- }
-
- if ((row = mysql_fetch_row(result)) == NULL) {
- logWrite("dbConfigValueGet: %s\n", mysql_error(_sql));
- pthread_mutex_unlock(&_mutex);
- return FAIL;
- }
-
- *value = atoi(row[0]);
-
- mysql_free_result(result);
-
- pthread_mutex_unlock(&_mutex);
-
- return SUCCESS;
-}
diff --git a/server/src/main.c b/server/src/main.c
index 045ee08..aa6e579 100644
--- a/server/src/main.c
+++ b/server/src/main.c
@@ -20,9 +20,9 @@
#include "os.h"
#include "console.h"
-#include "database.h"
#include "stddclmr.h"
#include "server.h"
+#include "rest.h"
#include "thirdparty/ini/src/ini.h"
@@ -32,11 +32,9 @@ uint8_t _running = 1; // Exported in os.h
// "Config" items come from the INI file. "Settings" are from the database.
-static char *_configServer = NULL;
-static uint16_t _configPort = 0;
-static char *_configDatabase = NULL;
static char *_configUser = NULL;
static char *_configPassword = NULL;
+static char *_configREST = NULL;
static void configRead(char *file);
@@ -46,24 +44,18 @@ static void configWrite(char *file);
static void configRead(char *file) {
ini_t *ini = NULL;
- // Numeric defaults.
- _configPort = 16550;
-
ini = ini_load(file);
if (ini) {
- ini_sget(ini, "SERVER", "PORT", "%d", &_configPort);
- _configServer = strdup(ini_get(ini, "SERVER", "HOST"));
- _configDatabase = strdup(ini_get(ini, "SERVER", "DATA"));
_configUser = strdup(ini_get(ini, "SERVER", "USER"));
_configPassword = strdup(ini_get(ini, "SERVER", "PASS"));
+ _configREST = strdup(ini_get(ini, "SERVER", "REST"));
ini_free(ini);
}
// String defaults.
- if (!_configServer) strdup("kanga.world");
- if (!_configDatabase) strdup("kpmpgsmkii");
if (!_configUser) strdup("");
if (!_configPassword) strdup("");
+ if (!_configREST) strdup("http://localhost:8000/api/kp/kangaworld/v1");
}
@@ -74,22 +66,17 @@ static void configWrite(char *file) {
if (out) {
fprintf(out,
"[SERVER]\n"
- "HOST=%s\n"
- "PORT=%d\n"
- "DATA=%s\n"
+ "REST=%s\n"
"USER=%s\n"
"PASS=%s\n",
- _configServer,
- _configPort,
- _configDatabase,
+ _configREST,
_configUser,
_configPassword
);
fclose(out);
}
- DEL(_configServer);
- DEL(_configDatabase);
+ DEL(_configREST);
DEL(_configUser);
DEL(_configPassword);
}
@@ -98,9 +85,10 @@ static void configWrite(char *file) {
int main(int argc, char *argv[]) {
char *configFile = NULL;
- uint32_t settingsMaxClients = 0;
- uint32_t settingsPortNumber = 0;
- uint32_t settingsClientVersion = 0;
+ int64_t settingsMaxClients = 0;
+ int64_t settingsPortNumber = 0;
+ int64_t settingsClientVersion = 0;
+ json_object *response = NULL;
(void)argc;
@@ -111,14 +99,15 @@ int main(int argc, char *argv[]) {
configFile = utilAppNameWithNewExtensionGet(argv[0], "ini");
configRead(configFile);
- if (!dbConnect(_configServer, _configPort, _configDatabase, _configUser, _configPassword)) {
- utilDie("Unable to connect to database.\n");
+ if (!restStartup(_configREST, _configUser, _configPassword)) {
+ utilDie("Unable to start REST.\n");
}
- // Fetch settings needed to start server.
- if (!dbSettingsValueGet("maxClients", (int32_t *)&settingsMaxClients)) utilDie("Unable to load maxClients.\n");
- if (!dbSettingsValueGet("portNumber", (int32_t *)&settingsPortNumber)) utilDie("Unable to load portNumber.\n");
- if (!dbSettingsValueGet("clientVersion", (int32_t *)&settingsClientVersion)) utilDie("Unable to load clientVersion.\n");
+ response = restRequest("CONFIG_GET_CONFIG", NULL);
+ settingsMaxClients = restHelperConfigIntegerGet(response, "maxClients", 2);
+ settingsPortNumber = restHelperConfigIntegerGet(response, "portNumber", 16550);
+ settingsClientVersion = restHelperConfigIntegerGet(response, "clientVersion", 1);
+ restRelease(response);
serverStartup(settingsPortNumber, settingsMaxClients);
logWrite("Server online.\n");
@@ -134,7 +123,7 @@ int main(int argc, char *argv[]) {
serverShutdown();
// Shut down.
- dbDisconnect();
+ restShutdown();
configWrite(configFile);
DEL(configFile);
logWrite("Shutdown complete.\n");
diff --git a/server/src/rest.c b/server/src/rest.c
new file mode 100644
index 0000000..0a9d2c1
--- /dev/null
+++ b/server/src/rest.c
@@ -0,0 +1,259 @@
+/*
+ * 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
+#include
+#include
+
+#include "os.h"
+#include "rest.h"
+
+
+typedef struct RestResponseS {
+ uint64_t length;
+ char *data;
+} RestResponseT;
+
+
+static char *_restURL = NULL;
+static char *_restUser = NULL;
+static char *_restPass = NULL;
+static pthread_mutex_t *_restMutexBuffer = NULL;
+
+
+static void restMutexLocker(int mode, int n, const char *file, int line);
+static size_t restResponseWrite(void *ptr, size_t size, size_t nmemb, RestResponseT *s);
+static unsigned long restThreadtIdGet(void);
+static json_object *restUrlPost(json_object *request);
+
+
+int64_t restHelperConfigIntegerGet(json_object *object, char *name, int64_t defaultValue) {
+ uint64_t i = 0;
+ json_object *config = NULL;
+ json_object *data = NULL;
+ json_object *item = NULL;
+ int64_t result = defaultValue;
+
+ config = json_object_object_get(object, "config");
+ //logWrite("Config: %d %s\n", json_object_get_type(config), json_object_to_json_string_ext(config, JSON_C_TO_STRING_PRETTY));
+ if (config) {
+ data = json_object_object_get(config, "data");
+ //logWrite("Data: %d %s\n", json_object_get_type(data), json_object_to_json_string_ext(data, JSON_C_TO_STRING_PRETTY));
+ if (data) {
+ for (i=0; ilength + size * nmemb;
+
+ s->data = realloc(s->data, newLength + 1);
+ if (s->data == NULL) {
+ utilDie("restResponseWrite: realloc() failed.\n");
+ }
+ memcpy(s->data + s->length, ptr, size*nmemb);
+ s->data[newLength] = 0;
+ s->length = newLength;
+
+ return size * nmemb;
+}
+
+
+void restShutdown(void) {
+ uint64_t i;
+
+ DEL(_restPass);
+ DEL(_restUser);
+ DEL(_restURL);
+
+ if (_restMutexBuffer) {
+ CRYPTO_set_id_callback(NULL);
+ CRYPTO_set_locking_callback(NULL);
+ for (i=0; i
-uint8_t dbConnect(char *host, uint16_t port, char *database, char *user, char *password);
-uint8_t dbDisconnect(void);
-uint8_t dbSettingsValueGet(char *key, int32_t *value);
+int64_t restHelperConfigIntegerGet(json_object *object, char *name, int64_t defaultValue);
+void restRelease(json_object *object);
+json_object *restRequest(char *command, char *format, ...);
+void restShutdown(void);
+uint8_t restStartup(char *url, char *user, char *password);
-#endif // DATABASE_H
+#endif // REST_H