Skip to content

Instantly share code, notes, and snippets.

@Subv
Forked from LordJZ/1.cs
Created November 21, 2011 00:03
Show Gist options
  • Save Subv/1381215 to your computer and use it in GitHub Desktop.
Save Subv/1381215 to your computer and use it in GitHub Desktop.
using System;
using System.Collections;
using System.Linq;
namespace Kamilla.WorldOfWarcraft.Latest.OpcodeDatas
{
public abstract class PackedData : OpcodeData
{
protected virtual bool IsMaskSequenceSwapped { get { return true; } }
protected abstract int[] MaskSequence { get; }
protected abstract int[] ByteSequence { get; }
protected abstract int ByteXorValue { get; }
void CheckSequences(int[] seq_b, int[] seq_m)
{
int size = seq_b.Count(element => element >= 0);
if (size != seq_m.Count(x => x >= 0))
throw new InvalidOperationException("Length of Mask Sequence must be equal to length of Byte Sequence.");
if (size / 8 * 8 != size)
throw new InvalidOperationException("Size of PackedData in bytes must be a multiple of 8.");
}
public sealed override void Read(StreamHandler reader)
{
var seq_b = ByteSequence;
var seq_m = MaskSequence;
var b_xor = ByteXorValue;
int size = seq_m.Count(x => x >= 0);
if (size != seq_m.Length && this.IsMaskSequenceSwapped)
throw new InvalidOperationException("Cannot have elements in swapped MaskSequence.");
CheckSequences(seq_b, seq_m);
if (this.IsMaskSequenceSwapped)
{
var seq_m_copy = new int[seq_m.Length];
for (int i = 0; i < seq_m.Length; )
{
var t = i;
for (int j = t + 8 - 1; j >= t; --j, ++i)
seq_m_copy[j] = seq_m[i];
}
seq_m = seq_m_copy;
}
byte[] data = new byte[size];
var dst = new BitArray(size);
for (int i = 0; i < seq_m.Length; ++i)
{
var el = seq_m[i];
if (el < 0)
ElementRead(reader, el);
else
dst[el] = reader.UnalignedReadBit();
}
for (int i = 0; i < seq_b.Length; ++i)
{
var el = seq_b[i];
if (el < 0)
ElementRead(reader, el);
else if (dst[el])
data[el] = (byte)(reader.ReadByte() ^ b_xor);
}
PackedRead(data);
}
protected virtual void PackedRead(StreamHandler reader)
{
throw new NotImplementedException("Reading " + this.GetType().Name + " is not implemented.");
}
protected virtual void PackedRead(byte[] data)
{
using (var reader = new StreamHandler(data))
PackedRead(reader);
}
/// <summary>
/// When overriden, reads the element at specified negative, -1 based index from the provided stream.
/// </summary>
/// <param name="reader">
/// Stream to read element from.
/// </param>
/// <param name="index">
/// The negative, -1 based index of the element to read.
/// </param>
protected virtual void ElementRead(StreamHandler reader, int index)
{
throw new NotImplementedException("Reading specific elements is not implemented.");
}
public sealed override void Save(StreamHandler writer)
{
var seq_b = ByteSequence;
var seq_m = MaskSequence;
var b_xor = ByteXorValue;
int size = seq_m.Count(x => x >= 0);
if (size != seq_m.Length && this.IsMaskSequenceSwapped)
throw new InvalidOperationException("Cannot have elements in swapped MaskSequence.");
CheckSequences(seq_b, seq_m);
if (this.IsMaskSequenceSwapped)
{
var seq_m_copy = new int[seq_m.Length];
for (int i = 0; i < seq_m.Length; )
{
var t = i;
for (int j = t + 8 - 1; j >= t; --j, ++i)
seq_m_copy[j] = seq_m[i];
}
seq_m = seq_m_copy;
}
byte[] data = new byte[size];
PackedSave(data);
var mask = new BitArray(size);
for (int i = 0; i < size; ++i)
{
var el = seq_m[i];
if (el < 0)
ElementWrite(writer, el);
else
writer.UnalignedWriteBit(data[el] != 0);
}
writer.FlushUnalignedBits();
for (int i = 0; i < seq_b.Length; ++i)
{
var el = seq_b[i];
if (el < 0)
ElementWrite(writer, el);
else if (data[el] != 0)
writer.WriteByte((byte)(data[el] ^ b_xor));
}
}
protected virtual void PackedSave(StreamHandler writer)
{
throw new NotImplementedException("Saving " + this.GetType().Name + " is not implemented.");
}
protected virtual void PackedSave(byte[] data)
{
using (var writer = new StreamHandler(data))
PackedSave(writer);
}
/// <summary>
/// When overriden, writes the element at specified negative, -1 based index to the provided stream.
/// </summary>
/// <param name="writer">
/// Stream to write element to.
/// </param>
/// <param name="index">
/// The negative, -1 based index of the element to write.
/// </param>
protected virtual void ElementWrite(StreamHandler writer, int index)
{
throw new NotImplementedException("Writing specific elements is not implemented.");
}
}
}
using System;
using System.Text;
namespace Kamilla.WorldOfWarcraft.Latest.OpcodeDatas
{
public sealed class SetPhaseShift : PackedData
{
public readonly byte[][] Data = new byte[4][];
public WowGuid Guid;
public uint Unk;
protected override int ByteXorValue
{
get { return 1; }
}
protected override int[] MaskSequence
{
get { return new int[] { 4, 6, 3, 4, 1, 2, 0, 7 }; }
}
protected override int[] ByteSequence
{
get { return new int[] { 6, 5, -1, 3, 7, -2, -3, 2, 4, -5, 0, 1, -4 }; }
}
protected override void ElementRead(StreamHandler reader, int index)
{
if (index == -5)
this.Unk = reader.ReadUInt32();
else
this.Data[-index - 1] = reader.ReadBytes(reader.ReadInt32());
}
protected override void ElementWrite(StreamHandler writer, int index)
{
if (index == -5)
{
writer.WriteUInt32(this.Unk);
}
else
{
index = -index - 1;
writer.WriteInt32(this.Data[index].Length);
writer.WriteBytes(this.Data[index]);
}
}
protected override void PackedRead(StreamHandler reader)
{
this.Guid = reader.ReadGuid();
}
protected override void PackedSave(StreamHandler writer)
{
writer.WriteGuid(this.Guid);
}
public override CustomPacket CreatePacket()
{
return base.CreatePacket(WowOpcodes.SMSG_PHASE_SHIFT_CHANGE, Direction.ToClient);
}
public override void ToString(StringBuilder builder)
{
builder.AppendLine("Guid: " + this.Guid);
builder.AppendLine("Unk: " + this.Unk);
for (int i = 0; i < this.Data.Length; ++i)
{
var arr = this.Data[i];
if ((arr.Length & 1) == 0)
{
builder.Append("Maps: ");
for (int j = 0; j < arr.Length; j += 2)
builder.Append((Maps)BitConverter.ToUInt16(arr, j)).Append(j == arr.Length - 2 ? "" : ", ");
builder.AppendLine();
}
else
builder.AppendLine("Bytes: " + arr.ToHexString());
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment