diff --git a/code/__DEFINES/_versions.dm b/code/__DEFINES/_versions.dm index 5670b470a8d..04554bf8b38 100644 --- a/code/__DEFINES/_versions.dm +++ b/code/__DEFINES/_versions.dm @@ -1,2 +1,2 @@ /// Version of RUST-G that this codebase wants -#define RUST_G_VERSION "0.6.0-P" +#define RUST_G_VERSION "1.2.0-P" diff --git a/code/__DEFINES/rust_g.dm b/code/__DEFINES/rust_g.dm index e134f8ef99e..38fa433a549 100644 --- a/code/__DEFINES/rust_g.dm +++ b/code/__DEFINES/rust_g.dm @@ -38,9 +38,17 @@ #define RUST_G (__rust_g || __detect_rust_g()) #endif -/// Gets the version of rust_g -/proc/rustg_get_version() return call(RUST_G, "get_version")() +// Handle 515 call() -> call_ext() changes +#if DM_VERSION >= 515 +#define RUSTG_CALL call_ext +#else +#define RUSTG_CALL call +#endif +/// Gets the version of rust_g +/proc/rustg_get_version() return RUSTG_CALL(RUST_G, "get_version")() + +// Aho-Corasick Replace // /** * Sets up the Aho-Corasick automaton with its default options. @@ -51,7 +59,7 @@ * * patterns - A non-associative list of strings to search for * * replacements - Default replacements for this automaton, used with rustg_acreplace */ -#define rustg_setup_acreplace(key, patterns, replacements) call(RUST_G, "setup_acreplace")(key, json_encode(patterns), json_encode(replacements)) +#define rustg_setup_acreplace(key, patterns, replacements) RUSTG_CALL(RUST_G, "setup_acreplace")(key, json_encode(patterns), json_encode(replacements)) /** * Sets up the Aho-Corasick automaton using supplied options. @@ -63,7 +71,7 @@ * * patterns - A non-associative list of strings to search for * * replacements - Default replacements for this automaton, used with rustg_acreplace */ -#define rustg_setup_acreplace_with_options(key, options, patterns, replacements) call(RUST_G, "setup_acreplace")(key, json_encode(options), json_encode(patterns), json_encode(replacements)) +#define rustg_setup_acreplace_with_options(key, options, patterns, replacements) RUSTG_CALL(RUST_G, "setup_acreplace")(key, json_encode(options), json_encode(patterns), json_encode(replacements)) /** * Run the specified replacement engine with the provided haystack text to replace, returning replaced text. @@ -72,7 +80,7 @@ * * key - The key for the automaton * * text - Text to run replacements on */ -#define rustg_acreplace(key, text) call(RUST_G, "acreplace")(key, text) +#define rustg_acreplace(key, text) RUSTG_CALL(RUST_G, "acreplace")(key, text) /** * Run the specified replacement engine with the provided haystack text to replace, returning replaced text. @@ -82,9 +90,9 @@ * * text - Text to run replacements on * * replacements - Replacements for this call. Must be the same length as the set-up patterns */ -#define rustg_acreplace_with_replacements(key, text, replacements) call(RUST_G, "acreplace_with_replacements")(key, text, json_encode(replacements)) +#define rustg_acreplace_with_replacements(key, text, replacements) RUSTG_CALL(RUST_G, "acreplace_with_replacements")(key, text, json_encode(replacements)) -// Cellular Noise Operations // +// Cellular Noise // /** * This proc generates a cellular automata noise grid which can be used in procedural generation methods. @@ -100,18 +108,41 @@ * * height: The height of the grid. */ #define rustg_cnoise_generate(percentage, smoothing_iterations, birth_limit, death_limit, width, height) \ - call(RUST_G, "cnoise_generate")(percentage, smoothing_iterations, birth_limit, death_limit, width, height) + RUSTG_CALL(RUST_G, "cnoise_generate")(percentage, smoothing_iterations, birth_limit, death_limit, width, height) + +// Grid Perlin Noise // + +/** + * This proc generates a grid of perlin-like noise + * + * Returns a single string that goes row by row, with values of 1 representing an turned on cell, and a value of 0 representing a turned off cell. + * + * Arguments: + * * seed: seed for the function + * * accuracy: how close this is to the original perlin noise, as accuracy approaches infinity, the noise becomes more and more perlin-like + * * stamp_size: Size of a singular stamp used by the algorithm, think of this as the same stuff as frequency in perlin noise + * * world_size: size of the returned grid. + * * lower_range: lower bound of values selected for. (inclusive) + * * upper_range: upper bound of values selected for. (exclusive) + */ +#define rustg_dbp_generate(seed, accuracy, stamp_size, world_size, lower_range, upper_range) \ + RUSTG_CALL(RUST_G, "dbp_generate")(seed, accuracy, stamp_size, world_size, lower_range, upper_range) + // DMI Operations // -#define rustg_dmi_strip_metadata(fname) call(RUST_G, "dmi_strip_metadata")(fname) -#define rustg_dmi_create_png(path, width, height, data) call(RUST_G, "dmi_create_png")(path, width, height, data) -#define rustg_dmi_resize_png(path, width, height, resizetype) call(RUST_G, "dmi_resize_png")(path, width, height, resizetype) + +#define rustg_dmi_strip_metadata(fname) RUSTG_CALL(RUST_G, "dmi_strip_metadata")(fname) +#define rustg_dmi_create_png(path, width, height, data) RUSTG_CALL(RUST_G, "dmi_create_png")(path, width, height, data) +#define rustg_dmi_resize_png(path, width, height, resizetype) RUSTG_CALL(RUST_G, "dmi_resize_png")(path, width, height, resizetype) // File Operations // -#define rustg_file_read(fname) call(RUST_G, "file_read")(fname) -#define rustg_file_exists(fname) call(RUST_G, "file_exists")(fname) -#define rustg_file_write(text, fname) call(RUST_G, "file_write")(text, fname) -#define rustg_file_append(text, fname) call(RUST_G, "file_append")(text, fname) + +#define rustg_file_read(fname) RUSTG_CALL(RUST_G, "file_read")(fname) +#define rustg_file_exists(fname) RUSTG_CALL(RUST_G, "file_exists")(fname) +#define rustg_file_write(text, fname) RUSTG_CALL(RUST_G, "file_write")(text, fname) +#define rustg_file_append(text, fname) RUSTG_CALL(RUST_G, "file_append")(text, fname) +#define rustg_file_get_line_count(fname) text2num(RUSTG_CALL(RUST_G, "file_get_line_count")(fname)) +#define rustg_file_seek_line(fname, line) RUSTG_CALL(RUST_G, "file_seek_line")(fname, "[line]") #ifdef RUSTG_OVERRIDE_BUILTINS #define file2text(fname) rustg_file_read("[fname]") @@ -119,14 +150,16 @@ #endif // Git Operations // -#define rustg_git_revparse(rev) call(RUST_G, "rg_git_revparse")(rev) -#define rustg_git_commit_date(rev) call(RUST_G, "rg_git_commit_date")(rev) -// Hashing Operations // -#define rustg_hash_string(algorithm, text) call(RUST_G, "hash_string")(algorithm, text) -#define rustg_hash_file(algorithm, fname) call(RUST_G, "hash_file")(algorithm, fname) -#define rustg_hash_generate_totp(seed) call(RUST_G, "generate_totp")(seed) -#define rustg_hash_generate_totp_tolerance(seed, tolerance) call(RUST_G, "generate_totp_tolerance")(seed, tolerance) +#define rustg_git_revparse(rev) RUSTG_CALL(RUST_G, "rg_git_revparse")(rev) +#define rustg_git_commit_date(rev) RUSTG_CALL(RUST_G, "rg_git_commit_date")(rev) + +// Hashing Functions // + +#define rustg_hash_string(algorithm, text) RUSTG_CALL(RUST_G, "hash_string")(algorithm, text) +#define rustg_hash_file(algorithm, fname) RUSTG_CALL(RUST_G, "hash_file")(algorithm, fname) +#define rustg_hash_generate_totp(seed) RUSTG_CALL(RUST_G, "generate_totp")(seed) +#define rustg_hash_generate_totp_tolerance(seed, tolerance) RUSTG_CALL(RUST_G, "generate_totp_tolerance")(seed, tolerance) #define RUSTG_HASH_MD5 "md5" #define RUSTG_HASH_SHA1 "sha1" @@ -140,66 +173,152 @@ #endif // HTTP Operations // + #define RUSTG_HTTP_METHOD_GET "get" #define RUSTG_HTTP_METHOD_PUT "put" #define RUSTG_HTTP_METHOD_DELETE "delete" #define RUSTG_HTTP_METHOD_PATCH "patch" #define RUSTG_HTTP_METHOD_HEAD "head" #define RUSTG_HTTP_METHOD_POST "post" -#define rustg_http_request_blocking(method, url, body, headers, options) call(RUST_G, "http_request_blocking")(method, url, body, headers, options) -#define rustg_http_request_async(method, url, body, headers, options) call(RUST_G, "http_request_async")(method, url, body, headers, options) -#define rustg_http_check_request(req_id) call(RUST_G, "http_check_request")(req_id) -/proc/rustg_create_async_http_client() return call(RUST_G, "start_http_client")() -/proc/rustg_close_async_http_client() return call(RUST_G, "shutdown_http_client")() +#define rustg_http_request_blocking(method, url, body, headers, options) RUSTG_CALL(RUST_G, "http_request_blocking")(method, url, body, headers, options) +#define rustg_http_request_async(method, url, body, headers, options) RUSTG_CALL(RUST_G, "http_request_async")(method, url, body, headers, options) +#define rustg_http_check_request(req_id) RUSTG_CALL(RUST_G, "http_check_request")(req_id) +/proc/rustg_create_async_http_client() return RUSTG_CALL(RUST_G, "start_http_client")() +/proc/rustg_close_async_http_client() return RUSTG_CALL(RUST_G, "shutdown_http_client")() + +// Jobs Defines // -// Jobs Subsystem Operations // #define RUSTG_JOB_NO_RESULTS_YET "NO RESULTS YET" #define RUSTG_JOB_NO_SUCH_JOB "NO SUCH JOB" #define RUSTG_JOB_ERROR "JOB PANICKED" // JSON Operations // -#define rustg_json_is_valid(text) (call(RUST_G, "json_is_valid")(text) == "true") + +#define rustg_json_is_valid(text) (RUSTG_CALL(RUST_G, "json_is_valid")(text) == "true") // Logging Operations // -#define rustg_log_write(fname, text) call(RUST_G, "log_write")(fname, text) -/proc/rustg_log_close_all() return call(RUST_G, "log_close_all")() + +#define rustg_log_write(fname, text) RUSTG_CALL(RUST_G, "log_write")(fname, text) +/proc/rustg_log_close_all() return RUSTG_CALL(RUST_G, "log_close_all")() // Noise Operations // -#define rustg_noise_get_at_coordinates(seed, x, y) call(RUST_G, "noise_get_at_coordinates")(seed, x, y) + +#define rustg_noise_get_at_coordinates(seed, x, y) RUSTG_CALL(RUST_G, "noise_get_at_coordinates")(seed, x, y) + +// AStar Operations // + +/** + * Register a list of nodes into a rust library. This list of nodes must have been serialized in a json. + * Node {// Index of this node in the list of nodes + * unique_id: usize, + * // Position of the node in byond + * x: usize, + * y: usize, + * z: usize, + * // Indexes of nodes connected to this one + * connected_nodes_id: Vec} + * It is important that the node with the unique_id 0 is the first in the json, unique_id 1 right after that, etc. + * It is also important that all unique ids follow. {0, 1, 2, 4} is not a correct list and the registering will fail + * Nodes should not link across z levels. + * A node cannot link twice to the same node and shouldn't link itself either + */ +#define rustg_register_nodes_astar(json) RUSTG_CALL(RUST_G, "register_nodes_astar")(json) + +/** + * Add a new node to the static list of nodes. Same rule as registering_nodes applies. + * This node unique_id must be equal to the current length of the static list of nodes + */ +#define rustg_add_node_astar(json) RUSTG_CALL(RUST_G, "add_node_astar")(json) + +/**² + * Remove every link to the node with unique_id. Replace that node by null + */ +#define rustg_remove_node_astart(unique_id) RUSTG_CALL(RUST_G, "remove_node_astar")(unique_id) + +/** + * Compute the shortest path between start_node and goal_node using A*. Heuristic used is simple geometric distance + */ +#define rustg_generate_path_astar(start_node_id, goal_node_id) RUSTG_CALL(RUST_G, "generate_path_astar")(start_node_id, goal_node_id) + +// Redis PubSub Operations // #define RUSTG_REDIS_ERROR_CHANNEL "RUSTG_REDIS_ERROR_CHANNEL" -#define rustg_redis_connect(addr) call(RUST_G, "redis_connect")(addr) -/proc/rustg_redis_disconnect() return call(RUST_G, "redis_disconnect")() -#define rustg_redis_subscribe(channel) call(RUST_G, "redis_subscribe")(channel) -/proc/rustg_redis_get_messages() return call(RUST_G, "redis_get_messages")() -#define rustg_redis_publish(channel, message) call(RUST_G, "redis_publish")(channel, message) +#define rustg_redis_connect(addr) RUSTG_CALL(RUST_G, "redis_connect")(addr) +/proc/rustg_redis_disconnect() return RUSTG_CALL(RUST_G, "redis_disconnect")() +#define rustg_redis_subscribe(channel) RUSTG_CALL(RUST_G, "redis_subscribe")(channel) +/proc/rustg_redis_get_messages() return RUSTG_CALL(RUST_G, "redis_get_messages")() +#define rustg_redis_publish(channel, message) RUSTG_CALL(RUST_G, "redis_publish")(channel, message) -// SQL Opeartions // -#define rustg_sql_connect_pool(options) call(RUST_G, "sql_connect_pool")(options) -#define rustg_sql_query_async(handle, query, params) call(RUST_G, "sql_query_async")(handle, query, params) -#define rustg_sql_query_blocking(handle, query, params) call(RUST_G, "sql_query_blocking")(handle, query, params) -#define rustg_sql_connected(handle) call(RUST_G, "sql_connected")(handle) -#define rustg_sql_disconnect_pool(handle) call(RUST_G, "sql_disconnect_pool")(handle) -#define rustg_sql_check_query(job_id) call(RUST_G, "sql_check_query")("[job_id]") +// SQL Operations // -#define rustg_time_microseconds(id) text2num(call(RUST_G, "time_microseconds")(id)) -#define rustg_time_milliseconds(id) text2num(call(RUST_G, "time_milliseconds")(id)) -#define rustg_time_reset(id) call(RUST_G, "time_reset")(id) +#define rustg_sql_connect_pool(options) RUSTG_CALL(RUST_G, "sql_connect_pool")(options) +#define rustg_sql_query_async(handle, query, params) RUSTG_CALL(RUST_G, "sql_query_async")(handle, query, params) +#define rustg_sql_query_blocking(handle, query, params) RUSTG_CALL(RUST_G, "sql_query_blocking")(handle, query, params) +#define rustg_sql_connected(handle) RUSTG_CALL(RUST_G, "sql_connected")(handle) +#define rustg_sql_disconnect_pool(handle) RUSTG_CALL(RUST_G, "sql_disconnect_pool")(handle) +#define rustg_sql_check_query(job_id) RUSTG_CALL(RUST_G, "sql_check_query")("[job_id]") + +// Time Tracking Functions // + +#define rustg_time_microseconds(id) text2num(RUSTG_CALL(RUST_G, "time_microseconds")(id)) +#define rustg_time_milliseconds(id) text2num(RUSTG_CALL(RUST_G, "time_milliseconds")(id)) +#define rustg_time_reset(id) RUSTG_CALL(RUST_G, "time_reset")(id) + +/proc/rustg_unix_timestamp() + return text2num(RUSTG_CALL(RUST_G, "unix_timestamp")()) // TOML Operations // -#define rustg_read_toml_file(path) json_decode(call(RUST_G, "toml_file_to_json")(path) || "null") -// Unzip Operations // -#define rustg_unzip_download_async(url, unzip_directory) call(RUST_G, "unzip_download_async")(url, unzip_directory) -#define rustg_unzip_check(job_id) call(RUST_G, "unzip_check")("[job_id]") +#define rustg_raw_read_toml_file(path) json_decode(RUSTG_CALL(RUST_G, "toml_file_to_json")(path) || "null") -// URL Encoder/Decoder Operations // -#define rustg_url_encode(text) call(RUST_G, "url_encode")("[text]") -#define rustg_url_decode(text) call(RUST_G, "url_decode")(text) +/proc/rustg_read_toml_file(path) + var/list/output = rustg_raw_read_toml_file(path) + if (output["success"]) + return json_decode(output["content"]) + else + CRASH(output["content"]) + +#define rustg_raw_toml_encode(value) json_decode(RUSTG_CALL(RUST_G, "toml_encode")(json_encode(value))) + +/proc/rustg_toml_encode(value) + var/list/output = rustg_raw_toml_encode(value) + if (output["success"]) + return output["content"] + else + CRASH(output["content"]) + +// ZIP File Operations // + +#define rustg_unzip_download_async(url, unzip_directory) RUSTG_CALL(RUST_G, "unzip_download_async")(url, unzip_directory) +#define rustg_unzip_check(job_id) RUSTG_CALL(RUST_G, "unzip_check")("[job_id]") + +// URL Operations // + +#define rustg_url_encode(text) RUSTG_CALL(RUST_G, "url_encode")("[text]") +#define rustg_url_decode(text) RUSTG_CALL(RUST_G, "url_decode")(text) #ifdef RUSTG_OVERRIDE_BUILTINS #define url_encode(text) rustg_url_encode(text) #define url_decode(text) rustg_url_decode(text) #endif +// Worley Noise Operations // + +/** + * This proc generates a noise grid using worley noise algorithm + * + * Returns a single string that goes row by row, with values of 1 representing an alive cell, and a value of 0 representing a dead cell. + * + * Arguments: + * * region_size: The size of regions + * * threshold: the value that determines wether a cell is dead or alive + * * node_per_region_chance: chance of a node existiing in a region + * * size: size of the returned grid + * * node_min: minimum amount of nodes in a region (after the node_per_region_chance is applied) + * * node_max: maximum amount of nodes in a region + */ +#define rustg_worley_generate(region_size, threshold, node_per_region_chance, size, node_min, node_max) \ + RUSTG_CALL(RUST_G, "worley_generate")(region_size, threshold, node_per_region_chance, size, node_min, node_max) + + diff --git a/code/__DEFINES/tgs.dm b/code/__DEFINES/tgs.dm index af09ab67110..83e06658c57 100644 --- a/code/__DEFINES/tgs.dm +++ b/code/__DEFINES/tgs.dm @@ -1,6 +1,6 @@ // tgstation-server DMAPI -#define TGS_DMAPI_VERSION "6.0.3" +#define TGS_DMAPI_VERSION "6.0.6" // All functions and datums outside this document are subject to change with any version and should not be relied on. @@ -102,6 +102,8 @@ // #define TGS_EVENT_WORLD_REBOOT 20 /// Watchdog event when TgsInitializationComplete() is called. No parameters. #define TGS_EVENT_WORLD_PRIME 21 +// DMAPI also doesnt implement this +// #define TGS_EVENT_DREAM_DAEMON_LAUNCH 22 // OTHER ENUMS diff --git a/code/modules/tgs/README.md b/code/modules/tgs/README.md index 445cee41f57..6319028d810 100644 --- a/code/modules/tgs/README.md +++ b/code/modules/tgs/README.md @@ -7,7 +7,7 @@ This folder should be placed on it's own inside a codebase that wishes to use th - The other versioned folders contain code for the different DMAPI versions. - [v3210](./v3210) contains the final TGS3 API. - [v4](./v4) is the legacy DMAPI 4 (Used in TGS 4.0.X versions). - - [v5](./v5) is the current DMAPI version used by TGS4 >=4.1. + - [v5](./v5) is the current DMAPI version used by TGS >=4.1. - [LICENSE](./LICENSE) is the MIT license for the DMAPI. APIs communicate with TGS in two ways. All versions implement TGS -> DM communication using /world/Topic. DM -> TGS communication, called the bridge method, is different for each version. diff --git a/code/modules/tgs/v3210/api.dm b/code/modules/tgs/v3210/api.dm index 63823251001..3c218d5b10b 100644 --- a/code/modules/tgs/v3210/api.dm +++ b/code/modules/tgs/v3210/api.dm @@ -28,6 +28,8 @@ #define SERVICE_RETURN_SUCCESS "SUCCESS" +#define TGS_FILE2LIST(filename) (splittext(trim_left(trim_right(file2text(filename))), "\n")) + /datum/tgs_api/v3210 var/reboot_mode = REBOOT_MODE_NORMAL var/comms_key @@ -53,9 +55,6 @@ return copytext(text, 1, i + 1) return "" -/datum/tgs_api/v3210/proc/file2list(filename) - return splittext(trim_left(trim_right(file2text(filename))), "\n") - /datum/tgs_api/v3210/OnWorldNew(minimum_required_security_level) . = FALSE @@ -64,13 +63,21 @@ if(!instance_name) instance_name = "TG Station Server" //maybe just upgraded - var/list/logs = file2list(".git/logs/HEAD") + var/list/logs = TGS_FILE2LIST(".git/logs/HEAD") if(logs.len) - logs = splittext(logs[logs.len - 1], " ") - commit = logs[2] - logs = file2list(".git/logs/refs/remotes/origin/master") + logs = splittext(logs[logs.len], " ") + if (logs.len >= 2) + commit = logs[2] + else + TGS_ERROR_LOG("Error parsing commit logs") + + logs = TGS_FILE2LIST(".git/logs/refs/remotes/origin/master") if(logs.len) - originmastercommit = splittext(logs[logs.len - 1], " ")[2] + logs = splittext(logs[logs.len], " ") + if (logs.len >= 2) + originmastercommit = logs[2] + else + TGS_ERROR_LOG("Error parsing origin commmit logs") if(world.system_type != MS_WINDOWS) TGS_ERROR_LOG("This API version is only supported on Windows. Not running on Windows. Aborting initialization!") @@ -92,7 +99,11 @@ if(skip_compat_check && !fexists(SERVICE_INTERFACE_DLL)) TGS_ERROR_LOG("Service parameter present but no interface DLL detected. This is symptomatic of running a service less than version 3.1! Please upgrade.") return + #if DM_VERSION >= 515 + call_ext(SERVICE_INTERFACE_DLL, SERVICE_INTERFACE_FUNCTION)(instance_name, command) //trust no retval + #else call(SERVICE_INTERFACE_DLL, SERVICE_INTERFACE_FUNCTION)(instance_name, command) //trust no retval + #endif return TRUE /datum/tgs_api/v3210/OnTopic(T) @@ -226,3 +237,5 @@ #undef SERVICE_REQUEST_API_VERSION #undef SERVICE_RETURN_SUCCESS + +#undef TGS_FILE2LIST diff --git a/code/modules/tgs/v5/api.dm b/code/modules/tgs/v5/api.dm index 704ff873c0a..572944ed401 100644 --- a/code/modules/tgs/v5/api.dm +++ b/code/modules/tgs/v5/api.dm @@ -269,7 +269,7 @@ if(!result) return - //okay so the standard TGS4 proceedure is: right before rebooting change the port to whatever was sent to us in the above json's data parameter + //okay so the standard TGS proceedure is: right before rebooting change the port to whatever was sent to us in the above json's data parameter var/port = result[DMAPI5_BRIDGE_RESPONSE_NEW_PORT] if(!isnum(port)) diff --git a/librust_g.so b/librust_g.so index 5374aaa8415..9ac58d5344e 100644 Binary files a/librust_g.so and b/librust_g.so differ diff --git a/rust_g.dll b/rust_g.dll index 4fc9d9b56d1..9207d9bbf32 100644 Binary files a/rust_g.dll and b/rust_g.dll differ