Removed NioTSO client and server

- NioTSO client isn't needed because we're using RayLib
- Added FreeSO's API server to handle most backend operations
This commit is contained in:
Tony Bark 2024-05-01 02:55:43 -04:00
parent f12ba1502b
commit 22191ce648
591 changed files with 53264 additions and 3362 deletions

View file

@ -0,0 +1,27 @@
using Mina.Core.Buffer;
using System;
namespace FSO.Common.Serialization
{
public interface IModelSerializer
{
object Deserialize(uint clsid, IoBuffer input, ISerializationContext context);
void Serialize(IoBuffer output, object obj, ISerializationContext context);
void Serialize(IoBuffer output, object value, ISerializationContext context, bool clsIdPrefix);
IoBuffer SerializeBuffer(object value, ISerializationContext context, bool clsIdPrefix);
uint? GetClsid(object value);
void AddTypeSerializer(ITypeSerializer serializer);
}
public interface ITypeSerializer
{
object Deserialize(uint clsid, IoBuffer input, ISerializationContext serializer);
void Serialize(IoBuffer output, object value, ISerializationContext serializer);
uint? GetClsid(object value);
bool CanSerialize(Type type);
bool CanDeserialize(uint clsid);
}
}

View file

@ -0,0 +1,10 @@
using Ninject;
namespace FSO.Common.Serialization
{
public interface ISerializationContext
{
IKernel Kernel { get; }
IModelSerializer ModelSerializer { get; }
}
}

View file

@ -0,0 +1,9 @@
using Mina.Core.Buffer;
namespace FSO.Common.Serialization
{
public interface IoBufferDeserializable
{
void Deserialize(IoBuffer input, ISerializationContext context);
}
}

View file

@ -0,0 +1,9 @@
using Mina.Core.Buffer;
namespace FSO.Common.Serialization
{
public interface IoBufferSerializable
{
void Serialize(IoBuffer output, ISerializationContext context);
}
}

View file

