|
1 | 1 | # RocketModFix.Unturned.Redist.Example |
2 | 2 |
|
| 3 | +A minimal [RocketMod](https://github.com/RocketModFix/RocketModFix) plugin showing how to consume the RocketModFix NuGet packages in an Unturned server plugin — in particular the [`RocketModFix.Unturned.Redist`](https://github.com/RocketModFix/RocketModFix.Unturned.Redist) **`.Publicized`** package, which lets a plugin read members that are non-public in the stock game. |
| 4 | + |
| 5 | +> This is an example **consumer** plugin. Its own namespace is `UnturnedRedistExample` — i.e. what *you'd* write in your own plugin — it just **references** the RocketModFix packages. |
| 6 | +
|
| 7 | +## What it demonstrates |
| 8 | + |
| 9 | +[`UnturnedRedistExamplePlugin.cs`](UnturnedRedistExamplePlugin.cs) is one class. On load it reads `SDG.Unturned.Provider.isDedicatedUGCInstalled` — a field that is **non-public** in the stock `Assembly-CSharp.dll` — and logs it: |
| 10 | + |
| 11 | +```csharp |
| 12 | +protected override void Load() |
| 13 | +{ |
| 14 | + // non-public in stock Unturned; reachable only via the .Publicized redist |
| 15 | + var ugcInstalled = Provider.isDedicatedUGCInstalled; |
| 16 | + Logger.Log($"[UnturnedRedistExample] Loaded. ... = {ugcInstalled} ..."); |
| 17 | +} |
| 18 | +``` |
| 19 | + |
| 20 | +That single line is the whole point: |
| 21 | + |
| 22 | +- It **compiles** only because the project references `RocketModFix.Unturned.Redist.Server.Publicized` (the publicizer rewrites that field to public). |
| 23 | +- It **runs** only because the `.csproj` sets `<AllowUnsafeBlocks>true</AllowUnsafeBlocks>`, which lets Unturned's Mono runtime skip the access check. |
| 24 | + |
| 25 | +## Packages used |
| 26 | + |
| 27 | +| Package | Why | |
| 28 | +| --- | --- | |
| 29 | +| [`RocketModFix.Rocket.Unturned`](https://www.nuget.org/packages/RocketModFix.Rocket.Unturned) | The RocketMod API — provides the `RocketPlugin` base class and `Logger`. | |
| 30 | +| [`RocketModFix.Unturned.Redist.Server.Publicized`](https://www.nuget.org/packages/RocketModFix.Unturned.Redist.Server.Publicized) | Unturned's server assemblies, **publicized** so the plugin can touch non-public members. Use [`…Server`](https://www.nuget.org/packages/RocketModFix.Unturned.Redist.Server) (without `.Publicized`) if you don't need that. | |
| 31 | +| [`RocketModFix.UnityEngine.Redist`](https://www.nuget.org/packages/RocketModFix.UnityEngine.Redist) | UnityEngine assemblies — required because Unturned types derive from `UnityEngine.MonoBehaviour`. | |
| 32 | + |
| 33 | +See the [redist README](https://github.com/RocketModFix/RocketModFix.Unturned.Redist#using-a-publicized-package) for more on `.Publicized` and `AllowUnsafeBlocks`. |
| 34 | + |
| 35 | +## Build |
| 36 | + |
| 37 | +```bash |
| 38 | +dotnet build -c Release |
| 39 | +``` |
| 40 | + |
| 41 | +The plugin DLL lands in `bin/Release/net461/UnturnedRedistExample.dll`. CI builds it on every push — see [`.github/workflows/build.yaml`](.github/workflows/build.yaml). |
| 42 | + |
| 43 | +## Verify it loads on a server |
| 44 | + |
| 45 | +1. Install [RocketModFix](https://github.com/RocketModFix/RocketModFix#installation) on an Unturned dedicated server (copy the `Rocket.Unturned` folder into `Modules/`) and start it once so it generates `Servers/<ServerID>/Rocket/`. |
| 46 | +2. Copy the built `UnturnedRedistExample.dll` into `Servers/<ServerID>/Rocket/Plugins/` (the DLL goes directly in `Plugins/`, not a subfolder). |
| 47 | +3. Start the server and watch the console for: |
| 48 | + |
| 49 | + ``` |
| 50 | + [UnturnedRedistExample] Loaded. Read non-public Provider.isDedicatedUGCInstalled = ... via the .Publicized redist. |
| 51 | + ``` |
| 52 | + |
| 53 | +That line confirms two things at once: the plugin **loaded**, and the **publicized** member was read successfully **at runtime** (so `AllowUnsafeBlocks` did its job). If publicization were broken you'd instead get a `FieldAccessException` / "is inaccessible" error. |
| 54 | + |
| 55 | +## License |
| 56 | + |
| 57 | +MIT — see [LICENSE](LICENSE). |
0 commit comments