mirror of
https://github.com/SabreTools/SabreTools.Serialization.git
synced 2026-02-04 05:36:12 +00:00
Add and implement IExtractable
This commit is contained in:
@@ -46,6 +46,7 @@ Below is a table representing the various non-conversion interfaces that are imp
|
||||
|
||||
| Interface Name | Purpose |
|
||||
| --- | --- |
|
||||
| `IExtractable` | Marks a wrapper as able to be extracted |
|
||||
| `IPrinter` | Provides a formatted output for a model |
|
||||
| `IWrapper` / `IWrapper<T>` | Wraps a model or set of models to provide additional functionality |
|
||||
|
||||
|
||||
16
SabreTools.Serialization/Interfaces/IExtractable.cs
Normal file
16
SabreTools.Serialization/Interfaces/IExtractable.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
namespace SabreTools.Serialization.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an item that is extractable
|
||||
/// </summary>
|
||||
public interface IExtractable
|
||||
{
|
||||
/// <summary>
|
||||
/// Extract to an output directory
|
||||
/// </summary>
|
||||
/// <param name="outputDirectory">Output directory to write to</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>True if extraction succeeded, false otherwise</returns>
|
||||
bool Extract(string outputDirectory, bool includeDebug);
|
||||
}
|
||||
}
|
||||
@@ -2,10 +2,11 @@
|
||||
using System.IO;
|
||||
using SabreTools.IO.Compression.Deflate;
|
||||
using SabreTools.Models.BFPK;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
public class BFPK : WrapperBase<Archive>
|
||||
public class BFPK : WrapperBase<Archive>, IExtractable
|
||||
{
|
||||
#region Descriptive Properties
|
||||
|
||||
@@ -87,13 +88,8 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
#region Extraction
|
||||
|
||||
/// <summary>
|
||||
/// Extract all files from the BFPK to an output directory
|
||||
/// </summary>
|
||||
/// <param name="outputDirectory">Output directory to write to</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>True if all files extracted, false otherwise</returns>
|
||||
public bool ExtractAll(string outputDirectory, bool includeDebug)
|
||||
/// <inheritdoc/>
|
||||
public bool Extract(string outputDirectory, bool includeDebug)
|
||||
{
|
||||
// If we have no files
|
||||
if (Files == null || Files.Length == 0)
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using SabreTools.Models.BSP;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
public class BSP : WrapperBase<BspFile>
|
||||
public class BSP : WrapperBase<BspFile>, IExtractable
|
||||
{
|
||||
#region Descriptive Properties
|
||||
|
||||
@@ -86,13 +87,8 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
#region Extraction
|
||||
|
||||
/// <summary>
|
||||
/// Extract all lumps from the BSP to an output directory
|
||||
/// </summary>
|
||||
/// <param name="outputDirectory">Output directory to write to</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>True if all lumps extracted, false otherwise</returns>
|
||||
public bool ExtractAllLumps(string outputDirectory, bool includeDebug)
|
||||
/// <inheritdoc/>
|
||||
public bool Extract(string outputDirectory, bool includeDebug)
|
||||
{
|
||||
// If we have no lumps
|
||||
if (Lumps == null || Lumps.Length == 0)
|
||||
|
||||
@@ -4,10 +4,11 @@ using System.IO;
|
||||
using System.Text;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Models.CFB;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
public class CFB : WrapperBase<Binary>
|
||||
public class CFB : WrapperBase<Binary>, IExtractable
|
||||
{
|
||||
#region Descriptive Properties
|
||||
|
||||
@@ -133,13 +134,8 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
#region Extraction
|
||||
|
||||
/// <summary>
|
||||
/// Extract all files from the CFB to an output directory
|
||||
/// </summary>
|
||||
/// <param name="outputDirectory">Output directory to write to</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>True if all files extracted, false otherwise</returns>
|
||||
public bool ExtractAll(string outputDirectory, bool includeDebug)
|
||||
/// <inheritdoc/>
|
||||
public bool Extract(string outputDirectory, bool includeDebug)
|
||||
{
|
||||
// If we have no files
|
||||
if (DirectoryEntries == null || DirectoryEntries.Length == 0)
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
public class GCF : WrapperBase<Models.GCF.File>
|
||||
public class GCF : WrapperBase<Models.GCF.File>, IExtractable
|
||||
{
|
||||
#region Descriptive Properties
|
||||
|
||||
@@ -228,13 +229,8 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
#region Extraction
|
||||
|
||||
/// <summary>
|
||||
/// Extract all files from the GCF to an output directory
|
||||
/// </summary>
|
||||
/// <param name="outputDirectory">Output directory to write to</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>True if all files extracted, false otherwise</returns>
|
||||
public bool ExtractAll(string outputDirectory, bool includeDebug)
|
||||
/// <inheritdoc/>
|
||||
public bool Extract(string outputDirectory, bool includeDebug)
|
||||
{
|
||||
// If we have no files
|
||||
if (Files == null || Files.Length == 0)
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using SabreTools.IO.Compression.Blast;
|
||||
using SabreTools.Models.InstallShieldArchiveV3;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
@@ -10,7 +11,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
/// Reference (de)compressor: https://www.sac.sk/download/pack/icomp95.zip
|
||||
/// </remarks>
|
||||
/// <see href="https://github.com/wfr/unshieldv3"/>
|
||||
public partial class InstallShieldArchiveV3 : WrapperBase<Archive>
|
||||
public partial class InstallShieldArchiveV3 : WrapperBase<Archive>, IExtractable
|
||||
{
|
||||
#region Descriptive Properties
|
||||
|
||||
@@ -173,13 +174,8 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
#region Extraction
|
||||
|
||||
/// <summary>
|
||||
/// Extract all files from the ISAv3 to an output directory
|
||||
/// </summary>
|
||||
/// <param name="outputDirectory">Output directory to write to</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>True if all files extracted, false otherwise</returns>
|
||||
public bool ExtractAll(string outputDirectory, bool includeDebug)
|
||||
/// <inheritdoc/>
|
||||
public bool Extract(string outputDirectory, bool includeDebug)
|
||||
{
|
||||
// Get the file count
|
||||
int fileCount = Files.Length;
|
||||
|
||||
@@ -2,10 +2,11 @@ using System;
|
||||
using System.IO;
|
||||
using SabreTools.IO.Compression.SZDD;
|
||||
using SabreTools.Models.LZ;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
public class LZKWAJ : WrapperBase<KWAJFile>
|
||||
public class LZKWAJ : WrapperBase<KWAJFile>, IExtractable
|
||||
{
|
||||
#region Descriptive Properties
|
||||
|
||||
@@ -96,12 +97,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
#region Extraction
|
||||
|
||||
/// <summary>
|
||||
/// Extract the contents to an output directory
|
||||
/// </summary>
|
||||
/// <param name="outputDirectory">Output directory to write to</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>True if the contents extracted, false otherwise</returns>
|
||||
/// <inheritdoc/>
|
||||
public bool Extract(string outputDirectory, bool includeDebug)
|
||||
{
|
||||
// Get the length of the compressed data
|
||||
|
||||
@@ -2,10 +2,11 @@ using System;
|
||||
using System.IO;
|
||||
using SabreTools.IO.Compression.SZDD;
|
||||
using SabreTools.Models.LZ;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
public class LZQBasic : WrapperBase<QBasicFile>
|
||||
public class LZQBasic : WrapperBase<QBasicFile>, IExtractable
|
||||
{
|
||||
#region Descriptive Properties
|
||||
|
||||
@@ -80,12 +81,7 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
#region Extraction
|
||||
|
||||
/// <summary>
|
||||
/// Extract the contents to an output directory
|
||||
/// </summary>
|
||||
/// <param name="outputDirectory">Output directory to write to</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>True if the contents extracted, false otherwise</returns>
|
||||
/// <inheritdoc/>
|
||||
public bool Extract(string outputDirectory, bool includeDebug)
|
||||
{
|
||||
// Get the length of the compressed data
|
||||
|
||||
@@ -2,10 +2,11 @@ using System;
|
||||
using System.IO;
|
||||
using SabreTools.IO.Compression.SZDD;
|
||||
using SabreTools.Models.LZ;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
public class LZSZDD : WrapperBase<SZDDFile>
|
||||
public class LZSZDD : WrapperBase<SZDDFile>, IExtractable
|
||||
{
|
||||
#region Descriptive Properties
|
||||
|
||||
@@ -87,13 +88,12 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
#region Extraction
|
||||
|
||||
/// <summary>
|
||||
/// Extract the contents to an output directory
|
||||
/// </summary>
|
||||
/// <param name="filename">Original filename to use as a base</param>
|
||||
/// <param name="outputDirectory">Output directory to write to</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>True if the contents extracted, false otherwise</returns>
|
||||
/// <inheritdoc/>
|
||||
public bool Extract(string outputDirectory, bool includeDebug)
|
||||
=> Extract(string.Empty, outputDirectory, includeDebug);
|
||||
|
||||
/// <inheritdoc cref="Extract(string, bool)"/>
|
||||
/// <param name="filename">Original name of the file to convert to the output name</param>
|
||||
public bool Extract(string filename, string outputDirectory, bool includeDebug)
|
||||
{
|
||||
// Get the length of the compressed data
|
||||
|
||||
@@ -3,10 +3,11 @@ using System.IO;
|
||||
using SabreTools.IO.Compression.MSZIP;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Models.MicrosoftCabinet;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
public partial class MicrosoftCabinet : WrapperBase<Cabinet>
|
||||
public partial class MicrosoftCabinet : WrapperBase<Cabinet>, IExtractable
|
||||
{
|
||||
#region Descriptive Properties
|
||||
|
||||
@@ -171,13 +172,12 @@ namespace SabreTools.Serialization.Wrappers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract a cabinet file from a set to an output directory, if possible
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
public bool Extract(string outputDirectory, bool includeDebug)
|
||||
=> Extract(null, outputDirectory, includeDebug);
|
||||
|
||||
/// <inheritdoc cref="Extract(string, bool)"/>
|
||||
/// <param name="filename">Filename for one cabinet in the set, if available</param>
|
||||
/// <param name="outDir">Path to the output directory</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>Indicates if all files were able to be extracted</returns>
|
||||
public bool Extract(string? filename, string outDir, bool includeDebug)
|
||||
{
|
||||
// If the archive is invalid
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using SabreTools.Models.PAK;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
public class PAK : WrapperBase<Models.PAK.File>
|
||||
public class PAK : WrapperBase<Models.PAK.File>, IExtractable
|
||||
{
|
||||
#region Descriptive Properties
|
||||
|
||||
@@ -86,13 +87,8 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
#region Extraction
|
||||
|
||||
/// <summary>
|
||||
/// Extract all files from the PAK to an output directory
|
||||
/// </summary>
|
||||
/// <param name="outputDirectory">Output directory to write to</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>True if all files extracted, false otherwise</returns>
|
||||
public bool ExtractAll(string outputDirectory, bool includeDebug)
|
||||
/// <inheritdoc/>
|
||||
public bool Extract(string outputDirectory, bool includeDebug)
|
||||
{
|
||||
// If we have no directory items
|
||||
if (DirectoryItems == null || DirectoryItems.Length == 0)
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using SabreTools.Models.PFF;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
public class PFF : WrapperBase<Archive>
|
||||
public class PFF : WrapperBase<Archive>, IExtractable
|
||||
{
|
||||
#region Descriptive Properties
|
||||
|
||||
@@ -91,13 +92,8 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
#region Extraction
|
||||
|
||||
/// <summary>
|
||||
/// Extract all segments from the PFF to an output directory
|
||||
/// </summary>
|
||||
/// <param name="outputDirectory">Output directory to write to</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>True if all segments extracted, false otherwise</returns>
|
||||
public bool ExtractAll(string outputDirectory, bool includeDebug)
|
||||
/// <inheritdoc/>
|
||||
public bool Extract(string outputDirectory, bool includeDebug)
|
||||
{
|
||||
// If we have no segments
|
||||
if (Segments == null || Segments.Length == 0)
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using SabreTools.Models.Quantum;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
public class Quantum : WrapperBase<Archive>
|
||||
public class Quantum : WrapperBase<Archive>, IExtractable
|
||||
{
|
||||
#region Descriptive Properties
|
||||
|
||||
@@ -95,13 +96,8 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
#region Extraction
|
||||
|
||||
/// <summary>
|
||||
/// Extract all files from the Quantum archive to an output directory
|
||||
/// </summary>
|
||||
/// <param name="outputDirectory">Output directory to write to</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>True if all files extracted, false otherwise</returns>
|
||||
public bool ExtractAll(string outputDirectory, bool includeDebug)
|
||||
/// <inheritdoc/>
|
||||
public bool Extract(string outputDirectory, bool includeDebug)
|
||||
{
|
||||
// If we have no files
|
||||
if (FileList == null || FileList.Length == 0)
|
||||
|
||||
@@ -3,10 +3,11 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using SabreTools.IO.Compression.zlib;
|
||||
using SabreTools.Models.SGA;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
public class SGA : WrapperBase<Archive>
|
||||
public class SGA : WrapperBase<Archive>, IExtractable
|
||||
{
|
||||
#region Descriptive Properties
|
||||
|
||||
@@ -124,13 +125,8 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
#region Extraction
|
||||
|
||||
/// <summary>
|
||||
/// Extract all files from the SGA to an output directory
|
||||
/// </summary>
|
||||
/// <param name="outputDirectory">Output directory to write to</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>True if all files extracted, false otherwise</returns>
|
||||
public bool ExtractAll(string outputDirectory, bool includeDebug)
|
||||
/// <inheritdoc/>
|
||||
public bool Extract(string outputDirectory, bool includeDebug)
|
||||
{
|
||||
// Get the file count
|
||||
int fileCount = FileCount;
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using SabreTools.Models.BSP;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
public class VBSP : WrapperBase<VbspFile>
|
||||
public class VBSP : WrapperBase<VbspFile>, IExtractable
|
||||
{
|
||||
#region Descriptive Properties
|
||||
|
||||
@@ -86,13 +87,8 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
#region Extraction
|
||||
|
||||
/// <summary>
|
||||
/// Extract all lumps from the VBSP to an output directory
|
||||
/// </summary>
|
||||
/// <param name="outputDirectory">Output directory to write to</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>True if all lumps extracted, false otherwise</returns>
|
||||
public bool ExtractAllLumps(string outputDirectory, bool includeDebug)
|
||||
/// <inheritdoc/>
|
||||
public bool Extract(string outputDirectory, bool includeDebug)
|
||||
{
|
||||
// If we have no lumps
|
||||
if (Lumps == null || Lumps.Length == 0)
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using SabreTools.IO.Extensions;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
using static SabreTools.Models.VPK.Constants;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
public class VPK : WrapperBase<Models.VPK.File>
|
||||
public class VPK : WrapperBase<Models.VPK.File>, IExtractable
|
||||
{
|
||||
#region Descriptive Properties
|
||||
|
||||
@@ -151,13 +152,8 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
#region Extraction
|
||||
|
||||
/// <summary>
|
||||
/// Extract all files from the VPK to an output directory
|
||||
/// </summary>
|
||||
/// <param name="outputDirectory">Output directory to write to</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>True if all files extracted, false otherwise</returns>
|
||||
public bool ExtractAll(string outputDirectory, bool includeDebug)
|
||||
/// <inheritdoc/>
|
||||
public bool Extract(string outputDirectory, bool includeDebug)
|
||||
{
|
||||
// If we have no directory items
|
||||
if (DirectoryItems == null || DirectoryItems.Length == 0)
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
public class WAD3 : WrapperBase<Models.WAD3.File>
|
||||
public class WAD3 : WrapperBase<Models.WAD3.File>, IExtractable
|
||||
{
|
||||
#region Descriptive Properties
|
||||
|
||||
@@ -85,13 +86,8 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
#region Extraction
|
||||
|
||||
/// <summary>
|
||||
/// Extract all lumps from the WAD3 to an output directory
|
||||
/// </summary>
|
||||
/// <param name="outputDirectory">Output directory to write to</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>True if all lumps extracted, false otherwise</returns>
|
||||
public bool ExtractAllLumps(string outputDirectory, bool includeDebug)
|
||||
/// <inheritdoc/>
|
||||
public bool Extract(string outputDirectory, bool includeDebug)
|
||||
{
|
||||
// If we have no lumps
|
||||
if (DirEntries == null || DirEntries.Length == 0)
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using SabreTools.Serialization.Interfaces;
|
||||
|
||||
namespace SabreTools.Serialization.Wrappers
|
||||
{
|
||||
public class XZP : WrapperBase<Models.XZP.File>
|
||||
public class XZP : WrapperBase<Models.XZP.File>, IExtractable
|
||||
{
|
||||
#region Descriptive Properties
|
||||
|
||||
@@ -88,13 +89,8 @@ namespace SabreTools.Serialization.Wrappers
|
||||
|
||||
#region Extraction
|
||||
|
||||
/// <summary>
|
||||
/// Extract all files from the XZP to an output directory
|
||||
/// </summary>
|
||||
/// <param name="outputDirectory">Output directory to write to</param>
|
||||
/// <param name="includeDebug">True to include debug data, false otherwise</param>
|
||||
/// <returns>True if all files extracted, false otherwise</returns>
|
||||
public bool ExtractAll(string outputDirectory, bool includeDebug)
|
||||
/// <inheritdoc/>
|
||||
public bool Extract(string outputDirectory, bool includeDebug)
|
||||
{
|
||||
// If we have no directory entries
|
||||
if (DirectoryEntries == null || DirectoryEntries.Length == 0)
|
||||
|
||||
Reference in New Issue
Block a user