mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Add null reference checks.
This commit is contained in:
Submodule Aaru.Checksums updated: 30cbd81c84...01391f7a76
@@ -58,7 +58,13 @@ public partial class Dump
|
||||
void Ata()
|
||||
{
|
||||
bool recoveredError;
|
||||
var outputFormat = _outputPlugin as IWritableImage;
|
||||
|
||||
if(_outputPlugin is not IWritableImage outputFormat)
|
||||
{
|
||||
StoppingErrorMessage?.Invoke("Image is not writable, aborting...");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(_dumpRaw)
|
||||
{
|
||||
|
||||
@@ -62,8 +62,15 @@ partial class Dump
|
||||
_dumpLog.WriteLine("Creating sidecar.");
|
||||
var filters = new FiltersList();
|
||||
IFilter filter = filters.GetFilter(_outputPath);
|
||||
var inputPlugin = ImageFormat.Detect(filter) as IMediaImage;
|
||||
totalChkDuration = 0;
|
||||
|
||||
if(ImageFormat.Detect(filter) is not IMediaImage inputPlugin)
|
||||
{
|
||||
StoppingErrorMessage?.Invoke("Could not detect image format.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ErrorNumber opened = inputPlugin.Open(filter);
|
||||
|
||||
if(opened != ErrorNumber.NoError)
|
||||
|
||||
@@ -75,7 +75,13 @@ partial class Dump
|
||||
Dictionary<MediaTagType, byte[]> mediaTags = new();
|
||||
byte[] cmdBuf;
|
||||
bool ret;
|
||||
var outputFormat = _outputPlugin as IWritableImage;
|
||||
|
||||
if(_outputPlugin is not IWritableImage outputFormat)
|
||||
{
|
||||
StoppingErrorMessage?.Invoke("Image is not writable, aborting...");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_dumpLog.WriteLine("Initializing reader.");
|
||||
var scsiReader = new Reader(_dev, _dev.Timeout, null, _errorLog);
|
||||
|
||||
@@ -70,7 +70,13 @@ public partial class Dump
|
||||
MediaType dskType;
|
||||
bool sense;
|
||||
byte[] senseBuf;
|
||||
var outputFormat = _outputPlugin as IWritableImage;
|
||||
|
||||
if(_outputPlugin is not IWritableImage outputFormat)
|
||||
{
|
||||
StoppingErrorMessage?.Invoke("Image is not writable, aborting...");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sense = _dev.ReadCapacity(out byte[] readBuffer, out _, _dev.Timeout, out _);
|
||||
|
||||
|
||||
@@ -65,7 +65,13 @@ public partial class Dump
|
||||
DateTime start;
|
||||
DateTime end;
|
||||
byte[] senseBuf;
|
||||
var outputOptical = _outputPlugin as IWritableOpticalImage;
|
||||
|
||||
if(_outputPlugin is not IWritableOpticalImage outputOptical)
|
||||
{
|
||||
StoppingErrorMessage?.Invoke("Image is not writable, aborting...");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool sense = _dev.Read12(out byte[] readBuffer, out _, 0, false, true, false, false, 0, 512, 0, 1, false,
|
||||
_dev.Timeout, out _);
|
||||
|
||||
@@ -51,7 +51,13 @@ partial class Dump
|
||||
bool blankCheck;
|
||||
byte[] buffer;
|
||||
var newBlank = false;
|
||||
var outputFormat = _outputPlugin as IWritableImage;
|
||||
|
||||
if(_outputPlugin is not IWritableImage outputFormat)
|
||||
{
|
||||
StoppingErrorMessage?.Invoke("Image is not writable, aborting...");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach(ulong badSector in tmpArray)
|
||||
{
|
||||
|
||||
@@ -72,7 +72,13 @@ partial class Dump
|
||||
double currentSpeed = 0;
|
||||
double maxSpeed = double.MinValue;
|
||||
double minSpeed = double.MaxValue;
|
||||
var outputFormat = _outputPlugin as IWritableImage;
|
||||
|
||||
if(_outputPlugin is not IWritableImage outputFormat)
|
||||
{
|
||||
StoppingErrorMessage?.Invoke("Image is not writable, aborting...");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(DetectOS.GetRealPlatformID() != PlatformID.Win32NT)
|
||||
{
|
||||
|
||||
@@ -79,6 +79,8 @@ public static class Statistics
|
||||
allStats = (Stats)xs.Deserialize(sr);
|
||||
sr.Close();
|
||||
|
||||
if(allStats != null)
|
||||
{
|
||||
if(allStats.Commands?.Analyze > 0)
|
||||
{
|
||||
Command command = ctx.Commands.FirstOrDefault(c => c.Name == "fs-info" && c.Synchronized) ??
|
||||
@@ -94,8 +96,8 @@ public static class Statistics
|
||||
|
||||
if(allStats.Commands?.Checksum > 0)
|
||||
{
|
||||
Command command = ctx.Commands.FirstOrDefault(c => c.Name == "checksum" && c.Synchronized) ??
|
||||
new Command
|
||||
Command command =
|
||||
ctx.Commands.FirstOrDefault(c => c.Name == "checksum" && c.Synchronized) ?? new Command
|
||||
{
|
||||
Name = "checksum",
|
||||
Synchronized = true
|
||||
@@ -121,7 +123,8 @@ public static class Statistics
|
||||
if(allStats.Commands?.ConvertImage > 0)
|
||||
{
|
||||
Command command =
|
||||
ctx.Commands.FirstOrDefault(c => c.Name == "convert-image" && c.Synchronized) ?? new Command
|
||||
ctx.Commands.FirstOrDefault(c => c.Name == "convert-image" && c.Synchronized) ??
|
||||
new Command
|
||||
{
|
||||
Name = "convert-image",
|
||||
Synchronized = true
|
||||
@@ -160,7 +163,8 @@ public static class Statistics
|
||||
|
||||
if(allStats.Commands?.DeviceInfo > 0)
|
||||
{
|
||||
Command command = ctx.Commands.FirstOrDefault(c => c.Name == "device-info" && c.Synchronized) ??
|
||||
Command command =
|
||||
ctx.Commands.FirstOrDefault(c => c.Name == "device-info" && c.Synchronized) ??
|
||||
new Command
|
||||
{
|
||||
Name = "device-info",
|
||||
@@ -174,7 +178,8 @@ public static class Statistics
|
||||
if(allStats.Commands?.DeviceReport > 0)
|
||||
{
|
||||
Command command =
|
||||
ctx.Commands.FirstOrDefault(c => c.Name == "device-report" && c.Synchronized) ?? new Command
|
||||
ctx.Commands.FirstOrDefault(c => c.Name == "device-report" && c.Synchronized) ??
|
||||
new Command
|
||||
{
|
||||
Name = "device-report",
|
||||
Synchronized = true
|
||||
@@ -186,7 +191,8 @@ public static class Statistics
|
||||
|
||||
if(allStats.Commands?.DumpMedia > 0)
|
||||
{
|
||||
Command command = ctx.Commands.FirstOrDefault(c => c.Name == "dump-media" && c.Synchronized) ??
|
||||
Command command =
|
||||
ctx.Commands.FirstOrDefault(c => c.Name == "dump-media" && c.Synchronized) ??
|
||||
new Command
|
||||
{
|
||||
Name = "dump-media",
|
||||
@@ -213,7 +219,8 @@ public static class Statistics
|
||||
if(allStats.Commands?.ExtractFiles > 0)
|
||||
{
|
||||
Command command =
|
||||
ctx.Commands.FirstOrDefault(c => c.Name == "extract-files" && c.Synchronized) ?? new Command
|
||||
ctx.Commands.FirstOrDefault(c => c.Name == "extract-files" && c.Synchronized) ??
|
||||
new Command
|
||||
{
|
||||
Name = "extract-files",
|
||||
Synchronized = true
|
||||
@@ -238,7 +245,8 @@ public static class Statistics
|
||||
|
||||
if(allStats.Commands?.ImageInfo > 0)
|
||||
{
|
||||
Command command = ctx.Commands.FirstOrDefault(c => c.Name == "image-info" && c.Synchronized) ??
|
||||
Command command =
|
||||
ctx.Commands.FirstOrDefault(c => c.Name == "image-info" && c.Synchronized) ??
|
||||
new Command
|
||||
{
|
||||
Name = "image-info",
|
||||
@@ -252,7 +260,8 @@ public static class Statistics
|
||||
if(allStats.Commands?.ListDevices > 0)
|
||||
{
|
||||
Command command =
|
||||
ctx.Commands.FirstOrDefault(c => c.Name == "list-devices" && c.Synchronized) ?? new Command
|
||||
ctx.Commands.FirstOrDefault(c => c.Name == "list-devices" && c.Synchronized) ??
|
||||
new Command
|
||||
{
|
||||
Name = "list-devices",
|
||||
Synchronized = true
|
||||
@@ -291,7 +300,8 @@ public static class Statistics
|
||||
|
||||
if(allStats.Commands?.MediaInfo > 0)
|
||||
{
|
||||
Command command = ctx.Commands.FirstOrDefault(c => c.Name == "media-info" && c.Synchronized) ??
|
||||
Command command =
|
||||
ctx.Commands.FirstOrDefault(c => c.Name == "media-info" && c.Synchronized) ??
|
||||
new Command
|
||||
{
|
||||
Name = "media-info",
|
||||
@@ -304,7 +314,8 @@ public static class Statistics
|
||||
|
||||
if(allStats.Commands?.MediaScan > 0)
|
||||
{
|
||||
Command command = ctx.Commands.FirstOrDefault(c => c.Name == "media-scan" && c.Synchronized) ??
|
||||
Command command =
|
||||
ctx.Commands.FirstOrDefault(c => c.Name == "media-scan" && c.Synchronized) ??
|
||||
new Command
|
||||
{
|
||||
Name = "media-scan",
|
||||
@@ -317,8 +328,8 @@ public static class Statistics
|
||||
|
||||
if(allStats.Commands?.PrintHex > 0)
|
||||
{
|
||||
Command command = ctx.Commands.FirstOrDefault(c => c.Name == "printhex" && c.Synchronized) ??
|
||||
new Command
|
||||
Command command =
|
||||
ctx.Commands.FirstOrDefault(c => c.Name == "printhex" && c.Synchronized) ?? new Command
|
||||
{
|
||||
Name = "printhex",
|
||||
Synchronized = true
|
||||
@@ -368,7 +379,8 @@ public static class Statistics
|
||||
if(string.IsNullOrWhiteSpace(nvs.name))
|
||||
continue;
|
||||
|
||||
Version existing = ctx.Versions.FirstOrDefault(c => c.Name == nvs.name && c.Synchronized) ??
|
||||
Version existing =
|
||||
ctx.Versions.FirstOrDefault(c => c.Name == nvs.name && c.Synchronized) ??
|
||||
new Version
|
||||
{
|
||||
Name = nvs.name,
|
||||
@@ -457,8 +469,8 @@ public static class Statistics
|
||||
if(string.IsNullOrWhiteSpace(nvs.name))
|
||||
continue;
|
||||
|
||||
Filter existing = ctx.Filters.FirstOrDefault(c => c.Name == nvs.name && c.Synchronized) ??
|
||||
new Filter
|
||||
Filter existing =
|
||||
ctx.Filters.FirstOrDefault(c => c.Name == nvs.name && c.Synchronized) ?? new Filter
|
||||
{
|
||||
Name = nvs.name,
|
||||
Synchronized = true
|
||||
@@ -507,7 +519,7 @@ public static class Statistics
|
||||
|
||||
ctx.SaveChanges();
|
||||
File.Delete(Path.Combine(Settings.StatsPath, "Statistics.xml"));
|
||||
}
|
||||
} }
|
||||
catch
|
||||
{
|
||||
// Do not care about it
|
||||
|
||||
@@ -301,7 +301,8 @@ static partial class Usb
|
||||
if(DeviceIoControl(h, IOCTL_USB_GET_ROOT_HUB_NAME, ptrHubName, nBytes, ptrHubName, nBytes, out _,
|
||||
IntPtr.Zero))
|
||||
{
|
||||
hubName = (UsbRootHubName)Marshal.PtrToStructure(ptrHubName, typeof(UsbRootHubName));
|
||||
hubName = (UsbRootHubName)(Marshal.PtrToStructure(ptrHubName, typeof(UsbRootHubName)) ??
|
||||
default(UsbRootHubName));
|
||||
root.HubDevicePath = @"\\.\" + hubName.RootHubName;
|
||||
}
|
||||
|
||||
@@ -428,8 +429,9 @@ static partial class Usb
|
||||
continue;
|
||||
|
||||
nodeConnection =
|
||||
(UsbNodeConnectionInformationEx)Marshal.PtrToStructure(ptrNodeConnection,
|
||||
typeof(UsbNodeConnectionInformationEx));
|
||||
(UsbNodeConnectionInformationEx)(Marshal.PtrToStructure(ptrNodeConnection,
|
||||
typeof(UsbNodeConnectionInformationEx)) ??
|
||||
default(UsbNodeConnectionInformationEx));
|
||||
|
||||
// load up the USBPort class
|
||||
var port = new UsbPort
|
||||
@@ -556,7 +558,8 @@ static partial class Usb
|
||||
var ptrStringDesc = IntPtr.Add(ptrRequest, Marshal.SizeOf(request));
|
||||
|
||||
var stringDesc =
|
||||
(UsbStringDescriptor)Marshal.PtrToStructure(ptrStringDesc, typeof(UsbStringDescriptor));
|
||||
(UsbStringDescriptor)(Marshal.PtrToStructure(ptrStringDesc, typeof(UsbStringDescriptor)) ??
|
||||
default(UsbStringDescriptor));
|
||||
|
||||
device.DeviceManufacturer = stringDesc.bString;
|
||||
}
|
||||
@@ -592,7 +595,8 @@ static partial class Usb
|
||||
var ptrStringDesc = IntPtr.Add(ptrRequest, Marshal.SizeOf(request));
|
||||
|
||||
var stringDesc =
|
||||
(UsbStringDescriptor)Marshal.PtrToStructure(ptrStringDesc, typeof(UsbStringDescriptor));
|
||||
(UsbStringDescriptor)(Marshal.PtrToStructure(ptrStringDesc, typeof(UsbStringDescriptor)) ??
|
||||
default(UsbStringDescriptor));
|
||||
|
||||
device.DeviceProduct = stringDesc.bString;
|
||||
}
|
||||
@@ -628,7 +632,8 @@ static partial class Usb
|
||||
var ptrStringDesc = IntPtr.Add(ptrRequest, Marshal.SizeOf(request));
|
||||
|
||||
var stringDesc =
|
||||
(UsbStringDescriptor)Marshal.PtrToStructure(ptrStringDesc, typeof(UsbStringDescriptor));
|
||||
(UsbStringDescriptor)(Marshal.PtrToStructure(ptrStringDesc, typeof(UsbStringDescriptor)) ??
|
||||
default(UsbStringDescriptor));
|
||||
|
||||
device.DeviceSerialNumber = stringDesc.bString;
|
||||
}
|
||||
@@ -678,8 +683,9 @@ static partial class Usb
|
||||
if(DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME, ptrDriverKey, nBytes, ptrDriverKey,
|
||||
nBytes, out nBytesReturned, IntPtr.Zero))
|
||||
{
|
||||
driverKey = (UsbNodeConnectionDriverkeyName)Marshal.PtrToStructure(ptrDriverKey,
|
||||
typeof(UsbNodeConnectionDriverkeyName));
|
||||
driverKey = (UsbNodeConnectionDriverkeyName)(Marshal.PtrToStructure(ptrDriverKey,
|
||||
typeof(UsbNodeConnectionDriverkeyName)) ??
|
||||
default(UsbNodeConnectionDriverkeyName));
|
||||
|
||||
device.DeviceDriverKey = driverKey.DriverKeyName;
|
||||
|
||||
@@ -727,7 +733,8 @@ static partial class Usb
|
||||
if(DeviceIoControl(h, IOCTL_USB_GET_NODE_CONNECTION_NAME, ptrNodeName, nBytes, ptrNodeName, nBytes, out _,
|
||||
IntPtr.Zero))
|
||||
{
|
||||
nodeName = (UsbNodeConnectionName)Marshal.PtrToStructure(ptrNodeName, typeof(UsbNodeConnectionName));
|
||||
nodeName = (UsbNodeConnectionName)(Marshal.PtrToStructure(ptrNodeName, typeof(UsbNodeConnectionName)) ??
|
||||
default(UsbNodeConnectionName));
|
||||
|
||||
hub.HubDevicePath = @"\\.\" + nodeName.NodeName;
|
||||
}
|
||||
@@ -751,7 +758,8 @@ static partial class Usb
|
||||
if(DeviceIoControl(h2, IOCTL_USB_GET_NODE_INFORMATION, ptrNodeInfo, nBytes, ptrNodeInfo, nBytes, out _,
|
||||
IntPtr.Zero))
|
||||
{
|
||||
nodeInfo = (UsbNodeInformation)Marshal.PtrToStructure(ptrNodeInfo, typeof(UsbNodeInformation));
|
||||
nodeInfo = (UsbNodeInformation)(Marshal.PtrToStructure(ptrNodeInfo, typeof(UsbNodeInformation)) ??
|
||||
default(UsbNodeInformation));
|
||||
|
||||
hub.HubIsBusPowered = Convert.ToBoolean(nodeInfo.HubInformation.HubIsBusPowered);
|
||||
hub.HubPortCount = nodeInfo.HubInformation.HubDescriptor.bNumberOfPorts;
|
||||
|
||||
@@ -56,6 +56,9 @@ public sealed partial class CPM
|
||||
var defsSerializer = new XmlSerializer(typeof(CpmDefinitions));
|
||||
_definitions = (CpmDefinitions)defsSerializer.Deserialize(defsReader);
|
||||
|
||||
if(_definitions is null)
|
||||
return false;
|
||||
|
||||
// Patch definitions
|
||||
foreach(CpmDefinition def in _definitions.definitions)
|
||||
{
|
||||
|
||||
@@ -97,7 +97,7 @@ public sealed class MediaInfoViewModel : ViewModelBase
|
||||
|
||||
var mediaResource = new Uri($"avares://Aaru.Gui/Assets/Logos/Media/{scsiInfo.MediaType}.png");
|
||||
|
||||
MediaLogo = assets.Exists(mediaResource) ? new Bitmap(assets.Open(mediaResource)) : null;
|
||||
MediaLogo = assets?.Exists(mediaResource) == true ? new Bitmap(assets.Open(mediaResource)) : null;
|
||||
|
||||
MediaType = scsiInfo.MediaType.ToString();
|
||||
|
||||
|
||||
@@ -2000,7 +2000,7 @@ public sealed class ImageConvertViewModel : ViewModelBase
|
||||
var sr = new StreamReader(result[0]);
|
||||
var resume = (Resume)sidecarXs.Deserialize(sr);
|
||||
|
||||
if(resume.Tries?.Any() == false)
|
||||
if(resume?.Tries?.Any() == false)
|
||||
{
|
||||
_dumpHardware = resume.Tries;
|
||||
ResumeFileText = result[0];
|
||||
|
||||
@@ -136,6 +136,9 @@ public sealed class MainWindowViewModel : ViewModelBase
|
||||
break;
|
||||
}
|
||||
|
||||
if(_assets == null)
|
||||
return;
|
||||
|
||||
_genericHddIcon =
|
||||
new Bitmap(_assets.Open(new Uri("avares://Aaru.Gui/Assets/Icons/oxygen/32x32/drive-harddisk.png")));
|
||||
|
||||
@@ -150,15 +153,18 @@ public sealed class MainWindowViewModel : ViewModelBase
|
||||
|
||||
_usbIcon =
|
||||
new
|
||||
Bitmap(_assets.Open(new Uri("avares://Aaru.Gui/Assets/Icons/oxygen/32x32/drive-removable-media-usb.png")));
|
||||
Bitmap(_assets.Open(new
|
||||
Uri("avares://Aaru.Gui/Assets/Icons/oxygen/32x32/drive-removable-media-usb.png")));
|
||||
|
||||
_removableIcon =
|
||||
new Bitmap(_assets.Open(new Uri("avares://Aaru.Gui/Assets/Icons/oxygen/32x32/drive-removable-media.png")));
|
||||
new
|
||||
Bitmap(_assets.Open(new Uri("avares://Aaru.Gui/Assets/Icons/oxygen/32x32/drive-removable-media.png")));
|
||||
|
||||
_sdIcon =
|
||||
new Bitmap(_assets.Open(new Uri("avares://Aaru.Gui/Assets/Icons/oxygen/32x32/media-flash-sd-mmc.png")));
|
||||
|
||||
_ejectIcon = new Bitmap(_assets.Open(new Uri("avares://Aaru.Gui/Assets/Icons/oxygen/32x32/media-eject.png")));
|
||||
_ejectIcon =
|
||||
new Bitmap(_assets.Open(new Uri("avares://Aaru.Gui/Assets/Icons/oxygen/32x32/media-eject.png")));
|
||||
}
|
||||
|
||||
public bool DevicesSupported
|
||||
@@ -168,7 +174,7 @@ public sealed class MainWindowViewModel : ViewModelBase
|
||||
}
|
||||
|
||||
public bool NativeMenuSupported =>
|
||||
NativeMenu.GetIsNativeMenuExported((Application.Current.ApplicationLifetime as
|
||||
NativeMenu.GetIsNativeMenuExported((Application.Current?.ApplicationLifetime as
|
||||
IClassicDesktopStyleApplicationLifetime)?.MainWindow);
|
||||
|
||||
[NotNull]
|
||||
@@ -480,7 +486,7 @@ public sealed class MainWindowViewModel : ViewModelBase
|
||||
}
|
||||
|
||||
internal void ExecuteExitCommand() =>
|
||||
(Application.Current.ApplicationLifetime as ClassicDesktopStyleApplicationLifetime)?.Shutdown();
|
||||
(Application.Current?.ApplicationLifetime as ClassicDesktopStyleApplicationLifetime)?.Shutdown();
|
||||
|
||||
void ExecuteConsoleCommand()
|
||||
{
|
||||
|
||||
Submodule Aaru.Helpers updated: 0462eaac5e...af338014d5
@@ -161,6 +161,10 @@ public abstract class ReadOnlyFilesystemTest : FilesystemTest
|
||||
var filtersList = new FiltersList();
|
||||
IFilter inputFilter = filtersList.GetFilter(testFile);
|
||||
var image = ImageFormat.Detect(inputFilter) as IMediaImage;
|
||||
|
||||
if(image is null)
|
||||
continue;
|
||||
|
||||
ErrorNumber opened = image.Open(inputFilter);
|
||||
|
||||
if(opened != ErrorNumber.NoError)
|
||||
|
||||
@@ -337,6 +337,9 @@ sealed class ExtractFilesCommand : Command
|
||||
var fs = (IReadOnlyFilesystem)plugin.GetType().GetConstructor(Type.EmptyTypes)?.
|
||||
Invoke(Array.Empty<object>());
|
||||
|
||||
if(fs is null)
|
||||
continue;
|
||||
|
||||
Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Mounting filesystem...").IsIndeterminate();
|
||||
@@ -370,6 +373,9 @@ sealed class ExtractFilesCommand : Command
|
||||
var fs = (IReadOnlyFilesystem)plugin.GetType().GetConstructor(Type.EmptyTypes)?.
|
||||
Invoke(Array.Empty<object>());
|
||||
|
||||
if(fs is null)
|
||||
continue;
|
||||
|
||||
Spectre.ProgressSingleSpinner(ctx =>
|
||||
{
|
||||
ctx.AddTask("Mounting filesystem...").IsIndeterminate();
|
||||
|
||||
@@ -214,7 +214,12 @@ sealed class PrintHexCommand : Command
|
||||
else
|
||||
for(ulong i = 0; i < length; i++)
|
||||
{
|
||||
var blockImage = inputFormat as IMediaImage;
|
||||
if(inputFormat is not IMediaImage blockImage)
|
||||
{
|
||||
AaruConsole.ErrorWriteLine("Cannot open image file, aborting...");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
AaruConsole.WriteLine("[bold][italic]Sector {0}[/][/]", start + i);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user