Skip to content

Commit

Permalink
add netstandard 2.0 again...
Browse files Browse the repository at this point in the history
  • Loading branch information
Folleach committed Jun 3, 2023
1 parent cdd553c commit 4d7f453
Show file tree
Hide file tree
Showing 19 changed files with 119 additions and 46 deletions.
2 changes: 1 addition & 1 deletion GeometryDashAPI.Tests/GeometryDashAPI.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net6.0</TargetFramework>
<TargetFrameworks>netcoreapp2.2;net6.0</TargetFrameworks>
<LangVersion>latest</LangVersion>
</PropertyGroup>

Expand Down
18 changes: 15 additions & 3 deletions GeometryDashAPI/Data/GameData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,13 @@ public virtual async Task LoadAsync(string fileName)
throw new FileNotFoundException($"file does not exists: '{fileName}'");

// File > Bytes > XOR > ToString > Replace > Base64 > Gzip
#if NETSTANDARD2_1
var data = await File.ReadAllBytesAsync(fileName);
#else
using var file = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
var data = new byte[file.Length];
var read = await file.ReadAsync(data, 0, data.Length);
#endif
var dataZip = Encoding.ASCII.GetString(Crypt.XOR(data, 0xB)).Split('\0')[0];
var resultPlist = Crypt.GZipDecompress(GameConvert.FromBase64(dataZip));

Expand All @@ -54,14 +60,20 @@ public void Save(string? fullName = null)
/// Saves class data to a file as a game save<br/><br/>
/// Before saving, make sure that you have closed the game. Otherwise, after closing, the game will overwrite the file<br/>
/// </summary>
/// <param name="fullName">File to write the data.<br />
/// <param name="fileName">File to write the data.<br />
/// use <b>null</b> value for default resolving
/// </param>
public async Task SaveAsync(string? fullName = null)
public async Task SaveAsync(string? fileName = null)
{
using var memory = new MemoryStream();
await DataPlist.SaveToStreamAsync(memory);
await File.WriteAllBytesAsync(fullName ?? ResolveFileName(type), GetFileContent(memory));
#if NETSTANDARD2_1
await File.WriteAllBytesAsync(fileName ?? ResolveFileName(type), GetFileContent(memory));
#else
using var file = new FileStream(fileName ?? ResolveFileName(type), FileMode.Create, FileAccess.ReadWrite, FileShare.Read);
var data = GetFileContent(memory);
await file.WriteAsync(data, 0, data.Length);
#endif
}

public static string ResolveFileName(GameDataType? type)
Expand Down
21 changes: 20 additions & 1 deletion GeometryDashAPI/Data/GameManager.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Security.Cryptography;
using System;
using System.Buffers;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using GeometryDashAPI.Data.Enums;
Expand Down Expand Up @@ -266,9 +268,26 @@ private static string GenerateUdid()
{
var builder = new StringBuilder();
builder.Append("S");
#if !NETSTANDARD2_1
var c = RandomNumberGenerator.Create();
#endif

for (var i = 0; i < 6; i++)
#if NETSTANDARD2_1
builder.Append(RandomNumberGenerator.GetInt32(0, 999999).ToString("000000"));
builder.Append(RandomNumberGenerator.GetInt32(0, 9));
#else
{
var buffer = ArrayPool<byte>.Shared.Rent(4);
c.GetBytes(buffer, 0, 4);
builder.Append((Math.Abs(BitConverter.ToInt32(buffer, 0)) % 1000000).ToString("000000"));
ArrayPool<byte>.Shared.Return(buffer);
}
var buffer2 = ArrayPool<byte>.Shared.Rent(1);
c.GetBytes(buffer2, 0, 4);
builder.Append((Math.Abs(BitConverter.ToInt32(buffer2, 0)) % 10).ToString("000000"));
ArrayPool<byte>.Shared.Return(buffer2);
#endif
return builder.ToString();
}
}
Expand Down
5 changes: 5 additions & 0 deletions GeometryDashAPI/Data/GameResources.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,13 @@ public async Task<Level> GetLevelAsync(OfficialLevel officialLevel)
throw new InvalidEnumArgumentException("meltdown levels is not supported");
if (!levels.TryGetValue(gameType, out var plist))
{
#if NETSTANDARD2_1
var bytes = await File.ReadAllBytesAsync(Path.Combine(path, GetLevelDataPath(gameType)));
levels.TryAdd(gameType, plist = new Plist(bytes));
#else
var bytes = File.ReadAllBytes(Path.Combine(path, GetLevelDataPath(gameType)));
levels.Add(gameType, plist = new Plist(bytes));
#endif
}

