Add IStringConverter, impl on PKM & SaveFile

use in trash editor to translate strings, from PKM instead of SAV.
Closes #4222
This commit is contained in:
Kurt
2024-04-23 00:57:17 -05:00
parent 394f5ed707
commit 093264bc24
45 changed files with 257 additions and 121 deletions

View File

@@ -12,6 +12,7 @@ public sealed class FakeSaveFile : SaveFile
public override string ChecksumInfo => string.Empty;
public override byte Generation => 3;
public override string GetString(ReadOnlySpan<byte> data) => string.Empty;
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer) => 0;
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option) => 0;
public override PersonalTable3 Personal => PersonalTable.RS;
public override int MaxEV => 0;

View File

@@ -301,4 +301,11 @@ public PK4 ConvertToPK4()
pk4.RefreshChecksum();
return pk4;
}
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter4.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter4.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter4.SetString(destBuffer, value, maxLength, option);
}

View File

@@ -228,4 +228,11 @@ public PK3 ConvertToPK3()
pk.RefreshChecksum();
return pk;
}
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter3GC.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter3GC.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter3GC.SetString(destBuffer, value, maxLength, option);
}

View File

@@ -423,4 +423,11 @@ private void EnsureScaleSizeExists()
WeightScalar = PokeSizeUtil.GetRandomScalar(rnd);
}
}
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter8.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter8.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter8.SetString(destBuffer, value, maxLength, option);
}

View File

@@ -582,7 +582,6 @@ public bool BelongsTo(ITrainerInfo tr)
return tr.OT == OriginalTrainerName;
}
public void UpdateHandler(ITrainerInfo tr)
{
// Process to the HT if the OT of the Pokémon does not match the SAV's OT info.
@@ -734,4 +733,11 @@ public void SetMasteryFlagMove(ushort move)
if (permit.IsRecordPermitted(flagIndex))
SetMasteredRecordFlag(flagIndex, true);
}
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter8.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter8.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter8.SetString(destBuffer, value, maxLength, option);
}

View File

@@ -6,7 +6,7 @@ namespace PKHeX.Core;
/// <summary> Generation 7 <see cref="PKM"/> format used for <see cref="GameVersion.GG"/>. </summary>
public sealed class PB7 : G6PKM, IHyperTrain, IAwakened, IScaledSizeValue, ICombatPower, IFavorite,
IFormArgument, IAppliedMarkings7, IHandlerUpdate
IFormArgument, IAppliedMarkings7
{
public override ReadOnlySpan<ushort> ExtraBytes =>
[
@@ -581,4 +581,11 @@ public static int GetRandomIndex(int bits, int characterIndex, Nature nature)
5 => 4,
_ => throw new ArgumentOutOfRangeException(nameof(characterIndex)), // never happens, characteristic is always 0-29
};
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter8.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter8.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter8.SetString(destBuffer, value, maxLength, option);
}

View File

@@ -146,4 +146,11 @@ private void TradeHT(ITrainerInfo tr)
public override bool WasEgg => IsEgg || EggDay != 0;
public override bool HasOriginalMetLocation => base.HasOriginalMetLocation && !(LA && MetLocation == LocationsHOME.SWLA);
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter8.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter8.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter8.SetString(destBuffer, value, maxLength, option);
}

View File

@@ -248,16 +248,12 @@ private string GetTransferTrainerName(int lang)
return StringConverter12Transporter.GetString(OriginalTrainerTrash, Japanese);
}
protected override string GetString(ReadOnlySpan<byte> data)
{
return StringConverter1.GetString(data, Japanese);
}
protected override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength,
StringConverterOption option = StringConverterOption.None)
{
return StringConverter1.SetString(destBuffer, value, maxLength, Japanese, option);
}
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter1.GetString(data, Japanese);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter1.LoadString(data, destBuffer, Japanese);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option = StringConverterOption.None)
=> StringConverter1.SetString(destBuffer, value, maxLength, Japanese, option);
/// <summary>
/// Gets a checksum over all the entity's data using a single list to wrap all components.

