mirror of
https://github.com/yawaflua/PL_JusticeBot.git
synced 2025-12-08 19:39:27 +02:00
updated
This commit is contained in:
@@ -29,5 +29,12 @@ namespace DiscordApp.Controllers
|
|||||||
})
|
})
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
|
public static async Task<bool> isAllowed(IServiceProvider services)
|
||||||
|
{
|
||||||
|
var context = services.GetRequiredService<ActionContext>();
|
||||||
|
if (context.HttpContext.Request.Cookies["geff"] == "ok") { return true; }
|
||||||
|
else { return false; }
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,6 +14,8 @@ namespace DiscordApp.Database
|
|||||||
public DbSet<BooksPatents> BookPatents { get; set; }
|
public DbSet<BooksPatents> BookPatents { get; set; }
|
||||||
public DbSet<Bizness> Bizness { get; set; }
|
public DbSet<Bizness> Bizness { get; set; }
|
||||||
public DbSet<Reports> Reports { get; set; }
|
public DbSet<Reports> Reports { get; set; }
|
||||||
|
public DbSet<Certificate> Certificates { get; set; }
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
{
|
{
|
||||||
base.OnModelCreating(modelBuilder);
|
base.OnModelCreating(modelBuilder);
|
||||||
|
|||||||
20
Database/Tables/Certificate.cs
Normal file
20
Database/Tables/Certificate.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace DiscordApp.Database.Tables
|
||||||
|
{
|
||||||
|
|
||||||
|
[Table("Certificate", Schema = "public")]
|
||||||
|
public class Certificate
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Employee { get; set; }
|
||||||
|
public Passport passport { get; set; }
|
||||||
|
public DateOnly Date { get; set; }
|
||||||
|
public string Text { get; set; }
|
||||||
|
public int DocumentId { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="CoreAdmin" Version="2.7.0" />
|
||||||
<PackageReference Include="Discord.Net" Version="3.12.0" />
|
<PackageReference Include="Discord.Net" Version="3.12.0" />
|
||||||
<PackageReference Include="Discord.Net.Commands" Version="3.12.0" />
|
<PackageReference Include="Discord.Net.Commands" Version="3.12.0" />
|
||||||
<PackageReference Include="Discord.Net.Core" Version="3.12.0" />
|
<PackageReference Include="Discord.Net.Core" Version="3.12.0" />
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ namespace DiscordApp
|
|||||||
handler.Log += LogAsync;
|
handler.Log += LogAsync;
|
||||||
|
|
||||||
await handler.AddModulesAsync(Assembly.GetEntryAssembly(), services);
|
await handler.AddModulesAsync(Assembly.GetEntryAssembly(), services);
|
||||||
var guildCommand = new SlashCommandBuilder();
|
|
||||||
|
|
||||||
client.InteractionCreated += HandleInteraction;
|
client.InteractionCreated += HandleInteraction;
|
||||||
}
|
}
|
||||||
|
|||||||
32
Justice.cs
32
Justice.cs
@@ -29,41 +29,15 @@ namespace DiscordApp
|
|||||||
client.Log += LogAsync;
|
client.Log += LogAsync;
|
||||||
client.UserJoined += Justice.Events.Events.onJoinGuild;
|
client.UserJoined += Justice.Events.Events.onJoinGuild;
|
||||||
client.MessageReceived += Justice.Events.Events.onMessageCreate;
|
client.MessageReceived += Justice.Events.Events.onMessageCreate;
|
||||||
client.Ready += onReady;
|
//client.Ready += onReady;
|
||||||
await client.LoginAsync(TokenType.Bot, "MTE2NjA3OTk3NjQ0NjEwMzYwMg.GAKOIo.4af972Wh11G0EF4O5tNYb7l-vt5OwMc4HPRnjE");
|
await client.LoginAsync(TokenType.Bot, "MTE2NjA3OTk3NjQ0NjEwMzYwMg.GAKOIo.4af972Wh11G0EF4O5tNYb7l-vt5OwMc4HPRnjE");
|
||||||
await client.StartAsync();
|
await client.StartAsync();
|
||||||
await interactionHandler.InitializeAsync();
|
await interactionHandler.InitializeAsync();
|
||||||
|
|
||||||
await Task.Delay(Timeout.Infinite);
|
await Task.Delay(Timeout.Infinite);
|
||||||
}
|
}
|
||||||
public async Task onReady()
|
|
||||||
{
|
|
||||||
await ChangeNicknames();
|
|
||||||
var myTimer = new System.Timers.Timer(6 * 60 * 60 * 1000); //calculate six hours in milliseconds
|
|
||||||
myTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
|
|
||||||
myTimer.Start();
|
|
||||||
}
|
|
||||||
private async void OnTimedEvent(object sender, ElapsedEventArgs e)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Started timer");
|
|
||||||
await ChangeNicknames();
|
|
||||||
}
|
|
||||||
private async Task ChangeNicknames()
|
|
||||||
{
|
|
||||||
IGuild guild = client.GetGuild(1107742957458685985);
|
|
||||||
IRole role = guild.GetRole(1136564585420304444);
|
|
||||||
var members = await guild.GetUsersAsync();
|
|
||||||
var membersArray = members.ToArray();
|
|
||||||
foreach (IGuildUser user in membersArray)
|
|
||||||
{
|
|
||||||
var spUser = await Startup.sp.GetUser(user.Id.ToString());
|
|
||||||
if (spUser.IsPlayer())
|
|
||||||
{
|
|
||||||
await user.ModifyAsync(func => { func.Nickname = spUser.Name; });
|
|
||||||
await user.AddRoleAsync(role);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private async Task LogAsync(LogMessage message)
|
private async Task LogAsync(LogMessage message)
|
||||||
=> Console.WriteLine(message.ToString());
|
=> Console.WriteLine(message.ToString());
|
||||||
}
|
}
|
||||||
|
|||||||
31
Justice/Commands/Getters.cs
Normal file
31
Justice/Commands/Getters.cs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
using Discord.Interactions;
|
||||||
|
using Discord;
|
||||||
|
|
||||||
|
namespace DiscordApp.Justice.Commands
|
||||||
|
{
|
||||||
|
public class Getters : InteractionModuleBase<SocketInteractionContext>
|
||||||
|
{
|
||||||
|
[SlashCommand("embed-getter-passport", "Отправляет сообщение для поиска паспорта")]
|
||||||
|
[DefaultMemberPermissions(GuildPermission.Administrator)]
|
||||||
|
public async Task getPassport()
|
||||||
|
{
|
||||||
|
await DeferAsync(true);
|
||||||
|
var embed = new EmbedBuilder()
|
||||||
|
.WithTitle("Получение информации о паспорте")
|
||||||
|
.WithDescription("Нажав на кнопку ниже вы можете получить данные о том, или ином игроке")
|
||||||
|
.WithColor(Color.DarkBlue)
|
||||||
|
.Build();
|
||||||
|
var components = new ComponentBuilder()
|
||||||
|
.WithButton(new ButtonBuilder()
|
||||||
|
{
|
||||||
|
CustomId = "searchPassport",
|
||||||
|
Label = "Поиск паспорта",
|
||||||
|
Style = ButtonStyle.Success
|
||||||
|
})
|
||||||
|
.Build();
|
||||||
|
var channel = Context.Channel as ITextChannel;
|
||||||
|
await channel.SendMessageAsync(embed: embed, components: components);
|
||||||
|
await FollowupAsync("Готово!", ephemeral: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
Justice/Commands/Notary.cs
Normal file
26
Justice/Commands/Notary.cs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
using Discord.Interactions;
|
||||||
|
using Discord;
|
||||||
|
|
||||||
|
namespace DiscordApp.Justice.Commands
|
||||||
|
{
|
||||||
|
public class Notary : InteractionModuleBase<SocketInteractionContext>
|
||||||
|
{
|
||||||
|
[SlashCommand("notary-embed", "Отправляет сообщение с кнопками для нотариусов")]
|
||||||
|
[DefaultMemberPermissions(GuildPermission.Administrator)]
|
||||||
|
public async Task sendNotaryEmbed()
|
||||||
|
{
|
||||||
|
await DeferAsync(true);
|
||||||
|
var Embed = new EmbedBuilder()
|
||||||
|
.WithTitle("**Заверка документа**")
|
||||||
|
.WithDescription("Ниже вы можете нажать на кнопку создания ID для документа и документа заверки")
|
||||||
|
.WithColor(Color.Blue)
|
||||||
|
.Build();
|
||||||
|
var Components = new ComponentBuilder()
|
||||||
|
.WithButton(new ButtonBuilder() { CustomId = "NewDocumentCertificate", Label = "Заверить документ", Style = ButtonStyle.Primary })
|
||||||
|
.Build();
|
||||||
|
await Context.Channel.SendMessageAsync(embed: Embed, components: Components);
|
||||||
|
await FollowupAsync("OK!");//, ephemeral: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -98,13 +98,14 @@ namespace DiscordApp.Discord.Commands
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Startup startup = new();
|
||||||
foreach (var employee in allEmployee)
|
foreach (var employee in allEmployee)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
Startup startup = new ();
|
var userData = await startup.getUserData(employee.Key);
|
||||||
await Startup.sp.CreateTransaction(startup.getUserData(employee.Key).Result.cardsOwned.First().number, employee.Value, $"zp {employee.Key}");
|
await Startup.sp.CreateTransaction(userData.cardsOwned.First().number, employee.Value, $"zp {employee.Key}");
|
||||||
await Console.Out.WriteLineAsync($"{employee.Key}, {employee.Value}");
|
await Console.Out.WriteLineAsync($"{employee.Key}, {employee.Value}");
|
||||||
allCount += employee.Value;
|
allCount += employee.Value;
|
||||||
}
|
}
|
||||||
|
|||||||
35
Justice/Interactions/NotaryInteractions.cs
Normal file
35
Justice/Interactions/NotaryInteractions.cs
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
using Discord.Interactions;
|
||||||
|
using DiscordApp.Justice.Modals;
|
||||||
|
using DiscordApp.Utilities;
|
||||||
|
|
||||||
|
namespace DiscordApp.Justice.Interactions
|
||||||
|
{
|
||||||
|
public class NotaryInteractions : InteractionModuleBase<SocketInteractionContext>
|
||||||
|
{
|
||||||
|
[ComponentInteraction("NewDocumentCertificate")]
|
||||||
|
public async Task newCertificatedDocument()
|
||||||
|
=> await Context.Interaction.RespondWithModalAsync<INotaryModal>("newCertificatedDocument");
|
||||||
|
|
||||||
|
[ModalInteraction("newCertificatedDocument")]
|
||||||
|
public async Task newCertificatedDocumentModal(INotaryModal modal)
|
||||||
|
{
|
||||||
|
await DeferAsync(true);
|
||||||
|
int passportId;
|
||||||
|
int documentId;
|
||||||
|
int certificateId;
|
||||||
|
Random random = new Random();
|
||||||
|
IdChecker.IdLenghtIsLower(out certificateId);
|
||||||
|
documentId = Startup.appDbContext.Certificates.OrderBy(t => t.Id).First().Id + 1;
|
||||||
|
bool isInt = int.TryParse(modal.passportId, out passportId);
|
||||||
|
if (!isInt)
|
||||||
|
{
|
||||||
|
await FollowupAsync($"Айди паспорта еще старое, попробуй использовать другого бота.", ephemeral: true);
|
||||||
|
}
|
||||||
|
else if (Startup.appDbContext.Passport.Find(passportId) == null)
|
||||||
|
{
|
||||||
|
await FollowupAsync($"Паспорт не найден в базе данных, попробуй написать правильно", ephemeral: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
55
Justice/Interactions/PassportGetterInteraction.cs
Normal file
55
Justice/Interactions/PassportGetterInteraction.cs
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
using Discord;
|
||||||
|
using Discord.Interactions;
|
||||||
|
using DiscordApp.Database.Tables;
|
||||||
|
using DiscordApp.Justice.Modals;
|
||||||
|
|
||||||
|
namespace DiscordApp.Justice.Interactions
|
||||||
|
{
|
||||||
|
public class PassportGetterInteraction : InteractionModuleBase<SocketInteractionContext>
|
||||||
|
{
|
||||||
|
[ComponentInteraction("searchPassport")]
|
||||||
|
public async Task searchPassportInteraction() => await RespondWithModalAsync<IPassportGetter>("GetPassportModal");
|
||||||
|
|
||||||
|
[ModalInteraction("GetPassportModal")]
|
||||||
|
public async Task getPassportInteraction(IPassportGetter modal)
|
||||||
|
{
|
||||||
|
await DeferAsync(true);
|
||||||
|
int passportId;
|
||||||
|
Passport passport;
|
||||||
|
bool isInteger = int.TryParse(modal.passport, out passportId);
|
||||||
|
if (isInteger)
|
||||||
|
{
|
||||||
|
passport = await Startup.appDbContext.Passport.FindAsync(passportId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
passport = Startup.appDbContext.Passport.Where(k => k.Applicant == modal.passport).FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (passport == null)
|
||||||
|
{
|
||||||
|
await FollowupAsync("Игрок или паспорт не найден в базе данных, попробуйте использовать старого бота.", ephemeral: true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var fields = new List<EmbedFieldBuilder>()
|
||||||
|
{
|
||||||
|
new EmbedFieldBuilder().WithName("Никнейм").WithValue(passport.Applicant).WithIsInline(true),
|
||||||
|
new EmbedFieldBuilder().WithName("РП Имя").WithValue(passport.RpName).WithIsInline(true),
|
||||||
|
new EmbedFieldBuilder().WithName("Гендер").WithValue(passport.Gender).WithIsInline(false),
|
||||||
|
new EmbedFieldBuilder().WithName("Благотворитель").WithValue((int)passport.Support).WithIsInline(false),
|
||||||
|
new EmbedFieldBuilder().WithName("Дата рождения").WithValue($"<t:{passport.birthDate}:D>").WithIsInline(false),
|
||||||
|
new EmbedFieldBuilder().WithName("Номер паспорта").WithValue(passport.Id).WithIsInline(true),
|
||||||
|
new EmbedFieldBuilder().WithName("Годен до").WithValue($"<t:{passport.Date}:D>").WithIsInline(true),
|
||||||
|
new EmbedFieldBuilder().WithName("Паспортист").WithValue($"<@{passport.Employee}>").WithIsInline(true)
|
||||||
|
};
|
||||||
|
var spUser = await spworlds.Types.User.CreateUser(passport.Applicant);
|
||||||
|
var embed = new EmbedBuilder()
|
||||||
|
.WithTitle("**Информация о паспорте**")
|
||||||
|
.WithFields(fields)
|
||||||
|
.WithThumbnailUrl(spUser.GetSkinPart(spworlds.Types.SkinPart.face))
|
||||||
|
.Build();
|
||||||
|
await FollowupAsync(embed:embed, ephemeral: true);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -158,8 +158,8 @@ namespace DiscordApp.Justice.Interactions
|
|||||||
Root spUserData = await startup.getUserData(name);
|
Root spUserData = await startup.getUserData(name);
|
||||||
DateTimeOffset toTime;
|
DateTimeOffset toTime;
|
||||||
DateOnly birthDate;
|
DateOnly birthDate;
|
||||||
int id = random.Next(00001, 99999);
|
int id;
|
||||||
while (id.ToString().Length < 5) { id = random.Next(00001, 99999); }
|
Utilities.IdChecker.IdLenghtIsLower(out id);
|
||||||
long unixBirthDateTime;
|
long unixBirthDateTime;
|
||||||
string cityName;
|
string cityName;
|
||||||
string cardNumber;
|
string cardNumber;
|
||||||
@@ -242,8 +242,7 @@ namespace DiscordApp.Justice.Interactions
|
|||||||
bool isUnical = false;
|
bool isUnical = false;
|
||||||
while (!isUnical)
|
while (!isUnical)
|
||||||
{
|
{
|
||||||
id = random.Next(00001, 99999);
|
Utilities.IdChecker.IdLenghtIsLower(out id);
|
||||||
while (id.ToString().Length < 5) { id = random.Next(00001, 99999); }
|
|
||||||
passport.Id = id;
|
passport.Id = id;
|
||||||
Console.WriteLine(passport.Id);
|
Console.WriteLine(passport.Id);
|
||||||
if (Startup.appDbContext.Passport.FindAsync(passport.Id).Result == null) { break; }
|
if (Startup.appDbContext.Passport.FindAsync(passport.Id).Result == null) { break; }
|
||||||
@@ -256,7 +255,7 @@ namespace DiscordApp.Justice.Interactions
|
|||||||
Имя: {passport.Applicant}
|
Имя: {passport.Applicant}
|
||||||
РП Имя: {passport.RpName}
|
РП Имя: {passport.RpName}
|
||||||
Айди: {id}
|
Айди: {id}
|
||||||
Благотворитель: {passport.Support}
|
Благотворитель: {(int)passport.Support}
|
||||||
Гендер: {passport.Gender}
|
Гендер: {passport.Gender}
|
||||||
Дата рождения: <t:{passport.birthDate}:D>
|
Дата рождения: <t:{passport.birthDate}:D>
|
||||||
Город: {cityName}
|
Город: {cityName}
|
||||||
|
|||||||
22
Justice/Modals/NotaryModals.cs
Normal file
22
Justice/Modals/NotaryModals.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
using Discord;
|
||||||
|
using Discord.Interactions;
|
||||||
|
|
||||||
|
namespace DiscordApp.Justice.Modals
|
||||||
|
{
|
||||||
|
public class INotaryModal : IModal
|
||||||
|
{
|
||||||
|
public string Title => "Сертификация док-ов";
|
||||||
|
[InputLabel("ID паспорта")]
|
||||||
|
[ModalTextInput("passportId", TextInputStyle.Short, placeholder: "96534", maxLength: 10)]
|
||||||
|
public string passportId { get; set; }
|
||||||
|
|
||||||
|
[InputLabel("Тип документа")]
|
||||||
|
[ModalTextInput("documentType", TextInputStyle.Short, placeholder: "Пользовательское соглашение", maxLength: 100)]
|
||||||
|
public string documentType { get; set; }
|
||||||
|
|
||||||
|
[InputLabel("Текст из документа")]
|
||||||
|
[ModalTextInput("textFromDocument", TextInputStyle.Paragraph)]
|
||||||
|
public string documentText { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
14
Justice/Modals/PassportGetterModals.cs
Normal file
14
Justice/Modals/PassportGetterModals.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using Discord;
|
||||||
|
using Discord.Interactions;
|
||||||
|
|
||||||
|
namespace DiscordApp.Justice.Modals
|
||||||
|
{
|
||||||
|
public class IPassportGetter : IModal
|
||||||
|
{
|
||||||
|
public string Title => "Поиск паспорта";
|
||||||
|
[InputLabel("Данные паспорта")]
|
||||||
|
[ModalTextInput("passport", TextInputStyle.Short, placeholder: "yawaflua или 97652", maxLength: 100)]
|
||||||
|
public string passport { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,8 +4,11 @@ using Discord.Interactions;
|
|||||||
using Discord.WebSocket;
|
using Discord.WebSocket;
|
||||||
using DiscordApp;
|
using DiscordApp;
|
||||||
using DiscordApp.Auth;
|
using DiscordApp.Auth;
|
||||||
|
using DiscordApp.Controllers;
|
||||||
using DiscordApp.Database;
|
using DiscordApp.Database;
|
||||||
using DiscordApp.Types;
|
using DiscordApp.Types;
|
||||||
|
using DotNetEd.CoreAdmin;
|
||||||
|
using DotNetEd.CoreAdmin.Controllers;
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Design;
|
using Microsoft.EntityFrameworkCore.Design;
|
||||||
@@ -114,6 +117,7 @@ namespace DiscordApp
|
|||||||
public void ConfigureServices(IServiceCollection services)
|
public void ConfigureServices(IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddControllers();
|
services.AddControllers();
|
||||||
|
services.AddCoreAdmin("yawaflua");
|
||||||
services
|
services
|
||||||
//.AddHostedService<DiscordBotService>()
|
//.AddHostedService<DiscordBotService>()
|
||||||
.AddHostedService<JusticeBotService>()
|
.AddHostedService<JusticeBotService>()
|
||||||
@@ -151,11 +155,11 @@ namespace DiscordApp
|
|||||||
c.RouteTemplate = "/swagger/v1/swagger.json";
|
c.RouteTemplate = "/swagger/v1/swagger.json";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
app.UseCoreAdminCustomAuth(k => Task.FromResult(true));
|
||||||
app.UseStaticFiles();
|
app.UseStaticFiles();
|
||||||
app.UseRouting();
|
app.UseRouting();
|
||||||
app.UseCors();
|
app.UseCors();
|
||||||
|
app.UseCoreAdminCustomUrl("admin/private/panel");
|
||||||
app.UseAuthentication();
|
app.UseAuthentication();
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
app.UseEndpoints(endpoints =>
|
app.UseEndpoints(endpoints =>
|
||||||
|
|||||||
13
Utilities/IdChecker.cs
Normal file
13
Utilities/IdChecker.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
namespace DiscordApp.Utilities
|
||||||
|
{
|
||||||
|
public class IdChecker
|
||||||
|
{
|
||||||
|
public static void IdLenghtIsLower(out int id)
|
||||||
|
{
|
||||||
|
Random random = new();
|
||||||
|
id = random.Next(00001, 99999);
|
||||||
|
while (id.ToString().Length < 5) { id = random.Next(00001, 99999); }
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user