tAdd basic metaserver support to GUI client - vaccinewars - be a doctor and try… | |
git clone git://src.adamsgaard.dk/vaccinewars | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 0eda1a10d2f68195b4e12ec9c938f59100b6099b | |
parent ac4948ce0b970217f9ea743531da1ee3b963b8fa | |
Author: Ben Webb <[email protected]> | |
Date: Sun, 1 Nov 2020 23:20:10 -0800 | |
Add basic metaserver support to GUI client | |
Diffstat: | |
M src/gui_client/gtk_client.c | 9 ++++++++- | |
M src/gui_client/newgamedia.c | 189 +++++++++++++++++++++++++++--… | |
M src/gui_client/newgamedia.h | 2 +- | |
3 files changed, 178 insertions(+), 22 deletions(-) | |
--- | |
diff --git a/src/gui_client/gtk_client.c b/src/gui_client/gtk_client.c | |
t@@ -109,6 +109,9 @@ static void GetClientMessage(gpointer data, gint socket, | |
GdkInputCondition condition); | |
void SocketStatus(NetworkBuffer *NetBuf, gboolean Read, gboolean Write, | |
gboolean CallNow); | |
+ | |
+/* Data waiting to be sent to/read from the metaserver */ | |
+CurlConnection MetaConn; | |
#endif /* NETWORKING */ | |
static void HandleClientMessage(char *buf, Player *Play); | |
t@@ -264,7 +267,7 @@ void NewGame(GtkWidget *widget, gpointer data) | |
BackupConfig(); | |
#ifdef NETWORKING | |
- NewGameDialog(ClientData.Play, SocketStatus); | |
+ NewGameDialog(ClientData.Play, SocketStatus, &MetaConn); | |
#else | |
NewGameDialog(ClientData.Play); | |
#endif | |
t@@ -2339,8 +2342,12 @@ gboolean GtkLoop(int *argc, char **argv[], | |
SetIcon(window, dopewars_pill_xpm); | |
+ CurlInit(&MetaConn); | |
+ | |
gtk_main(); | |
+ CurlCleanup(&MetaConn); | |
+ | |
/* Free the main player */ | |
FirstClient = RemovePlayer(ClientData.Play, FirstClient); | |
diff --git a/src/gui_client/newgamedia.c b/src/gui_client/newgamedia.c | |
t@@ -41,7 +41,7 @@ struct StartGameStruct { | |
*metaserv, *notebook; | |
Player *play; | |
#ifdef NETWORKING | |
- HttpConnection *MetaConn; | |
+ CurlConnection *MetaConn; | |
GSList *NewMetaList; | |
NBCallBack sockstat; | |
#endif | |
t@@ -56,6 +56,7 @@ static void MetaSocksAuthDialog(NetworkBuffer *netbuf, gpoin… | |
static void SocksAuthDialog(NetworkBuffer *netbuf, gpointer data); | |
static void MetaSocketStatus(NetworkBuffer *NetBuf, gboolean Read, | |
gboolean Write, gboolean CallNow); | |
+static void FillMetaServerList(gboolean UseNewList); | |
/* List of servers on the metaserver */ | |
static GSList *MetaList = NULL; | |
t@@ -86,15 +87,154 @@ static void SetStartGameStatus(gchar *msg) | |
} | |
#ifdef NETWORKING | |
+ | |
+/* Global information, common to all connections */ | |
+typedef struct _GlobalData { | |
+ CURLM *multi; | |
+ guint timer_event; | |
+ int still_running; | |
+} GlobalData; | |
+ | |
+/* Information associated with a specific socket */ | |
+typedef struct _SockData { | |
+ curl_socket_t sockfd; | |
+ CURL *easy; | |
+ int action; | |
+ long timeout; | |
+ GIOChannel *ch; | |
+ guint ev; | |
+ GlobalData *global; | |
+} SockData; | |
+ | |
+GlobalData global_data; | |
+ | |
+/* Called by glib when we get action on a multi socket */ | |
+static gboolean glib_socket(GIOChannel *ch, GIOCondition condition, gpointer d… | |
+{ | |
+ GlobalData *g = (GlobalData*) data; | |
+ CURLMcode rc; | |
+ int fd = g_io_channel_unix_get_fd(ch); | |
+ fprintf(stderr, "bw> glib socket\n"); | |
+ int action = | |
+ ((condition & G_IO_IN) ? CURL_CSELECT_IN : 0) | | |
+ ((condition & G_IO_OUT) ? CURL_CSELECT_OUT : 0); | |
+ | |
+ rc = curl_multi_socket_action(g->multi, fd, action, &g->still_running); | |
+ if (rc != CURLM_OK) fprintf(stderr, "action %d %s\n", rc, curl_multi_strerro… | |
+ if (g->still_running) { | |
+ return TRUE; | |
+ } else { | |
+ fprintf(stderr, "got data %s\n", stgam.MetaConn->data); | |
+ fprintf(stderr, "last transfer done, kill timeout\n"); | |
+ if (g->timer_event) { | |
+ g_source_remove(g->timer_event); | |
+ g->timer_event = 0; | |
+ } | |
+ HandleWaitingMetaServerData(stgam.MetaConn, &stgam.NewMetaList); | |
+ SetStartGameStatus(NULL); | |
+ CloseCurlConnection(stgam.MetaConn); | |
+ FillMetaServerList(TRUE); | |
+ return FALSE; | |
+ } | |
+} | |
+ | |
+static gboolean glib_timeout(gpointer userp) | |
+{ | |
+ GlobalData *g = userp; | |
+ CURLMcode rc; | |
+ fprintf(stderr, "bw> glib_timeout\n"); | |
+ rc = curl_multi_socket_action(g->multi, CURL_SOCKET_TIMEOUT, 0, &g->still_ru… | |
+ if (rc != CURLM_OK) fprintf(stderr, "action %d %s\n", rc, curl_multi_strerro… | |
+ g->timer_event = 0; | |
+ return G_SOURCE_REMOVE; | |
+} | |
+ | |
+int timer_cb(CURLM *multi, long timeout_ms, void *userp) | |
+{ | |
+ fprintf(stderr, "bw> timer_cb %ld\n", timeout_ms); | |
+ GlobalData *g = userp; | |
+ | |
+ if (g->timer_event) { | |
+ g_source_remove(g->timer_event); | |
+ g->timer_event = 0; | |
+ } | |
+ | |
+ /* -1 means we should just delete our timer. */ | |
+ if (timeout_ms >= 0) { | |
+ g->timer_event = g_timeout_add(timeout_ms, glib_timeout, g); | |
+ } | |
+ return 0; | |
+} | |
+ | |
+/* Clean up the SockData structure */ | |
+static void remsock(SockData *f) | |
+{ | |
+ if (!f) { | |
+ return; | |
+ } | |
+ if (f->ev) { | |
+ g_source_remove(f->ev); | |
+ } | |
+ g_free(f); | |
+} | |
+ | |
+/* Assign information to a SockData structure */ | |
+static void setsock(SockData *f, curl_socket_t s, CURL *e, int act, | |
+ GlobalData *g) | |
+{ | |
+ GIOCondition kind = | |
+ ((act & CURL_POLL_IN) ? G_IO_IN : 0) | | |
+ ((act & CURL_POLL_OUT) ? G_IO_OUT : 0); | |
+ | |
+ f->sockfd = s; | |
+ f->action = act; | |
+ f->easy = e; | |
+ if (f->ev) { | |
+ g_source_remove(f->ev); | |
+ } | |
+ f->ev = g_io_add_watch(f->ch, kind, glib_socket, g); | |
+} | |
+ | |
+/* Initialize a new SockData structure */ | |
+static void addsock(curl_socket_t s, CURL *easy, int action, GlobalData *g) | |
+{ | |
+ SockData *fdp = g_malloc0(sizeof(SockData)); | |
+ | |
+ fdp->global = g; | |
+ fdp->ch = g_io_channel_unix_new(s); | |
+ setsock(fdp, s, easy, action, g); | |
+ curl_multi_assign(g->multi, s, fdp); | |
+} | |
+ | |
+int socket_cb(CURL *easy, curl_socket_t s, int what, void *userp, | |
+ void *socketp) | |
+{ | |
+ GlobalData *g = userp; | |
+ SockData *fdp = socketp; | |
+ static const char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE" }; | |
+ fprintf(stderr, "bw> socket_cb s=%d %d what=%s\n", s, what, whatstr[what]); | |
+ if (what == CURL_POLL_REMOVE) { | |
+ fprintf(stderr, "remove socket\n"); | |
+ remsock(fdp); | |
+ } else if (!fdp) { | |
+ fprintf(stderr, "add socket\n"); | |
+ addsock(s, easy, what, g); | |
+ } else { | |
+ fprintf(stderr, "change socket\n"); | |
+ setsock(fdp, s, easy, what, g); | |
+ } | |
+ return 0; | |
+} | |
+ | |
static void ConnectError(gboolean meta) | |
{ | |
GString *neterr; | |
gchar *text; | |
LastError *error; | |
- if (meta) | |
+/*if (meta) | |
error = stgam.MetaConn->NetBuf.error; | |
- else | |
+ else*/ | |
error = stgam.play->NetBuf.error; | |
neterr = g_string_new(""); | |
t@@ -149,9 +289,8 @@ static void DoConnect(void) | |
/* Terminate any existing connection attempts */ | |
ShutdownNetworkBuffer(NetBuf); | |
- if (stgam.MetaConn) { | |
- CloseHttpConnection(stgam.MetaConn); | |
- stgam.MetaConn = NULL; | |
+ if (stgam.MetaConn->running) { | |
+ CloseCurlConnection(stgam.MetaConn); | |
} | |
oldstatus = NetBuf->status; | |
t@@ -242,13 +381,13 @@ void DisplayConnectStatus(gboolean meta, | |
NBSocksStatus sockstat; | |
gchar *text; | |
- if (meta) { | |
+/*if (meta) { | |
status = stgam.MetaConn->NetBuf.status; | |
sockstat = stgam.MetaConn->NetBuf.sockstat; | |
- } else { | |
+ } else {*/ | |
status = stgam.play->NetBuf.status; | |
sockstat = stgam.play->NetBuf.sockstat; | |
- } | |
+//} | |
if (oldstatus == status && sockstat == oldsocks) | |
return; | |
t@@ -293,13 +432,12 @@ void DisplayConnectStatus(gboolean meta, | |
static void MetaDone(void) | |
{ | |
- if (IsHttpError(stgam.MetaConn)) { | |
+/*if (IsHttpError(stgam.MetaConn)) { | |
ConnectError(TRUE); | |
- } else { | |
+ } else {*/ | |
SetStartGameStatus(NULL); | |
- } | |
- CloseHttpConnection(stgam.MetaConn); | |
- stgam.MetaConn = NULL; | |
+//} | |
+ CloseCurlConnection(stgam.MetaConn); | |
FillMetaServerList(TRUE); | |
} | |
t@@ -351,12 +489,12 @@ static void UpdateMetaServerList(GtkWidget *widget) | |
{ | |
GtkWidget *metaserv; | |
gchar *text; | |
+ const char *merr; | |
/* Terminate any existing connection attempts */ | |
ShutdownNetworkBuffer(&stgam.play->NetBuf); | |
- if (stgam.MetaConn) { | |
- CloseHttpConnection(stgam.MetaConn); | |
- stgam.MetaConn = NULL; | |
+ if (stgam.MetaConn->running) { | |
+ CloseCurlConnection(stgam.MetaConn); | |
} | |
ClearServerList(&stgam.NewMetaList); | |
t@@ -367,6 +505,10 @@ static void UpdateMetaServerList(GtkWidget *widget) | |
SetStartGameStatus(text); | |
g_free(text); | |
+ if ((merr = OpenMetaHttpConnection(stgam.MetaConn))) { | |
+ ConnectError(TRUE); | |
+ } else { | |
+ } | |
/* | |
if (OpenMetaHttpConnection(&stgam.MetaConn)) { | |
metaserv = stgam.metaserv; | |
t@@ -422,7 +564,7 @@ static void CloseNewGameDia(GtkWidget *widget, gpointer da… | |
ShutdownNetworkBuffer(&stgam.play->NetBuf); | |
} | |
if (stgam.MetaConn) { | |
- CloseHttpConnection(stgam.MetaConn); | |
+ CloseCurlConnection(stgam.MetaConn); | |
stgam.MetaConn = NULL; | |
} | |
ClearServerList(&stgam.NewMetaList); | |
t@@ -445,7 +587,7 @@ static void metalist_row_unselect(GtkWidget *clist, gint r… | |
} | |
#ifdef NETWORKING | |
-void NewGameDialog(Player *play, NBCallBack sockstat) | |
+void NewGameDialog(Player *play, NBCallBack sockstat, CurlConnection *MetaConn) | |
#else | |
void NewGameDialog(Player *play) | |
#endif | |
t@@ -456,10 +598,17 @@ void NewGameDialog(Player *play) | |
guint AccelKey; | |
#ifdef NETWORKING | |
+ global_data.multi = MetaConn->multi; | |
+ global_data.timer_event = 0; | |
GtkWidget *clist, *scrollwin, *table, *hbbox; | |
gchar *server_titles[5], *ServerEntry, *text; | |
gboolean UpdateMeta = FALSE; | |
+ curl_multi_setopt(MetaConn->multi, CURLMOPT_TIMERFUNCTION, timer_cb); | |
+ curl_multi_setopt(MetaConn->multi, CURLMOPT_TIMERDATA, &global_data); | |
+ curl_multi_setopt(MetaConn->multi, CURLMOPT_SOCKETFUNCTION, socket_cb); | |
+ curl_multi_setopt(MetaConn->multi, CURLMOPT_SOCKETDATA, &global_data); | |
+ | |
/* Column titles of metaserver information */ | |
server_titles[0] = _("Server"); | |
server_titles[1] = _("Port"); | |
t@@ -467,7 +616,7 @@ void NewGameDialog(Player *play) | |
server_titles[3] = _("Players"); | |
server_titles[4] = _("Comment"); | |
- stgam.MetaConn = NULL; | |
+ stgam.MetaConn = MetaConn; | |
stgam.NewMetaList = NULL; | |
stgam.sockstat = sockstat; | |
diff --git a/src/gui_client/newgamedia.h b/src/gui_client/newgamedia.h | |
t@@ -32,7 +32,7 @@ | |
#include "network.h" | |
#ifdef NETWORKING | |
-void NewGameDialog(Player *play, NBCallBack sockstat); | |
+void NewGameDialog(Player *play, NBCallBack sockstat, CurlConnection *MetaConn… | |
void DisplayConnectStatus(gboolean meta, NBStatus oldstatus, | |
NBSocksStatus oldsocks); | |
void FinishServerConnect(gboolean ConnectOK); |