View File

@@ -259,15 +259,21 @@ public SK2 ConvertToSK2() => new(Japanese)
OriginalTrainerName = OriginalTrainerName,
};
protected override string GetString(ReadOnlySpan<byte> data)
public override string GetString(ReadOnlySpan<byte> data)
{
if (Korean)
return StringConverter2KOR.GetString(data);
return StringConverter2.GetString(data, Language);
}
protected override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength,
StringConverterOption option = StringConverterOption.None)
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
{
if (Korean)
return StringConverter2KOR.LoadString(data, destBuffer);
return StringConverter2.LoadString(data, destBuffer, Language);
}
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
{
if (Korean)
return StringConverter2KOR.SetString(destBuffer, value, maxLength, option);

View File

@@ -353,4 +353,11 @@ public CK3 ConvertToCK3()
pk.ResetPartyStats();
return pk;
}
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter3.GetString(data, Language);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter3.LoadString(data, destBuffer, Language);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter3.SetString(destBuffer, value, maxLength, Language, option);
}

View File

@@ -383,4 +383,11 @@ public static void TransferTrash(ReadOnlySpan<byte> src, Span<byte> dest)
StringConverter345.TransferGlyphs45(temp[..len]);
StringConverter5.SetString(dest, temp[..len], len);
}
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter4.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter4.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter4.SetString(destBuffer, value, maxLength, option);
}

View File

@@ -552,4 +552,11 @@ internal static ushort GetTransferMetLocation4(PKM pk)
_ => Locations.Transfer4,
};
}
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter5.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter5.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter5.SetString(destBuffer, value, maxLength, option);
}

View File

@@ -523,4 +523,11 @@ public PK7 ConvertToPK7()
return pk7; // Done!
}
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter6.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter6.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter6.SetString(destBuffer, value, maxLength, option);
}

View File

@@ -547,6 +547,13 @@ internal void SetTransferPID(bool isShiny)
break;
}
}
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter7.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter7.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter7.SetString(destBuffer, value, maxLength, Language);
}
public enum ResortEventState : byte

View File

@@ -129,4 +129,11 @@ private void TradeHT(ITrainerInfo tr)
public override bool BDSP => MetLocation is LocationsHOME.SWBD or LocationsHOME.SHSP;
public override bool LA => MetLocation is LocationsHOME.SWLA;
public override bool HasOriginalMetLocation => base.HasOriginalMetLocation && !(BDSP || LA);
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter8.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter8.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter8.SetString(destBuffer, value, maxLength, option);
}

View File

@@ -681,4 +681,11 @@ private void TradeHT(ITrainerInfo tr)
public override int MaxItemID => Legal.MaxItemID_9;
public override int MaxBallID => Legal.MaxBallID_9;
public override GameVersion MaxGameID => Legal.MaxGameID_HOME;
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter8.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter8.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter8.SetString(destBuffer, value, maxLength, option);
}

View File

@@ -11,7 +11,7 @@ namespace PKHeX.Core;
/// Object representing a <see cref="PKM"/>'s data and derived properties.
/// </summary>
[DynamicallyAccessedMembers(PublicProperties | NonPublicProperties | PublicParameterlessConstructor)]
public abstract class PKM : ISpeciesForm, ITrainerID32, IGeneration, IShiny, ILangNick, IGameValueLimit, INature, IFatefulEncounter
public abstract class PKM : ISpeciesForm, ITrainerID32, IGeneration, IShiny, ILangNick, IGameValueLimit, INature, IFatefulEncounter, IStringConverter
{
/// <summary>
/// Valid file extensions that represent <see cref="PKM"/> data, without the leading '.'
@@ -148,6 +148,10 @@ private byte[] Write()
public virtual byte Fullness { get => 0; set { } }
public virtual int AbilityNumber { get => 0; set { } }
public abstract string GetString(ReadOnlySpan<byte> data);
public abstract int LoadString(ReadOnlySpan<byte> data, Span<char> text);
public abstract int SetString(Span<byte> data, ReadOnlySpan<char> text, int length, StringConverterOption option);
/// <summary>
/// The date the Pokémon was met.
/// </summary>

View File

@@ -345,4 +345,11 @@ public PK4 ConvertToPK4()
pk4.RefreshChecksum();
return pk4;
}
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter4.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter4.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter4.SetString(destBuffer, value, maxLength, option);
}

