Skip to content

Commit

Permalink
First stage of getting rid of Uri.EscapeUriString in zip packages; fu…
Browse files Browse the repository at this point in the history
…ll new validation support; render passed players in special questions; stop fading out players in hidden stakes question; switch to Table and Theme list visible round types
  • Loading branch information
VladimirKhil committed Dec 22, 2024
1 parent 0d49c34 commit 5f52cdd
Show file tree
Hide file tree
Showing 50 changed files with 714 additions and 648 deletions.
3 changes: 0 additions & 3 deletions src/Common/SI.GameServer.Client/GameServerClient.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using SI.GameServer.Client.Properties;
using SI.GameServer.Contract;
using SIData;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Text;
Expand Down
1 change: 0 additions & 1 deletion src/Common/SIEngine/GameEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using SIEngine.QuestionSelectionStrategies;
using SIEngine.Rules;
using SIPackages;
using SIPackages.Core;

namespace SIEngine;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public void Dispose() { }
public void Flush() => throw new NotImplementedException();

/// <inheritdoc />
public string[] GetEntries(string category) => Array.Empty<string>();
public IEnumerable<string> GetEntries(string category) => Array.Empty<string>();

/// <inheritdoc />
public StreamInfo? GetStream(string name, bool read = true) => null;
Expand Down
4 changes: 2 additions & 2 deletions src/Common/SIPackages/Containers/FolderSIPackageContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public void Dispose()

public void Flush() { }

public string[] GetEntries(string category)
public IEnumerable<string> GetEntries(string category)
{
var directoryInfo = new DirectoryInfo(Path.Combine(_folder, category));

Expand All @@ -76,7 +76,7 @@ public string[] GetEntries(string category)
return Array.Empty<string>();
}

return directoryInfo.GetFiles().Select(file => file.Name).ToArray();
return directoryInfo.GetFiles().Select(file => file.Name);
}

public StreamInfo? GetStream(string name, bool read = true)
Expand Down
2 changes: 1 addition & 1 deletion src/Common/SIPackages/Containers/ISIPackageContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public interface ISIPackageContainer : IDisposable
/// Gets container entries by category.
/// </summary>
/// <param name="category">Category name.</param>
string[] GetEntries(string category);
IEnumerable<string> GetEntries(string category);

/// <summary>
/// Gets stream length.
Expand Down
119 changes: 104 additions & 15 deletions src/Common/SIPackages/Containers/ZipSIPackageContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@

namespace SIPackages.Containers;

// TODO: Keep Uri.EscapeUriString only for backward compatibility; use original names in zip archive

