forked from sin365/AxibugEmuOnline
272 lines
8.9 KiB
C#
272 lines
8.9 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Runtime.Serialization.Formatters.Binary;
|
||
|
||
[Serializable]
|
||
public class AxiEssgssStatusData
|
||
{
|
||
public Dictionary<string, byte[]> MemberData = new Dictionary<string, byte[]>();
|
||
public Dictionary<string, AxiEssgssStatusData_2DArray> Array2DMemberData = new Dictionary<string, AxiEssgssStatusData_2DArray>();
|
||
public Dictionary<string, AxiEssgssStatusData> ClassData = new Dictionary<string, AxiEssgssStatusData>();
|
||
}
|
||
|
||
|
||
[Serializable]
|
||
public class AxiEssgssStatusData_2DArray
|
||
{
|
||
public int rows;
|
||
public int cols;
|
||
public byte[] array1D;
|
||
public AxiEssgssStatusData_2DArray(byte[,] data2D)
|
||
{
|
||
rows = data2D.GetLength(0);
|
||
cols = data2D.GetLength(1);
|
||
array1D = data2D.FlattenByteArray2D();
|
||
}
|
||
|
||
public byte[,] Get2DArrayBytesData()
|
||
{
|
||
return array1D.CreateByteArray2D(rows, cols);
|
||
}
|
||
}
|
||
internal static class AxiEssgssStatusDataExtention
|
||
{
|
||
internal static byte[] ToByteArray(this AxiEssgssStatusData data)
|
||
{
|
||
return AxiStatus.saveCover.ToByteArray(data);
|
||
}
|
||
|
||
internal static AxiEssgssStatusData ToAxiEssgssStatusData(this byte[] byteArray)
|
||
{
|
||
return AxiStatus.saveCover.ToAxiEssgssStatusData(byteArray);
|
||
}
|
||
}
|
||
public interface IAxiEssgssStatus
|
||
{
|
||
public void LoadAxiStatus(AxiEssgssStatusData data);
|
||
public AxiEssgssStatusData SaveAxiStatus();
|
||
}
|
||
|
||
public interface IAxiEssgssStatusBytesCover
|
||
{
|
||
public byte[] ToByteArray(AxiEssgssStatusData data);
|
||
public AxiEssgssStatusData ToAxiEssgssStatusData(byte[] byteArray);
|
||
}
|
||
|
||
internal static class AxiStatus
|
||
{
|
||
public static IAxiEssgssStatusBytesCover saveCover { get; private set; }
|
||
public static void Init(IAxiEssgssStatusBytesCover coverter)
|
||
{
|
||
saveCover = coverter;
|
||
}
|
||
// ½«ÈÎÒâö¾ÙÊý×éת»»Îªbyte[]
|
||
public static byte[] ToByteArray<TEnum>(this TEnum[] enumArray) where TEnum : struct, Enum
|
||
{
|
||
if (!typeof(TEnum).IsEnum) throw new ArgumentException("TEnum must be an enumerated type");
|
||
|
||
// »ñȡö¾ÙµÄ»ù´¡ÀàÐÍ£¨Í¨³£ÊÇInt32£©
|
||
Type enumUnderlyingType = Enum.GetUnderlyingType(typeof(TEnum));
|
||
if (enumUnderlyingType != typeof(byte)) // ¼ì²é»ù´¡ÀàÐÍÊÇ·ñΪbyte£¬Èç¹û²»ÊÇ£¬ÔòÐèÒª½øÐжîÍâµÄ´¦Àí
|
||
{
|
||
// Èç¹û»ù´¡ÀàÐͲ»ÊÇbyte£¬ÎÒÃÇÐèÒª¾ö¶¨ÈçºÎ´¦Àí¡£ÕâÀïÎÒÃǼÙÉè»ù´¡ÀàÐÍÊÇint£¬²¢½«Æäת»»ÎªbyteÊý×飬
|
||
// µ«Òª×¢Ò⣬Õâ¿ÉÄܻᵼÖÂÊý¾Ý¶ªÊ§£¨Èç¹ûö¾ÙÖµ³¬³öÁËbyteµÄ·¶Î§£©¡£
|
||
// Ò»¸ö¸ü°²È«µÄ·½·¨ÊÇʹÓøü´óµÄÊý¾ÝÀàÐÍ£¨Èçint[]£©×÷ΪÖмä±íʾ¡£
|
||
// µ«ÎªÁ˼ò»¯Ê¾Àý£¬ÎÒÃǽ«¼ÌÐø²¢¼ÙÉèËùÓÐö¾ÙÖµ¶¼¿ÉÒÔ°²È«µØת»»Îªbyte¡£
|
||
// ¾¯¸æ£ºÕâ¸ö¼ÙÉè¿ÉÄܲ»ÊÊÓÃÓÚËùÓÐÇé¿ö£¡
|
||
|
||
// ÓÉÓÚÎÒÃǼÙÉè»ù´¡ÀàÐÍÊÇint£¨ÕâÊÇ×î³£¼ûµÄö¾Ù»ù´¡ÀàÐÍ£©£¬ÎÒÃÇ¿ÉÒÔÖ±½Óת»»Ã¿¸öö¾ÙֵΪint£¬
|
||
// È»ºó¼ì²éËüÃÇÊÇ·ñ¿ÉÒÔ°²È«µØת»»Îªbyte¡£Èç¹û²»ÄÜ£¬ÕâÀォÅ׳öÒì³£¡£
|
||
return enumArray.Select(e =>
|
||
{
|
||
int intValue = Convert.ToInt32(e);
|
||
if (intValue < byte.MinValue || intValue > byte.MaxValue)
|
||
throw new OverflowException($"Enum value {e} ({intValue}) is out of range for byte.");
|
||
return (byte)intValue;
|
||
}).ToArray();
|
||
}
|
||
else
|
||
{
|
||
// Èç¹û»ù´¡ÀàÐÍÒѾÊÇbyte£¬ÔòÖ±½Óת»»
|
||
return Array.ConvertAll(enumArray, e => Convert.ToByte(e));
|
||
}
|
||
}
|
||
|
||
// ´Óbyte[]ת»»ÎªÈÎÒâö¾ÙÊý×é
|
||
public static TEnum[] ToEnumArray<TEnum>(this byte[] byteArray) where TEnum : struct, Enum
|
||
{
|
||
if (!typeof(TEnum).IsEnum) throw new ArgumentException("TEnum must be an enumerated type");
|
||
|
||
// Ö±½Óת»»Ã¿¸öbyteΪö¾ÙÖµ
|
||
return Array.ConvertAll(byteArray, b => (TEnum)Enum.ToObject(typeof(TEnum), b));
|
||
}
|
||
|
||
// ½«µ¥¸öö¾Ùת»»Îªbyte[]£¨Í¨³£Õâ¸öת»»²»Ì«³£¼û£¬ÒòΪ½á¹û½«Ö»ÓÐÒ»¸ö×Ö½Ú£¬µ«ÎÒÃÇ»¹ÊÇʵÏÖËü£©
|
||
public static byte[] ToByteArray<TEnum>(this TEnum enumValue) where TEnum : struct, Enum
|
||
{
|
||
if (!typeof(TEnum).IsEnum) throw new ArgumentException("TEnum must be an enumerated type");
|
||
|
||
// »ñȡö¾ÙµÄ»ù´¡ÀàÐÍ
|
||
Type enumUnderlyingType = Enum.GetUnderlyingType(typeof(TEnum));
|
||
|
||
// ¼ì²é»ù´¡ÀàÐÍÊÇ·ñΪbyte£¬Èç¹û²»ÊÇ£¬Ôò½øÐÐת»»£¨ÕâÀïÎÒÃǼÙÉè¿ÉÒÔ°²È«µØת»»Îªbyte£¬µ«Í¨³£Ã¶¾ÙµÄ»ù´¡ÀàÐÍÊÇint£©
|
||
if (enumUnderlyingType == typeof(byte))
|
||
{
|
||
// Èç¹û»ù´¡ÀàÐÍÒѾÊÇbyte£¬ÔòÖ±½Ó·µ»Ø°üº¬¸Ã×Ö½ÚµÄÊý×é
|
||
return new[] { Convert.ToByte(enumValue) };
|
||
}
|
||
else if (enumUnderlyingType == typeof(int)) // ×î³£¼ûµÄö¾Ù»ù´¡ÀàÐÍ
|
||
{
|
||
// ½«Ã¶¾Ùֵת»»Îªint£¬È»ºó¼ì²éÊÇ·ñ¿ÉÒÔ°²È«µØת»»Îªbyte
|
||
int intValue = Convert.ToInt32(enumValue);
|
||
if (intValue < byte.MinValue || intValue > byte.MaxValue)
|
||
throw new OverflowException($"Enum value {enumValue} ({intValue}) is out of range for byte.");
|
||
|
||
// ·µ»Ø°üº¬×ª»»ºóµÄ×Ö½ÚµÄÊý×é
|
||
return new[] { (byte)intValue };
|
||
}
|
||
else
|
||
{
|
||
// Èç¹û»ù´¡ÀàÐͲ»ÊÇbyte»òint£¬ÔòÅ׳öÒì³££¨»òÕßÄã¿ÉÒÔÌí¼Ó¸ü¶àµÄÀàÐͼì²éºÍ´¦ÀíÂß¼£©
|
||
throw new NotSupportedException($"The underlying type of the enum {typeof(TEnum).Name} is not supported.");
|
||
}
|
||
}
|
||
|
||
// ´Óbyte[]ת»»Îªµ¥¸öö¾Ù£¨¼ÙÉèbyte[]Ö»ÓÐÒ»¸ö×Ö½Ú£©
|
||
public static TEnum ToEnum<TEnum>(this byte[] byteArray) where TEnum : struct, Enum
|
||
{
|
||
if (byteArray == null || byteArray.Length != 1)
|
||
throw new ArgumentException("The byte array must contain exactly one byte.");
|
||
|
||
// Ö±½Ó´Ó×Ö½Úת»»ÎªÃ¶¾ÙÖµ
|
||
return (TEnum)Enum.ToObject(typeof(TEnum), byteArray[0]);
|
||
}
|
||
|
||
// ushort[] ת byte[]
|
||
public static byte[] ToByteArray(this ushort[] ushortArray)
|
||
{
|
||
byte[] byteArray = new byte[ushortArray.Length * 2];
|
||
Buffer.BlockCopy(ushortArray, 0, byteArray, 0, byteArray.Length);
|
||
return byteArray;
|
||
}
|
||
|
||
// byte[] ת ushort[]
|
||
public static ushort[] ToUShortArray(this byte[] byteArray)
|
||
{
|
||
if (byteArray.Length % 2 != 0)
|
||
throw new ArgumentException("byteÊý×鳤¶È±ØÐëÊÇżÊý");
|
||
|
||
ushort[] ushortArray = new ushort[byteArray.Length / 2];
|
||
Buffer.BlockCopy(byteArray, 0, ushortArray, 0, byteArray.Length);
|
||
return ushortArray;
|
||
}
|
||
|
||
|
||
|
||
public static byte[] ToByteArray(this bool[] boolArr)
|
||
{
|
||
byte[] byteArray = new byte[boolArr.Length];
|
||
for (int i = 0; i < byteArray.Length; i++)
|
||
{
|
||
byteArray[i] = (byte)(boolArr[i] ? 1 : 0);
|
||
}
|
||
return byteArray;
|
||
}
|
||
|
||
public static bool[] ToBoolArray(this byte[] byteArray)
|
||
{
|
||
bool[] boolArr = new bool[byteArray.Length];
|
||
for (int i = 0; i < byteArray.Length; i++)
|
||
{
|
||
boolArr[i] = byteArray[i] == 0 ? false : true;
|
||
}
|
||
return boolArr;
|
||
}
|
||
|
||
public static byte[] FlattenByteArray2D(this byte[,] array2D)
|
||
{
|
||
int rows = array2D.GetLength(0);
|
||
int cols = array2D.GetLength(1);
|
||
byte[] array1D = new byte[rows * cols];
|
||
|
||
int index = 0;
|
||
for (int i = 0; i < rows; i++)
|
||
{
|
||
for (int j = 0; j < cols; j++)
|
||
{
|
||
array1D[index++] = array2D[i, j];
|
||
}
|
||
}
|
||
|
||
return array1D;
|
||
}
|
||
public static byte[,] CreateByteArray2D(this byte[] array1D, int rows, int cols)
|
||
{
|
||
if (array1D.Length != rows * cols)
|
||
{
|
||
throw new ArgumentException("The length of the 1D array does not match the specified dimensions for the 2D array.");
|
||
}
|
||
|
||
byte[,] array2D = new byte[rows, cols];
|
||
|
||
int index = 0;
|
||
for (int i = 0; i < rows; i++)
|
||
{
|
||
for (int j = 0; j < cols; j++)
|
||
{
|
||
array2D[i, j] = array1D[index++];
|
||
}
|
||
}
|
||
|
||
return array2D;
|
||
}
|
||
|
||
public static byte[] FlattenByteArray3D(this byte[,,] array3D)
|
||
{
|
||
int layer = array3D.GetLength(0);
|
||
int rows = array3D.GetLength(1);
|
||
int cols = array3D.GetLength(2);
|
||
byte[] array1D = new byte[layer * rows * cols];
|
||
|
||
int index = 0;
|
||
for (int i = 0; i < layer; i++)
|
||
{
|
||
for (int j = 0; j < rows; j++)
|
||
{
|
||
for (int k = 0; k < cols; k++)
|
||
{
|
||
array1D[index++] = array3D[i, j, k];
|
||
}
|
||
}
|
||
}
|
||
|
||
return array1D;
|
||
}
|
||
|
||
public static byte[,,] CreateByteArray3D(this byte[] array1D, int layer, int rows, int cols)
|
||
{
|
||
if (array1D.Length != layer * rows * cols)
|
||
{
|
||
throw new ArgumentException("The length of the 1D array does not match the specified dimensions for the 3D array.");
|
||
}
|
||
|
||
byte[,,] array3D = new byte[layer, rows, cols];
|
||
|
||
int index = 0;
|
||
for (int i = 0; i < layer; i++)
|
||
{
|
||
for (int j = 0; j < rows; j++)
|
||
{
|
||
for (int k = 0; k < cols; k++)
|
||
{
|
||
array3D[i, j, k] = array1D[index++];
|
||
}
|
||
}
|
||
}
|
||
|
||
return array3D;
|
||
}
|
||
}
|