View File

@@ -212,4 +212,11 @@ private static bool IsEnglish(ReadOnlySpan<byte> data)
public bool IsPossible(bool japanese) => japanese ? IsJapanese(Data) : IsEnglish(Data);
public void SwapLanguage() => IsEncodingJapanese ^= true;
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter2.GetString(data, Language);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter2.LoadString(data, destBuffer, Language);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter2.SetString(destBuffer, value, maxLength, Language, option);
}

View File

@@ -61,11 +61,6 @@ protected override void GetNonNickname(int language, Span<byte> data)
}
}
protected abstract string GetString(ReadOnlySpan<byte> data);
protected abstract int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength,
StringConverterOption option = StringConverterOption.None);
public sealed override string Nickname
{
get => GetString(NicknameTrash);

View File

@@ -0,0 +1,10 @@
using System;
namespace PKHeX.Core;
public interface IStringConverter
{
string GetString(ReadOnlySpan<byte> data);
int LoadString(ReadOnlySpan<byte> data, Span<char> text);
int SetString(Span<byte> data, ReadOnlySpan<char> text, int length, StringConverterOption option);
}

View File

@@ -232,4 +232,11 @@ public PK3 ConvertToPK3()
90 or 91 or 92 => true, // Pokespot: Rock / Oasis / Cave
_ => false,
};
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter3GC.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter3GC.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter3GC.SetString(destBuffer, value, maxLength, option);
}

View File

@@ -547,10 +547,10 @@ public bool[] EventSpawnFlags
}
}
public override string GetString(ReadOnlySpan<byte> data) => StringConverter1.GetString(data, Japanese);
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter1.GetString(data, Japanese);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter1.LoadString(data, destBuffer, Japanese);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
{
return StringConverter1.SetString(destBuffer, value, maxLength, Japanese, option);
}
=> StringConverter1.SetString(destBuffer, value, maxLength, Japanese, option);
}

View File

@@ -580,15 +580,8 @@ public override int PartyCount
get => Data[Offsets.Party]; protected set => Data[Offsets.Party] = (byte)value;
}
public override int GetBoxOffset(int box)
{
return (box * SIZE_BOX_AS_SINGLES);
}
public override int GetPartyOffset(int slot)
{
return (BoxCount * SIZE_BOX_AS_SINGLES) + (slot * SIZE_STORED);
}
public override int GetBoxOffset(int box) => box * SIZE_BOX_AS_SINGLES;
public override int GetPartyOffset(int slot) => (BoxCount * SIZE_BOX_AS_SINGLES) + (slot * SIZE_STORED);
public override int CurrentBox
{
@@ -801,6 +794,13 @@ public override string GetString(ReadOnlySpan<byte> data)
return StringConverter2.GetString(data, Language);
}
public override int LoadString(ReadOnlySpan<byte> data, Span<char> text)
{
if (Korean)
return StringConverter2KOR.LoadString(data, text);
return StringConverter2.LoadString(data, text, Language);
}
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
{
if (Korean)

View File

@@ -600,12 +600,12 @@ public byte PokedexNationalMagicFRLG
public abstract bool NationalDex { get; set; }
#endregion
public sealed override string GetString(ReadOnlySpan<byte> data) => StringConverter3.GetString(data, Japanese);
public sealed override string GetString(ReadOnlySpan<byte> data)
=> StringConverter3.GetString(data, Japanese);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter3.LoadString(data, destBuffer, Japanese);
public sealed override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
{
return StringConverter3.SetString(destBuffer, value, maxLength, Japanese, option);
}
=> StringConverter3.SetString(destBuffer, value, maxLength, Japanese, option);
protected abstract int MailOffset { get; }
public int GetMailOffset(int index) => (index * Mail3.SIZE) + MailOffset;

View File

@@ -288,10 +288,10 @@ public override IReadOnlyList<InventoryPouch> Inventory
public void SetDaycareEXP(int index, uint value) => WriteUInt32BigEndian(Data[(DaycareOffset + 4)..], value);
public Memory<byte> GetDaycareSlot(int slot) => Raw.Slice(DaycareOffset + 8, PokeCrypto.SIZE_3CSTORED);
public override string GetString(ReadOnlySpan<byte> data) => StringConverter3GC.GetString(data);
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter3GC.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter3GC.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
{
return StringConverter3GC.SetString(destBuffer, value, maxLength, option);
}
=> StringConverter3GC.SetString(destBuffer, value, maxLength, option);
}

