From 1d7dc89a8af2e358a02faf13e0b1b4f3ea6e9db8 Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Sun, 21 Nov 2021 21:22:15 -0600 Subject: [PATCH] Start of server configuration code. --- client/src/config.c | 4 +- client/src/system/os.h | 3 ++ kpmpgsmkii.pro | 4 +- server/database.h | 33 ++++++++++++ server/os.h | 7 +++ server/server.pro | 17 ++++++- server/src/database.c | 108 +++++++++++++++++++++++++++++++++++++++ server/src/main.c | 112 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 282 insertions(+), 6 deletions(-) create mode 100644 server/database.h create mode 100644 server/src/database.c diff --git a/client/src/config.c b/client/src/config.c index cdc4272..60e2b19 100644 --- a/client/src/config.c +++ b/client/src/config.c @@ -92,6 +92,6 @@ void configStartup(char *file) { } // String defaults. - if (!_configData.serverHost) _configData.serverHost = strdup("\"kanga.world\""); - if (!_configData.userName) _configData.userName = strdup("\"New User\""); + if (!_configData.serverHost) _configData.serverHost = strdup("kanga.world"); + if (!_configData.userName) _configData.userName = strdup("New User"); } diff --git a/client/src/system/os.h b/client/src/system/os.h index 25df85c..f3ab0bf 100644 --- a/client/src/system/os.h +++ b/client/src/system/os.h @@ -22,6 +22,9 @@ #define OS_H +// https://sourceforge.net/p/predef/wiki/Architectures/ + + // Common platform includes. #include #include diff --git a/kpmpgsmkii.pro b/kpmpgsmkii.pro index 9b042d4..05bbb6a 100644 --- a/kpmpgsmkii.pro +++ b/kpmpgsmkii.pro @@ -20,6 +20,6 @@ TEMPLATE = subdirs CONFIG *= ORDERED SUBDIRS = \ - font \ - client \ +# font \ +# client \ server diff --git a/server/database.h b/server/database.h new file mode 100644 index 0000000..d57daa9 --- /dev/null +++ b/server/database.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 DATABASE_H +#define DATABASE_H + + +#include "os.h" + + +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); + + +#endif // DATABASE_H diff --git a/server/os.h b/server/os.h index 6d42ae2..c86080a 100644 --- a/server/os.h +++ b/server/os.h @@ -37,5 +37,12 @@ // Now our headers. #include "log.h" +// Allocation helpers. +#define NEW(t,v) (v)=(t*)malloc(sizeof(t)) +#define DEL(v) free(v); v=NULL + +#define SUCCESS 1 +#define FAIL 0 + #endif // OS_H diff --git a/server/server.pro b/server/server.pro index d5d83a0..b357b78 100644 --- a/server/server.pro +++ b/server/server.pro @@ -17,13 +17,16 @@ # -TEMPLATE = app -CONFIG -= qt +TEMPLATE = app +CONFIG -= qt +CONFIG += c11 DESTDIR = $$OUT_PWD/bin SHARED = $$PWD/../shared INCLUDEPATH += \ + /usr/include/mariadb \ + /usr/include/mariadb/mysql \ $$SHARED \ $$PWD/src @@ -37,6 +40,7 @@ HEADERS = \ $$SHARED/log.h \ $$SHARED/memory.h \ $$SHARED/util.h \ + database.h \ os.h SOURCES = \ @@ -47,6 +51,15 @@ SOURCES = \ $$SHARED/log.c \ $$SHARED/memory.c \ $$SHARED/util.c \ + src/database.c \ src/main.c +LIBS = \ + -L/usr/lib/x86_64-linux-gnu/ \ + -lmariadb \ + -ldl \ + -lm \ + -lpthread \ + -lgnutls + OTHER_FILES = diff --git a/server/src/database.c b/server/src/database.c new file mode 100644 index 0000000..8826aae --- /dev/null +++ b/server/src/database.c @@ -0,0 +1,108 @@ +/* + * 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) { + if (_sql == NULL) { + _sql = mysql_init(NULL); + 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 7fef177..c32aa32 100644 --- a/server/src/main.c +++ b/server/src/main.c @@ -20,20 +20,132 @@ #include "os.h" #include "util.h" +#include "stddclmr.h" +#include "thirdparty/ini/src/ini.h" +#include "database.h" +#include "array.h" + + +typedef struct HashValueS { + char *string; + int32_t integer; +} HashValueT; + +typedef struct HashMapS { + char *key; + HashValueT value; +} HashMapT; + + +static char *_configServer = NULL; +static uint16_t _configPort = 0; +static char *_configDatabase = NULL; +static char *_configUser = NULL; +static char *_configPassword = NULL; + +static HashMapT *_settings = NULL; + + +static void configRead(char *file); +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")); + ini_free(ini); + } + + // String defaults. + if (!_configServer) strdup("kanga.world"); + if (!_configDatabase) strdup("kpmpgsmkii"); + if (!_configUser) strdup(""); + if (!_configPassword) strdup(""); +} + + +static void configWrite(char *file) { + FILE *out = NULL; + + out = fopen(file, "w"); + if (out) { + fprintf(out, + "[SERVER]\n" + "HOST=%s\n" + "PORT=%d\n" + "DATA=%s\n" + "USER=%s\n" + "PASS=%s\n", + _configServer, + _configPort, + _configDatabase, + _configUser, + _configPassword + ); + fclose(out); + } + + DEL(_configServer); + DEL(_configDatabase); + DEL(_configUser); + DEL(_configPassword); +} int main(int argc, char *argv[]) { + char *configFile = NULL; + HashValueT tempValue; + (void)argc; memoryStartup(argv[0]); logOpenByHandle(memoryLogHandleGet()); + configFile = utilAppNameWithNewExtensionGet(argv[0], "ini"); + configRead(configFile); // 0 1 2 3 4 5 6 7 8 // 12345678901234567890123456789012345678901234567890123456789012345678901234567890 logWrite("%s", "Kangaroo Punch MultiPlayer DOS Game Server Mark II\n"); logWrite("%s", "Copyright (C) 2020-2021 Scott Duensing scott@kangaroopunch.com\n\n"); + if (dbConnect(_configServer, _configPort, _configDatabase, _configUser, _configPassword)) { + tempValue.string = NULL; + if (dbSettingsValueGet("maxClients", &tempValue.integer)) shput(_settings, "maxClients", tempValue); + if (dbSettingsValueGet("portNumber", &tempValue.integer)) shput(_settings, "portNumber", tempValue); + dbDisconnect(); + } else { + logWrite("Unable to connect to database.\n"); + } + + // Show hashmap contents. + for (size_t i=0; i