diff --git a/.gitignore b/.gitignore index 7cd12b9..4f55658 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,7 @@ mono_crash.* # Build results [Dd]ebug/ [Dd]ebugPublic/ -[Rr]elease/ +# [Rr]elease/ [Rr]eleases/ x64/ x86/ @@ -27,7 +27,7 @@ x86/ [Aa][Rr][Mm]/ [Aa][Rr][Mm]64/ bld/ -[Bb]in/ +# [Bb]in/ [Oo]bj/ [Ll]og/ [Ll]ogs/ @@ -177,7 +177,8 @@ DocProject/Help/Html2 DocProject/Help/html # Click-Once directory -publish/ +native/ +# publish/ # Publish Web Output *.[Pp]ublish.xml @@ -239,6 +240,11 @@ ClientBin/ *.pfx *.publishsettings orleans.codegen.cs +*.deps.json +*.dll.dbg +*.so.dbg +extension/bin/Release/net8.0/linux-x64/ArmaRAMDb_x64.dll +extension/bin/Release/net8.0/win-x64/ArmaRAMDb_x64.dll # Including strong name files can present a security risk # (https://github.com/github/gitignore/pull/2483#issue-259490424) @@ -398,13 +404,4 @@ FodyWeavers.xsd *.sln.iml # Hemtt -*.pbo -.hemttout -hemtt -hemtt.exe -*.biprivatekey - - -# Added by cargo - -/target +.hemttout/ \ No newline at end of file diff --git a/addons/main/script_component.hpp b/addons/main/script_component.hpp index 3caee07..8945c78 100644 --- a/addons/main/script_component.hpp +++ b/addons/main/script_component.hpp @@ -7,6 +7,7 @@ #ifdef DEBUG_ENABLED_MAIN #define DEBUG_MODE_FULL #endif + #ifdef DEBUG_SETTINGS_MAIN #define DEBUG_SETTINGS DEBUG_SETTINGS_MAIN #endif diff --git a/extension/ArmaRAMDb.csproj b/extension/ArmaRAMDb.csproj index d9c1e3e..201fbb8 100644 --- a/extension/ArmaRAMDb.csproj +++ b/extension/ArmaRAMDb.csproj @@ -10,4 +10,8 @@ AnyCPU + + + + 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 new file mode 100644 index 0000000..8891efc Binary files /dev/null and b/extension/bin/Release/net8.0/win-x64/publish/ArmaRAMDb_x64.dll differ diff --git a/extension/build.ps1 b/extension/build.ps1 new file mode 100644 index 0000000..86ed93e --- /dev/null +++ b/extension/build.ps1 @@ -0,0 +1,5 @@ +# Build Windows DLL +dotnet publish -f net8.0 -c Release -r win-x64 -p:PublishAot=true -p:NativeLib=Shared -p:SelfContained=true + +# Build Linux SO using WSL +wsl -e bash -ic "dotnet publish -f net8.0 -c Release -r linux-x64 -p:PublishAot=true -p:NativeLib=Shared -p:SelfContained=true" diff --git a/extension/src/HashStore.cs b/extension/src/HashStore.cs index 9a2cc8b..098e7ad 100644 --- a/extension/src/HashStore.cs +++ b/extension/src/HashStore.cs @@ -6,25 +6,12 @@ namespace ArmaRAMDb { private static readonly ConcurrentDictionary> _hashTables = RAMDb._hashTables; - public static bool HashSet(string tableName, string key, string value) + public static bool HashDelete(string tableName) { - var table = _hashTables.GetOrAdd(tableName, _ => new ConcurrentDictionary()); - table.AddOrUpdate(key, value, (_, _) => value); + var result = _hashTables.TryRemove(tableName, out _); - Main.Log($"HashSet: {tableName} - {key} - {value}", "debug"); - return true; - } - - public static bool HashSetBulk(string tableName, Dictionary values) - { - var table = _hashTables.GetOrAdd(tableName, _ => new ConcurrentDictionary()); - foreach (var kv in values) - { - table.AddOrUpdate(kv.Key, kv.Value, (_, _) => kv.Value); - Main.Log($"HashSetBulk: {tableName} - {kv.Key} - {kv.Value}", "debug"); - } - - return true; + Main.Log($"HashDelete: {tableName} - Success: {result}", "debug"); + return result; } public static string HashGet(string tableName, string key) @@ -62,12 +49,12 @@ namespace ArmaRAMDb return []; } - public static bool HashDelete(string tableName, string key) + public static bool HashRemove(string tableName, string key) { if (_hashTables.TryGetValue(tableName, out var table)) { var result = table.TryRemove(key, out _); - Main.Log($"HashDelete: {tableName} - {key} - Success: {result}", "debug"); + Main.Log($"HashRemove: {tableName} - {key} - Success: {result}", "debug"); return result; } @@ -75,12 +62,25 @@ namespace ArmaRAMDb return false; } - public static bool DeleteHashTable(string tableName) + public static bool HashSet(string tableName, string key, string value) { - var result = _hashTables.TryRemove(tableName, out _); + var table = _hashTables.GetOrAdd(tableName, _ => new ConcurrentDictionary()); + table.AddOrUpdate(key, value, (_, _) => value); - Main.Log($"DeleteHashTable: {tableName} - Success: {result}", "debug"); - return result; + Main.Log($"HashSet: {tableName} - {key} - {value}", "debug"); + return true; + } + + public static bool HashSetBulk(string tableName, Dictionary values) + { + var table = _hashTables.GetOrAdd(tableName, _ => new ConcurrentDictionary()); + foreach (var kv in values) + { + table.AddOrUpdate(kv.Key, kv.Value, (_, _) => kv.Value); + Main.Log($"HashSetBulk: {tableName} - {kv.Key} - {kv.Value}", "debug"); + } + + return true; } } } \ No newline at end of file diff --git a/extension/src/KeyValueStore.cs b/extension/src/KeyValueStore.cs index 2bf46e5..fdb04b8 100644 --- a/extension/src/KeyValueStore.cs +++ b/extension/src/KeyValueStore.cs @@ -6,14 +6,6 @@ namespace ArmaRAMDb { private static readonly ConcurrentDictionary _keyValues = RAMDb._keyValues; - public static bool SetValue(string key, string value) - { - _keyValues.AddOrUpdate(key, value, (_, _) => value); - - Main.Log($"SetValue: {key} - Value: {value}", "debug"); - return true; - } - public static string GetValue(string key) { string value = _keyValues.TryGetValue(key, out string data) ? data : string.Empty; @@ -29,5 +21,13 @@ namespace ArmaRAMDb Main.Log($"DeleteValue: {key} - Success: {result}", "debug"); return result; } + + public static bool SetValue(string key, string value) + { + _keyValues.AddOrUpdate(key, value, (_, _) => value); + + Main.Log($"SetValue: {key} - Value: {value}", "debug"); + return true; + } } } \ No newline at end of file diff --git a/extension/src/ListStore.cs b/extension/src/ListStore.cs index de73ca1..f56e11e 100644 --- a/extension/src/ListStore.cs +++ b/extension/src/ListStore.cs @@ -6,14 +6,14 @@ namespace ArmaRAMDb { private static readonly ConcurrentDictionary> _lists = RAMDb._lists; - public static bool ListPush(string listName, string value) + public static bool ListAdd(string listName, string value) { if (_lists.TryGetValue(listName, out var list)) { lock (list) { list.Add(value); - Main.Log($"ListPush: {listName} - Value: {value}", "debug"); + Main.Log($"ListAdd: {listName} - Value: {value}", "debug"); return true; } } @@ -22,14 +22,22 @@ namespace ArmaRAMDb return false; } - public static string ListGet(string listName, int index) + public static bool ListDelete(string listName) + { + var result = _lists.TryRemove(listName, out _); + + Main.Log($"ListDelete: {listName} - Success: {result}", "debug"); + return result; + } + + public static string ListIndex(string listName, int index) { if (_lists.TryGetValue(listName, out var list)) { lock (list) { string value = index >= 0 && index < list.Count ? list[index] : string.Empty; - Main.Log($"ListGet: {listName} - Index: {index} - Value: {value}", "debug"); + Main.Log($"ListIndex: {listName} - Index: {index} - Value: {value}", "debug"); return value; } } @@ -38,26 +46,46 @@ namespace ArmaRAMDb return string.Empty; } - public static List GetList(string listName) - { - Main.Log($"Getting contents for list: {listName}", "debug"); - + public static List ListRange(string listName, int startIndex, int endIndex) + { if (_lists.TryGetValue(listName, out var list)) { - var contents = new List(list); - Main.Log($"Found {contents.Count} entries in list {listName}", "debug"); - foreach (var item in contents) - { - Main.Log($"Value: {item}", "debug"); - } - return contents; + lock (list) + { + startIndex = Math.Max(0, startIndex); + endIndex = Math.Min(list.Count - 1, endIndex); + + if (startIndex <= endIndex) + { + int count = endIndex - startIndex + 1; + var value = list.GetRange(startIndex, count); + Main.Log($"ListRange: {listName} - StartIndex: {startIndex} - EndIndex: {endIndex} - Count: {count}", "debug"); + return value; + } + } } Main.Log($"List not found: {listName}", "debug"); return []; } - public static bool ListDelete(string listName, int index) + public static bool ListRemove(string listName, string value) + { + if (_lists.TryGetValue(listName, out var list)) + { + lock (list) + { + int removedCount = list.RemoveAll(item => item == value); + Main.Log($"ListRemove: {listName} - Value: {value} - Removed Count: {removedCount}", "debug"); + return removedCount > 0; + } + } + + Main.Log($"List not found: {listName}", "debug"); + return false; + } + + public static bool ListSet(string listName, int index, string value) { if (_lists.TryGetValue(listName, out var list)) { @@ -65,9 +93,8 @@ namespace ArmaRAMDb { if (index >= 0 && index < list.Count) { - string value = list[index]; - list.RemoveAt(index); - Main.Log($"ListDelete: {listName} - Index: {index} - Value: {value}", "debug"); + list[index] = value; + Main.Log($"ListSet: {listName} - Index: {index} - Value: {value}", "debug"); return true; } } @@ -76,13 +103,5 @@ namespace ArmaRAMDb Main.Log($"List not found: {listName}", "debug"); return false; } - - public static bool DeleteList(string listName) - { - var result = _lists.TryRemove(listName, out _); - - Main.Log($"DeleteList: {listName} - Success: {result}", "debug"); - return result; - } } } \ No newline at end of file diff --git a/extension/src/Main.cs b/extension/src/Main.cs index 0ffc204..b701737 100644 --- a/extension/src/Main.cs +++ b/extension/src/Main.cs @@ -195,25 +195,89 @@ namespace ArmaRAMDb switch (func.ToLower()) { - case "hset": - HandleHashSetOperation(args, argc); + case "del": + HandleDeleteOperation(args, argc); WriteOutput(output, "Async"); return 200; - case "hsetbulk": - HandleHashSetBulkOperation(args, argc); + case "get": + HandleGetOperation(args, argc); + WriteOutput(output, $"[\"{_id}_get\",{args[0]}]"); + return 100; + case "hdel": + HandleHashDeleteOperation(args, argc); + WriteOutput(output, "Async"); + return 200; + case "hdelid": + HandleHashDeleteIdOperation(args, argc); WriteOutput(output, "Async"); return 200; case "hget": HandleHashGetOperation(args, argc); WriteOutput(output, $"[\"{_id}_hget\",{args[1]}]"); return 100; + case "hgetid": + HandleHashGetIdOperation(args, argc); + WriteOutput(output, $"[\"{_id}_hgetid\",{args[0]}]"); + return 100; case "hgetall": HandleHashGetAllOperation(args, argc); WriteOutput(output, $"[\"{_id}_hgetall\",{args[0]}]"); return 100; + case "hgetallid": + HandleHashGetAllIdOperation(args, argc); + WriteOutput(output, $"[\"{_id}_hgetallid\",{args[0]}]"); + return 100; + case "hrem": + HandleHashRemoveOperation(args, argc); + WriteOutput(output, "Async"); + return 200; + case "hremid": + HandleHashRemoveIdOperation(args, argc); + WriteOutput(output, "Async"); + return 200; + case "hset": + HandleHashSetOperation(args, argc); + WriteOutput(output, "Async"); + return 200; + case "hsetid": + HandleHashSetIdOperation(args, argc); + WriteOutput(output, "Async"); + return 200; + case "hsetbulk": + HandleHashSetBulkOperation(args, argc); + WriteOutput(output, "Async"); + return 200; + case "hsetbulkid": + HandleHashSetBulkIdOperation(args, argc); + WriteOutput(output, "Async"); + return 200; case "isloaded": WriteOutput(output, ARDB_ISLOADED.ToString().ToLower()); return 100; + case "listadd": + HandleListAddOperation(args, argc); + WriteOutput(output, "Async"); + return 200; + case "listdel": + HandleListDeleteOperation(args, argc); + WriteOutput(output, "Async"); + return 200; + case "listidx": + HandleListIndexOperation(args, argc); + WriteOutput(output, $"[\"{_id}_listindex\",{args[0]}]"); + return 100; + case "listrng": + HandleListRangeOperation(args, argc); + WriteOutput(output, $"[\"{_id}_listrange\",{args[0]}]"); + return 100; + case "listrem": + HandleListRemoveOperation(args, argc); + WriteOutput(output, "Async"); + return 200; + case "listset": + HandleListSetOperation(args, argc); + WriteOutput(output, "Async"); + return 200; case "load": LoadData(); WriteOutput(output, "Data loaded"); @@ -222,11 +286,15 @@ namespace ArmaRAMDb SaveData(); WriteOutput(output, "Data saved"); return 100; + case "set": + HandleSetOperation(args, argc); + WriteOutput(output, "Async"); + return 200; case "version": WriteOutput(output, ARDB_VERSION); return 100; default: - WriteOutput(output, "Available functions: hset, hsetbulk, hget, hgetall, isloaded, load, save, version"); + WriteOutput(output, "Available functions: delete, get, hget, hgetid, hgetall, hgetallid, hset, hsetid, hsetbulk, hsetbulkid, isloaded, load, save, set, version"); return -1; } } @@ -283,6 +351,77 @@ namespace ArmaRAMDb Log("Data loaded from XML", "action"); } +#pragma warning disable IDE0060 // Remove unused parameter + private static void HandleHashDeleteOperation(List args, int argc) +#pragma warning restore IDE0060 // Remove unused parameter + { + HashStore.HashDelete(STEAMID); + } + +#pragma warning disable IDE0060 // Remove unused parameter + private static void HandleHashDeleteIdOperation(List args, int argc) +#pragma warning restore IDE0060 // Remove unused parameter + { + HashStore.HashDelete(args[0]); + } + +#pragma warning disable IDE0060 // Remove unused parameter + private static void HandleHashGetOperation(List args, int argc) +#pragma warning restore IDE0060 // Remove unused parameter + { + var value = HashStore.HashGet(STEAMID, args[0]); + + Log($"HashGet: {SerializeList([value])}", "debug"); + Callback("ArmaRAMDb", args[1].Trim('"'), SerializeList([value])); + } + +#pragma warning disable IDE0060 // Remove unused parameter + private static void HandleHashGetIdOperation(List args, int argc) +#pragma warning restore IDE0060 // Remove unused parameter + { + var value = HashStore.HashGet(args[0], args[1]); + + Log($"HashGetId: {SerializeList([value])}", "debug"); + Callback("ArmaRAMDb", args[2].Trim('"'), SerializeList([value])); + } + +#pragma warning disable IDE0060 // Remove unused parameter + private static void HandleHashGetAllOperation(List args, int argc) +#pragma warning restore IDE0060 // Remove unused parameter + { + var contents = HashStore.HashGetAll(STEAMID); + var list = contents.SelectMany(kv => new[] { kv.Key, kv.Value }).ToList(); + + Log($"HashGetAll: {SerializeList(list)}", "debug"); + Callback("ArmaRAMDb", args[0].Trim('"'), SerializeList(list)); + } + +#pragma warning disable IDE0060 // Remove unused parameter + private static void HandleHashGetAllIdOperation(List args, int argc) +#pragma warning restore IDE0060 // Remove unused parameter + { + var hashId = args[0]; + var contents = HashStore.HashGetAll(hashId); + var list = contents.SelectMany(kv => new[] { kv.Key, kv.Value }).ToList(); + + Log($"HashGetAllId: {SerializeList(list)}", "debug"); + Callback("ArmaRAMDb", args[1].Trim('"'), SerializeList(list)); + } + +#pragma warning disable IDE0060 // Remove unused parameter + private static void HandleHashRemoveOperation(List args, int argc) +#pragma warning restore IDE0060 // Remove unused parameter + { + HashStore.HashRemove(STEAMID, args[0]); + } + +#pragma warning disable IDE0060 // Remove unused parameter + private static void HandleHashRemoveIdOperation(List args, int argc) +#pragma warning restore IDE0060 // Remove unused parameter + { + var value = HashStore.HashRemove(args[0], args[1]); + } + #pragma warning disable IDE0060 // Remove unused parameter private static void HandleHashSetOperation(List args, int argc) #pragma warning restore IDE0060 // Remove unused parameter @@ -291,6 +430,14 @@ namespace ArmaRAMDb HashStore.HashSet(STEAMID, args[0], args[1]); } +#pragma warning disable IDE0060 // Remove unused parameter + private static void HandleHashSetIdOperation(List args, int argc) +#pragma warning restore IDE0060 // Remove unused parameter + { + Log($"HashSetId: {SerializeList(args)}", "debug"); + HashStore.HashSet(args[0], args[1], args[2]); + } + #pragma warning disable IDE0060 // Remove unused parameter private static void HandleHashSetBulkOperation(List args, int argc) #pragma warning restore IDE0060 // Remove unused parameter @@ -309,24 +456,122 @@ namespace ArmaRAMDb } #pragma warning disable IDE0060 // Remove unused parameter - private static void HandleHashGetOperation(List args, int argc) + private static void HandleHashSetBulkIdOperation(List args, int argc) #pragma warning restore IDE0060 // Remove unused parameter { - var value = HashStore.HashGet(STEAMID, args[0]); + var hashId = args[0]; + var values = new Dictionary(); + + for (int i = 1; i < args.Count; i += 2) + { + string key = args[i]; + string value = args[i + 1]; + values.Add(key, value); + } + + Log($"BulkHashSetId: Keys={string.Join(",", values.Keys)}", "debug"); + HashStore.HashSetBulk(hashId, values); + } - Log($"HashGet: {SerializeList([value])}", "debug"); +#pragma warning disable IDE0060 // Remove unused parameter + private static void HandleListAddOperation(List args, int argc) +#pragma warning restore IDE0060 // Remove unused parameter + { + var key = args[0]; + var value = args[1]; + + Log($"ListAdd: {SerializeList([key, value])}", "debug"); + ListStore.ListAdd(key, value); + } + +#pragma warning disable IDE0060 // Remove unused parameter + private static void HandleListDeleteOperation(List args, int argc) +#pragma warning restore IDE0060 // Remove unused parameter + { + var listId = args[0]; + + Log($"ListDelete: {SerializeList([listId])}", "debug"); + ListStore.ListDelete(listId); + } + +#pragma warning disable IDE0060 // Remove unused parameter + private static void HandleListIndexOperation(List args, int argc) +#pragma warning restore IDE0060 // Remove unused parameter + { + var listId = args[0]; + var key = args[1]; + var value = ListStore.ListIndex(listId, int.Parse(key)); + + Log($"ListIndex: {SerializeList([key, value])}", "debug"); + Callback("ArmaRAMDb", args[2].Trim('"'), SerializeList([value])); + } + +#pragma warning disable IDE0060 // Remove unused parameter + private static void HandleListRangeOperation(List args, int argc) +#pragma warning restore IDE0060 // Remove unused parameter + { + var listId = args[0]; + var startIndex = int.Parse(args[1]); + var endIndex = int.Parse(args[2]); + + var values = ListStore.ListRange(listId, startIndex, endIndex); + + Log($"ListRange: ListId={listId} Start={startIndex} End={endIndex} Values={SerializeList(values)}", "debug"); + Callback("ArmaRAMDb", args[3].Trim('"'), SerializeList(values)); + } + +#pragma warning disable IDE0060 // Remove unused parameter + private static void HandleListRemoveOperation(List args, int argc) +#pragma warning restore IDE0060 // Remove unused parameter + { + var listId = args[0]; + var index = int.Parse(args[1]); + + ListStore.ListSet(listId, index, "RAMDBREMOVE"); + ListStore.ListRemove(listId, "RAMDBREMOVE"); + } + +#pragma warning disable IDE0060 // Remove unused parameter + private static void HandleListSetOperation(List args, int argc) +#pragma warning restore IDE0060 // Remove unused parameter + { + var listId = args[0]; + var index = int.Parse(args[1]); + var value = args[2]; + + ListStore.ListSet(listId, index, value); + } + +#pragma warning disable IDE0060 // Remove unused parameter + private static void HandleSetOperation(List args, int argc) +#pragma warning restore IDE0060 // Remove unused parameter + { + var key = args[0]; + var value = args[1]; + + KeyValueStore.SetValue(key, value); + Log($"Set: Key={key} Value={value}", "debug"); + } + +#pragma warning disable IDE0060 // Remove unused parameter + private static void HandleGetOperation(List args, int argc) +#pragma warning restore IDE0060 // Remove unused parameter + { + var key = args[0]; + var value = KeyValueStore.GetValue(key); + + Log($"Get: Key={key} Value={value}", "debug"); Callback("ArmaRAMDb", args[1].Trim('"'), SerializeList([value])); } #pragma warning disable IDE0060 // Remove unused parameter - private static void HandleHashGetAllOperation(List args, int argc) + private static void HandleDeleteOperation(List args, int argc) #pragma warning restore IDE0060 // Remove unused parameter { - var contents = HashStore.HashGetAll(STEAMID); - var list = contents.SelectMany(kv => new[] { kv.Key, kv.Value }).ToList(); - - Log($"HashGetAll: {SerializeList(list)}", "debug"); - Callback("ArmaRAMDb", args[0].Trim('"'), SerializeList(list)); + var key = args[0]; + + KeyValueStore.DeleteValue(key); + Log($"Delete: Key={key}", "debug"); } } } \ No newline at end of file