View File

@@ -207,10 +207,10 @@ public override void WriteBoxSlot(PKM pk, Span<byte> data)
WriteUInt16LittleEndian(data[(PokeCrypto.SIZE_3STORED + 2)..], pk.SID16);
}
public override string GetString(ReadOnlySpan<byte> data) => StringConverter3.GetString(data, Japanese);
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter3.GetString(data, Japanese);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter3.LoadString(data, destBuffer, Japanese);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
{
return StringConverter3.SetString(destBuffer, value, maxLength, Japanese, option);
}
=> StringConverter3.SetString(destBuffer, value, maxLength, Japanese, option);
}

View File

@@ -452,10 +452,10 @@ public override IReadOnlyList<InventoryPouch> Inventory
public void SetDaycareEXP(int index, uint value) => WriteUInt32BigEndian(Data.AsSpan(DaycareOffset + 4), value);
public Memory<byte> GetDaycareSlot(int slot) => Data.AsMemory(DaycareOffset + 8, PokeCrypto.SIZE_3XSTORED);
public override string GetString(ReadOnlySpan<byte> data) => StringConverter3GC.GetString(data);
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter3GC.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter3GC.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
{
return StringConverter3GC.SetString(destBuffer, value, maxLength, option);
}
=> StringConverter3GC.SetString(destBuffer, value, maxLength, option);
}

View File

@@ -478,12 +478,12 @@ public int DexUpgraded
}
}
public sealed override string GetString(ReadOnlySpan<byte> data) => StringConverter4.GetString(data);
public sealed override string GetString(ReadOnlySpan<byte> data)
=> StringConverter4.GetString(data);
public sealed override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter4.LoadString(data, destBuffer);
public sealed override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
{
return StringConverter4.SetString(destBuffer, value, maxLength, option);
}
=> StringConverter4.SetString(destBuffer, value, maxLength, option);
#region Event Flag/Event Work
public bool GetEventFlag(int flagNumber)

View File

