mirror of
https://github.com/kwsch/pkNX.git
synced 2026-09-09 02:55:21 -05:00
Enable nullable checks for all subprojects except structures/game
This commit is contained in:
@@ -28,7 +28,7 @@ public static IFileContainer GetContainer(string path, ContainerType t)
|
||||
/// Gets a <see cref="IFileContainer"/> for the stream.
|
||||
/// </summary>
|
||||
/// <param name="path">Path to the binary data</param>
|
||||
public static IFileContainer GetContainer(string path)
|
||||
public static IFileContainer? GetContainer(string path)
|
||||
{
|
||||
var fs = new FileStream(path, FileMode.Open);
|
||||
var container = GetContainer(fs);
|
||||
@@ -45,7 +45,7 @@ public static IFileContainer GetContainer(string path)
|
||||
/// Gets a <see cref="IFileContainer"/> for the stream.
|
||||
/// </summary>
|
||||
/// <param name="stream">Stream for the binary data</param>
|
||||
public static IFileContainer GetContainer(Stream stream)
|
||||
public static IFileContainer? GetContainer(Stream stream)
|
||||
{
|
||||
var br = new BinaryReader(stream);
|
||||
var container = GetContainer(br);
|
||||
@@ -58,9 +58,9 @@ public static IFileContainer GetContainer(Stream stream)
|
||||
/// Gets a <see cref="IFileContainer"/> for the stream within the <see cref="BinaryReader"/>.
|
||||
/// </summary>
|
||||
/// <param name="br">Reader for the binary data</param>
|
||||
public static IFileContainer GetContainer(BinaryReader br)
|
||||
public static IFileContainer? GetContainer(BinaryReader br)
|
||||
{
|
||||
IFileContainer container;
|
||||
IFileContainer? container;
|
||||
if ((container = GARC.GetGARC(br)) != null)
|
||||
return container;
|
||||
if ((container = MiniUtil.GetMini(br)) != null)
|
||||
|
||||
@@ -6,8 +6,8 @@ namespace pkNX.Containers
|
||||
{
|
||||
public sealed class ContainerHandler
|
||||
{
|
||||
public event EventHandler<FileCountDeterminedEventArgs> FileCountDetermined;
|
||||
public event EventHandler<FileProgressedEventArgs> FileProgressed;
|
||||
public event EventHandler<FileCountDeterminedEventArgs>? FileCountDetermined;
|
||||
public event EventHandler<FileProgressedEventArgs>? FileProgressed;
|
||||
|
||||
private int count;
|
||||
|
||||
@@ -18,11 +18,11 @@ public void Initialize(int total)
|
||||
FileCountDetermined?.Invoke(null, args);
|
||||
}
|
||||
|
||||
public void StepFile(int ctr, int total = -1, string fileName = null)
|
||||
public void StepFile(int ctr, int total = -1, string? fileName = null)
|
||||
{
|
||||
if (total < 0)
|
||||
total = count;
|
||||
var args = new FileProgressedEventArgs {Current = ctr, Total = total, CurrentFile = fileName};
|
||||
var args = new FileProgressedEventArgs {Current = ctr, Total = total, CurrentFile = fileName ?? string.Empty};
|
||||
FileProgressed?.Invoke(null, args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,6 @@ public class FileProgressedEventArgs : EventArgs
|
||||
{
|
||||
public int Current { get; set; }
|
||||
public int Total { get; set; }
|
||||
public string CurrentFile { get; set; }
|
||||
public string? CurrentFile { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ public FakeContainer(byte[][] files)
|
||||
Backup[i] = (byte[])files[i].Clone();
|
||||
}
|
||||
|
||||
public string FilePath { get; set; } = string.Empty;
|
||||
public string? FilePath { get; set; } = string.Empty;
|
||||
public bool Modified { get; set; }
|
||||
public int Count => Files.Length;
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@ public static class FileMitm
|
||||
public static void EnableIfSetup() => Enabled = PathOriginal != null;
|
||||
public static void Disable() => Enabled = false;
|
||||
|
||||
private static string PathOriginal;
|
||||
private static string PathRedirect;
|
||||
private static string? PathOriginal;
|
||||
private static string? PathRedirect;
|
||||
|
||||
public static byte[] ReadAllBytes(string path)
|
||||
{
|
||||
@@ -23,6 +23,8 @@ public static byte[] ReadAllBytes(string path)
|
||||
|
||||
public static void WriteAllBytes(string path, byte[] data)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
throw new FileNotFoundException("Invalid filename.");
|
||||
path = GetRedirectedWritePath(path);
|
||||
File.WriteAllBytes(path, data);
|
||||
}
|
||||
|
||||
@@ -10,16 +10,18 @@ namespace pkNX.Containers
|
||||
public class FolderContainer : IFileContainer
|
||||
{
|
||||
private readonly List<string> Paths = new();
|
||||
private readonly List<byte[]> Data = new();
|
||||
private readonly List<byte[]?> Data = new();
|
||||
private readonly List<bool> TrackModify = new();
|
||||
|
||||
public string? FilePath { get; set; }
|
||||
|
||||
public FolderContainer() { }
|
||||
public FolderContainer(IEnumerable<string> files) => AddFiles(files);
|
||||
|
||||
public FolderContainer(string path) => FilePath = path;
|
||||
public FolderContainer(string path, Func<string, bool> filter) : this(path) => Initialize(filter);
|
||||
|
||||
public void Initialize(Func<string, bool> filter = null)
|
||||
public void Initialize(Func<string, bool>? filter = null)
|
||||
{
|
||||
if (Paths.Count > 0)
|
||||
return; // already initialized
|
||||
@@ -30,7 +32,7 @@ public void Initialize(Func<string, bool> filter = null)
|
||||
AddFiles(files);
|
||||
}
|
||||
|
||||
public void AddFile(string file, byte[] data = null)
|
||||
public void AddFile(string file, byte[]? data = null)
|
||||
{
|
||||
Paths.Add(file);
|
||||
Data.Add(data);
|
||||
@@ -43,7 +45,7 @@ public void AddFiles(IEnumerable<string> files)
|
||||
AddFile(f);
|
||||
}
|
||||
|
||||
public byte[] GetFileData(string file)
|
||||
public byte[]? GetFileData(string file)
|
||||
{
|
||||
var index = Paths.FindIndex(z => Path.GetFileName(z) == file);
|
||||
if (index < 0)
|
||||
@@ -55,8 +57,6 @@ public byte[] GetFileData(string file)
|
||||
|
||||
public byte[] GetFileData(int index)
|
||||
{
|
||||
if (index < 0 || (uint)index >= Data.Count)
|
||||
return null;
|
||||
var data = Data[index] ??= FileMitm.ReadAllBytes(Paths[index]);
|
||||
return (byte[])data.Clone();
|
||||
}
|
||||
@@ -66,18 +66,20 @@ public byte[] GetFileData(int index)
|
||||
get => GetFileData(index);
|
||||
set
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
var current = Data[index] ??= GetFileData(index);
|
||||
TrackModify[index] = !value.SequenceEqual(current);
|
||||
}
|
||||
var current = Data[index] ??= GetFileData(index);
|
||||
TrackModify[index] = !value.SequenceEqual(current);
|
||||
|
||||
Data[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string GetFileName(int index) => Paths[index];
|
||||
public void ResetIndex(int index)
|
||||
{
|
||||
Data[index] = null;
|
||||
TrackModify[index] = false;
|
||||
}
|
||||
|
||||
public string FilePath { get; set; }
|
||||
public string GetFileName(int index) => Paths[index];
|
||||
|
||||
public bool Modified
|
||||
{
|
||||
|
||||
@@ -10,15 +10,14 @@ internal class FATBEntry
|
||||
public readonly bool IsFolder;
|
||||
public readonly FATBSubEntry[] SubEntries;
|
||||
|
||||
// ReSharper disable once UnusedMember.Local -- needed to init subentries
|
||||
private FATBEntry()
|
||||
{
|
||||
SubEntries = new FATBSubEntry[32];
|
||||
for (int i = 0; i < SubEntries.Length; i++)
|
||||
SubEntries[i] = new FATBSubEntry();
|
||||
var sub = SubEntries = new FATBSubEntry[32];
|
||||
for (int i = 0; i < sub.Length; i++)
|
||||
sub[i] = new FATBSubEntry();
|
||||
}
|
||||
|
||||
public FATBEntry(string file)
|
||||
public FATBEntry(string file) : this()
|
||||
{
|
||||
IsFolder = false;
|
||||
Vector = 1;
|
||||
@@ -26,7 +25,7 @@ public FATBEntry(string file)
|
||||
SubEntries[0].File = file;
|
||||
}
|
||||
|
||||
public FATBEntry(IEnumerable<string> files)
|
||||
public FATBEntry(IEnumerable<string> files) : this()
|
||||
{
|
||||
IsFolder = true;
|
||||
Vector = 0;
|
||||
@@ -45,7 +44,7 @@ public FATBEntry(IEnumerable<string> files)
|
||||
}
|
||||
}
|
||||
|
||||
public FATBEntry(BinaryReader br, int DataOffset)
|
||||
public FATBEntry(BinaryReader br, int DataOffset) : this()
|
||||
{
|
||||
Vector = br.ReadUInt32();
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ internal class FATO
|
||||
|
||||
private readonly uint Magic = MAGIC;
|
||||
private readonly int HeaderSize = 0xC;
|
||||
private readonly ushort EntryCount;
|
||||
public readonly ushort EntryCount;
|
||||
private readonly short Padding = -1;
|
||||
|
||||
private FATOEntry[] Entries { get; }
|
||||
|
||||
@@ -12,22 +12,26 @@ public class GARC : LargeContainer
|
||||
private FATO FATO;
|
||||
private FATB FATB;
|
||||
|
||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
public GARC(BinaryReader br) => OpenRead(br);
|
||||
public GARC(string file) => OpenBinary(file);
|
||||
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
|
||||
public GARC(IReadOnlyList<string> files, GARCVersion version = GARCVersion.VER_6)
|
||||
{
|
||||
Header = new GARCHeader(version);
|
||||
FATO = new FATO(files.Count);
|
||||
FATB = new FATB(files);
|
||||
Files = new byte[]?[files.Count];
|
||||
}
|
||||
|
||||
protected override void Initialize()
|
||||
{
|
||||
Reader.BaseStream.Position = 0;
|
||||
Reader!.BaseStream.Position = 0;
|
||||
Header = new GARCHeader(Reader);
|
||||
FATO = new FATO(Reader);
|
||||
FATB = new FATB(Reader, Header.DataOffset);
|
||||
Files = new byte[]?[FATO.EntryCount];
|
||||
}
|
||||
|
||||
protected override int GetFileOffset(int file, int subFile = 0)
|
||||
@@ -42,12 +46,12 @@ public override byte[] GetEntry(int index, int subFile)
|
||||
if (f.File is byte[] data)
|
||||
return data;
|
||||
|
||||
data = f.GetFileData(Reader.BaseStream);
|
||||
data = f.GetFileData(Reader!.BaseStream);
|
||||
f.File = data; // cache for future fetches
|
||||
return data;
|
||||
}
|
||||
|
||||
public override void SetEntry(int index, byte[] value, int subFile)
|
||||
public override void SetEntry(int index, byte[]? value, int subFile)
|
||||
{
|
||||
Modified |= value != null && !GetEntry(index, subFile).SequenceEqual(value);
|
||||
var f = FATB[index].SubEntries[subFile];
|
||||
@@ -94,7 +98,7 @@ private void WriteIntro(BinaryWriter bw, bool lastPass = false)
|
||||
private void WriteEntry(BinaryWriter bw, int i, int DataOffset)
|
||||
{
|
||||
FATO[i].Offset = (uint)bw.BaseStream.Position;
|
||||
FATB[i].WriteEntries(bw, Reader?.BaseStream, Header.ContentPadToNearest, DataOffset,
|
||||
FATB[i].WriteEntries(bw, Reader!.BaseStream, Header.ContentPadToNearest, DataOffset,
|
||||
ref Header.ContentLargestUnpadded, ref Header.ContentLargestPadded);
|
||||
}
|
||||
|
||||
@@ -108,12 +112,12 @@ public override void Dump(string path, ContainerHandler handler)
|
||||
handler.Initialize(Count);
|
||||
for (int i = 0; i < Count; i++)
|
||||
{
|
||||
FATB[i].Dump(path, i, format, Reader.BaseStream, Header.DataOffset);
|
||||
FATB[i].Dump(path, i, format, Reader!.BaseStream, Header.DataOffset);
|
||||
handler.StepFile(i+1);
|
||||
}
|
||||
}
|
||||
|
||||
public static GARC GetGARC(BinaryReader br)
|
||||
public static GARC? GetGARC(BinaryReader br)
|
||||
{
|
||||
if (br.BaseStream.Length < 20)
|
||||
return null;
|
||||
|
||||
@@ -12,7 +12,7 @@ public interface IFileContainer
|
||||
/// <summary>
|
||||
/// Path the <see cref="IFileContainer"/> was loaded from.
|
||||
/// </summary>
|
||||
string FilePath { get; set; }
|
||||
string? FilePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indication if the contents of the <see cref="IFileContainer"/> have been modified.
|
||||
|
||||
@@ -14,16 +14,16 @@ public abstract class LargeContainer : IDisposable, IFileContainer
|
||||
{
|
||||
public virtual int Count => Files.Length;
|
||||
|
||||
public Task<byte[][]> GetFiles() => new(() => { CacheAll(); return Files; });
|
||||
public Task<byte[][]> GetFiles() => new(() => { CacheAll(); return Files!; });
|
||||
public Task<byte[]> GetFile(int file, int subFile = 0) => new(() => GetEntry(file, subFile));
|
||||
public Task SetFile(int file, byte[] value, int subFile = 0) => new(() => SetEntry(file, value, subFile));
|
||||
|
||||
public string Extension => Path.GetExtension(FilePath);
|
||||
public string FileName => Path.GetFileName(FilePath);
|
||||
public string FilePath { get; set; }
|
||||
public string? Extension => Path.GetExtension(FilePath);
|
||||
public string? FileName => Path.GetFileName(FilePath);
|
||||
public string? FilePath { get; set; }
|
||||
public bool Modified { get; set; }
|
||||
|
||||
protected byte[][] Files { get; set; }
|
||||
protected byte[]?[] Files = Array.Empty<byte[]>();
|
||||
|
||||
/// <summary>
|
||||
/// Packs the <see cref="LargeContainer"/> to the specified writing stream.
|
||||
@@ -36,8 +36,8 @@ public abstract class LargeContainer : IDisposable, IFileContainer
|
||||
|
||||
#region File Reading
|
||||
|
||||
protected BinaryReader Reader { get; private set; }
|
||||
private Stream Stream;
|
||||
protected BinaryReader? Reader { get; private set; }
|
||||
private Stream? Stream;
|
||||
|
||||
protected void OpenBinary(string path)
|
||||
{
|
||||
@@ -60,6 +60,8 @@ protected void OpenRead(BinaryReader br)
|
||||
|
||||
public BinaryReader Seek(int file, long offset = 0, int subFile = 0)
|
||||
{
|
||||
if (Reader == null)
|
||||
throw new NullReferenceException("Reader is not initialized.");
|
||||
offset += GetFileOffset(file, subFile);
|
||||
Reader.BaseStream.Position = offset;
|
||||
return Reader;
|
||||
@@ -67,7 +69,7 @@ public BinaryReader Seek(int file, long offset = 0, int subFile = 0)
|
||||
|
||||
public abstract byte[] GetEntry(int index, int subFile);
|
||||
|
||||
public virtual void SetEntry(int index, byte[] value, int subFile)
|
||||
public virtual void SetEntry(int index, byte[]? value, int subFile)
|
||||
{
|
||||
Files[index] = value;
|
||||
Modified |= value != null && !this[index].SequenceEqual(value);
|
||||
@@ -92,7 +94,8 @@ public void CacheAll()
|
||||
Files[i] ??= GetCachedValue(i, 0);
|
||||
|
||||
Reader = null;
|
||||
Stream.Close();
|
||||
Stream?.Close();
|
||||
Stream = null;
|
||||
}
|
||||
|
||||
public void CancelEdits()
|
||||
@@ -143,8 +146,8 @@ public void Dispose()
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
Stream.Dispose();
|
||||
Reader.Dispose();
|
||||
Stream?.Dispose();
|
||||
Reader?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ public class LargeContainerEntry
|
||||
public int Start { get; set; }
|
||||
public int End { get; set; }
|
||||
public virtual int Length { get; set; }
|
||||
public object File { get; set; }
|
||||
public object? File { get; set; }
|
||||
public int ParentDataPosition { get; set; }
|
||||
|
||||
public byte[] GetFileData(Stream parent)
|
||||
|
||||
@@ -29,7 +29,7 @@ public Mini(byte[][] data, string ident)
|
||||
}
|
||||
}
|
||||
|
||||
public string FilePath { get; set; }
|
||||
public string? FilePath { get; set; }
|
||||
private readonly byte[][] Backup;
|
||||
|
||||
public bool Modified { get; set; }
|
||||
|
||||
@@ -30,10 +30,10 @@ public static byte[] PackMini(byte[][] fileData, string identifier)
|
||||
int dataOffset = 4 + 4 + (count * 4);
|
||||
|
||||
// Start the data filling.
|
||||
using MemoryStream dataout = new MemoryStream();
|
||||
using MemoryStream offsetMap = new MemoryStream();
|
||||
using BinaryWriter bd = new BinaryWriter(dataout);
|
||||
using BinaryWriter bo = new BinaryWriter(offsetMap);
|
||||
using MemoryStream dataout = new();
|
||||
using MemoryStream offsetMap = new();
|
||||
using BinaryWriter bd = new(dataout);
|
||||
using BinaryWriter bo = new(offsetMap);
|
||||
// For each file...
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
@@ -60,21 +60,21 @@ public static byte[] PackMini(byte[][] fileData, string identifier)
|
||||
return newPack.ToArray();
|
||||
}
|
||||
|
||||
public static byte[][] UnpackMini(string file, string identifier = null)
|
||||
public static byte[][] UnpackMini(string file, string identifier)
|
||||
{
|
||||
byte[] fileData = FileMitm.ReadAllBytes(file);
|
||||
return UnpackMini(fileData, identifier);
|
||||
}
|
||||
|
||||
public static byte[][] UnpackMini(byte[] fileData, string identifier = null)
|
||||
public static byte[][] UnpackMini(byte[] fileData, string identifier)
|
||||
{
|
||||
if (fileData == null || fileData.Length < 4)
|
||||
return null;
|
||||
if (fileData.Length < 4)
|
||||
throw new ArgumentOutOfRangeException(nameof(fileData));
|
||||
|
||||
if (identifier?.Length == 2)
|
||||
if (identifier.Length == 2)
|
||||
{
|
||||
if (identifier[0] != fileData[0] || identifier[1] != fileData[1])
|
||||
return null;
|
||||
throw new FormatException("Prefix does not match.");
|
||||
}
|
||||
|
||||
int count = BitConverter.ToUInt16(fileData, 2); int ctr = 4;
|
||||
@@ -97,10 +97,13 @@ public static Mini GetMini(string path)
|
||||
path = FileMitm.GetRedirectedReadPath(path);
|
||||
using var fs = new FileStream(path, FileMode.Open, FileAccess.Read);
|
||||
using var br = new BinaryReader(fs);
|
||||
return GetMini(br);
|
||||
var result = GetMini(br);
|
||||
if (result is null)
|
||||
throw new FormatException($"The file at {path} is not a {nameof(Mini)} file.");
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Mini GetMini(BinaryReader br)
|
||||
public static Mini? GetMini(BinaryReader br)
|
||||
{
|
||||
var ident = GetIsMini(br);
|
||||
if (string.IsNullOrEmpty(ident))
|
||||
@@ -115,18 +118,18 @@ public static Mini GetMini(BinaryReader br)
|
||||
public static string GetIsMini(BinaryReader br)
|
||||
{
|
||||
if (br.BaseStream.Length < 12)
|
||||
return null;
|
||||
return string.Empty;
|
||||
br.BaseStream.Position = 0;
|
||||
var ident = br.ReadBytes(2);
|
||||
var count = br.ReadUInt16();
|
||||
|
||||
int finalLengthOfs = 4 + (count * 4);
|
||||
if (br.BaseStream.Length < finalLengthOfs + 4)
|
||||
return null;
|
||||
return string.Empty;
|
||||
br.BaseStream.Position = 4 + (count * 4);
|
||||
var len = br.ReadUInt32();
|
||||
if (len != br.BaseStream.Length)
|
||||
return null;
|
||||
return string.Empty;
|
||||
return $"{(char)ident[0]}{(char)ident[1]}";
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ public static string ReadNXString(this BinaryReader br)
|
||||
|
||||
public static string ReadStringBytesUntil(this BinaryReader br, byte end = 0)
|
||||
{
|
||||
StringBuilder str = new StringBuilder();
|
||||
StringBuilder str = new();
|
||||
byte b;
|
||||
while ((b = br.ReadByte()) != end)
|
||||
str.Append((char)b);
|
||||
|
||||
@@ -24,6 +24,7 @@ public class GFPack : IEnumerable<byte[]>, IFileContainer
|
||||
public byte[][] CompressedFiles { get; set; }
|
||||
public byte[][] DecompressedFiles { get; set; }
|
||||
|
||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
public GFPack(string path) : this(FileMitm.ReadAllBytes(path)) => FilePath = path;
|
||||
public GFPack(string[] directories, string parent = @"\bin") => LoadFiles(directories, parent);
|
||||
|
||||
@@ -39,6 +40,7 @@ public GFPack(byte[] data)
|
||||
}
|
||||
|
||||
public GFPack(BinaryReader br) => ReadPack(br);
|
||||
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
|
||||
private void ReadPack(BinaryReader br)
|
||||
{
|
||||
@@ -212,8 +214,7 @@ private static byte[] Decompress(byte[] encryptedData, int decryptedLength, Comp
|
||||
return type switch
|
||||
{
|
||||
CompressionType.None => encryptedData,
|
||||
CompressionType.Zlib => null // not implemented
|
||||
,
|
||||
CompressionType.Zlib => throw new NotSupportedException(nameof(CompressionType.Zlib)), // not implemented
|
||||
_ => LZ4.Decode(encryptedData, decryptedLength)
|
||||
};
|
||||
}
|
||||
@@ -223,8 +224,7 @@ private static byte[] Compress(byte[] decryptedData, CompressionType type)
|
||||
return type switch
|
||||
{
|
||||
CompressionType.None => decryptedData,
|
||||
CompressionType.Zlib => null // not implemented
|
||||
,
|
||||
CompressionType.Zlib => throw new NotSupportedException(nameof(CompressionType.Zlib)), // not implemented
|
||||
_ => LZ4.Encode(decryptedData)
|
||||
};
|
||||
}
|
||||
@@ -260,7 +260,7 @@ private void WriteHeaderTableList(BinaryWriter bw)
|
||||
bw.Write(ft.ToBytesClass());
|
||||
}
|
||||
|
||||
public string FilePath { get; set; }
|
||||
public string? FilePath { get; set; }
|
||||
public bool Modified { get; set; }
|
||||
public Task<byte[][]> GetFiles() => Task.FromResult(DecompressedFiles);
|
||||
public Task<byte[]> GetFile(int file, int subFile = 0) => Task.FromResult(this[file]);
|
||||
@@ -365,8 +365,8 @@ public class FileHashAbsolute
|
||||
|
||||
public class FileHashFolder
|
||||
{
|
||||
public FileHashFolderInfo Folder;
|
||||
public FileHashIndex[] Files;
|
||||
public FileHashFolderInfo Folder = new();
|
||||
public FileHashIndex[] Files = Array.Empty<FileHashIndex>();
|
||||
public int GetIndexFileName(ulong hash) => Array.FindIndex(Files, z => z.HashFnv1aPathFileName == hash);
|
||||
public int GetIndexFileName(string name) => Array.FindIndex(Files, z => z.IsMatch(name));
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ public class NSO
|
||||
public decimal CompressionRatioRO => (decimal)DecompressedRO.Length / CompressedRO.Length;
|
||||
public decimal CompressionRatioData => (decimal)DecompressedData.Length / CompressedData.Length;
|
||||
|
||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
public NSO(BinaryReader br) => ReadHeader(br);
|
||||
|
||||
public NSO(byte[] data)
|
||||
@@ -32,6 +33,7 @@ public NSO(byte[] data)
|
||||
using var br = new BinaryReader(ms);
|
||||
ReadHeader(br);
|
||||
}
|
||||
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
|
||||
private void ReadHeader(BinaryReader br)
|
||||
{
|
||||
|
||||
@@ -16,6 +16,7 @@ public class NSOHeader
|
||||
public uint Reserved;
|
||||
public NSOFlag Flags;
|
||||
|
||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
public SegmentHeader HeaderText;
|
||||
public int ModuleOffset;
|
||||
public SegmentHeader HeaderRO;
|
||||
@@ -46,4 +47,5 @@ public class NSOHeader
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
|
||||
public byte[] HashData;
|
||||
}
|
||||
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
}
|
||||
@@ -34,8 +34,10 @@ public SARC(IReadOnlyList<string> files, string baseFolder)
|
||||
Header = new SARCHeader();
|
||||
SFAT = new SFAT(baseFolder, files);
|
||||
SFNT = new SFNT();
|
||||
Files = new byte[]?[SFAT.Entries.Count];
|
||||
}
|
||||
|
||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
/// <summary>
|
||||
/// Initializes a <see cref="SARC"/> from a file location.
|
||||
/// </summary>
|
||||
@@ -53,12 +55,15 @@ public SARC(IReadOnlyList<string> files, string baseFolder)
|
||||
/// </summary>
|
||||
/// <param name="br"></param>
|
||||
public SARC(BinaryReader br) => OpenRead(br);
|
||||
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
|
||||
/// <summary>
|
||||
/// Reads the contents of the <see cref="SARC"/> header and file info tables.
|
||||
/// </summary>
|
||||
protected override void Initialize()
|
||||
{
|
||||
if (Reader is null)
|
||||
throw new NullReferenceException(nameof(Reader));
|
||||
Header = new SARCHeader(Reader);
|
||||
if (!SigMatches)
|
||||
return;
|
||||
@@ -83,8 +88,8 @@ private void PackSARC(BinaryWriter bw, ContainerHandler handler, CancellationTok
|
||||
{
|
||||
var entr = SFAT.Entries[i];
|
||||
if (entr.FileName == null)
|
||||
entr.GetFileName(Reader.BaseStream, (int)currentStringOffset);
|
||||
entr.WriteFileName(Reader.BaseStream, (int)SFNT.StringOffset);
|
||||
entr.GetFileName(Reader!.BaseStream, (int)currentStringOffset);
|
||||
entr.WriteFileName(Reader!.BaseStream, (int)SFNT.StringOffset);
|
||||
while (Reader.BaseStream.Position % 4 != 0)
|
||||
bw.Write((byte)0);
|
||||
}
|
||||
@@ -126,12 +131,12 @@ public override byte[] GetEntry(int index, int subFile)
|
||||
if (f.File is byte[] data)
|
||||
return data;
|
||||
|
||||
data = f.GetFileData(Reader.BaseStream);
|
||||
data = f.GetFileData(Reader!.BaseStream);
|
||||
f.File = data; // cache for future fetches
|
||||
return data;
|
||||
}
|
||||
|
||||
public override void Dump(string path, ContainerHandler handler)
|
||||
public override void Dump(string? path, ContainerHandler handler)
|
||||
{
|
||||
path ??= FilePath;
|
||||
if (path == null)
|
||||
@@ -149,12 +154,12 @@ public override void Dump(string path, ContainerHandler handler)
|
||||
handler.Initialize(count);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
SFAT.Entries[i].Dump(Reader.BaseStream, path, Header.DataOffset);
|
||||
SFAT.Entries[i].Dump(Reader!.BaseStream, path, Header.DataOffset);
|
||||
handler.StepFile(i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public static SARC GetSARC(BinaryReader br)
|
||||
public static SARC? GetSARC(BinaryReader br)
|
||||
{
|
||||
if (br.BaseStream.Length < 20)
|
||||
return null;
|
||||
|
||||
@@ -11,7 +11,7 @@ public class SFATEntry : LargeContainerEntry
|
||||
public uint FileNameHash;
|
||||
public int FileNameOffset;
|
||||
|
||||
public string FileName { get; private set; }
|
||||
public string? FileName { get; private set; }
|
||||
|
||||
private static uint GetHash(string name, int length, uint multiplier)
|
||||
{
|
||||
@@ -66,7 +66,7 @@ public void WriteFileName(Stream parent, int StringOffset)
|
||||
{
|
||||
FileNameOffset = (int)(parent.Position - StringOffset) / 4;
|
||||
|
||||
var str = FileName.Replace(Path.DirectorySeparatorChar, '/');
|
||||
var str = FileName?.Replace(Path.DirectorySeparatorChar, '/') ?? string.Empty;
|
||||
foreach (var b in str)
|
||||
parent.WriteByte((byte)b);
|
||||
parent.WriteByte(0); // \0
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.IO;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@@ -7,12 +8,12 @@ namespace pkNX.Containers
|
||||
{
|
||||
public class SingleFileContainer : IFileContainer
|
||||
{
|
||||
public string FilePath { get; set; }
|
||||
public string? FilePath { get; set; }
|
||||
public bool Modified { get; set; }
|
||||
public int Count => 1;
|
||||
|
||||
public byte[] Data;
|
||||
private byte[] Backup;
|
||||
public byte[] Data = Array.Empty<byte>();
|
||||
private byte[] Backup = Array.Empty<byte>();
|
||||
public SingleFileContainer(byte[] data) => LoadData(data);
|
||||
public SingleFileContainer(BinaryReader br) => LoadData(br.ReadBytes((int) br.BaseStream.Length));
|
||||
public SingleFileContainer(string path) => LoadData(FileMitm.ReadAllBytes(FilePath = path));
|
||||
@@ -39,6 +40,6 @@ public void CancelEdits()
|
||||
public Task<byte[]> GetFile(int file, int subFile = 0) => Task.FromResult(this[0]);
|
||||
public Task SetFile(int file, byte[] value, int subFile = 0) => Task.FromResult(Data = value);
|
||||
public Task SaveAs(string path, ContainerHandler handler, CancellationToken token) => new(() => Dump(path, handler), token);
|
||||
public void Dump(string path, ContainerHandler handler) => FileMitm.WriteAllBytes(path ?? FilePath, Data);
|
||||
public void Dump(string? path, ContainerHandler handler) => FileMitm.WriteAllBytes(path ?? FilePath!, Data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<TargetFrameworks>netstandard2.0;net46</TargetFrameworks>
|
||||
<Description>Packing & Unpacking</Description>
|
||||
<LangVersion>9</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -14,7 +14,7 @@ public FormRandomizer(PersonalTable t)
|
||||
Personal = t;
|
||||
}
|
||||
|
||||
public int GetRandomForme(int species, bool mega, bool fused, bool alola, bool galar, PersonalInfo[] stats = null)
|
||||
public int GetRandomForme(int species, bool mega, bool fused, bool alola, bool galar, PersonalInfo[]? stats = null)
|
||||
{
|
||||
stats ??= Personal.Table;
|
||||
if (stats[species].FormeCount <= 1)
|
||||
@@ -48,7 +48,7 @@ public int GetRandomForme(int species, bool mega, bool fused, bool alola, bool g
|
||||
case Darmanitan when galar:
|
||||
{
|
||||
int form = Util.Random.Next(stats[species].FormeCount);
|
||||
return form &= 2;
|
||||
return form & 2;
|
||||
}
|
||||
|
||||
// some species have 1 invalid form among several other valid forms, handle them here
|
||||
|
||||
@@ -14,9 +14,9 @@ public class LearnsetRandomizer : Randomizer
|
||||
private readonly GameInfo Game;
|
||||
private readonly PersonalTable Personal;
|
||||
private MoveRandomizer moverand;
|
||||
public IReadOnlyList<Move> Moves { private get; set; }
|
||||
public IReadOnlyList<Move> Moves { private get; set; } = Array.Empty<Move>();
|
||||
|
||||
public LearnSettings Settings { get; private set; }
|
||||
public LearnSettings Settings { get; private set; } = new();
|
||||
public IList<int> BannedMoves { set => moverand.Settings.BannedMoves = value; }
|
||||
|
||||
public LearnsetRandomizer(GameInfo game, Learnset[] learnsets, PersonalTable t)
|
||||
@@ -24,6 +24,9 @@ public LearnsetRandomizer(GameInfo game, Learnset[] learnsets, PersonalTable t)
|
||||
Game = game;
|
||||
Learnsets = learnsets;
|
||||
Personal = t;
|
||||
|
||||
// temp, overwrite later if using it
|
||||
moverand = new MoveRandomizer(game, Moves, Personal);
|
||||
}
|
||||
|
||||
private static readonly int[] MetronomeMove = { 118 };
|
||||
@@ -59,7 +62,7 @@ public void ExecuteExpandOnly()
|
||||
}
|
||||
}
|
||||
|
||||
public void Initialize(Move[] moves, LearnSettings settings, MovesetRandSettings moverandset, int[] bannedMoves = null)
|
||||
public void Initialize(Move[] moves, LearnSettings settings, MovesetRandSettings moverandset, int[]? bannedMoves = null)
|
||||
{
|
||||
Moves = moves;
|
||||
Settings = settings;
|
||||
|
||||
@@ -12,7 +12,7 @@ public class MoveRandomizer : Randomizer
|
||||
private readonly GameInfo Config;
|
||||
|
||||
private GenericRandomizer<int> RandMove;
|
||||
internal MovesetRandSettings Settings;
|
||||
internal MovesetRandSettings Settings = new();
|
||||
|
||||
public MoveRandomizer(GameInfo config, IReadOnlyList<Move> moves, PersonalTable t)
|
||||
{
|
||||
|
||||
@@ -17,7 +17,7 @@ public class PersonalRandomizer : Randomizer
|
||||
private readonly PersonalTable Table;
|
||||
private readonly EvolutionSet[] Evolutions;
|
||||
|
||||
public PersonalRandSettings Settings { get; set; }
|
||||
public PersonalRandSettings Settings { get; set; } = new();
|
||||
|
||||
public PersonalRandomizer(PersonalTable table, GameInfo game, EvolutionSet[] evolutions)
|
||||
{
|
||||
@@ -47,7 +47,7 @@ private void RandomizeAllSpecies()
|
||||
RandomizeSpecies(species);
|
||||
}
|
||||
|
||||
private bool[] processed;
|
||||
private bool[] processed = Array.Empty<bool>();
|
||||
|
||||
private void RandomizeChains()
|
||||
{
|
||||
@@ -61,9 +61,12 @@ private void RandomizeChains()
|
||||
|
||||
private bool AlreadyProcessed(int index)
|
||||
{
|
||||
if (processed[index])
|
||||
var p = processed;
|
||||
if (p.Length <= index)
|
||||
return false;
|
||||
if (p[index])
|
||||
return true;
|
||||
processed[index] = true;
|
||||
p[index] = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using pkNX.Structures;
|
||||
|
||||
namespace pkNX.Randomization
|
||||
@@ -9,7 +10,7 @@ public class SpeciesRandomizer
|
||||
private readonly int MaxSpeciesID;
|
||||
private readonly GameInfo Game;
|
||||
|
||||
private SpeciesSettings s;
|
||||
private SpeciesSettings s = new();
|
||||
|
||||
public SpeciesRandomizer(GameInfo game, PersonalTable t)
|
||||
{
|
||||
@@ -31,7 +32,7 @@ public void Initialize(SpeciesSettings settings, params int[] banlist)
|
||||
}
|
||||
|
||||
#region Random Species Filtering Parameters
|
||||
private GenericRandomizer<int> RandSpec;
|
||||
private GenericRandomizer<int> RandSpec = new(Array.Empty<int>());
|
||||
private int loopctr;
|
||||
private const int l = 10; // tweakable scalars
|
||||
private const int h = 11;
|
||||
|
||||
@@ -17,17 +17,19 @@ public class TrainerRandomizer : Randomizer
|
||||
private readonly IList<int> SpecialClasses;
|
||||
private readonly IList<int> CrashClasses;
|
||||
|
||||
public GenericRandomizer<int> Class { get; set; }
|
||||
public LearnsetRandomizer Learn { get; set; }
|
||||
public SpeciesRandomizer RandSpec { get; set; }
|
||||
public FormRandomizer RandForm { get; set; }
|
||||
public MoveRandomizer RandMove { get; set; }
|
||||
public int ClassCount { get; set; }
|
||||
public Func<TrainerPoke> GetBlank { get; set; }
|
||||
public EvolutionSet[] Evos { get; set; }
|
||||
public EvolutionSet[] Evos { get; }
|
||||
|
||||
private TrainerRandSettings Settings;
|
||||
private SpeciesSettings SpecSettings;
|
||||
// Set these before starting up
|
||||
public GenericRandomizer<int> Class { get; set; } = null!;
|
||||
public LearnsetRandomizer Learn { get; set; } = null!;
|
||||
public SpeciesRandomizer RandSpec { get; set; } = null!;
|
||||
public FormRandomizer RandForm { get; set; } = null!;
|
||||
public MoveRandomizer RandMove { get; set; } = null!;
|
||||
public Func<TrainerPoke> GetBlank { get; set; } = null!;
|
||||
|
||||
private TrainerRandSettings Settings = null!;
|
||||
private SpeciesSettings SpecSettings = null!;
|
||||
|
||||
public TrainerRandomizer(GameInfo info, PersonalTable t, VsTrainer[] trainers, EvolutionSet[] evos)
|
||||
{
|
||||
|
||||
@@ -28,15 +28,19 @@ public static void Shuffle<T>(IList<T> array)
|
||||
}
|
||||
}
|
||||
|
||||
public static int ToInt32(string value)
|
||||
public static int ToInt32(string? value)
|
||||
{
|
||||
string val = value?.Replace(" ", "").Replace("_", "").Trim();
|
||||
if (value is null)
|
||||
return 0;
|
||||
string val = value.Replace(" ", "").Replace("_", "").Trim();
|
||||
return string.IsNullOrWhiteSpace(val) ? 0 : int.Parse(val);
|
||||
}
|
||||
|
||||
public static uint ToUInt32(string value)
|
||||
public static uint ToUInt32(string? value)
|
||||
{
|
||||
string val = value?.Replace(" ", "").Replace("_", "").Trim();
|
||||
if (value is null)
|
||||
return 0;
|
||||
string val = value.Replace(" ", "").Replace("_", "").Trim();
|
||||
return string.IsNullOrWhiteSpace(val) ? 0 : uint.Parse(val);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<TargetFrameworks>netstandard2.0;net46</TargetFrameworks>
|
||||
<Description>Randomizer Utility</Description>
|
||||
<LangVersion>9</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -19,8 +19,6 @@ public static Bitmap LayerImage(Image baseLayer, Image overLayer, int x, int y,
|
||||
|
||||
public static Bitmap LayerImage(Image baseLayer, Image overLayer, int x, int y)
|
||||
{
|
||||
if (baseLayer is null)
|
||||
return (Bitmap)overLayer;
|
||||
Bitmap img = new(baseLayer);
|
||||
using Graphics gr = Graphics.FromImage(img);
|
||||
gr.DrawImage(overLayer, x, y, overLayer.Width, overLayer.Height);
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace pkNX.Structures
|
||||
using System;
|
||||
|
||||
namespace pkNX.Structures
|
||||
{
|
||||
/// <summary>
|
||||
/// Table of Evolution Branch Entries
|
||||
@@ -7,5 +9,7 @@ public abstract class EvolutionSet
|
||||
{
|
||||
public EvolutionMethod[] PossibleEvolutions;
|
||||
public abstract byte[] Write();
|
||||
|
||||
protected EvolutionSet() => PossibleEvolutions = Array.Empty<EvolutionMethod>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,12 @@ public abstract class Learnset
|
||||
public int[] Moves { get; protected set; }
|
||||
public int[] Levels { get; protected set; }
|
||||
|
||||
protected Learnset()
|
||||
{
|
||||
Moves = Array.Empty<int>();
|
||||
Levels = Array.Empty<int>();
|
||||
}
|
||||
|
||||
public abstract byte[] Write();
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace pkNX.Structures
|
||||
|
||||
@@ -89,8 +89,8 @@ private void UpdateRowImage(int row)
|
||||
dgv.Rows[row].Cells[0].Value = SpriteUtil.GetSprite(sp, form, 0, 0, false, false, false);
|
||||
}
|
||||
|
||||
private EncounterSlot7b[] Slots;
|
||||
public static string[] species;
|
||||
private EncounterSlot7b[]? Slots;
|
||||
public static string[] species = Array.Empty<string>();
|
||||
|
||||
public void LoadSlots(EncounterSlot7b[] slots)
|
||||
{
|
||||
|
||||
@@ -79,8 +79,8 @@ private void UpdateRowImage(int row)
|
||||
dgv.Rows[row].Cells[0].Value = SpriteUtil.GetSprite(sp, form, 0, 0, false, false, false);
|
||||
}
|
||||
|
||||
private EncounterSlot8[] Slots;
|
||||
public static string[] species;
|
||||
private EncounterSlot8[]? Slots;
|
||||
public static string[] species = Array.Empty<string>();
|
||||
|
||||
public void LoadSlots(EncounterSlot8[] slots)
|
||||
{
|
||||
|
||||
@@ -42,7 +42,7 @@ public EvolutionRow()
|
||||
|
||||
private void ChangeSpecies(int spec, int form) => PB_Preview.Image = SpriteUtil.GetSprite(spec, form, 0, 0, false, false, false);
|
||||
|
||||
private EvolutionMethod current;
|
||||
private EvolutionMethod? current;
|
||||
private EvolutionTypeArgumentType oldMethod;
|
||||
|
||||
public void LoadEvolution(EvolutionMethod s)
|
||||
@@ -58,6 +58,8 @@ public void LoadEvolution(EvolutionMethod s)
|
||||
public void SaveEvolution()
|
||||
{
|
||||
var evo = current;
|
||||
if (evo == null)
|
||||
return;
|
||||
evo.Species = CB_Species.SelectedIndex;
|
||||
evo.Form = (int)NUD_Form.Value;
|
||||
evo.Level = (int)NUD_Level.Value;
|
||||
@@ -65,10 +67,10 @@ public void SaveEvolution()
|
||||
evo.Argument = CB_Arg.SelectedIndex;
|
||||
}
|
||||
|
||||
public static string[] items;
|
||||
public static string[] movelist;
|
||||
public static string[] species;
|
||||
public static string[] types;
|
||||
public static string[] items = Array.Empty<string>();
|
||||
public static string[] movelist = Array.Empty<string>();
|
||||
public static string[] species = Array.Empty<string>();
|
||||
public static string[] types = Array.Empty<string>();
|
||||
|
||||
private static readonly string[] EvoMethods = Enum.GetNames(typeof(EvolutionType));
|
||||
private static readonly string[] Levels = Enumerable.Range(0, 100 + 1).Select(z => z.ToString()).ToArray();
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace pkNX.WinForms
|
||||
{
|
||||
public partial class MegaEvoEntry : UserControl
|
||||
{
|
||||
public static string[] items;
|
||||
public static string[] items = Array.Empty<string>();
|
||||
|
||||
private static readonly string[] EvoMethods = Enum.GetNames(typeof(MegaEvolutionMethod));
|
||||
|
||||
@@ -27,7 +27,7 @@ public MegaEvoEntry()
|
||||
}
|
||||
|
||||
public int Species { private get; set; }
|
||||
private MegaEvolutionSet current;
|
||||
private MegaEvolutionSet? current;
|
||||
|
||||
private void ChangeSpecies(int form)
|
||||
{
|
||||
@@ -47,6 +47,9 @@ public void LoadEvolution(MegaEvolutionSet s, int species)
|
||||
|
||||
public void SaveEvolution()
|
||||
{
|
||||
if (current == null)
|
||||
return;
|
||||
|
||||
if (CB_Method.SelectedIndex <= 0)
|
||||
{
|
||||
current.ToForm = 0;
|
||||
|
||||
@@ -26,9 +26,9 @@ public void Initialize(string[] types)
|
||||
UpdatingFields = false;
|
||||
}
|
||||
|
||||
public PersonalTable Personal { private get; set; }
|
||||
public PersonalTable? Personal { private get; set; }
|
||||
public bool UpdatingFields;
|
||||
public StatPKM PKM { get; set; }
|
||||
public StatPKM PKM { get; set; } = new TrainerPoke7b();
|
||||
|
||||
private readonly MaskedTextBox[] tb_iv;
|
||||
private readonly MaskedTextBox[] tb_ev;
|
||||
@@ -52,7 +52,11 @@ public void UpdateStats()
|
||||
}
|
||||
UpdatingFields = false;
|
||||
|
||||
var pi = Personal.GetFormeEntry(PKM.Species, PKM.Form);
|
||||
var pt = Personal;
|
||||
if (pt == null)
|
||||
throw new NullReferenceException("Personal table hasn't been initialized.");
|
||||
|
||||
var pi = pt.GetFormeEntry(PKM.Species, PKM.Form);
|
||||
var stats = PKM.GetStats(pi);
|
||||
|
||||
Stat_HP.Text = stats[0].ToString();
|
||||
|
||||
@@ -17,7 +17,7 @@ private int Language
|
||||
set => CB_Lang.SelectedIndex = value;
|
||||
}
|
||||
|
||||
private EditorBase Editor;
|
||||
private EditorBase? Editor;
|
||||
|
||||
public Main()
|
||||
{
|
||||
|
||||
@@ -20,7 +20,7 @@ public class SharedSettings
|
||||
|
||||
public static class EditUtil
|
||||
{
|
||||
public static SharedSettings Settings { get; set; }
|
||||
public static SharedSettings Settings { get; set; } = new();
|
||||
|
||||
public static void LoadSettings(GameVersion game)
|
||||
{
|
||||
@@ -35,7 +35,7 @@ public static void LoadSettings(GameVersion game)
|
||||
var reader = new XmlSerializer(typeof(SharedSettings));
|
||||
try
|
||||
{
|
||||
Settings = (SharedSettings) reader.Deserialize(file) ?? new SharedSettings();
|
||||
Settings = (SharedSettings?) reader.Deserialize(file) ?? new SharedSettings();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@@ -14,7 +14,7 @@ public abstract class EditorBase
|
||||
public int Language { get => ROM.Language; set => ROM.Language = value; }
|
||||
|
||||
protected EditorBase(GameManager rom) => ROM = rom;
|
||||
public string Location { get; internal set; }
|
||||
public string? Location { get; internal set; }
|
||||
|
||||
public IEnumerable<Button> GetControls(int width, int height)
|
||||
{
|
||||
@@ -41,7 +41,7 @@ public IEnumerable<Button> GetControls(int width, int height)
|
||||
|
||||
public void Close() => ROM.SaveAll(true);
|
||||
|
||||
private static EditorBase GetEditor(GameManager ROM)
|
||||
private static EditorBase? GetEditor(GameManager ROM)
|
||||
{
|
||||
var g = ROM.Game;
|
||||
if (GameVersion.XY.Contains(g)) return new EditorXY(ROM);
|
||||
@@ -55,13 +55,17 @@ private static EditorBase GetEditor(GameManager ROM)
|
||||
return null;
|
||||
}
|
||||
|
||||
public static EditorBase GetEditor(string loc, int language)
|
||||
public static EditorBase? GetEditor(string loc, int language)
|
||||
{
|
||||
var gl = GameLocation.GetGame(loc);
|
||||
if (gl == null)
|
||||
return null;
|
||||
GameManager gm = GameManager.GetManager(gl, language);
|
||||
EditorBase editor = GetEditor(gm);
|
||||
|
||||
var gm = GameManager.GetManager(gl, language);
|
||||
var editor = GetEditor(gm);
|
||||
if (editor == null)
|
||||
return null;
|
||||
|
||||
editor.Location = loc;
|
||||
return editor;
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ private static FileRipperResult GFPackDump(BinaryReader br, uint header, string
|
||||
return new FileRipperResult(RipResultCode.Success) {ResultPath = resultPath};
|
||||
}
|
||||
|
||||
public static FileRipperResult TryOpenFile(string path, ContainerHandler handler = null)
|
||||
public static FileRipperResult TryOpenFile(string path, ContainerHandler? handler = null)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
return new FileRipperResult(RipResultCode.FileExist);
|
||||
@@ -115,7 +115,7 @@ private static FileRipperResult TryLoadFile(BinaryReader br, uint header, string
|
||||
public class FileRipperResult
|
||||
{
|
||||
public readonly RipResultCode Code;
|
||||
public string ResultPath;
|
||||
public string? ResultPath;
|
||||
|
||||
public FileRipperResult(RipResultCode code) => Code = code;
|
||||
}
|
||||
|
||||
@@ -16,9 +16,12 @@ namespace pkNX.WinForms
|
||||
public partial class BTTE : Form
|
||||
{
|
||||
private readonly LearnsetRandomizer learn;
|
||||
private string[][] AltForms;
|
||||
private readonly string[][] AltForms;
|
||||
private readonly PictureBox[] pba;
|
||||
|
||||
private int entry = -1;
|
||||
private PictureBox[] pba;
|
||||
private TrainerPoke pkm = new TrainerPoke7b();
|
||||
private bool loadingPKM;
|
||||
|
||||
private readonly PersonalTable Personal;
|
||||
private readonly GameManager Game;
|
||||
@@ -38,12 +41,16 @@ public partial class BTTE : Form
|
||||
public BTTE(GameManager game, TrainerEditor editor)
|
||||
{
|
||||
InitializeComponent();
|
||||
pba = new[] { PB_Team1, PB_Team2, PB_Team3, PB_Team4, PB_Team5, PB_Team6 };
|
||||
|
||||
Stats.Personal = Personal = game.Data.PersonalData;
|
||||
Game = game;
|
||||
Trainers = editor;
|
||||
learn = new LearnsetRandomizer(game.Info, game.Data.LevelUpData.LoadAll(), Personal);
|
||||
|
||||
AltForms = new byte[Personal.TableLength]
|
||||
.Select(_ => Enumerable.Range(0, 32).Select(i => i.ToString()).ToArray()).ToArray();
|
||||
|
||||
trClass = Game.GetStrings(TextName.TrainerClasses);
|
||||
trName = Game.GetStrings(TextName.TrainerClasses);
|
||||
|
||||
@@ -225,11 +232,9 @@ private void RefreshPKMSlotAbility()
|
||||
|
||||
private void Setup()
|
||||
{
|
||||
AltForms = new byte[Personal.TableLength]
|
||||
.Select(_ => Enumerable.Range(0, 32).Select(i => i.ToString()).ToArray()).ToArray();
|
||||
CB_TrainerID.Items.Clear();
|
||||
for (int i = 0; i < Trainers.Length; i++)
|
||||
CB_TrainerID.Items.Add(GetEntryTitle(trName[i] ?? "UNKNOWN", i));
|
||||
CB_TrainerID.Items.Add(GetEntryTitle(trName[i], i));
|
||||
|
||||
CB_Trainer_Class.Items.Clear();
|
||||
for (int i = 0; i < trClass.Length; i++)
|
||||
@@ -237,7 +242,6 @@ private void Setup()
|
||||
|
||||
specieslist[0] = "---";
|
||||
abilitylist[0] = itemlist[0] = movelist[0] = "(None)";
|
||||
pba = new[] {PB_Team1, PB_Team2, PB_Team3, PB_Team4, PB_Team5, PB_Team6};
|
||||
|
||||
CB_Species.Items.AddRange(specieslist);
|
||||
|
||||
@@ -270,7 +274,6 @@ private void Setup()
|
||||
|
||||
CB_TrainerID.SelectedIndex = 0;
|
||||
entry = 0;
|
||||
pkm = new TrainerPoke7b();
|
||||
PopulateFields(pkm);
|
||||
}
|
||||
|
||||
@@ -312,10 +315,6 @@ private void UpdateTrainerName(object sender, EventArgs e)
|
||||
CB_TrainerID.Items[entry] = GetEntryTitle(str, entry);
|
||||
}
|
||||
|
||||
private TrainerPoke pkm;
|
||||
|
||||
private bool loadingPKM;
|
||||
|
||||
private void PopulateFields(TrainerPoke pk)
|
||||
{
|
||||
pkm = pk.Clone();
|
||||
|
||||
@@ -18,7 +18,7 @@ public sealed partial class GGWE : Form
|
||||
public GGWE(GameManager rom, EncounterArchive7b obj)
|
||||
{
|
||||
InitializeComponent();
|
||||
if (obj?.EncounterTables?[0]?.GroundTable == null)
|
||||
if (obj.EncounterTables.Length == 0 || obj.EncounterTables[0].GroundTable.Length == 0)
|
||||
{
|
||||
WinFormsUtil.Error("Bad data provided.", $"Unable to parse to {nameof(EncounterArchive7b)} data.");
|
||||
Close();
|
||||
@@ -80,7 +80,7 @@ private static IEnumerable<string> GetNames(IEnumerable<ulong> locs, string[] lo
|
||||
private static IEnumerable<string> GetScreenedNames(IEnumerable<string> names)
|
||||
{
|
||||
int ctr = 0;
|
||||
string prev = null;
|
||||
string? prev = null;
|
||||
foreach (var name in names)
|
||||
{
|
||||
if (name != prev)
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace pkNX.WinForms
|
||||
{
|
||||
public sealed partial class GenericEditor<T> : Form where T : class
|
||||
{
|
||||
public GenericEditor(DataCache<T> cache, string[] names, string title, Action randomize = null)
|
||||
public GenericEditor(DataCache<T> cache, string[] names, string title, Action? randomize = null)
|
||||
{
|
||||
InitializeComponent();
|
||||
Cache = cache;
|
||||
|
||||
@@ -14,6 +14,8 @@ namespace pkNX.WinForms
|
||||
{
|
||||
public partial class PokeDataUI : Form
|
||||
{
|
||||
private readonly bool Loaded;
|
||||
|
||||
public PokeDataUI(PokeEditor editor, GameManager rom)
|
||||
{
|
||||
ROM = rom;
|
||||
@@ -36,6 +38,10 @@ public PokeDataUI(PokeEditor editor, GameManager rom)
|
||||
abilities[0] = items[0] = movelist[0] = "";
|
||||
|
||||
var pt = ROM.Data.PersonalData;
|
||||
cPersonal = pt[0];
|
||||
cLearnset = Editor.Learn[0];
|
||||
cEvos = Editor.Evolve[0];
|
||||
cMega = Editor.Mega.Length > 0 ? Editor.Mega[0] : Array.Empty<MegaEvolutionSet>();
|
||||
|
||||
var altForms = pt.GetFormList(species, pt.MaxSpeciesID);
|
||||
entryNames = pt.GetPersonalEntryList(altForms, species, pt.MaxSpeciesID, out baseForms, out formVal);
|
||||
@@ -45,10 +51,10 @@ public PokeDataUI(PokeEditor editor, GameManager rom)
|
||||
|
||||
InitEvo(Editor.Evolve[0].PossibleEvolutions.Length);
|
||||
|
||||
if (Editor.Mega != null)
|
||||
InitMega(2);
|
||||
Megas = Editor.Mega != null ? InitMega(2) : Array.Empty<MegaEvoEntry>();
|
||||
|
||||
CB_Species.SelectedIndex = 1;
|
||||
Loaded = true;
|
||||
|
||||
PG_Personal.SelectedObject = EditUtil.Settings.Personal;
|
||||
PG_Evolution.SelectedObject = EditUtil.Settings.Species;
|
||||
@@ -78,6 +84,7 @@ public PokeDataUI(PokeEditor editor, GameManager rom)
|
||||
public Learnset cLearnset;
|
||||
public EvolutionSet cEvos;
|
||||
public MegaEvolutionSet[] cMega;
|
||||
private readonly MegaEvoEntry[] Megas;
|
||||
|
||||
public void InitPersonal()
|
||||
{
|
||||
@@ -138,7 +145,7 @@ public void InitLearn()
|
||||
dgvLevel.Width = 45;
|
||||
dgvLevel.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
|
||||
}
|
||||
DataGridViewComboBoxColumn dgvMove = new DataGridViewComboBoxColumn();
|
||||
DataGridViewComboBoxColumn dgvMove = new();
|
||||
{
|
||||
dgvMove.HeaderText = "Move";
|
||||
dgvMove.DisplayIndex = 1;
|
||||
@@ -152,7 +159,7 @@ public void InitLearn()
|
||||
dgv.Columns.Add(dgvMove);
|
||||
}
|
||||
|
||||
private static EvolutionRow[] EvoRows;
|
||||
private static EvolutionRow[] EvoRows = Array.Empty<EvolutionRow>();
|
||||
|
||||
public void InitEvo(int rows)
|
||||
{
|
||||
@@ -171,24 +178,24 @@ public void InitEvo(int rows)
|
||||
}
|
||||
}
|
||||
|
||||
private MegaEvoEntry[] Megas;
|
||||
|
||||
public void InitMega(int count)
|
||||
public MegaEvoEntry[] InitMega(int count)
|
||||
{
|
||||
Megas = new MegaEvoEntry[count];
|
||||
var result = new MegaEvoEntry[count];
|
||||
MegaEvoEntry.items = items;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var row = new MegaEvoEntry();
|
||||
flowLayoutPanel1.Controls.Add(row);
|
||||
Megas[i] = row;
|
||||
result[i] = row;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void UpdateIndex(object sender, EventArgs e)
|
||||
{
|
||||
if (cPersonal != null)
|
||||
if (Loaded)
|
||||
SaveCurrent();
|
||||
LoadIndex(CB_Species.SelectedIndex);
|
||||
}
|
||||
@@ -205,7 +212,7 @@ private void LoadIndex(int index)
|
||||
if (Editor.Mega != null)
|
||||
LoadMegas(Editor.Mega[index], spec);
|
||||
Bitmap rawImg = (Bitmap)SpriteUtil.GetSprite(spec, form, 0, 0, false, false, false);
|
||||
Bitmap bigImg = new Bitmap(rawImg.Width * 2, rawImg.Height * 2);
|
||||
Bitmap bigImg = new(rawImg.Width * 2, rawImg.Height * 2);
|
||||
for (int x = 0; x < rawImg.Width; x++)
|
||||
{
|
||||
for (int y = 0; y < rawImg.Height; y++)
|
||||
@@ -403,8 +410,8 @@ public void LoadLearnset(Learnset pkm)
|
||||
public void SaveLearnset()
|
||||
{
|
||||
var pkm = cLearnset;
|
||||
List<int> moves = new List<int>();
|
||||
List<int> levels = new List<int>();
|
||||
List<int> moves = new();
|
||||
List<int> levels = new();
|
||||
for (int i = 0; i < dgv.Rows.Count - 1; i++)
|
||||
{
|
||||
int move = Array.IndexOf(movelist, dgv.Rows[i].Cells[1].Value);
|
||||
|
||||
@@ -232,10 +232,10 @@ private void TC_Tables_DrawItem(object sender, DrawItemEventArgs e)
|
||||
}
|
||||
|
||||
// Use our own font.
|
||||
Font _tabFont = new Font("Arial", (float)10.0, FontStyle.Bold, GraphicsUnit.Pixel);
|
||||
Font _tabFont = new("Arial", (float)10.0, FontStyle.Bold, GraphicsUnit.Pixel);
|
||||
|
||||
// Draw string. Center the text.
|
||||
StringFormat _stringFlags = new StringFormat
|
||||
StringFormat _stringFlags = new()
|
||||
{
|
||||
Alignment = StringAlignment.Center,
|
||||
LineAlignment = StringAlignment.Center
|
||||
|
||||
@@ -26,8 +26,8 @@ public ShinyRate(ShinyRateInfo info)
|
||||
RB_Default.Checked = true;
|
||||
|
||||
// force update labels
|
||||
ChangePercent(null, null);
|
||||
ChangeRerollCount(null, null);
|
||||
ChangePercent(this, EventArgs.Empty);
|
||||
ChangeRerollCount(this, EventArgs.Empty);
|
||||
Loaded = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ public TMList(ushort[] moves, int[] allowed, string[] movenames)
|
||||
}
|
||||
|
||||
public bool Modified { get; set; }
|
||||
public ushort[] FinalMoves { get; private set; }
|
||||
public ushort[] FinalMoves { get; private set; } = Array.Empty<ushort>();
|
||||
|
||||
private void SetupDGV(string[] list)
|
||||
{
|
||||
|
||||
@@ -7,12 +7,12 @@ namespace pkNX.WinForms
|
||||
public class TextContainer
|
||||
{
|
||||
public readonly IFileContainer Container;
|
||||
public readonly TextConfig Config;
|
||||
public readonly TextConfig? Config;
|
||||
public bool Remap { get; set; }
|
||||
|
||||
private readonly string[][] Cache;
|
||||
private readonly string[]?[] Cache;
|
||||
|
||||
public TextContainer(IFileContainer c, TextConfig t = null, bool remap = false)
|
||||
public TextContainer(IFileContainer c, TextConfig? t = null, bool remap = false)
|
||||
{
|
||||
Remap = remap;
|
||||
Config = t;
|
||||
|
||||
@@ -60,13 +60,13 @@ private void B_Import_Click(object sender, EventArgs e)
|
||||
return;
|
||||
|
||||
// Reload the form with the new data.
|
||||
ChangeEntry(null, null);
|
||||
ChangeEntry(this, e);
|
||||
WinFormsUtil.Alert("Imported Text from Input Path:", path);
|
||||
}
|
||||
|
||||
public static void ExportTextFile(string fileName, bool newline, TextContainer lineData)
|
||||
{
|
||||
using MemoryStream ms = new MemoryStream();
|
||||
using MemoryStream ms = new();
|
||||
ms.Write(new byte[] {0xFF, 0xFE}, 0, 2); // Write Unicode BOM
|
||||
using (TextWriter tw = new StreamWriter(ms, new UnicodeEncoding()))
|
||||
{
|
||||
@@ -88,7 +88,6 @@ private static void WriteTextFile(TextWriter tw, string fn, string[] data, bool
|
||||
tw.WriteLine("Text File : " + fn);
|
||||
tw.WriteLine("~~~~~~~~~~~~~~~");
|
||||
// Write the String to the File
|
||||
if (data == null) return;
|
||||
foreach (string line in data)
|
||||
{
|
||||
tw.WriteLine(newline
|
||||
@@ -130,7 +129,7 @@ private bool ImportTextFiles(string fileName)
|
||||
// else pray that the filename index lines up
|
||||
|
||||
i += 2; // Skip over the other header line
|
||||
List<string> Lines = new List<string>();
|
||||
List<string> Lines = new();
|
||||
while (i < fileText.Length && fileText[i] != "~~~~~~~~~~~~~~~")
|
||||
{
|
||||
Lines.Add(fileText[i]);
|
||||
@@ -166,7 +165,7 @@ private bool ImportTextFiles(string fileName)
|
||||
private void ChangeEntry(object sender, EventArgs e)
|
||||
{
|
||||
// Save All the old text
|
||||
if (entry > -1 && sender != null)
|
||||
if (entry > -1 && sender != this)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -189,7 +188,7 @@ private void SetStringsDataGridView(string[] textArray)
|
||||
dgv.Rows.Clear();
|
||||
// Clear the header columns, these are repopulated every time.
|
||||
dgv.Columns.Clear();
|
||||
if (textArray == null || textArray.Length == 0)
|
||||
if (textArray.Length == 0)
|
||||
return;
|
||||
// Reset settings and columns.
|
||||
dgv.AllowUserToResizeColumns = false;
|
||||
@@ -203,7 +202,7 @@ private void SetStringsDataGridView(string[] textArray)
|
||||
};
|
||||
dgvLine.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
|
||||
|
||||
DataGridViewTextBoxColumn dgvText = new DataGridViewTextBoxColumn
|
||||
DataGridViewTextBoxColumn dgvText = new()
|
||||
{
|
||||
HeaderText = "Text",
|
||||
DisplayIndex = 1,
|
||||
@@ -310,7 +309,7 @@ private void B_Randomize_Click(object sender, EventArgs e)
|
||||
int end = all ? TextData.Length - 1 : entry;
|
||||
|
||||
// Gather strings
|
||||
List<string> strings = new List<string>();
|
||||
List<string> strings = new();
|
||||
for (int i = start; i <= end; i++)
|
||||
{
|
||||
string[] data = TextData[i];
|
||||
|
||||
@@ -35,6 +35,6 @@ internal static DialogResult Prompt(MessageBoxButtons btn, params string[] lines
|
||||
/// Gets the selected value of the input <see cref="cb"/>. If no value is selected, will return 0.
|
||||
/// </summary>
|
||||
/// <param name="cb">ComboBox to retrieve value for.</param>
|
||||
internal static int GetIndex(ComboBox cb) => (int)(cb?.SelectedValue ?? 0);
|
||||
internal static int GetIndex(ComboBox cb) => (int)(cb.SelectedValue ?? 0);
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@
|
||||
<StartupObject>pkNX.WinForms.Program</StartupObject>
|
||||
<AssemblyName>pkNX</AssemblyName>
|
||||
<LangVersion>9</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user