diff --git a/Distribution/Data/Decoration/Britannia/_hythloth.cfg b/Distribution/Data/Decoration/Britannia/_hythloth.cfg index f85e11cf2..b462966b2 100644 --- a/Distribution/Data/Decoration/Britannia/_hythloth.cfg +++ b/Distribution/Data/Decoration/Britannia/_hythloth.cfg @@ -701,10 +701,6 @@ MetalDoor2 0x06C7 (Facing=EastCCW) 5988 159 0 6060 167 0 -# Blood Moss -Static 0x0F7B -2678 712 0 - # garbage Static 0x10F0 5988 46 22 diff --git a/Projects/Server.Tests/Helpers/PacketTestUtilities.cs b/Projects/Server.Tests/Helpers/PacketTestUtilities.cs index b90c457e9..afcbc6423 100644 --- a/Projects/Server.Tests/Helpers/PacketTestUtilities.cs +++ b/Projects/Server.Tests/Helpers/PacketTestUtilities.cs @@ -1,7 +1,5 @@ using System; -using System.Collections.Generic; using System.Net.Sockets; -using Moq; using Server.Network; namespace Server.Tests.Network @@ -11,18 +9,8 @@ namespace Server.Tests.Network public static Span Compile(this Packet p) => p.Compile(false, out var length).AsSpan(0, length); - public static NetState CreateTestNetState() - { - var socket = new Mock(); - socket - .Setup(s => s.SendAsync(It.IsAny>>(), SocketFlags.None)) - .ReturnsAsync(() => 0); - - socket - .Setup(s => s.ReceiveAsync(It.IsAny>>(), SocketFlags.None)) - .ReturnsAsync(() => 0); - - return new NetState(socket.Object); - } + public static NetState CreateTestNetState() => new( + new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) + ); } } diff --git a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/LightPacketTests.cs b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/LightPacketTests.cs index 36e79adf9..a6eb94b47 100644 --- a/Projects/Server.Tests/Tests/Network/Packets/Outgoing/LightPacketTests.cs +++ b/Projects/Server.Tests/Tests/Network/Packets/Outgoing/LightPacketTests.cs @@ -9,7 +9,7 @@ namespace Server.Tests.Network [Fact] public void TestGlobalLightLevel() { - byte lightLevel = 5; + const byte lightLevel = 5; var expected = new GlobalLightLevel(lightLevel).Compile(); var ns = PacketTestUtilities.CreateTestNetState(); diff --git a/Projects/Server/Mobiles/Mobile.cs b/Projects/Server/Mobiles/Mobile.cs index 02c2a43f2..5e259a849 100644 --- a/Projects/Server/Mobiles/Mobile.cs +++ b/Projects/Server/Mobiles/Mobile.cs @@ -916,8 +916,15 @@ namespace Server else { m_NetState.SendChangeCombatant(m_Combatant.Serial); - Timer.StartTimer(ExpireCombatantDelay, ExpireCombatant, out _expireCombatantTimerToken); - Timer.StartTimer(TimeSpan.FromSeconds(0.01), 0, CheckCombatTime, out _combatTimerToken); + if (!_expireCombatantTimerToken.Running) + { + Timer.StartTimer(ExpireCombatantDelay, ExpireCombatant, out _expireCombatantTimerToken); + } + + if (!_combatTimerToken.Running) + { + Timer.StartTimer(TimeSpan.FromSeconds(0.01), 0, CheckCombatTime, out _combatTimerToken); + } if (CanBeHarmful(m_Combatant, false)) { diff --git a/Projects/Server/Network/NetState/NetState.cs b/Projects/Server/Network/NetState/NetState.cs index 136b84320..943ff4f10 100755 --- a/Projects/Server/Network/NetState/NetState.cs +++ b/Projects/Server/Network/NetState/NetState.cs @@ -20,6 +20,7 @@ using System.Collections.Generic; using System.IO; using System.Net; using System.Net.Sockets; +using System.Network; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Server.Accounting; @@ -48,7 +49,7 @@ namespace Server.Network private const int MenuCap = 512; private const int PacketPerSecondThreshold = 3000; - private static NetState[] _polledStates = new NetState[2048]; + private static GCHandle[] _polledStates = new GCHandle[2048]; private static readonly IPollGroup _pollGroup = PollGroup.Create(); private static readonly Queue FlushPending = new(2048); private static readonly Queue FlushedPartials = new(2048); @@ -101,7 +102,7 @@ namespace Server.Network Timer.DelayCall(TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1.5), CheckAllAlive); } - public NetState(ISocket connection) + public NetState(Socket connection) { Connection = connection; Seeded = false; @@ -130,7 +131,7 @@ namespace Server.Network try { - _pollGroup.Add(this); + _pollGroup.Add(connection, _handle); } catch (Exception ex) { @@ -171,7 +172,7 @@ namespace Server.Network public Pipe SendPipe { get; } - public ISocket Connection { get; } + public Socket Connection { get; } public bool CompressionEnabled { get; set; } @@ -885,8 +886,8 @@ namespace Server.Network { for (int i = 0; i < count; i++) { - _polledStates[i].HandleReceive(); - _polledStates[i] = null; + (_polledStates[i].Target as NetState)?.HandleReceive(); + _polledStates[i] = default; } } @@ -1032,7 +1033,7 @@ namespace Server.Network TcpServer.Instances.Remove(this); try { - _pollGroup.Remove(this); + _pollGroup.Remove(Connection); } catch (Exception ex) { diff --git a/Projects/Server/Network/NetworkSocket.cs b/Projects/Server/Network/NetworkSocket.cs deleted file mode 100644 index f762ba1cf..000000000 --- a/Projects/Server/Network/NetworkSocket.cs +++ /dev/null @@ -1,77 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2020 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: NetworkSocket.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; -using System.Collections.Generic; -using System.Net; -using System.Net.Sockets; -using System.Runtime.CompilerServices; -using System.Threading.Tasks; - -namespace Server.Network -{ - public class NetworkSocket : ISocket - { - private readonly Socket _connection; - - public Socket Connection - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _connection; - } - - public IntPtr Handle - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _connection.Handle; - } - - public EndPoint LocalEndPoint - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _connection.LocalEndPoint; - } - - public EndPoint RemoteEndPoint - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => _connection.RemoteEndPoint; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public NetworkSocket(Socket connection) => _connection = connection; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Task SendAsync(IList> buffers, SocketFlags flags) => - _connection.SendAsync(buffers, flags); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int Send(IList> buffers, SocketFlags flags) => _connection.Send(buffers, flags); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Task ReceiveAsync(IList> buffers, SocketFlags flags) => - _connection.ReceiveAsync(buffers, flags); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int Receive(IList> buffers, SocketFlags flags) => - _connection.Receive(buffers, flags); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Shutdown(SocketShutdown how) => _connection.Shutdown(how); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Close() => _connection.Close(); - } -} diff --git a/Projects/Server/Network/PollGroup/EPollGroup.cs b/Projects/Server/Network/PollGroup/EPollGroup.cs deleted file mode 100755 index bf615e4cc..000000000 --- a/Projects/Server/Network/PollGroup/EPollGroup.cs +++ /dev/null @@ -1,206 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: EPollGroup.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; -using System.Runtime.InteropServices; - -namespace Server.Network -{ - public sealed class EPollGroup : IPollGroup - { - [Flags] - private enum epoll_flags - { - NONE = 0, - CLOEXEC = 0x02000000, - NONBLOCK = 0x04000, - } - - [Flags] - private enum epoll_events : uint - { - EPOLLIN = 0x001, - EPOLLPRI = 0x002, - EPOLLOUT = 0x004, - EPOLLRDNORM = 0x040, - EPOLLRDBAND = 0x080, - EPOLLWRNORM = 0x100, - EPOLLWRBAND = 0x200, - EPOLLMSG = 0x400, - EPOLLERR = 0x008, - EPOLLHUP = 0x010, - EPOLLRDHUP = 0x2000, - EPOLLONESHOT = 1 << 30, - EPOLLET = unchecked((uint)(1 << 31)) - } - - private enum epoll_op - { - EPOLL_CTL_ADD = 1, - EPOLL_CTL_DEL = 2, - EPOLL_CTL_MOD = 3, - } - - [StructLayout(LayoutKind.Explicit)] - private struct epoll_data - { - [FieldOffset(0)] - public int fd; - - [FieldOffset(0)] - public IntPtr ptr; - - [FieldOffset(0)] - public uint u32; - - [FieldOffset(0)] - public ulong u64; - } - - [StructLayout(LayoutKind.Sequential)] - private struct epoll_event - { - public epoll_events events; - public epoll_data data; - } - - private static class Windows - { - [DllImport("wepoll.dll", SetLastError = true)] - public static extern int epoll_create1(epoll_flags flags); - - [DllImport("wepoll.dll", SetLastError = true)] - public static extern int epoll_close(int epfd); - - [DllImport("wepoll.dll", SetLastError = true)] - public static extern int epoll_ctl(int epfd, epoll_op op, int fd, ref epoll_event ee); - - [DllImport("wepoll.dll", SetLastError = true)] - public static extern int epoll_wait(int epfd, [In, Out] epoll_event[] ee, int maxevents, int timeout); - } - - private static class Linux - { - [DllImport("libc", SetLastError = true)] - public static extern int epoll_create1(epoll_flags flags); - - [DllImport("libc", SetLastError = true)] - public static extern int epoll_close(int epfd); - - [DllImport("libc", SetLastError = true)] - public static extern int epoll_ctl(int epfd, epoll_op op, int fd, ref epoll_event ee); - - [DllImport("libc", SetLastError = true)] - public static extern int epoll_wait(int epfd, [In, Out] epoll_event[] ee, int maxevents, int timeout); - } - - private readonly int _epHndle; - - public EPollGroup() - { - _epHndle = Core.IsWindows ? Windows.epoll_create1(epoll_flags.NONE) : Linux.epoll_create1(epoll_flags.NONE); - - if (_epHndle == 0) - { - throw new Exception("Unable to initialize poll group"); - } - } - - public void Dispose() - { - if (Core.IsWindows) - { - Windows.epoll_close(_epHndle); - } - else - { - Linux.epoll_close(_epHndle); - } - } - - public void Add(NetState state) - { - var ev = new epoll_event - { - events = epoll_events.EPOLLIN | epoll_events.EPOLLERR - }; - - ev.data.ptr = (IntPtr)state._handle; - - var rc = Core.IsWindows ? - Windows.epoll_ctl(_epHndle, epoll_op.EPOLL_CTL_ADD, (int)state.Connection.Handle, ref ev) : - Linux.epoll_ctl(_epHndle, epoll_op.EPOLL_CTL_ADD, (int)state.Connection.Handle, ref ev); - - - if (rc != 0) - { - throw new Exception($"epoll_ctl failed with error code {Marshal.GetLastWin32Error()}"); - } - } - - public void Remove(NetState state) - { - var ev = new epoll_event - { - events = epoll_events.EPOLLIN | epoll_events.EPOLLERR, - }; - ev.data.ptr = (IntPtr)state._handle; - - var rc = Core.IsWindows ? - Windows.epoll_ctl(_epHndle, epoll_op.EPOLL_CTL_DEL, (int)state.Connection.Handle, ref ev) : - Linux.epoll_ctl(_epHndle, epoll_op.EPOLL_CTL_DEL, (int)state.Connection.Handle, ref ev); - - if (rc != 0) - { - throw new Exception($"epoll_ctl failed with error code {Marshal.GetLastWin32Error()}"); - } - } - - private epoll_event[] _events = new epoll_event[2048]; - - public int Poll(ref NetState[] states) - { - if (states.Length > _events.Length) - { - var newLength = Math.Max(states.Length, _events.Length + (_events.Length >> 2)); - _events = new epoll_event[newLength]; - } - - var rc = Core.IsWindows ? - Windows.epoll_wait(_epHndle, _events, states.Length, 0) : - Linux.epoll_wait(_epHndle, _events, states.Length, 0); - - if (rc <= 0) - { - return rc; - } - - int count = 0; - - for (int i = 0; i < rc; i++) - { - if (((GCHandle)_events[i].data.ptr).Target is not NetState state) - { - continue; - } - - states[count++] = state; - } - - return count; - } - - } -} diff --git a/Projects/Server/Network/PollGroup/KQueuePollGroup.cs b/Projects/Server/Network/PollGroup/KQueuePollGroup.cs deleted file mode 100644 index 41466b968..000000000 --- a/Projects/Server/Network/PollGroup/KQueuePollGroup.cs +++ /dev/null @@ -1,248 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: KQueuePollGroup.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; -using System.IO; -using System.Runtime.InteropServices; - -namespace Server.Network -{ - public class KQueuePollGroup : IPollGroup - { - [StructLayout(LayoutKind.Sequential)] - private struct kevent - { - public IntPtr ident; - public kqueue_filter filter; - public kqueue_flags flags; - public kqueue_fflags fflags; - public IntPtr data; - public IntPtr udata; - } - - [Flags] - private enum kqueue_filter : short - { - READ = -1, - WRITE = -2, - AIO = -3, - VNODE = -4, - PROC = -5, - SIGNAL = -6, - TIMER = -7, - MACHPORT = -8, - FS = -9, - USER = -10, - UNUSED = -11, - VM = -12, - EXCEPT = -15 - } - - [Flags] - private enum kqueue_flags : ushort - { - ADD = 0x0001, - DELETE = 0x0002, - ENABLE = 0x0004, - DISABLE = 0x0008, - ONESHOT = 0x0010, - CLEAR = 0x0020, - RECEIPT = 0x0040, - DISPATCH = 0x0080, - UDATA_SPECIFIC = 0x0100, - DISPATCH2 = (DISPATCH | UDATA_SPECIFIC), - VANISHED = 0x0200, - SYSFLAGS = 0xF000, - FLAG0 = 0x1000, - FLAG1 = 0x2000, - EOF = 0x8000, - ERROR = 0x4000 - } - - [Flags] - private enum kqueue_fflags : uint - { - TRIGGER = 0x01000000, - FFNOP = 0x00000000, - FFAND = 0x40000000, - FFOR = 0x80000000, - FFCOPY = 0xc0000000, - FFCTRLMASK = 0xc0000000, - FFFLAGSMASK = 0x00ffffff, - LOWAT = 0x00000001, - DELETE = 0x00000001, - WRITE = 0x00000002, - EXTEND = 0x00000004, - ATTRIB = 0x00000008, - LINK = 0x00000010, - RENAME = 0x00000020, - REVOKE = 0x00000040, - NONE = 0x00000080, - } - - [StructLayout(LayoutKind.Sequential)] - struct timespec - { - public long tv_sec; - public long tv_nsec; - - public timespec(long sec, long nsec) - { - tv_sec = sec; - tv_nsec = nsec; - } - } - - private static readonly kevent[] _singleEvent = new kevent[1]; - private static readonly IntPtr _zeroTimeoutPtr; - // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable - private static readonly timespec _zeroTimeout; - - static KQueuePollGroup() - { - _zeroTimeout = new timespec(0, 0); - _zeroTimeoutPtr = Marshal.AllocHGlobal(Marshal.SizeOf()); - Marshal.StructureToPtr(_zeroTimeout, _zeroTimeoutPtr, false); - } - - private static class BSD - { - [DllImport ("libc", SetLastError = true)] - public static extern int close (int fd); - - [DllImport("libc", SetLastError = true)] - public static extern int kqueue(); - - [DllImport("libc", SetLastError = true)] - public static extern int kevent(int kq, kevent[] changelist, int nchanges, [In, Out] kevent[] eventlist, int nevents, IntPtr timeout); - - public static int kevent( - int kq, - IntPtr ident, - kqueue_filter filter, - kqueue_flags flags, - kqueue_fflags fflags = 0, - IntPtr data = default, - IntPtr udata = default - ) - { - _singleEvent[0] = new kevent - { - ident = ident, - filter = filter, - flags = flags, - fflags = fflags, - data = data, - udata = udata - }; - - var rc = kevent(kq, _singleEvent, 1, null, 0, _zeroTimeoutPtr); - if (rc != 0) - { - throw new Exception($"kqueue failed to {flags} with error code {Marshal.GetLastWin32Error()}"); - } - - if (_singleEvent[0].flags.HasFlag(kqueue_flags.ERROR)) - { - throw new IOException($"kqueue failed to {flags} with error {_singleEvent[0].data}"); - } - - return rc; - } - } - - private readonly int _kqueueHndle; - - public KQueuePollGroup() - { - _kqueueHndle = BSD.kqueue(); - - if (_kqueueHndle == 0) - { - throw new Exception("Unable to initialize poll group"); - } - } - - public void Dispose() - { - BSD.close(_kqueueHndle); - Marshal.FreeHGlobal(_zeroTimeoutPtr); - } - - public void Add(NetState state) - { - var rc = BSD.kevent( - _kqueueHndle, - state.Connection.Handle, - kqueue_filter.READ | kqueue_filter.WRITE, - kqueue_flags.ADD | kqueue_flags.CLEAR, - udata: (IntPtr)state._handle - ); - - if (rc != 0) - { - throw new Exception($"kevent failed with error code {Marshal.GetLastWin32Error()}"); - } - } - - public void Remove(NetState state) - { - var rc = BSD.kevent( - _kqueueHndle, - state.Connection.Handle, - kqueue_filter.READ | kqueue_filter.WRITE, - kqueue_flags.DELETE, - udata: (IntPtr)state._handle - ); - - if (rc != 0) - { - throw new Exception($"kevent failed with error code {Marshal.GetLastWin32Error()}"); - } - } - - private kevent[] _events = new kevent[2048]; - - public int Poll(ref NetState[] states) - { - if (states.Length > _events.Length) - { - var newLength = Math.Max(states.Length, _events.Length + (_events.Length >> 2)); - _events = new kevent[newLength]; - } - - var rc = BSD.kevent(_kqueueHndle, null, 0, _events, _events.Length, _zeroTimeoutPtr); - - if (rc <= 0) - { - return rc; - } - - int count = 0; - - for (int i = 0; i < rc; i++) - { - if (((GCHandle)_events[i].udata).Target is not NetState state) - { - continue; - } - - states[count++] = state; - } - - return count; - } - } -} diff --git a/Projects/Server/Network/PollGroup/PollGroup.cs b/Projects/Server/Network/PollGroup/PollGroup.cs deleted file mode 100644 index 9089f871b..000000000 --- a/Projects/Server/Network/PollGroup/PollGroup.cs +++ /dev/null @@ -1,39 +0,0 @@ -/************************************************************************* - * ModernUO * - * Copyright 2019-2021 - ModernUO Development Team * - * Email: hi@modernuo.com * - * File: PollGroup.cs * - * * - * This program is free software: you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation, either version 3 of the License, or * - * (at your option) any later version. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - *************************************************************************/ - -using System; - -namespace Server.Network -{ - public interface IPollGroup : IDisposable - { - void Add(NetState state); - void Remove(NetState state); - int Poll(ref NetState[] states); - } - - public static class PollGroup - { - public static IPollGroup Create() - { - if (Core.IsBSD) - { - return new KQueuePollGroup(); - } - - return new EPollGroup(); - } - } -} diff --git a/Projects/Server/Network/TcpServer.cs b/Projects/Server/Network/TcpServer.cs index 428c40cf9..a9b9f1955 100644 --- a/Projects/Server/Network/TcpServer.cs +++ b/Projects/Server/Network/TcpServer.cs @@ -196,7 +196,7 @@ namespace Server.Network } else { - var ns = new NetState(new NetworkSocket(socket)); + var ns = new NetState(socket); _connectedQueue.Enqueue(ns); } } diff --git a/Projects/Server/Server.csproj b/Projects/Server/Server.csproj index a0d4042b7..bf42d652f 100755 --- a/Projects/Server/Server.csproj +++ b/Projects/Server/Server.csproj @@ -13,32 +13,29 @@ - - - - - - - - + - - + + + + + + + + + + + - - - Always - Always - - + diff --git a/Projects/Server/wepoll.dll b/Projects/Server/wepoll.dll deleted file mode 100644 index d3f207d74..000000000 Binary files a/Projects/Server/wepoll.dll and /dev/null differ diff --git a/Projects/UOContent/Accounting/Account.Migrations.cs b/Projects/UOContent/Accounting/Account.Migrations.cs index 16b61efa1..dd9148b01 100644 --- a/Projects/UOContent/Accounting/Account.Migrations.cs +++ b/Projects/UOContent/Accounting/Account.Migrations.cs @@ -93,7 +93,8 @@ namespace Server.Accounting _totalGameTime = reader.ReadTimeSpan(); - _email = reader.ReadString(); + if (version > 1) + _email = reader.ReadString(); Timer.StartTimer(AfterDeserialization); } diff --git a/Projects/UOContent/Compression/ZstdArchive.cs b/Projects/UOContent/Compression/ZstdArchive.cs index b121e023a..35fd533d5 100755 --- a/Projects/UOContent/Compression/ZstdArchive.cs +++ b/Projects/UOContent/Compression/ZstdArchive.cs @@ -14,7 +14,8 @@ namespace Server.Compression // bsdtar has a bug and hangs, so we are doing it in two steps. if (Core.IsWindows) { - var tempTarArchive = Path.Combine(Core.BaseDirectory, "temp/temp-file.tar"); + var tempDir = PathUtility.EnsureRandomPath(Path.GetTempPath()); + var tempTarArchive = Path.Combine(tempDir, "temp-file.tar"); try { @@ -22,8 +23,8 @@ namespace Server.Compression { StartInfo = new ProcessStartInfo { - FileName = _pathToZstd, - Arguments = $"-q -d \"{fileNamePath}\" -o \"${tempTarArchive}\"" + FileName = Path.Combine(_pathToZstd, "zstd.exe"), + Arguments = $"-q -d \"{fileNamePath}\" -o \"{tempTarArchive}\"" } }; @@ -54,11 +55,12 @@ namespace Server.Compression // bsdtar has a bug and hangs, so we are doing it in two steps. if (Core.IsWindows) { - var tempTarArchive = Path.Combine(Core.BaseDirectory, "temp/temp-file.tar"); + var tempDir = PathUtility.EnsureRandomPath(Path.GetTempPath()); + var tempTarArchive = Path.Combine(tempDir, "temp-file.tar"); try { - if (!TarArchive.CreateFromPaths(paths, relativeTo, tempTarArchive)) + if (!TarArchive.CreateFromPaths(paths, tempTarArchive, relativeTo)) { return false; } @@ -83,7 +85,7 @@ namespace Server.Compression } finally { - File.Delete(tempTarArchive); + Directory.Delete(tempDir, true); } } diff --git a/Projects/UOContent/Misc/ServerList.cs b/Projects/UOContent/Misc/ServerList.cs index 33e33d2af..031f44bc8 100644 --- a/Projects/UOContent/Misc/ServerList.cs +++ b/Projects/UOContent/Misc/ServerList.cs @@ -68,7 +68,11 @@ namespace Server.Misc { var ns = e.State; - var ipep = (IPEndPoint)ns.Connection.LocalEndPoint; + var ipep = (IPEndPoint)ns.Connection?.LocalEndPoint; + if (ipep == null) + { + return; + } var localAddress = ipep.Address; var localPort = ipep.Port; @@ -76,7 +80,7 @@ namespace Server.Misc if (IsPrivateNetwork(localAddress)) { ipep = (IPEndPoint)ns.Connection.RemoteEndPoint; - if (!IsPrivateNetwork(ipep.Address) && _publicAddress != null) + if (ipep == null || !IsPrivateNetwork(ipep.Address) && _publicAddress != null) { localAddress = _publicAddress; } diff --git a/Projects/UOContent/World Saves/AutoArchive.cs b/Projects/UOContent/World Saves/AutoArchive.cs index fc839e830..7d46d6168 100755 --- a/Projects/UOContent/World Saves/AutoArchive.cs +++ b/Projects/UOContent/World Saves/AutoArchive.cs @@ -314,7 +314,7 @@ namespace Server.Saves foreach (var (rangeStart, sortedBackups) in items) { var backups = sortedBackups.Values; - if (backups.Count == 0) + if (backups.Count <= minimum) { continue; } @@ -380,7 +380,7 @@ namespace Server.Saves private static IEnumerable PathsByTimestampName(string path, bool files = false) { - var allItems = files ? Directory.GetFiles(path) : Directory.GetDirectories(path); + var allItems = files ? Directory.EnumerateFiles(path) : Directory.GetDirectories(path); var items = new SortedDictionary(new DescendingComparer()); foreach (var item in allItems) { @@ -397,7 +397,9 @@ namespace Server.Saves if (TryGetDate(name, out var date)) { - items.Add(date, item); + // Might give wrong results if there is a file that matches: + // Example: 2021-09-01, and 2021-09-01-00 + items[date] = item; } } @@ -435,7 +437,6 @@ namespace Server.Saves } catch { - logger.Warning($"Path was not in the correct date format: {value}"); date = DateTime.MinValue; return false; }