@@ -367,7 +367,10 @@ private static void ComputeChecksums(Span<byte> span, Span<uint> checksums)
}
}
public override string GetString(ReadOnlySpan<byte> data) => StringConverter4GC.GetStringUnicode(data);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option) => StringConverter4GC.SetStringUnicode(value, destBuffer, maxLength, option);
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter4GC.GetStringUnicode(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter4GC.LoadStringUnicode(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter4GC.SetStringUnicode(value, destBuffer, maxLength, option);
}

View File

@@ -117,12 +117,12 @@ protected override void SetPKM(PKM pk, bool isParty = false)
public override bool GetCaught(ushort species) => Zukan.GetCaught(species);
public override bool GetSeen(ushort species) => Zukan.GetSeen(species);
public sealed override string GetString(ReadOnlySpan<byte> data) => StringConverter5.GetString(data);
public sealed override string GetString(ReadOnlySpan<byte> data)
=> StringConverter5.GetString(data);
public sealed override int LoadString(ReadOnlySpan<byte> data, Span<char> result)
=> StringConverter5.LoadString(data, result);
public sealed override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
{
return StringConverter5.SetString(destBuffer, value, maxLength, option);
}
=> StringConverter5.SetString(destBuffer, value, maxLength, option);
// DLC
private int CGearSkinInfoOffset => CGearInfoOffset + (this is SAV5B2W2 ? 0x10 : 0) + 0x24;

View File

@@ -138,12 +138,12 @@ public override int PartyCount
protected set => Data[Party + (6 * SIZE_PARTY)] = (byte)value;
}
public sealed override string GetString(ReadOnlySpan<byte> data) => StringConverter6.GetString(data);
public sealed override string GetString(ReadOnlySpan<byte> data)
=> StringConverter6.GetString(data);
public sealed override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter6.LoadString(data, destBuffer);
public sealed override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
{
return StringConverter6.SetString(destBuffer, value, maxLength, option);
}
=> StringConverter6.SetString(destBuffer, value, maxLength, option);
public int GetRecord(int recordID) => Records.GetRecord(recordID);
public int GetRecordOffset(int recordID) => Records.GetRecordOffset(recordID);

View File

@@ -109,12 +109,12 @@ protected override byte[] GetFinalData()
public override bool IsVersionValid() =>
Version is GameVersion.SN or GameVersion.MN or GameVersion.US or GameVersion.UM;
public sealed override string GetString(ReadOnlySpan<byte> data) => StringConverter7.GetString(data);
public sealed override string GetString(ReadOnlySpan<byte> data)
=> StringConverter7.GetString(data);
public sealed override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter7.LoadString(data, destBuffer);
public sealed override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
{
return StringConverter7.SetString(destBuffer, value, maxLength, Language, option);
}
=> StringConverter7.SetString(destBuffer, value, maxLength, Language, option);
// Player Information
public override uint ID32 { get => MyStatus.ID32; set => MyStatus.ID32 = value; }

View File

@@ -124,12 +124,12 @@ public override StorageSlotSource GetSlotFlags(int index)
return result;
}
public override string GetString(ReadOnlySpan<byte> data) => StringConverter8.GetString(data);
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter8.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter8.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
{
return StringConverter8.SetString(destBuffer, value, maxLength);
}
=> StringConverter8.SetString(destBuffer, value, maxLength);
public override bool IsVersionValid() => Version is GameVersion.GP or GameVersion.GE;

View File