@ -0,0 +1,304 @@
using Mina.Core.Buffer;
using System;
using System.Collections.Generic;
using System.Text;
namespace FSO.Common.Serialization
{
public static class IoBufferUtils
{
public static void PutSerializable(this IoBuffer buffer, object obj, ISerializationContext context)
{
buffer.PutSerializable(context, obj, false);
}
public static byte[] GetBytes(this IoBuffer buffer)
{
var result = new byte[buffer.Limit];
buffer.Get(result, 0, buffer.Limit);
return result;
}
public static T Deserialize<T>(byte[] bytes, ISerializationContext context) where T : IoBufferDeserializable
{
var buffer = IoBuffer.Wrap(bytes);
return Deserialize<T>(buffer, context);
}
public static T Deserialize<T>(IoBuffer buffer, ISerializationContext context) where T : IoBufferDeserializable
{
var model = Activator.CreateInstance<T>();
model.Deserialize(buffer, context);
return (T)model;
}
public static IoBuffer SerializableToIoBuffer(object obj, ISerializationContext context)
{
if (obj is IoBuffer)
{
var ioBuffer = (IoBuffer)obj;
return (IoBuffer)ioBuffer;
}
else if (obj is byte[])
{
var byteArray = (byte[])obj;
return IoBuffer.Wrap(byteArray);
}
else if (obj is IoBufferSerializable)
{
var ioBuffer = IoBuffer.Allocate(0);
ioBuffer.AutoExpand = true;
ioBuffer.Order = ByteOrder.BigEndian;
var serializable = (IoBufferSerializable)obj;
serializable.Serialize(ioBuffer, context);
ioBuffer.Flip();
return ioBuffer;
}
throw new Exception("Unknown serializable type: " + obj);
}
public static void PutSerializable(this IoBuffer buffer, ISerializationContext context, object obj, bool writeLength)
{
if(obj is IoBuffer)
{
var ioBuffer = (IoBuffer)obj;
if (writeLength){
buffer.PutUInt32((uint)ioBuffer.Remaining);
}
buffer.Put(ioBuffer);
}else if(obj is byte[])
{
var byteArray = (byte[])obj;
if (writeLength)
{
buffer.PutUInt32((uint)byteArray.Length);
}
buffer.Put(byteArray);
}else if(obj is IoBufferSerializable)
{
var ioBuffer = IoBuffer.Allocate(0);
ioBuffer.AutoExpand = true;
ioBuffer.Order = ByteOrder.BigEndian;
var serializable = (IoBufferSerializable)obj;
serializable.Serialize(ioBuffer, context);
ioBuffer.Flip();
if (writeLength)
{
buffer.PutUInt32((uint)ioBuffer.Remaining);
}
buffer.Put(ioBuffer);
}
}
public static void PutBool(this IoBuffer buffer, bool value)
{
buffer.Put(value ? (byte)0x01 : (byte)0x00);
}
public static bool GetBool(this IoBuffer buffer)
{
return buffer.Get() == 1 ? true : false;
}
public static void PutUInt32(this IoBuffer buffer, uint value)
{
int converted = unchecked((int)value);
buffer.PutInt32(converted);
}
public static uint GetUInt32(this IoBuffer buffer)
{
return (uint)buffer.GetInt32();
}
public static void PutUInt16(this IoBuffer buffer, ushort value)
{
buffer.PutInt16((short)value);
}
public static void PutUInt64(this IoBuffer buffer, ulong value)
{
buffer.PutInt64((long)value);
}
public static void PutEnum<T>(this IoBuffer buffer, T enumValue)
{
ushort value = Convert.ToUInt16((object)enumValue);
buffer.PutUInt16(value);
}
public static void PutUTF8(this IoBuffer buffer, string value)
{
if (value == null)
{
buffer.PutInt16(-1);
}
else
{
buffer.PutInt16((short)value.Length);
buffer.PutString(value, Encoding.UTF8);
}
}
public static string GetUTF8(this IoBuffer buffer)
{
short len = buffer.GetInt16();
if (len == -1)
{
return null;
}
return buffer.GetString(len, Encoding.UTF8);
}
public static ushort GetUInt16(this IoBuffer buffer)
{
return (ushort)buffer.GetInt16();
}
public static ulong GetUInt64(this IoBuffer buffer)
{
return (ulong)buffer.GetInt64();
}
public static T GetEnum<T>(this IoBuffer buffer)
{
return (T)System.Enum.Parse(typeof(T), buffer.GetUInt16().ToString());
}
public static String GetPascalVLCString(this IoBuffer buffer)
{
byte lengthByte = 0;
uint length = 0;
int shift = 0;
do
{
lengthByte = buffer.Get();
length |= (uint)((lengthByte & (uint)0x7F) << shift);
shift += 7;
} while (
(lengthByte >> 7) == 1
);
if (length > 0)
{
var data = new List<byte>();
for (int i = 0; i < length; i++)
{
data.Add(buffer.Get());
}
return Encoding.UTF8.GetString(data.ToArray());
}
else
{
return "";
}
}
public static byte[] GetPascalVLCString(String value)
{
if(value == null)
{
return new byte[] { 0x00 };
}
//TODO: Support strings bigger than 128 chars
var buffer = new byte[1 + value.Length];
buffer[0] = (byte)value.Length;
var chars = value.ToCharArray();
for(int i=0; i < chars.Length; i++){
buffer[i + 1] = (byte)chars[i];
}
return buffer;
}
public static void PutPascalVLCString(this IoBuffer buffer, String value)
{
byte[] encode = null;
long strlen = 0;
if (value != null)
{
encode = Encoding.UTF8.GetBytes(value);
strlen = encode.Length;
}
bool write = strlen > 0;
bool first = true;
while (strlen > 0 || first)
{
buffer.Put((byte)(((strlen > 127) ? (uint)128 : 0) | (strlen & 127)));
strlen >>= 7;
first = false;
}
if (write)
{
buffer.Put(encode);
}
}
public static String GetPascalString(this IoBuffer buffer)
{
byte len1 = buffer.Get();
byte len2 = buffer.Get();
byte len3 = buffer.Get();
byte len4 = buffer.Get();
len1 &= 0x7F;
long len = len1 << 24 | len2 << 16 | len3 << 8 | len4;
if (len > 0)
{
StringBuilder str = new StringBuilder();
for (int i = 0; i < len; i++)
{
str.Append((char)buffer.Get());
}
return str.ToString();
}
else
{
return "";
}
}
public static void PutPascalString(this IoBuffer buffer, String value)
{
long strlen = 0;
if (value != null)
{
strlen = value.Length;
}
byte len1 = (byte)((strlen >> 24) | 0x80);
byte len2 = (byte)((strlen >> 16) & 0xFF);
byte len3 = (byte)((strlen >> 8) & 0xFF);
byte len4 = (byte)(strlen & 0xFF);
buffer.Put(len1);
buffer.Put(len2);
buffer.Put(len3);
buffer.Put(len4);
if (strlen > 0)
{
foreach (char ch in value.ToCharArray())
{
buffer.Put((byte)ch);
}
}
}
}
}

View file

