-
-
Save Subv/1381215 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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."); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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