diff --git a/OpenRA.Launcher.Gtk/bridge.c b/OpenRA.Launcher.Gtk/bridge.c index 3811895d49..3456f1b95f 100644 --- a/OpenRA.Launcher.Gtk/bridge.c +++ b/OpenRA.Launcher.Gtk/bridge.c @@ -5,6 +5,8 @@ * as published by the Free Software Foundation. For more information, * see LICENSE. */ +#include +#include #include #include @@ -14,23 +16,43 @@ #define JS_FUNC(ctx, callback) JSObjectMakeFunctionWithCallback(ctx, NULL, \ callback) +int js_check_num_args(JSContextRef ctx, char const * func_name, int argc, int num_expected, JSValueRef * exception) +{ + char buf[64]; + if (argc < num_expected) + { + sprintf(buf, "%s: Not enough args, expected %d got %d", func_name, num_expected, argc); + *exception = JSValueMakeString(ctx, JS_STR(buf)); + return 0; + } + return 1; +} + +char * js_get_cstr_from_val(JSContextRef ctx, JSValueRef val, size_t * size) +{ + char * buf; + size_t str_size; + JSStringRef str = JSValueToStringCopy(ctx, val, NULL); + str_size = JSStringGetMaximumUTF8CStringSize(str); + buf = (char *)malloc(str_size); + *size = JSStringGetUTF8CString(str, buf, str_size); + return buf; +} + JSValueRef js_log(JSContextRef ctx, JSObjectRef func, JSObjectRef this, - size_t argc, const JSValueRef argv[], - JSValueRef * exception) + size_t argc, const JSValueRef argv[], JSValueRef * exception) { JSValueRef return_value = JSValueMakeNull(ctx); - if (argc < 1) - { - *exception = JSValueMakeString(ctx, JS_STR("Not enough args")); + if (!js_check_num_args(ctx, "log", argc, 1, exception)) return return_value; - } if (JSValueIsString(ctx, argv[0])) { - char buffer[1024]; - JSStringRef s = JSValueToStringCopy(ctx, argv[0], NULL); - JSStringGetUTF8CString(s, buffer, 1024); + char * buffer; + size_t str_size; + buffer = js_get_cstr_from_val(ctx, argv[0], &str_size); g_message("JS Log: %s", buffer); + free(buffer); return return_value; } else @@ -44,13 +66,65 @@ JSValueRef js_exists_in_mod(JSContextRef ctx, JSObjectRef func, JSObjectRef this, size_t argc, const JSValueRef argv[], JSValueRef * exception) { - if (argc < 2) + char * mod_buf, * file_buf, search_path[512]; + size_t mod_size, file_size; + JSValueRef return_value = JSValueMakeNumber(ctx, 0); + FILE * f; + if (!js_check_num_args(ctx, "existsInMod", argc, 2, exception)) + return JSValueMakeNull(ctx); + + if (!JSValueIsString(ctx, argv[0]) || !JSValueIsString(ctx, argv[1])) { - *exception = JSValueMakeString(ctx, JS_STR("Not enough args")); + *exception = JSValueMakeString(ctx, JS_STR("One or more args are incorrect types.")); return JSValueMakeNull(ctx); } - return JSValueMakeNumber(ctx, 1); + file_buf = js_get_cstr_from_val(ctx, argv[0], &file_size); + mod_buf = js_get_cstr_from_val(ctx, argv[1], &mod_size); + + sprintf(search_path, "mods/%s/%s", mod_buf, file_buf); + + free(file_buf); + free(mod_buf); + + g_message("JS ExistsInMod: Looking for %s", search_path); + + f = fopen(search_path, "r"); + + if (f != NULL) + { + g_message("JS ExistsInMod: Found"); + fclose(f); + return_value = JSValueMakeNumber(ctx, 1); + } + + return return_value; +} + +JSValueRef js_launch_mod(JSContextRef ctx, JSObjectRef func, + JSObjectRef this, size_t argc, + const JSValueRef argv[], JSValueRef * exception) +{ + char * mod; + size_t mod_size; + JSValueRef return_value = JSValueMakeNull(ctx); + + if (!js_check_num_args(ctx, "launchMod", argc, 1, exception)) + return return_value; + + if (!JSValueIsString(ctx, argv[0])) + { + *exception = JSValueMakeString(ctx, JS_STR("One or more args are incorrect types.")); + return return_value; + } + + mod = js_get_cstr_from_val(ctx, argv[0], &mod_size); + + g_message("JS LaunchMod: %s", mod); + + free(mod); + + return return_value; } void js_add_functions(JSGlobalContextRef ctx, JSObjectRef target, char ** names, @@ -71,9 +145,9 @@ void bind_js_bridge(WebKitWebView * view, WebKitWebFrame * frame, JSGlobalContextRef js_ctx; JSObjectRef window_obj, external_obj; - int func_count = 2; - char * names[] = { "log", "existsInMod" }; - JSObjectCallAsFunctionCallback callbacks[] = { js_log, js_exists_in_mod }; + int func_count = 3; + char * names[] = { "log", "existsInMod", "launchMod" }; + JSObjectCallAsFunctionCallback callbacks[] = { js_log, js_exists_in_mod, js_launch_mod }; js_ctx = (JSGlobalContextRef)context; diff --git a/OpenRA.Launcher.Gtk/main.c b/OpenRA.Launcher.Gtk/main.c index c62cfbad10..55f589ef22 100644 --- a/OpenRA.Launcher.Gtk/main.c +++ b/OpenRA.Launcher.Gtk/main.c @@ -14,6 +14,8 @@ #include "server.h" #include "bridge.h" +#define WEBSERVER_PORT 48764 + GtkWindow * window; WebKitWebView * browser; @@ -27,7 +29,7 @@ gboolean window_delete(GtkWidget * widget, GdkEvent * event, int main(int argc, char ** argv) { - server_init(48764); + server_init(WEBSERVER_PORT); gtk_init(&argc, &argv); @@ -41,6 +43,7 @@ int main(int argc, char ** argv) gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(browser)); + //TODO: Load the mod html file based on selected mod in launcher webkit_web_view_load_uri(browser, "http://localhost:48764/mods/cnc/mod.html"); diff --git a/OpenRA.Launcher.Gtk/server.c b/OpenRA.Launcher.Gtk/server.c index 92c3663ccf..5f74805022 100644 --- a/OpenRA.Launcher.Gtk/server.c +++ b/OpenRA.Launcher.Gtk/server.c @@ -20,20 +20,13 @@ struct MHD_Daemon * server; -int http_get_args(void * cls, enum MHD_ValueKind kind, - const char * key, const char * value) -{ - g_message("%s: %s", key, value); - return MHD_YES; -} - int try_file_response(const char * url, struct MHD_Connection * connection) { int fd, ret; struct MHD_Response * response; struct stat sbuf; - g_message("Opening %s", url + 1); + g_message("Web server: Opening %s", url + 1); if ((-1 == (fd = open(url + 1, O_RDONLY))) || (0 != fstat(fd, &sbuf))) @@ -60,7 +53,7 @@ int access_handler_callback(void * userdata, struct MHD_Response * response; int ret = MHD_NO; char * text = "1"; - g_message(url); + g_message("Web server: Got request for %s", url); if ((ret = try_file_response(url, connection))) return ret;