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

@ -451,7 +451,7 @@ namespace Server.Commands
"ICloneable", "ICloneable",
"Type" "Type"
}; };
public static bool DontLink( string name ) public static bool DontLink( string name )
{ {
foreach( string dontLink in m_DontLink ) foreach( string dontLink in m_DontLink )
@ -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

@ -192,7 +192,7 @@ namespace Server.Commands
/*if (( flags & ExpandFlag.TempFlag ) != 0) /*if (( flags & ExpandFlag.TempFlag ) != 0)
++countTable[5]; ++countTable[5];
if (( flags & ExpandFlag.SaveFlag ) != 0) if (( flags & ExpandFlag.SaveFlag ) != 0)
++countTable[6];*/ ++countTable[6];*/
@ -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,10 +1,11 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using Server.Accounting; using Server.Accounting;
namespace Server.Misc namespace Server.Misc
{ {
/** /**
* This file requires to be saved in a Unicode * This file requires to be saved in a Unicode
* compatible format. * compatible format.
* *
@ -19,368 +20,348 @@ 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 =
{ {
new InternationalCode("ARA", "Arabic", "Saudi Arabia", "العربية", "السعودية"), private static readonly InternationalCode[] InternationalCodes =
new InternationalCode("ARI", "Arabic", "Iraq", "العربية", "العراق"), {
new InternationalCode("ARE", "Arabic", "Egypt", "العربية", "مصر"), new InternationalCode("ARA", "Arabic", "Saudi Arabia", "العربية", "السعودية"),
new InternationalCode("ARL", "Arabic", "Libya", "العربية", "ليبيا"), new InternationalCode("ARI", "Arabic", "Iraq", "العربية", "العراق"),
new InternationalCode("ARG", "Arabic", "Algeria", "العربية", "الجزائر"), new InternationalCode("ARE", "Arabic", "Egypt", "العربية", "مصر"),
new InternationalCode("ARM", "Arabic", "Morocco", "العربية", "المغرب"), new InternationalCode("ARL", "Arabic", "Libya", "العربية", "ليبيا"),
new InternationalCode("ART", "Arabic", "Tunisia", "العربية", "تونس"), new InternationalCode("ARG", "Arabic", "Algeria", "العربية", "الجزائر"),
new InternationalCode("ARO", "Arabic", "Oman", "العربية", "عمان"), new InternationalCode("ARM", "Arabic", "Morocco", "العربية", "المغرب"),
new InternationalCode("ARY", "Arabic", "Yemen", "العربية", "اليمن"), new InternationalCode("ART", "Arabic", "Tunisia", "العربية", "تونس"),
new InternationalCode("ARS", "Arabic", "Syria", "العربية", "سورية"), new InternationalCode("ARO", "Arabic", "Oman", "العربية", "عمان"),
new InternationalCode("ARJ", "Arabic", "Jordan", "العربية", "الأردن"), new InternationalCode("ARY", "Arabic", "Yemen", "العربية", "اليمن"),
new InternationalCode("ARB", "Arabic", "Lebanon", "العربية", "لبنان"), new InternationalCode("ARS", "Arabic", "Syria", "العربية", "سورية"),
new InternationalCode("ARK", "Arabic", "Kuwait", "العربية", "الكويت"), new InternationalCode("ARJ", "Arabic", "Jordan", "العربية", "الأردن"),
new InternationalCode("ARU", "Arabic", "U.A.E.", "العربية", "الامارات"), new InternationalCode("ARB", "Arabic", "Lebanon", "العربية", "لبنان"),
new InternationalCode("ARH", "Arabic", "Bahrain", "العربية", "البحرين"), new InternationalCode("ARK", "Arabic", "Kuwait", "العربية", "الكويت"),
new InternationalCode("ARQ", "Arabic", "Qatar", "العربية", "قطر"), new InternationalCode("ARU", "Arabic", "U.A.E.", "العربية", "الامارات"),
new InternationalCode("BGR", "Bulgarian", "Bulgaria", "Български", "България"), new InternationalCode("ARH", "Arabic", "Bahrain", "العربية", "البحرين"),
new InternationalCode("CAT", "Catalan", "Spain", "Català", "Espanya"), new InternationalCode("ARQ", "Arabic", "Qatar", "العربية", "قطر"),
new InternationalCode("CHT", "Chinese", "Taiwan", "台語", "臺灣"), new InternationalCode("BGR", "Bulgarian", "Bulgaria", "Български", "България"),
new InternationalCode("CHS", "Chinese", "PRC", "中文", "中国"), new InternationalCode("CAT", "Catalan", "Spain", "Català", "Espanya"),
new InternationalCode("ZHH", "Chinese", "Hong Kong", "中文", "香港"), new InternationalCode("CHT", "Chinese", "Taiwan", "台語", "臺灣"),
new InternationalCode("ZHI", "Chinese", "Singapore", "中文", "新加坡"), new InternationalCode("CHS", "Chinese", "PRC", "中文", "中国"),
new InternationalCode("ZHM", "Chinese", "Macau", "中文", "澳門"), new InternationalCode("ZHH", "Chinese", "Hong Kong", "中文", "香港"),
new InternationalCode("CSY", "Czech", "Czech Republic", "Čeština", "Česká republika"), new InternationalCode("ZHI", "Chinese", "Singapore", "中文", "新加坡"),
new InternationalCode("DAN", "Danish", "Denmark", "Dansk", "Danmark"), new InternationalCode("ZHM", "Chinese", "Macau", "中文", "澳門"),
new InternationalCode("DEU", "German", "Germany", "Deutsch", "Deutschland"), new InternationalCode("CSY", "Czech", "Czech Republic", "Čeština", "Česká republika"),
new InternationalCode("DES", "German", "Switzerland", "Deutsch", "der Schweiz"), new InternationalCode("DAN", "Danish", "Denmark", "Dansk", "Danmark"),
new InternationalCode("DEA", "German", "Austria", "Deutsch", "Österreich"), new InternationalCode("DEU", "German", "Germany", "Deutsch", "Deutschland"),
new InternationalCode("DEL", "German", "Luxembourg", "Deutsch", "Luxembourg"), new InternationalCode("DES", "German", "Switzerland", "Deutsch", "der Schweiz"),
new InternationalCode("DEC", "German", "Liechtenstein", "Deutsch", "Liechtenstein"), new InternationalCode("DEA", "German", "Austria", "Deutsch", "Österreich"),
new InternationalCode("ELL", "Greek", "Greece", "Ελληνικά", "Ελλάδα"), new InternationalCode("DEL", "German", "Luxembourg", "Deutsch", "Luxembourg"),
new InternationalCode("ENU", "English", "United States"), new InternationalCode("DEC", "German", "Liechtenstein", "Deutsch", "Liechtenstein"),
new InternationalCode("ENG", "English", "United Kingdom"), new InternationalCode("ELL", "Greek", "Greece", "Ελληνικά", "Ελλάδα"),
new InternationalCode("ENA", "English", "Australia"), new InternationalCode("ENU", "English", "United States"),
new InternationalCode("ENC", "English", "Canada"), new InternationalCode("ENG", "English", "United Kingdom"),
new InternationalCode("ENZ", "English", "New Zealand"), new InternationalCode("ENA", "English", "Australia"),
new InternationalCode("ENI", "English", "Ireland"), new InternationalCode("ENC", "English", "Canada"),
new InternationalCode("ENS", "English", "South Africa"), new InternationalCode("ENZ", "English", "New Zealand"),
new InternationalCode("ENJ", "English", "Jamaica"), new InternationalCode("ENI", "English", "Ireland"),
new InternationalCode("ENB", "English", "Caribbean"), new InternationalCode("ENS", "English", "South Africa"),
new InternationalCode("ENL", "English", "Belize"), new InternationalCode("ENJ", "English", "Jamaica"),
new InternationalCode("ENT", "English", "Trinidad"), new InternationalCode("ENB", "English", "Caribbean"),
new InternationalCode("ENW", "English", "Zimbabwe"), new InternationalCode("ENL", "English", "Belize"),
new InternationalCode("ENP", "English", "Philippines"), new InternationalCode("ENT", "English", "Trinidad"),
new InternationalCode("ESP", "Spanish", "Spain (Traditional Sort)", "Español", "España (tipo tradicional)"), new InternationalCode("ENW", "English", "Zimbabwe"),
new InternationalCode("ESM", "Spanish", "Mexico", "Español", "México"), new InternationalCode("ENP", "English", "Philippines"),
new InternationalCode("ESN", "Spanish", "Spain (International Sort)", "Español", "España (tipo internacional)"), new InternationalCode("ESP", "Spanish", "Spain (Traditional Sort)", "Español", "España (tipo tradicional)"),
new InternationalCode("ESG", "Spanish", "Guatemala", "Español", "Guatemala"), new InternationalCode("ESM", "Spanish", "Mexico", "Español", "México"),
new InternationalCode("ESC", "Spanish", "Costa Rica", "Español", "Costa Rica"), new InternationalCode("ESN", "Spanish", "Spain (International Sort)", "Español", "España (tipo internacional)"),
new InternationalCode("ESA", "Spanish", "Panama", "Español", "Panama"), new InternationalCode("ESG", "Spanish", "Guatemala", "Español", "Guatemala"),
new InternationalCode("ESD", "Spanish", "Dominican Republic", "Español", "Republica Dominicana"), new InternationalCode("ESC", "Spanish", "Costa Rica", "Español", "Costa Rica"),
new InternationalCode("ESV", "Spanish", "Venezuela", "Español", "Venezuela"), new InternationalCode("ESA", "Spanish", "Panama", "Español", "Panama"),
new InternationalCode("ESO", "Spanish", "Colombia", "Español", "Colombia"), new InternationalCode("ESD", "Spanish", "Dominican Republic", "Español", "Republica Dominicana"),
new InternationalCode("ESR", "Spanish", "Peru", "Español", "Peru"), new InternationalCode("ESV", "Spanish", "Venezuela", "Español", "Venezuela"),
new InternationalCode("ESS", "Spanish", "Argentina", "Español", "Argentina"), new InternationalCode("ESO", "Spanish", "Colombia", "Español", "Colombia"),
new InternationalCode("ESF", "Spanish", "Ecuador", "Español", "Ecuador"), new InternationalCode("ESR", "Spanish", "Peru", "Español", "Peru"),
new InternationalCode("ESL", "Spanish", "Chile", "Español", "Chile"), new InternationalCode("ESS", "Spanish", "Argentina", "Español", "Argentina"),
new InternationalCode("ESY", "Spanish", "Uruguay", "Español", "Uruguay"), new InternationalCode("ESF", "Spanish", "Ecuador", "Español", "Ecuador"),
new InternationalCode("ESZ", "Spanish", "Paraguay", "Español", "Paraguay"), new InternationalCode("ESL", "Spanish", "Chile", "Español", "Chile"),
new InternationalCode("ESB", "Spanish", "Bolivia", "Español", "Bolivia"), new InternationalCode("ESY", "Spanish", "Uruguay", "Español", "Uruguay"),
new InternationalCode("ESE", "Spanish", "El Salvador", "Español", "El Salvador"), new InternationalCode("ESZ", "Spanish", "Paraguay", "Español", "Paraguay"),
new InternationalCode("ESH", "Spanish", "Honduras", "Español", "Honduras"), new InternationalCode("ESB", "Spanish", "Bolivia", "Español", "Bolivia"),
new InternationalCode("ESI", "Spanish", "Nicaragua", "Español", "Nicaragua"), new InternationalCode("ESE", "Spanish", "El Salvador", "Español", "El Salvador"),
new InternationalCode("ESU", "Spanish", "Puerto Rico", "Español", "Puerto Rico"), new InternationalCode("ESH", "Spanish", "Honduras", "Español", "Honduras"),
new InternationalCode("FIN", "Finnish", "Finland", "Suomi", "Suomi"), new InternationalCode("ESI", "Spanish", "Nicaragua", "Español", "Nicaragua"),
new InternationalCode("FRA", "French", "France", "Français", "France"), new InternationalCode("ESU", "Spanish", "Puerto Rico", "Español", "Puerto Rico"),
new InternationalCode("FRB", "French", "Belgium", "Français", "Belgique"), new InternationalCode("FIN", "Finnish", "Finland", "Suomi", "Suomi"),
new InternationalCode("FRC", "French", "Canada", "Français", "Canada"), new InternationalCode("FRA", "French", "France", "Français", "France"),
new InternationalCode("FRS", "French", "Switzerland", "Français", "Suisse"), new InternationalCode("FRB", "French", "Belgium", "Français", "Belgique"),
new InternationalCode("FRL", "French", "Luxembourg", "Français", "Luxembourg"), new InternationalCode("FRC", "French", "Canada", "Français", "Canada"),
new InternationalCode("FRM", "French", "Monaco", "Français", "Monaco"), new InternationalCode("FRS", "French", "Switzerland", "Français", "Suisse"),
new InternationalCode("HEB", "Hebrew", "Israel", "עִבְרִית", "ישׂראל"), new InternationalCode("FRL", "French", "Luxembourg", "Français", "Luxembourg"),
new InternationalCode("HUN", "Hungarian", "Hungary", "Magyar", "Magyarország"), new InternationalCode("FRM", "French", "Monaco", "Français", "Monaco"),
new InternationalCode("ISL", "Icelandic", "Iceland", "Íslenska", "Ísland"), new InternationalCode("HEB", "Hebrew", "Israel", "עִבְרִית", "ישׂראל"),
new InternationalCode("ITA", "Italian", "Italy", "Italiano", "Italia"), new InternationalCode("HUN", "Hungarian", "Hungary", "Magyar", "Magyarország"),
new InternationalCode("ITS", "Italian", "Switzerland", "Italiano", "Svizzera"), new InternationalCode("ISL", "Icelandic", "Iceland", "Íslenska", "Ísland"),
new InternationalCode("JPN", "Japanese", "Japan", "日本語", "日本"), new InternationalCode("ITA", "Italian", "Italy", "Italiano", "Italia"),
new InternationalCode("KOR", "Korean (Extended Wansung)", "Korea", "한국어", "한국"), new InternationalCode("ITS", "Italian", "Switzerland", "Italiano", "Svizzera"),
new InternationalCode("NLD", "Dutch", "Netherlands", "Nederlands", "Nederland"), new InternationalCode("JPN", "Japanese", "Japan", "日本語", "日本"),
new InternationalCode("NLB", "Dutch", "Belgium", "Nederlands", "België"), new InternationalCode("KOR", "Korean (Extended Wansung)", "Korea", "한국어", "한국"),
new InternationalCode("NOR", "Norwegian", "Norway (Bokmål)", "Norsk", "Norge (Bokmål)"), new InternationalCode("NLD", "Dutch", "Netherlands", "Nederlands", "Nederland"),
new InternationalCode("NON", "Norwegian", "Norway (Nynorsk)", "Norsk", "Norge (Nynorsk)"), new InternationalCode("NLB", "Dutch", "Belgium", "Nederlands", "België"),
new InternationalCode("PLK", "Polish", "Poland", "Polski", "Polska"), new InternationalCode("NOR", "Norwegian", "Norway (Bokmål)", "Norsk", "Norge (Bokmål)"),
new InternationalCode("PTB", "Portuguese", "Brazil", "Português", "Brasil"), new InternationalCode("NON", "Norwegian", "Norway (Nynorsk)", "Norsk", "Norge (Nynorsk)"),
new InternationalCode("PTG", "Portuguese", "Portugal", "Português", "Brasil"), new InternationalCode("PLK", "Polish", "Poland", "Polski", "Polska"),
new InternationalCode("ROM", "Romanian", "Romania", "Limba Română", "România"), new InternationalCode("PTB", "Portuguese", "Brazil", "Português", "Brasil"),
new InternationalCode("RUS", "Russian", "Russia", "Русский", "Россия"), new InternationalCode("PTG", "Portuguese", "Portugal", "Português", "Brasil"),
new InternationalCode("HRV", "Croatian", "Croatia", "Hrvatski", "Hrvatska"), new InternationalCode("ROM", "Romanian", "Romania", "Limba Română", "România"),
new InternationalCode("SRL", "Serbian", "Serbia (Latin)", "Srpski", "Srbija i Crna Gora"), new InternationalCode("RUS", "Russian", "Russia", "Русский", "Россия"),
new InternationalCode("SRB", "Serbian", "Serbia (Cyrillic)", "Српски", "Србија и Црна Гора"), new InternationalCode("HRV", "Croatian", "Croatia", "Hrvatski", "Hrvatska"),
new InternationalCode("SKY", "Slovak", "Slovakia", "Slovenčina", "Slovensko"), new InternationalCode("SRL", "Serbian", "Serbia (Latin)", "Srpski", "Srbija i Crna Gora"),
new InternationalCode("SQI", "Albanian", "Albania", "Shqip", "Shqipëria"), new InternationalCode("SRB", "Serbian", "Serbia (Cyrillic)", "Српски", "Србија и Црна Гора"),
new InternationalCode("SVE", "Swedish", "Sweden", "Svenska", "Sverige"), new InternationalCode("SKY", "Slovak", "Slovakia", "Slovenčina", "Slovensko"),
new InternationalCode("SVF", "Swedish", "Finland", "Svenska", "Finland"), new InternationalCode("SQI", "Albanian", "Albania", "Shqip", "Shqipëria"),
new InternationalCode("THA", "Thai", "Thailand", "ภาษาไทย", "ประเทศไทย"), new InternationalCode("SVE", "Swedish", "Sweden", "Svenska", "Sverige"),
new InternationalCode("TRK", "Turkish", "Turkey", "Türkçe", "Türkiye"), new InternationalCode("SVF", "Swedish", "Finland", "Svenska", "Finland"),
new InternationalCode("URP", "Urdu", "Pakistan", "اردو", "پاکستان"), new InternationalCode("THA", "Thai", "Thailand", "ภาษาไทย", "ประเทศไทย"),
new InternationalCode("IND", "Indonesian", "Indonesia", "Bahasa Indonesia", "Indonesia"), new InternationalCode("TRK", "Turkish", "Turkey", "Türkçe", "Türkiye"),
new InternationalCode("UKR", "Ukrainian", "Ukraine", "Українська", "Украина"), new InternationalCode("URP", "Urdu", "Pakistan", "اردو", "پاکستان"),
new InternationalCode("BEL", "Belarusian", "Belarus", "Беларускі", "Беларусь"), new InternationalCode("IND", "Indonesian", "Indonesia", "Bahasa Indonesia", "Indonesia"),
new InternationalCode("SLV", "Slovene", "Slovenia", "Slovenščina", "Slovenija"), new InternationalCode("UKR", "Ukrainian", "Ukraine", "Українська", "Украина"),
new InternationalCode("ETI", "Estonian", "Estonia", "Eesti", "Eesti"), new InternationalCode("BEL", "Belarusian", "Belarus", "Беларускі", "Беларусь"),
new InternationalCode("LVI", "Latvian", "Latvia", "Latviešu", "Latvija"), new InternationalCode("SLV", "Slovene", "Slovenia", "Slovenščina", "Slovenija"),
new InternationalCode("LTH", "Lithuanian", "Lithuania", "Lietuvių", "Lietuva"), new InternationalCode("ETI", "Estonian", "Estonia", "Eesti", "Eesti"),
new InternationalCode("LTC", "Classic Lithuanian", "Lithuania", "Lietuviškai", "Lietuva"), new InternationalCode("LVI", "Latvian", "Latvia", "Latviešu", "Latvija"),
new InternationalCode("FAR", "Farsi", "Iran", "فارسى", "ايران"), new InternationalCode("LTH", "Lithuanian", "Lithuania", "Lietuvių", "Lietuva"),
new InternationalCode("VIT", "Vietnamese", "Viet Nam", "tiếng Việt", "Việt Nam"), new InternationalCode("LTC", "Classic Lithuanian", "Lithuania", "Lietuviškai", "Lietuva"),
new InternationalCode("HYE", "Armenian", "Armenia", "Հայերէն", "Հայաստան"), new InternationalCode("FAR", "Farsi", "Iran", "فارسى", "ايران"),
new InternationalCode("AZE", "Azeri", "Azerbaijan (Latin)", "Azərbaycanca", "Azərbaycan"), new InternationalCode("VIT", "Vietnamese", "Viet Nam", "tiếng Việt", "Việt Nam"),
new InternationalCode("AZE", "Azeri", "Azerbaijan (Cyrillic)", "Азәрбајҹанҹа", "Азәрбајҹан"), new InternationalCode("HYE", "Armenian", "Armenia", "Հայերէն", "Հայաստան"),
new InternationalCode("EUQ", "Basque", "Spain", "Euskera", "Espainia"), new InternationalCode("AZE", "Azeri", "Azerbaijan (Latin)", "Azərbaycanca", "Azərbaycan"),
new InternationalCode("MKI", "Macedonian", "Macedonia", "Македонски", "Македонија"), new InternationalCode("AZE", "Azeri", "Azerbaijan (Cyrillic)", "Азәрбајҹанҹа", "Азәрбајҹан"),
new InternationalCode("AFK", "Afrikaans", "South Africa", "Afrikaans", "Republiek van Suid-Afrika"), new InternationalCode("EUQ", "Basque", "Spain", "Euskera", "Espainia"),
new InternationalCode("KAT", "Georgian", "Georgia", "ქართული", "საკარტველო"), new InternationalCode("MKI", "Macedonian", "Macedonia", "Македонски", "Македонија"),
new InternationalCode("FOS", "Faeroese", "Faeroe Islands", "Føroyska", "Føroya"), new InternationalCode("AFK", "Afrikaans", "South Africa", "Afrikaans", "Republiek van Suid-Afrika"),
new InternationalCode("HIN", "Hindi", "India", "हिन्दी", "भारत"), new InternationalCode("KAT", "Georgian", "Georgia", "ქართული", "საკარტველო"),
new InternationalCode("MSL", "Malay", "Malaysia", "Bahasa melayu", "Malaysia"), new InternationalCode("FOS", "Faeroese", "Faeroe Islands", "Føroyska", "Føroya"),
new InternationalCode("MSB", "Malay", "Brunei Darussalam", "Bahasa melayu", "Negara Brunei Darussalam"), new InternationalCode("HIN", "Hindi", "India", "हिन्दी", "भारत"),
new InternationalCode("KAZ", "Kazak", "Kazakstan", "Қазақ", "Қазақстан"), new InternationalCode("MSL", "Malay", "Malaysia", "Bahasa melayu", "Malaysia"),
new InternationalCode("SWK", "Swahili", "Kenya", "Kiswahili", "Kenya"), new InternationalCode("MSB", "Malay", "Brunei Darussalam", "Bahasa melayu", "Negara Brunei Darussalam"),
new InternationalCode("UZB", "Uzbek", "Uzbekistan (Latin)", "O'zbek", "O'zbekiston"), new InternationalCode("KAZ", "Kazak", "Kazakstan", "Қазақ", "Қазақстан"),
new InternationalCode("UZB", "Uzbek", "Uzbekistan (Cyrillic)", "Ўзбек", "Ўзбекистон"), new InternationalCode("SWK", "Swahili", "Kenya", "Kiswahili", "Kenya"),
new InternationalCode("TAT", "Tatar", "Tatarstan", "Татарча", "Татарстан"), new InternationalCode("UZB", "Uzbek", "Uzbekistan (Latin)", "O'zbek", "O'zbekiston"),
new InternationalCode("BEN", "Bengali", "India", "বাংলা", "ভারত"), new InternationalCode("UZB", "Uzbek", "Uzbekistan (Cyrillic)", "Ўзбек", "Ўзбекистон"),
new InternationalCode("PAN", "Punjabi", "India", "ਪੰਜਾਬੀ", "ਭਾਰਤ"), new InternationalCode("TAT", "Tatar", "Tatarstan", "Татарча", "Татарстан"),
new InternationalCode("GUJ", "Gujarati", "India", "ગુજરાતી", "ભારત"), new InternationalCode("BEN", "Bengali", "India", "বাংলা", "ভারত"),
new InternationalCode("ORI", "Oriya", "India", "ଓଡ଼ିଆ", "ଭାରତ"), new InternationalCode("PAN", "Punjabi", "India", "ਪੰਜਾਬੀ", "ਭਾਰਤ"),
new InternationalCode("TAM", "Tamil", "India", "தமிழ்", "இந்தியா"), new InternationalCode("GUJ", "Gujarati", "India", "ગુજરાતી", "ભારત"),
new InternationalCode("TEL", "Telugu", "India", "తెలుగు", "భారత"), new InternationalCode("ORI", "Oriya", "India", "ଓଡ଼ିଆ", "ଭାରତ"),
new InternationalCode("KAN", "Kannada", "India", "ಕನ್ನಡ", "ಭಾರತ"), new InternationalCode("TAM", "Tamil", "India", "தமிழ்", "இந்தியா"),
new InternationalCode("MAL", "Malayalam", "India", "മലയാളം", "ഭാരത"), new InternationalCode("TEL", "Telugu", "India", "తెలుగు", "భారత"),
new InternationalCode("ASM", "Assamese", "India", "অসমিয়া", "Bhārat"), // missing correct country name new InternationalCode("KAN", "Kannada", "India", "ಕನ್ನಡ", "ಭಾರತ"),
new InternationalCode("MAR", "Marathi", "India", "मराठी", "भारत"), new InternationalCode("MAL", "Malayalam", "India", "മലയാളം", "ഭാരത"),
new InternationalCode("SAN", "Sanskrit", "India", "संस्कृत", "भारतम्"), new InternationalCode("ASM", "Assamese", "India", "অসমিয়া", "Bhārat"), // missing correct country name
new InternationalCode("KOK", "Konkani", "India", "कोंकणी", "भारत") new InternationalCode("MAR", "Marathi", "India", "मराठी", "भारत"),
}; new InternationalCode("SAN", "Sanskrit", "India", "संस्कृत", "भारतम्"),
new InternationalCode("KOK", "Konkani", "India", "कोंकणी", "भारत")
};
private static readonly bool DefaultLocalNames = false; private static readonly bool DefaultLocalNames = false;
private static readonly bool ShowAlternatives = true; private static readonly bool ShowAlternatives = true;
private static readonly bool CountAccounts = true; // will consider only first character's valid language private static readonly bool CountAccounts = true; // will consider only first character's valid language
private static string GetFormattedInfo(string code) private static string GetFormattedInfo(string code)
{ {
if (code == null || code.Length != 3) if (code == null || code.Length != 3)
{ {
return $"Unknown code {code}"; return $"Unknown code {code}";
} }
for (var i = 0; i < InternationalCodes.Length; i++) for (var i = 0; i < InternationalCodes.Length; i++)
{ {
if (code == InternationalCodes[i].Code) if (code == InternationalCodes[i].Code)
{ {
return $"{InternationalCodes[i].GetName()}"; return $"{InternationalCodes[i].GetName()}";
} }
} }
return $"Unknown code {code}"; return $"Unknown code {code}";
}
public static void Initialize()
{
CommandSystem.Register("LanguageStatistics", AccessLevel.Administrator, LanguageStatistics_OnCommand);
}
[Usage("LanguageStatistics")]
[Description("Generate a file containing the list of languages for each PlayerMobile.")]
public static void LanguageStatistics_OnCommand(CommandEventArgs e)
{
var ht = new Dictionary<string, InternationalCodeCounter>();
using var writer = new StreamWriter("languages.txt");
if (CountAccounts)
{
foreach (Account acc in Accounts.GetAccounts())
{
for (var i = 0; i < acc.Length; i++)
{
var mob = acc[i];
var lang = mob?.Language;
if (lang == null)
{
continue;
}
lang = lang.ToUpper();
if (ht.TryGetValue(lang, out var codes))
{
codes.Increase();
}
else
{
ht[lang] = new InternationalCodeCounter(lang);
}
break;
}
}
}
else
{
foreach (var mob in World.Mobiles.Values)
{
if (mob.Player)
{
var lang = mob.Language;
if (lang == null)
{
continue;
}
lang = lang.ToUpper();
if (ht.TryGetValue(lang, out var codes))
{
codes.Increase();
}
else
{
ht[lang] = new InternationalCodeCounter(lang);
}
}
}
}
writer.WriteLine(
$"Language statistics. Numbers show how many {(CountAccounts ? "accounts" : "playermobile")} use the specified language.");
writer.WriteLine(
"====================================================================================================");
writer.WriteLine();
// sort the list
var list = new List<InternationalCodeCounter>(ht.Values);
list.Sort(InternationalCodeComparer.Instance);
foreach (var c in list)
{
writer.WriteLine($"{GetFormattedInfo(c.Code)} : {c.Count}");
}
e.Mobile.SendMessage("Languages list generated.");
}
private struct InternationalCode
{
private readonly bool m_HasLocalInfo;
public string Code { get; }
public string Language { get; }
public string Country { get; }
public string Language_LocalName { get; }
public string Country_LocalName { get; }
public InternationalCode(string code, string language, string country) : this(code, language, country, null,
null) =>
m_HasLocalInfo = false;
public InternationalCode(string code, string language, string country, string language_localname,
string country_localname)
{
Code = code;
Language = language;
Country = country;
Language_LocalName = language_localname;
Country_LocalName = country_localname;
m_HasLocalInfo = true;
}
public string GetName()
{
string s;
if (m_HasLocalInfo)
{
s =
$"{(DefaultLocalNames ? Language_LocalName : Language)} - {(DefaultLocalNames ? Country_LocalName : Country)}";
if (ShowAlternatives)
{
s +=
$" 【{(DefaultLocalNames ? Language : Language_LocalName)} - {(DefaultLocalNames ? Country : Country_LocalName)}‎】";
}
}
else
{
s = $"{Language} - {Country}";
}
return s;
}
}
private class InternationalCodeCounter
{
public InternationalCodeCounter(string code)
{
Code = code;
Count = 1;
}
public string Code { get; }
public int Count { get; private set; }
public void Increase()
{
Count++;
}
}
private class InternationalCodeComparer : IComparer<InternationalCodeCounter>
{
public static readonly InternationalCodeComparer Instance = new InternationalCodeComparer();
public int Compare(InternationalCodeCounter x, InternationalCodeCounter y)
{
var ca = x?.Count ?? 0;
var cb = y?.Count ?? 0;
if (ca > cb)
{
return -1;
}
if (ca < cb)
{
return 1;
}
return string.CompareOrdinal(x?.Code, y?.Code);
}
}
} }
public static void Initialize()
{
CommandSystem.Register("LanguageStatistics", AccessLevel.Administrator, LanguageStatistics_OnCommand);
}
[Usage("LanguageStatistics")]
[Description("Generate a file containing the list of languages for each PlayerMobile.")]
public static void LanguageStatistics_OnCommand(CommandEventArgs e)
{
var ht = new Dictionary<string, InternationalCodeCounter>();
using var writer = new StreamWriter("languages.txt");
if (CountAccounts)
{
foreach (Account acc in Accounts.GetAccounts())
{
for (var i = 0; i < acc.Length; i++)
{
var mob = acc[i];
var lang = mob?.Language;
if (lang == null)
{
continue;
}
lang = lang.ToUpper();
if (ht.TryGetValue(lang, out var codes))
{
codes.Increase();
}
else
{
ht[lang] = new InternationalCodeCounter(lang);
}
break;
}
}
}
else
{
foreach (var mob in World.Mobiles.Values)
{
if (mob.Player)
{
var lang = mob.Language;
if (lang == null)
{
continue;
}
lang = lang.ToUpper();
if (ht.TryGetValue(lang, out var codes))
{
codes.Increase();
}
else
{
ht[lang] = new InternationalCodeCounter(lang);
}
}
}
}
writer.WriteLine(
$"Language statistics. Numbers show how many {(CountAccounts ? "accounts" : "playermobile")} use the specified language.");
writer.WriteLine(
"====================================================================================================");
writer.WriteLine();
// sort the list
var list = new List<InternationalCodeCounter>(ht.Values);
list.Sort(InternationalCodeComparer.Instance);
foreach (var c in list)
{
writer.WriteLine($"{GetFormattedInfo(c.Code)} : {c.Count}");
}
e.Mobile.SendMessage("Languages list generated.");
}
private struct InternationalCode
{
private readonly bool m_HasLocalInfo;
public string Code { get; }
public string Language { get; }
public string Country { get; }
public string Language_LocalName { get; }
public string Country_LocalName { get; }
public InternationalCode(string code, string language, string country) : this(code, language, country, null,
null) =>
m_HasLocalInfo = false;
public InternationalCode(string code, string language, string country, string language_localname,
string country_localname)
{
Code = code;
Language = language;
Country = country;
Language_LocalName = language_localname;
Country_LocalName = country_localname;
m_HasLocalInfo = true;
}
public string GetName()
{
string s;
if (m_HasLocalInfo)
{
s =
$"{(DefaultLocalNames ? Language_LocalName : Language)} - {(DefaultLocalNames ? Country_LocalName : Country)}";
if (ShowAlternatives)
{
s +=
$" 【{(DefaultLocalNames ? Language : Language_LocalName)} - {(DefaultLocalNames ? Country : Country_LocalName)}‎】";
}
}
else
{
s = $"{Language} - {Country}";
}
return s;
}
}
private class InternationalCodeCounter
{
public InternationalCodeCounter(string code)
{
Code = code;
Count = 1;
}
public string Code { get; }
public int Count { get; private set; }
public void Increase()
{
Count++;
}
}
private class InternationalCodeComparer : IComparer<InternationalCodeCounter>
{
public static readonly InternationalCodeComparer Instance = new InternationalCodeComparer();
public int Compare(InternationalCodeCounter x, InternationalCodeCounter y)
{
string a = null, b = null;
int ca = 0, cb = 0;
a = x.Code;
ca = x.Count;
b = y.Code;
cb = y.Count;
if (ca > cb)
{
return -1;
}
if (ca < cb)
{
return 1;
}
if (a == null && b == null)
{
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,34 +911,22 @@ 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 GetFromOreInfo(info);
{
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 info.Level switch
{
0 => CraftResource.RegularLeather,
1 => CraftResource.SpinedLeather,
2 => CraftResource.HornedLeather,
3 => CraftResource.BarbedLeather,
_ => CraftResource.None
};
} }
} }

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