diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 224ead32cc..49bd2fb513 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -6492,105 +6492,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } - private static bool ListFind_areEqual(object l, object r) - { - if (l is null || r is null) - return false; - - if (l is LSL_Integer lli) - { - if (r is LSL_Integer rli) - return lli.value == rli.value; - if (r is int ri) - return lli.value == ri; - return false; - } - - if (l is int li) - { - if (r is LSL_Integer rli) - return li == rli.value; - if (r is int ri) - return li == ri; - return false; - } - - if (l is LSL_Float llf) - { - if (r is LSL_Float rlf) - return llf.value == rlf.value; - if (r is float rf) - return llf.value == (double)rf; - if (r is double rd) - return llf.value == rd; - return false; - } - if (l is double ld) - { - if (r is LSL_Float rlf) - return ld == rlf.value; - if (r is float rf) - return ld == (double)rf; - if (r is double rd) - return ld == rd; - return false; - } - if (l is float lf) - { - if (r is LSL_Float rlf) - return lf == (float)rlf.value; - if (r is float rf) - return lf == rf; - if (r is double rd) - return lf == (float)rd; - return false; - } - - if (l is LSL_String lls) - { - if (r is LSL_String rls) - return lls.m_string.Equals(rls.m_string, StringComparison.Ordinal); - if (r is string rs) - return lls.m_string.Equals(rs, StringComparison.Ordinal); - return false; - } - - if (l is string ls) - { - if (r is LSL_String rls) - return ls.Equals(rls.m_string, StringComparison.Ordinal); - if (r is string rs) - return ls.Equals(rs, StringComparison.Ordinal); - if (r is LSL_Key rlk) - return ls.Equals(rlk.m_string, StringComparison.OrdinalIgnoreCase); - return false; - } - - if(l is LSL_Key llk) - { - if (r is LSL_Key rlk) - return llk.m_string.Equals(rlk.m_string, StringComparison.OrdinalIgnoreCase); - if (r is string rk) - return llk.m_string.Equals(rk, StringComparison.OrdinalIgnoreCase); - } - - if (l is LSL_Vector llv) - { - if(r is LSL_Vector rlv) - return llv.Equals(rlv); - return false; - } - - if (l is LSL_Rotation llr) - { - if(r is LSL_Rotation rlr) - return llr.Equals(rlr); - return false; - } - - return false; - } - /// /// Returns the index of the first occurrence of test /// in src. @@ -6613,13 +6514,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api object test0 = test[0]; for (int i = 0; i <= src.Length - test.Length; i++) { - if (ListFind_areEqual(test0, src[i])) + if (LSL_List.ListFind_areEqual(test0, src[i])) { int k = i + 1; int j = 1; while(j < test.Length) { - if (!ListFind_areEqual(test[j], src[k])) + if (!LSL_List.ListFind_areEqual(test[j], src[k])) break; ++j; ++k; @@ -6669,13 +6570,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api object test0 = test[0]; for (int i = start; i <= end; i += stride) { - if (ListFind_areEqual(test0, src[i])) + if (LSL_List.ListFind_areEqual(test0, src[i])) { int k = i + 1; int j = 1; while (j < test.Length) { - if (!ListFind_areEqual(test[j], src[k])) + if (!LSL_List.ListFind_areEqual(test[j], src[k])) break; ++j; ++k; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index eaf2ba583b..b3ea193873 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -6639,5 +6639,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api green = Math.Clamp(green, 0, 1.0f); return new LSL_Vector(red, green, 1.0f); } + + public LSL_Integer osListFindListNext(LSL_List src, LSL_List test, LSL_Integer lstart, LSL_Integer lend, LSL_Integer instance) + { + if (src.Length == 0) + return -1; + if (test.Length == 0) + return 0; + if (test.Length > src.Length) + return -1; + + int start = lstart.value; + if (start < 0) + { + start += src.Length; + if (start < 0) + return -1; + } + else if (start >= src.Length) + return -1; + + int end = lend.value; + if (end < 0) + { + end += src.Length; + if (end < 0) + return -1; + end -= test.Length - 1; + } + else if (end > src.Length - test.Length) + end = src.Length - test.Length; + + if(instance < 0) + instance = 0; + else if (instance > src.Length / test.Length) + return -1; + + int nmatchs = 0; + object test0 = test[0]; + for (int i = start; i <= end; i++) + { + if (LSL_List.ListFind_areEqual(test0, src[i])) + { + int k = i + 1; + int j = 1; + while(j < test.Length) + { + if (!LSL_List.ListFind_areEqual(test[j], src[k])) + break; + ++j; + ++k; + } + + if (j == test.Length) + { + if(nmatchs == instance) + return i; + + nmatchs++; + } + } + } + return -1; + } } } \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 604c349976..af36123d0b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -629,5 +629,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_String osAESDecryptFrom(string secret, string encryptedText, string ivString); vector osGetLinkColor(LSL_Integer linknum, LSL_Integer face); vector osTemperature2sRGB(LSL_Float dtemp); + + /// + /// osListFindListNext identical to llListFindListNext but with search limited to sublist from start to end (excluded) + /// + /// string to test for match + /// string to use as pattern + /// index of where to start search + /// index of where to stop search. + /// number of match to return + /// a integer with index of match point or -1 + LSL_Integer osListFindListNext(LSL_List src, LSL_List test, LSL_Integer start, LSL_Integer end, LSL_Integer instance); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 3c181623b1..5a502493b1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -1819,5 +1819,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { return m_OSSL_Functions.osTemperature2sRGB(dtemp); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public LSL_Integer osListFindListNext(LSL_List src, LSL_List test, LSL_Integer start, LSL_Integer end, LSL_Integer instance) + { + return m_OSSL_Functions.osListFindListNext(src, test, start, end, instance); + } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs index 4ac430c893..8e8fcec37f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs +++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs @@ -1369,6 +1369,32 @@ namespace OpenSim.Region.ScriptEngine.Shared } return result + GetSublist(start, Data.Length); + } + } + + // compare for ??ListFindList* functions + public static bool ListFind_areEqual(object l, object r) + { + if (l is null || r is null) + return false; + + if (l is LSLInteger lli) + { + if (r is LSLInteger rli) + return lli.value == rli.value; + if (r is int ri) + return lli.value == ri; + return false; + } + + if (l is int li) + { + if (r is LSLInteger rli) + return li == rli.value; + if (r is int ri) + return li == ri; + return false; + } } }