@ -0,0 +1,106 @@
using FSO.Common.Serialization.TypeSerializers;
using Mina.Core.Buffer;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
namespace FSO.Common.Serialization
{
public class ModelSerializer : IModelSerializer
{
private List<ITypeSerializer> TypeSerializers = new List<ITypeSerializer>();
private ConcurrentDictionary<Type, ITypeSerializer> SerialCache = new ConcurrentDictionary<Type, ITypeSerializer>();
private ConcurrentDictionary<uint, ITypeSerializer> DeserialCache = new ConcurrentDictionary<uint, ITypeSerializer>();
public ModelSerializer(){
//Built-in
AddTypeSerializer(new cTSOValueBoolean());
AddTypeSerializer(new cTSOValueBooleanVector());
AddTypeSerializer(new cTSOValueBooleanMap());
AddTypeSerializer(new cTSOValueString());
AddTypeSerializer(new cTSOValueStringVector());
AddTypeSerializer(new cTSOValueByte());
AddTypeSerializer(new cTSOValueByteVector());
AddTypeSerializer(new cTSOValueSByte());
AddTypeSerializer(new cTSOValueSByteVector());
AddTypeSerializer(new cTSOValueUInt32());
AddTypeSerializer(new cTSOValueUInt32Vector());
AddTypeSerializer(new cTSOValueUInt16());
AddTypeSerializer(new cTSOValueDecorated());
AddTypeSerializer(new cTSOValueUInt64());
AddTypeSerializer(new cTSOValueGenericData());
}
public uint? GetClsid(object value)
{
if (value == null) { return null; }
var serializer = GetSerializer(value.GetType());
if (serializer == null) { return null; }
return serializer.GetClsid(value);
}
public void Serialize(IoBuffer output, object obj, ISerializationContext context)
{
if (obj == null) { return; }
var serializer = GetSerializer(obj.GetType());
if (serializer == null) { return; }
serializer.Serialize(output, obj, context);
}
public void Serialize(IoBuffer output, object value, ISerializationContext context, bool clsIdPrefix)
{
if (value == null) { return; }
var serializer = GetSerializer(value.GetType());
if (serializer == null) { return; }
if (clsIdPrefix){
output.PutUInt32(serializer.GetClsid(value).Value);
}
serializer.Serialize(output, value, context);
}
public IoBuffer SerializeBuffer(object value, ISerializationContext context, bool clsIdPrefix)
{
var buffer = IoBuffer.Allocate(256);
buffer.AutoExpand = true;
buffer.Order = ByteOrder.BigEndian;
Serialize(buffer, value, context, clsIdPrefix);
buffer.Flip();
return buffer;
}
public object Deserialize(uint clsid, IoBuffer input, ISerializationContext context)
{
var serializer = GetSerializer(clsid);
if (serializer == null) { return null; }
return serializer.Deserialize(clsid, input, context);
}
public void AddTypeSerializer(ITypeSerializer serializer)
{
TypeSerializers.Add(serializer);
}
private ITypeSerializer GetSerializer(uint clsid){
return DeserialCache.GetOrAdd(clsid, (t) =>
{
return TypeSerializers.FirstOrDefault(x => x.CanDeserialize(clsid));
});
}
private ITypeSerializer GetSerializer(Type type){
return SerialCache.GetOrAdd(type, (t) =>
{
return TypeSerializers.FirstOrDefault(x => x.CanSerialize(type));
});
}
}
}

View file

@ -0,0 +1,13 @@
namespace FSO.Common.Serialization.Primitives
{
public class cTSOGenericData
{
public byte[] Data;
public cTSOGenericData() { }
public cTSOGenericData(byte[] data)
{
Data = data;
}
}
}

View file