@@ -244,12 +244,12 @@ public static bool GetIsHashValid(ReadOnlySpan<byte> data, ReadOnlySpan<byte> cu
public override bool IsVersionValid() => Version is GameVersion.BD or GameVersion.SP;
public override string GetString(ReadOnlySpan<byte> data) => StringConverter8.GetString(data);
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter8.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter8.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
{
return StringConverter8.SetString(destBuffer, value, maxLength, option);
}
=> StringConverter8.SetString(destBuffer, value, maxLength, option);
// Player Information
public override uint ID32 { get => MyStatus.ID32; set => MyStatus.ID32 = value; }

View File

@@ -38,8 +38,12 @@ public SAV8LA()
_ => throw new ArgumentOutOfRangeException(nameof(SaveRevision)),
};
public override string GetString(ReadOnlySpan<byte> data) => StringConverter8.GetString(data);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option) => StringConverter8.SetString(destBuffer, value, maxLength, option);
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter8.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter8.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter8.SetString(destBuffer, value, maxLength, option);
public override void CopyChangesFrom(SaveFile sav)
{

View File

@@ -158,7 +158,10 @@ private void Initialize()
public override bool IsVersionValid() => Version is GameVersion.SW or GameVersion.SH;
public override string GetString(ReadOnlySpan<byte> data) => StringConverter8.GetString(data);
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter8.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter8.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter8.SetString(destBuffer, value, maxLength, option);

View File

@@ -164,7 +164,10 @@ private void Initialize()
public override bool IsVersionValid() => Version is GameVersion.SL or GameVersion.VL;
public override string GetString(ReadOnlySpan<byte> data) => StringConverter8.GetString(data);
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter8.GetString(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter8.LoadString(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter8.SetString(destBuffer, value, maxLength, option);

View File

@@ -93,12 +93,12 @@ public virtual SlotGroup[] GetRegisteredTeams()
return result;
}
public sealed override string GetString(ReadOnlySpan<byte> data) => StringConverter1.GetString(data, Japanese);
public sealed override string GetString(ReadOnlySpan<byte> data)
=> StringConverter1.GetString(data, Japanese);
public sealed override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter1.LoadString(data, destBuffer, Japanese);
public sealed override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
{
return StringConverter1.SetString(destBuffer, value, maxLength, Japanese, option);
}
=> StringConverter1.SetString(destBuffer, value, maxLength, Japanese, option);
/// <summary>
/// Some emulators emit with system architecture endianness (Little Endian) instead of the original Big Endian ordering.

View File

@@ -8,7 +8,7 @@ namespace PKHeX.Core;
/// <summary>
/// Base Class for Save Files
/// </summary>
public abstract class SaveFile : ITrainerInfo, IGameValueLimit, IGeneration, IVersion
public abstract class SaveFile : ITrainerInfo, IGameValueLimit, IGeneration, IVersion, IStringConverter
{
// General Object Properties
public byte[] Data;
@@ -78,6 +78,7 @@ public void SetData(Span<byte> dest, ReadOnlySpan<byte> input)
}
public abstract string GetString(ReadOnlySpan<byte> data);
public abstract int LoadString(ReadOnlySpan<byte> data, Span<char> text);
public abstract int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option);
#endregion

View File

@@ -54,7 +54,8 @@ protected BulkStorage(byte[] data, Type t, int start, int slotsPerBox = 30) : ba
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter.GetString(data, Generation, blank.Japanese, IsBigEndian, Language);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter.LoadString(data, destBuffer, Generation, blank.Japanese, IsBigEndian, Language);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
=> StringConverter.SetString(destBuffer, value, maxLength, option: option, generation: Generation, jp: blank.Japanese, isBigEndian: IsBigEndian, language: Language);
}

View File

@@ -45,7 +45,6 @@ public sealed class SAV4Ranch : BulkStorage, ISaveFileRevision
protected override bool IsSlotSwapProtected(int box, int slot) => IsSlotOverwriteProtected(box, slot);
public override bool IsPKMPresent(ReadOnlySpan<byte> data) => EntityDetection.IsPresentSAV4Ranch(data);
private readonly GameVersion _version;
public override GameVersion Version { get => _version; set { } }
public SAV4Ranch(byte[] data) : base(data, typeof(RK4), 0)
@@ -251,10 +250,10 @@ public override int PlayedSeconds
set { var time = PlayedSpan; PlayedSpan = time - TimeSpan.FromSeconds(time.Seconds) + TimeSpan.FromSeconds(value); }
}
public override string GetString(ReadOnlySpan<byte> data) => StringConverter4GC.GetStringUnicode(data);
public override string GetString(ReadOnlySpan<byte> data)
=> StringConverter4GC.GetStringUnicode(data);
public override int LoadString(ReadOnlySpan<byte> data, Span<char> destBuffer)
=> StringConverter4GC.LoadStringUnicode(data, destBuffer);
public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, int maxLength, StringConverterOption option)
{
return StringConverter4GC.SetStringUnicode(value, destBuffer, maxLength, option);
}
=> StringConverter4GC.SetStringUnicode(value, destBuffer, maxLength, option);
}

View File

@@ -1408,8 +1408,7 @@ private void UpdateNicknameClick(object sender, MouseEventArgs e)
return;
}
var sav = RequestSaveFile;
using var d = new TrashEditor(tb, trash, sav);
using var d = new TrashEditor(tb, trash, Entity, Entity.Format);
d.ShowDialog();
tb.Text = d.FinalString;
d.FinalBytes.CopyTo(trash);

View File

