diff --git a/MLEM.Data/MLEM.Data.csproj b/MLEM.Data/MLEM.Data.csproj
new file mode 100644
index 0000000..86a3a94
--- /dev/null
+++ b/MLEM.Data/MLEM.Data.csproj
@@ -0,0 +1,28 @@
+
+
+ netstandard2.0
+
+
+
+ Ellpeck
+ Some simple data and network handling for (M)LEM (L)ibrary by (E)llpeck for (M)onoGame
+ monogame ellpeck mlem utility extensions data network serialize
+ https://github.com/Ellpeck/MLEM
+ https://github.com/Ellpeck/MLEM
+ https://github.com/Ellpeck/MLEM/blob/master/LICENSE
+ 1.0.0
+
+
+
+
+
+ all
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MLEM.Data/NetBufferSerializer.cs b/MLEM.Data/NetBufferSerializer.cs
new file mode 100644
index 0000000..0f41bab
--- /dev/null
+++ b/MLEM.Data/NetBufferSerializer.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using Lidgren.Network;
+
+namespace MLEM.Data {
+ public class NetBufferSerializer {
+
+ private readonly Dictionary> writeFunctions = new Dictionary>();
+ private readonly Dictionary> readFunctions = new Dictionary>();
+ private readonly Dictionary fieldCache = new Dictionary();
+
+ public NetBufferSerializer() {
+ foreach (var method in typeof(NetBuffer).GetMethods(BindingFlags.Instance | BindingFlags.Public)) {
+ if (method.GetParameters().Length == 0 && method.Name.StartsWith("Read", StringComparison.Ordinal) && method.Name.Substring(4) == method.ReturnType.Name)
+ this.readFunctions[method.ReturnType] = buffer => method.Invoke(buffer, null);
+ }
+ foreach (var method in typeof(NetBuffer).GetMethods(BindingFlags.Instance | BindingFlags.Public)) {
+ if (method.Name.Equals("Write", StringComparison.InvariantCulture)) {
+ var parameters = method.GetParameters();
+ if (parameters.Length == 1)
+ this.writeFunctions[parameters[0].ParameterType] = (buffer, o) => method.Invoke(buffer, new[] {o});
+ }
+ }
+ this.AddHandler((buffer, o) => buffer.Write(o), buffer => buffer.ReadVector2());
+ this.AddHandler((buffer, o) => buffer.Write(o), buffer => buffer.ReadGuid());
+ this.AddHandler((buffer, o) => buffer.Write(o), buffer => buffer.ReadDirection());
+ }
+
+ public void Serialize(NetBuffer buffer, object o, BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) {
+ foreach (var field in this.GetFields(o.GetType(), flags)) {
+ if (!this.writeFunctions.TryGetValue(field.FieldType, out var func))
+ throw new ArgumentException($"The type {field.FieldType} doesn't have a writer");
+ func(buffer, field.GetValue(o));
+ }
+ }
+
+ public void Deserialize(NetBuffer buffer, object o, BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) {
+ foreach (var field in this.GetFields(o.GetType(), flags)) {
+ if (!this.readFunctions.TryGetValue(field.FieldType, out var func))
+ throw new ArgumentException($"The type {field.FieldType} doesn't have a reader");
+ field.SetValue(o, func(buffer));
+ }
+ }
+
+ private IEnumerable GetFields(Type type, BindingFlags flags) {
+ if (!this.fieldCache.TryGetValue(type, out var fields)) {
+ fields = type.GetFields(flags);
+ Array.Sort(fields, (f1, f2) => string.Compare(f1.Name, f2.Name, StringComparison.Ordinal));
+ this.fieldCache.Add(type, fields);
+ }
+ return fields;
+ }
+
+ public void AddHandler(Action write, Func read) {
+ this.writeFunctions.Add(typeof(T), (buffer, o) => write(buffer, (T) o));
+ this.readFunctions.Add(typeof(T), buffer => read(buffer));
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/MLEM.Data/NetExtensions.cs b/MLEM.Data/NetExtensions.cs
new file mode 100644
index 0000000..93489e2
--- /dev/null
+++ b/MLEM.Data/NetExtensions.cs
@@ -0,0 +1,54 @@
+using System;
+using System.IO;
+using System.IO.Compression;
+using Lidgren.Network;
+using Microsoft.Xna.Framework;
+using MLEM.Misc;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Bson;
+
+namespace MLEM.Data {
+ public static class NetExtensions {
+
+ public static void Write(this NetBuffer buffer, Vector2 vector) {
+ buffer.Write(vector.X);
+ buffer.Write(vector.Y);
+ }
+
+ public static Vector2 ReadVector2(this NetBuffer buffer) {
+ return new Vector2(buffer.ReadFloat(), buffer.ReadFloat());
+ }
+
+ public static void Write(this NetBuffer buffer, Guid guid) {
+ buffer.Write(guid.ToByteArray());
+ }
+
+ public static Guid ReadGuid(this NetBuffer buffer) {
+ return new Guid(buffer.ReadBytes(16));
+ }
+
+ public static void Write(this NetBuffer buffer, Direction2 direction) {
+ buffer.Write((short) direction);
+ }
+
+ public static Direction2 ReadDirection(this NetBuffer buffer) {
+ return (Direction2) buffer.ReadInt16();
+ }
+
+ public static void WriteObject(this NetBuffer buffer, T obj, JsonSerializer serializer) {
+ using (var memory = new MemoryStream()) {
+ using (var gzip = new GZipStream(memory, CompressionLevel.Fastest, true))
+ serializer.Serialize(new BsonDataWriter(gzip), obj, typeof(T));
+ buffer.Write(memory.ToArray());
+ }
+ }
+
+ public static T ReadObject(this NetBuffer buffer, JsonSerializer serializer) {
+ using (var memory = new MemoryStream(buffer.ReadBytes(buffer.LengthBytes))) {
+ using (var gzip = new GZipStream(memory, CompressionMode.Decompress, true))
+ return serializer.Deserialize(new BsonDataReader(gzip));
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/MLEM.sln b/MLEM.sln
index 77b4d80..6d5b2e0 100644
--- a/MLEM.sln
+++ b/MLEM.sln
@@ -16,6 +16,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sandbox", "Sandbox\Sandbox.
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demos.Android", "Demos.Android\Demos.Android.csproj", "{410C0262-131C-4D0E-910D-D01B4F7143E0}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MLEM.Data", "MLEM.Data\MLEM.Data.csproj", "{28938AAA-FB91-4E6F-8511-0DB99EC831F7}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -54,5 +56,9 @@ Global
{410C0262-131C-4D0E-910D-D01B4F7143E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{410C0262-131C-4D0E-910D-D01B4F7143E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{410C0262-131C-4D0E-910D-D01B4F7143E0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {28938AAA-FB91-4E6F-8511-0DB99EC831F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {28938AAA-FB91-4E6F-8511-0DB99EC831F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {28938AAA-FB91-4E6F-8511-0DB99EC831F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {28938AAA-FB91-4E6F-8511-0DB99EC831F7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal