So some time ago I wanted to write a small plugin for a server that would have a global Dictionary. My problem was and is that Hooks in Oxide are, expectedly, called in an asynchronous/multithreaded kind of way. To still be able to write/add keys to a Dictionary one would usually use a lock or a static ReaderWriterLockSlim so that access is synchronized across multiple threads.
Problem is this: Oxide throws UnauthorizedAccessException when using lock or ReaderWriterLockSlim · Issue #8 · OxideMod/Oxide.CSharp · GitHub
And I don't understand how the developer expects someone to work around this. I also have not found that omnious whitelist.
I would also like to know how blocking access to those two functions is helping with Sandboxing. I guess I never took a look at these two from a security POV.
How to work around not having lock/ReaderWriterLockSlim?
Discussion in 'Rust Development' started by Commander Strax, Mar 11, 2018.
-
I think you totally misunderstood how Rust/Unity works.
There's actually no multithreading nor asynchronous hooks.
It looks like you went on "premature optimization" way.
What's your reason for use locks, are you encountered a race condition?
I would be interested in looking at such code.Last edited by a moderator: Mar 11, 2018 -
Code:
using System; using System.Collections.Generic; using Oxide.Core; using System.Threading;namespace Oxide.Plugins { [Info("Tester", "CommanderStrax", 0.2)] [Description("Multithread/Async test!")] class Blamer : RustPlugin { static Blamer instance; void Init() { } void Loaded() { instance = this; } int a; static int b; bool CanLootPlayer(BasePlayer target, BasePlayer looter) { a++; b++; Puts("A:" + a); Puts("B:" + b); Puts("InstanceA" + instance.a); return true; } } }
Oh...I didn't think about that: Obviously it could, in theory, also mean that the Puts function is async.
Curiously I never had exceptions like 'The collection was changed while iterating over it' even though that should have plopped up.Last edited by a moderator: Mar 11, 2018 -
Wulf Community Admin
Your issue is because you can’t iterate over something and also modify it. Instead, store the list in a variable and iterate over that, then store the new values. This isn’t really unique to Oxide. Just generally what you have to do. -
@Wulf you are talking about doing something like changing a collection while iterating over it which I'm not doing. Not in the sample code and not in my 'real' code.
-
Wulf Community Admin
-
@Wulf ah, sorry. I misunderstood you. Yes that could happen which is one of two reasons why I wanted to use lock/ReaderWriterLockSlim.
Also I'm a bit confused by
-
I have to apologize for my not-so-nice way of phrasing things above. I also am obviously in the wrong here as I have read up a bit on Unity and it's single-threadedness.
However, I'm still confused about the output and the original problems I had. So my final question still stands: When a hook function in a C# script is called by Oxide, does Oxide wait for that method to return (synchronous) or does it proceed to call other hooks(asynchronous)? -
Wulf Community Admin
-
@Wulf thank you for answering so quickly and also (sort of) confirming the async part (at least to me that is async behaviour). How would I go about having a global Dictionary<uint, string> where I want to save the ID of the player that did something and a message, consisting among other things out of a date and time? Usually I would use lock for that...
-
Wulf Community Admin