@ -0,0 +1,114 @@
using System;
using Mina.Core.Buffer;
using System.ComponentModel;
using FSO.Common.Serialization.TypeSerializers;
namespace FSO.Common.Serialization.Primitives
{
[cTSOValue(0x125194E5)]
public class cTSONetMessageStandard : IoBufferSerializable, IoBufferDeserializable
{
public uint Unknown_1 { get; set; }
public uint SendingAvatarID { get; set; }
public cTSOParameterizedEntityFlags Flags { get; set; }
public uint MessageID { get; set; }
public uint? DatabaseType { get; set; }
public uint? DataServiceType { get; set; }
public uint? Parameter { get; set; }
public uint RequestResponseID { get; set; }
[TypeConverter(typeof(ExpandableObjectConverter))]
public object ComplexParameter { get; set; }
public uint Unknown_2 { get; set; }
public cTSONetMessageStandard(){
}
public void Deserialize(IoBuffer input, ISerializationContext context)
{
this.Unknown_1 = input.GetUInt32();
this.SendingAvatarID = input.GetUInt32();
var flagsByte = input.Get();
this.Flags = (cTSOParameterizedEntityFlags)flagsByte;
this.MessageID = input.GetUInt32();
if ((this.Flags & cTSOParameterizedEntityFlags.HAS_DS_TYPE) == cTSOParameterizedEntityFlags.HAS_DS_TYPE)
{
this.DataServiceType = input.GetUInt32();
}else if ((this.Flags & cTSOParameterizedEntityFlags.HAS_DB_TYPE) == cTSOParameterizedEntityFlags.HAS_DB_TYPE){
this.DatabaseType = input.GetUInt32();
}
if ((this.Flags & cTSOParameterizedEntityFlags.HAS_BASIC_PARAMETER) == cTSOParameterizedEntityFlags.HAS_BASIC_PARAMETER)
{
this.Parameter = input.GetUInt32();
}
if ((this.Flags & cTSOParameterizedEntityFlags.UNKNOWN) == cTSOParameterizedEntityFlags.UNKNOWN)
{
this.Unknown_2 = input.GetUInt32();
}
if ((this.Flags & cTSOParameterizedEntityFlags.HAS_COMPLEX_PARAMETER) == cTSOParameterizedEntityFlags.HAS_COMPLEX_PARAMETER)
{
uint typeId = DatabaseType.HasValue ? DatabaseType.Value : DataServiceType.Value;
this.ComplexParameter = context.ModelSerializer.Deserialize(typeId, input, context);
}
}
public void Serialize(IoBuffer output, ISerializationContext context)
{
output.PutUInt32(Unknown_1);
output.PutUInt32(SendingAvatarID);
byte flags = 0;
if (this.DatabaseType.HasValue){
flags |= (byte)cTSOParameterizedEntityFlags.HAS_DB_TYPE;
}
if (this.DataServiceType.HasValue){
flags |= (byte)cTSOParameterizedEntityFlags.HAS_DB_TYPE;
flags |= (byte)cTSOParameterizedEntityFlags.HAS_DS_TYPE;
}
if (this.Parameter != null){
flags |= (byte)cTSOParameterizedEntityFlags.HAS_BASIC_PARAMETER;
}
if(this.ComplexParameter != null){
flags |= (byte)cTSOParameterizedEntityFlags.HAS_COMPLEX_PARAMETER;
}
output.Put(flags);
output.PutUInt32(MessageID);
if (this.DataServiceType.HasValue)
{
output.PutUInt32(this.DataServiceType.Value);
}else if (this.DatabaseType.HasValue){
output.PutUInt32(this.DatabaseType.Value);
}
if (this.Parameter.HasValue){
output.PutUInt32(this.Parameter.Value);
}
if (this.ComplexParameter != null){
context.ModelSerializer.Serialize(output, ComplexParameter, context, false);
}
}
}
[Flags]
public enum cTSOParameterizedEntityFlags
{
HAS_DB_TYPE = 1,
HAS_DS_TYPE = 2,
HAS_BASIC_PARAMETER = 4,
UNKNOWN = 8,
HAS_COMPLEX_PARAMETER = 32
}
}

View file

@ -0,0 +1,53 @@
using System.Collections.Generic;
using Mina.Core.Buffer;
namespace FSO.Common.Serialization.Primitives
{
public class cTSOProperty : IoBufferSerializable, IoBufferDeserializable
{
public uint StructType;
public List<cTSOPropertyField> StructFields;
public void Serialize(IoBuffer output, ISerializationContext context)
{
output.PutUInt32(0x89739A79);
output.PutUInt32(StructType);
output.PutUInt32((uint)StructFields.Count);
foreach (var item in StructFields)
{
output.PutUInt32(item.StructFieldID);
context.ModelSerializer.Serialize(output, item.Value, context, true);
}
}
public void Deserialize(IoBuffer input, ISerializationContext context)
{
//Unknown
input.GetUInt32();
StructType = input.GetUInt32();
StructFields = new List<cTSOPropertyField>();
var numFields = input.GetUInt32();
for(int i=0; i < numFields; i++){
var fieldId = input.GetUInt32();
var typeId = input.GetUInt32();
var value = context.ModelSerializer.Deserialize(typeId, input, context);
StructFields.Add(new cTSOPropertyField
{
StructFieldID = fieldId,
Value = value
});
}
}
}
public class cTSOPropertyField
{
public uint StructFieldID;
public object Value;
}
}

View file

@ -0,0 +1,70 @@
using Mina.Core.Buffer;
using FSO.Common.Serialization.TypeSerializers;
namespace FSO.Common.Serialization.Primitives
{
[cTSOValue(0x9736027)]
public class cTSOTopicUpdateMessage : IoBufferSerializable, IoBufferDeserializable
{
public uint MessageId { get; set; } = 0xA97360C5;
public uint StructType { get; set; }
public uint StructId { get; set; }
public uint StructField { get; set; }
public uint[] DotPath { get; set; }
public uint Unknown1 { get; set; }
public uint Unknown2 { get; set; }
public object Value { get; set; }
public string ReasonText { get; set; }
public void Serialize(IoBuffer output, ISerializationContext context)
{
output.PutUInt32(Unknown1); //Update counter
output.PutUInt32(MessageId); //Message id
output.PutUInt32(Unknown2); //Unknown
if (DotPath != null)
{
output.PutUInt32((uint)DotPath.Length);
foreach(var component in DotPath){
output.PutUInt32(component);
}
}
else
{
//Vector size
output.PutUInt32(3);
output.PutUInt32(StructType);
output.PutUInt32(StructId);
output.PutUInt32(StructField);
}
//Write value
context.ModelSerializer.Serialize(output, Value, context, true);
output.PutPascalVLCString(ReasonText);
}
public void Deserialize(IoBuffer input, ISerializationContext context)
{
Unknown1 = input.GetUInt32();
MessageId = input.GetUInt32();
Unknown2 = input.GetUInt32();
var vectorSize = input.GetUInt32();
DotPath = new uint[vectorSize];
for(int i=0; i < vectorSize; i++){
DotPath[i] = input.GetUInt32();
}
var valueType = input.GetUInt32();
this.Value = context.ModelSerializer.Deserialize(valueType, input, context);
//this.ReasonText = input.GetPascalVLCString();
}
}
}

View file

@ -0,0 +1,16 @@
using Ninject;
namespace FSO.Common.Serialization
{
public class SerializationContext : ISerializationContext
{
public IKernel Kernel { get; internal set; }
public IModelSerializer ModelSerializer { get; internal set; }
public SerializationContext(IKernel Kernel, IModelSerializer ModelSerializer)
{
this.Kernel = Kernel;
this.ModelSerializer = ModelSerializer;
}
}
}

View file

@ -0,0 +1,37 @@
using Mina.Core.Buffer;
using System;
namespace FSO.Common.Serialization.TypeSerializers
{
public class cTSOValueBoolean : ITypeSerializer
{
private readonly uint CLSID = 0x696D1183;
public bool CanDeserialize(uint clsid)
{
return clsid == CLSID;
}
public bool CanSerialize(Type type)
{
return type.IsAssignableFrom(typeof(bool));
}
public object Deserialize(uint clsid, IoBuffer input, ISerializationContext serializer)
{
var byteValue = input.Get();
return byteValue == 0x01 ? true : false;
}
public void Serialize(IoBuffer output, object value, ISerializationContext serializer)
{
bool boolValue = (bool)value;
output.Put(boolValue ? (byte)0x01 : (byte)0x00);
}
public uint? GetClsid(object value)
{
return CLSID;
}
}
}

View file

@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using Mina.Core.Buffer;
using System.Collections.Immutable;
namespace FSO.Common.Serialization.TypeSerializers
{
public class cTSOValueBooleanMap : ITypeSerializer
{
private readonly uint CLSID = 0xC97757F5;
public bool CanDeserialize(uint clsid)
{
return clsid == CLSID;
}
public bool CanSerialize(Type type)
{
return typeof(ImmutableDictionary<uint, bool>).IsAssignableFrom(type);
}
public object Deserialize(uint clsid, IoBuffer buffer, ISerializationContext serializer)
{
var result = new Dictionary<uint, bool>();
var count = buffer.GetUInt32();
for(int i=0; i < count; i++){
var key = buffer.GetUInt32();
result.Add(key, buffer.Get() > 0);
}
return ImmutableDictionary.ToImmutableDictionary(result);
}
public void Serialize(IoBuffer output, object value, ISerializationContext serializer)
{
var dict = (ImmutableDictionary<uint, bool>)value;
output.PutUInt32((uint)dict.Count);
foreach (var elem in dict)
{
output.PutUInt32(elem.Key);
output.Put((byte)(elem.Value ? 1 : 0));
}
}
public uint? GetClsid(object value)
{
return CLSID;
}
}
}

View file