@@ -9,15 +9,15 @@ namespace PKHeX.WinForms;
public partial class TrashEditor : Form
{
private readonly SaveFile SAV;
private readonly IStringConverter Converter;
public TrashEditor(TextBoxBase TB_NN, SaveFile sav) : this(TB_NN, [], sav) { }
public TrashEditor(TextBoxBase TB_NN, SaveFile sav) : this(TB_NN, [], sav, sav.Generation) { }
public TrashEditor(TextBoxBase TB_NN, Span<byte> raw, SaveFile sav)
public TrashEditor(TextBoxBase TB_NN, Span<byte> raw, IStringConverter converter, byte generation)
{
InitializeComponent();
WinFormsUtil.TranslateInterface(this, Main.CurrentLanguage);
SAV = sav;
Converter = converter;
FinalString = TB_NN.Text;
@@ -25,7 +25,7 @@ public TrashEditor(TextBoxBase TB_NN, Span<byte> raw, SaveFile sav)
if (raw.Length != 0)
{
Raw = FinalBytes = raw.ToArray();
AddTrashEditing(raw.Length);
AddTrashEditing(raw.Length, generation);
}
else
{
@@ -33,7 +33,7 @@ public TrashEditor(TextBoxBase TB_NN, Span<byte> raw, SaveFile sav)
}
var f = FontUtil.GetPKXFont();
AddCharEditing(f);
AddCharEditing(f, generation);
TB_Text.MaxLength = TB_NN.MaxLength;
TB_Text.Text = TB_NN.Text;
TB_Text.Font = f;
@@ -76,9 +76,9 @@ private void B_Save_Click(object sender, EventArgs e)
Close();
}
private void AddCharEditing(Font f)
private void AddCharEditing(Font f, byte generation)
{
var chars = GetChars(SAV.Generation);
var chars = GetChars(generation);
if (chars.Length == 0)
return;
@@ -94,11 +94,11 @@ private void AddCharEditing(Font f)
}
}
private void AddTrashEditing(int count)
private void AddTrashEditing(int count, byte generation)
{
FLP_Hex.Visible = true;
GB_Trash.Visible = true;
NUD_Generation.Value = SAV.Generation;
NUD_Generation.Value = generation;
for (int i = 0; i < count; i++)
{
var l = GetLabel($"${i:X2}");
@@ -127,7 +127,7 @@ private void AddTrashEditing(int count)
CB_Species.DataSource = new BindingSource(GameInfo.SpeciesDataSource, null);
CB_Language.InitializeBinding();
CB_Language.DataSource = GameInfo.LanguageDataSource(SAV.Generation);
CB_Language.DataSource = GameInfo.LanguageDataSource(generation);
}
private void UpdateNUD(object sender, EventArgs e)
@@ -200,11 +200,11 @@ private void B_ClearTrash_Click(object sender, EventArgs e)
private byte[] SetString(ReadOnlySpan<char> text)
{
Span<byte> temp = stackalloc byte[Raw.Length];
var written = SAV.SetString(temp, text, text.Length, StringConverterOption.None);
var written = Converter.SetString(temp, text, text.Length, StringConverterOption.None);
return temp[..written].ToArray();
}
private string GetString() => SAV.GetString(Raw);
private string GetString() => Converter.GetString(Raw);
// Helpers
private static Label GetLabel(string str) => new() { Text = str, AutoSize = false, Size = new Size(40, 24), TextAlign = ContentAlignment.MiddleRight };

View File

@@ -399,7 +399,7 @@ private void ChangeNickname(object sender, MouseEventArgs e)
var nicktrash = Data.Slice(0x18 + offset, 26);
var text = tb.Text;
SAV.SetString(nicktrash, text, 12, StringConverterOption.ClearZero);
var d = new TrashEditor(tb, nicktrash, SAV);
var d = new TrashEditor(tb, nicktrash, SAV, SAV.Generation);
d.ShowDialog();
tb.Text = d.FinalString;
d.FinalBytes.CopyTo(nicktrash);