360 lines
9.7 KiB
C#
360 lines
9.7 KiB
C#
using BoneSync.Networking.Messages;
|
|
using StressLevelZero;
|
|
using StressLevelZero.Combat;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using UnityEngine;
|
|
|
|
namespace BoneSync.Data
|
|
{
|
|
public static class BitPacking
|
|
{
|
|
public static byte[] PackBits(bool[] bits)
|
|
{
|
|
int byteCount = bits.Length / 8;
|
|
if (bits.Length % 8 != 0)
|
|
{
|
|
byteCount++;
|
|
}
|
|
byte[] bytes = new byte[byteCount];
|
|
for (int i = 0; i < bits.Length; i++)
|
|
{
|
|
int byteIndex = i / 8;
|
|
int bitIndex = i % 8;
|
|
if (bits[i])
|
|
{
|
|
bytes[byteIndex] |= (byte)(1 << bitIndex);
|
|
}
|
|
}
|
|
return bytes;
|
|
}
|
|
|
|
public static bool[] UnpackBits(byte[] bytes, int bitCount)
|
|
{
|
|
bool[] bits = new bool[bitCount];
|
|
for (int i = 0; i < bitCount; i++)
|
|
{
|
|
int byteIndex = i / 8;
|
|
int bitIndex = i % 8;
|
|
bits[i] = (bytes[byteIndex] & (1 << bitIndex)) != 0;
|
|
}
|
|
return bits;
|
|
}
|
|
}
|
|
internal class ByteEncoder
|
|
{
|
|
//public BinaryWriter writer;
|
|
//public BinaryReader reader;
|
|
|
|
public List<byte> Data;
|
|
public ByteEncoder()
|
|
{
|
|
Data = new List<byte>();
|
|
}
|
|
|
|
public ByteEncoder(byte[] data)
|
|
{
|
|
Data = data.ToList();
|
|
}
|
|
|
|
public byte[] ToArray()
|
|
{
|
|
return Data.ToArray();
|
|
}
|
|
|
|
public void SetBytes(byte[] data)
|
|
{
|
|
Data = data.ToList();
|
|
}
|
|
|
|
public void WriteByte(byte value)
|
|
{
|
|
Data.Add(value);
|
|
}
|
|
|
|
public void WriteBytes(byte[] value)
|
|
{
|
|
Data.AddRange(value);
|
|
}
|
|
public byte[] ReadBytes(int count)
|
|
{
|
|
if (Data.Count < count)
|
|
{
|
|
throw new Exception("Not enough data to read, expected " + count + " but only have " + Data.Count);
|
|
}
|
|
byte[] value = Data.GetRange(0, count).ToArray();
|
|
Data.RemoveRange(0, count);
|
|
return value;
|
|
}
|
|
|
|
public byte ReadByte()
|
|
{
|
|
byte value = Data[0];
|
|
Data.RemoveAt(0);
|
|
return value;
|
|
}
|
|
|
|
public void WriteBool(bool value)
|
|
{
|
|
WriteByte((byte)(value ? 1 : 0));
|
|
}
|
|
|
|
public bool ReadBool()
|
|
{
|
|
return ReadByte() == 1;
|
|
}
|
|
|
|
public void WriteInt(int value)
|
|
{
|
|
WriteBytes(BitConverter.GetBytes(value));
|
|
}
|
|
|
|
public int ReadInt()
|
|
{
|
|
return BitConverter.ToInt32(ReadBytes(sizeof(int)), 0);
|
|
}
|
|
|
|
public void WriteLong(long value)
|
|
{
|
|
WriteBytes(BitConverter.GetBytes(value));
|
|
}
|
|
|
|
public long ReadLong()
|
|
{
|
|
return BitConverter.ToInt64(ReadBytes(sizeof(long)), 0);
|
|
}
|
|
|
|
public void WriteFloat(float value)
|
|
{
|
|
WriteBytes(BitConverter.GetBytes(value));
|
|
}
|
|
|
|
public float ReadFloat()
|
|
{
|
|
return BitConverter.ToSingle(ReadBytes(sizeof(float)), 0);
|
|
}
|
|
|
|
public void WriteUShort(ushort value)
|
|
{
|
|
WriteBytes(BitConverter.GetBytes(value));
|
|
}
|
|
public ushort ReadUShort() {
|
|
return BitConverter.ToUInt16(ReadBytes(sizeof(ushort)), 0);
|
|
}
|
|
|
|
public void WriteDouble(double value)
|
|
{
|
|
WriteBytes(BitConverter.GetBytes(value));
|
|
}
|
|
|
|
public double ReadDouble()
|
|
{
|
|
return BitConverter.ToDouble(ReadBytes(sizeof(double)), 0);
|
|
}
|
|
|
|
public void WriteString(string value)
|
|
{
|
|
byte[] bytes = Encoding.UTF8.GetBytes(value);
|
|
WriteInt(bytes.Length);
|
|
WriteBytes(bytes);
|
|
}
|
|
|
|
public string ReadString()
|
|
{
|
|
int length = ReadInt();
|
|
return Encoding.UTF8.GetString(ReadBytes(length));
|
|
}
|
|
|
|
public void WriteULong(ulong value)
|
|
{
|
|
WriteBytes(BitConverter.GetBytes(value));
|
|
}
|
|
|
|
public ulong ReadULong()
|
|
{
|
|
return BitConverter.ToUInt64(ReadBytes(sizeof(ulong)), 0);
|
|
}
|
|
|
|
public void WriteVector3(Vector3 value)
|
|
{
|
|
WriteFloat(value.x);
|
|
WriteFloat(value.y);
|
|
WriteFloat(value.z);
|
|
}
|
|
|
|
public Vector3 ReadVector3()
|
|
{
|
|
float x = ReadFloat();
|
|
float y = ReadFloat();
|
|
float z = ReadFloat();
|
|
return new Vector3(x, y, z);
|
|
}
|
|
|
|
public void WriteQuaternion(Quaternion value)
|
|
{
|
|
WriteVector3(value.eulerAngles);
|
|
}
|
|
|
|
public Quaternion ReadQuaternion()
|
|
{
|
|
Vector3 eulerAngles = ReadVector3();
|
|
return Quaternion.Euler(eulerAngles);
|
|
}
|
|
|
|
public void WriteSimpleTransform(SimpleSyncTransform value)
|
|
{
|
|
WriteVector3(value.position);
|
|
WriteQuaternion(value.rotation);
|
|
WriteBool(value.scale.HasValue);
|
|
if (value.scale.HasValue)
|
|
WriteVector3(value.scale.Value);
|
|
}
|
|
|
|
public SimpleSyncTransform ReadSimpleTransform()
|
|
{
|
|
Vector3 position = ReadVector3();
|
|
Quaternion rotation = ReadQuaternion();
|
|
bool hasScale = ReadBool();
|
|
Vector3? scale = null;
|
|
if (hasScale)
|
|
{
|
|
scale = ReadVector3();
|
|
}
|
|
return new SimpleSyncTransform()
|
|
{
|
|
position = position,
|
|
rotation = rotation,
|
|
scale = scale
|
|
};
|
|
}
|
|
|
|
public void WriteMatrix4x4(Matrix4x4 matrix)
|
|
{
|
|
for (int i = 0; i < 16; i++)
|
|
{
|
|
WriteFloat(matrix[i]);
|
|
}
|
|
}
|
|
|
|
public Matrix4x4 ReadMatrix4x4()
|
|
{
|
|
Matrix4x4 matrix = new Matrix4x4();
|
|
for (int i = 0; i < 16; i++)
|
|
{
|
|
matrix[i] = ReadFloat();
|
|
}
|
|
return matrix;
|
|
}
|
|
|
|
public void WriteBoolArray(bool[] array)
|
|
{
|
|
byte[] bytes = BitPacking.PackBits(array);
|
|
WriteByte((byte)bytes.Length);
|
|
WriteBytes(bytes);
|
|
}
|
|
|
|
public bool[] ReadBoolArray()
|
|
{
|
|
byte length = ReadByte();
|
|
byte[] bytes = ReadBytes(length);
|
|
return BitPacking.UnpackBits(bytes, length);
|
|
}
|
|
|
|
public void WriteAmmoVariables(AmmoVariables ammoVariables)
|
|
{
|
|
WriteBool(ammoVariables.Tracer);
|
|
WriteFloat(ammoVariables.ProjectileMass);
|
|
WriteFloat(ammoVariables.ExitVelocity);
|
|
WriteFloat(ammoVariables.AttackDamage);
|
|
WriteByte((byte)ammoVariables.AttackType);
|
|
WriteByte((byte)ammoVariables.cartridgeType);
|
|
}
|
|
|
|
public AmmoVariables ReadAmmoVariables()
|
|
{
|
|
AmmoVariables ammoVariables = new AmmoVariables()
|
|
{
|
|
Tracer = ReadBool(),
|
|
ProjectileMass = ReadFloat(),
|
|
ExitVelocity = ReadFloat(),
|
|
AttackDamage = ReadFloat(),
|
|
AttackType = (AttackType)ReadByte(),
|
|
cartridgeType = (Cart)ReadByte()
|
|
};
|
|
return ammoVariables;
|
|
}
|
|
|
|
public void WriteMagazineData(MagazineData magazineData)
|
|
{
|
|
WriteByte((byte)magazineData.weight);
|
|
WriteByte((byte)magazineData.platform);
|
|
WriteUShort((byte)magazineData.cartridgeType);
|
|
BulletObject[] bulletObjects = magazineData.AmmoSlots;
|
|
WriteByte((byte)bulletObjects.Length);
|
|
for (int i = 0; i < bulletObjects.Length; i++)
|
|
{
|
|
WriteAmmoVariables(bulletObjects[i].ammoVariables);
|
|
}
|
|
}
|
|
|
|
public MagazineData ReadMagazineData()
|
|
{
|
|
MagazineData mag = new MagazineData();
|
|
mag.weight = (Weight)ReadByte();
|
|
mag.platform = (Platform)ReadByte();
|
|
mag.cartridgeType = (Cart)ReadUShort();
|
|
byte bulletCount = ReadByte();
|
|
|
|
mag.AmmoSlots = new BulletObject[bulletCount];
|
|
for (int i = 0; i < bulletCount; i++)
|
|
{
|
|
mag.AmmoSlots[i] = new BulletObject()
|
|
{
|
|
ammoVariables = ReadAmmoVariables()
|
|
};
|
|
}
|
|
|
|
return mag;
|
|
}
|
|
|
|
public void WriteCompressedFloat(float value)
|
|
{
|
|
// write a float in the range of 0-1 with 2 decimal places
|
|
value = Mathf.Clamp01(value);
|
|
int rounded = Mathf.FloorToInt(value * 255f);
|
|
WriteByte((byte)rounded);
|
|
}
|
|
|
|
public float ReadCompressedFloat()
|
|
{
|
|
return ReadByte() / 255f;
|
|
}
|
|
|
|
public void WriteFingerCurl(SimpleFingerCurl fingerCurl)
|
|
{
|
|
WriteCompressedFloat(fingerCurl.thumb);
|
|
WriteCompressedFloat(fingerCurl.index);
|
|
WriteCompressedFloat(fingerCurl.middle);
|
|
WriteCompressedFloat(fingerCurl.ring);
|
|
WriteCompressedFloat(fingerCurl.pinky);
|
|
}
|
|
|
|
public SimpleFingerCurl ReadFingerCurl()
|
|
{
|
|
SimpleFingerCurl fingerCurl = new SimpleFingerCurl()
|
|
{
|
|
thumb = ReadCompressedFloat(),
|
|
index = ReadCompressedFloat(),
|
|
middle = ReadCompressedFloat(),
|
|
ring = ReadCompressedFloat(),
|
|
pinky = ReadCompressedFloat()
|
|
};
|
|
return fingerCurl;
|
|
}
|
|
}
|
|
}
|