mirror of
https://github.com/tym1116/BH3.git
synced 2025-12-16 08:25:20 +01:00
202 lines
3.8 KiB
C#
202 lines
3.8 KiB
C#
using System.IO;
|
|
|
|
namespace MoleMole
|
|
{
|
|
public class SprotoPack
|
|
{
|
|
private MemoryStream buffer;
|
|
|
|
private byte[] tmp;
|
|
|
|
public SprotoPack()
|
|
{
|
|
tmp = new byte[8];
|
|
}
|
|
|
|
private void write_ff(byte[] src, int offset, long pos, int n)
|
|
{
|
|
int num = (n + 7) & -8;
|
|
long position = buffer.Position;
|
|
buffer.Seek(pos, SeekOrigin.Begin);
|
|
buffer.WriteByte(byte.MaxValue);
|
|
buffer.WriteByte((byte)(num / 8 - 1));
|
|
buffer.Write(src, offset, n);
|
|
for (int i = 0; i < num - n; i++)
|
|
{
|
|
buffer.WriteByte(0);
|
|
}
|
|
buffer.Seek(position, SeekOrigin.Begin);
|
|
}
|
|
|
|
private int pack_seg(byte[] src, long offset, int ff_n)
|
|
{
|
|
byte b = 0;
|
|
int num = 0;
|
|
long position = buffer.Position;
|
|
buffer.Seek(1L, SeekOrigin.Current);
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
if (src[offset + i] != 0)
|
|
{
|
|
num++;
|
|
b |= (byte)(1 << i);
|
|
buffer.WriteByte(src[offset + i]);
|
|
}
|
|
}
|
|
if ((num == 7 || num == 6) && ff_n > 0)
|
|
{
|
|
num = 8;
|
|
}
|
|
if (num == 8)
|
|
{
|
|
if (ff_n > 0)
|
|
{
|
|
buffer.Seek(position, SeekOrigin.Begin);
|
|
return 8;
|
|
}
|
|
buffer.Seek(position, SeekOrigin.Begin);
|
|
return 10;
|
|
}
|
|
buffer.Seek(position, SeekOrigin.Begin);
|
|
buffer.WriteByte(b);
|
|
buffer.Seek(position, SeekOrigin.Begin);
|
|
return num + 1;
|
|
}
|
|
|
|
public int pack(byte[] data, int len, byte[] outBuffer, int outBufferOffset)
|
|
{
|
|
clear();
|
|
buffer = new MemoryStream(outBuffer);
|
|
buffer.Position = outBufferOffset;
|
|
byte[] array = null;
|
|
int num = 0;
|
|
long pos = 0L;
|
|
int num2 = 0;
|
|
byte[] array2 = data;
|
|
int num3 = 0;
|
|
int num5;
|
|
for (int i = 0; i < len; buffer.Seek(num5, SeekOrigin.Current), i += 8)
|
|
{
|
|
num3 = i;
|
|
int num4 = i + 8 - len;
|
|
if (num4 > 0)
|
|
{
|
|
for (int j = 0; j < 8 - num4; j++)
|
|
{
|
|
tmp[j] = array2[i + j];
|
|
}
|
|
for (int k = 0; k < num4; k++)
|
|
{
|
|
tmp[7 - k] = 0;
|
|
}
|
|
array2 = tmp;
|
|
num3 = 0;
|
|
}
|
|
num5 = pack_seg(array2, num3, num2);
|
|
switch (num5)
|
|
{
|
|
case 10:
|
|
array = array2;
|
|
num = num3;
|
|
pos = buffer.Position;
|
|
num2 = 1;
|
|
continue;
|
|
case 8:
|
|
if (num2 > 0)
|
|
{
|
|
num2++;
|
|
if (num2 == 256)
|
|
{
|
|
write_ff(array, num, pos, 2048);
|
|
num2 = 0;
|
|
}
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
if (num2 > 0)
|
|
{
|
|
write_ff(array, num, pos, num2 * 8);
|
|
num2 = 0;
|
|
}
|
|
}
|
|
if (num2 == 1)
|
|
{
|
|
write_ff(array, num, pos, 8);
|
|
}
|
|
else if (num2 > 1)
|
|
{
|
|
int num6 = ((array != data) ? array.Length : len);
|
|
write_ff(array, num, pos, num6 - num);
|
|
}
|
|
long num7 = (len + 2047) / 2048 * 2 + len + 2;
|
|
if (num7 < buffer.Position)
|
|
{
|
|
}
|
|
int result = (int)(buffer.Position - outBufferOffset);
|
|
buffer.Dispose();
|
|
return result;
|
|
}
|
|
|
|
public int unpack(byte[] data, int len, byte[] outBuffer, int outBufferOffset)
|
|
{
|
|
clear();
|
|
buffer = new MemoryStream(outBuffer);
|
|
buffer.Position = outBufferOffset;
|
|
len = ((len != 0) ? len : data.Length);
|
|
int num = len;
|
|
while (num > 0)
|
|
{
|
|
byte b = data[len - num];
|
|
num--;
|
|
if (b == byte.MaxValue)
|
|
{
|
|
if (num < 0)
|
|
{
|
|
}
|
|
int num2 = (data[len - num] + 1) * 8;
|
|
if (num < num2 + 1)
|
|
{
|
|
}
|
|
buffer.Write(data, len - num + 1, num2);
|
|
num -= num2 + 1;
|
|
continue;
|
|
}
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
int num3 = (b >> i) & 1;
|
|
if (num3 == 1)
|
|
{
|
|
if (num < 0)
|
|
{
|
|
}
|
|
buffer.WriteByte(data[len - num]);
|
|
num--;
|
|
}
|
|
else
|
|
{
|
|
buffer.WriteByte(0);
|
|
}
|
|
}
|
|
}
|
|
int result = (int)(buffer.Position - outBufferOffset);
|
|
buffer.Dispose();
|
|
return result;
|
|
}
|
|
|
|
private void clear()
|
|
{
|
|
for (int i = 0; i < tmp.Length; i++)
|
|
{
|
|
tmp[i] = 0;
|
|
}
|
|
}
|
|
|
|
public int RoundUpTo8(int x)
|
|
{
|
|
int num = x & 7;
|
|
return (num != 0) ? (x + 8 - num) : x;
|
|
}
|
|
}
|
|
}
|