static void GetShortsUpdateValue(Hashtable tbl, MemberValue value, int field) { UpdateValueAttribute attrib = (UpdateValueAttribute)value.Attribute; if (attrib.ShortsIndex < 0 || attrib.ShortsIndex > 1) { throw new ObjectUpdateManagerException("ShortsIndex out of range on " + value.GetName() + " ShortsIndex = " + attrib.ShortsIndex); } if (tbl.Contains(field)) { object tmp = tbl[field]; Type cType = tmp.GetType(); if (cType != typeof(ShortUU_UpdateValue) && cType != typeof(ShortSS_UpdateValue)) { throw new ObjectUpdateManagerException("Failed to combine short values on field " + field + ", type " + tmp.GetType() + " was already in hashtable (" + value.GetName() + ")"); } IShortsCombine c = (IShortsCombine)tmp; tbl[field] = c.ShortsCombine(value, attrib.ShortsIndex, value.GetValueType()); } else { if (value.GetValueType() == typeof(short)) { ShortSS_UpdateValue uv = new ShortSS_UpdateValue(field); uv.SetMemberValue(value, attrib.ShortsIndex); tbl[field] = uv; } else { ShortUU_UpdateValue uv = new ShortUU_UpdateValue(field); uv.SetMemberValue(value, attrib.ShortsIndex); tbl[field] = uv; } } }
static void GetBytesUpdateValue(Hashtable tbl, MemberValue value, int field) { UpdateValueAttribute attrib = (UpdateValueAttribute)value.Attribute; if (attrib.BytesIndex < 0 || attrib.BytesIndex > 3) { throw new ObjectUpdateManagerException("BytesIndex out of range on " + value.GetName() + " BytesIndex = " + attrib.BytesIndex); } BytesUpdateValue v; if (tbl.Contains(field)) { IUpdateValue tmp = (IUpdateValue)tbl[field]; if (!(tmp is BytesUpdateValue)) { throw new ObjectUpdateManagerException("Field " + field + " was a " + tmp.GetType() + " not a BytesUpdateValue (" + value.GetName() + ")"); } v = (BytesUpdateValue)tmp; } else { v = new BytesUpdateValue(field); tbl[field] = v; } v.SetMemberValue(value, attrib.BytesIndex); }
static bool checkType(UpdateValueAttribute attrib, Type type) { if (attrib.OnlyForType == null) { return(true); } if (attrib.OnlyForType == type) { return(true); } while (type.BaseType != typeof(object)) { type = type.BaseType; if (attrib.OnlyForType == type) { return(true); } } return(false); }
static void GetSubClassUpdateValues(Hashtable tbl, MemberValue parentValue, int baseField, Type type, Type updateObjectType) { foreach (MemberValue tmp in MemberValue.GetMemberValues(type, typeof(UpdateValueAttribute), true, false)) { MemberValue value = new SubClassMemberValue(parentValue, tmp); UpdateValueAttribute attrib = (UpdateValueAttribute)value.Attribute; if (!checkType(attrib, updateObjectType)) { continue; } Type valueType = value.GetValueType(); if (valueType.IsArray == false) { if (!IsSubClass(valueType)) { if (attrib.Field == -1) { throw new ObjectUpdateManagerException("Field was not set on " + updateObjectType.Name + value.GetName()); } if (tmp is IndexMemberValue) { IndexMemberValue indexValue = tmp as IndexMemberValue; if (valueType == typeof(ulong) || valueType == typeof(long)) { AddUpdateValue(tbl, value, baseField + attrib.Field + indexValue.Index * 2); } else { AddUpdateValue(tbl, value, baseField + attrib.Field + indexValue.Index); } } else { AddUpdateValue(tbl, value, baseField + attrib.Field); } } else { GetSubClassUpdateValues(tbl, value, attrib.Field == -1 ? baseField : (baseField + attrib.Field), valueType, type); } } else { if (attrib.ArraySize == -1) { throw new ObjectUpdateManagerException("ArraySize was not set on " + updateObjectType.Name + "." + value.GetName()); } if (attrib.Field == -1) { throw new ObjectUpdateManagerException("Field was not set on the array " + updateObjectType.Name + "." + value.GetName()); } if (attrib.NumSubFields == -1) { throw new ObjectUpdateManagerException("NumFields was not set on the subclass array " + updateObjectType.Name + "." + value.GetName()); } valueType = valueType.GetElementType(); for (int i = 0; i < attrib.ArraySize; i++) { IndexMemberValue indexValue = new IndexMemberValue(value, i); GetSubClassUpdateValues(tbl, indexValue, baseField + attrib.Field + i * attrib.NumSubFields, valueType, updateObjectType); } } } }
public static void RegisterUpdateObject(Type type) { try { object[] tmp = type.GetCustomAttributes(typeof(UpdateObjectAttribute), true); if (tmp.Length == 0) { throw new ObjectUpdateManagerException(type.ToString() + " has no UpdateObjectAttribute"); } UpdateObjectAttribute updateObjectAttribute = (UpdateObjectAttribute)tmp[0]; if (updateObjectAttribute.MaxFields == -1) { throw new ObjectUpdateManagerException("MaxFields is not set in UpdateObjectAttribute on " + type.ToString()); } Hashtable tbl = new Hashtable(); foreach (MemberValue value in MemberValue.GetMemberValues(type, typeof(UpdateValueAttribute), true, false)) { UpdateValueAttribute attrib = (UpdateValueAttribute)value.Attribute; if (!checkType(attrib, type)) { continue; } Type valueType = value.GetValueType(); if (valueType.IsArray == false) { if (!IsSubClass(valueType)) { if (attrib.Field == -1) { throw new ObjectUpdateManagerException("Field was not set on " + type.Name + value.GetName()); } if (value is IndexMemberValue) { IndexMemberValue indexValue = value as IndexMemberValue; if (valueType == typeof(ulong) || valueType == typeof(long)) { AddUpdateValue(tbl, value, attrib.Field + indexValue.Index * 2); } else { AddUpdateValue(tbl, value, attrib.Field + indexValue.Index); } } else { AddUpdateValue(tbl, value, attrib.Field); } } else { GetSubClassUpdateValues(tbl, value, attrib.Field == -1 ? 0 : attrib.Field, valueType, type); } } else { if (attrib.ArraySize == -1) { throw new ObjectUpdateManagerException("ArraySize was not set on " + type.Name + "." + value.GetName()); } if (attrib.Field == -1) { throw new ObjectUpdateManagerException("Field was not set on the array " + type.Name + "." + value.GetName()); } if (attrib.NumSubFields == -1) { throw new ObjectUpdateManagerException("NumFields was not set on the subclass array " + type.Name + "." + value.GetName()); } valueType = valueType.GetElementType(); for (int i = 0; i < attrib.ArraySize; i++) { IndexMemberValue indexValue = new IndexMemberValue(value, i); GetSubClassUpdateValues(tbl, indexValue, attrib.Field + i * attrib.NumSubFields, valueType, type); } } } if (tbl.Count == 0) { throw new ObjectUpdateManagerException("No update values in " + type.ToString()); } UpdateObjectInfo uoi = new UpdateObjectInfo(tbl, updateObjectAttribute.MaxFields); m_updateObjectInfos[type] = uoi; } catch (Exception exp) { DebugLogger.Log("", exp); } }