com.xmobitea.changx.gn-unity 2.0.2 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/Editor/GNServerSettingsEditor.cs +42 -322
  2. package/Runtime/Common/GNArray.cs +120 -35
  3. package/Runtime/Common/GNData.cs +19 -6
  4. package/Runtime/Common/GNHashtable.cs +174 -11
  5. package/Runtime/Common/IGNData.cs +11 -2
  6. package/Runtime/Config/GNServerSettings.cs +136 -92
  7. package/Runtime/Constant/Commands.cs +82 -19
  8. package/Runtime/Constant/EnumType/GoogleLoginType.cs +5 -5
  9. package/Runtime/Constant/EnumType/GroupStatus.cs +7 -7
  10. package/Runtime/Constant/EnumType/ItemType.cs +5 -5
  11. package/Runtime/Constant/EnumType/MatchmakingMemberStatus.cs +6 -6
  12. package/Runtime/Constant/EnumType/MatchmakingTicketStatus.cs +2 -2
  13. package/Runtime/Constant/EnumType/OwnerType.cs +3 -2
  14. package/Runtime/Constant/EnumType/PushPlatformType.cs +10 -0
  15. package/Runtime/Constant/EnumType/PushPlatformType.cs.meta +11 -0
  16. package/Runtime/Constant/EnumType/RequestType.cs +1 -0
  17. package/Runtime/Constant/EnumType/StoreReceiveType.cs +13 -0
  18. package/Runtime/Constant/EnumType/StoreReceiveType.cs.meta +11 -0
  19. package/Runtime/Constant/ErrorCode/GNErrorCode.cs +53 -48
  20. package/Runtime/Constant/EventCode.cs +29 -2
  21. package/Runtime/Constant/OperationCode.cs +249 -211
  22. package/Runtime/Constant/ParameterCode/GNParameterCode.cs +610 -466
  23. package/Runtime/Constant/ReturnCode.cs +50 -2
  24. package/Runtime/Entity/DataMember.cs +221 -3
  25. package/Runtime/Entity/GNMetadata.cs +46 -1
  26. package/Runtime/Entity/InvalidMember.cs +24 -5
  27. package/Runtime/Entity/Models/AuthenticateModels.cs +251 -207
  28. package/Runtime/Entity/Models/AuthenticateRequestModels.cs +153 -131
  29. package/Runtime/Entity/Models/AuthenticateResponseModels.cs +61 -51
  30. package/Runtime/Entity/Models/CharacterPlayerModels.cs +985 -849
  31. package/Runtime/Entity/Models/CharacterPlayerRequestModels.cs +957 -885
  32. package/Runtime/Entity/Models/CharacterPlayerResponseModels.cs +165 -150
  33. package/Runtime/Entity/Models/CloudScriptModels.cs +185 -0
  34. package/Runtime/Entity/Models/CloudScriptModels.cs.meta +11 -0
  35. package/Runtime/Entity/Models/CloudScriptRequestModels.cs +134 -0
  36. package/Runtime/Entity/Models/CloudScriptRequestModels.cs.meta +11 -0
  37. package/Runtime/Entity/Models/CloudScriptResponseModels.cs +34 -0
  38. package/Runtime/Entity/Models/CloudScriptResponseModels.cs.meta +11 -0
  39. package/Runtime/Entity/Models/ContentModels.cs +150 -153
  40. package/Runtime/Entity/Models/ContentRequestModels.cs +129 -129
  41. package/Runtime/Entity/Models/ContentResponseModels.cs +24 -24
  42. package/Runtime/Entity/Models/DashboardModels.cs +1684 -1156
  43. package/Runtime/Entity/Models/DashboardRequestModels.cs +220 -147
  44. package/Runtime/Entity/Models/DashboardResponseModels.cs +92 -57
  45. package/Runtime/Entity/Models/GamePlayerModels.cs +1073 -933
  46. package/Runtime/Entity/Models/GamePlayerRequestModels.cs +939 -867
  47. package/Runtime/Entity/Models/GamePlayerResponseModels.cs +162 -147
  48. package/Runtime/Entity/Models/GenericModels.cs +102 -102
  49. package/Runtime/Entity/Models/GroupModels.cs +812 -676
  50. package/Runtime/Entity/Models/GroupRequestModels.cs +741 -669
  51. package/Runtime/Entity/Models/GroupResponseModels.cs +129 -114
  52. package/Runtime/Entity/Models/InventoryModels.cs +667 -558
  53. package/Runtime/Entity/Models/InventoryRequestModels.cs +626 -579
  54. package/Runtime/Entity/Models/InventoryResponseModels.cs +109 -99
  55. package/Runtime/Entity/Models/MasterPlayerModels.cs +1882 -1340
  56. package/Runtime/Entity/Models/MasterPlayerRequestModels.cs +1643 -1253
  57. package/Runtime/Entity/Models/MasterPlayerResponseModels.cs +293 -213
  58. package/Runtime/Entity/Models/MultiplayerModels.cs +293 -223
  59. package/Runtime/Entity/Models/MultiplayerRequestModels.cs +199 -149
  60. package/Runtime/Entity/Models/MultiplayerResponseModels.cs +10 -0
  61. package/Runtime/Entity/Models/StoreInventoryModels.cs +514 -323
  62. package/Runtime/Entity/Models/StoreInventoryRequestModels.cs +236 -165
  63. package/Runtime/Entity/Models/StoreInventoryResponseModels.cs +45 -30
  64. package/Runtime/Entity/OperationEvent.cs +43 -7
  65. package/Runtime/Entity/OperationHelper.cs +18 -2
  66. package/Runtime/Entity/OperationRequest.cs +80 -37
  67. package/Runtime/Entity/OperationResponse.cs +111 -63
  68. package/Runtime/Entity/Request/CustomOperationRequest.cs +53 -2
  69. package/Runtime/Entity/Response/CustomOperationResponse.cs +25 -4
  70. package/Runtime/GNNetwork.cs +333 -21
  71. package/Runtime/GNNetworkApi.cs +25 -13
  72. package/Runtime/GNNetworkAuthenticateApi.cs +531 -98
  73. package/Runtime/GNNetworkCharacterPlayerApi.cs +1587 -762
  74. package/Runtime/GNNetworkCloudScriptApi.cs +181 -0
  75. package/Runtime/GNNetworkCloudScriptApi.cs.meta +11 -0
  76. package/Runtime/GNNetworkContentApi.cs +238 -132
  77. package/Runtime/GNNetworkDashboardApi.cs +278 -117
  78. package/Runtime/GNNetworkGamePlayerApi.cs +1558 -747
  79. package/Runtime/GNNetworkGroupApi.cs +1228 -582
  80. package/Runtime/GNNetworkInventoryApi.cs +1048 -507
  81. package/Runtime/GNNetworkMasterPlayerApi.cs +2586 -1067
  82. package/Runtime/GNNetworkMultiplayerApi.cs +328 -147
  83. package/Runtime/GNNetworkStoreInventoryApi.cs +388 -162
  84. package/Runtime/Helper/CodeHelper.cs +45 -3
  85. package/Runtime/Helper/ConverterService.cs +240 -85
  86. package/Runtime/Logger/GNDebug.cs +46 -3
  87. package/Runtime/Networking/AuthenticateStatus.cs +30 -8
  88. package/Runtime/Networking/Handler/IServerEventHandler.cs +8 -8
  89. package/Runtime/Networking/Handler/OnCharacterPlayerFriendUpdateEventHandler.cs +31 -2
  90. package/Runtime/Networking/Handler/OnCharacterPlayerGroupUpdateEventHandler.cs +24 -3
  91. package/Runtime/Networking/Handler/OnGamePlayerFriendUpdateEventHandler.cs +24 -2
  92. package/Runtime/Networking/Handler/OnGamePlayerGroupUpdateEventHandler.cs +24 -2
  93. package/Runtime/Networking/Handler/OnGroupMemberUpdateEventHandler.cs +21 -2
  94. package/Runtime/Networking/Handler/OnGroupMessageUpdateEventHandler.cs +20 -2
  95. package/Runtime/Networking/Http/HttpPeer.cs +68 -25
  96. package/Runtime/Networking/Http/NetworkingHttpPeerBase.cs +44 -4
  97. package/Runtime/Networking/Http/NetworkingPeerHttpClientRequest.cs +63 -40
  98. package/Runtime/Networking/Http/NetworkingPeerHttpRequest.cs +43 -13
  99. package/Runtime/Networking/Http/NetworkingPeerUnityWebRequest.cs +72 -39
  100. package/Runtime/Networking/IPeer.cs +24 -2
  101. package/Runtime/Networking/NetworkingPeer.cs +64 -10
  102. package/Runtime/Networking/NetworkingPeerAPI.cs +20 -21
  103. package/Runtime/Networking/OperationPending.cs +79 -15
  104. package/Runtime/Networking/PeerBase.cs +86 -23
  105. package/Runtime/Networking/Socket/NetworkingPeerSocketV2.cs +57 -18
  106. package/Runtime/Networking/Socket/NetworkingPeerSocketV3.cs +70 -10
  107. package/Runtime/Networking/Socket/NetworkingSocketPeerBase.cs +165 -23
  108. package/Runtime/Networking/Socket/SocketPeer.cs +63 -12
  109. package/Runtime/Unity/ServiceCoroutine.cs +10 -0
  110. package/Runtime/Unity/ServiceCoroutine.cs.meta +11 -0
  111. package/Runtime/Unity/ServiceUpdate.cs +14 -1
  112. package/package.json +1 -1
