mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-10 17:28:27 -04:00
Package upgrades
- Upgraded all packages to latest version - Removed obsolete code due to version upgrade - More nullref warnings silenced
This commit is contained in:
@@ -7,9 +7,9 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1" />
|
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@@ -74,7 +74,7 @@ namespace NadekoBot.Core.Modules.Searches.Common.StreamNotifications.Providers
|
|||||||
if (!res.IsSuccessStatusCode)
|
if (!res.IsSuccessStatusCode)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var userData = JsonConvert.DeserializeObject<PicartoChannelResponse>(await res.Content.ReadAsStringAsync());
|
var userData = JsonConvert.DeserializeObject<PicartoChannelResponse>(await res.Content.ReadAsStringAsync())!;
|
||||||
|
|
||||||
toReturn.Add(ToStreamData(userData));
|
toReturn.Add(ToStreamData(userData));
|
||||||
_failingStreams.TryRemove(login, out _);
|
_failingStreams.TryRemove(login, out _);
|
||||||
|
@@ -72,7 +72,7 @@ namespace NadekoBot.Core.Modules.Searches.Common.StreamNotifications.Providers
|
|||||||
// get id based on the username
|
// get id based on the username
|
||||||
var idsStr = await http.GetStringAsync($"https://api.twitch.tv/kraken/users?login={login}");
|
var idsStr = await http.GetStringAsync($"https://api.twitch.tv/kraken/users?login={login}");
|
||||||
var userData = JsonConvert.DeserializeObject<TwitchUsersResponseV5>(idsStr);
|
var userData = JsonConvert.DeserializeObject<TwitchUsersResponseV5>(idsStr);
|
||||||
var user = userData.Users.FirstOrDefault();
|
var user = userData?.Users.FirstOrDefault();
|
||||||
|
|
||||||
// if user can't be found, skip, it means there is no such user
|
// if user can't be found, skip, it means there is no such user
|
||||||
if (user is null)
|
if (user is null)
|
||||||
@@ -84,11 +84,11 @@ namespace NadekoBot.Core.Modules.Searches.Common.StreamNotifications.Providers
|
|||||||
JsonConvert.DeserializeAnonymousType(str, new {Stream = new TwitchResponseV5.Stream()});
|
JsonConvert.DeserializeAnonymousType(str, new {Stream = new TwitchResponseV5.Stream()});
|
||||||
|
|
||||||
// if stream is null, user is not streaming
|
// if stream is null, user is not streaming
|
||||||
if (resObj.Stream is null)
|
if (resObj?.Stream is null)
|
||||||
{
|
{
|
||||||
// if user is not streaming, get his offline banner
|
// if user is not streaming, get his offline banner
|
||||||
var chStr = await http.GetStringAsync($"https://api.twitch.tv/kraken/channels/{user.Id}");
|
var chStr = await http.GetStringAsync($"https://api.twitch.tv/kraken/channels/{user.Id}");
|
||||||
var ch = JsonConvert.DeserializeObject<TwitchResponseV5.Channel>(chStr);
|
var ch = JsonConvert.DeserializeObject<TwitchResponseV5.Channel>(chStr)!;
|
||||||
|
|
||||||
toReturn.Add(new StreamData
|
toReturn.Add(new StreamData
|
||||||
{
|
{
|
||||||
|
@@ -9,40 +9,43 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AngleSharp" Version="0.14.0" />
|
<PackageReference Include="AngleSharp" Version="0.16.0" />
|
||||||
<PackageReference Include="AWSSDK.S3" Version="3.7.0.14" />
|
<PackageReference Include="AWSSDK.S3" Version="3.7.1.4" />
|
||||||
<PackageReference Include="CodeHollow.FeedReader" Version="1.2.1" />
|
<PackageReference Include="CodeHollow.FeedReader" Version="1.2.1" />
|
||||||
<PackageReference Include="CommandLineParser" Version="2.8.0" />
|
<PackageReference Include="CommandLineParser" Version="2.8.0" />
|
||||||
<PackageReference Include="Discord.Net" Version="2.3.1" />
|
<PackageReference Include="Discord.Net" Version="2.4.0" />
|
||||||
<PackageReference Include="CoreCLR-NCalc" Version="2.2.80" />
|
<PackageReference Include="CoreCLR-NCalc" Version="2.2.92" />
|
||||||
<PackageReference Include="Google.Apis.Urlshortener.v1" Version="1.41.1.138" />
|
<PackageReference Include="Google.Apis.Urlshortener.v1" Version="1.41.1.138" />
|
||||||
<PackageReference Include="Google.Apis.YouTube.v3" Version="1.47.0.2008" />
|
<PackageReference Include="Google.Apis.YouTube.v3" Version="1.52.0.2343" />
|
||||||
<PackageReference Include="Google.Apis.Customsearch.v1" Version="1.48.0.2014" />
|
<PackageReference Include="Google.Apis.Customsearch.v1" Version="1.49.0.2084" />
|
||||||
<PackageReference Include="Html2Markdown" Version="3.3.1.407" />
|
<PackageReference Include="Html2Markdown" Version="4.0.0.427" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.15" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.7" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.15" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.7">
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.15" />
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.15" />
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="3.1.15" />
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.15" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.7" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.15" />
|
<PackageReference Include="Microsoft.Extensions.Configuration" Version="5.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.15" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="5.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Http" Version="3.1.15" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="5.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.15" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.1" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.1.15" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="5.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="5.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="5.0.0" />
|
||||||
<PackageReference Include="Microsoft.SyndicationFeed.ReaderWriter" Version="1.0.2" />
|
<PackageReference Include="Microsoft.SyndicationFeed.ReaderWriter" Version="1.0.2" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
|
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
|
||||||
<PackageReference Include="Serilog.Sinks.Seq" Version="5.0.1" />
|
<PackageReference Include="Serilog.Sinks.Seq" Version="5.0.1" />
|
||||||
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.0-rc0003" />
|
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.3" />
|
||||||
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta0010" />
|
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta0010" />
|
||||||
<PackageReference Include="StackExchange.Redis" Version="1.2.7-alpha-00002" />
|
<PackageReference Include="StackExchange.Redis" Version="2.2.4" />
|
||||||
<PackageReference Include="System.Threading.Channels" Version="5.0.0" />
|
<PackageReference Include="System.Threading.Channels" Version="5.0.0" />
|
||||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||||
<PackageReference Include="VideoLibrary" Version="3.0.7" />
|
<PackageReference Include="VideoLibrary" Version="3.1.2" />
|
||||||
<PackageReference Include="YamlDotNet" Version="11.1.1" />
|
<PackageReference Include="YamlDotNet" Version="11.2.0" />
|
||||||
<PackageReference Include="YoutubeExplode" Version="5.1.8" />
|
<PackageReference Include="YoutubeExplode" Version="6.0.2" />
|
||||||
<PackageReference Include="linq2db.EntityFrameworkCore" Version="3.10.1" />
|
<PackageReference Include="linq2db.EntityFrameworkCore" Version="5.3.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@@ -24,7 +24,6 @@ namespace NadekoBot.Core.Services.Impl
|
|||||||
|
|
||||||
Redis = ConnectionMultiplexer.Connect(conf);
|
Redis = ConnectionMultiplexer.Connect(conf);
|
||||||
_redisEndpoint = Redis.GetEndPoints().First();
|
_redisEndpoint = Redis.GetEndPoints().First();
|
||||||
Redis.PreserveAsyncOrder = false;
|
|
||||||
LocalImages = new RedisImagesCache(Redis, creds);
|
LocalImages = new RedisImagesCache(Redis, creds);
|
||||||
LocalData = new RedisLocalDataCache(Redis, creds, shardId);
|
LocalData = new RedisLocalDataCache(Redis, creds, shardId);
|
||||||
_redisKey = creds.RedisKey();
|
_redisKey = creds.RedisKey();
|
||||||
|
@@ -1,209 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Buffers;
|
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
// Licensed to the .NET Foundation under one or more agreements.
|
|
||||||
// The .NET Foundation licenses this file to you under the MIT license.
|
|
||||||
|
|
||||||
namespace Ayu.Discord.Voice
|
|
||||||
{
|
|
||||||
sealed class ArrayBufferWriter<T> : IBufferWriter<T>
|
|
||||||
{
|
|
||||||
// Copy of Array.MaxLength.
|
|
||||||
private const int ArrayMaxLength = 0x7FFFFFC7;
|
|
||||||
|
|
||||||
private const int DefaultInitialBufferSize = 256;
|
|
||||||
|
|
||||||
private T[] _buffer;
|
|
||||||
private int _index;
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates an instance of an <see cref="ArrayBufferWriter{T}"/>, in which data can be written to,
|
|
||||||
/// with the default initial capacity.
|
|
||||||
/// </summary>
|
|
||||||
public ArrayBufferWriter()
|
|
||||||
{
|
|
||||||
_buffer = Array.Empty<T>();
|
|
||||||
_index = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates an instance of an <see cref="ArrayBufferWriter{T}"/>, in which data can be written to,
|
|
||||||
/// with an initial capacity specified.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="initialCapacity">The minimum capacity with which to initialize the underlying buffer.</param>
|
|
||||||
/// <exception cref="ArgumentException">
|
|
||||||
/// Thrown when <paramref name="initialCapacity"/> is not positive (i.e. less than or equal to 0).
|
|
||||||
/// </exception>
|
|
||||||
public ArrayBufferWriter(int initialCapacity)
|
|
||||||
{
|
|
||||||
if (initialCapacity <= 0)
|
|
||||||
throw new ArgumentException(null, nameof(initialCapacity));
|
|
||||||
|
|
||||||
_buffer = new T[initialCapacity];
|
|
||||||
_index = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the data written to the underlying buffer so far, as a <see cref="ReadOnlyMemory{T}"/>.
|
|
||||||
/// </summary>
|
|
||||||
public ReadOnlyMemory<T> WrittenMemory => _buffer.AsMemory(0, _index);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the data written to the underlying buffer so far, as a <see cref="ReadOnlySpan{T}"/>.
|
|
||||||
/// </summary>
|
|
||||||
public ReadOnlySpan<T> WrittenSpan => _buffer.AsSpan(0, _index);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the amount of data written to the underlying buffer so far.
|
|
||||||
/// </summary>
|
|
||||||
public int WrittenCount => _index;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the total amount of space within the underlying buffer.
|
|
||||||
/// </summary>
|
|
||||||
public int Capacity => _buffer.Length;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the amount of space available that can still be written into without forcing the underlying buffer to grow.
|
|
||||||
/// </summary>
|
|
||||||
public int FreeCapacity => _buffer.Length - _index;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Clears the data written to the underlying buffer.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// You must clear the <see cref="ArrayBufferWriter{T}"/> before trying to re-use it.
|
|
||||||
/// </remarks>
|
|
||||||
public void Clear()
|
|
||||||
{
|
|
||||||
Debug.Assert(_buffer.Length >= _index);
|
|
||||||
_buffer.AsSpan(0, _index).Clear();
|
|
||||||
_index = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Notifies <see cref="IBufferWriter{T}"/> that <paramref name="count"/> amount of data was written to the output <see cref="Span{T}"/>/<see cref="Memory{T}"/>
|
|
||||||
/// </summary>
|
|
||||||
/// <exception cref="ArgumentException">
|
|
||||||
/// Thrown when <paramref name="count"/> is negative.
|
|
||||||
/// </exception>
|
|
||||||
/// <exception cref="InvalidOperationException">
|
|
||||||
/// Thrown when attempting to advance past the end of the underlying buffer.
|
|
||||||
/// </exception>
|
|
||||||
/// <remarks>
|
|
||||||
/// You must request a new buffer after calling Advance to continue writing more data and cannot write to a previously acquired buffer.
|
|
||||||
/// </remarks>
|
|
||||||
public void Advance(int count)
|
|
||||||
{
|
|
||||||
if (count < 0)
|
|
||||||
throw new ArgumentException(null, nameof(count));
|
|
||||||
|
|
||||||
if (_index > _buffer.Length - count)
|
|
||||||
ThrowInvalidOperationException_AdvancedTooFar(_buffer.Length);
|
|
||||||
|
|
||||||
_index += count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a <see cref="Memory{T}"/> to write to that is at least the requested length (specified by <paramref name="sizeHint"/>).
|
|
||||||
/// If no <paramref name="sizeHint"/> is provided (or it's equal to <code>0</code>), some non-empty buffer is returned.
|
|
||||||
/// </summary>
|
|
||||||
/// <exception cref="ArgumentException">
|
|
||||||
/// Thrown when <paramref name="sizeHint"/> is negative.
|
|
||||||
/// </exception>
|
|
||||||
/// <remarks>
|
|
||||||
/// This will never return an empty <see cref="Memory{T}"/>.
|
|
||||||
/// </remarks>
|
|
||||||
/// <remarks>
|
|
||||||
/// There is no guarantee that successive calls will return the same buffer or the same-sized buffer.
|
|
||||||
/// </remarks>
|
|
||||||
/// <remarks>
|
|
||||||
/// You must request a new buffer after calling Advance to continue writing more data and cannot write to a previously acquired buffer.
|
|
||||||
/// </remarks>
|
|
||||||
public Memory<T> GetMemory(int sizeHint = 0)
|
|
||||||
{
|
|
||||||
CheckAndResizeBuffer(sizeHint);
|
|
||||||
Debug.Assert(_buffer.Length > _index);
|
|
||||||
return _buffer.AsMemory(_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a <see cref="Span{T}"/> to write to that is at least the requested length (specified by <paramref name="sizeHint"/>).
|
|
||||||
/// If no <paramref name="sizeHint"/> is provided (or it's equal to <code>0</code>), some non-empty buffer is returned.
|
|
||||||
/// </summary>
|
|
||||||
/// <exception cref="ArgumentException">
|
|
||||||
/// Thrown when <paramref name="sizeHint"/> is negative.
|
|
||||||
/// </exception>
|
|
||||||
/// <remarks>
|
|
||||||
/// This will never return an empty <see cref="Span{T}"/>.
|
|
||||||
/// </remarks>
|
|
||||||
/// <remarks>
|
|
||||||
/// There is no guarantee that successive calls will return the same buffer or the same-sized buffer.
|
|
||||||
/// </remarks>
|
|
||||||
/// <remarks>
|
|
||||||
/// You must request a new buffer after calling Advance to continue writing more data and cannot write to a previously acquired buffer.
|
|
||||||
/// </remarks>
|
|
||||||
public Span<T> GetSpan(int sizeHint = 0)
|
|
||||||
{
|
|
||||||
CheckAndResizeBuffer(sizeHint);
|
|
||||||
Debug.Assert(_buffer.Length > _index);
|
|
||||||
return _buffer.AsSpan(_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CheckAndResizeBuffer(int sizeHint)
|
|
||||||
{
|
|
||||||
if (sizeHint < 0)
|
|
||||||
throw new ArgumentException(nameof(sizeHint));
|
|
||||||
|
|
||||||
if (sizeHint == 0)
|
|
||||||
{
|
|
||||||
sizeHint = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sizeHint > FreeCapacity)
|
|
||||||
{
|
|
||||||
int currentLength = _buffer.Length;
|
|
||||||
|
|
||||||
// Attempt to grow by the larger of the sizeHint and double the current size.
|
|
||||||
int growBy = Math.Max(sizeHint, currentLength);
|
|
||||||
|
|
||||||
if (currentLength == 0)
|
|
||||||
{
|
|
||||||
growBy = Math.Max(growBy, DefaultInitialBufferSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
int newSize = currentLength + growBy;
|
|
||||||
|
|
||||||
if ((uint) newSize > int.MaxValue)
|
|
||||||
{
|
|
||||||
// Attempt to grow to ArrayMaxLength.
|
|
||||||
uint needed = (uint) (currentLength - FreeCapacity + sizeHint);
|
|
||||||
Debug.Assert(needed > currentLength);
|
|
||||||
|
|
||||||
if (needed > ArrayMaxLength)
|
|
||||||
{
|
|
||||||
ThrowOutOfMemoryException(needed);
|
|
||||||
}
|
|
||||||
|
|
||||||
newSize = ArrayMaxLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
Array.Resize(ref _buffer, newSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug.Assert(FreeCapacity > 0 && FreeCapacity >= sizeHint);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ThrowInvalidOperationException_AdvancedTooFar(int capacity)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ThrowOutOfMemoryException(uint capacity)
|
|
||||||
{
|
|
||||||
throw new OutOfMemoryException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,13 +1,12 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="Current">
|
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="Current">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
<LangVersion>8.0</LangVersion>
|
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<NoWarn>CS8632</NoWarn>
|
<NoWarn>CS8632</NoWarn>
|
||||||
<Version>1.0.1</Version>
|
<Version>1.0.2</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
<PackageReference Include="Serilog" Version="2.10.0" />
|
<PackageReference Include="Serilog" Version="2.10.0" />
|
||||||
<PackageReference Include="System.Threading.Channels" Version="5.0.0" />
|
<PackageReference Include="System.Threading.Channels" Version="5.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
using Serilog;
|
using Serilog;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
using System.Net.WebSockets;
|
using System.Net.WebSockets;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Ayu.Discord.Voice;
|
|
||||||
|
|
||||||
namespace Ayu.Discord.Gateway
|
namespace Ayu.Discord.Gateway
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user