mirror of
https://github.com/claunia/SabreTools.git
synced 2025-12-16 19:14:27 +00:00
[SabreTools, Build] Convert extension split to use lists externally; overhaul help
This commit is contained in:
@@ -148,17 +148,38 @@ namespace SabreTools.Helper.Data
|
|||||||
case "SabreTools":
|
case "SabreTools":
|
||||||
helptext.Add(Resources.Resources.SabreTools_Name + " - " + Resources.Resources.SabreTools_Desc);
|
helptext.Add(Resources.Resources.SabreTools_Name + " - " + Resources.Resources.SabreTools_Desc);
|
||||||
helptext.Add(barrier);
|
helptext.Add(barrier);
|
||||||
helptext.Add(Resources.Resources.Usage + ": " + Resources.Resources.SabreTools_Name + " [option] [filename|dirname] ...");
|
helptext.Add(Resources.Resources.Usage + ": " + Resources.Resources.SabreTools_Name + " [option] [flags] [filename|dirname] ...");
|
||||||
helptext.Add("");
|
helptext.Add("");
|
||||||
|
|
||||||
|
// Determine which help to show
|
||||||
|
switch (subset)
|
||||||
|
{
|
||||||
|
case null:
|
||||||
helptext.Add("Options:");
|
helptext.Add("Options:");
|
||||||
helptext.Add(" -?, -h, --help Show this help");
|
helptext.Add(" -?, -h, --help Show this help");
|
||||||
helptext.Add(" --script Enable script mode (no clear screen)");
|
helptext.Add(" --script Enable script mode (no clear screen)");
|
||||||
|
|
||||||
// DATFromDir
|
|
||||||
if (subset == null || subset == "d" || subset == "dfd" || subset == "d2d")
|
|
||||||
{
|
|
||||||
helptext.Add("");
|
|
||||||
helptext.Add(" -d, --dfd, --d2d Create a DAT from an input directory");
|
helptext.Add(" -d, --dfd, --d2d Create a DAT from an input directory");
|
||||||
|
helptext.Add(" -es, --ext-split Split a DAT by two file extensions");
|
||||||
|
helptext.Add(" -ex, --extract Extract and remove copier headers");
|
||||||
|
helptext.Add(" -hs, --hash-split Split a DAT or folder by best-available hashes");
|
||||||
|
helptext.Add(" -ls, --lvl-split Split a SuperDAT or folder by internal path");
|
||||||
|
helptext.Add(" -re, --restore Restore header to file based on SHA-1");
|
||||||
|
helptext.Add(" -ss, --sort Sort input files by a set of DATs");
|
||||||
|
helptext.Add(" -ssd, --sort-depot Sort input files by a set of DATs");
|
||||||
|
helptext.Add(" -st, --stats Get statistics on all input DATs");
|
||||||
|
helptext.Add(" -ts, --type-split Split a DAT or folder by file types (rom/disk)");
|
||||||
|
helptext.Add(" -ud, --update Update a DAT file");
|
||||||
|
helptext.Add(" -ve, --verify Verify a folder against DATs");
|
||||||
|
helptext.Add(" -ved, --verify-depot Verify a folder against DATs");
|
||||||
|
helptext.Add("");
|
||||||
|
helptext.Add("For information on available flags, put the option name after help");
|
||||||
|
break;
|
||||||
|
|
||||||
|
//DATFromDir
|
||||||
|
case "d":
|
||||||
|
case "d2d":
|
||||||
|
case "dfd":
|
||||||
|
helptext.Add("Available Flags:");
|
||||||
helptext.Add(" -nm, --noMD5 Don't include MD5 in output");
|
helptext.Add(" -nm, --noMD5 Don't include MD5 in output");
|
||||||
helptext.Add(" -ns, --noSHA1 Don't include SHA1 in output");
|
helptext.Add(" -ns, --noSHA1 Don't include SHA1 in output");
|
||||||
helptext.Add(" -b, --bare Don't include date in file name");
|
helptext.Add(" -b, --bare Don't include date in file name");
|
||||||
@@ -197,58 +218,51 @@ namespace SabreTools.Helper.Data
|
|||||||
helptext.Add(" -h=, --header= Set a header skipper to use, blank means all");
|
helptext.Add(" -h=, --header= Set a header skipper to use, blank means all");
|
||||||
helptext.Add(" -t=, --temp= Set the temporary directory to use");
|
helptext.Add(" -t=, --temp= Set the temporary directory to use");
|
||||||
helptext.Add(" -mt={4} Amount of threads to use (-1 unlimted)");
|
helptext.Add(" -mt={4} Amount of threads to use (-1 unlimted)");
|
||||||
}
|
break;
|
||||||
|
|
||||||
|
|
||||||
// Extension Split
|
// Extension Split
|
||||||
if (subset == null || subset == "es" || subset == "ext-split")
|
case "es":
|
||||||
{
|
case "ext-split":
|
||||||
helptext.Add("");
|
helptext.Add("Available Flags:");
|
||||||
helptext.Add(" -es, --ext-split Split a DAT by two file extensions");
|
helptext.Add(" -exta= First extension (multiple allowed)");
|
||||||
helptext.Add(" -exta= First set of extensions (comma-separated)");
|
helptext.Add(" -extb= Second extension (multiple allowed)");
|
||||||
helptext.Add(" -extb= Second set of extensions (comma-separated)");
|
|
||||||
helptext.Add(" -out= Output directory");
|
helptext.Add(" -out= Output directory");
|
||||||
}
|
break;
|
||||||
|
|
||||||
// Extract and Remove Headers
|
// Extract and Remove Headers
|
||||||
if (subset == null || subset == "ex" || subset == "extract")
|
case "ex":
|
||||||
{
|
case "extract":
|
||||||
helptext.Add("");
|
helptext.Add("Available Flags:");
|
||||||
helptext.Add(" -ex, --extract Extract and remove copier headers");
|
|
||||||
helptext.Add(" -out= Output directory");
|
helptext.Add(" -out= Output directory");
|
||||||
}
|
break;
|
||||||
|
|
||||||
// Hash Split
|
// Hash Split
|
||||||
if (subset == null || subset == "hs" || subset == "hash-split")
|
case "hs":
|
||||||
{
|
case "hash-split":
|
||||||
helptext.Add("");
|
helptext.Add("Available Flags:");
|
||||||
helptext.Add(" -hs, --hash-split Split a DAT or folder by best-available hashes");
|
|
||||||
helptext.Add(" -out= Output directory");
|
helptext.Add(" -out= Output directory");
|
||||||
}
|
break;
|
||||||
|
|
||||||
// Level/SuperDAT Split
|
// Level/SuperDAT Split
|
||||||
if (subset == null || subset == "ls" || subset == "lvl-split")
|
case "ls":
|
||||||
{
|
case "lvl-split":
|
||||||
helptext.Add("");
|
helptext.Add("Available Flags:");
|
||||||
helptext.Add(" -ls, --lvl-split Split a SuperDAT or folder by internal path");
|
|
||||||
helptext.Add(" -out= Output directory");
|
helptext.Add(" -out= Output directory");
|
||||||
helptext.Add(" -s, --short Use short output names");
|
helptext.Add(" -s, --short Use short output names");
|
||||||
helptext.Add(" -ba, --base Use source DAT as base name for outputs");
|
helptext.Add(" -ba, --base Use source DAT as base name for outputs");
|
||||||
}
|
break;
|
||||||
|
|
||||||
// Restore Headers
|
// Restore Headers
|
||||||
if (subset == null || subset == "re" || subset == "restore")
|
case "re":
|
||||||
{
|
case "restore":
|
||||||
helptext.Add("");
|
helptext.Add("Available Flags:");
|
||||||
helptext.Add(" -re, --restore Restore header to file based on SHA-1");
|
|
||||||
helptext.Add(" -out= Output directory");
|
helptext.Add(" -out= Output directory");
|
||||||
}
|
break;
|
||||||
|
|
||||||
// Sort
|
// Sort
|
||||||
if (subset == null || subset == "ss" || subset == "sort")
|
case "ss":
|
||||||
{
|
case "sort":
|
||||||
helptext.Add("");
|
helptext.Add("Available Flags:");
|
||||||
helptext.Add(" -ss, --sort Sort input files by a set of DATs");
|
|
||||||
helptext.Add(" -dat= Input DAT to rebuild against");
|
helptext.Add(" -dat= Input DAT to rebuild against");
|
||||||
helptext.Add(" -out= Output directory");
|
helptext.Add(" -out= Output directory");
|
||||||
helptext.Add(" -t=, --temp= Set the temporary directory to use");
|
helptext.Add(" -t=, --temp= Set the temporary directory to use");
|
||||||
@@ -271,13 +285,18 @@ namespace SabreTools.Helper.Data
|
|||||||
helptext.Add(" -zip={1} Set scanning level for ZIP archives");
|
helptext.Add(" -zip={1} Set scanning level for ZIP archives");
|
||||||
helptext.Add(" -ud, --update-dat Output updated DAT to output directory");
|
helptext.Add(" -ud, --update-dat Output updated DAT to output directory");
|
||||||
helptext.Add(" -mt={4} Amount of threads to use (-1 unlimted)");
|
helptext.Add(" -mt={4} Amount of threads to use (-1 unlimted)");
|
||||||
}
|
|
||||||
|
helptext.Add("");
|
||||||
|
helptext.Add("Archive scanning levels:");
|
||||||
|
helptext.Add(" 0 Hash archive and contents");
|
||||||
|
helptext.Add(" 1 Only hash contents");
|
||||||
|
helptext.Add(" 2 Only hash archive");
|
||||||
|
break;
|
||||||
|
|
||||||
// Sort Depot
|
// Sort Depot
|
||||||
if (subset == null || subset == "ssd" || subset == "sort-depot")
|
case "ssd":
|
||||||
{
|
case "sort-depot":
|
||||||
helptext.Add("");
|
helptext.Add("Available Flags:");
|
||||||
helptext.Add(" -ssd, --sort-depot Sort input files by a set of DATs");
|
|
||||||
helptext.Add(" -dat= Input DAT to rebuild against");
|
helptext.Add(" -dat= Input DAT to rebuild against");
|
||||||
helptext.Add(" -out= Output directory");
|
helptext.Add(" -out= Output directory");
|
||||||
helptext.Add(" -t=, --temp= Set the temporary directory to use");
|
helptext.Add(" -t=, --temp= Set the temporary directory to use");
|
||||||
@@ -295,13 +314,12 @@ namespace SabreTools.Helper.Data
|
|||||||
helptext.Add(" -h=, --header= Set a header skipper to use, blank means all");
|
helptext.Add(" -h=, --header= Set a header skipper to use, blank means all");
|
||||||
helptext.Add(" -ud, --update-dat Output updated DAT to output directory");
|
helptext.Add(" -ud, --update-dat Output updated DAT to output directory");
|
||||||
helptext.Add(" -mt={4} Amount of threads to use (-1 unlimted)");
|
helptext.Add(" -mt={4} Amount of threads to use (-1 unlimted)");
|
||||||
}
|
break;
|
||||||
|
|
||||||
// Stats
|
// Stats
|
||||||
if (subset == null || subset == "st" || subset == "stats")
|
case "st":
|
||||||
{
|
case "stats":
|
||||||
helptext.Add("");
|
helptext.Add("Available Flags:");
|
||||||
helptext.Add(" -st, --stats Get statistics on all input DATs");
|
|
||||||
helptext.Add(" -bc, --baddump-col Add baddump stats to output");
|
helptext.Add(" -bc, --baddump-col Add baddump stats to output");
|
||||||
helptext.Add(" -csv, --csv Output in Comma-Separated Value format");
|
helptext.Add(" -csv, --csv Output in Comma-Separated Value format");
|
||||||
helptext.Add(" -f=, --filename= Set the filename for the output");
|
helptext.Add(" -f=, --filename= Set the filename for the output");
|
||||||
@@ -310,21 +328,19 @@ namespace SabreTools.Helper.Data
|
|||||||
helptext.Add(" -nc, --nodump-col Add nodump stats to output");
|
helptext.Add(" -nc, --nodump-col Add nodump stats to output");
|
||||||
helptext.Add(" -si, --single Show individual statistics");
|
helptext.Add(" -si, --single Show individual statistics");
|
||||||
helptext.Add(" -tsv, --tsv Output in Tab-Separated Value format");
|
helptext.Add(" -tsv, --tsv Output in Tab-Separated Value format");
|
||||||
}
|
break;
|
||||||
|
|
||||||
// Type Split
|
// Type Split
|
||||||
if (subset == null || subset == "ts" || subset == "type-split")
|
case "ts":
|
||||||
{
|
case "type-split":
|
||||||
helptext.Add("");
|
helptext.Add("Available Flags:");
|
||||||
helptext.Add(" -ts, --type-split Split a DAT or folder by file types (rom/disk)");
|
|
||||||
helptext.Add(" -out= Output directory");
|
helptext.Add(" -out= Output directory");
|
||||||
}
|
break;
|
||||||
|
|
||||||
// Update
|
// Update
|
||||||
if (subset == null || subset == "ud" || subset == "update")
|
case "ud":
|
||||||
{
|
case "update":
|
||||||
helptext.Add("");
|
helptext.Add("Available Flags:");
|
||||||
helptext.Add(" -ud, --update Update a DAT file");
|
|
||||||
helptext.Add(" -oa, --output-all Output in all formats");
|
helptext.Add(" -oa, --output-all Output in all formats");
|
||||||
helptext.Add(" -oam, --output-am Output in AttractMode format");
|
helptext.Add(" -oam, --output-am Output in AttractMode format");
|
||||||
helptext.Add(" -oc, --output-cmp Output in CMP format");
|
helptext.Add(" -oc, --output-cmp Output in CMP format");
|
||||||
@@ -444,42 +460,7 @@ namespace SabreTools.Helper.Data
|
|||||||
helptext.Add(" -nrun, --not-run Include only items that are marked unrunnable");
|
helptext.Add(" -nrun, --not-run Include only items that are marked unrunnable");
|
||||||
helptext.Add(" -out= Output directory (overridden by --inplace)");
|
helptext.Add(" -out= Output directory (overridden by --inplace)");
|
||||||
helptext.Add(" -mt={4} Amount of threads to use (-1 unlimted)");
|
helptext.Add(" -mt={4} Amount of threads to use (-1 unlimted)");
|
||||||
}
|
|
||||||
|
|
||||||
// Verify
|
|
||||||
if (subset == null || subset == "ve" || subset == "verify")
|
|
||||||
{
|
|
||||||
helptext.Add("");
|
|
||||||
helptext.Add(" -ve, --verify Verify a folder against DATs");
|
|
||||||
helptext.Add(" -dat= Input DAT to verify against");
|
|
||||||
helptext.Add(" -t=, --temp= Set the temporary directory to use");
|
|
||||||
helptext.Add(" -ho, --hash-only Check files by hash only");
|
|
||||||
helptext.Add(" -qs, --quick Enable quick scanning of archives");
|
|
||||||
helptext.Add(" -h=, --header= Set a header skipper to use, blank means all");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify Depot
|
|
||||||
if (subset == null || subset == "ved" || subset == "verify-depot")
|
|
||||||
{
|
|
||||||
helptext.Add("");
|
|
||||||
helptext.Add(" -ved, --verify-depot Verify a folder against DATs");
|
|
||||||
helptext.Add(" -dat= Input DAT to verify against");
|
|
||||||
helptext.Add(" -t=, --temp= Set the temporary directory to use");
|
|
||||||
helptext.Add(" -h=, --header= Set a header skipper to use, blank means all");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Additional notes
|
|
||||||
if (subset == null || subset == "ss" || subset == "sort")
|
|
||||||
{
|
|
||||||
helptext.Add("");
|
|
||||||
helptext.Add("Archive scanning levels:");
|
|
||||||
helptext.Add(" 0 Hash archive and contents");
|
|
||||||
helptext.Add(" 1 Only hash contents");
|
|
||||||
helptext.Add(" 2 Only hash archive");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (subset == null || subset == "ud" || subset == "update")
|
|
||||||
{
|
|
||||||
helptext.Add("");
|
helptext.Add("");
|
||||||
helptext.Add("Filter parameters game name, rom name, CRC, MD5, SHA-1 can");
|
helptext.Add("Filter parameters game name, rom name, CRC, MD5, SHA-1 can");
|
||||||
helptext.Add("do partial matches using asterisks as follows (case insensitive):");
|
helptext.Add("do partial matches using asterisks as follows (case insensitive):");
|
||||||
@@ -495,6 +476,33 @@ namespace SabreTools.Helper.Data
|
|||||||
helptext.Add("");
|
helptext.Add("");
|
||||||
helptext.Add("Most of the filter parameters allow for multiple inputs:");
|
helptext.Add("Most of the filter parameters allow for multiple inputs:");
|
||||||
helptext.Add(" e.g. --game-name=foo --game-name=bar");
|
helptext.Add(" e.g. --game-name=foo --game-name=bar");
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
case "ve":
|
||||||
|
case "verify":
|
||||||
|
helptext.Add("Available Flags:");
|
||||||
|
helptext.Add(" -dat= Input DAT to verify against");
|
||||||
|
helptext.Add(" -t=, --temp= Set the temporary directory to use");
|
||||||
|
helptext.Add(" -ho, --hash-only Check files by hash only");
|
||||||
|
helptext.Add(" -qs, --quick Enable quick scanning of archives");
|
||||||
|
helptext.Add(" -h=, --header= Set a header skipper to use, blank means all");
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Verify Depot
|
||||||
|
case "ved":
|
||||||
|
case "verify-depot":
|
||||||
|
helptext.Add("Available Flags:");
|
||||||
|
helptext.Add(" -dat= Input DAT to verify against");
|
||||||
|
helptext.Add(" -t=, --temp= Set the temporary directory to use");
|
||||||
|
helptext.Add(" -h=, --header= Set a header skipper to use, blank means all");
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Default
|
||||||
|
default:
|
||||||
|
helptext.Add("Available Flags:");
|
||||||
|
helptext.Add(" No flags found for " + subset);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -290,13 +290,13 @@ Options:
|
|||||||
to be split. Files with any extensions not listed in the input lists will be included
|
to be split. Files with any extensions not listed in the input lists will be included
|
||||||
in both outputted DAT files.
|
in both outputted DAT files.
|
||||||
|
|
||||||
-exta= First set of extensions (comma-separated)
|
-exta= First extension (multiple allowed)
|
||||||
Set the extensions to be used to populate the first DAT. If more than one
|
Set the extensions to be used to populate the first DAT. If more than one
|
||||||
extension is defined, they must be separated by commas.
|
extension is defined, they must be placed in separate flags.
|
||||||
|
|
||||||
-extb= Second set of extensions (comma-separated)
|
-extb= Second extension (multiple allowed)
|
||||||
Set the extensions to be used to populate the second DAT. If more than one
|
Set the extensions to be used to populate the second DAT. If more than one
|
||||||
extension is defined, they must be separated by commas.
|
extension is defined, they must be placed in separate flags.
|
||||||
|
|
||||||
-out= Set the name of the output directory
|
-out= Set the name of the output directory
|
||||||
This sets an output folder to be used when the files are created. If a path
|
This sets an output folder to be used when the files are created. If a path
|
||||||
|
|||||||
@@ -165,12 +165,8 @@ namespace SabreTools
|
|||||||
/// <param name="exta">First extension to split on</param>
|
/// <param name="exta">First extension to split on</param>
|
||||||
/// <param name="extb">Second extension to split on</param>
|
/// <param name="extb">Second extension to split on</param>
|
||||||
/// <param name="outDir">Output directory for the split files</param>
|
/// <param name="outDir">Output directory for the split files</param>
|
||||||
private static void InitExtSplit(List<string> inputs, string exta, string extb, string outDir)
|
private static void InitExtSplit(List<string> inputs, List<string> exta, List<string> extb, string outDir)
|
||||||
{
|
{
|
||||||
// Convert comma-separated strings to list
|
|
||||||
List<string> extaList = exta.Split(',').ToList();
|
|
||||||
List<string> extbList = extb.Split(',').ToList();
|
|
||||||
|
|
||||||
// Loop over the input files
|
// Loop over the input files
|
||||||
foreach (string input in inputs)
|
foreach (string input in inputs)
|
||||||
{
|
{
|
||||||
@@ -178,7 +174,7 @@ namespace SabreTools
|
|||||||
{
|
{
|
||||||
DatFile datFile = new DatFile();
|
DatFile datFile = new DatFile();
|
||||||
datFile.Parse(Path.GetFullPath(input), 0, 0, _logger, softlist: true);
|
datFile.Parse(Path.GetFullPath(input), 0, 0, _logger, softlist: true);
|
||||||
datFile.SplitByExt(outDir, Path.GetDirectoryName(input), extaList, extbList, _logger);
|
datFile.SplitByExt(outDir, Path.GetDirectoryName(input), exta, extb, _logger);
|
||||||
}
|
}
|
||||||
else if (Directory.Exists(input))
|
else if (Directory.Exists(input))
|
||||||
{
|
{
|
||||||
@@ -186,7 +182,7 @@ namespace SabreTools
|
|||||||
{
|
{
|
||||||
DatFile datFile = new DatFile();
|
DatFile datFile = new DatFile();
|
||||||
datFile.Parse(Path.GetFullPath(file), 0, 0, _logger, softlist: true);
|
datFile.Parse(Path.GetFullPath(file), 0, 0, _logger, softlist: true);
|
||||||
datFile.SplitByExt(outDir, (input.EndsWith(Path.DirectorySeparatorChar.ToString()) ? input : input + Path.DirectorySeparatorChar), extaList, extbList, _logger);
|
datFile.SplitByExt(outDir, (input.EndsWith(Path.DirectorySeparatorChar.ToString()) ? input : input + Path.DirectorySeparatorChar), exta, extb, _logger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -124,8 +124,6 @@ namespace SabreTools
|
|||||||
date = null,
|
date = null,
|
||||||
description = null,
|
description = null,
|
||||||
email = null,
|
email = null,
|
||||||
exta = null,
|
|
||||||
extb = null,
|
|
||||||
filename = null,
|
filename = null,
|
||||||
forcemerge = "",
|
forcemerge = "",
|
||||||
forcend = "",
|
forcend = "",
|
||||||
@@ -144,8 +142,8 @@ namespace SabreTools
|
|||||||
version = null;
|
version = null;
|
||||||
List<string> crc = new List<string>();
|
List<string> crc = new List<string>();
|
||||||
List<string> datfiles = new List<string>();
|
List<string> datfiles = new List<string>();
|
||||||
//List<string> exta = new List<string>();
|
List<string> exta = new List<string>();
|
||||||
//List<string> extb = new List<string>();
|
List<string> extb = new List<string>();
|
||||||
List<string> gamename = new List<string>();
|
List<string> gamename = new List<string>();
|
||||||
List<string> gametype = new List<string>();
|
List<string> gametype = new List<string>();
|
||||||
List<string> inputs = new List<string>();
|
List<string> inputs = new List<string>();
|
||||||
@@ -563,11 +561,11 @@ namespace SabreTools
|
|||||||
break;
|
break;
|
||||||
case "-exta":
|
case "-exta":
|
||||||
case "--exta":
|
case "--exta":
|
||||||
exta = args[++i];
|
exta.Add(args[++i]);
|
||||||
break;
|
break;
|
||||||
case "-extb":
|
case "-extb":
|
||||||
case "--extb":
|
case "--extb":
|
||||||
extb = args[++i];
|
extb.Add(args[++i]);
|
||||||
break;
|
break;
|
||||||
case "-fi":
|
case "-fi":
|
||||||
case "--filename":
|
case "--filename":
|
||||||
@@ -796,11 +794,11 @@ namespace SabreTools
|
|||||||
break;
|
break;
|
||||||
case "-exta":
|
case "-exta":
|
||||||
case "--exta":
|
case "--exta":
|
||||||
exta = split[1];
|
exta.Add(split[1]);
|
||||||
break;
|
break;
|
||||||
case "-extb":
|
case "-extb":
|
||||||
case "--extb":
|
case "--extb":
|
||||||
extb = split[1];
|
extb.Add(split[1]);
|
||||||
break;
|
break;
|
||||||
case "-f":
|
case "-f":
|
||||||
case "--filename":
|
case "--filename":
|
||||||
|
|||||||
Reference in New Issue
Block a user