Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
@@ -425,6 +425,7 @@ public record MasterySkill
|
||||
|
||||
public record CommonSkill
|
||||
{
|
||||
[JsonConverter(typeof(SafeDoubleConverter))]
|
||||
public double PointsEarnedDuringSession { get; set; }
|
||||
|
||||
public long LastAccess { get; set; }
|
||||
|
||||
@@ -159,7 +159,13 @@ public class ProbabilityObjectArray<K, V> : List<ProbabilityObject<K, V>>
|
||||
for (var i = 0; i < itemCountToDraw; i++)
|
||||
{
|
||||
var rand = Random.Shared.NextDouble();
|
||||
var randomIndex = cumulativeProbabilities.FindIndex(probability => probability > rand);
|
||||
var randomIndex = cumulativeProbabilities.FindIndex(probability => probability >= rand);
|
||||
|
||||
if (randomIndex == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
results.Add(this[randomIndex].Key);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Text;
|
||||
using SPTarkov.DI.Annotations;
|
||||
|
||||
namespace SPTarkov.Server.Core.Utils;
|
||||
@@ -101,27 +102,52 @@ public class FileUtil
|
||||
|
||||
public async Task WriteFileAsync(string filePath, string fileContent)
|
||||
{
|
||||
if (!DirectoryExists(Path.GetDirectoryName(filePath)))
|
||||
{
|
||||
CreateDirectory(Path.GetDirectoryName(filePath));
|
||||
}
|
||||
|
||||
if (!FileExists(filePath))
|
||||
{
|
||||
CreateFile(filePath);
|
||||
}
|
||||
|
||||
await File.WriteAllTextAsync(filePath, fileContent);
|
||||
var bytes = Encoding.UTF8.GetBytes(fileContent);
|
||||
await WriteFileAsync(filePath, bytes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a file atomically by first writing to a temporary file, then replacing the original.
|
||||
/// This prevents corruption if the write operation fails or is interrupted.
|
||||
/// </summary>
|
||||
public async Task WriteFileAsync(string filePath, byte[] fileContent)
|
||||
{
|
||||
if (!FileExists(filePath))
|
||||
var directoryPath = Path.GetDirectoryName(filePath);
|
||||
|
||||
if (!string.IsNullOrEmpty(directoryPath) && !Directory.Exists(directoryPath))
|
||||
{
|
||||
CreateFile(filePath);
|
||||
Directory.CreateDirectory(directoryPath);
|
||||
}
|
||||
|
||||
await File.WriteAllBytesAsync(filePath, fileContent);
|
||||
var tempFilePath = filePath + ".bak";
|
||||
|
||||
try
|
||||
{
|
||||
await using (
|
||||
var fs = new FileStream(tempFilePath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 4096, useAsync: true)
|
||||
)
|
||||
{
|
||||
await fs.WriteAsync(fileContent);
|
||||
|
||||
// We flush here so we can be sure it's immediately committed to disk
|
||||
await fs.FlushAsync();
|
||||
}
|
||||
|
||||
// Overwrite over the old file
|
||||
File.Move(tempFilePath, filePath, overwrite: true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (File.Exists(tempFilePath))
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete(tempFilePath);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateFile(string filePath)
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace SPTarkov.Server.Core.Utils.Json.Converters;
|
||||
|
||||
public class SafeDoubleConverter : JsonConverter<double>
|
||||
{
|
||||
public override double Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
switch (reader.TokenType)
|
||||
{
|
||||
case JsonTokenType.Number:
|
||||
try
|
||||
{
|
||||
return reader.GetDouble();
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
try
|
||||
{
|
||||
var decimalValue = reader.GetDecimal();
|
||||
return decimalValue > 0 ? double.MaxValue : 0;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return double.MaxValue;
|
||||
}
|
||||
}
|
||||
|
||||
case JsonTokenType.String:
|
||||
if (double.TryParse(reader.GetString(), out var stringParsed))
|
||||
{
|
||||
return stringParsed;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case JsonTokenType.Null:
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, double value, JsonSerializerOptions options)
|
||||
{
|
||||
writer.WriteNumberValue(value);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user