@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using Mina.Core.Buffer;
using System.Collections.Immutable;
namespace FSO.Common.Serialization.TypeSerializers
{
public class cTSOValueBooleanVector : ITypeSerializer
{
private readonly uint CLSID = 0x89738492;
public bool CanDeserialize(uint clsid)
{
return clsid == CLSID;
}
public bool CanSerialize(Type type)
{
return typeof(IList<bool>).IsAssignableFrom(type);
}
public object Deserialize(uint clsid, IoBuffer buffer, ISerializationContext serializer)
{
var result = new List<bool>();
var count = buffer.GetUInt32();
for(int i=0; i < count; i++){
result.Add(buffer.Get() > 0);
}
return ImmutableList.ToImmutableList(result);
}
public void Serialize(IoBuffer output, object value, ISerializationContext serializer)
{
IList<bool> list = (IList<bool>)value;
output.PutUInt32((uint)list.Count);
byte last = 0;
int pos = 0;
for (int i = 0; i < list.Count; i++)
{
output.Put((byte)(list[i]?1:0));
//output.Put((byte)(1));
/*last |= (byte)((list[i] ? 1 : 0) << pos++);
if (pos >= 8)
{
output.Put(last);
pos = 0;
last = 0;
}*/
}
}
public uint? GetClsid(object value)
{
return CLSID;
}
}
}

View file

@ -0,0 +1,35 @@
using System;
using Mina.Core.Buffer;
namespace FSO.Common.Serialization.TypeSerializers
{
public class cTSOValueByte : ITypeSerializer
{
private readonly uint CLSID = 0xC976087C;
public bool CanDeserialize(uint clsid)
{
return clsid == CLSID;
}
public bool CanSerialize(Type type)
{
return type.IsAssignableFrom(typeof(byte));
}
public object Deserialize(uint clsid, IoBuffer input, ISerializationContext serializer)
{
return input.Get();
}
public void Serialize(IoBuffer output, object value, ISerializationContext serializer)
{
output.Put((byte)value);
}
public uint? GetClsid(object value)
{
return CLSID;
}
}
}

View file

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using Mina.Core.Buffer;
using System.Collections.Immutable;
namespace FSO.Common.Serialization.TypeSerializers
{
public class cTSOValueByteVector : ITypeSerializer
{
private readonly uint CLSID = 0x097608AB;
public bool CanDeserialize(uint clsid)
{
return clsid == CLSID;
}
public bool CanSerialize(Type type)
{
return typeof(IList<byte>).IsAssignableFrom(type);
}
public object Deserialize(uint clsid, IoBuffer buffer, ISerializationContext serializer)
{
var result = new List<byte>();
var count = buffer.GetUInt32();
for(int i=0; i < count; i++){
result.Add(buffer.Get());
}
return ImmutableList.ToImmutableList(result);
}
public void Serialize(IoBuffer output, object value, ISerializationContext serializer)
{
IList<byte> list = (IList<byte>)value;
output.PutUInt32((uint)list.Count);
for (int i = 0; i < list.Count; i++)
{
output.Put(list[i]);
}
}
public uint? GetClsid(object value)
{
return CLSID;
}
}
}

View file

@ -0,0 +1,97 @@
using System;
using System.Collections.Generic;
using Mina.Core.Buffer;
using System.Reflection;
using FSO.Common.Utils;
namespace FSO.Common.Serialization.TypeSerializers
{
/// <summary>
/// Serializes / deserializes anything that implements IoBufferSerializable & IoBufferDeserializable and has a cTSOValue decoration
/// </summary>
public class cTSOValueDecorated : ITypeSerializer
{
protected Dictionary<uint, Type> ClsIdToType = new Dictionary<uint, Type>();
protected Dictionary<Type, uint> TypeToClsId = new Dictionary<Type, uint>();
public cTSOValueDecorated(){
//
//var assembly = Assembly.GetAssembly(typeof(cTSOSerializer));
var assemblies = AssemblyUtils.GetFreeSOLibs();
foreach(var asm in assemblies)
{
ScanAssembly(asm);
}
}
protected virtual void ScanAssembly(Assembly assembly)
{
try
{
foreach (Type type in assembly.GetTypes())
{
System.Attribute[] attributes = System.Attribute.GetCustomAttributes(type);
foreach (Attribute attribute in attributes)
{
if (attribute is cTSOValue)
{
foreach (uint clsid in ((cTSOValue)attribute).ClsId)
{
ClsIdToType.Add(clsid, type);
TypeToClsId.Add(type, clsid);
}
}
}
}
} catch (Exception)
{
}
}
public bool CanDeserialize(uint clsid)
{
return ClsIdToType.ContainsKey(clsid);
}
public bool CanSerialize(Type type)
{
return TypeToClsId.ContainsKey(type);
}
public object Deserialize(uint clsid, IoBuffer input, ISerializationContext serializer)
{
var instance = Activator.CreateInstance(ClsIdToType[clsid]);
((IoBufferDeserializable)instance).Deserialize(input, serializer);
return instance;
}
public uint? GetClsid(object value)
{
Type type = value.GetType();
if (TypeToClsId.ContainsKey(type))
{
return TypeToClsId[type];
}
return null;
}
public void Serialize(IoBuffer output, object value, ISerializationContext serializer)
{
((IoBufferSerializable)value).Serialize(output, serializer);
}
}
[System.AttributeUsage(System.AttributeTargets.Class)]
public class cTSOValue : System.Attribute
{
public uint[] ClsId;
public cTSOValue(params uint[] ClsId)
{
this.ClsId = ClsId;
}
}
}

