commit 75933825927c74101db4897eb308dc45ab9b0fc8
parent 4ad8e4a7073fdef762c986711f4a3b7caa1ac510
Author: Michael Savage <mikejsavage@gmail.com>
Date: Sun, 3 May 2020 01:48:13 +0300
Check appdata/my documents/exe folder for scripts
Diffstat:
7 files changed, 833 insertions(+), 40 deletions(-)
diff --git a/libs/whereami.lua b/libs/whereami.lua
@@ -0,0 +1 @@
+lib( "whereami", { "libs/whereami/whereami.cpp" } )
diff --git a/libs/whereami/whereami.cpp b/libs/whereami/whereami.cpp
@@ -0,0 +1,679 @@
+// (‑●‑●)> dual licensed under the WTFPL v2 and MIT licenses
+// without any warranty.
+// by Gregory Pakosz (@gpakosz)
+// https://github.com/gpakosz/whereami
+
+// in case you want to #include "whereami.c" in a larger compilation unit
+#if !defined(WHEREAMI_H)
+#include "whereami.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(WAI_MALLOC) || !defined(WAI_FREE) || !defined(WAI_REALLOC)
+#include <stdlib.h>
+#endif
+
+#if !defined(WAI_MALLOC)
+#define WAI_MALLOC(size) malloc(size)
+#endif
+
+#if !defined(WAI_FREE)
+#define WAI_FREE(p) free(p)
+#endif
+
+#if !defined(WAI_REALLOC)
+#define WAI_REALLOC(p, size) realloc(p, size)
+#endif
+
+#ifndef WAI_NOINLINE
+#if defined(_MSC_VER)
+#define WAI_NOINLINE __declspec(noinline)
+#elif defined(__GNUC__)
+#define WAI_NOINLINE __attribute__((noinline))
+#else
+#error unsupported compiler
+#endif
+#endif
+
+#if defined(_MSC_VER)
+#define WAI_RETURN_ADDRESS() _ReturnAddress()
+#elif defined(__GNUC__)
+#define WAI_RETURN_ADDRESS() __builtin_extract_return_addr(__builtin_return_address(0))
+#else
+#error unsupported compiler
+#endif
+
+#if defined(_WIN32)
+
+#define WIN32_LEAN_AND_MEAN
+#if defined(_MSC_VER)
+#pragma warning(push, 3)
+#endif
+#include <windows.h>
+#include <intrin.h>
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+static int WAI_PREFIX(getModulePath_)(HMODULE module, char* out, int capacity, int* dirname_length)
+{
+ wchar_t buffer1[MAX_PATH];
+ wchar_t buffer2[MAX_PATH];
+ wchar_t* path = NULL;
+ int length = -1;
+
+ for (;;)
+ {
+ DWORD size;
+ int length_, length__;
+
+ size = GetModuleFileNameW(module, buffer1, sizeof(buffer1) / sizeof(buffer1[0]));
+
+ if (size == 0)
+ break;
+ else if (size == (DWORD)(sizeof(buffer1) / sizeof(buffer1[0])))
+ {
+ DWORD size_ = size;
+ do
+ {
+ wchar_t* path_;
+
+ path_ = (wchar_t*)WAI_REALLOC(path, sizeof(wchar_t) * size_ * 2);
+ if (!path_)
+ break;
+ size_ *= 2;
+ path = path_;
+ size = GetModuleFileNameW(module, path, size_);
+ }
+ while (size == size_);
+
+ if (size == size_)
+ break;
+ }
+ else
+ path = buffer1;
+
+ if (!_wfullpath(buffer2, path, MAX_PATH))
+ break;
+ length_ = (int)wcslen(buffer2);
+ length__ = WideCharToMultiByte(CP_UTF8, 0, buffer2, length_ , out, capacity, NULL, NULL);
+
+ if (length__ == 0)
+ length__ = WideCharToMultiByte(CP_UTF8, 0, buffer2, length_, NULL, 0, NULL, NULL);
+ if (length__ == 0)
+ break;
+
+ if (length__ <= capacity && dirname_length)
+ {
+ int i;
+
+ for (i = length__ - 1; i >= 0; --i)
+ {
+ if (out[i] == '\\')
+ {
+ *dirname_length = i;
+ break;
+ }
+ }
+ }
+
+ length = length__;
+
+ break;
+ }
+
+ if (path != buffer1)
+ WAI_FREE(path);
+
+ return length;
+}
+
+WAI_NOINLINE WAI_FUNCSPEC
+int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length)
+{
+ return WAI_PREFIX(getModulePath_)(NULL, out, capacity, dirname_length);
+}
+
+WAI_NOINLINE WAI_FUNCSPEC
+int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
+{
+ HMODULE module;
+ int length = -1;
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable: 4054)
+#endif
+ if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCTSTR)WAI_RETURN_ADDRESS(), &module))
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+ {
+ length = WAI_PREFIX(getModulePath_)(module, out, capacity, dirname_length);
+ }
+
+ return length;
+}
+
+#elif defined(__linux__) || defined(__CYGWIN__) || defined(__sun) || defined(WAI_USE_PROC_SELF_EXE)
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if defined(__linux__)
+#include <linux/limits.h>
+#else
+#include <limits.h>
+#endif
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS
+#endif
+#include <inttypes.h>
+
+#if !defined(WAI_PROC_SELF_EXE)
+#if defined(__sun)
+#define WAI_PROC_SELF_EXE "/proc/self/path/a.out"
+#else
+#define WAI_PROC_SELF_EXE "/proc/self/exe"
+#endif
+#endif
+
+WAI_FUNCSPEC
+int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length)
+{
+ char buffer[PATH_MAX];
+ char* resolved = NULL;
+ int length = -1;
+
+ for (;;)
+ {
+ resolved = realpath(WAI_PROC_SELF_EXE, buffer);
+ if (!resolved)
+ break;
+
+ length = (int)strlen(resolved);
+ if (length <= capacity)
+ {
+ memcpy(out, resolved, length);
+
+ if (dirname_length)
+ {
+ int i;
+
+ for (i = length - 1; i >= 0; --i)
+ {
+ if (out[i] == '/')
+ {
+ *dirname_length = i;
+ break;
+ }
+ }
+ }
+ }
+
+ break;
+ }
+
+ return length;
+}
+
+#if !defined(WAI_PROC_SELF_MAPS_RETRY)
+#define WAI_PROC_SELF_MAPS_RETRY 5
+#endif
+
+#if !defined(WAI_PROC_SELF_MAPS)
+#if defined(__sun)
+#define WAI_PROC_SELF_MAPS "/proc/self/map"
+#else
+#define WAI_PROC_SELF_MAPS "/proc/self/maps"
+#endif
+#endif
+
+#if defined(__ANDROID__) || defined(ANDROID)
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#endif
+
+WAI_NOINLINE WAI_FUNCSPEC
+int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
+{
+ int length = -1;
+ FILE* maps = NULL;
+
+ for (int r = 0; r < WAI_PROC_SELF_MAPS_RETRY; ++r)
+ {
+ maps = fopen(WAI_PROC_SELF_MAPS, "r");
+ if (!maps)
+ break;
+
+ for (;;)
+ {
+ char buffer[PATH_MAX < 1024 ? 1024 : PATH_MAX];
+ uint64_t low, high;
+ char perms[5];
+ uint64_t offset;
+ uint32_t major, minor;
+ char path[PATH_MAX];
+ uint32_t inode;
+
+ if (!fgets(buffer, sizeof(buffer), maps))
+ break;
+
+ if (sscanf(buffer, "%" PRIx64 "-%" PRIx64 " %s %" PRIx64 " %x:%x %u %s\n", &low, &high, perms, &offset, &major, &minor, &inode, path) == 8)
+ {
+ uint64_t addr = (uintptr_t)WAI_RETURN_ADDRESS();
+ if (low <= addr && addr <= high)
+ {
+ char* resolved;
+
+ resolved = realpath(path, buffer);
+ if (!resolved)
+ break;
+
+ length = (int)strlen(resolved);
+#if defined(__ANDROID__) || defined(ANDROID)
+ if (length > 4
+ &&buffer[length - 1] == 'k'
+ &&buffer[length - 2] == 'p'
+ &&buffer[length - 3] == 'a'
+ &&buffer[length - 4] == '.')
+ {
+ int fd = open(path, O_RDONLY);
+ char* begin;
+ char* p;
+
+ begin = (char*)mmap(0, offset, PROT_READ, MAP_SHARED, fd, 0);
+ p = begin + offset;
+
+ while (p >= begin) // scan backwards
+ {
+ if (*((uint32_t*)p) == 0x04034b50UL) // local file header found
+ {
+ uint16_t length_ = *((uint16_t*)(p + 26));
+
+ if (length + 2 + length_ < (int)sizeof(buffer))
+ {
+ memcpy(&buffer[length], "!/", 2);
+ memcpy(&buffer[length + 2], p + 30, length_);
+ length += 2 + length_;
+ }
+
+ break;
+ }
+
+ p -= 4;
+ }
+
+ munmap(begin, offset);
+ close(fd);
+ }
+#endif
+ if (length <= capacity)
+ {
+ memcpy(out, resolved, length);
+
+ if (dirname_length)
+ {
+ int i;
+
+ for (i = length - 1; i >= 0; --i)
+ {
+ if (out[i] == '/')
+ {
+ *dirname_length = i;
+ break;
+ }
+ }
+ }
+ }
+
+ break;
+ }
+ }
+ }
+
+ fclose(maps);
+ maps = NULL;
+
+ if (length != -1)
+ break;
+ }
+
+ if (maps)
+ fclose(maps);
+
+ return length;
+}
+
+#elif defined(__APPLE__)
+
+#define _DARWIN_BETTER_REALPATH
+#include <mach-o/dyld.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+
+WAI_FUNCSPEC
+int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length)
+{
+ char buffer1[PATH_MAX];
+ char buffer2[PATH_MAX];
+ char* path = buffer1;
+ char* resolved = NULL;
+ int length = -1;
+
+ for (;;)
+ {
+ uint32_t size = (uint32_t)sizeof(buffer1);
+ if (_NSGetExecutablePath(path, &size) == -1)
+ {
+ path = (char*)WAI_MALLOC(size);
+ if (!_NSGetExecutablePath(path, &size))
+ break;
+ }
+
+ resolved = realpath(path, buffer2);
+ if (!resolved)
+ break;
+
+ length = (int)strlen(resolved);
+ if (length <= capacity)
+ {
+ memcpy(out, resolved, length);
+
+ if (dirname_length)
+ {
+ int i;
+
+ for (i = length - 1; i >= 0; --i)
+ {
+ if (out[i] == '/')
+ {
+ *dirname_length = i;
+ break;
+ }
+ }
+ }
+ }
+
+ break;
+ }
+
+ if (path != buffer1)
+ WAI_FREE(path);
+
+ return length;
+}
+
+WAI_NOINLINE WAI_FUNCSPEC
+int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
+{
+ char buffer[PATH_MAX];
+ char* resolved = NULL;
+ int length = -1;
+
+ for(;;)
+ {
+ Dl_info info;
+
+ if (dladdr(WAI_RETURN_ADDRESS(), &info))
+ {
+ resolved = realpath(info.dli_fname, buffer);
+ if (!resolved)
+ break;
+
+ length = (int)strlen(resolved);
+ if (length <= capacity)
+ {
+ memcpy(out, resolved, length);
+
+ if (dirname_length)
+ {
+ int i;
+
+ for (i = length - 1; i >= 0; --i)
+ {
+ if (out[i] == '/')
+ {
+ *dirname_length = i;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ break;
+ }
+
+ return length;
+}
+
+#elif defined(__QNXNTO__)
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+
+#if !defined(WAI_PROC_SELF_EXE)
+#define WAI_PROC_SELF_EXE "/proc/self/exefile"
+#endif
+
+WAI_FUNCSPEC
+int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length)
+{
+ char buffer1[PATH_MAX];
+ char buffer2[PATH_MAX];
+ char* resolved = NULL;
+ FILE* self_exe = NULL;
+ int length = -1;
+
+ for (;;)
+ {
+ self_exe = fopen(WAI_PROC_SELF_EXE, "r");
+ if (!self_exe)
+ break;
+
+ if (!fgets(buffer1, sizeof(buffer1), self_exe))
+ break;
+
+ resolved = realpath(buffer1, buffer2);
+ if (!resolved)
+ break;
+
+ length = (int)strlen(resolved);
+ if (length <= capacity)
+ {
+ memcpy(out, resolved, length);
+
+ if (dirname_length)
+ {
+ int i;
+
+ for (i = length - 1; i >= 0; --i)
+ {
+ if (out[i] == '/')
+ {
+ *dirname_length = i;
+ break;
+ }
+ }
+ }
+ }
+
+ break;
+ }
+
+ fclose(self_exe);
+
+ return length;
+}
+
+WAI_FUNCSPEC
+int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
+{
+ char buffer[PATH_MAX];
+ char* resolved = NULL;
+ int length = -1;
+
+ for(;;)
+ {
+ Dl_info info;
+
+ if (dladdr(WAI_RETURN_ADDRESS(), &info))
+ {
+ resolved = realpath(info.dli_fname, buffer);
+ if (!resolved)
+ break;
+
+ length = (int)strlen(resolved);
+ if (length <= capacity)
+ {
+ memcpy(out, resolved, length);
+
+ if (dirname_length)
+ {
+ int i;
+
+ for (i = length - 1; i >= 0; --i)
+ {
+ if (out[i] == '/')
+ {
+ *dirname_length = i;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ break;
+ }
+
+ return length;
+}
+
+#elif defined(__DragonFly__) || defined(__FreeBSD__) || \
+ defined(__FreeBSD_kernel__) || defined(__NetBSD__)
+
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <dlfcn.h>
+
+WAI_FUNCSPEC
+int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length)
+{
+ char buffer1[PATH_MAX];
+ char buffer2[PATH_MAX];
+ char* path = buffer1;
+ char* resolved = NULL;
+ int length = -1;
+
+ for (;;)
+ {
+#if defined(__NetBSD__)
+ int mib[4] = { CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME };
+#else
+ int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
+#endif
+ size_t size = sizeof(buffer1);
+
+ if (sysctl(mib, (u_int)(sizeof(mib) / sizeof(mib[0])), path, &size, NULL, 0) != 0)
+ break;
+
+ resolved = realpath(path, buffer2);
+ if (!resolved)
+ break;
+
+ length = (int)strlen(resolved);
+ if (length <= capacity)
+ {
+ memcpy(out, resolved, length);
+
+ if (dirname_length)
+ {
+ int i;
+
+ for (i = length - 1; i >= 0; --i)
+ {
+ if (out[i] == '/')
+ {
+ *dirname_length = i;
+ break;
+ }
+ }
+ }
+ }
+
+ break;
+ }
+
+ if (path != buffer1)
+ WAI_FREE(path);
+
+ return length;
+}
+
+WAI_NOINLINE WAI_FUNCSPEC
+int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
+{
+ char buffer[PATH_MAX];
+ char* resolved = NULL;
+ int length = -1;
+
+ for(;;)
+ {
+ Dl_info info;
+
+ if (dladdr(WAI_RETURN_ADDRESS(), &info))
+ {
+ resolved = realpath(info.dli_fname, buffer);
+ if (!resolved)
+ break;
+
+ length = (int)strlen(resolved);
+ if (length <= capacity)
+ {
+ memcpy(out, resolved, length);
+
+ if (dirname_length)
+ {
+ int i;
+
+ for (i = length - 1; i >= 0; --i)
+ {
+ if (out[i] == '/')
+ {
+ *dirname_length = i;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ break;
+ }
+
+ return length;
+}
+
+#else
+
+#error unsupported platform
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/libs/whereami/whereami.h b/libs/whereami/whereami.h
@@ -0,0 +1,67 @@
+// (‑●‑●)> dual licensed under the WTFPL v2 and MIT licenses
+// without any warranty.
+// by Gregory Pakosz (@gpakosz)
+// https://github.com/gpakosz/whereami
+
+#ifndef WHEREAMI_H
+#define WHEREAMI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef WAI_FUNCSPEC
+ #define WAI_FUNCSPEC
+#endif
+#ifndef WAI_PREFIX
+#define WAI_PREFIX(function) wai_##function
+#endif
+
+/**
+ * Returns the path to the current executable.
+ *
+ * Usage:
+ * - first call `int length = wai_getExecutablePath(NULL, 0, NULL);` to
+ * retrieve the length of the path
+ * - allocate the destination buffer with `path = (char*)malloc(length + 1);`
+ * - call `wai_getExecutablePath(path, length, NULL)` again to retrieve the
+ * path
+ * - add a terminal NUL character with `path[length] = '\0';`
+ *
+ * @param out destination buffer, optional
+ * @param capacity destination buffer capacity
+ * @param dirname_length optional recipient for the length of the dirname part
+ * of the path.
+ *
+ * @return the length of the executable path on success (without a terminal NUL
+ * character), otherwise `-1`
+ */
+WAI_FUNCSPEC
+int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length);
+
+/**
+ * Returns the path to the current module
+ *
+ * Usage:
+ * - first call `int length = wai_getModulePath(NULL, 0, NULL);` to retrieve
+ * the length of the path
+ * - allocate the destination buffer with `path = (char*)malloc(length + 1);`
+ * - call `wai_getModulePath(path, length, NULL)` again to retrieve the path
+ * - add a terminal NUL character with `path[length] = '\0';`
+ *
+ * @param out destination buffer, optional
+ * @param capacity destination buffer capacity
+ * @param dirname_length optional recipient for the length of the dirname part
+ * of the path.
+ *
+ * @return the length of the module path on success (without a terminal NUL
+ * character), otherwise `-1`
+ */
+WAI_FUNCSPEC
+int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // #ifndef WHEREAMI_H
diff --git a/make.lua b/make.lua
@@ -1,6 +1,7 @@
require( "ggbuild.gen_ninja" )
require( "libs.tracy" )
+require( "libs.whereami" )
obj_cxxflags( ".*", "-I source -I libs" )
@@ -37,7 +38,11 @@ bin( "mudgangster", {
"src/ui.cc", "src/script.cc", "src/textbox.cc", "src/input.cc", "src/platform_network.cc",
},
- libs = { platform_libs, "tracy" },
+ libs = {
+ platform_libs,
+ "tracy",
+ "whereami"
+ },
rc = "src/rc",
diff --git a/src/lua/main.lua b/src/lua/main.lua
@@ -15,7 +15,8 @@ local handlers = require( "handlers" )
local printMain, newlineMain, printChat, newlineChat,
setHandlers, urgent, setStatus,
sock_connect, sock_send, sock_close,
- get_time, set_font = ...
+ get_time, set_font,
+ exe_path = ...
local socket_api = {
connect = sock_connect,
@@ -51,4 +52,4 @@ require( "status" ).init( setStatus )
setHandlers( handlers.input, handlers.macro, handlers.close, socket_data_handler, handlers.interval )
-script.load()
+script.load( exe_path )
diff --git a/src/lua/script.lua b/src/lua/script.lua
@@ -1,14 +1,25 @@
local lfs = require( "lfs" )
local serialize = require( "serialize" )
-local ScriptsDir
+local ScriptsDirs
if mud.os == "windows" then
- ScriptsDir = os.getenv( "APPDATA" ) .. "\\Mud Gangster\\scripts"
+ ScriptsDirs = {
+ os.getenv( "APPDATA" ) .. "\\Mud Gangster\\scripts",
+ os.getenv( "USERPROFILE" ) .. "\\Documents\\Mud Gangster\\scripts",
+ }
else
- ScriptsDir = os.getenv( "HOME" ) .. "/.mudgangster/scripts"
+ ScriptsDirs = { os.getenv( "HOME" ) .. "/.mudgangster/scripts" }
end
-package.path = package.path .. ";" .. ScriptsDir .. "/?.lua"
+-- TODO: missing exe dir
+do
+ local paths = { }
+ for _, dir in ipairs( ScriptsDirs ) do
+ table.insert( paths, dir .. "/?.lua" )
+ end
+
+ package.path = package.path .. ";" .. table.concat( paths, ";" )
+end
local function loadScript( name, path, padding )
local function throw( err )
@@ -92,55 +103,60 @@ local function loadScript( name, path, padding )
end
end
-local function loadScripts()
- mud.print( "#s> Loading scripts..." )
+local function loadScriptsFrom( dir )
+ mud.print( "\n#s> Loading scripts from %s... ", dir )
+
+ local readable, err = io.readable( dir )
- local readable, err = io.readable( ScriptsDir )
+ if not readable then
+ mud.print( "#lrfailed!\n#s> %s", err )
+ return
+ end
- if readable then
- local attr = lfs.attributes( ScriptsDir )
+ local attr = lfs.attributes( dir )
- if attr.mode == "directory" then
- local scripts = { }
- local maxLen = 0
+ if attr.mode == "directory" then
+ local scripts = { }
+ local maxLen = 0
- for script in lfs.dir( ScriptsDir ) do
- if not script:match( "^%." ) then
- local path = ScriptsDir .. "/" .. script
- local scriptAttr = lfs.attributes( path )
+ for script in lfs.dir( dir ) do
+ if not script:match( "^%." ) then
+ local path = dir .. "/" .. script
+ local scriptAttr = lfs.attributes( path )
- if scriptAttr.mode == "directory" then
- maxLen = math.max( script:len(), maxLen )
+ if scriptAttr.mode == "directory" then
+ maxLen = math.max( script:len(), maxLen )
- table.insert( scripts, {
- name = script,
- path = path,
- } )
- end
+ table.insert( scripts, {
+ name = script,
+ path = path,
+ } )
end
end
+ end
- table.sort( scripts, function( a, b )
- return a.name < b.name
- end )
+ table.sort( scripts, function( a, b )
+ return a.name < b.name
+ end )
- for _, script in ipairs( scripts ) do
- loadScript( script.name, script.path, maxLen )
- end
- else
- mud.print( "#sfailed!\n> `%s' isn't a directory", ScriptsDir )
+ for _, script in ipairs( scripts ) do
+ loadScript( script.name, script.path, maxLen )
end
else
- mud.print( "#sfailed!\n> %s", err )
+ mud.print( "#lrfailed!\n#s> `%s' isn't a directory", dir )
end
-
- mud.event( "scriptsLoaded" )
end
-local function closeScripts()
+local function loadScripts( exe_path )
+ for _, dir in ipairs( ScriptsDirs ) do
+ loadScriptsFrom( dir )
+ end
+
+ loadScriptsFrom( exe_path .. "/scripts" )
+
+ mud.event( "scriptsLoaded" )
end
return {
load = loadScripts,
- close = closeScripts,
}
diff --git a/src/script.cc b/src/script.cc
@@ -10,6 +10,8 @@
#include <lua.hpp>
#endif
+#include "whereami/whereami.h"
+
#if LUA_VERSION_NUM < 502
#define luaL_len lua_objlen
#endif
@@ -246,6 +248,26 @@ extern "C" int mud_set_font( lua_State * L ) {
} // anon namespace
+static void push_exe_dir( lua_State * L ) {
+ int len = wai_getExecutablePath( NULL, 0, NULL );
+ if( len == -1 ) {
+ lua_pushliteral( L, "." );
+ }
+ else {
+ char * buf = alloc_many< char >( len );
+
+ int dirlen;
+ if( wai_getExecutablePath( buf, len, &dirlen ) == -1 ) {
+ lua_pushliteral( L, "." );
+ }
+ else {
+ lua_pushlstring( L, buf, dirlen );
+ }
+
+ free( buf );
+ }
+}
+
#if PLATFORM_WINDOWS
extern "C" int luaopen_lpeg( lua_State * L );
extern "C" int luaopen_lfs( lua_State * L );
@@ -293,7 +315,9 @@ void script_init() {
lua_pushcfunction( lua, mud_set_font );
- pcall( 12, "Error running main.lua" );
+ push_exe_dir( lua );
+
+ pcall( 13, "Error running main.lua" );
}
void script_term() {