Resource icon

ServUO Pub57.4.1 w/ Vitanex @Net10-windows 2026-04-19

Author
iWerking
Downloads
6
Views
37
First release
Last update

Ratings

0.00 star(s) 0 ratings
No permission to download Join the discussion

More resources from iWerking

Requirements
ClassicUO
Ultima Online client
What to expect:
~
Windows-only deployment (no linux/unix, net10 doesn't support it)
~ 30-40% performance gain out of the box for windows/windows server due to improvements in the language from C#7.3 to C#13
~ access to latest C# lang and .NET/Asp.net
~ single-process restarts/shutdown
~ autonomous hostpolicy.json net 2.0+ standalone-app fix
~ EnableDefaultItems compilation fix for duplicative files
~ Explicit .csproj inclusion compilation for "*.cs" files
you'll need to define new .cs files in the .csproj:

<ItemGroup>
<Compile Include="PATH_HERE\FileName.cs" />
<ItemGroup>
~ Expect a rosilyn-error to creep up, happens everywhere net2.0+, you'll need to reopen the IDE/clean the build until it resolves.
~ Delegate.BeginInvoke/EndInvoke is unsupported on .NET Core+/.NET 10 (it relied on .NET Remoting). Switching to Task.Run.
Delegate.BeginInvoke/EndInvoke (the legacy IAsyncResult pattern on plain Func/Action delegates) is not supported on .NET Core/5+/10 — it threw PlatformNotSupportedException from System.Func1.BeginInvoke` at runtime, even though it compiled fine. Three places used it:
  1. Scripts/Misc/
    ConsoleCommands.cs
    — replaced _Listen.BeginInvoke(...) (a Func over Console.ReadLine) with Task.Run(() = ProcessInput(Console.ReadLine())) via a small BeginListen() helper.
  2. Scripts/Misc/ArchivedSaves.cs — the async pack/prune for archived saves used _Pack.BeginInvoke/EndInvoke (Action) and _Prune.BeginInvoke/EndInvoke (Action DateTime). Replaced both with Task.Run(() = _Pack.Invoke(source)) and changed the _Tasks list from ListIAsyncResult to ListTask (still used by PendingTasks and the periodic IsCompleted cleanup, both of which work identically on Task).
  3. Scripts/Services/Ethics/Core/Ethic.cs:174 — power.BeginInvoke(pl) is a domain method on the abstract Power class (not the delegate API), so it stays as-is.


  4. I had to downgrade to C#12 because of errors.
    Estimated time to resolve it: 3 hours

    Scripts/VitaNex/Core/Modules/WebSockets/Objects/Client.cs
    Problem: CS0721 — MessagePump is now a static class, can't be a parameter
    Fix: Changed ctor to WebSocketsClient(TcpClient client) : base(new SocketState(client.Client, null))

    …/WebSockets.cs
    Problem: Caller passed Core.MessagePump (doesn't exist)

    Scripts/Scripts.csproj, Server.csproj, Ultima.csproj
    Problem: ServUO was only defined in Debug|x64/Release|x64 PropertyGroups, so design-time analysis (and the in-IDE Roslyn) was taking the #else branches and reporting OnCraft / CanCraft / GetPriceScalar mismatches
    Fix: Added an unconditional DefineConstants;ServUO;NEWTIMERS;TRACE

    Scripts/Scripts.csproj
    Problem: VitaNex/Core/Build/CSharpCompiler.cs needed System.CodeDom (legacy CSharpCodeProvider / CompilerParameters / CompilerResults); the NuGet package triggers the SDK 10.0.202 Roslyn NRE
    Fix: Excluded the file from compilation (with a comment explaining why). Runtime script compilation isn't used by the server.

    Scripts/VitaNex/Core/Extensions/System/EnumerableExt.cs
    Problem: CS0121 — OrderT(IEnumerableT) collides with the built-in System.Linq.Enumerable.OrderT added in .NET 7
    Fix: Removed the legacy OrderT / OrderDescendingT shims

    All three .csproj
    Problem: LangVersion=latest (C# 13) made the SDK 10.0.202 Roslyn ICE much more frequent
    Fix: Pinned LangVersion=12.0

    Scripts/Scripts.csproj
    Problem: Three new harmless analyzer warnings (CS0109, SYSLIB0001 UTF-7, SYSLIB0045 obsolete HashAlgorithm.Create)
    Fix: Added them to NoWarn

    There's a real intermittent NRE inside Microsoft.CodeAnalysis.CSharp.BindingDiagnosticBag.AddAssembliesUsedByNamespaceReference in .NET SDK 10.0.202. It crashes Roslyn while validating using directives over the very large Scripts compilation. It's not in our code, has no clean workaround, and in my testing succeeds on roughly the second attempt every time. If you see it, just rerun the build (or upgrade the SDK once a newer 10.0.30x ships).

    I actually want to use the VitaNex WebAPI for discord/X/stream/twitch integration so fixed that too;
    [Web API]: Exception has been thrown by the target of an invocation.
    [Web API]: Cannot set initonly static field 'Enabled' after type 'Server.Misc.StatusPage' is initialized.
    Resolution: Server.Misc.StatusPage.Enabled is declared as public static readonly bool — and on .NET 5+ writing to a readonly static via reflection throws FieldAccessException instead of silently succeeding like .NET Framework did. VitaNex was trying to flip it to false, which is already its value anyway.
    VitaNex's WebAPI.CSConfig() uses reflection to set it to false. On .NET Framework, FieldInfo.SetValue against an initonly static silently succeeded (legacy behavior). On .NET 5/6/.../10 the runtime correctly enforces the contract and throws FieldAccessException: Cannot set initonly static field 'Enabled' after type 'Server.Misc.StatusPage' is initialized.
    Fix: Skip the write when the field is IsInitOnly, and only write at all when the value would actually change. Also wrap in a try/catch (FieldAccessException) so any future reordering still configures cleanly.
    Since StatusPage.Enabled is already false in your build, the net effect is a no-op — VitaNex's intent (don't let the legacy status page steal the port) is already satisfied. The unwrap-TargetInvocationException change in CoreServiceInfo.ToConsole from the previous turn stays in place, so any future reflection failures will surface their real cause directly.


Useful for forking ClassicUO, Centred, UORazor, UOFiddler, or UOArchitect

Donations

Total amount
$50.00
Goal
$500.00

Shards

Back