View file

@ -0,0 +1,50 @@
using FSO.Common.Serialization.Primitives;
using Mina.Core.Buffer;
using System;
using System.Collections.Generic;
namespace FSO.Common.Serialization.TypeSerializers
{
class cTSOValueGenericData : ITypeSerializer
{
private readonly uint CLSID = 0xA99AF3B7;
public bool CanDeserialize(uint clsid)
{
return clsid == CLSID;
}
public bool CanSerialize(Type type)
{
return type.IsAssignableFrom(typeof(cTSOGenericData));
}
public object Deserialize(uint clsid, IoBuffer input, ISerializationContext serializer)
{
var result = new List<byte>();
var iclsid = input.GetUInt32();
var count = input.GetUInt32();
for (int i = 0; i < count; i++)
{
result.Add(input.Get());
}
return new cTSOGenericData(result.ToArray());
}
public void Serialize(IoBuffer output, object value, ISerializationContext serializer)
{
var dat = (cTSOGenericData)value;
output.PutUInt32(0x0A2C6585);
output.PutUInt32((uint)dat.Data.Length);
for (int i = 0; i < dat.Data.Length; i++)
{
output.Put(dat.Data[i]);
}
}
public uint? GetClsid(object value)
{
return CLSID;
}
}
}

View file

@ -0,0 +1,35 @@
using System;
using Mina.Core.Buffer;
namespace FSO.Common.Serialization.TypeSerializers
{
public class cTSOValueSByte : ITypeSerializer
{
private readonly uint CLSID = 0xE976088A;
public bool CanDeserialize(uint clsid)
{
return clsid == CLSID;
}
public bool CanSerialize(Type type)
{
return type.IsAssignableFrom(typeof(sbyte));
}
public object Deserialize(uint clsid, IoBuffer input, ISerializationContext serializer)
{
return (sbyte)input.Get();
}
public void Serialize(IoBuffer output, object value, ISerializationContext serializer)
{
output.Put((byte)(sbyte)value);
}
public uint? GetClsid(object value)
{
return CLSID;
}
}
}

View file

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using Mina.Core.Buffer;
using System.Collections.Immutable;
namespace FSO.Common.Serialization.TypeSerializers
{
public class cTSOValueSByteVector : ITypeSerializer
{
private readonly uint CLSID = 0x097608AF;
public bool CanDeserialize(uint clsid)
{
return clsid == CLSID;
}
public bool CanSerialize(Type type)
{
return typeof(IList<sbyte>).IsAssignableFrom(type);
}
public object Deserialize(uint clsid, IoBuffer input, ISerializationContext serializer)
{
var result = new List<sbyte>();
var count = input.GetUInt32();
for(int i=0; i < count; i++){
result.Add((sbyte)input.Get());
}
return ImmutableList.ToImmutableList(result);
}
public void Serialize(IoBuffer output, object value, ISerializationContext serializer)
{
IList<sbyte> list = (IList<sbyte>)value;
output.PutUInt32((uint)list.Count);
for (int i = 0; i < list.Count; i++)
{
output.Put((byte)list[i]);
}
}
public uint? GetClsid(object value)
{
return CLSID;
}
}
}

View file

@ -0,0 +1,35 @@
using System;
using Mina.Core.Buffer;
namespace FSO.Common.Serialization.TypeSerializers
{
public class cTSOValueString : ITypeSerializer
{
private readonly uint CLSID = 0x896D1688;
public bool CanDeserialize(uint clsid)
{
return clsid == CLSID;
}
public bool CanSerialize(Type type)
{
return type.IsAssignableFrom(typeof(string));
}
public object Deserialize(uint clsid, IoBuffer input, ISerializationContext serializer)
{
return IoBufferUtils.GetPascalVLCString(input);
}
public void Serialize(IoBuffer output, object value, ISerializationContext serializer)
{
output.PutPascalVLCString((string)value);
}
public uint? GetClsid(object value)
{
return CLSID;
}
}
}

View file