/// <summary>
/// Define a Zip-based package source.
/// </summary>
Expand All @@ -16,11 +14,33 @@ internal sealed class ZipSIPackageContainer : ISIPackageContainer
{
private readonly Stream _stream;
private readonly ZipArchive _zipArchive;
private readonly Dictionary<string, Dictionary<string, string>> _nameMap = new();

private ZipSIPackageContainer(Stream stream, ZipArchive zipArchive)
{
_stream = stream;
_zipArchive = zipArchive;

// Fill the categories name maps
foreach (var entry in _zipArchive.Entries)
{
var nameSegments = entry.FullName.Split('/', 2);

if (nameSegments.Length < 2)
{
continue;
}

var category = nameSegments[0];
var name = Uri.UnescapeDataString(entry.Name);

if (!_nameMap.TryGetValue(category, out var categoryMap))
{
_nameMap[category] = categoryMap = new Dictionary<string, string>();
}

categoryMap[name] = entry.Name;
}
}

/// <summary>
Expand All @@ -35,17 +55,19 @@ public static ZipSIPackageContainer Create(Stream stream, bool leaveOpen = false
public static ZipSIPackageContainer Open(Stream stream, bool read = true) =>
new(stream, new ZipArchive(stream, read ? ZipArchiveMode.Read : ZipArchiveMode.Update, false));

public string[] GetEntries(string category)
public IEnumerable<string> GetEntries(string category)
{
if (_zipArchive.Mode == ZipArchiveMode.Create)
{
return Array.Empty<string>();
}

return _zipArchive.Entries
.Where(entry => entry.FullName.StartsWith(category))
.Select(entry => Uri.UnescapeDataString(entry.Name))
.ToArray();
if (!_nameMap.TryGetValue(category, out var categoryMap))
{
return Array.Empty<string>();
}

return categoryMap.Keys;
}

public StreamInfo? GetStream(string name, bool read = true)
Expand All @@ -67,20 +89,51 @@ public string[] GetEntries(string category)
return new StreamInfo { Stream = stream, Length = _zipArchive.Mode == ZipArchiveMode.Read ? entry.Length : 0 };
}

public StreamInfo? GetStream(string category, string name, bool read = true) => GetStream($"{category}/{Uri.EscapeUriString(name)}", read);
public StreamInfo? GetStream(string category, string name, bool read = true)
{
if (!_nameMap.TryGetValue(category, out var categoryMap))
{
return null;
}

public void CreateStream(string name) => _zipArchive.CreateEntry(Uri.EscapeUriString(name), CompressionLevel.Optimal);
if (!categoryMap.TryGetValue(name, out var entryName))
{
return null;
}

return GetStream($"{category}/{entryName}", read);
}

public void CreateStream(string category, string name) =>
_zipArchive.CreateEntry($"{category}/{Uri.EscapeUriString(name)}", CompressionLevel.NoCompression);
public void CreateStream(string name) => _zipArchive.CreateEntry(name, CompressionLevel.Optimal);

public void CreateStream(string category, string name)
{
var entryName = Uri.EscapeUriString(name); // TODO: do not escape after everyone updates to the new version

Check warning on line 111 in src/Common/SIPackages/Containers/ZipSIPackageContainer.cs

View workflow job for this annotation

GitHub Actions / build

'Uri.EscapeUriString(string)' is obsolete: 'Uri.EscapeUriString can corrupt the Uri string in some cases. Consider using Uri.EscapeDataString for query string components.' (https://aka.ms/dotnet-warnings/SYSLIB0013)
_zipArchive.CreateEntry($"{category}/{entryName}", CompressionLevel.NoCompression);

if (!_nameMap.TryGetValue(category, out var categoryMap))
{
_nameMap[category] = categoryMap = new Dictionary<string, string>();
}

categoryMap[name] = entryName;
}

public async Task CreateStreamAsync(
string category,
string name,
Stream stream,
CancellationToken cancellationToken = default)
{
var entry = _zipArchive.CreateEntry($"{category}/{Uri.EscapeUriString(name)}", CompressionLevel.NoCompression);
var entryName = Uri.EscapeUriString(name); // TODO: do not escape after everyone updates to the new version
var entry = _zipArchive.CreateEntry($"{category}/{entryName}", CompressionLevel.NoCompression);

if (!_nameMap.TryGetValue(category, out var categoryMap))
{
_nameMap[category] = categoryMap = new Dictionary<string, string>();
}

categoryMap[name] = entryName;

using var writeStream = entry.Open();
await stream.CopyToAsync(writeStream, cancellationToken);
Expand All @@ -99,7 +152,20 @@ public bool DeleteStream(string name)
return true;
}

public bool DeleteStream(string category, string name) => DeleteStream($"{category}/{Uri.EscapeUriString(name)}");
public bool DeleteStream(string category, string name)
{
if (!_nameMap.TryGetValue(category, out var categoryMap))
{
return false;
}

if (!categoryMap.TryGetValue(name, out var entryName))
{
return false;
}

return DeleteStream($"{category}/{entryName}");
}

public ISIPackageContainer CopyTo(Stream stream, bool closeCurrent, out bool isNew)
{
Expand Down Expand Up @@ -135,11 +201,34 @@ public long GetStreamLength(string name)
return entry?.Length ?? -1;
}

public long GetStreamLength(string category, string name) => GetStreamLength($"{category}/{Uri.EscapeUriString(name)}");
public long GetStreamLength(string category, string name)
{
if (!_nameMap.TryGetValue(category, out var categoryMap))
{
return -1;
}

if (!categoryMap.TryGetValue(name, out var entryName))
{
return -1;
}

return GetStreamLength($"{category}/{entryName}");
}

public MediaInfo? TryGetMedia(string category, string name)
{
var fullName = $"{category}/{Uri.EscapeUriString(name)}";
if (!_nameMap.TryGetValue(category, out var categoryMap))
{
return null;
}

if (!categoryMap.TryGetValue(name, out var entryName))
{
return null;
}

var fullName = $"{category}/{entryName}";
var entry = _zipArchive.GetEntry(fullName);

if (entry == null)
Expand Down
4 changes: 2 additions & 2 deletions src/Common/SIPackages/Core/RoundTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
public static class RoundTypes
{
/// <summary>
/// Simple round type.
/// [Table] Simple round type.
/// </summary>
public const string Standart = "standart";

/// <summary>
/// Final round type.
/// [Theme list] Final round type.
/// </summary>
public const string Final = "final";
}
12 changes: 3 additions & 9 deletions src/Common/SIPackages/Question.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,6 @@ public int Price
/// <summary>
/// Question type name.
/// </summary>
/// <remarks>
/// Replaces deprecated <see cref="Type" /> property.
/// </remarks>
[DefaultValue(QuestionTypes.Default)]
public string TypeName
{
Expand All @@ -66,17 +63,11 @@ public string TypeName
/// <summary>
/// Question script.
/// </summary>
/// <remarks>
/// Replaces deprecated <see cref="Scenario" /> property.
/// </remarks>
public Script? Script { get; set; }

/// <summary>
/// Question parameters.
/// </summary>
/// <remarks>
/// Replaces deprecated <see cref="Scenario" /> and <see cref="Type" /> properties.
/// </remarks>
public StepParameters Parameters { get; } = new();

/// <summary>
Expand Down Expand Up @@ -602,6 +593,9 @@ private static string GetTextFromContent(StepParameter content)
return result.ToString();
}

/// <summary>
/// Checks if the question has media content.
/// </summary>
public bool HasMediaContent()
{
foreach (var item in GetContent())
Expand Down
12 changes: 1 addition & 11 deletions src/SICore/SICore/Clients/Actor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,16 @@ namespace SICore;
/// </summary>
/// <typeparam name="D">Тип данных клиента</typeparam>
/// <typeparam name="L">Тип логики клиента</typeparam>
public abstract class Actor<D, L> : IActor
public abstract class Actor<D> : IActor
where D : Data
where L : class, ILogic
{
protected Client _client;

/// <summary>
/// Логика клиента
/// </summary>
protected L _logic;

/// <summary>
/// Данные клиента
/// </summary>
public D ClientData { get; private set; }

public L Logic => _logic;

public IClient Client => _client;

public abstract ValueTask OnMessageReceivedAsync(Message message);
Expand Down Expand Up @@ -59,8 +51,6 @@ private void Client_Disposed()
}
}

public void AddLog(string s) => _logic.AddLog(s);

protected virtual void Dispose(bool disposing)
{
_client.MessageReceived -= OnMessageReceivedAsync;
Expand Down
4 changes: 0 additions & 4 deletions src/SICore/SICore/Clients/Data.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,6 @@ public Data(IGameHost gameManager)
protected static string PrintAccount(ViewerAccount viewerAccount) =>
$"{viewerAccount?.Name}@{viewerAccount?.IsHuman}:{viewerAccount?.IsConnected}";

public virtual void OnAddString(string person, string text, LogMode mode)
{
}

protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

Expand Down
Loading

0 comments on commit 5f52cdd

Please sign in to comment.