@@ -7,40 +7,52 @@
7
7
  using XmobiTea.GN.Common;
8
8
  using XmobiTea.GN.Entity;
9
9
 
10
+ /// <summary>
11
+ /// Mapper class for extracting and caching metadata of fields in a class decorated with DataMember attributes.
12
+ /// </summary>
10
13
  internal class DataMemberFieldInfoTypeMapper
11
14
  {
15
+ // A cache to store metadata mappings of fields for each class type
12
16
  private Dictionary<Type, GNEnhancedObjectFieldMetadata[]> declaredFieldsMap;
13
17
 
18
+ // Retrieves metadata for all fields in a class, including inherited ones
14
19
  public GNEnhancedObjectFieldMetadata[] getGNEnhancedObjectFieldMetadata(System.Type cls)
15
20
  {
16
21
  GNEnhancedObjectFieldMetadata[] declaredFields;
17
22
 
18
- if (this.declaredFieldsMap.ContainsKey(cls)) declaredFields = this.declaredFieldsMap[cls];
23
+ // If the class has been mapped, return the cached metadata
24
+ if (this.declaredFieldsMap.ContainsKey(cls))
25
+ {
26
+ declaredFields = this.declaredFieldsMap[cls];
27
+ }
19
28
  else
20
29
  {
30
+ // List to store all found fields
21
31
  var fieldInfoLst = new List<FieldInfo>();
22
32
 
23
33
  var currentCls = cls;
24
34
 
35
+ // Iterate through the class hierarchy to find all fields
25
36
  while (true)
26
37
  {
27
- var allDeclaredFields = currentCls.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly).Where(field => field.GetCustomAttribute<DataMemberAttribute>(true) != null);
38
+ // Retrieve all fields marked with the DataMemberAttribute
39
+ var allDeclaredFields = currentCls.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)
40
+ .Where(field => field.GetCustomAttribute<DataMemberAttribute>(true) != null);
28
41
 
29
42
  foreach (var field in allDeclaredFields)
30
43
  {
44
+ // Check if the field already exists in the list, add it if not
31
45
  var thisDeclaredField = fieldInfoLst.Find(x => x.Name.Equals(field.Name));
32
-
33
46
  if (thisDeclaredField == null) fieldInfoLst.Add(field);
34
47
  }
35
48
 
36
- if (currentCls.BaseType == typeof(object))
37
- {
38
- break;
39
- }
49
+ // If we have reached the base class (object), exit the loop
50
+ if (currentCls.BaseType == typeof(object)) break;
40
51
 
41
52
  currentCls = currentCls.BaseType;
42
53
  }
43
54
 
55
+ // Create an array to hold the metadata for the fields
44
56
  declaredFields = new GNEnhancedObjectFieldMetadata[fieldInfoLst.Count];
45
57
 
46
58
  for (var i = 0; i < fieldInfoLst.Count; i++)
@@ -49,12 +61,13 @@
49
61
 
50
62
  var field = fieldInfoLst[i];
51
63
 
64
+ // Retrieve the attribute information for the field
52
65
  var dataMemberAnno = field.GetCustomAttribute<DataMemberAttribute>(true);
53
66
 
67
+ // Handle each specific type of attribute and map its data to GNEnhancedObjectFieldMetadata
54
68
  if (dataMemberAnno is StringDataMemberAttribute stringDataMemberAnno)
55
69
  {
56
70
  gnEnhancedObjectFieldMetadata = new GNEnhancedObjectFieldMetadata(field.Name, FieldDataType.String, field.FieldType, field);
57
-
58
71
  gnEnhancedObjectFieldMetadata.defaultValue = stringDataMemberAnno.defaultValue;
59
72
  gnEnhancedObjectFieldMetadata.mustNonNull = stringDataMemberAnno.mustNonNull;
60
73
  gnEnhancedObjectFieldMetadata.minLength = stringDataMemberAnno.minLength;
@@ -63,13 +76,11 @@
63
76
  else if (dataMemberAnno is BooleanDataMemberAttribute booleanDataMemberAnno)
64
77
  {
65
78
  gnEnhancedObjectFieldMetadata = new GNEnhancedObjectFieldMetadata(field.Name, FieldDataType.Boolean, field.FieldType, field);
66
-
67
79
  gnEnhancedObjectFieldMetadata.defaultValue = booleanDataMemberAnno.defaultValue;
68
80
  }
69
81
  else if (dataMemberAnno is GNHashtableDataMemberAttribute gnHashtableDataMemberAnno)
70
82
  {
71
83
  gnEnhancedObjectFieldMetadata = new GNEnhancedObjectFieldMetadata(field.Name, FieldDataType.Object, field.FieldType, field);
72
-
73
84
  gnEnhancedObjectFieldMetadata.defaultValue = gnHashtableDataMemberAnno.defaultValue;
74
85
  gnEnhancedObjectFieldMetadata.mustNonNull = gnHashtableDataMemberAnno.mustNonNull;
75
86
  gnEnhancedObjectFieldMetadata.minLength = gnHashtableDataMemberAnno.minLength;
@@ -78,7 +89,6 @@
78
89
  else if (dataMemberAnno is GNArrayDataMemberAttribute gnArrayDataMemberAnno)
79
90
  {
80
91
  gnEnhancedObjectFieldMetadata = new GNEnhancedObjectFieldMetadata(field.Name, FieldDataType.Array, gnArrayDataMemberAnno.elementCls == null ? field.FieldType : gnArrayDataMemberAnno.elementCls, field);
81
-
82
92
  gnEnhancedObjectFieldMetadata.defaultValue = gnArrayDataMemberAnno.defaultValue;
83
93
  gnEnhancedObjectFieldMetadata.mustNonNull = gnArrayDataMemberAnno.mustNonNull;
84
94
  gnEnhancedObjectFieldMetadata.minLength = gnArrayDataMemberAnno.minLength;
@@ -87,7 +97,6 @@
87
97
  else if (dataMemberAnno is NumberDataMemberAttribute numberDataMemberAnno)
88
98
  {
89
99
  gnEnhancedObjectFieldMetadata = new GNEnhancedObjectFieldMetadata(field.Name, FieldDataType.Number, field.FieldType, field);
90
-
91
100
  gnEnhancedObjectFieldMetadata.defaultValue = numberDataMemberAnno.defaultValue;
92
101
  gnEnhancedObjectFieldMetadata.minValue = numberDataMemberAnno.minValue;
93
102
  gnEnhancedObjectFieldMetadata.maxValue = numberDataMemberAnno.maxValue;
@@ -96,33 +105,41 @@
96
105
  else
97
106
  {
98
107
  gnEnhancedObjectFieldMetadata = new GNEnhancedObjectFieldMetadata(field.Name, FieldDataType.Object, field.FieldType, field);
99
-
100
108
  gnEnhancedObjectFieldMetadata.defaultValue = dataMemberAnno.defaultValue;
101
109
  }
102
110
 
111
+ // Map common properties from the attribute to the metadata
103
112
  gnEnhancedObjectFieldMetadata.code = dataMemberAnno.code;
104
113
  gnEnhancedObjectFieldMetadata.isOptional = dataMemberAnno.isOptional;
105
114
  gnEnhancedObjectFieldMetadata.gnFieldType = dataMemberAnno.gnFieldType;
106
115
 
116
+ // Add the field metadata to the array
107
117
  declaredFields[i] = gnEnhancedObjectFieldMetadata;
108
118
  }
109
119
 
120
+ // Cache the metadata for future access
110
121
  this.declaredFieldsMap[cls] = declaredFields;
111
122
  }
112
123
 
113
124
  return declaredFields;
114
125
  }
115
126
 
127
+ // Constructor initializes the declaredFieldsMap dictionary
116
128
  public DataMemberFieldInfoTypeMapper()
117
129
  {
118
130
  this.declaredFieldsMap = new Dictionary<Type, GNEnhancedObjectFieldMetadata[]>();
119
131
  }
120
132
  }
121
133
 
134
+ /// <summary>
135
+ /// Class responsible for deserializing objects and arrays from GNHashtable and GNArray
136
+ /// </summary>
122
137
  internal class DeserializeConverter
123
138
  {
139
+ // Mapper to retrieve metadata for fields with DataMember attributes
124
140
  private DataMemberFieldInfoTypeMapper dataMemberFieldInfoMapper;
125
141
 
142
+ // Cached type definitions for common types
126
143
  private Type typeOfByte;
127
144
  private Type typeOfSByte;
128
145
  private Type typeOfShort;
@@ -135,112 +152,149 @@
135
152
  private Type typeOfGNArray;
136
153
  private Type typeOfGNHashtable;
137
154
 
155
+ bool TryGetNullable(FieldInfo fieldInfo, out Type tType)
156
+ {
157
+ tType = Nullable.GetUnderlyingType(fieldInfo.FieldType);
158
+ return tType != null;
159
+ }
160
+
161
+ /// <summary>
162
+ /// Deserializes a GNHashtable into an object of the specified type.
163
+ /// </summary>
164
+ /// <param name="gnHashtable">The GNHashtable to deserialize.</param>
165
+ /// <param name="cls">The type of the object to create.</param>
166
+ /// <returns>An instance of the specified type populated with data from the GNHashtable.</returns>
138
167
  public object deserializeObject(GNHashtable gnHashtable, Type cls)
139
168
  {
169
+ // Return null if the input is null
140
170
  if (gnHashtable == null) return null;
141
171
 
172
+ // Retrieve metadata for all fields in the target type
142
173
  var declaredFields = this.dataMemberFieldInfoMapper.getGNEnhancedObjectFieldMetadata(cls);
143
174
 
175
+ // Create an instance of the target class
144
176
  var answer = Activator.CreateInstance(cls);
145
177
 
178
+ // Iterate through each field and populate its value from the GNHashtable
146
179
  foreach (var declaredField in declaredFields)
147
180
  {
181
+ // Retrieve the value for the field based on its code
148
182
  var value = gnHashtable.getObject(declaredField.code);
149
183
 
184
+ // Handle field types based on GNFieldDataType
150
185
  if (declaredField.gnFieldType == GNFieldDataType.String)
151
186
  {
152
- if (value == null)
153
- {
154
- if (declaredField.defaultValue != null) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
155
- }
187
+ if (value == null) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
156
188
  else if (value is string) declaredField.fieldInfo.SetValue(answer, value);
157
189
  }
158
190
  else if (declaredField.gnFieldType == GNFieldDataType.Boolean)
159
191
  {
160
- if (value == null)
161
- {
162
- if (declaredField.defaultValue != null) declaredField.fieldInfo.SetValue(answer, CustomConvert.ChangeType(declaredField.defaultValue, declaredField.fieldInfo.FieldType));
163
- }
192
+ if (value == null) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
164
193
  else if (value is bool) declaredField.fieldInfo.SetValue(answer, value);
165
194
  }
166
195
  else if (declaredField.gnFieldType == GNFieldDataType.GNHashtable)
167
196
  {
197
+ // Handle nested objects
168
198
  if (value == null)
169
199
  {
170
200
  if (declaredField.defaultValue != null)
171
201
  {
172
- if (declaredField.fieldInfo.FieldType == typeOfGNHashtable) declaredField.fieldInfo.SetValue(answer, CustomConvert.ChangeType(declaredField.defaultValue, declaredField.fieldInfo.FieldType));
173
- else if (declaredField.fieldInfo.FieldType == typeof(System.Collections.IDictionary)) declaredField.fieldInfo.SetValue(answer, CustomConvert.ChangeType(((GNHashtable)(declaredField.defaultValue)).toData(), declaredField.fieldInfo.FieldType));
202
+ if (declaredField.fieldInfo.FieldType == this.typeOfGNHashtable) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
203
+ else if (declaredField.fieldInfo.FieldType == typeof(System.Collections.IDictionary)) declaredField.fieldInfo.SetValue(answer, ((GNHashtable)(declaredField.defaultValue)).toData());
174
204
  else declaredField.fieldInfo.SetValue(answer, this.deserializeObject((GNHashtable)declaredField.defaultValue, declaredField.cls));
175
205
  }
176
206
  }
177
207
  else
178
208
  {
179
- if (declaredField.fieldInfo.FieldType == typeOfGNHashtable) declaredField.fieldInfo.SetValue(answer, CustomConvert.ChangeType(value, declaredField.fieldInfo.FieldType));
180
- else if (declaredField.fieldInfo.FieldType == typeof(System.Collections.IDictionary)) declaredField.fieldInfo.SetValue(answer, CustomConvert.ChangeType(((IGNData)value).toData(), declaredField.fieldInfo.FieldType));
209
+ if (declaredField.fieldInfo.FieldType == this.typeOfGNHashtable) declaredField.fieldInfo.SetValue(answer, value);
210
+ else if (declaredField.fieldInfo.FieldType == typeof(System.Collections.IDictionary)) declaredField.fieldInfo.SetValue(answer, ((IGNData)value).toData());
181
211
  else declaredField.fieldInfo.SetValue(answer, this.deserializeObject((GNHashtable)value, declaredField.cls));
182
212
  }
183
213
  }
184
214
  else if (declaredField.gnFieldType == GNFieldDataType.GNArray)
185
215
  {
216
+ // Handle arrays
186
217
  if (value == null)
187
218
  {
188
219
  if (declaredField.defaultValue != null)
189
220
  {
190
- if (declaredField.fieldInfo.FieldType == typeOfGNArray) declaredField.fieldInfo.SetValue(answer, CustomConvert.ChangeType(declaredField.defaultValue, declaredField.fieldInfo.FieldType));
191
- else if (declaredField.fieldInfo.FieldType == typeof(System.Collections.IList)) declaredField.fieldInfo.SetValue(answer, CustomConvert.ChangeType(((GNArray)declaredField.defaultValue).toData(), declaredField.fieldInfo.FieldType));
221
+ if (declaredField.fieldInfo.FieldType == this.typeOfGNArray) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
222
+ else if (declaredField.fieldInfo.FieldType == typeof(System.Collections.IList)) declaredField.fieldInfo.SetValue(answer, ((GNArray)declaredField.defaultValue).toData());
192
223
  }
193
224
  }
194
225
  else
195
226
  {
196
- if (declaredField.fieldInfo.FieldType == typeOfGNArray) declaredField.fieldInfo.SetValue(answer, CustomConvert.ChangeType(value, declaredField.fieldInfo.FieldType));
197
- else if (declaredField.fieldInfo.FieldType == typeof(System.Collections.IList)) declaredField.fieldInfo.SetValue(answer, CustomConvert.ChangeType(((IGNData)value).toData(), declaredField.fieldInfo.FieldType));
227
+ if (declaredField.fieldInfo.FieldType == this.typeOfGNArray) declaredField.fieldInfo.SetValue(answer, value);
228
+ else if (declaredField.fieldInfo.FieldType == typeof(System.Collections.IList)) declaredField.fieldInfo.SetValue(answer, ((IGNData)value).toData());
198
229
  }
199
230
  }
200
231
  else if (declaredField.gnFieldType == GNFieldDataType.Number)
201
232
  {
202
- if (value == null)
233
+ object lastValue;
234
+
235
+ if (value == null) lastValue = declaredField.defaultValue;
236
+ else lastValue = value;
237
+
238
+ if (ConverterService.isNumber(lastValue))
203
239
  {
204
- if (declaredField.defaultValue != null) declaredField.fieldInfo.SetValue(answer, CustomConvert.ChangeType(declaredField.defaultValue, declaredField.fieldInfo.FieldType));
240
+ if (TryGetNullable(declaredField.fieldInfo, out var tType))
241
+ {
242
+ var typeCode = Type.GetTypeCode(tType);
243
+
244
+ if (typeCode == TypeCode.SByte) declaredField.fieldInfo.SetValue(answer, Convert.ToSByte(lastValue));
245
+ else if (typeCode == TypeCode.Byte) declaredField.fieldInfo.SetValue(answer, Convert.ToByte(lastValue));
246
+ else if (typeCode == TypeCode.Int16) declaredField.fieldInfo.SetValue(answer, Convert.ToInt16(lastValue));
247
+ else if (typeCode == TypeCode.UInt16) declaredField.fieldInfo.SetValue(answer, Convert.ToUInt16(lastValue));
248
+ else if (typeCode == TypeCode.Int32) declaredField.fieldInfo.SetValue(answer, Convert.ToInt32(lastValue));
249
+ else if (typeCode == TypeCode.UInt32) declaredField.fieldInfo.SetValue(answer, Convert.ToUInt32(lastValue));
250
+ else if (typeCode == TypeCode.Int64) declaredField.fieldInfo.SetValue(answer, Convert.ToInt64(lastValue));
251
+ else if (typeCode == TypeCode.UInt64) declaredField.fieldInfo.SetValue(answer, Convert.ToUInt64(lastValue));
252
+ else if (typeCode == TypeCode.Single) declaredField.fieldInfo.SetValue(answer, Convert.ToSingle(lastValue));
253
+ else if (typeCode == TypeCode.Double) declaredField.fieldInfo.SetValue(answer, Convert.ToDouble(lastValue));
254
+ }
255
+ else
256
+ {
257
+ declaredField.fieldInfo.SetValue(answer, lastValue);
258
+ }
205
259
  }
206
- else if (ConverterService.isNumber(value)) declaredField.fieldInfo.SetValue(answer, CustomConvert.ChangeType(value, declaredField.fieldInfo.FieldType));
207
260
  }
208
261
  else
209
262
  {
263
+ // Handle other primitive types
210
264
  if (value == null)
211
265
  {
212
266
  if (declaredField.defaultValue != null)
213
267
  {
214
- if (declaredField.fieldInfo.FieldType == typeOfByte) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
215
- else if (declaredField.fieldInfo.FieldType == typeOfSByte) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
216
- else if (declaredField.fieldInfo.FieldType == typeOfShort) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
217
- else if (declaredField.fieldInfo.FieldType == typeOfInt) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
218
- else if (declaredField.fieldInfo.FieldType == typeOfFloat) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
219
- else if (declaredField.fieldInfo.FieldType == typeOfLong) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
220
- else if (declaredField.fieldInfo.FieldType == typeOfDouble) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
221
- else if (declaredField.fieldInfo.FieldType == typeOfBool) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
222
- else if (declaredField.fieldInfo.FieldType == typeOfString) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
223
- else if (declaredField.fieldInfo.FieldType == typeOfGNArray) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
268
+ if (declaredField.fieldInfo.FieldType == this.typeOfByte) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
269
+ else if (declaredField.fieldInfo.FieldType == this.typeOfSByte) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
270
+ else if (declaredField.fieldInfo.FieldType == this.typeOfShort) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
271
+ else if (declaredField.fieldInfo.FieldType == this.typeOfInt) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
272
+ else if (declaredField.fieldInfo.FieldType == this.typeOfFloat) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
273
+ else if (declaredField.fieldInfo.FieldType == this.typeOfLong) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
274
+ else if (declaredField.fieldInfo.FieldType == this.typeOfDouble) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
275
+ else if (declaredField.fieldInfo.FieldType == this.typeOfBool) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
276
+ else if (declaredField.fieldInfo.FieldType == this.typeOfString) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
277
+ else if (declaredField.fieldInfo.FieldType == this.typeOfGNArray) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
224
278
  else if (declaredField.fieldInfo.FieldType == typeof(System.Collections.IList)) declaredField.fieldInfo.SetValue(answer, ((IGNData)declaredField.defaultValue).toData());
225
- else if (declaredField.fieldInfo.FieldType == typeOfGNHashtable) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
279
+ else if (declaredField.fieldInfo.FieldType == this.typeOfGNHashtable) declaredField.fieldInfo.SetValue(answer, declaredField.defaultValue);
226
280
  else if (declaredField.fieldInfo.FieldType == typeof(System.Collections.IDictionary)) declaredField.fieldInfo.SetValue(answer, ((IGNData)declaredField.defaultValue).toData());
227
281
  else declaredField.fieldInfo.SetValue(answer, this.deserializeObject((GNHashtable)declaredField.defaultValue, declaredField.cls));
228
282
  }
229
283
  }
230
284
  else
231
285
  {
232
- if (declaredField.fieldInfo.FieldType == typeOfByte) declaredField.fieldInfo.SetValue(answer, value);
233
- else if (declaredField.fieldInfo.FieldType == typeOfSByte) declaredField.fieldInfo.SetValue(answer, value);
234
- else if (declaredField.fieldInfo.FieldType == typeOfShort) declaredField.fieldInfo.SetValue(answer, value);
235
- else if (declaredField.fieldInfo.FieldType == typeOfInt) declaredField.fieldInfo.SetValue(answer, value);
236
- else if (declaredField.fieldInfo.FieldType == typeOfFloat) declaredField.fieldInfo.SetValue(answer, value);
237
- else if (declaredField.fieldInfo.FieldType == typeOfLong) declaredField.fieldInfo.SetValue(answer, value);
238
- else if (declaredField.fieldInfo.FieldType == typeOfDouble) declaredField.fieldInfo.SetValue(answer, value);
239
- else if (declaredField.fieldInfo.FieldType == typeOfBool) declaredField.fieldInfo.SetValue(answer, value);
240
- else if (declaredField.fieldInfo.FieldType == typeOfString) declaredField.fieldInfo.SetValue(answer, value);
241
- else if (declaredField.fieldInfo.FieldType == typeOfGNArray) declaredField.fieldInfo.SetValue(answer, value);
286
+ if (declaredField.fieldInfo.FieldType == this.typeOfByte) declaredField.fieldInfo.SetValue(answer, value);
287
+ else if (declaredField.fieldInfo.FieldType == this.typeOfSByte) declaredField.fieldInfo.SetValue(answer, value);
288
+ else if (declaredField.fieldInfo.FieldType == this.typeOfShort) declaredField.fieldInfo.SetValue(answer, value);
289
+ else if (declaredField.fieldInfo.FieldType == this.typeOfInt) declaredField.fieldInfo.SetValue(answer, value);
290
+ else if (declaredField.fieldInfo.FieldType == this.typeOfFloat) declaredField.fieldInfo.SetValue(answer, value);
291
+ else if (declaredField.fieldInfo.FieldType == this.typeOfLong) declaredField.fieldInfo.SetValue(answer, value);
292
+ else if (declaredField.fieldInfo.FieldType == this.typeOfDouble) declaredField.fieldInfo.SetValue(answer, value);
293
+ else if (declaredField.fieldInfo.FieldType == this.typeOfBool) declaredField.fieldInfo.SetValue(answer, value);
294
+ else if (declaredField.fieldInfo.FieldType == this.typeOfString) declaredField.fieldInfo.SetValue(answer, value);
295
+ else if (declaredField.fieldInfo.FieldType == this.typeOfGNArray) declaredField.fieldInfo.SetValue(answer, value);
242
296
  else if (declaredField.fieldInfo.FieldType == typeof(System.Collections.IList)) declaredField.fieldInfo.SetValue(answer, ((IGNData)value).toData());
243
- else if (declaredField.fieldInfo.FieldType == typeOfGNHashtable) declaredField.fieldInfo.SetValue(answer, value);
297
+ else if (declaredField.fieldInfo.FieldType == this.typeOfGNHashtable) declaredField.fieldInfo.SetValue(answer, value);
244
298
  else if (declaredField.fieldInfo.FieldType == typeof(System.Collections.IDictionary)) declaredField.fieldInfo.SetValue(answer, ((IGNData)value).toData());
245
299
  else declaredField.fieldInfo.SetValue(answer, this.deserializeObject((GNHashtable)value, declaredField.cls));
246
300
  }
@@ -250,12 +304,19 @@
250
304
  return answer;
251
305
  }
252
306
 
307
+ /// <summary>
308
+ /// Deserializes a GNArray into a list of objects of the specified type.
309
+ /// </summary>
310
+ /// <param name="gnArray">The GNArray to deserialize.</param>
311
+ /// <param name="cls">The type of objects in the resulting list.</param>
312
+ /// <returns>A list of objects of the specified type.</returns>
253
313
  public System.Collections.IList deserializeArray(GNArray gnArray, Type cls)
254
314
  {
255
315
  if (gnArray == null) return null;
256
316
 
257
317
  var answer = new System.Collections.Generic.List<object>();
258
318
 
319
+ // Deserialize each element in the array
259
320
  for (var i = 0; i < gnArray.count(); i++)
260
321
  {
261
322
  var value = gnArray.getObject(i);
@@ -264,17 +325,17 @@
264
325
  {
265
326
  var typeOfValue = value.GetType();
266
327
 
267
- if (cls == typeOfByte) answer.Add(value);
268
- else if (cls == typeOfSByte) answer.Add(value);
269
- else if (cls == typeOfShort) answer.Add(value);
270
- else if (cls == typeOfInt) answer.Add(value);
271
- else if (cls == typeOfFloat) answer.Add(value);
272
- else if (cls == typeOfLong) answer.Add(value);
273
- else if (cls == typeOfDouble) answer.Add(value);
274
- else if (cls == typeOfBool) answer.Add(value);
275
- else if (cls == typeOfString) answer.Add(value);
276
- else if (cls == typeOfGNArray) answer.Add(value);
277
- else if (cls == typeOfGNHashtable) answer.Add(value);
328
+ if (cls == this.typeOfByte) answer.Add(value);
329
+ else if (cls == this.typeOfSByte) answer.Add(value);
330
+ else if (cls == this.typeOfShort) answer.Add(value);
331
+ else if (cls == this.typeOfInt) answer.Add(value);
332
+ else if (cls == this.typeOfFloat) answer.Add(value);
333
+ else if (cls == this.typeOfLong) answer.Add(value);
334
+ else if (cls == this.typeOfDouble) answer.Add(value);
335
+ else if (cls == this.typeOfBool) answer.Add(value);
336
+ else if (cls == this.typeOfString) answer.Add(value);
337
+ else if (cls == this.typeOfGNArray) answer.Add(value);
338
+ else if (cls == this.typeOfGNHashtable) answer.Add(value);
278
339
  else if (typeOfValue == typeof(System.Collections.IList))
279
340
  answer.Add(this.deserializeArray(gnArray.getGNArray(i), cls));
280
341
  else
@@ -285,6 +346,11 @@
285
346
  return answer;
286
347
  }
287
348
 
349
+ /// <summary>
350
+ /// Constructor for DeserializeConverter.
351
+ /// Initializes type mappings and field info mapper.
352
+ /// </summary>
353
+ /// <param name="dataMemberFieldInfoMapper">The mapper for field metadata.</param>
288
354
  public DeserializeConverter(DataMemberFieldInfoTypeMapper dataMemberFieldInfoMapper)
289
355
  {
290
356
  this.typeOfByte = typeof(byte);
@@ -303,30 +369,47 @@
303
369
  }
304
370
  }
305
371
 
372
+ /// <summary>
373
+ /// Class responsible for serializing objects and arrays into GNHashtable and GNArray.
374
+ /// </summary>
306
375
  internal class SerializeConverter
307
376
  {
377
+ // Mapper to retrieve metadata for fields with DataMember attributes.
308
378
  private DataMemberFieldInfoTypeMapper dataMemberFieldInfoMapper;
309
379
 
380
+ /// <summary>
381
+ /// Serializes an object into a GNHashtable.
382
+ /// </summary>
383
+ /// <param name="obj">The object to serialize.</param>
384
+ /// <returns>A GNHashtable representing the serialized object.</returns>
310
385
  public GNHashtable serializeObject(object obj)
311
386
  {
387
+ // Return null if the input object is null.
312
388
  if (obj == null) return null;
313
389
 
390
+ // Get the type of the input object.
314
391
  var type = obj.GetType();
315
392
 
393
+ // Retrieve metadata for all fields in the object's type.
316
394
  var declaredFields = this.dataMemberFieldInfoMapper.getGNEnhancedObjectFieldMetadata(type);
317
395
 
396
+ // Initialize the result GNHashtable.
318
397
  var answer = new GNHashtable();
319
398
 
399
+ // Iterate through each field and populate the GNHashtable.
320
400
  foreach (var declaredField in declaredFields)
321
401
  {
402
+ // Get the value of the field from the object.
322
403
  var value = declaredField.fieldInfo.GetValue(obj);
323
404
 
324
405
  if (value == null)
325
406
  {
407
+ // Add null value if the field is not optional.
326
408
  if (!declaredField.isOptional) answer.add(declaredField.code, null);
327
409
  }
328
410
  else
329
411
  {
412
+ // Handle serialization based on the GNFieldDataType.
330
413
  if (declaredField.gnFieldType == GNFieldDataType.String)
331
414
  {
332
415
  if (value is string) answer.add(declaredField.code, value);
@@ -337,21 +420,25 @@
337
420
  }
338
421
  else if (declaredField.gnFieldType == GNFieldDataType.GNHashtable)
339
422
  {
423
+ // Handle GNHashtable fields or nested objects.
340
424
  if (value is GNHashtable) answer.add(declaredField.code, value);
341
425
  else if (value is System.Collections.IDictionary valueDict) answer.add(declaredField.code, new GNHashtable.Builder().addAll(valueDict).build());
342
426
  else answer.add(declaredField.code, this.serializeObject(value));
343
427
  }
344
428
  else if (declaredField.gnFieldType == GNFieldDataType.GNArray)
345
429
  {
430
+ // Handle GNArray fields or lists.
346
431
  if (value is GNArray) answer.add(declaredField.code, value);
347
432
  else if (value is System.Collections.IList valueLst) answer.add(declaredField.code, this.serializeArray(valueLst));
348
433
  }
349
434
  else if (declaredField.gnFieldType == GNFieldDataType.Number)
350
435
  {
436
+ // Handle numeric fields.
351
437
  if (ConverterService.isNumber(value)) answer.add(declaredField.code, value);
352
438
  }
353
439
  else
354
440
  {
441
+ // Handle other types.
355
442
  if (value is string) answer.add(declaredField.code, value);
356
443
  else if (value is bool) answer.add(declaredField.code, value);
357
444
  else if (ConverterService.isNumber(value)) answer.add(declaredField.code, value);
@@ -366,12 +453,20 @@
366
453
  return answer;
367
454
  }
368
455
 
456
+ /// <summary>
457
+ /// Serializes a list into a GNArray.
458
+ /// </summary>
459
+ /// <param name="objLst">The list to serialize.</param>
460
+ /// <returns>A GNArray representing the serialized list.</returns>
369
461
  public GNArray serializeArray(System.Collections.IList objLst)
370
462
  {
463
+ // Return null if the input list is null.
371
464
  if (objLst == null) return null;
372
465
 
466
+ // Initialize the result GNArray.
373
467
  var answer = new GNArray();
374
468
 
469
+ // Iterate through each element in the list.
375
470
  for (var i = 0; i < objLst.Count; i++)
376
471
  {
377
472
  var obj = objLst[i];
@@ -388,75 +483,107 @@
388
483
  return answer;
389
484
  }
390
485
 
486
+ /// <summary>
487
+ /// Constructor for SerializeConverter.
488
+ /// </summary>
489
+ /// <param name="dataMemberFieldInfoMapper">The mapper for field metadata.</param>
391
490
  public SerializeConverter(DataMemberFieldInfoTypeMapper dataMemberFieldInfoMapper)
392
491
  {
393
492
  this.dataMemberFieldInfoMapper = dataMemberFieldInfoMapper;
394
493
  }
395
494
  }
396
495
 
397
- internal class CustomConvert
398
- {
399
- public static object ChangeType(object value, Type conversion)
400
- {
401
- var t = conversion;
402
-
403
- if (t.IsGenericType && t.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
404
- {
405
- if (value == null)
406
- {
407
- return null;
408
- }
409
-
410
- t = Nullable.GetUnderlyingType(t);
411
- }
412
-
413
- return Convert.ChangeType(value, t);
414
- }
415
- }
416
-
496
+ /// <summary>
497
+ /// Service class providing serialization and deserialization functionality.
498
+ /// Handles conversion of objects to GNHashtable/GNArray and vice versa.
499
+ /// </summary>
417
500
  public class ConverterService
418
501
  {
502
+ // Private static instances for serialization and deserialization operations.
419
503
  private static SerializeConverter serializeConverter;
420
504
  private static DeserializeConverter deserializeConverter;
421
505
 
506
+ /// <summary>
507
+ /// Deserializes a GNHashtable into a strongly-typed object.
508
+ /// </summary>
509
+ /// <typeparam name="T">The target object type.</typeparam>
510
+ /// <param name="gnHashtable">The GNHashtable to deserialize.</param>
511
+ /// <returns>The deserialized object of type T.</returns>
422
512
  public static T deserializeObject<T>(GNHashtable gnHashtable)
423
513
  {
424
514
  return (T)ConverterService.deserializeObject(gnHashtable, typeof(T));
425
515
  }
426
516
 
517
+ /// <summary>
518
+ /// Deserializes a GNHashtable into an object of the specified type.
519
+ /// </summary>
520
+ /// <param name="gnHashtable">The GNHashtable to deserialize.</param>
521
+ /// <param name="cls">The type to deserialize into.</param>
522
+ /// <returns>The deserialized object.</returns>
427
523
  public static object deserializeObject(GNHashtable gnHashtable, Type cls)
428
524
  {
429
525
  return ConverterService.deserializeConverter.deserializeObject(gnHashtable, cls);
430
526
  }
431
527
 
528
+ /// <summary>
529
+ /// Deserializes a GNArray into a strongly-typed list.
530
+ /// </summary>
531
+ /// <typeparam name="T">The element type of the resulting list.</typeparam>
532
+ /// <param name="gnArray">The GNArray to deserialize.</param>
533
+ /// <returns>A list of deserialized elements.</returns>
432
534
  public static System.Collections.IList deserializeArray<T>(GNArray gnArray)
433
535
  {
434
536
  return ConverterService.deserializeArray<T>(gnArray);
435
537
  }
436
538
 
539
+ /// <summary>
540
+ /// Deserializes a GNArray into a list of a specified type.
541
+ /// </summary>
542
+ /// <param name="gnArray">The GNArray to deserialize.</param>
543
+ /// <param name="cls">The target element type.</param>
544
+ /// <returns>A list of deserialized elements.</returns>
437
545
  public static System.Collections.IList deserializeArray(GNArray gnArray, Type cls)
438
546
  {
439
547
  return ConverterService.deserializeConverter.deserializeArray(gnArray, cls);
440
548
  }
441
549
 
550
+ /// <summary>
551
+ /// Serializes an object into a GNHashtable.
552
+ /// </summary>
553
+ /// <param name="obj">The object to serialize.</param>
554
+ /// <returns>A GNHashtable representing the serialized object.</returns>
442
555
  public static GNHashtable serializeObject(object obj)
443
556
  {
444
557
  return ConverterService.serializeConverter.serializeObject(obj);
445
558
  }
446
559
 
560
+ /// <summary>
561
+ /// Serializes a list into a GNArray.
562
+ /// </summary>
563
+ /// <param name="objLst">The list to serialize.</param>
564
+ /// <returns>A GNArray representing the serialized list.</returns>
447
565
  public static GNArray serializeArray(System.Collections.IList objLst)
448
566
  {
449
567
  return ConverterService.serializeConverter.serializeArray(objLst);
450
568
  }
451
569
 
570
+ /// <summary>
571
+ /// Static constructor to initialize the SerializeConverter and DeserializeConverter instances.
572
+ /// </summary>
452
573
  static ConverterService()
453
574
  {
575
+ // Create a shared DataMemberFieldInfoTypeMapper for both converters.
454
576
  var dataMemberFieldInfoMapper = new DataMemberFieldInfoTypeMapper();
455
577
 
456
578
  ConverterService.serializeConverter = new SerializeConverter(dataMemberFieldInfoMapper);
457
579
  ConverterService.deserializeConverter = new DeserializeConverter(dataMemberFieldInfoMapper);
458
580
  }
459
581
 
582
+ /// <summary>
583
+ /// Checks if a value is a numeric type.
584
+ /// </summary>
585
+ /// <param name="value">The value to check.</param>
586
+ /// <returns>True if the value is a numeric type; otherwise, false.</returns>
460
587
  public static bool isNumber(object value)
461
588
  {
462
589
  return (value is byte
@@ -468,6 +595,11 @@
468
595
  || value is double);
469
596
  }
470
597
 
598
+ /// <summary>
599
+ /// Checks if a value is an integer type.
600
+ /// </summary>
601
+ /// <param name="value">The value to check.</param>
602
+ /// <returns>True if the value is an integer type; otherwise, false.</returns>
471
603
  public static bool isInteger(object value)
472
604
  {
473
605
  return (value is byte
@@ -478,4 +610,27 @@
478
610
  }
479
611
  }
480
612
 
613
+ public class ConverterServiceV2
614
+ {
615
+ class DetectSupport
616
+ {
617
+ public static bool isNumber(object value)
618
+ {
619
+ return value is byte
620
+ || value is sbyte
621
+ || value is short
622
+ || value is ushort
623
+ || value is int
624
+ || value is uint
625
+ || value is float
626
+ || value is long
627
+ || value is ulong
628
+ || value is double;
629
+ }
630
+
631
+ }
632
+
633
+
634
+ }
635
+
481
636
  }