From 6401bf07e6f10cff425e939e865e40081d61bbf3 Mon Sep 17 00:00:00 2001 From: Flleeppyy Date: Tue, 16 Dec 2025 03:16:23 -0800 Subject: [PATCH 1/2] mrrrrp~ --- cev_eris.dme | 1 + code/__DEFINES/rust_g.dm | 72 ++++++++++++++++++- code/__DEFINES/rust_g_uuid.dm | 15 ++++ .../batched/batched_spritesheet.dm | 4 +- .../spritesheet/batched/universal_icon.dm | 2 +- dependencies.sh | 2 +- tools/tgs4_scripts/PreCompile.sh | 2 +- 7 files changed, 91 insertions(+), 7 deletions(-) create mode 100644 code/__DEFINES/rust_g_uuid.dm diff --git a/cev_eris.dme b/cev_eris.dme index b79f0b9df93..4918741c544 100644 --- a/cev_eris.dme +++ b/cev_eris.dme @@ -86,6 +86,7 @@ #include "code\__DEFINES\research.dm" #include "code\__DEFINES\rust_g.dm" #include "code\__DEFINES\rust_g_overrides.dm" +#include "code\__DEFINES\rust_g_uuid.dm" #include "code\__DEFINES\sanity.dm" #include "code\__DEFINES\say.dm" #include "code\__DEFINES\shields.dm" diff --git a/code/__DEFINES/rust_g.dm b/code/__DEFINES/rust_g.dm index 8387bd0bf64..877d06ed19f 100644 --- a/code/__DEFINES/rust_g.dm +++ b/code/__DEFINES/rust_g.dm @@ -42,7 +42,12 @@ #define RUST_G (__rust_g || __detect_rust_g()) #endif +// 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")() @@ -133,6 +138,39 @@ */ #define rustg_dmi_icon_states(fname) RUSTG_CALL(RUST_G, "dmi_icon_states")(fname) +/** + * The below functions involve dmi metadata represented in the following format: + * list( + * "width": number, + * "height": number, + * "states": list([STATE_DATA], ...) + * ) + * + * STATE_DATA format: + * list( + * "name": string, + * "dirs": 1 | 4 | 8, + * "delays"?: list(number, ...), + * "rewind"?: TRUE | FALSE, + * "movement"?: TRUE | FALSE, + * "loop"?: number + * ) + */ + +/** + * Get the dmi metadata of the file located at `fname`. + * Returns a list in the metadata format listed above, or an error message. + */ +#define rustg_dmi_read_metadata(fname) json_decode(RUSTG_CALL(RUST_G, "dmi_read_metadata")(fname)) +/** + * Inject dmi metadata into a png file located at `path`. + * `metadata` must be a json_encode'd list in the metadata format listed above. + */ +#define rustg_dmi_inject_metadata(path, metadata) RUSTG_CALL(RUST_G, "dmi_inject_metadata")(path, metadata) + +#define rustg_create_qr_code_png(path, data) RUSTG_CALL(RUST_G, "create_qr_code_png")(path, data) +#define rustg_create_qr_code_svg(data) RUSTG_CALL(RUST_G, "create_qr_code_svg")(data) + #define rustg_file_read(fname) RUSTG_CALL(RUST_G, "file_read")(fname) #define rustg_file_exists(fname) (RUSTG_CALL(RUST_G, "file_exists")(fname) == "true") #define rustg_file_write(text, fname) RUSTG_CALL(RUST_G, "file_write")(text, fname) @@ -193,6 +231,9 @@ #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) +/// This is basically just `rustg_http_request_async` if you don't care about the response. +/// This will either return "ok" or an error, as this does not create a job. +#define rustg_http_request_fire_and_forget(method, url, body, headers, options) RUSTG_CALL(RUST_G, "http_request_fire_and_forget")(method, url, body, headers, options) /// Generates a spritesheet at: [file_path][spritesheet_name]_[size_id].[png or dmi] /// The resulting spritesheet arranges icons in a random order, with the position being denoted in the "sprites" return value. @@ -220,9 +261,15 @@ /// ) /// TRANSFORM_OBJECT format: /// list("type" = RUSTG_ICONFORGE_BLEND_COLOR, "color" = "#ff0000", "blend_mode" = ICON_MULTIPLY) -/// list("type" = RUSTG_ICONFORGE_BLEND_ICON, "icon" = [SPRITE_OBJECT], "blend_mode" = ICON_OVERLAY) +/// list("type" = RUSTG_ICONFORGE_BLEND_ICON, "icon" = [SPRITE_OBJECT], "blend_mode" = ICON_OVERLAY, "x" = 1, "y" = 1) // offsets optional /// list("type" = RUSTG_ICONFORGE_SCALE, "width" = 32, "height" = 32) /// list("type" = RUSTG_ICONFORGE_CROP, "x1" = 1, "y1" = 1, "x2" = 32, "y2" = 32) // (BYOND icons index from 1,1 to the upper bound, inclusive) +/// list("type" = RUSTG_ICONFORGE_MAP_COLORS, "rr" = 0.5, "rg" = 0.5, "rb" = 0.5, "ra" = 1, "gr" = 1, "gg" = 1, "gb" = 1, "ga" = 1, ...) // alpha arguments and rgba0 optional +/// list("type" = RUSTG_ICONFORGE_FLIP, "dir" = SOUTH) +/// list("type" = RUSTG_ICONFORGE_TURN, "angle" = 90.0) +/// list("type" = RUSTG_ICONFORGE_SHIFT, "dir" = EAST, "offset" = 10, "wrap" = FALSE) +/// list("type" = RUSTG_ICONFORGE_SWAP_COLOR, "src_color" = "#ff0000", "dst_color" = "#00ff00") // alpha bits supported +/// list("type" = RUSTG_ICONFORGE_DRAW_BOX, "color" = "#ff0000", "x1" = 1, "y1" = 1, "x2" = 32, "y2" = 32) // alpha bits supported. color can be null/omitted for transparency. x2 and y2 will default to x1 and y1 if omitted /// /// Returns a SpritesheetResult as JSON, containing fields: /// list( @@ -236,6 +283,21 @@ #define rustg_iconforge_generate(file_path, spritesheet_name, sprites, hash_icons, generate_dmi, flatten) RUSTG_CALL(RUST_G, "iconforge_generate")(file_path, spritesheet_name, sprites, "[hash_icons]", "[generate_dmi]", "[flatten]") /// Returns a job_id for use with rustg_iconforge_check() #define rustg_iconforge_generate_async(file_path, spritesheet_name, sprites, hash_icons, generate_dmi, flatten) RUSTG_CALL(RUST_G, "iconforge_generate_async")(file_path, spritesheet_name, sprites, "[hash_icons]", "[generate_dmi]", "[flatten]") +/// Creates a single DMI or PNG using 'sprites' as a list of icon states / images. +/// This function is intended for generating icons with only a few states that have little in common with each other, and only one size. +/// For icons with a large number of states, potentially variable sizes, that re-use sets of transforms more than once, or that benefit from caching, use rustg_iconforge_generate. +/// sprites - follows the same format as rustg_iconforge_generate. +/// file_path - the full relative path at which the PNG or DMI will be written. It must be a full filepath such as tmp/my_icon.dmi or my_icon.png +/// flatten - boolean (0 or 1) determines if the DMI output will be flattened to a single frame/dir if unscoped (null/0 dir or frame values). +/// +/// Returns a HeadlessResult, decoded to a BYOND list (always, it's not possible for this to panic unless rustg itself has an issue) containing the following fields: +/// list( +/// "file_path" = "tmp/my_icon.dmi" // [whatever you input returned back to you, null if there was a fatal error] +/// "width" = 32 // the width, which is determined by the first entry of 'sprites', null if there was a fatal error +/// "height" = 32 // the height, which is determined by the first entry of 'sprites', null if there was a fatal error +/// "error" = "[A string, null if there were no errors.]" +/// ) +#define rustg_iconforge_generate_headless(file_path, sprites, flatten) json_decode(RUSTG_CALL(RUST_G, "iconforge_generate_headless")(file_path, sprites, "[flatten]")) /// Returns the status of an async job_id, or its result if it is completed. See RUSTG_JOB DEFINEs. #define rustg_iconforge_check(job_id) RUSTG_CALL(RUST_G, "iconforge_check")("[job_id]") /// Clears all cached DMIs and images, freeing up memory. @@ -256,7 +318,7 @@ /// Provided a /datum/greyscale_config typepath, JSON string containing the greyscale config, and path to a DMI file containing the base icons, /// Loads that config into memory for later use by rustg_iconforge_gags(). The config_path is the unique identifier used later. /// JSON Config schema: https://hackmd.io/@tgstation/GAGS-Layer-Types -/// Unsupported features: color_matrix layer type, 'or' blend_mode. May not have BYOND parity with animated icons or varying dirs between layers. +/// Adding dirs or frames (via blending larger icons) to icons with more than 1 dir or 1 frame is not supported. /// Returns "OK" if successful, otherwise, returns a string containing the error. #define rustg_iconforge_load_gags_config(config_path, config_json, config_icon_path) RUSTG_CALL(RUST_G, "iconforge_load_gags_config")("[config_path]", config_json, config_icon_path) /// Given a config_path (previously loaded by rustg_iconforge_load_gags_config), and a string of hex colors formatted as "#ff00ff#ffaa00" @@ -272,6 +334,12 @@ #define RUSTG_ICONFORGE_BLEND_ICON "BlendIcon" #define RUSTG_ICONFORGE_CROP "Crop" #define RUSTG_ICONFORGE_SCALE "Scale" +#define RUSTG_ICONFORGE_MAP_COLORS "MapColors" +#define RUSTG_ICONFORGE_FLIP "Flip" +#define RUSTG_ICONFORGE_TURN "Turn" +#define RUSTG_ICONFORGE_SHIFT "Shift" +#define RUSTG_ICONFORGE_SWAP_COLOR "SwapColor" +#define RUSTG_ICONFORGE_DRAW_BOX "DrawBox" #define RUSTG_JOB_NO_RESULTS_YET "NO RESULTS YET" #define RUSTG_JOB_NO_SUCH_JOB "NO SUCH JOB" diff --git a/code/__DEFINES/rust_g_uuid.dm b/code/__DEFINES/rust_g_uuid.dm new file mode 100644 index 00000000000..a59e31317bf --- /dev/null +++ b/code/__DEFINES/rust_g_uuid.dm @@ -0,0 +1,15 @@ +/// Generates a version 4 UUID. +/// See https://www.ietf.org/rfc/rfc9562.html#section-5.4 for specifics on version 4 UUIDs. +#define rustg_generate_uuid_v4(...) RUSTG_CALL(RUST_G, "uuid_v4")() + +/// Generates a version 7 UUID, with the current time. +/// See https://www.ietf.org/rfc/rfc9562.html#section-5.7 for specifics on version 7 UUIDs. +#define rustg_generate_uuid_v7(...) RUSTG_CALL(RUST_G, "uuid_v7")() + +/// Generates a random version 2 CUID. +/// See https://github.com/paralleldrive/cuid2 for specifics on version 2 CUIDs. +#define rustg_generate_cuid2(...) RUSTG_CALL(RUST_G, "cuid2")() + +/// Generates a random version 2 CUID with the given length. +/// See https://github.com/paralleldrive/cuid2 for specifics on version 2 CUIDs. +#define rustg_generate_cuid2_length(length) RUSTG_CALL(RUST_G, "cuid2_len")("[length]") diff --git a/code/modules/asset_cache/spritesheet/batched/batched_spritesheet.dm b/code/modules/asset_cache/spritesheet/batched/batched_spritesheet.dm index 76b6fb209dc..a5a636327f5 100644 --- a/code/modules/asset_cache/spritesheet/batched/batched_spritesheet.dm +++ b/code/modules/asset_cache/spritesheet/batched/batched_spritesheet.dm @@ -189,10 +189,10 @@ var/data_out if(yield || !isnull(job_id)) if(isnull(job_id)) - job_id = rustg_iconforge_generate_async("data/spritesheets/", name, entries_json, do_cache, TRUE, TRUE) + job_id = rustg_iconforge_generate_async("data/spritesheets/", name, entries_json, do_cache, FALSE, TRUE) UNTIL((data_out = rustg_iconforge_check(job_id)) != RUSTG_JOB_NO_RESULTS_YET) else - data_out = rustg_iconforge_generate("data/spritesheets/", name, entries_json, do_cache, TRUE, TRUE) + data_out = rustg_iconforge_generate("data/spritesheets/", name, entries_json, do_cache, FALSE, TRUE) if (data_out == RUSTG_JOB_ERROR) CRASH("Spritesheet [name] JOB PANIC") else if(!findtext(data_out, "{", 1, 2)) diff --git a/code/modules/asset_cache/spritesheet/batched/universal_icon.dm b/code/modules/asset_cache/spritesheet/batched/universal_icon.dm index aecc9485ad2..899f64f757c 100644 --- a/code/modules/asset_cache/spritesheet/batched/universal_icon.dm +++ b/code/modules/asset_cache/spritesheet/batched/universal_icon.dm @@ -10,7 +10,7 @@ var/datum/icon_transformer/transform /// Don't instantiate these yourself, use uni_icon. -/datum/universal_icon/New(icon/icon_file, icon_state="", dir=SOUTH, frame=1, datum/icon_transformer/transform=null, color=null) +/datum/universal_icon/New(icon/icon_file, icon_state="", dir=null, frame=null, datum/icon_transformer/transform=null, color=null) #ifdef UNIT_TESTS // This check is kinda slow and shouldn't fail unless a developer makes a mistake. So it'll get caught in unit tests. if(!isicon(icon_file) || !isfile(icon_file) || "[icon_file]" == "/icon" || !length("[icon_file]")) diff --git a/dependencies.sh b/dependencies.sh index 90566cf322a..3ed72428336 100644 --- a/dependencies.sh +++ b/dependencies.sh @@ -8,7 +8,7 @@ export BYOND_MAJOR=516 export BYOND_MINOR=1666 #rust_g git tag -export RUST_G_VERSION=3.11.0 +export RUST_G_VERSION=4.2.0 #node version export NODE_VERSION=14 diff --git a/tools/tgs4_scripts/PreCompile.sh b/tools/tgs4_scripts/PreCompile.sh index b429aa7b567..e693f3fdec9 100644 --- a/tools/tgs4_scripts/PreCompile.sh +++ b/tools/tgs4_scripts/PreCompile.sh @@ -62,7 +62,7 @@ fi echo "Deploying rust-g..." git checkout "$RUST_G_VERSION" -env PKG_CONFIG_ALLOW_CROSS=1 ~/.cargo/bin/cargo build --release --target=i686-unknown-linux-gnu +env PKG_CONFIG_ALLOW_CROSS=1 ~/.cargo/bin/cargo build --release --target=i686-unknown-linux-gnu --features uuid mv target/i686-unknown-linux-gnu/release/librust_g.so "$1/librust_g.so" cd .. From 09e0261711844b9693a33e516ef056279592c7ce Mon Sep 17 00:00:00 2001 From: Flleeppyy Date: Tue, 16 Dec 2025 03:57:07 -0800 Subject: [PATCH 2/2] buh? --- cev_eris.dme | 1 - code/__DEFINES/rust_g.dm | 5 +++-- code/__DEFINES/rust_g_overrides.dm | 3 --- 3 files changed, 3 insertions(+), 6 deletions(-) delete mode 100644 code/__DEFINES/rust_g_overrides.dm diff --git a/cev_eris.dme b/cev_eris.dme index 4918741c544..4918ced24a3 100644 --- a/cev_eris.dme +++ b/cev_eris.dme @@ -85,7 +85,6 @@ #include "code\__DEFINES\reagents.dm" #include "code\__DEFINES\research.dm" #include "code\__DEFINES\rust_g.dm" -#include "code\__DEFINES\rust_g_overrides.dm" #include "code\__DEFINES\rust_g_uuid.dm" #include "code\__DEFINES\sanity.dm" #include "code\__DEFINES\say.dm" diff --git a/code/__DEFINES/rust_g.dm b/code/__DEFINES/rust_g.dm index 877d06ed19f..4817797c8b3 100644 --- a/code/__DEFINES/rust_g.dm +++ b/code/__DEFINES/rust_g.dm @@ -496,8 +496,9 @@ #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 +// RUSTG_OVERRIDE_BUILTINS is not used since the file APIs don't work well over Linux. +// #ifdef RUSTG_OVERRIDE_BUILTINS #define url_encode(text) rustg_url_encode(text) #define url_decode(text) rustg_url_decode(text) -#endif +// #endif diff --git a/code/__DEFINES/rust_g_overrides.dm b/code/__DEFINES/rust_g_overrides.dm deleted file mode 100644 index 57de7d96acd..00000000000 --- a/code/__DEFINES/rust_g_overrides.dm +++ /dev/null @@ -1,3 +0,0 @@ -// RUSTG_OVERRIDE_BUILTINS is not used since the file APIs don't work well over Linux. -#define url_encode(text) rustg_url_encode("[text]") -#define url_decode(text) rustg_url_decode("[text]")