@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using Mina.Core.Buffer;
using System.Collections.Immutable;
namespace FSO.Common.Serialization.TypeSerializers
{
public class cTSOValueStringVector : ITypeSerializer
{
private readonly uint CLSID = 0x8973849E;
public bool CanDeserialize(uint clsid)
{
return clsid == CLSID;
}
public bool CanSerialize(Type type)
{
return typeof(IList<string>).IsAssignableFrom(type);
}
public object Deserialize(uint clsid, IoBuffer input, ISerializationContext serializer)
{
var result = new List<String>();
var count = input.GetUInt32();
for(int i=0; i < count; i++){
result.Add(IoBufferUtils.GetPascalVLCString(input));
}
return ImmutableList.ToImmutableList(result);
}
public void Serialize(IoBuffer output, object value, ISerializationContext serializer)
{
IList<String> list = (IList<String>)value;
output.PutUInt32((uint)list.Count);
for(int i=0; i < list.Count; i++){
output.PutPascalVLCString(list[i]);
}
}
public uint? GetClsid(object value)
{
return CLSID;
}
}
}

View file

@ -0,0 +1,36 @@
using Mina.Core.Buffer;
using System;
namespace FSO.Common.Serialization.TypeSerializers
{
public class cTSOValueUInt16 : ITypeSerializer
{
//0xE9760891: cTSOValue<unsigned short>
private readonly uint CLSID = 0xE9760891;
public bool CanDeserialize(uint clsid)
{
return clsid == CLSID;
}
public bool CanSerialize(Type type)
{
return type.IsAssignableFrom(typeof(ushort));
}
public object Deserialize(uint clsid, IoBuffer input, ISerializationContext serializer)
{
return input.GetUInt16();
}
public void Serialize(IoBuffer output, object value, ISerializationContext serializer)
{
output.PutUInt16((ushort)value);
}
public uint? GetClsid(object value)
{
return CLSID;
}
}
}

View file

@ -0,0 +1,36 @@
using Mina.Core.Buffer;
using System;
namespace FSO.Common.Serialization.TypeSerializers
{
public class cTSOValueUInt32 : ITypeSerializer
{
//0x696D1189: cTSOValue<unsigned long>
private readonly uint CLSID = 0x696D1189;
public bool CanDeserialize(uint clsid)
{
return clsid == CLSID;
}
public bool CanSerialize(Type type)
{
return type.IsAssignableFrom(typeof(uint));
}
public object Deserialize(uint clsid, IoBuffer input, ISerializationContext serializer)
{
return input.GetUInt32();
}
public void Serialize(IoBuffer output, object value, ISerializationContext serializer)
{
output.PutUInt32((uint)value);
}
public uint? GetClsid(object value)
{
return CLSID;
}
}
}

View file

@ -0,0 +1,49 @@
using Mina.Core.Buffer;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
namespace FSO.Common.Serialization.TypeSerializers
{
class cTSOValueUInt32Vector : ITypeSerializer
{
//0x89738496: cTSOValueVector<unsigned long>
private readonly uint CLSID = 0x89738496;
public bool CanDeserialize(uint clsid)
{
return clsid == CLSID;
}
public bool CanSerialize(Type type)
{
return typeof(IList<uint>).IsAssignableFrom(type);
}
public object Deserialize(uint clsid, IoBuffer input, ISerializationContext serializer)
{
var result = new List<uint>();
var count = input.GetUInt32();
for (int i = 0; i < count; i++)
{
result.Add((uint)input.GetUInt32());
}
return ImmutableList.ToImmutableList(result);
}
public void Serialize(IoBuffer output, object value, ISerializationContext serializer)
{
IList<uint> list = (IList<uint>)value;
output.PutUInt32((uint)list.Count);
for (int i = 0; i < list.Count; i++)
{
output.PutUInt32((uint)list[i]);
}
}
public uint? GetClsid(object value)
{
return CLSID;
}
}
}

View file

@ -0,0 +1,36 @@
using Mina.Core.Buffer;
using System;
namespace FSO.Common.Serialization.TypeSerializers
{
public class cTSOValueUInt64 : ITypeSerializer
{
//0x69D3E3DB: cTSOValue<unsigned __int64>
private readonly uint CLSID = 0x69D3E3DB;
public bool CanDeserialize(uint clsid)
{
return clsid == CLSID;
}
public bool CanSerialize(Type type)
{
return type.IsAssignableFrom(typeof(ulong));
}
public object Deserialize(uint clsid, IoBuffer input, ISerializationContext serializer)
{
return input.GetUInt64();
}
public void Serialize(IoBuffer output, object value, ISerializationContext serializer)
{
output.PutUInt64((ulong)value);
}
public uint? GetClsid(object value)
{
return CLSID;
}
}
}