Adds official .NET 5 support (#300)

This commit is contained in:
Kamron Batman 2020-11-07 13:26:27 -08:00 committed by GitHub
parent c3289a20ab
commit 013f333898
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
39 changed files with 496 additions and 668 deletions

View file

@ -19,15 +19,15 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
with: with:
fetch-depth: 0 # avoid shallow clone so nbgv can do its work. fetch-depth: 0 # avoid shallow clone so nbgv can do its work.
- name: Setup .NET Core - name: Setup .NET 5
uses: actions/setup-dotnet@v1 uses: actions/setup-dotnet@v1
with: with:
dotnet-version: 3.1.401 dotnet-version: 5.0.100-rc.2.20479.15
- name: Restore NuGet Packages - name: Restore NuGet Packages
run: dotnet restore --force-evaluate run: dotnet restore --force-evaluate
- name: Build Server - name: Build Server
run: dotnet build -c Release -f netcoreapp3.1 --no-restore Projects/Server/Server.csproj run: dotnet build -c Release -f net5.0 --no-restore Projects/Server/Server.csproj
- name: Build UO Content - name: Build UO Content
run: dotnet build -c Release -f netcoreapp3.1 --no-restore Projects/UOContent/UOContent.csproj run: dotnet build -c Release -f net5.0 --no-restore Projects/UOContent/UOContent.csproj
- name: Test - name: Test
run: dotnet test --no-restore -f netcoreapp3.1 run: dotnet test --no-restore -f net5.0

View file

@ -14,10 +14,10 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
with: with:
fetch-depth: 0 # avoid shallow clone so nbgv can do its work. fetch-depth: 0 # avoid shallow clone so nbgv can do its work.
- name: Setup .NET Core - name: Setup .NET 5
uses: actions/setup-dotnet@v1 uses: actions/setup-dotnet@v1
with: with:
dotnet-version: 3.1.401 dotnet-version: 5.0.100-rc.2.20479.15
- uses: dotnet/nbgv@master - uses: dotnet/nbgv@master
id: nbgv id: nbgv
- name: Create Release - name: Create Release
@ -50,10 +50,10 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
with: with:
fetch-depth: 0 # avoid shallow clone so nbgv can do its work. fetch-depth: 0 # avoid shallow clone so nbgv can do its work.
- name: Setup .NET Core - name: Setup .NET 5
uses: actions/setup-dotnet@v1 uses: actions/setup-dotnet@v1
with: with:
dotnet-version: 3.1.401 dotnet-version: 5.0.100-rc.2.20479.15
- uses: dotnet/nbgv@master - uses: dotnet/nbgv@master
id: nbgv id: nbgv
- name: Load Release URL File from release job - name: Load Release URL File from release job
@ -67,7 +67,7 @@ jobs:
echo ::set-output name=upload_url::$value echo ::set-output name=upload_url::$value
rm -rf ./release_url rm -rf ./release_url
- name: Publish Distribution - name: Publish Distribution
run: ./publish.cmd ${{ matrix.os }} core Release run: ./publish.cmd release ${{ matrix.os }}
- name: Create Artifact - name: Create Artifact
run: rm -rf ./Projects/*/bin && rm -rf ./Projects/*/obj && zip -9 -r modernuo-asset.zip ./* run: rm -rf ./Projects/*/bin && rm -rf ./Projects/*/obj && zip -9 -r modernuo-asset.zip ./*
- name: Upload Release - name: Upload Release

View file

@ -41,5 +41,5 @@ jobs:
shell: powershell shell: powershell
run: | run: |
.\.sonar\scanner\dotnet-sonarscanner begin /k:"modernuo_ModernUO" /o:"modernuo" /d:sonar.login="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" .\.sonar\scanner\dotnet-sonarscanner begin /k:"modernuo_ModernUO" /o:"modernuo" /d:sonar.login="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io"
.\publish.cmd win core Release .\publish.cmd release win
.\.sonar\scanner\dotnet-sonarscanner end /d:sonar.login="${{ secrets.SONAR_TOKEN }}" .\.sonar\scanner\dotnet-sonarscanner end /d:sonar.login="${{ secrets.SONAR_TOKEN }}"

22
.gitignore vendored
View file

@ -8,33 +8,13 @@
/Distribution/Backups /Distribution/Backups
/Distribution/Saves /Distribution/Saves
/Distribution/docs /Distribution/docs
/Distribution/System.IO.Pipelines.dll
/Distribution/libdrng.dll
/Distribution/zlib.dll /Distribution/zlib.dll
/Distribution/libz.dylib /Distribution/libz.dylib
/Distribution/libz.so /Distribution/libz.so
/Distribution/Microsoft.Bcl.AsyncInterfaces.dll
/Distribution/System.ComponentModel.Annotations.dll
/Distribution/System.Runtime.CompilerServices.Unsafe.dll
/Distribution/ZLib.Bindings.dll /Distribution/ZLib.Bindings.dll
/Distribution/Data/modernuo.json
/Distribution/runtimes /Distribution/runtimes
/Distribution/nohup.out /Distribution/nohup.out
/Distribution/ref
# LibUv Dependencies
/Distribution/libuv.dylib
/Distribution/libuv.dll
/Distribution/libuv.so
/Distribution/Microsoft.AspNetCore.Connections.Abstractions.dll
/Distribution/Microsoft.AspNetCore.Http.Features.dll
/Distribution/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.dll
/Distribution/Microsoft.Extensions.Configuration.Abstractions.dll
/Distribution/Microsoft.Extensions.DependencyInjection.Abstractions.dll
/Distribution/Microsoft.Extensions.FileProviders.Abstractions.dll
/Distribution/Microsoft.Extensions.Hosting.Abstractions.dll
/Distribution/Microsoft.Extensions.Logging.Abstractions.dll
/Distribution/Microsoft.Extensions.Options.dll
/Distribution/Microsoft.Extensions.Primitives.dll
/Projects/*/obj /Projects/*/obj
/Projects/*/bin /Projects/*/bin

View file

@ -4,10 +4,10 @@
<Authors>Kamron Batman</Authors> <Authors>Kamron Batman</Authors>
<Company>ModernUO</Company> <Company>ModernUO</Company>
<Copyright>2019-2020</Copyright> <Copyright>2019-2020</Copyright>
<TargetFramework>netcoreapp3.1</TargetFramework> <TargetFrameworks>netcoreapp3.1;net5.0</TargetFrameworks>
<Platforms>x64</Platforms> <Platforms>x64</Platforms>
<PlatformTarget>x64</PlatformTarget> <PlatformTarget>x64</PlatformTarget>
<LangVersion>8.0</LangVersion> <LangVersion>9</LangVersion>
<PublicRelease>true</PublicRelease> <PublicRelease>true</PublicRelease>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<NoWarn>NU1603</NoWarn> <NoWarn>NU1603</NoWarn>
@ -30,6 +30,7 @@
<DisableFastUpToDateCheck>true</DisableFastUpToDateCheck> <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
<SelfContained>false</SelfContained> <SelfContained>false</SelfContained>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(IsWindows)'=='true' AND '$(RuntimeIdentifier)'==''"> <PropertyGroup Condition="'$(IsWindows)'=='true' AND '$(RuntimeIdentifier)'==''">
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>

View file

@ -64,7 +64,7 @@ namespace Server.Tests.Network
public long GetTotalGold() => TotalGold + TotalPlat * 100; public long GetTotalGold() => TotalGold + TotalPlat * 100;
public int CompareTo(IAccount other) => other == null ? 1 : Username.CompareTo(other.Username); public int CompareTo(IAccount other) => string.CompareOrdinal(Username, other?.Username);
public string Username { get; set; } public string Username { get; set; }
public string Email { get; set; } public string Email { get; set; }
@ -90,6 +90,6 @@ namespace Server.Tests.Network
public bool CheckPassword(string password) => m_Password == password; public bool CheckPassword(string password) => m_Password == password;
public int CompareTo(MockAccount other) => other == null ? 1 : Username.CompareTo(other.Username); public int CompareTo(MockAccount other) => string.CompareOrdinal(Username, other?.Username);
} }
} }

View file

@ -3,7 +3,7 @@
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
<PackageReference Include="xunit" Version="2.4.1" /> <PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
<PackageReference Include="coverlet.collector" Version="1.3.0" /> <PackageReference Include="coverlet.collector" Version="1.3.0" />

View file

@ -60,12 +60,12 @@ namespace Server
} }
} }
if (fmt.IndexOf("god") >= 0 || fmt.IndexOf("gq") >= 0) if (fmt.IndexOf("god", StringComparison.Ordinal) >= 0 || fmt.IndexOf("gq", StringComparison.Ordinal) >= 0)
{ {
Type = ClientType.God; Type = ClientType.God;
} }
else if (fmt.IndexOf("third dawn") >= 0 || fmt.IndexOf("uo:td") >= 0 || fmt.IndexOf("uotd") >= 0 || else if (fmt.IndexOf("third dawn", StringComparison.Ordinal) >= 0 || fmt.IndexOf("uo:td", StringComparison.Ordinal) >= 0 || fmt.IndexOf("uotd", StringComparison.Ordinal) >= 0 ||
fmt.IndexOf("uo3d") >= 0 || fmt.IndexOf("uo:3d") >= 0) fmt.IndexOf("uo3d", StringComparison.Ordinal) >= 0 || fmt.IndexOf("uo:3d", StringComparison.Ordinal) >= 0)
{ {
Type = ClientType.UOTD; Type = ClientType.UOTD;
} }

View file

@ -108,7 +108,7 @@ namespace Server
public AccessLevel AccessLevel { get; } public AccessLevel AccessLevel { get; }
public int CompareTo(CommandEntry e) => e == null ? 1 : Command.CompareTo(e.Command); public int CompareTo(CommandEntry e) => string.CompareOrdinal(Command, e?.Command);
} }
public static class CommandSystem public static class CommandSystem

View file

@ -244,7 +244,7 @@ namespace Server
break; break;
} }
if (ipStr.IndexOf(":", StringComparison.Ordinal) == -1) if (ipStr.IndexOf(':') == -1)
{ {
ipStr += ":2593"; ipStr += ":2593";
} }

View file

@ -104,23 +104,13 @@ namespace Server
public int CompareTo(Point2D other) public int CompareTo(Point2D other)
{ {
var xComparison = m_X.CompareTo(other.m_X); var xComparison = m_X.CompareTo(other.m_X);
if (xComparison != 0) return xComparison != 0 ? xComparison : m_Y.CompareTo(other.m_Y);
{
return xComparison;
}
return m_Y.CompareTo(other.m_Y);
} }
public int CompareTo(IPoint2D other) public int CompareTo(IPoint2D other)
{ {
var xComparison = m_X.CompareTo(other.X); var xComparison = m_X.CompareTo(other.X);
if (xComparison != 0) return xComparison != 0 ? xComparison : m_Y.CompareTo(other.Y);
{
return xComparison;
}
return m_Y.CompareTo(other.Y);
} }
} }
} }

View file

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -63,7 +64,7 @@ namespace Server.Guilds
{ {
var name = g.Name.ToLower(); var name = g.Name.ToLower();
if (words.All(t => name.IndexOf(t) != -1)) if (words.All(t => name.IndexOf(t, StringComparison.Ordinal) != -1))
{ {
results.Add(g); results.Add(g);
} }

View file

@ -163,7 +163,7 @@ namespace Server.Network
public bool IsDisposing => m_Disposing != 0; public bool IsDisposing => m_Disposing != 0;
public int CompareTo(NetState other) => other == null ? 1 : m_ToString.CompareTo(other.m_ToString); public int CompareTo(NetState other) => string.CompareOrdinal(m_ToString, other?.m_ToString);
public void ValidateAllTrades() public void ValidateAllTrades()
{ {

View file

@ -26,7 +26,7 @@
<Delete Files="..\..\Distribution\$(AssemblyName).runtimeconfig.json" ContinueOnError="true" /> <Delete Files="..\..\Distribution\$(AssemblyName).runtimeconfig.json" ContinueOnError="true" />
</Target> </Target>
<ItemGroup> <ItemGroup>
<PackageReference Include="Nerdbank.GitVersioning" Version="3.2.31"> <PackageReference Include="Nerdbank.GitVersioning" Version="3.3.37">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>

View file

@ -3,7 +3,7 @@
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
<PackageReference Include="xunit" Version="2.4.1" /> <PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
<PackageReference Include="coverlet.collector" Version="1.3.0" /> <PackageReference Include="coverlet.collector" Version="1.3.0" />

View file

@ -403,7 +403,7 @@ namespace Server.Accounting
} }
} }
public int CompareTo(IAccount other) => other == null ? 1 : Username.CompareTo(other.Username); public int CompareTo(IAccount other) => string.CompareOrdinal(Username, other?.Username);
/// <summary> /// <summary>
/// This amount represents the current amount of Gold owned by the player. /// This amount represents the current amount of Gold owned by the player.
@ -512,7 +512,7 @@ namespace Server.Accounting
/// <returns>Total gold, capped at Int32.MaxValue</returns> /// <returns>Total gold, capped at Int32.MaxValue</returns>
public long GetTotalGold() => TotalGold + TotalPlat * AccountGold.CurrencyThreshold; public long GetTotalGold() => TotalGold + TotalPlat * AccountGold.CurrencyThreshold;
public int CompareTo(Account other) => other == null ? 1 : Username.CompareTo(other.Username); public int CompareTo(Account other) => string.CompareOrdinal(Username, other?.Username);
/// <summary> /// <summary>
/// Gets the value of a specific flag in the Flags bitfield. /// Gets the value of a specific flag in the Flags bitfield.

View file

@ -2835,7 +2835,10 @@ namespace Server.Commands
if (v == 0) if (v == 0)
{ {
v = GetNameFrom(aCtor, aProp, aMethod).CompareTo(GetNameFrom(bCtor, bProp, bMethod)); v = string.CompareOrdinal(
GetNameFrom(aCtor, aProp, aMethod),
GetNameFrom(bCtor, bProp, bMethod)
);
} }
if (v == 0 && aCtor != null && bCtor != null) if (v == 0 && aCtor != null && bCtor != null)
@ -2879,11 +2882,7 @@ namespace Server.Commands
private class TypeComparer : IComparer<TypeInfo> private class TypeComparer : IComparer<TypeInfo>
{ {
public int Compare(TypeInfo x, TypeInfo y) => public int Compare(TypeInfo x, TypeInfo y) => string.CompareOrdinal(x?.TypeName, y?.TypeName);
x == null && y == null ? 0 :
x == null ? -1 :
y == null ? 1 :
x.TypeName.CompareTo(y.TypeName);
} }
private class TypeInfo private class TypeInfo
@ -2973,12 +2972,7 @@ namespace Server.Commands
var v = b?.AccessLevel.CompareTo(a?.AccessLevel) ?? 1; var v = b?.AccessLevel.CompareTo(a?.AccessLevel) ?? 1;
if (v != 0) return v != 0 ? v : string.CompareOrdinal(a?.Name, b?.Name);
{
return v;
}
return a?.Name.CompareTo(b?.Name) ?? 1;
} }
} }
} }
@ -3034,12 +3028,7 @@ namespace Server.Commands
v = a?.Body.BodyID.CompareTo(b?.Body.BodyID) ?? 1; v = a?.Body.BodyID.CompareTo(b?.Body.BodyID) ?? 1;
} }
if (v != 0) return v != 0 ? v : string.CompareOrdinal(a?.Name, b?.Name);
{
return v;
}
return a?.Name.CompareTo(b?.Name) ?? 1;
} }
} }
} }

View file

@ -135,7 +135,7 @@ namespace Server.Gumps
var t = types[i]; var t = types[i];
if ((typeofMobile.IsAssignableFrom(t) || typeofItem.IsAssignableFrom(t)) && if ((typeofMobile.IsAssignableFrom(t) || typeofItem.IsAssignableFrom(t)) &&
t.Name.ToLower().IndexOf(match) >= 0 && !results.Contains(t)) t.Name.ToLower().IndexOf(match, StringComparison.Ordinal) >= 0 && !results.Contains(t))
{ {
var ctors = t.GetConstructors(); var ctors = t.GetConstructors();
@ -236,7 +236,7 @@ namespace Server.Gumps
private class TypeNameComparer : IComparer<Type> private class TypeNameComparer : IComparer<Type>
{ {
public int Compare(Type x, Type y) => x?.Name.CompareTo(y?.Name) ?? 1; public int Compare(Type x, Type y) => string.CompareOrdinal(x?.Name, y?.Name);
} }
public class InternalTarget : Target public class InternalTarget : Target

View file

@ -265,34 +265,14 @@ namespace Server.Commands
public class CategorySorter : IComparer<CategoryEntry> public class CategorySorter : IComparer<CategoryEntry>
{ {
public int Compare(CategoryEntry x, CategoryEntry y) public int Compare(CategoryEntry x, CategoryEntry y) =>
{ string.CompareOrdinal(x?.Title, y?.Title);
var a = x?.Title;
var b = y?.Title;
return a switch
{
null when b == null => 0,
null => 1,
_ => a.CompareTo(b)
};
}
} }
public class CategoryTypeSorter : IComparer<CategoryTypeEntry> public class CategoryTypeSorter : IComparer<CategoryTypeEntry>
{ {
public int Compare(CategoryTypeEntry x, CategoryTypeEntry y) public int Compare(CategoryTypeEntry x, CategoryTypeEntry y) =>
{ string.CompareOrdinal(x?.Type.Name, y?.Type.Name);
var a = x?.Type.Name;
var b = y?.Type.Name;
return a switch
{
null when b == null => 0,
null => 1,
_ => a.CompareTo(b)
};
}
} }
public class CategoryTypeEntry public class CategoryTypeEntry

View file

@ -390,7 +390,7 @@ namespace Server.Commands
var v = -aCount.CompareTo(bCount); var v = -aCount.CompareTo(bCount);
return v != 0 ? v : x.Key.FullName?.CompareTo(y.Key.FullName) ?? -1; return v != 0 ? v : string.CompareOrdinal(x.Key.FullName, y.Key.FullName);
} }
} }
@ -403,7 +403,7 @@ namespace Server.Commands
var v = -aCount.CompareTo(bCount); var v = -aCount.CompareTo(bCount);
return v != 0 ? v : x.Key.FullName?.CompareTo(y.Key.FullName) ?? 1; return v != 0 ? v : string.CompareOrdinal(x.Key.FullName, y.Key.FullName);
} }
} }
} }

View file

@ -522,28 +522,7 @@ namespace Server.Engines.ConPVP
public static List<Arena> Arenas { get; } = new List<Arena>(); public static List<Arena> Arenas { get; } = new List<Arena>();
public int CompareTo(Arena c) public int CompareTo(Arena c) => string.CompareOrdinal(m_Name, c?.m_Name);
{
var a = m_Name;
var b = c.m_Name;
if (a == null && b == null)
{
return 0;
}
if (a == null)
{
return -1;
}
if (b == null)
{
return +1;
}
return a.CompareTo(b);
}
public Ladder AcquireLadder() => Ladder?.Ladder ?? ConPVP.Ladder.Instance; public Ladder AcquireLadder() => Ladder?.Ladder ?? ConPVP.Ladder.Instance;

View file

@ -2463,12 +2463,12 @@ namespace Server.Gumps
var m = ns.Mobile; var m = ns.Mobile;
var a = ns.Account; var a = ns.Account;
isMatch = m?.Name.ToLower().IndexOf(match) >= 0 isMatch = m?.Name.ToLower().IndexOf(match, StringComparison.Ordinal) >= 0
|| a?.Username.ToLower().IndexOf(match) >= 0; || a?.Username.ToLower().IndexOf(match, StringComparison.Ordinal) >= 0;
} }
else else
{ {
isMatch = ns.ToString().IndexOf(match) >= 0; isMatch = ns.ToString().IndexOf(match, StringComparison.Ordinal) >= 0;
} }
if (isMatch) if (isMatch)
@ -2725,7 +2725,8 @@ namespace Server.Gumps
else else
{ {
results = Accounts.GetAccounts() results = Accounts.GetAccounts()
.Where(acct => acct.Username.ToLower().IndexOf(match) >= 0) .Where(acct =>
acct.Username.ToLower().IndexOf(match, StringComparison.Ordinal) >= 0)
.ToList(); .ToList();
results.Sort(AccountComparer.Instance); results.Sort(AccountComparer.Instance);
} }

View file

@ -1,3 +1,4 @@
using System;
using Server.Gumps; using Server.Gumps;
using Server.Misc; using Server.Misc;
using Server.Mobiles; using Server.Mobiles;
@ -119,7 +120,7 @@ namespace Server.Guilds
for (var i = 0; i < disallowed.Length; i++) for (var i = 0; i < disallowed.Length; i++)
{ {
if (s.IndexOf(disallowed[i]) != -1) if (s.IndexOf(disallowed[i], StringComparison.Ordinal) != -1)
{ {
return false; return false;
} }

View file

@ -868,7 +868,7 @@ namespace Server.Gumps
return -1; return -1;
} }
return y == null ? 1 : x.Name.CompareTo(x.Name); return y == null ? 1 : string.CompareOrdinal(x.Name, x.Name);
} }
} }

View file

@ -330,12 +330,7 @@ namespace Server.Gumps
public int CompareTo(InternalEntry comp) public int CompareTo(InternalEntry comp)
{ {
if (Name == null && comp.Name == null) var v = string.CompareOrdinal(Name, comp.Name);
{
return 0;
}
var v = Name?.CompareTo(comp.Name) ?? 1;
return v == 0 ? Body.CompareTo(comp.Body) : v; return v == 0 ? Body.CompareTo(comp.Body) : v;
} }

View file

@ -634,7 +634,7 @@ namespace Server.Gumps
var aName = SkillInfo.Table[(int)a].Name; var aName = SkillInfo.Table[(int)a].Name;
var bName = SkillInfo.Table[(int)b].Name; var bName = SkillInfo.Table[(int)b].Name;
return aName.CompareTo(bName); return string.CompareOrdinal(aName, bName);
} }
} }
} }

View file

@ -105,7 +105,7 @@ namespace Server.Gumps
if (m != null && (m == owner || !m.Hidden || owner.AccessLevel >= m.AccessLevel || if (m != null && (m == owner || !m.Hidden || owner.AccessLevel >= m.AccessLevel ||
m is PlayerMobile mobile && mobile.VisibilityList.Contains(owner))) m is PlayerMobile mobile && mobile.VisibilityList.Contains(owner)))
{ {
if (filter != null && !(m.Name?.ToLower().IndexOf(filter) >= 0)) if (filter != null && !(m.Name?.ToLower().IndexOf(filter, StringComparison.Ordinal) >= 0))
{ {
continue; continue;
} }

View file

@ -598,7 +598,7 @@ namespace Server.Items
{ {
isMatch = true; isMatch = true;
} }
else if (m_Substring != null && e.Speech.ToLower().IndexOf(m_Substring.ToLower()) >= 0) else if (m_Substring != null && e.Speech.ToLower().IndexOf(m_Substring.ToLower(), StringComparison.Ordinal) >= 0)
{ {
isMatch = true; isMatch = true;
} }

View file

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using Server.Accounting; using Server.Accounting;
@ -19,7 +20,7 @@ namespace Server.Misc
* If you do not see the above chars, please * If you do not see the above chars, please
* enable showing of unicode control chars * enable showing of unicode control chars
**/ **/
public class LanguageStatistics public static class LanguageStatistics
{ {
private static readonly InternationalCode[] InternationalCodes = private static readonly InternationalCode[] InternationalCodes =
{ {
@ -346,13 +347,8 @@ namespace Server.Misc
public int Compare(InternationalCodeCounter x, InternationalCodeCounter y) public int Compare(InternationalCodeCounter x, InternationalCodeCounter y)
{ {
string a = null, b = null; var ca = x?.Count ?? 0;
int ca = 0, cb = 0; var cb = y?.Count ?? 0;
a = x.Code;
ca = x.Count;
b = y.Code;
cb = y.Count;
if (ca > cb) if (ca > cb)
{ {
@ -364,22 +360,7 @@ namespace Server.Misc
return 1; return 1;
} }
if (a == null && b == null) return string.CompareOrdinal(x?.Code, y?.Code);
{
return 0;
}
if (a == null)
{
return 1;
}
if (b == null)
{
return -1;
}
return a.CompareTo(b);
} }
} }
} }

View file

@ -202,7 +202,7 @@ namespace Server.Misc
for (var i = 0; i < disallowed.Length; ++i) for (var i = 0; i < disallowed.Length; ++i)
{ {
var indexOf = name.IndexOf(disallowed[i]); var indexOf = name.IndexOf(disallowed[i], StringComparison.Ordinal);
if (indexOf == -1) if (indexOf == -1)
{ {

View file

@ -1,3 +1,5 @@
using System;
namespace Server.Misc namespace Server.Misc
{ {
public static class RenameRequests public static class RenameRequests
@ -32,7 +34,7 @@ namespace Server.Misc
for (var i = 0; i < disallowed.Length; i++) for (var i = 0; i < disallowed.Length; i++)
{ {
if (name.IndexOf(disallowed[i]) != -1) if (name.IndexOf(disallowed[i], StringComparison.Ordinal) != -1)
{ {
from.SendLocalizedMessage(1072622); // That name isn't very polite. from.SendLocalizedMessage(1072622); // That name isn't very polite.
return; return;

View file

@ -806,9 +806,8 @@ namespace Server.Items
/// Returns the first <see cref="CraftResource" /> in the series of resources for which '<paramref name="resource" />' /// Returns the first <see cref="CraftResource" /> in the series of resources for which '<paramref name="resource" />'
/// belongs. /// belongs.
/// </summary> /// </summary>
public static CraftResource GetStart(CraftResource resource) public static CraftResource GetStart(CraftResource resource) =>
{ GetType(resource) switch
return GetType(resource) switch
{ {
CraftResourceType.Metal => CraftResource.Iron, CraftResourceType.Metal => CraftResource.Iron,
CraftResourceType.Leather => CraftResource.RegularLeather, CraftResourceType.Leather => CraftResource.RegularLeather,
@ -816,7 +815,6 @@ namespace Server.Items
CraftResourceType.Wood => CraftResource.RegularWood, CraftResourceType.Wood => CraftResource.RegularWood,
_ => CraftResource.None _ => CraftResource.None
}; };
}
/// <summary> /// <summary>
/// Returns the index of '<paramref name="resource" />' in the seriest of resources for which it belongs. /// Returns the index of '<paramref name="resource" />' in the seriest of resources for which it belongs.
@ -872,72 +870,39 @@ namespace Server.Items
/// </summary> /// </summary>
public static CraftResource GetFromOreInfo(OreInfo info) public static CraftResource GetFromOreInfo(OreInfo info)
{ {
if (info.Name.IndexOf("Spined") >= 0) if (info.Name.IndexOf("Spined", StringComparison.Ordinal) >= 0)
{ {
return CraftResource.SpinedLeather; return CraftResource.SpinedLeather;
} }
if (info.Name.IndexOf("Horned") >= 0) if (info.Name.IndexOf("Horned", StringComparison.Ordinal) >= 0)
{ {
return CraftResource.HornedLeather; return CraftResource.HornedLeather;
} }
if (info.Name.IndexOf("Barbed") >= 0) if (info.Name.IndexOf("Barbed", StringComparison.Ordinal) >= 0)
{ {
return CraftResource.BarbedLeather; return CraftResource.BarbedLeather;
} }
if (info.Name.IndexOf("Leather") >= 0) if (info.Name.IndexOf("Leather", StringComparison.Ordinal) >= 0)
{ {
return CraftResource.RegularLeather; return CraftResource.RegularLeather;
} }
if (info.Level == 0) return info.Level switch
{ {
return CraftResource.Iron; 0 => CraftResource.Iron,
} 1 => CraftResource.DullCopper,
2 => CraftResource.ShadowIron,
if (info.Level == 1) 3 => CraftResource.Copper,
{ 4 => CraftResource.Bronze,
return CraftResource.DullCopper; 5 => CraftResource.Gold,
} 6 => CraftResource.Agapite,
7 => CraftResource.Verite,
if (info.Level == 2) 8 => CraftResource.Valorite,
{ _ => CraftResource.None
return CraftResource.ShadowIron; };
}
if (info.Level == 3)
{
return CraftResource.Copper;
}
if (info.Level == 4)
{
return CraftResource.Bronze;
}
if (info.Level == 5)
{
return CraftResource.Gold;
}
if (info.Level == 6)
{
return CraftResource.Agapite;
}
if (info.Level == 7)
{
return CraftResource.Verite;
}
if (info.Level == 8)
{
return CraftResource.Valorite;
}
return CraftResource.None;
} }
/// <summary> /// <summary>
@ -946,35 +911,23 @@ namespace Server.Items
/// </summary> /// </summary>
public static CraftResource GetFromOreInfo(OreInfo info, ArmorMaterialType material) public static CraftResource GetFromOreInfo(OreInfo info, ArmorMaterialType material)
{ {
if (material == ArmorMaterialType.Studded || material == ArmorMaterialType.Leather || if (material != ArmorMaterialType.Studded && material != ArmorMaterialType.Leather &&
material == ArmorMaterialType.Spined || material != ArmorMaterialType.Spined && material != ArmorMaterialType.Horned &&
material == ArmorMaterialType.Horned || material == ArmorMaterialType.Barbed) material != ArmorMaterialType.Barbed)
{ {
if (info.Level == 0)
{
return CraftResource.RegularLeather;
}
if (info.Level == 1)
{
return CraftResource.SpinedLeather;
}
if (info.Level == 2)
{
return CraftResource.HornedLeather;
}
if (info.Level == 3)
{
return CraftResource.BarbedLeather;
}
return CraftResource.None;
}
return GetFromOreInfo(info); return GetFromOreInfo(info);
} }
return info.Level switch
{
0 => CraftResource.RegularLeather,
1 => CraftResource.SpinedLeather,
2 => CraftResource.HornedLeather,
3 => CraftResource.BarbedLeather,
_ => CraftResource.None
};
}
} }
// NOTE: This class is only for compatibility with very old RunUO versions. // NOTE: This class is only for compatibility with very old RunUO versions.

View file

@ -393,7 +393,7 @@ namespace Server.Misc
do do
{ {
++count; ++count;
index = title.IndexOf("<br>", index + 1); index = title.IndexOf("<br>", index + 1, StringComparison.Ordinal);
} while (index >= 0); } while (index >= 0);
return count; return count;

View file

@ -7,7 +7,6 @@ ModernUO [![Discord](https://img.shields.io/discord/751317910504603701?logo=disc
##### Ultima Online Server Emulator for the modern era! ##### Ultima Online Server Emulator for the modern era!
[![.NET](https://img.shields.io/badge/.NET-%205.0-5C2D91)](https://dotnet.microsoft.com/download/dotnet/5.0) [![.NET](https://img.shields.io/badge/.NET-%205.0-5C2D91)](https://dotnet.microsoft.com/download/dotnet/5.0)
[![.NET Core](https://img.shields.io/badge/.NET-Core%203.1.9-5C2D91)](https://dotnet.microsoft.com/download/dotnet-core/3.1)
<br /> <br />
![Windows](https://img.shields.io/badge/-server%202019-0078D6?logo=windows) ![Windows](https://img.shields.io/badge/-server%202019-0078D6?logo=windows)
![OSX](https://img.shields.io/badge/-catalina-222222?logo=apple&logoColor=white) ![OSX](https://img.shields.io/badge/-catalina-222222?logo=apple&logoColor=white)
@ -27,31 +26,24 @@ ModernUO [![Discord](https://img.shields.io/discord/751317910504603701?logo=disc
## Publishing a build ## Publishing a build
#### Requirements #### Requirements
- [.NET Core 3.1.9 SDK](https://dotnet.microsoft.com/download/dotnet-core/3.1) - [.NET 5 SDK](https://dotnet.microsoft.com/download/dotnet/5.0)
<br />or
- [.NET 5.0 (Preview) SDK](https://dotnet.microsoft.com/download/dotnet/5.0)
#### Publishing Builds #### Publishing Builds
- Using terminal or powershell: `./publish.cmd [os] [framework] [release|debug (default: release)]` - Using terminal or powershell: `./publish.cmd [release|debug (default: release)] [os]`
- Supported `os`: - Supported `os`:
- `win` for Windows 8/10/2019 - `win` for Windows 8/10/2019
- `osx` for MacOS - `osx` for MacOS
- `ubuntu.16.04`, `ubuntu.18.04` `ubuntu.20.04` for Ubuntu LTS - `ubuntu.16.04`, `ubuntu.18.04` `ubuntu.20.04` for Ubuntu LTS
- `debian.9`, `debian.10` for Debian - `debian.9`, `debian.10` for Debian
- `centos.7`, `centos.8` for CentOS - `centos.7`, `centos.8` for CentOS
- If blank, will use host operating system - If blank, the host operating system is used
- Supported `framework`:
- `core` for .NET Core 3.1.9
- `net` for .NET 5.0
## Deploying / Running Server ## Deploying / Running Server
- Follow the [publish](https://github.com/modernuo/ModernUO#publishing-a-build) instructions - Follow the [publish](https://github.com/modernuo/ModernUO#publishing-a-build) instructions
- Copy `Distribution` directory to the production server - Copy `Distribution` directory to the production server
#### Requirements #### Requirements
- [.NET Core 3.1.9 Runtime](https://dotnet.microsoft.com/download/dotnet-core/3.1) - [.NET 5 Runtime](https://dotnet.microsoft.com/download/dotnet/5.0)
<br />or
- [.NET 5.0 (Preview) Runtime](https://dotnet.microsoft.com/download/dotnet/5.0)
#### Running #### Running
- `dotnet ModernUO.dll` - `dotnet ModernUO.dll`

View file

@ -15,29 +15,35 @@ jobs:
steps: steps:
- task: UseDotNet@2 - task: UseDotNet@2
displayName: 'Install .NET Core' displayName: 'Install .NET 5'
inputs: inputs:
packageType: sdk packageType: sdk
version: '3.1.401' version: '5.0.100-rc.2.20479.15'
- task: NuGetAuthenticate@0 - task: NuGetAuthenticate@0
- script: dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json - script: dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json
displayName: 'Restore NuGet Packages' displayName: 'Restore NuGet Packages'
- script: dotnet build -c $(buildConfiguration) -f netcoreapp3.1 --no-restore Projects/Server/Server.csproj - script: dotnet build -c $(buildConfiguration) -f net5.0 --no-restore Projects/Server/Server.csproj
displayName: 'Build Server' displayName: 'Build Server'
- script: dotnet build -c $(buildConfiguration) -f netcoreapp3.1 --no-restore Projects/UOContent/UOContent.csproj - script: dotnet build -c $(buildConfiguration) -f net5.0 --no-restore Projects/UOContent/UOContent.csproj
displayName: 'Build UO Content' displayName: 'Build UO Content'
- script: dotnet test --no-restore -f netcoreapp3.1 - script: dotnet test --no-restore -f net5.0
displayName: 'Test' displayName: 'Test'
- job: BuildLinux - job: BuildLinux
strategy: strategy:
matrix: matrix:
'Debian 9':
containerImage: amd64/buildpack-deps:stretch
'Debian 10': 'Debian 10':
containerImage: mcr.microsoft.com/dotnet/core/sdk:3.1-buster containerImage: amd64/buildpack-deps:buster
# 'Debian 11':
# containerImage: amd64/buildpack-deps:bullseye
'Ubuntu 16':
containerImage: amd64/buildpack-deps:xenial
'Ubuntu 18': 'Ubuntu 18':
containerImage: mcr.microsoft.com/dotnet/core/sdk:3.1-bionic containerImage: amd64/buildpack-deps:bionic
'Ubuntu 20': 'Ubuntu 20':
containerImage: mcr.microsoft.com/dotnet/core/sdk:3.1-focal containerImage: amd64/buildpack-deps:focal
displayName: Linux displayName: Linux
@ -48,16 +54,16 @@ jobs:
steps: steps:
- task: UseDotNet@2 - task: UseDotNet@2
displayName: 'Install .NET Core' displayName: 'Install .NET 5'
inputs: inputs:
packageType: sdk packageType: sdk
version: '3.1.401' version: '5.0.100-rc.2.20479.15'
- task: NuGetAuthenticate@0 - task: NuGetAuthenticate@0
- script: dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json - script: dotnet restore --force-evaluate --source https://api.nuget.org/v3/index.json
displayName: 'Restore NuGet Packages' displayName: 'Restore NuGet Packages'
- script: dotnet build -c $(buildConfiguration) -f netcoreapp3.1 --no-restore Projects/Server/Server.csproj - script: dotnet build -c $(buildConfiguration) -f net5.0 --no-restore Projects/Server/Server.csproj
displayName: 'Build Server' displayName: 'Build Server'
- script: dotnet build -c $(buildConfiguration) -f netcoreapp3.1 --no-restore Projects/UOContent/UOContent.csproj - script: dotnet build -c $(buildConfiguration) -f net5.0 --no-restore Projects/UOContent/UOContent.csproj
displayName: 'Build UO Content' displayName: 'Build UO Content'
- script: dotnet test --no-restore -f netcoreapp3.1 - script: dotnet test --no-restore -f net5.0
displayName: 'Test' displayName: 'Test'

View file

@ -9,13 +9,13 @@ The server software must be built before it can be run.
=== "Windows" === "Windows"
Using _command prompt_, _git bash_, or _powershell_, run: Using _command prompt_, _git bash_, or _powershell_, run:
```bash ```bash
./publish.cmd <os> <framework> <release|debug> ./publish.cmd <release|debug> <os>
``` ```
=== "OSX/Linux" === "OSX/Linux"
Using _terminal_, run: Using _terminal_, run:
```bash ```bash
./publish.sh <os> <framework> <release|debug> ./publish.sh <release|debug> <os>
``` ```
<br><br> <br><br>
`os` (_Optional_)<br> `os` (_Optional_)<br>
@ -25,11 +25,4 @@ The operating system to build the server against. If not specified then the serv
:fontawesome-brands-apple:{: .apple } `osx`<br> :fontawesome-brands-apple:{: .apple } `osx`<br>
:fontawesome-brands-ubuntu:{: .ubuntu } `ubuntu.16.04`, `ubuntu.18.04` `ubuntu.20.04`<br> :fontawesome-brands-ubuntu:{: .ubuntu } `ubuntu.16.04`, `ubuntu.18.04` `ubuntu.20.04`<br>
:brands-debian:{: .debian } `debian.9`, `debian.10`<br> :brands-debian:{: .debian } `debian.9`, `debian.10`<br>
:fontawesome-brands-centos:{: .centos } `centos.7`, `centos.8`<br> :fontawesome-brands-centos:{: .centos } `centos.7`, `centos.8`
<br>
`framework` (_Optional_)<br>
The framework used to build the server. That framework must be installed.
.NET Core 3.1 `core`<br>
.NET 5 Preview `net`

View file

@ -6,7 +6,7 @@ title: Installation
=== "Windows" === "Windows"
### Prerequisites ### Prerequisites
1. Download and install the latest [.NET Core SDK](https://dotnet.microsoft.com/download/dotnet-core/3.1) 1. Download and install the latest [.NET 5 SDK](https://dotnet.microsoft.com/download/dotnet/5.0)
1. Download and install from [here](https://git-scm.com/download/win) 1. Download and install from [here](https://git-scm.com/download/win)
!!! Tip !!! Tip
@ -22,7 +22,7 @@ title: Installation
=== "OSX" === "OSX"
<h3>Prerequisites</h3> <h3>Prerequisites</h3>
1. Download and install the latest [.NET Core SDK](https://dotnet.microsoft.com/download/dotnet-core/3.1) 1. Download and install the latest [.NET 5 SDK](https://dotnet.microsoft.com/download/dotnet/5.0)
1. Using _terminal_, install [homebrew](https://brew.sh) and git: 1. Using _terminal_, install [homebrew](https://brew.sh) and git:
```bash ```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

View file

@ -7,19 +7,19 @@ title: Quick Start
If you are familiar with RunUO, then follow these steps to get your ModernUO server running in less than 10 minutes: If you are familiar with RunUO, then follow these steps to get your ModernUO server running in less than 10 minutes:
=== "Windows" === "Windows"
1. Download and install the [.NET Core Runtime](https://dotnet.microsoft.com/download/dotnet-core/thank-you/runtime-3.1.8-windows-x64-installer) 1. Download and install the [.NET 5 Runtime](https://dotnet.microsoft.com/download/dotnet/5.0)
1. Download and extract [ModernUO](https://github.com/modernuo/ModernUO/releases/latest) to a folder. 1. Download and extract [ModernUO](https://github.com/modernuo/ModernUO/releases/latest) to a folder.
1. Navigate to the _Distribution_ folder. 1. Navigate to the _Distribution_ folder.
1. Run `ModernUO.exe` 1. Run `ModernUO.exe`
=== "OSX" === "OSX"
1. Download and install the [.NET Core Runtime](https://dotnet.microsoft.com/download/dotnet-core/thank-you/runtime-aspnetcore-3.1.8-macos-x64-binaries) 1. Download and install the [.NET 5 Runtime](https://dotnet.microsoft.com/download/dotnet/5.0)
1. Download and extract [ModernUO](https://github.com/modernuo/ModernUO/releases/latest) to a folder. 1. Download and extract [ModernUO](https://github.com/modernuo/ModernUO/releases/latest) to a folder.
1. Using _terminal_, navigate to the _Distribution_ folder. 1. Using _terminal_, navigate to the _Distribution_ folder.
1. Run `./dotnet ModernUO.dll` 1. Run `./dotnet ModernUO.dll`
=== "Linux" === "Linux"
1. Download and install the [.NET Core Runtime](instructions [here](https://docs.microsoft.com/en-us/dotnet/core/install/linux)) 1. Download and install the [.NET 5 Runtime](instructions [here](https://docs.microsoft.com/en-us/dotnet/core/install/linux))
1. Download and extract [ModernUO](https://github.com/modernuo/ModernUO/releases/latest) to a folder. 1. Download and extract [ModernUO](https://github.com/modernuo/ModernUO/releases/latest) to a folder.
1. Using _bash_, navigate to the _Distribution_ folder. 1. Using _bash_, navigate to the _Distribution_ folder.
1. Run `./dotnet ModernUO.dll` 1. Run `./dotnet ModernUO.dll`

View file

@ -5,63 +5,47 @@ dotnet restore --force-evaluate
GOTO :CMDSCRIPT GOTO :CMDSCRIPT
::SHELLSCRIPT ::SHELLSCRIPT
os=$1 config=$1
os=$2
if [[ $os ]]; then if [[ $os ]]; then
r="-r $os-x64" os="-r $os-x64"
elif [[ $(uname) = "Darwin" ]]; then elif [[ $(uname) = "Darwin" ]]; then
r="-r osx-x64" os="-r osx-x64"
elif [[ -f /etc/os-release ]]; then elif [[ -f /etc/os-release ]]; then
. /etc/os-release . /etc/os-release
NAME="$(tr '[:upper:]' '[:lower:]' <<< $NAME)" NAME="$(tr '[:upper:]' '[:lower:]' <<< $NAME)"
r="-r $NAME.$VERSION_ID-x64" os="-r $NAME.$VERSION_ID-x64"
fi fi
framework="$(tr '[:upper:]' '[:lower:]' <<< $2)" if [[ $config ]]; then
if [[ $framework = "net" ]]; then
f="-f net5.0"
else
f="-f netcoreapp3.1"
fi
if [[ -z $3 ]]; then
c="-c Release"
else
config="$(tr '[:lower:]' '[:upper:]' <<< ${3:0:1})${3:1}" config="$(tr '[:lower:]' '[:upper:]' <<< ${3:0:1})${3:1}"
c="-c $config" config="-c $config"
else
config="-c Release"
fi fi
echo dotnet publish ${c} ${r} ${f} --no-restore --self-contained=false -o Distribution Projects/Server/Server.csproj echo dotnet publish ${config} ${os} -f net5.0 --no-restore --self-contained=false -o Distribution Projects/Server/Server.csproj
dotnet publish ${c} ${r} ${f} --no-restore --self-contained=false -o Distribution Projects/Server/Server.csproj dotnet publish ${config} ${os} -f net5.0 --no-restore --self-contained=false -o Distribution Projects/Server/Server.csproj
echo dotnet publish ${c} ${r} ${f} --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj echo dotnet publish ${config} ${os} -f net5.0 --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj
dotnet publish ${c} ${r} ${f} --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj dotnet publish ${config} ${os} -f net5.0 --no-restore --self-contained=false -o Distribution/Assemblies Projects/UOContent/UOContent.csproj
exit $? exit $?
:CMDSCRIPT :CMDSCRIPT
IF "%~1" == "" or "%~1" == "release" (
SET config=-c Release
) ELSE (
SET config=-c Debug
)
IF "%~2" == "" ( IF "%~2" == "" (
SET f=-f netcoreapp3.1 SET os=-r win-x64
) ELSE ( ) ELSE (
IF "%~2" == "core" ( SET os=-r %~1-x64
SET f=-f netcoreapp3.1
) ELSE (
SET f=-f net5.0
)
) )
IF "%~3" == "" or "%~3" == "release" ( echo dotnet publish %config% %os% -f net5.0 --no-restore --self-contained=false -o Distribution Projects\Server\Server.csproj
SET c=-c Release dotnet publish %config% %os% -f net5.0 --no-restore --self-contained=false -o Distribution Projects\Server\Server.csproj
) ELSE ( echo dotnet publish %config% %os% -f net5.0 --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj
SET c=-c Debug dotnet publish %config% %os% -f net5.0 --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj
)
IF "%~1" == "" (
SET r=-r win-x64
) ELSE (
SET r=-r %~1-x64
)
echo dotnet publish %c% %r% %f% --no-restore --self-contained=false -o Distribution Projects\Server\Server.csproj
dotnet publish %c% %r% %f% --no-restore --self-contained=false -o Distribution Projects\Server\Server.csproj
echo dotnet publish %c% %r% %f% --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj
dotnet publish %c% %r% %f% --no-restore --self-contained=false -o Distribution\Assemblies Projects\UOContent\UOContent.csproj