var content = plist[((int)officialLevel).ToString()].ToString();
Expand Down
2 changes: 1 addition & 1 deletion GeometryDashAPI/GameConvert.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public static string BoolToString(bool value, bool isReverse = false)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool StringToBool(ReadOnlySpan<char> value, bool isReverse = false)
{
return (value.CompareTo("1", StringComparison.Ordinal) == 0) ^ isReverse;
return (value.CompareTo("1".AsSpan(), StringComparison.Ordinal) == 0) ^ isReverse;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand Down
2 changes: 1 addition & 1 deletion GeometryDashAPI/GeometryDashAPI.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<TargetFrameworks>netstandard2.1;netstandard2.0</TargetFrameworks>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>Folleach</Authors>
<NeutralLanguage>en</NeutralLanguage>
Expand Down
8 changes: 6 additions & 2 deletions GeometryDashAPI/Levels/BlockGroup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,17 @@ public override string ToString()
public static BlockGroup Parse(ReadOnlySpan<char> data)
{
var result = new BlockGroup();
var parser = new LLParserSpan(".", data);
var parser = new LLParserSpan(".".AsSpan(), data);
while (true)
{
var idRaw = parser.Next();
if (idRaw == null)
break;
#if NETSTANDARD2_1
if (!int.TryParse(idRaw, out var id))
#else
if (!int.TryParse(idRaw.ToString(), out var id))
#endif
throw new Exception($"Can't parse group id in: {data.ToString()}");
result.Add(id);
}
Expand All @@ -46,7 +50,7 @@ public static BlockGroup Parse(ReadOnlySpan<char> data)
public static BlockGroup Parse(string data)
{
var result = new BlockGroup();
var parser = new LLParserSpan(".", data);
var parser = new LLParserSpan(".".AsSpan(), data.AsSpan());
while (true)
{
var idRaw = parser.Next();
Expand Down
7 changes: 7 additions & 0 deletions GeometryDashAPI/Levels/Color.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,16 @@ public override string ToString()
public static string RgbToHex(RgbColor rgb) => $"{rgb.Red:X2}{rgb.Green:X2}{rgb.Blue:X2}";
public static RgbColor HexToRgb(ReadOnlySpan<char> hex) => new()
{
#if NETSTANDARD2_1
Red = (byte)((byte.Parse(hex.Slice(1, 2)) >> 16) & 0xFF),
Green = (byte)((byte.Parse(hex.Slice(3, 2)) >> 8) & 0xFF),
Blue = (byte)(byte.Parse(hex.Slice(5, 2)) & 0xFF)
#else
Red = (byte)((byte.Parse(hex.Slice(1, 2).ToString()) >> 16) & 0xFF),
Green = (byte)((byte.Parse(hex.Slice(3, 2).ToString()) >> 8) & 0xFF),
Blue = (byte)(byte.Parse(hex.Slice(5, 2).ToString()) & 0xFF)
#endif

};
}
}
10 changes: 5 additions & 5 deletions GeometryDashAPI/Levels/Guidelines.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public static Guidelines Parse(ReadOnlySpan<char> raw)
var guidelines = new Guidelines();

ReadOnlySpan<char> value;
var parser = new LLParserSpan(SEPERATOR, raw);
var parser = new LLParserSpan(SEPERATOR.AsSpan(), raw);

int index = 0;
double timestamp = 0;
Expand Down Expand Up @@ -59,10 +59,10 @@ public static string GetStringFromGuidelineColor(GuidelineColor color)
public static GuidelineColor GetGuidelineColorFromString(ReadOnlySpan<char> color)
{
return
color.CompareTo("0", StringComparison.Ordinal) == 0 ? GuidelineColor.Orange :
color.CompareTo("0.8", StringComparison.Ordinal) == 0 ? GuidelineColor.Orange :
color.CompareTo("0.9", StringComparison.Ordinal) == 0 ? GuidelineColor.Yellow :
color.CompareTo("1", StringComparison.Ordinal) == 0 ? GuidelineColor.Green : throw new IndexOutOfRangeException("unknown color");
color.CompareTo("0".AsSpan(), StringComparison.Ordinal) == 0 ? GuidelineColor.Orange :
color.CompareTo("0.8".AsSpan(), StringComparison.Ordinal) == 0 ? GuidelineColor.Orange :
color.CompareTo("0.9".AsSpan(), StringComparison.Ordinal) == 0 ? GuidelineColor.Yellow :
color.CompareTo("1".AsSpan(), StringComparison.Ordinal) == 0 ? GuidelineColor.Green : throw new IndexOutOfRangeException("unknown color");
}
}
}
8 changes: 4 additions & 4 deletions GeometryDashAPI/Levels/Hsv.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ public static Hsv Parse(string raw)
{
var result = new Hsv();
var dataArray = raw.Split(SEPARATOR);
result.Hue = GameConvert.StringToSingle(dataArray[0]);
result.Saturation = GameConvert.StringToSingle(dataArray[1]);
result.Brightness = GameConvert.StringToSingle(dataArray[2]);
result.DeltaSaturation = GameConvert.StringToBool(dataArray[3]);
result.Hue = GameConvert.StringToSingle(dataArray[0].AsSpan());
result.Saturation = GameConvert.StringToSingle(dataArray[1].AsSpan());
result.Brightness = GameConvert.StringToSingle(dataArray[2].AsSpan());
result.DeltaSaturation = GameConvert.StringToBool(dataArray[3].AsSpan());
result.DeltaBrightness = GameConvert.StringToBool(dataArray[4]);

return result;
Expand Down
6 changes: 5 additions & 1 deletion GeometryDashAPI/Levels/Level.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ protected virtual void Load(string data, bool compressed)
{
if (compressed)
data = Decompress(data);
var parser = new LLParserSpan(";", data);
var parser = new LLParserSpan(";".AsSpan(), data.AsSpan());
var header = parser.Next();
Options = Level.Serializer.Decode<LevelOptions>(header);
LoadBlocks(parser);
Expand All @@ -84,7 +84,11 @@ protected virtual void LoadBlocks(LLParserSpan llParser)
public string SaveAsString(bool compress = true)
{
var builder = new StringBuilder();
#if NETSTANDARD2_1
builder.Append(GeometryDashApi.Serializer.Encode(Options));
#else
builder.Append(GeometryDashApi.Serializer.Encode(Options).ToString());
#endif

foreach (var block in Blocks)
{
Expand Down
14 changes: 9 additions & 5 deletions GeometryDashAPI/Serialization/ObjectSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public ReadOnlySpan<char> Encode<T>(T value) where T : IGameObject
throw new InvalidOperationException($"descriptor is not implement '{typeof(ICopyDescriptor<T>)}'");
var builder = new StringBuilder();
copyDescriptor.CopyTo(value, builder);
return builder.ToString();
return builder.ToString().AsSpan();
}

public Action<IGameObject, StringBuilder> GetCopier(Type type) => copiersCache.GetOrAdd(type, CreateCopier);
Expand All @@ -46,7 +46,7 @@ private static Action<IGameObject, StringBuilder> CreateCopier(Type type)

public List<T> DecodeList<T>(ReadOnlySpan<char> raw, string separator) where T : IGameObject
{
var parser = new LLParserSpan(separator, raw);
var parser = new LLParserSpan(separator.AsSpan(), raw);
ReadOnlySpan<char> value;
var list = new List<T>();
while ((value = parser.Next()) != null)
Expand All @@ -56,7 +56,7 @@ public List<T> DecodeList<T>(ReadOnlySpan<char> raw, string separator) where T :

public T[] GetArray<T>(ReadOnlySpan<char> raw, string separator, IGameSerializer.Parser<T> getValue)
{
var parser = new LLParserSpan(separator, raw);
var parser = new LLParserSpan(separator.AsSpan(), raw);
var length = parser.GetCountOfValues();
ReadOnlySpan<char> rawValue;
var array = new T[length];
Expand All @@ -68,17 +68,21 @@ public T[] GetArray<T>(ReadOnlySpan<char> raw, string separator, IGameSerializer

public IGameObject DecodeBlock(ReadOnlySpan<char> raw)
{
var parser = new LLParserSpan(",", raw);
var parser = new LLParserSpan(",".AsSpan(), raw);
ReadOnlySpan<char> key;
ReadOnlySpan<char> blockId;
while (parser.TryParseNext(out key, out blockId))
{
if (key.SequenceEqual("1"))
if (key.SequenceEqual("1".AsSpan()))
goto FoundKey;
}
throw new Exception("Raw data doesn't contains id component");
FoundKey:
#if NETSTANDARD2_1
if (!int.TryParse(blockId, out var id))
#else
if (!int.TryParse(blockId.ToString(), out var id))
#endif
throw new Exception("Id is not a number");
var type = GeometryDashApi.GetBlockType(id);

Expand Down
9 changes: 9 additions & 0 deletions GeometryDashAPI/Serialization/Parsers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,21 @@ namespace GeometryDashAPI.Serialization
internal class Parsers
{
public static bool GetOrDefault_Boolean__(ReadOnlySpan<char> data) => GameConvert.StringToBool(data);
#if NETSTANDARD2_1
public static byte GetOrDefault_Byte__(ReadOnlySpan<char> data) => byte.TryParse(data, out var value) ? value : default;
public static sbyte GetOrDefault_SByte__(ReadOnlySpan<char> data) => sbyte.TryParse(data, out var value) ? value : default;
public static short GetOrDefault_Int16__(ReadOnlySpan<char> data) => short.TryParse(data, out var value) ? value : default;
public static int GetOrDefault_Int32__(ReadOnlySpan<char> data) => int.TryParse(data, out var value) ? value : default;
public static int? GetOrDefault_Int32_Y(ReadOnlySpan<char> data) => int.TryParse(data, out var value) ? value : default;
public static long GetOrDefault_Int64__(ReadOnlySpan<char> data) => long.TryParse(data, out var value) ? value : default;
#else
public static byte GetOrDefault_Byte__(ReadOnlySpan<char> data) => byte.TryParse(data.ToString(), out var value) ? value : default;
public static sbyte GetOrDefault_SByte__(ReadOnlySpan<char> data) => sbyte.TryParse(data.ToString(), out var value) ? value : default;
public static short GetOrDefault_Int16__(ReadOnlySpan<char> data) => short.TryParse(data.ToString(), out var value) ? value : default;
public static int GetOrDefault_Int32__(ReadOnlySpan<char> data) => int.TryParse(data.ToString(), out var value) ? value : default;
public static int? GetOrDefault_Int32_Y(ReadOnlySpan<char> data) => int.TryParse(data.ToString(), out var value) ? value : default;
public static long GetOrDefault_Int64__(ReadOnlySpan<char> data) => long.TryParse(data.ToString(), out var value) ? value : default;
#endif
public static double GetOrDefault_Double__(ReadOnlySpan<char> data) => GameConvert.StringToDouble(data);
public static float GetOrDefault_Single__(ReadOnlySpan<char> data) => GameConvert.StringToSingle(data);
public static string GetOrDefault_String__(ReadOnlySpan<char> data) => data.ToString();
Expand Down
8 changes: 6 additions & 2 deletions GeometryDashAPI/Serialization/Plist.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ private void Load(Stream stream)

private void Parse(Plist dict, IEnumerable<XElement> elements)
{
foreach (var (key, value) in elements.Pairs())
dict[key.Value] = ParseValue(value);
foreach (var item in elements.Pairs())
dict[item.Key.Value] = ParseValue(item.Value);
}

private dynamic ParseValue(XElement val)
Expand Down Expand Up @@ -104,7 +104,11 @@ public void SaveToStream(Stream stream)
public async Task SaveToStreamAsync(Stream stream)
{
var document = CreateDocumentFromThis();
#if NETSTANDARD2_1
await document.SaveAsync(stream, SaveOptions.DisableFormatting, CancellationToken.None);
#else
await Task.Run(() => document.Save(stream, SaveOptions.DisableFormatting));
#endif
}

private XDocument CreateDocumentFromThis()
Expand Down
28 changes: 14 additions & 14 deletions GeometryDashAPI/Serialization/Printers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,20 @@ namespace GeometryDashAPI.Serialization
// Used for TypeDescriptor
internal class Printers
{
public static ReadOnlySpan<char> GetOrDefault_Boolean__(bool value) => GameConvert.BoolToString(value);
public static ReadOnlySpan<char> GetOrDefault_Byte__(byte value) => value.ToString();
public static ReadOnlySpan<char> GetOrDefault_SByte__(sbyte value) => value.ToString();
public static ReadOnlySpan<char> GetOrDefault_Int16__(short value) => value.ToString();
public static ReadOnlySpan<char> GetOrDefault_Int32__(int value) => value.ToString();
public static ReadOnlySpan<char> GetOrDefault_Int32_Y(int? value) => value.ToString();
public static ReadOnlySpan<char> GetOrDefault_Int64__(long value) => value.ToString();
public static ReadOnlySpan<char> GetOrDefault_Double__(double value) => GameConvert.DoubleToString(value);
public static ReadOnlySpan<char> GetOrDefault_Single__(float value) => GameConvert.SingleToString(value);
public static ReadOnlySpan<char> GetOrDefault_String__(string value) => value.ToString();
public static ReadOnlySpan<char> GetOrDefault_BlockGroup__(BlockGroup value) => value.ToString();
public static ReadOnlySpan<char> GetOrDefault_Hsv__(Hsv value) => Hsv.Parse(value);
public static ReadOnlySpan<char> GetOrDefault_Pagination__(Pagination value) => Pagination.Serialize(value);
public static ReadOnlySpan<char> GetOrDefault_Guidelines__(Guidelines value) => Guidelines.Parse(value);
public static ReadOnlySpan<char> GetOrDefault_Boolean__(bool value) => GameConvert.BoolToString(value).AsSpan();
public static ReadOnlySpan<char> GetOrDefault_Byte__(byte value) => value.ToString().AsSpan();
public static ReadOnlySpan<char> GetOrDefault_SByte__(sbyte value) => value.ToString().AsSpan();
public static ReadOnlySpan<char> GetOrDefault_Int16__(short value) => value.ToString().AsSpan();
public static ReadOnlySpan<char> GetOrDefault_Int32__(int value) => value.ToString().AsSpan();
public static ReadOnlySpan<char> GetOrDefault_Int32_Y(int? value) => value.ToString().AsSpan();
public static ReadOnlySpan<char> GetOrDefault_Int64__(long value) => value.ToString().AsSpan();
public static ReadOnlySpan<char> GetOrDefault_Double__(double value) => GameConvert.DoubleToString(value).AsSpan();
public static ReadOnlySpan<char> GetOrDefault_Single__(float value) => GameConvert.SingleToString(value).AsSpan();
public static ReadOnlySpan<char> GetOrDefault_String__(string value) => value.AsSpan();
public static ReadOnlySpan<char> GetOrDefault_BlockGroup__(BlockGroup value) => value.ToString().AsSpan();
public static ReadOnlySpan<char> GetOrDefault_Hsv__(Hsv value) => Hsv.Parse(value).AsSpan();
public static ReadOnlySpan<char> GetOrDefault_Pagination__(Pagination value) => Pagination.Serialize(value).AsSpan();
public static ReadOnlySpan<char> GetOrDefault_Guidelines__(Guidelines value) => Guidelines.Parse(value).AsSpan();

public delegate void PrinterAppend<in TInstance>(TInstance instance, StringBuilder destination);
public static void PrintArray<T>(T[] array, string separator, StringBuilder destination, PrinterAppend<T> append)
Expand Down
8 changes: 6 additions & 2 deletions GeometryDashAPI/Serialization/TypeDescriptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public TypeDescriptor()
public T Create(ReadOnlySpan<char> raw)
{
var instance = create();
var parser = new LLParserSpan(sense, raw);
var parser = new LLParserSpan(sense.AsSpan(), raw);

if (isStruct)
{
Expand All @@ -85,7 +85,11 @@ public T Create(ReadOnlySpan<char> raw)
{
while (parser.TryParseNext(out var key, out var value))
{
#if NETSTANDARD2_1
if (!int.TryParse(key, out var index))
#else
if (!int.TryParse(key.ToString(), out var index))
#endif
{
var keyString = key.ToString();
if (!mappings.TryGetValue(keyString, out var mapped))
Expand Down Expand Up @@ -215,7 +219,7 @@ private static (SetterInfo<T>[], int baseIndex, Dictionary<string, int> mappings

if (mappings != null)
{
var values = mappings.Select(x => x.Value).ToHashSet();
var values = new HashSet<int>(mappings.Select(x => x.Value));
for (var i = 0; i < mappings.Count; i++)
{
if (!values.Contains(i))
Expand Down
Loading

0 comments on commit 4d7f453

Please sign in to comment.