diff --git a/ArmaRAMDb_x64.dll b/ArmaRAMDb_x64.dll index 3728e29..b13775a 100644 Binary files a/ArmaRAMDb_x64.dll and b/ArmaRAMDb_x64.dll differ diff --git a/ArmaRAMDb_x64.so b/ArmaRAMDb_x64.so index 924c0c3..98d5c33 100644 Binary files a/ArmaRAMDb_x64.so and b/ArmaRAMDb_x64.so differ diff --git a/addons/db/functions/fnc_fetch.sqf b/addons/db/functions/fnc_fetch.sqf index ab6e960..ca21313 100644 --- a/addons/db/functions/fnc_fetch.sqf +++ b/addons/db/functions/fnc_fetch.sqf @@ -26,6 +26,7 @@ params ["_uniqueID", "_function", "_index", "_total", "_datachunk", "_call", "_netId"]; +private _dataString = ""; private _index_array = []; private _count_total = -1; @@ -43,35 +44,15 @@ _count_total = { if (_count_total == _total) then { _index_array sort true; - private _allElements = []; - { - private _chunkData = _x select 1; - private _chunkArray = []; - - #ifdef __A3__DEBUG__ - diag_log text format ["ArmaRAMDb: Processing chunk: %1", _chunkData]; - #endif - - try { - _chunkArray = parseSimpleArray _chunkData; - _allElements append _chunkArray; - - #ifdef __A3__DEBUG__ - diag_log text format ["ArmaRAMDb: Parsed chunk successfully with %1 elements", count _chunkArray]; - #endif - } catch { - #ifdef __A3__DEBUG__ - diag_log text format ["ArmaRAMDb: Error parsing chunk: %1", _chunkData]; - #endif - }; + _dataString = _dataString + (_x select 1); } forEach _index_array; #ifdef __A3__DEBUG__ - diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_fetch' Combined %1 chunks into array with %2 elements", count _index_array, count _allElements]; + diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_fetch' Data String: %1", _dataString]; #endif - [_uniqueID, _function, _call, _allElements, _netId] call FUNC(handler); + [_uniqueID, _function, _call, (parseSimpleArray _dataString), _netId] call FUNC(handler); ramdb_db_fetch_array = ramdb_db_fetch_array select {!((_x select 0) in [_uniqueID])}; }; \ No newline at end of file diff --git a/addons/db/functions/fnc_handler.sqf b/addons/db/functions/fnc_handler.sqf index e819732..c10bd46 100644 --- a/addons/db/functions/fnc_handler.sqf +++ b/addons/db/functions/fnc_handler.sqf @@ -44,10 +44,34 @@ if (_function == "" || count _data == 0) exitWith { private _func = call compile format ["%1", _function]; -if ((!isNil "_netId") and (_netId isNotEqualTo "")) then { +if (_netId != "") then { private _target = objectFromNetId _netId; - - if (_call) then { _data remoteExecCall [_function, _target, false]; } else { _data remoteExec [_function, _target, false]; }; + + if (!isNull _target) then { + #ifdef __A3__DEBUG__ + diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_handler' Using NetId: '%1'", _netId]; + #endif + + if (_call) then { + _data remoteExecCall [_function, _target, false]; + } else { + _data remoteExec [_function, _target, false]; + }; + } else { + #ifdef __A3__DEBUG__ + diag_log text format ["ArmaRAMDb: 'ramdb_db_fnc_handler' NetId '%1' resolved to null object, using local execution", _netId]; + #endif + + if (_call) then { + _data call _func; + } else { + _data spawn _func; + }; + }; } else { - if (_call) then { _data call _func; } else { _data spawn _func; }; + if (_call) then { + _data call _func; + } else { + _data spawn _func; + }; }; \ No newline at end of file diff --git a/addons/db/functions/fnc_save.sqf b/addons/db/functions/fnc_save.sqf index 8a95c46..265cbf7 100644 --- a/addons/db/functions/fnc_save.sqf +++ b/addons/db/functions/fnc_save.sqf @@ -30,4 +30,4 @@ params [["_createBackup", false, [false]]]; -"ArmaRAMDb" callExtension ["save", []]; \ No newline at end of file +"ArmaRAMDb" callExtension ["save", [_createBackup]]; \ No newline at end of file diff --git a/extension/bin/Release/net8.0/linux-x64/publish/ArmaRAMDb_x64.so b/extension/bin/Release/net8.0/linux-x64/publish/ArmaRAMDb_x64.so index 924c0c3..98d5c33 100644 Binary files a/extension/bin/Release/net8.0/linux-x64/publish/ArmaRAMDb_x64.so and b/extension/bin/Release/net8.0/linux-x64/publish/ArmaRAMDb_x64.so differ diff --git a/extension/bin/Release/net8.0/win-x64/publish/ArmaRAMDb_x64.dll b/extension/bin/Release/net8.0/win-x64/publish/ArmaRAMDb_x64.dll index 3728e29..b13775a 100644 Binary files a/extension/bin/Release/net8.0/win-x64/publish/ArmaRAMDb_x64.dll and b/extension/bin/Release/net8.0/win-x64/publish/ArmaRAMDb_x64.dll differ diff --git a/extension/src/Utils.cs b/extension/src/Utils.cs index fceb511..55b7073 100644 --- a/extension/src/Utils.cs +++ b/extension/src/Utils.cs @@ -24,203 +24,59 @@ namespace ArmaRAMDb return str; } - public static List SplitIntoChunks(string data, int maxChunkSize) + public static List SplitIntoChunks(string data, int chunkSize) { + int chunksNeeded = (int)Math.Ceiling((double)data.Length / chunkSize); List chunks = []; - if (data.StartsWith("[") && data.EndsWith("]")) + for (int i = 0; i < chunksNeeded; i++) { - string innerData = data[1..^1]; - - List elements = []; - int depth = 0; - int startPos = 0; - - for (int i = 0; i < innerData.Length; i++) - { - char c = innerData[i]; - - if (c == '[') depth++; - else if (c == ']') depth--; - - else if (c == ',' && depth == 0) - { - elements.Add(innerData[startPos..i]); - startPos = i + 1; - } - } - - if (startPos < innerData.Length) - { - elements.Add(innerData[startPos..]); - } - - StringBuilder currentChunk = new StringBuilder(); - - foreach (string element in elements) - { - if (currentChunk.Length > 0 && - Encoding.UTF8.GetByteCount(currentChunk.ToString() + "," + element) > maxChunkSize) - { - chunks.Add(currentChunk.ToString()); - currentChunk.Clear(); - } - - if (currentChunk.Length > 0) - { - currentChunk.Append(","); - } - - currentChunk.Append(element); - } - - if (currentChunk.Length > 0) - { - chunks.Add(currentChunk.ToString()); - } + int start = i * chunkSize; + int end = Math.Min(data.Length, start + chunkSize); + chunks.Add(data[start..end]); } - else - { - int bytesProcessed = 0; - while (bytesProcessed < Encoding.UTF8.GetByteCount(data)) - { - int charCount = 0; - while (bytesProcessed + Encoding.UTF8.GetByteCount(data.Substring(bytesProcessed, Math.Min(charCount + 1, data.Length - bytesProcessed))) <= maxChunkSize && - bytesProcessed + charCount < data.Length) - { - charCount++; - } - - chunks.Add(data.Substring(bytesProcessed, charCount)); - bytesProcessed += charCount; - } - } - + return chunks; } + public static long GetUniqueId() + { + return DateTimeOffset.Now.ToUnixTimeMilliseconds(); + } + public static void CheckByteCount(string uniqueId, string data, string function, string entity, bool call, int bufferSize) { if (Encoding.UTF8.GetByteCount(data) <= bufferSize) { if (!data.StartsWith('[')) data = BuildArray(data); + Main.Log($"Single chunk data: {data}", "debug"); string dataAsString = $"[\"{uniqueId}\",\"{function}\",{call.ToString().ToLower()},{data},\"{entity}\"]"; + + Main.Log($"Single chunk data string: {dataAsString}", "debug"); Main.Callback("ArmaRAMDb", "ramdb_db_fnc_handler", dataAsString); } else { if (!data.StartsWith('[') || !data.EndsWith(']')) - { data = BuildArray(data); - } - - List elements = ParseArrayElements(data); - - int totalChunks = CalculateChunks(elements, bufferSize); - - for (int chunkIndex = 0; chunkIndex < totalChunks; chunkIndex++) + + Main.Log($"Single chunk data: {data}", "debug"); + + var chunks = SplitIntoChunks(data, bufferSize); + int totalChunks = chunks.Count; + + for (int chunkIndex = 0; chunkIndex < chunks.Count; chunkIndex++) { - List chunkElements = GetChunkElements(elements, chunkIndex, totalChunks); - - string chunkData = "[" + string.Join(",", chunkElements) + "]"; - - string escapedChunkData = chunkData.Replace("\"", "\"\""); - + string escapedChunkData = chunks[chunkIndex].Replace("\"", "\"\""); string chunkAsString = $"[\"{uniqueId}\",\"{function}\",{chunkIndex+1},{totalChunks},\"{escapedChunkData}\",{call.ToString().ToLower()},\"{entity}\"]"; - + Main.Log($"Sending chunk {chunkIndex+1}/{totalChunks}: {chunkAsString}", "debug"); Main.Callback("ArmaRAMDb", "ramdb_db_fnc_fetch", chunkAsString); } } } - - private static List ParseArrayElements(string arrayString) - { - List elements = []; - - string content = arrayString[1..^1].Trim(); - - if (string.IsNullOrEmpty(content)) - return elements; - - int startPos = 0; - int nestLevel = 0; - bool inQuotes = false; - - for (int i = 0; i < content.Length; i++) - { - char c = content[i]; - - if (c == '\\' && i + 1 < content.Length && content[i + 1] == '"') - { - i++; - continue; - } - - if (c == '"') - inQuotes = !inQuotes; - - if (!inQuotes) - { - if (c == '[') nestLevel++; - else if (c == ']') nestLevel--; - - if (nestLevel == 0 && c == ',') - { - elements.Add(content[startPos..i].Trim()); - startPos = i + 1; - } - } - } - - if (startPos < content.Length) - { - elements.Add(content[startPos..].Trim()); - } - - return elements; - } - - private static int CalculateChunks(List elements, int bufferSize) - { - int chunks = 1; - int currentSize = 2; - - foreach (string element in elements) - { - int elementSize = Encoding.UTF8.GetByteCount(element) + 1; - - if (currentSize + elementSize > bufferSize) - { - chunks++; - currentSize = 2 + elementSize; - } - else - { - currentSize += elementSize; - } - } - - return chunks; - } - - private static List GetChunkElements(List allElements, int chunkIndex, int totalChunks) - { - int elementsPerChunk = (int)Math.Ceiling((double)allElements.Count / totalChunks); - int startIdx = chunkIndex * elementsPerChunk; - int count = Math.Min(elementsPerChunk, allElements.Count - startIdx); - - List result = []; - for (int i = 0; i < count; i++) - { - if (startIdx + i < allElements.Count) - result.Add(allElements[startIdx + i]); - } - - return result; - } } } \ No newline at end of file