Searching local game database works.
This commit is contained in:
parent
88369132e3
commit
377e40f28f
13 changed files with 352 additions and 112 deletions
|
@ -72,6 +72,7 @@ HEADERS = \
|
|||
$$SHARED/primes.h \
|
||||
$$SHARED/packet.h \
|
||||
$$SHARED/packets.h \
|
||||
../shared/game.h \
|
||||
../shared/macros.h \
|
||||
src/browser.h \
|
||||
src/config.h \
|
||||
|
|
|
@ -27,28 +27,29 @@
|
|||
#include "button.h"
|
||||
#include "frame.h"
|
||||
#include "listbox.h"
|
||||
#include "textbox.h"
|
||||
#include "timer.h"
|
||||
|
||||
#include "db.h"
|
||||
#include "network.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
static WindowT *_winBrowser = NULL;
|
||||
static ButtonT *_btnBoxTab = NULL;
|
||||
static ButtonT *_btnDescriptionTab = NULL;
|
||||
static ButtonT *_btnInfoTab = NULL;
|
||||
static ButtonT *_btnScreensTab = NULL;
|
||||
static TimerT *_timSearchUpdate = NULL;
|
||||
|
||||
static ButtonT *_btnSearchTab = NULL;
|
||||
static uint8_t _channel = 0;
|
||||
static FrameT *_fraBox = NULL;
|
||||
static FrameT *_fraDescription = NULL;
|
||||
static FrameT *_fraInfo = NULL;
|
||||
static FrameT *_fraScreens = NULL;
|
||||
static FrameT *_fraSearch = NULL;
|
||||
static ListboxT *_lstDescription = NULL;
|
||||
static ListboxT *_lstInfo = NULL;
|
||||
static TextboxT *_txtSearch = NULL;
|
||||
static ListboxT *_lstResults = NULL;
|
||||
|
||||
static ButtonT *_btnDescriptionTab = NULL;
|
||||
static FrameT *_fraDescription = NULL;
|
||||
static PictureT *_picBanner = NULL;
|
||||
static PictureT *_picBox1 = NULL;
|
||||
static PictureT *_picBox2 = NULL;
|
||||
static ListboxT *_lstDescription = NULL;
|
||||
|
||||
static ButtonT *_btnScreensTab = NULL;
|
||||
static FrameT *_fraScreens = NULL;
|
||||
static PictureT *_picThumb1 = NULL;
|
||||
static PictureT *_picThumb2 = NULL;
|
||||
static PictureT *_picThumb3 = NULL;
|
||||
|
@ -56,14 +57,36 @@ static PictureT *_picThumb4 = NULL;
|
|||
static PictureT *_picThumb5 = NULL;
|
||||
static PictureT *_picThumb6 = NULL;
|
||||
|
||||
static ButtonT *_btnBoxTab = NULL;
|
||||
static FrameT *_fraBox = NULL;
|
||||
static PictureT *_picBox1 = NULL;
|
||||
static PictureT *_picBox2 = NULL;
|
||||
|
||||
static ButtonT *_btnInfoTab = NULL;
|
||||
static FrameT *_fraInfo = NULL;
|
||||
static ListboxT *_lstInfo = NULL;
|
||||
|
||||
static uint8_t _channel = 0;
|
||||
static char *_lastSearchText = NULL;
|
||||
|
||||
|
||||
static void browserHide(void);
|
||||
static void btnTabClick(WidgetT *widget);
|
||||
static void packetHandler(PacketDecodeDataT *packet);
|
||||
static void timSearchUpdate(WidgetT *widget);
|
||||
|
||||
|
||||
static void browserHide(void) {
|
||||
timerStop(_timSearchUpdate);
|
||||
DEL(_lastSearchText);
|
||||
netChannelRelease(_channel);
|
||||
guiDelete(D(_winBrowser));
|
||||
}
|
||||
|
||||
|
||||
void browserShow(void) {
|
||||
|
||||
char **lines = NULL;
|
||||
//char **lines = NULL;
|
||||
|
||||
TagItemT uiBrowser[] = {
|
||||
T_START,
|
||||
|
@ -81,7 +104,18 @@ void browserShow(void) {
|
|||
T_X, 5, T_Y, 32,
|
||||
T_WIDTH, 500, T_HEIGHT, 250,
|
||||
T_TITLE, P("Search"),
|
||||
T_VISIBLE, T_FALSE,
|
||||
|
||||
T_TEXTBOX, O(_txtSearch),
|
||||
T_TITLE, P("Game, Publisher, or Developer:"),
|
||||
T_X, 5, T_Y, 3,
|
||||
T_WIDTH, 490,
|
||||
T_LENGTH, 255,
|
||||
T_TEXTBOX, T_DONE,
|
||||
T_LISTBOX, O(_lstResults),
|
||||
T_X, 1, T_Y, 35,
|
||||
T_WIDTH, 493, T_HEIGHT, 190, // Works out to 57 characters wide, 13 high.
|
||||
T_LISTBOX, T_DONE,
|
||||
|
||||
T_FRAME, T_DONE,
|
||||
|
||||
// GAME
|
||||
|
@ -89,6 +123,7 @@ void browserShow(void) {
|
|||
T_X, 78, T_Y, 5,
|
||||
T_TITLE, P("Game"),
|
||||
T_CLICK, P(btnTabClick),
|
||||
T_ENABLED, T_FALSE,
|
||||
T_BUTTON, T_DONE,
|
||||
T_FRAME, O(_fraDescription),
|
||||
T_X, 5, T_Y, 32,
|
||||
|
@ -98,7 +133,7 @@ void browserShow(void) {
|
|||
|
||||
T_PICTURE, O(_picBanner),
|
||||
T_X, 1, // 490PX wide
|
||||
T_FILENAME, P("banner.png"),
|
||||
T_CACHENAME, P("games:d:descent:banner.png"), // ***TODO*** This needs a "browser:no-banner.png" image.
|
||||
T_PICTURE, T_DONE,
|
||||
T_LISTBOX, O(_lstDescription),
|
||||
T_X, 1, T_Y, 105,
|
||||
|
@ -112,6 +147,7 @@ void browserShow(void) {
|
|||
T_X, 135, T_Y, 5,
|
||||
T_TITLE, P("Screens"),
|
||||
T_CLICK, P(btnTabClick),
|
||||
T_ENABLED, T_FALSE,
|
||||
T_BUTTON, T_DONE,
|
||||
T_FRAME, O(_fraScreens),
|
||||
T_X, 5, T_Y, 32,
|
||||
|
@ -121,28 +157,33 @@ void browserShow(void) {
|
|||
|
||||
T_PICTURE, O(_picThumb1), // Thumbs are 160x100
|
||||
T_X, 1, T_Y, 5,
|
||||
T_FILENAME, P("thumb1.png"),
|
||||
T_CACHENAME, P("browser:no-screen.png"),
|
||||
T_PICTURE, T_DONE,
|
||||
T_PICTURE, O(_picThumb2),
|
||||
T_X, 167, T_Y, 5,
|
||||
T_FILENAME, P("thumb2.png"),
|
||||
T_CACHENAME, P("browser:no-screen.png"),
|
||||
T_VISIBLE, T_FALSE,
|
||||
T_PICTURE, T_DONE,
|
||||
T_PICTURE, O(_picThumb3),
|
||||
T_X, 333, T_Y, 5,
|
||||
T_FILENAME, P("thumb3.png"),
|
||||
T_CACHENAME, P("browser:no-screen.png"),
|
||||
T_VISIBLE, T_FALSE,
|
||||
T_PICTURE, T_DONE,
|
||||
|
||||
T_PICTURE, O(_picThumb4),
|
||||
T_X, 1, T_Y, 116,
|
||||
T_FILENAME, P("thumb4.png"),
|
||||
T_CACHENAME, P("browser:no-screen.png"),
|
||||
T_VISIBLE, T_FALSE,
|
||||
T_PICTURE, T_DONE,
|
||||
T_PICTURE, O(_picThumb5),
|
||||
T_X, 167, T_Y, 116,
|
||||
T_FILENAME, P("thumb5.png"),
|
||||
T_CACHENAME, P("browser:no-screen.png"),
|
||||
T_VISIBLE, T_FALSE,
|
||||
T_PICTURE, T_DONE,
|
||||
T_PICTURE, O(_picThumb6),
|
||||
T_X, 333, T_Y, 116,
|
||||
T_FILENAME, P("thumb6.png"),
|
||||
T_CACHENAME, P("browser:no-screen.png"),
|
||||
T_VISIBLE, T_FALSE,
|
||||
T_PICTURE, T_DONE,
|
||||
|
||||
T_FRAME, T_DONE,
|
||||
|
@ -152,6 +193,7 @@ void browserShow(void) {
|
|||
T_X, 216, T_Y, 5,
|
||||
T_TITLE, P("Box"),
|
||||
T_CLICK, P(btnTabClick),
|
||||
T_ENABLED, T_FALSE,
|
||||
T_BUTTON, T_DONE,
|
||||
T_FRAME, O(_fraBox),
|
||||
T_X, 5, T_Y, 32,
|
||||
|
@ -161,11 +203,12 @@ void browserShow(void) {
|
|||
|
||||
T_PICTURE, O(_picBox1), // Thumbs are 240x210
|
||||
T_X, 1, T_Y, 5,
|
||||
T_FILENAME, P("box1.png"),
|
||||
T_CACHENAME, P("browser:no-box.png"),
|
||||
T_PICTURE, T_DONE,
|
||||
T_PICTURE, O(_picBox2),
|
||||
T_X, 250, T_Y, 5,
|
||||
T_FILENAME, P("box2.png"),
|
||||
T_CACHENAME, P("browser:no-box.png"),
|
||||
T_VISIBLE, T_FALSE,
|
||||
T_PICTURE, T_DONE,
|
||||
|
||||
T_FRAME, T_DONE,
|
||||
|
@ -175,12 +218,13 @@ void browserShow(void) {
|
|||
T_X, 265, T_Y, 5,
|
||||
T_TITLE, P("Info"),
|
||||
T_CLICK, P(btnTabClick),
|
||||
T_ENABLED, T_FALSE,
|
||||
T_BUTTON, T_DONE,
|
||||
T_FRAME, O(_fraInfo),
|
||||
T_X, 5, T_Y, 32,
|
||||
T_WIDTH, 500, T_HEIGHT, 250,
|
||||
T_TITLE, P("Information"),
|
||||
T_VISIBLE, T_TRUE,
|
||||
T_VISIBLE, T_FALSE,
|
||||
|
||||
T_LISTBOX, O(_lstInfo),
|
||||
T_X, 1, T_Y, 5,
|
||||
|
@ -189,19 +233,24 @@ void browserShow(void) {
|
|||
|
||||
T_FRAME, T_DONE,
|
||||
|
||||
T_TIMER, O(_timSearchUpdate),
|
||||
T_EVENT, P(timSearchUpdate),
|
||||
T_VALUE, 3,
|
||||
T_ENABLED, 1,
|
||||
T_TIMER, T_DONE,
|
||||
|
||||
T_WINDOW, T_DONE,
|
||||
T_END
|
||||
};
|
||||
|
||||
tagListRun(uiBrowser);
|
||||
guiFocusSet(W(_txtSearch));
|
||||
_channel = netChannelGet(packetHandler);
|
||||
|
||||
guiDebugAreaShow(W(_btnSearchTab));
|
||||
guiDebugAreaShow(W(_btnDescriptionTab));
|
||||
guiDebugAreaShow(W(_btnScreensTab));
|
||||
guiDebugAreaShow(W(_btnBoxTab));
|
||||
guiDebugAreaShow(W(_btnInfoTab));
|
||||
_lastSearchText = strdup("");
|
||||
|
||||
/*
|
||||
guiDebugAreaShow(W(_fraSearch));
|
||||
|
||||
lines = utilWrapText(
|
||||
"The Post-Terran Minerals Corporation (PTMC) digs up minerals on all nine planets of the solar system, "
|
||||
|
@ -216,23 +265,24 @@ void browserShow(void) {
|
|||
arrdel(lines, 0);
|
||||
}
|
||||
|
||||
listboxItemAdd(_lstInfo, "123456789012345678901234567890123456789012345678901234567");
|
||||
listboxItemAdd(_lstInfo, "2");
|
||||
listboxItemAdd(_lstInfo, "3");
|
||||
listboxItemAdd(_lstInfo, "4");
|
||||
listboxItemAdd(_lstInfo, "5");
|
||||
listboxItemAdd(_lstInfo, "6");
|
||||
listboxItemAdd(_lstInfo, "7");
|
||||
listboxItemAdd(_lstInfo, "8");
|
||||
listboxItemAdd(_lstInfo, "9");
|
||||
listboxItemAdd(_lstInfo, "10");
|
||||
listboxItemAdd(_lstInfo, "11");
|
||||
listboxItemAdd(_lstInfo, "12");
|
||||
listboxItemAdd(_lstInfo, "13");
|
||||
listboxItemAdd(_lstInfo, "14");
|
||||
listboxItemAdd(_lstInfo, "15");
|
||||
listboxItemAdd(_lstInfo, "16");
|
||||
listboxItemAdd(_lstInfo, "17");
|
||||
listboxItemAdd(_lstResults, "123456789012345678901234567890123456789012345678901234567");
|
||||
listboxItemAdd(_lstResults, "2");
|
||||
listboxItemAdd(_lstResults, "3");
|
||||
listboxItemAdd(_lstResults, "4");
|
||||
listboxItemAdd(_lstResults, "5");
|
||||
listboxItemAdd(_lstResults, "6");
|
||||
listboxItemAdd(_lstResults, "7");
|
||||
listboxItemAdd(_lstResults, "8");
|
||||
listboxItemAdd(_lstResults, "9");
|
||||
listboxItemAdd(_lstResults, "10");
|
||||
listboxItemAdd(_lstResults, "11");
|
||||
listboxItemAdd(_lstResults, "12");
|
||||
listboxItemAdd(_lstResults, "13");
|
||||
listboxItemAdd(_lstResults, "14");
|
||||
listboxItemAdd(_lstResults, "15");
|
||||
listboxItemAdd(_lstResults, "16");
|
||||
listboxItemAdd(_lstResults, "17");
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
@ -255,3 +305,43 @@ static void btnTabClick(WidgetT *widget) {
|
|||
static void packetHandler(PacketDecodeDataT *packet) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void timSearchUpdate(WidgetT *widget) {
|
||||
char ***records = NULL;
|
||||
char **fields = NULL;
|
||||
uint16_t count = 0;
|
||||
char query[258]; // 255 search characters, two %'s, and the terminating null.
|
||||
|
||||
(void)widget;
|
||||
|
||||
// Are there more than two characters in the search field?
|
||||
if (textboxValueGet(_txtSearch) && strlen(textboxValueGet(_txtSearch)) > 2) {
|
||||
// Did the search contents change?
|
||||
if (strcmp(_lastSearchText, textboxValueGet(_txtSearch))) {
|
||||
// Remember what was in the search box.
|
||||
DEL(_lastSearchText);
|
||||
_lastSearchText = strdup(textboxValueGet(_txtSearch));
|
||||
// Clear current search results.
|
||||
listboxItemsClear(_lstResults);
|
||||
// Execute search.
|
||||
snprintf(query, 258, "%%%s%%", _lastSearchText);
|
||||
dbQueryMultiple(&records,
|
||||
"SELECT title FROM games WHERE "
|
||||
"title LIKE ? OR developer LIKE ? OR publisher LIKE ? "
|
||||
"ORDER BY title",
|
||||
"vvv",
|
||||
query,
|
||||
query,
|
||||
query);
|
||||
// Did we get anything?
|
||||
if (records) {
|
||||
for (count = 0; count < arrlen(records); count++) {
|
||||
fields = records[count];
|
||||
listboxItemAdd(_lstResults, fields[0]);
|
||||
}
|
||||
dbResultRelease(&records);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,15 +44,8 @@ static void listboxSizesRecalculate(ListboxT *listbox);
|
|||
|
||||
static void listboxDel(WidgetT **widget) {
|
||||
ListboxT *l = (ListboxT *)*widget;
|
||||
size_t len = arrlenu(l->values);
|
||||
size_t x;
|
||||
|
||||
if (len > 0) {
|
||||
for (x=0; x<len; x++) {
|
||||
free(l->values[x]);
|
||||
}
|
||||
}
|
||||
arrfree(l->values);
|
||||
listboxItemsClear(l);
|
||||
}
|
||||
|
||||
|
||||
|
@ -102,6 +95,7 @@ void listboxItemRemove(ListboxT *listbox, char *item) {
|
|||
if (len > 0) {
|
||||
for (x=0; x<len; x++) {
|
||||
if (strcmp(item, listbox->values[x]) == 0) {
|
||||
DEL(listbox->values[x]);
|
||||
arrdel(listbox->values, x);
|
||||
if (listbox->selected > len || listbox->selected > 0) listbox->selected--;
|
||||
GUI_SET_FLAG((WidgetT *)listbox, WIDGET_FLAG_DIRTY);
|
||||
|
@ -112,6 +106,17 @@ void listboxItemRemove(ListboxT *listbox, char *item) {
|
|||
}
|
||||
|
||||
|
||||
void listboxItemsClear(ListboxT *listbox) {
|
||||
while (arrlen(listbox->values) > 0) {
|
||||
DEL(listbox->values[0]);
|
||||
arrdel(listbox->values, 0);
|
||||
}
|
||||
arrfree(listbox->values);
|
||||
|
||||
listbox->selected = 0;
|
||||
}
|
||||
|
||||
|
||||
static void listboxKeyboardEvent(WidgetT *widget, uint8_t ascii, uint8_t extended, uint8_t scancode, uint8_t shift, uint8_t control, uint8_t alt) {
|
||||
|
||||
ListboxT *l = (ListboxT *)widget;
|
||||
|
|
|
@ -41,6 +41,7 @@ void listboxIndexSet(ListboxT *listbox, uint16_t index);
|
|||
WidgetT *listboxInit(WidgetT *widget, char *title);
|
||||
void listboxItemAdd(ListboxT *listbox, char *item);
|
||||
void listboxItemRemove(ListboxT *listbox, char *item);
|
||||
void listboxItemsClear(ListboxT *listbox);
|
||||
ListboxT *listboxNew(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *title);
|
||||
void listboxStepSet(ListboxT *listbox, int32_t step);
|
||||
void listboxTitleSet(ListboxT *listbox, char *title);
|
||||
|
|
|
@ -211,6 +211,7 @@ static uint8_t startup(int argc, char *argv[]) {
|
|||
|
||||
|
||||
extern void browserShow(void);
|
||||
extern void updateGameDatabase(void);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
|
@ -221,8 +222,9 @@ int main(int argc, char *argv[]) {
|
|||
// Perform "first run" setup tasks or start the client?
|
||||
if (hasValidSettings()) {
|
||||
// We have what we need, start the client.
|
||||
welcomeShow();
|
||||
//browserShow();
|
||||
//welcomeShow();
|
||||
updateGameDatabase();
|
||||
browserShow();
|
||||
eventLoop();
|
||||
} else {
|
||||
// Run the setup.
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "network.h"
|
||||
#include "vesa.h"
|
||||
#include "db.h"
|
||||
#include "game.h"
|
||||
|
||||
#include "taglist.h"
|
||||
#include "msgbox.h"
|
||||
|
@ -44,7 +45,7 @@ static void picForumsClick(WidgetT *widget);
|
|||
static void picGamesClick(WidgetT *widget);
|
||||
static void picLogoffClick(WidgetT *widget);
|
||||
static void picProfileClick(WidgetT *widget);
|
||||
static void updateGameDatabase(void);
|
||||
/* static */ void updateGameDatabase(void);
|
||||
|
||||
|
||||
static PictureT *_picChat = NULL;
|
||||
|
@ -154,6 +155,7 @@ void menuShow(void) {
|
|||
"menu:48profile.png",
|
||||
"generated:games.dat",
|
||||
|
||||
// LOAD THE WORLD! This is for debugging the browser.
|
||||
"games:d:descent:banner.png",
|
||||
"games:d:descent:box2.png",
|
||||
"games:d:descent:screen1.png",
|
||||
|
@ -355,9 +357,51 @@ static void picProfileClick(WidgetT *widget) {
|
|||
}
|
||||
|
||||
|
||||
static void updateGameDatabase(void) {
|
||||
uint8_t utilFromFileReadByte(FILE *f, uint8_t *result) {
|
||||
unsigned char c;
|
||||
|
||||
// Get next byte.
|
||||
c = fgetc(f);
|
||||
// End of file?
|
||||
if (feof(f)) return FAIL;
|
||||
// Add to result.
|
||||
*result = c;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
uint8_t utilFromFileReadString(FILE *f, char **result) {
|
||||
unsigned char c;
|
||||
char buffer[GAME_MAX_DESCRIPTION];
|
||||
uint16_t x = 0;
|
||||
|
||||
// Something already in 'result'?
|
||||
DEL(*result);
|
||||
|
||||
while (1) {
|
||||
// Get next byte.
|
||||
c = fgetc(f);
|
||||
// End of file?
|
||||
if (feof(f)) return FAIL;
|
||||
// Add to result.
|
||||
buffer[x++] = c;
|
||||
buffer[x] = 0;
|
||||
// End of string?
|
||||
if (c == 0) {
|
||||
*result = strdup(buffer);
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* static */ void updateGameDatabase(void) {
|
||||
FILE *f = NULL;
|
||||
uint8_t c;
|
||||
uint8_t result;
|
||||
GameT game;
|
||||
|
||||
// Clear 'game'.
|
||||
memset(&game, 0, sizeof(GameT));
|
||||
|
||||
// Do we need to create the game database?
|
||||
dbExecute(
|
||||
|
@ -372,7 +416,7 @@ static void updateGameDatabase(void) {
|
|||
"origin VARCHAR(255), "
|
||||
"shortName VARCHAR(8) PRIMARY KEY, "
|
||||
"worksWith VARCHAR(255), "
|
||||
"type VARCHAR(8), "
|
||||
"type INTEGER, "
|
||||
"maxPlayers INTEGER, "
|
||||
"joinable BOOLEAN, "
|
||||
"screens INTEGER, "
|
||||
|
@ -382,22 +426,85 @@ static void updateGameDatabase(void) {
|
|||
NULL);
|
||||
|
||||
// Mark everything untouched.
|
||||
dbExecute("UPDATE games SET touced=0", NULL);
|
||||
dbExecute("UPDATE games SET touched=0", NULL);
|
||||
|
||||
/*
|
||||
// Process latest downloaded game list.
|
||||
f = cacheFOpen("generated:games.dat", "rb");
|
||||
if (f) {
|
||||
result = FAIL;
|
||||
while (1) {
|
||||
// Get next byte.
|
||||
c = fgetc(f);
|
||||
// End of file?
|
||||
if (feof(f)) break;
|
||||
// If this first read fails, we're out of data. Any other read fails, we have problems.
|
||||
if (!utilFromFileReadString(f, &game.title)) {
|
||||
result = SUCCESS;
|
||||
break;
|
||||
}
|
||||
if (!utilFromFileReadString(f, &game.publisher)) break;
|
||||
if (!utilFromFileReadString(f, &game.developer)) break;
|
||||
if (!utilFromFileReadString(f, &game.description)) break;
|
||||
if (!utilFromFileReadString(f, &game.releaseDate)) break;
|
||||
if (!utilFromFileReadString(f, &game.rating)) break;
|
||||
if (!utilFromFileReadString(f, &game.series)) break;
|
||||
if (!utilFromFileReadString(f, &game.origin)) break;
|
||||
if (!utilFromFileReadString(f, &game.shortName)) break;
|
||||
if (!utilFromFileReadString(f, &game.worksWith)) break;
|
||||
|
||||
if (!utilFromFileReadByte(f, (uint8_t *)&game.type)) break;
|
||||
if (!utilFromFileReadByte(f, &game.maxPlayers)) break;
|
||||
if (!utilFromFileReadByte(f, &game.joinable)) break;
|
||||
if (!utilFromFileReadByte(f, &game.screens)) break;
|
||||
if (!utilFromFileReadByte(f, &game.boxes)) break;
|
||||
|
||||
// Write this to the database.
|
||||
dbExecute(
|
||||
"REPLACE INTO games ("
|
||||
"shortName, title, publisher, developer, description, releaseDate, "
|
||||
"rating, series, origin, worksWith, type, maxPlayers, joinable, "
|
||||
"screens, boxes, touched"
|
||||
") VALUES ("
|
||||
"?, ?, ?, ?, ?, ?, "
|
||||
"?, ?, ?, ?, ?, ?, ?, "
|
||||
"?, ?, 1 "
|
||||
")",
|
||||
"vvvvvv"
|
||||
"vvvviii"
|
||||
"iii",
|
||||
game.shortName,
|
||||
game.title,
|
||||
game.publisher,
|
||||
game.developer,
|
||||
game.description,
|
||||
game.releaseDate,
|
||||
game.rating,
|
||||
game.series,
|
||||
game.origin,
|
||||
game.worksWith,
|
||||
game.type,
|
||||
game.maxPlayers,
|
||||
game.joinable,
|
||||
game.screens,
|
||||
game.boxes
|
||||
);
|
||||
}
|
||||
cacheFClose(f);
|
||||
|
||||
// Delete anything untouched.
|
||||
dbExecute("DELETE FROM games WHERE touced=0", NULL);
|
||||
dbExecute("DELETE FROM games WHERE touched=0", NULL);
|
||||
|
||||
// Free 'game'.
|
||||
DEL(game.title);
|
||||
DEL(game.publisher);
|
||||
DEL(game.developer);
|
||||
DEL(game.description);
|
||||
DEL(game.releaseDate);
|
||||
DEL(game.rating);
|
||||
DEL(game.series);
|
||||
DEL(game.origin);
|
||||
DEL(game.shortName);
|
||||
DEL(game.worksWith);
|
||||
|
||||
//***TODO*** Did we have problems updating the game database?
|
||||
if (result == FAIL) {
|
||||
// Do something here.
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -40,10 +40,9 @@ void runtimeDataLoad(void) {
|
|||
shput(__runtimeData.strings, fields[0], strdup(fields[1]));
|
||||
}
|
||||
}
|
||||
dbResultRelease(&records);
|
||||
}
|
||||
|
||||
dbResultRelease(&records);
|
||||
|
||||
/*
|
||||
logWrite("\n\n");
|
||||
for (int r = 0; r < shlen(__runtimeData.strings); r++) {
|
||||
|
|
|
@ -109,6 +109,8 @@ static void clientApiFileRequestCheck(ClientThreadT *client, PacketDecodeDataT *
|
|||
if (!client->authenticated && mustAuth) {
|
||||
logWrite("Unauthenticated user requested file: %s\n", path);
|
||||
clientApiFileFailed(client, data);
|
||||
DEL(sha256);
|
||||
DEL(path);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -165,13 +167,13 @@ static void clientApiFileRequestCheck(ClientThreadT *client, PacketDecodeDataT *
|
|||
packetSend(client->packetThreadData, &encoded);
|
||||
DEL(packetData);
|
||||
|
||||
DEL(sha256);
|
||||
DEL(path);
|
||||
|
||||
// Start sending actual file data.
|
||||
clientApiFileRequestNext(client, data);
|
||||
}
|
||||
|
||||
DEL(sha256);
|
||||
DEL(path);
|
||||
|
||||
END
|
||||
}
|
||||
|
||||
|
|
|
@ -286,8 +286,8 @@ static void dbFileSha256Create(char *file, char *buf) {
|
|||
}
|
||||
|
||||
|
||||
void dbGameRelease(DbGameT **game) {
|
||||
DbGameT *g = *game;
|
||||
void dbGameRelease(GameT **game) {
|
||||
GameT *g = *game;
|
||||
|
||||
if (g) {
|
||||
DEL(g->title);
|
||||
|
@ -305,15 +305,15 @@ void dbGameRelease(DbGameT **game) {
|
|||
}
|
||||
|
||||
|
||||
DbGameT **dbGamesGet(void) {
|
||||
GameT **dbGamesGet(void) {
|
||||
char statement[STATEMENT_MAX];
|
||||
char *p = statement;
|
||||
MYSQL_RES *result = NULL;
|
||||
MYSQL_ROW row = NULL;
|
||||
int32_t count = 0;
|
||||
int32_t i = 0;
|
||||
DbGameT **gameList = NULL;
|
||||
DbGameT *game = NULL;
|
||||
GameT **gameList = NULL;
|
||||
GameT *game = NULL;
|
||||
char filename[MAX_PATH];
|
||||
int32_t x = 0;
|
||||
|
||||
|
@ -351,7 +351,7 @@ DbGameT **dbGamesGet(void) {
|
|||
pthread_mutex_unlock(&_mutex);
|
||||
return NULL;
|
||||
}
|
||||
NEW(DbGameT, game);
|
||||
NEW(GameT, game);
|
||||
game->title = strdup(row[0]);
|
||||
game->publisher = strdup(row[1]);
|
||||
game->developer = strdup(row[2]);
|
||||
|
|
|
@ -23,20 +23,12 @@
|
|||
|
||||
|
||||
#include "os.h"
|
||||
#include "game.h"
|
||||
|
||||
|
||||
#define DB_CONFIG_ITEM_SIZE 1024
|
||||
|
||||
|
||||
typedef enum DbGameTypeE {
|
||||
GAME_TYPE_UNKNOWN = 0,
|
||||
GAME_TYPE_DOOR,
|
||||
GAME_TYPE_SERIAL,
|
||||
GAME_TYPE_IPX,
|
||||
GAME_TYPE_FICTION
|
||||
} DbGameTypeT;
|
||||
|
||||
|
||||
typedef struct DbClientConfigS {
|
||||
char *name;
|
||||
char *data;
|
||||
|
@ -52,24 +44,6 @@ typedef struct DbFileInfoS {
|
|||
uint8_t touched;
|
||||
} DbFileInfoT;
|
||||
|
||||
typedef struct DbGameS {
|
||||
char *title;
|
||||
char *publisher;
|
||||
char *developer;
|
||||
char *description;
|
||||
char *releaseDate;
|
||||
char *rating;
|
||||
char *series;
|
||||
char *origin;
|
||||
char *shortName;
|
||||
char *worksWith;
|
||||
DbGameTypeT type;
|
||||
uint8_t maxPlayers;
|
||||
uint8_t joinable;
|
||||
uint8_t screens;
|
||||
uint8_t boxes;
|
||||
} DbGameT;
|
||||
|
||||
|
||||
uint8_t dbConnect(char *host, uint16_t port, char *database, char *user, char *password);
|
||||
void dbClientConfigRelease(DbClientConfigT **config);
|
||||
|
@ -77,8 +51,8 @@ DbClientConfigT **dbClientConfigGet(void);
|
|||
uint8_t dbDisconnect(void);
|
||||
DbFileInfoT *dbFileInfoGet(char *vpath);
|
||||
void dbFileInfoRelease(DbFileInfoT **info);
|
||||
void dbGameRelease(DbGameT **game);
|
||||
DbGameT **dbGamesGet(void);
|
||||
void dbGameRelease(GameT **game);
|
||||
GameT **dbGamesGet(void);
|
||||
uint8_t dbSettingsStringGet(char *host, char *key, char *value, uint32_t max);
|
||||
uint8_t dbSettingsValueGet(char *host, char *key, int32_t *value);
|
||||
uint8_t dbUpdateFileData(char *file, uint64_t len, char *time);
|
||||
|
|
|
@ -209,8 +209,8 @@ static int32_t updateFileEntry(const char *filepath, const struct stat *info, co
|
|||
|
||||
|
||||
static void updateGames(void) {
|
||||
DbGameT **gameList = NULL;
|
||||
DbGameT *game = NULL;
|
||||
GameT **gameList = NULL;
|
||||
GameT *game = NULL;
|
||||
char file[MAX_PATH] = { 0 };
|
||||
FILE *f = NULL;
|
||||
uint8_t c = 0;
|
||||
|
|
59
shared/game.h
Normal file
59
shared/game.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef GAME_H
|
||||
#define GAME_H
|
||||
|
||||
|
||||
#include "os.h"
|
||||
|
||||
|
||||
#define GAME_MAX_DESCRIPTION 4096
|
||||
|
||||
|
||||
typedef enum GameTypeE {
|
||||
GAME_TYPE_UNKNOWN = 0,
|
||||
GAME_TYPE_DOOR,
|
||||
GAME_TYPE_SERIAL,
|
||||
GAME_TYPE_IPX,
|
||||
GAME_TYPE_FICTION
|
||||
} GameTypeT;
|
||||
|
||||
|
||||
typedef struct GameS { // Data type in DAT file sent to client.
|
||||
char *title; // 255
|
||||
char *publisher; // 255
|
||||
char *developer; // 255
|
||||
char *description; // TEXT
|
||||
char *releaseDate; // DATETIME
|
||||
char *rating; // 255
|
||||
char *series; // 255
|
||||
char *origin; // 255
|
||||
char *shortName; // 8
|
||||
char *worksWith; // 8
|
||||
GameTypeT type; // 1
|
||||
uint8_t maxPlayers; // 1
|
||||
uint8_t joinable; // 1
|
||||
uint8_t screens; // 1
|
||||
uint8_t boxes; // 1
|
||||
} GameT;
|
||||
|
||||
|
||||
#endif // GAME_H
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
// Allocation helpers.
|
||||
#define NEW(t,v) (v)=(t*)malloc(sizeof(t))
|
||||
#define DEL(v) {free(v); v=NULL;}
|
||||
#define DEL(v) {if(v) {free(v); v=NULL;}}
|
||||
|
||||
// Some helper defines.
|
||||
#define DIVISIBLE_BY_EIGHT(x) ((((x) >> 3) << 3) == (x))
|
||||
|
|
Loading…
Add table
Reference in a new issue