├── .gitignore ├── Demo.meta ├── Demo ├── LocalDataModuleTest.unity ├── LocalDataModuleTest.unity.meta ├── LocalDataTest.cs ├── LocalDataTest.cs.meta ├── TestData.cs └── TestData.cs.meta ├── LICENSE.md ├── LICENSE.md.meta ├── README.md ├── README.md.meta ├── Runtime.meta ├── Runtime ├── Compressor.meta ├── Compressor │ ├── BrotliCompressor.cs │ ├── BrotliCompressor.cs.meta │ ├── CompressorBase.cs │ ├── CompressorBase.cs.meta │ ├── FileCompression.cs │ ├── FileCompression.cs.meta │ ├── GZipCompressor.cs │ ├── GZipCompressor.cs.meta │ ├── ICompressor.cs │ ├── ICompressor.cs.meta │ ├── NullCompressor.cs │ ├── NullCompressor.cs.meta │ ├── ZipCompressor.cs │ └── ZipCompressor.cs.meta ├── Encryptor.meta ├── Encryptor │ ├── AESEncryptor.cs │ ├── AESEncryptor.cs.meta │ ├── DESEncryptor.cs │ ├── DESEncryptor.cs.meta │ ├── EncryptorBase.cs │ ├── EncryptorBase.cs.meta │ ├── FileEncryption.cs │ ├── FileEncryption.cs.meta │ ├── IEncryptor.cs │ ├── IEncryptor.cs.meta │ ├── NullEncryptor.cs │ ├── NullEncryptor.cs.meta │ ├── RC2Encryptor.cs │ ├── RC2Encryptor.cs.meta │ ├── TripleDESEncryptor.cs │ └── TripleDESEncryptor.cs.meta ├── FileResult.cs ├── FileResult.cs.meta ├── FronkonGames.GameWork.Modules.LocalData.asmdef ├── FronkonGames.GameWork.Modules.LocalData.asmdef.meta ├── ILocalData.cs ├── ILocalData.cs.meta ├── Integrity.meta ├── Integrity │ ├── FileIntegrity.cs │ ├── FileIntegrity.cs.meta │ ├── IIntegrity.cs │ ├── IIntegrity.cs.meta │ ├── IntegrityBase.cs │ ├── IntegrityBase.cs.meta │ ├── MD5Integrity.cs │ ├── MD5Integrity.cs.meta │ ├── NullIntegrity.cs │ ├── NullIntegrity.cs.meta │ ├── SHA1Integrity.cs │ ├── SHA1Integrity.cs.meta │ ├── SHA256Integrity.cs │ ├── SHA256Integrity.cs.meta │ ├── SHA512Integrity.cs │ └── SHA512Integrity.cs.meta ├── LocalData.cs ├── LocalData.cs.meta ├── LocalDataModule.Read.cs ├── LocalDataModule.Read.cs.meta ├── LocalDataModule.Write.cs ├── LocalDataModule.Write.cs.meta ├── LocalDataModule.cs ├── LocalDataModule.cs.meta ├── SerializationSurrogates.meta └── SerializationSurrogates │ ├── BoundsSerializationSurrogate.cs │ ├── BoundsSerializationSurrogate.cs.meta │ ├── ColorSerializationSurrogate.cs │ ├── ColorSerializationSurrogate.cs.meta │ ├── LayerMaskSerializationSurrogate.cs │ ├── LayerMaskSerializationSurrogate.cs.meta │ ├── Matrix4x4SerializationSurrogate.cs │ ├── Matrix4x4SerializationSurrogate.cs.meta │ ├── QuaternionSerializationSurrogate.cs │ ├── QuaternionSerializationSurrogate.cs.meta │ ├── RectSerializationSurrogate.cs │ ├── RectSerializationSurrogate.cs.meta │ ├── Vector2IntSerializationSurrogate.cs │ ├── Vector2IntSerializationSurrogate.cs.meta │ ├── Vector2SerializationSurrogate.cs │ ├── Vector2SerializationSurrogate.cs.meta │ ├── Vector3IntSerializationSurrogate.cs │ ├── Vector3IntSerializationSurrogate.cs.meta │ ├── Vector3SerializationSurrogate.cs │ ├── Vector3SerializationSurrogate.cs.meta │ ├── Vector4SerializationSurrogate.cs │ └── Vector4SerializationSurrogate.cs.meta ├── Test.meta ├── Test ├── FronkonGames.GameWork.Modules.LocalData.test.asmdef ├── FronkonGames.GameWork.Modules.LocalData.test.asmdef.meta ├── LocalData.Compression.Test.cs ├── LocalData.Compression.Test.cs.meta ├── LocalData.Encryption.Test.cs ├── LocalData.Encryption.Test.cs.meta ├── LocalData.Integrity.Test.cs ├── LocalData.Integrity.Test.cs.meta ├── LocalData.WriteRead.Test.cs └── LocalData.WriteRead.Test.cs.meta ├── docs.meta ├── docs ├── Animation.gif ├── Animation.gif.meta ├── index.rst └── index.rst.meta ├── package.json └── package.json.meta /.gitignore: -------------------------------------------------------------------------------- 1 | ############################### 2 | # Unity. 3 | ############################### 4 | [Ll]ibrary/ 5 | [Tt]emp/ 6 | [Oo]bj/ 7 | [Ll]ogs/ 8 | [Ll]ibrary/ 9 | [Bb]uilds/ 10 | UnityGenerated/ 11 | UnityPackageManager/ 12 | ProBuilderPreferences.* 13 | [Rr]ecordings/ 14 | sysinfo.txt 15 | Assets/AssetStoreTools* 16 | *.pidb.meta 17 | *.pdb.meta 18 | *.stackdump 19 | project.json 20 | project.lock.json 21 | package-lock.json 22 | 23 | ############################### 24 | # Visual Studio. 25 | ############################### 26 | [Ee]xported[Oo]bj/ 27 | .vs/ 28 | *.userprefs 29 | *.csproj 30 | *.pidb 31 | *.suo 32 | *.sln* 33 | *.user 34 | *.unityproj 35 | *.booproj 36 | 37 | ############################### 38 | # Visual Studio Code. 39 | ############################### 40 | .vscode 41 | 42 | ############################### 43 | # JetBrains Rider. 44 | ############################### 45 | .idea/ 46 | /.idea 47 | JetBrains/ 48 | Unity/.idea/ 49 | JetBrains.* 50 | 51 | ############################### 52 | # DocFX. 53 | ############################### 54 | .cache 55 | /**/_site/ 56 | Documentation/api/ 57 | Documentation/index.* 58 | 59 | ############################### 60 | # OS. 61 | ############################### 62 | .DS_Store* 63 | ._* 64 | .Spotlight-V100 65 | .Trashes 66 | Icon? 67 | ehthumbs.db 68 | [Tt]humbs.db 69 | [Dd]esktop.ini 70 | -------------------------------------------------------------------------------- /Demo.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a5b4bdf58937393409904033d823feb1 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Demo/LocalDataModuleTest.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0.17452987, g: 0.21829115, b: 0.3005383, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 12 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 512 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 256 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 1 83 | m_PVRDenoiserTypeDirect: 1 84 | m_PVRDenoiserTypeIndirect: 1 85 | m_PVRDenoiserTypeAO: 1 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 1 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_LightingSettings: {fileID: 0} 102 | --- !u!196 &4 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 2 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666667 118 | manualTileSize: 0 119 | tileSize: 256 120 | accuratePlacement: 0 121 | maxJobWorkers: 0 122 | preserveTilesOutsideBounds: 0 123 | debug: 124 | m_Flags: 0 125 | m_NavMeshData: {fileID: 0} 126 | --- !u!1 &283009871 127 | GameObject: 128 | m_ObjectHideFlags: 0 129 | m_CorrespondingSourceObject: {fileID: 0} 130 | m_PrefabInstance: {fileID: 0} 131 | m_PrefabAsset: {fileID: 0} 132 | serializedVersion: 6 133 | m_Component: 134 | - component: {fileID: 283009873} 135 | - component: {fileID: 283009872} 136 | m_Layer: 0 137 | m_Name: Directional Light 138 | m_TagString: Untagged 139 | m_Icon: {fileID: 0} 140 | m_NavMeshLayer: 0 141 | m_StaticEditorFlags: 0 142 | m_IsActive: 1 143 | --- !u!108 &283009872 144 | Light: 145 | m_ObjectHideFlags: 0 146 | m_CorrespondingSourceObject: {fileID: 0} 147 | m_PrefabInstance: {fileID: 0} 148 | m_PrefabAsset: {fileID: 0} 149 | m_GameObject: {fileID: 283009871} 150 | m_Enabled: 1 151 | serializedVersion: 10 152 | m_Type: 1 153 | m_Shape: 0 154 | m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} 155 | m_Intensity: 1 156 | m_Range: 10 157 | m_SpotAngle: 30 158 | m_InnerSpotAngle: 21.80208 159 | m_CookieSize: 10 160 | m_Shadows: 161 | m_Type: 2 162 | m_Resolution: -1 163 | m_CustomResolution: -1 164 | m_Strength: 1 165 | m_Bias: 0.05 166 | m_NormalBias: 0.4 167 | m_NearPlane: 0.2 168 | m_CullingMatrixOverride: 169 | e00: 1 170 | e01: 0 171 | e02: 0 172 | e03: 0 173 | e10: 0 174 | e11: 1 175 | e12: 0 176 | e13: 0 177 | e20: 0 178 | e21: 0 179 | e22: 1 180 | e23: 0 181 | e30: 0 182 | e31: 0 183 | e32: 0 184 | e33: 1 185 | m_UseCullingMatrixOverride: 0 186 | m_Cookie: {fileID: 0} 187 | m_DrawHalo: 0 188 | m_Flare: {fileID: 0} 189 | m_RenderMode: 0 190 | m_CullingMask: 191 | serializedVersion: 2 192 | m_Bits: 4294967295 193 | m_RenderingLayerMask: 1 194 | m_Lightmapping: 4 195 | m_LightShadowCasterMode: 0 196 | m_AreaSize: {x: 1, y: 1} 197 | m_BounceIntensity: 1 198 | m_ColorTemperature: 6570 199 | m_UseColorTemperature: 0 200 | m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} 201 | m_UseBoundingSphereOverride: 0 202 | m_UseViewFrustumForShadowCasterCull: 1 203 | m_ShadowRadius: 0 204 | m_ShadowAngle: 0 205 | --- !u!4 &283009873 206 | Transform: 207 | m_ObjectHideFlags: 0 208 | m_CorrespondingSourceObject: {fileID: 0} 209 | m_PrefabInstance: {fileID: 0} 210 | m_PrefabAsset: {fileID: 0} 211 | m_GameObject: {fileID: 283009871} 212 | m_LocalRotation: {x: 0.7773719, y: -0.15362293, z: 0.20829615, w: 0.5733287} 213 | m_LocalPosition: {x: 0, y: 3, z: 0} 214 | m_LocalScale: {x: 1, y: 1, z: 1} 215 | m_ConstrainProportionsScale: 0 216 | m_Children: [] 217 | m_Father: {fileID: 0} 218 | m_RootOrder: 1 219 | m_LocalEulerAnglesHint: {x: 107.181, y: -30, z: 0} 220 | --- !u!1 &798115380 221 | GameObject: 222 | m_ObjectHideFlags: 0 223 | m_CorrespondingSourceObject: {fileID: 0} 224 | m_PrefabInstance: {fileID: 0} 225 | m_PrefabAsset: {fileID: 0} 226 | serializedVersion: 6 227 | m_Component: 228 | - component: {fileID: 798115381} 229 | - component: {fileID: 798115382} 230 | m_Layer: 0 231 | m_Name: LocalData 232 | m_TagString: Untagged 233 | m_Icon: {fileID: 0} 234 | m_NavMeshLayer: 0 235 | m_StaticEditorFlags: 0 236 | m_IsActive: 1 237 | --- !u!4 &798115381 238 | Transform: 239 | m_ObjectHideFlags: 0 240 | m_CorrespondingSourceObject: {fileID: 0} 241 | m_PrefabInstance: {fileID: 0} 242 | m_PrefabAsset: {fileID: 0} 243 | m_GameObject: {fileID: 798115380} 244 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 245 | m_LocalPosition: {x: 0, y: 0, z: 0} 246 | m_LocalScale: {x: 1, y: 1, z: 1} 247 | m_ConstrainProportionsScale: 0 248 | m_Children: [] 249 | m_Father: {fileID: 1440672287} 250 | m_RootOrder: 0 251 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 252 | --- !u!114 &798115382 253 | MonoBehaviour: 254 | m_ObjectHideFlags: 0 255 | m_CorrespondingSourceObject: {fileID: 0} 256 | m_PrefabInstance: {fileID: 0} 257 | m_PrefabAsset: {fileID: 0} 258 | m_GameObject: {fileID: 798115380} 259 | m_Enabled: 1 260 | m_EditorHideFlags: 0 261 | m_Script: {fileID: 11500000, guid: 70fac41f51b844543be1dc3745ced385, type: 3} 262 | m_Name: 263 | m_EditorClassIdentifier: 264 | bufferSize: 32 265 | fileIntegrity: 1 266 | fileCompression: 3 267 | compressionLevel: 0 268 | fileEncryption: 0 269 | password: Password 270 | seed: 1bb6bd0e-37ae-4701-b8aa-f5bf2415 271 | --- !u!1 &1440672285 272 | GameObject: 273 | m_ObjectHideFlags: 0 274 | m_CorrespondingSourceObject: {fileID: 0} 275 | m_PrefabInstance: {fileID: 0} 276 | m_PrefabAsset: {fileID: 0} 277 | serializedVersion: 6 278 | m_Component: 279 | - component: {fileID: 1440672287} 280 | - component: {fileID: 1440672288} 281 | m_Layer: 0 282 | m_Name: GameTest 283 | m_TagString: Untagged 284 | m_Icon: {fileID: 0} 285 | m_NavMeshLayer: 0 286 | m_StaticEditorFlags: 0 287 | m_IsActive: 1 288 | --- !u!4 &1440672287 289 | Transform: 290 | m_ObjectHideFlags: 0 291 | m_CorrespondingSourceObject: {fileID: 0} 292 | m_PrefabInstance: {fileID: 0} 293 | m_PrefabAsset: {fileID: 0} 294 | m_GameObject: {fileID: 1440672285} 295 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 296 | m_LocalPosition: {x: 0, y: 0, z: 0} 297 | m_LocalScale: {x: 1, y: 1, z: 1} 298 | m_ConstrainProportionsScale: 0 299 | m_Children: 300 | - {fileID: 798115381} 301 | m_Father: {fileID: 0} 302 | m_RootOrder: 2 303 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 304 | --- !u!114 &1440672288 305 | MonoBehaviour: 306 | m_ObjectHideFlags: 0 307 | m_CorrespondingSourceObject: {fileID: 0} 308 | m_PrefabInstance: {fileID: 0} 309 | m_PrefabAsset: {fileID: 0} 310 | m_GameObject: {fileID: 1440672285} 311 | m_Enabled: 1 312 | m_EditorHideFlags: 0 313 | m_Script: {fileID: 11500000, guid: 2917d0450d4c16447a452dce15c9804f, type: 3} 314 | m_Name: 315 | m_EditorClassIdentifier: 316 | --- !u!1 &1688904117 317 | GameObject: 318 | m_ObjectHideFlags: 0 319 | m_CorrespondingSourceObject: {fileID: 0} 320 | m_PrefabInstance: {fileID: 0} 321 | m_PrefabAsset: {fileID: 0} 322 | serializedVersion: 6 323 | m_Component: 324 | - component: {fileID: 1688904120} 325 | - component: {fileID: 1688904119} 326 | - component: {fileID: 1688904118} 327 | m_Layer: 0 328 | m_Name: Main Camera 329 | m_TagString: MainCamera 330 | m_Icon: {fileID: 0} 331 | m_NavMeshLayer: 0 332 | m_StaticEditorFlags: 0 333 | m_IsActive: 1 334 | --- !u!81 &1688904118 335 | AudioListener: 336 | m_ObjectHideFlags: 0 337 | m_CorrespondingSourceObject: {fileID: 0} 338 | m_PrefabInstance: {fileID: 0} 339 | m_PrefabAsset: {fileID: 0} 340 | m_GameObject: {fileID: 1688904117} 341 | m_Enabled: 1 342 | --- !u!20 &1688904119 343 | Camera: 344 | m_ObjectHideFlags: 0 345 | m_CorrespondingSourceObject: {fileID: 0} 346 | m_PrefabInstance: {fileID: 0} 347 | m_PrefabAsset: {fileID: 0} 348 | m_GameObject: {fileID: 1688904117} 349 | m_Enabled: 1 350 | serializedVersion: 2 351 | m_ClearFlags: 2 352 | m_BackGroundColor: {r: 0.5019608, g: 0.5019608, b: 0.5019608, a: 0} 353 | m_projectionMatrixMode: 1 354 | m_GateFitMode: 2 355 | m_FOVAxisMode: 0 356 | m_SensorSize: {x: 36, y: 24} 357 | m_LensShift: {x: 0, y: 0} 358 | m_FocalLength: 50 359 | m_NormalizedViewPortRect: 360 | serializedVersion: 2 361 | x: 0 362 | y: 0 363 | width: 1 364 | height: 1 365 | near clip plane: 0.3 366 | far clip plane: 1000 367 | field of view: 60 368 | orthographic: 0 369 | orthographic size: 5 370 | m_Depth: -1 371 | m_CullingMask: 372 | serializedVersion: 2 373 | m_Bits: 4294967295 374 | m_RenderingPath: -1 375 | m_TargetTexture: {fileID: 0} 376 | m_TargetDisplay: 0 377 | m_TargetEye: 3 378 | m_HDR: 1 379 | m_AllowMSAA: 1 380 | m_AllowDynamicResolution: 0 381 | m_ForceIntoRT: 0 382 | m_OcclusionCulling: 1 383 | m_StereoConvergence: 10 384 | m_StereoSeparation: 0.022 385 | --- !u!4 &1688904120 386 | Transform: 387 | m_ObjectHideFlags: 0 388 | m_CorrespondingSourceObject: {fileID: 0} 389 | m_PrefabInstance: {fileID: 0} 390 | m_PrefabAsset: {fileID: 0} 391 | m_GameObject: {fileID: 1688904117} 392 | m_LocalRotation: {x: 0, y: 1, z: 0, w: 0} 393 | m_LocalPosition: {x: 0, y: -5.7, z: 13.6} 394 | m_LocalScale: {x: 1, y: 1, z: 1} 395 | m_ConstrainProportionsScale: 0 396 | m_Children: [] 397 | m_Father: {fileID: 0} 398 | m_RootOrder: 0 399 | m_LocalEulerAnglesHint: {x: 0, y: 180, z: 0} 400 | -------------------------------------------------------------------------------- /Demo/LocalDataModuleTest.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b3fb64062d5305f45816cdea670911de 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Demo/LocalDataTest.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System; 18 | using System.Collections.Generic; 19 | using System.IO; 20 | using UnityEngine; 21 | using FronkonGames.GameWork.Foundation; 22 | using FronkonGames.GameWork.Core; 23 | using FronkonGames.GameWork.Modules.LocalData; 24 | 25 | /// 26 | /// Local Data test. 27 | /// 28 | public sealed class LocalDataTest : Game, IGUI 29 | { 30 | [Inject] 31 | private LocalDataModule localData; 32 | 33 | private GUIStyle BoxStyle => boxStyle ??= new GUIStyle(GUI.skin.box) { normal = { background = MakeTex(2, 2, new Color(0.15f, 0.15f, 0.15f, 0.75f)) } }; 34 | 35 | private GUIStyle FontStyle => fontStyle ??= new GUIStyle(GUI.skin.label) { fontSize = 18, richText = true }; 36 | 37 | private GUIStyle ButtonStyle => buttonStyle ??= new GUIStyle(GUI.skin.button) 38 | { 39 | fontSize = 18, 40 | richText = true, 41 | normal = { background = MakeTex(2, 2, new Color(0.1f, 0.1f, 0.1f, 0.75f)) }, 42 | hover = { background = MakeTex(2, 2, new Color(0.3f, 0.3f, 0.3f, 0.75f)) } 43 | }; 44 | 45 | private FileIntegrity Integrity 46 | { 47 | get => (FileIntegrity)PlayerPrefs.GetInt("GameWork.LocalData.Test.Integrity", (int)FileIntegrity.None); 48 | set 49 | { 50 | PlayerPrefs.SetInt("GameWork.LocalData.Test.Integrity", (int)value); 51 | localData.Integrity = value; 52 | } 53 | } 54 | 55 | private FileCompression Compression 56 | { 57 | get => (FileCompression)PlayerPrefs.GetInt("GameWork.LocalData.Test.Compression", (int)FileCompression.None); 58 | set 59 | { 60 | PlayerPrefs.SetInt("GameWork.LocalData.Test.Compression", (int) value); 61 | localData.Compression = value; 62 | } 63 | } 64 | 65 | private FileEncryption Encryption 66 | { 67 | get => (FileEncryption)PlayerPrefs.GetInt("GameWork.LocalData.Test.Encryption", (int)FileEncryption.None); 68 | set 69 | { 70 | PlayerPrefs.SetInt("GameWork.LocalData.Test.Encryption", (int) value); 71 | localData.Encryption = value; 72 | } 73 | } 74 | 75 | private GUIStyle boxStyle; 76 | private GUIStyle fontStyle; 77 | private GUIStyle buttonStyle; 78 | 79 | private Vector2 scrollView; 80 | private string statusLabel = "NO ACTIVE FILE OPERATIONS"; 81 | 82 | private int kilobytes = 10; 83 | private int megabytes; 84 | private float randomness = 0.5f; 85 | 86 | private List files = new(); 87 | private int fileSelected = -1; 88 | private TestData test; 89 | 90 | private FileResult lastFileResult = FileResult.Ok; 91 | 92 | /// 93 | /// On initialize. 94 | /// 95 | public override void OnInitialize() 96 | { 97 | } 98 | 99 | /// 100 | /// At the end of initialization. 101 | /// Called in the first Update frame. 102 | /// 103 | public override void OnInitialized() 104 | { 105 | files = localData.GetFilesInfo(); 106 | } 107 | 108 | /// 109 | /// OnDrawGizmos event. 110 | /// 111 | public void OnGizmos() 112 | { 113 | } 114 | 115 | public void OnGUI() 116 | { 117 | const float margin = 10.0f; 118 | 119 | GUILayout.BeginHorizontal(GUILayout.Width(Screen.width - margin * 2)); 120 | { 121 | GUILayout.Space(margin); 122 | 123 | GUILayout.BeginVertical(BoxStyle, GUILayout.Width(Screen.width - margin * 2), GUILayout.Height(Screen.height - margin * 2)); 124 | { 125 | GUILayout.Space(margin); 126 | 127 | GUILayout.BeginHorizontal(GUILayout.Height(Screen.height * 0.4f)); 128 | { 129 | GUILayout.Space(margin); 130 | 131 | GUILayout.BeginVertical(BoxStyle, GUILayout.ExpandWidth(true)); 132 | { 133 | scrollView = GUILayout.BeginScrollView(scrollView); 134 | { 135 | for (int i = 0; i < files.Count; ++i) 136 | { 137 | GUI.color = i == fileSelected ? Color.cyan : Color.white; 138 | 139 | GUILayout.BeginHorizontal(); 140 | { 141 | if (GUILayout.Button(files[i].Name, FontStyle) == true) 142 | { 143 | fileSelected = i; 144 | test = null; 145 | 146 | localData.Read(files[i].Name, 147 | progress => statusLabel = $"READING {(progress * 100.0f):00}%", 148 | (result, file) => 149 | { 150 | lastFileResult = result; 151 | statusLabel = "NO ACTIVE FILE OPERATIONS"; 152 | test = file; 153 | }); 154 | } 155 | 156 | GUILayout.FlexibleSpace(); 157 | 158 | GUILayout.Label($"{((int)files[i].Length).BytesToHumanReadable()}"); 159 | } 160 | GUILayout.EndHorizontal(); 161 | } 162 | 163 | GUI.color = Color.white; 164 | } 165 | GUILayout.EndScrollView(); 166 | } 167 | GUILayout.EndVertical(); 168 | 169 | GUILayout.Space(margin); 170 | 171 | GUILayout.BeginVertical(BoxStyle, GUILayout.Width(Screen.width * 0.5f)); 172 | { 173 | GUILayout.BeginHorizontal(); 174 | { 175 | GUILayout.FlexibleSpace(); 176 | GUILayout.Label(statusLabel, FontStyle); 177 | GUILayout.FlexibleSpace(); 178 | } 179 | GUILayout.EndHorizontal(); 180 | 181 | GUILayout.Space(margin); 182 | 183 | GUI.enabled = !localData.Busy; 184 | 185 | if (GUILayout.Button("OPEN FOLDER", ButtonStyle) == true) 186 | System.Diagnostics.Process.Start("explorer.exe", $"/select,{localData.Path.Replace("/", "\\")}"); 187 | 188 | if (GUILayout.Button("REFRESH", ButtonStyle) == true) 189 | files = localData.GetFilesInfo(); 190 | 191 | GUILayout.Space(margin); 192 | 193 | const float labelWidth = 80.0f; 194 | 195 | GUILayout.BeginVertical("box"); 196 | { 197 | GUILayout.BeginHorizontal(); 198 | { 199 | GUILayout.Label("Integrity", GUILayout.Width(labelWidth)); 200 | Integrity = (FileIntegrity)GUILayout.SelectionGrid((int)Integrity, Enum.GetNames(typeof(FileIntegrity)), Enum.GetNames(typeof(FileIntegrity)).Length); 201 | } 202 | GUILayout.EndHorizontal(); 203 | 204 | GUILayout.BeginHorizontal(); 205 | { 206 | GUILayout.Label("Compression", GUILayout.Width(labelWidth)); 207 | Compression = (FileCompression)GUILayout.SelectionGrid((int)Compression, Enum.GetNames(typeof(FileCompression)), Enum.GetNames(typeof(FileCompression)).Length); 208 | } 209 | GUILayout.EndHorizontal(); 210 | 211 | GUILayout.BeginHorizontal(); 212 | { 213 | GUILayout.Label("Encryption", GUILayout.Width(labelWidth)); 214 | Encryption = (FileEncryption)GUILayout.SelectionGrid((int)Encryption, Enum.GetNames(typeof(FileEncryption)), Enum.GetNames(typeof(FileEncryption)).Length); 215 | } 216 | GUILayout.EndHorizontal(); 217 | } 218 | GUILayout.EndVertical(); 219 | 220 | GUILayout.Space(margin); 221 | 222 | GUILayout.BeginVertical("box"); 223 | { 224 | GUILayout.BeginHorizontal(); 225 | { 226 | GUILayout.Label("Kilobytes", GUILayout.Width(labelWidth)); 227 | kilobytes = (int)GUILayout.HorizontalSlider(kilobytes, 1.0f, 1024); 228 | } 229 | GUILayout.EndHorizontal(); 230 | 231 | GUILayout.BeginHorizontal(); 232 | { 233 | GUILayout.Label("Megabytes", GUILayout.Width(labelWidth)); 234 | megabytes = (int)GUILayout.HorizontalSlider(megabytes, 0.0f, 98, GUILayout.ExpandWidth(true)); 235 | } 236 | GUILayout.EndHorizontal(); 237 | 238 | GUILayout.BeginHorizontal(); 239 | { 240 | GUILayout.Label("Sequential", GUILayout.Width(labelWidth)); 241 | randomness = GUILayout.HorizontalSlider(randomness, 0.0f, 1.0f, GUILayout.ExpandWidth(true)); 242 | GUILayout.Label("Random", GUILayout.Width(50.0f)); 243 | } 244 | GUILayout.EndHorizontal(); 245 | } 246 | GUILayout.EndVertical(); 247 | 248 | GUILayout.Space(margin); 249 | 250 | GUILayout.BeginHorizontal(); 251 | { 252 | if (GUILayout.Button($"CREATE {(megabytes * 1024 * 1024 + kilobytes * 1024).BytesToHumanReadable()} FILE", ButtonStyle) == true) 253 | { 254 | localData.Cancel(); 255 | 256 | localData.Write(new TestData(megabytes * 1024 * 1024 + kilobytes * 1024, randomness), 257 | localData.NextAvailableName($"{Integrity}_{Compression}_{Encryption}.data", "_"), 258 | progress => statusLabel = $"WRITING {(progress * 100.0f):00}%", 259 | (result) => 260 | { 261 | lastFileResult = result; 262 | files = localData.GetFilesInfo(); 263 | statusLabel = "NO ACTIVE FILE OPERATIONS"; 264 | }); 265 | } 266 | 267 | GUILayout.Space(margin); 268 | 269 | GUI.enabled = fileSelected != -1 && localData.Busy == false; 270 | 271 | if (GUILayout.Button("DELETE", ButtonStyle) == true && fileSelected < files.Count) 272 | { 273 | localData.Cancel(); 274 | 275 | localData.Delete(files[fileSelected].Name); 276 | fileSelected = -1; 277 | 278 | files = localData.GetFilesInfo(); 279 | } 280 | 281 | GUI.enabled = localData.Busy; 282 | 283 | if (GUILayout.Button(localData.Busy ? "CANCEL" : "CANCEL", ButtonStyle) == true) 284 | localData.Cancel(); 285 | } 286 | GUILayout.EndHorizontal(); 287 | 288 | GUI.enabled = true; 289 | } 290 | GUILayout.EndVertical(); 291 | 292 | GUILayout.Space(margin); 293 | } 294 | GUILayout.EndHorizontal(); 295 | 296 | GUILayout.Space(margin); 297 | 298 | GUILayout.BeginHorizontal(); 299 | { 300 | GUILayout.Space(margin); 301 | 302 | GUILayout.BeginVertical(BoxStyle, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true)); 303 | { 304 | if (lastFileResult == FileResult.Ok) 305 | { 306 | if (fileSelected != -1 && test != null) 307 | { 308 | GUILayout.Label($"File '{files[fileSelected].Name}' ({test.data.Length.BytesToHumanReadable()})", FontStyle); 309 | 310 | GUILayout.BeginVertical("box", GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true)); 311 | { 312 | GUILayout.Label($"Bool:{test.boolValue} Byte:{test.byteValue} SByte:{test.sbyteValue} Short:{test.shortValue} UShort:{test.ushortValue} " + 313 | $"Int:{test.intValue} UInt:{test.uintValue} Long:{test.longValue} ULong:{test.ulongValue} " + 314 | $"Float:{test.floatValue:0.00} Double:{test.doubleValue:0.00} Decimal:{test.decimalValue:0:00} DateTime:'{test.dateTimeValue}'"); 315 | 316 | GUILayout.Label($"String:'{test.stringValue}' Char:'{test.charValue}' Struct:'{test.structData.stringValue}' Class:'{test.classData.stringValue}" + 317 | $"List size:{test.listValue.Count} Dictionary size:{test.dictValue.Count}"); 318 | 319 | GUILayout.Label($"Vector2:{test.vector2} Vector3:{test.vector3} Vector4:{test.vector4} Color:{test.color}"); 320 | 321 | string hex = BitConverter.ToString(test.data[..Math.Min(test.data.Length, 600)]).Replace("-",""); 322 | GUILayout.TextArea(test.data.Length <= 600 ? hex : hex + "..."); 323 | } 324 | GUILayout.EndVertical(); 325 | } 326 | } 327 | else if (lastFileResult != FileResult.Cancelled) 328 | GUILayout.Label($"Error: {lastFileResult.ToString().FromCamelCase()}", FontStyle); 329 | 330 | GUILayout.FlexibleSpace(); 331 | } 332 | GUILayout.EndVertical(); 333 | 334 | GUILayout.Space(margin); 335 | } 336 | GUILayout.EndHorizontal(); 337 | 338 | GUILayout.Space(margin); 339 | } 340 | GUILayout.EndVertical(); 341 | 342 | GUILayout.FlexibleSpace(); 343 | 344 | GUILayout.Space(margin); 345 | } 346 | GUILayout.EndHorizontal(); 347 | } 348 | 349 | private Texture2D MakeTex(int width, int height, Color col) 350 | { 351 | Color[] pix = new Color[width * height]; 352 | for (int i = 0; i < pix.Length; ++i) 353 | pix[i] = col; 354 | 355 | Texture2D result = new Texture2D(width, height); 356 | result.SetPixels(pix); 357 | result.Apply(); 358 | 359 | return result; 360 | } 361 | } 362 | -------------------------------------------------------------------------------- /Demo/LocalDataTest.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2917d0450d4c16447a452dce15c9804f 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Demo/TestData.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System; 18 | using System.Collections.Generic; 19 | using UnityEngine; 20 | using FronkonGames.GameWork.Foundation; 21 | using FronkonGames.GameWork.Modules.LocalData; 22 | using Random = UnityEngine.Random; 23 | 24 | [Serializable] 25 | public struct StructData 26 | { 27 | public string stringValue; 28 | } 29 | 30 | [Serializable] 31 | public class ClassData 32 | { 33 | public string stringValue; 34 | } 35 | 36 | /// 37 | /// Test file. 38 | /// 39 | [Serializable] 40 | public sealed class TestData : LocalData 41 | { 42 | public bool boolValue; 43 | 44 | public byte byteValue; 45 | public sbyte sbyteValue; 46 | 47 | public char charValue; 48 | 49 | public string stringValue; 50 | 51 | public short shortValue; 52 | public ushort ushortValue; 53 | 54 | public int intValue; 55 | public uint uintValue; 56 | 57 | public long longValue; 58 | public ulong ulongValue; 59 | 60 | public float floatValue; 61 | public double doubleValue; 62 | public decimal decimalValue; 63 | 64 | public DateTime dateTimeValue; 65 | 66 | public StructData structData; 67 | public ClassData classData; 68 | 69 | public List listValue; 70 | public Dictionary dictValue; 71 | 72 | public Vector2 vector2; 73 | public Vector3 vector3; 74 | public Vector4 vector4; 75 | public Color color; 76 | 77 | public byte[] data; 78 | 79 | public TestData(int size, float randomness = 0.5f) 80 | { 81 | Check.Greater(size, 0); 82 | 83 | boolValue = true; 84 | byteValue = 42; 85 | sbyteValue = -42; 86 | charValue = 'A'; 87 | stringValue = "All your base are belong to us!"; 88 | shortValue = -42; 89 | ushortValue = 42; 90 | intValue = -42; 91 | uintValue = 42; 92 | longValue = -42; 93 | ulongValue = 42; 94 | floatValue = Mathf.PI; 95 | doubleValue = Math.PI; 96 | decimalValue = (decimal)Math.E; 97 | dateTimeValue = DateTime.Now; 98 | 99 | structData = new StructData { stringValue = "This is a structure." }; 100 | classData = new ClassData { stringValue = "This is a class." }; 101 | 102 | listValue = new List { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 103 | dictValue = new Dictionary 104 | { 105 | { 0, "Zero" }, 106 | { 1, "One" }, 107 | { 2, "Two" }, 108 | { 3, "Three" }, 109 | { 4, "Four" }, 110 | { 5, "Five" }, 111 | { 6, "Six" }, 112 | { 7, "Seven" }, 113 | { 8, "Eight" }, 114 | { 9, "Nine" }, 115 | }; 116 | 117 | vector2 = Vector2.zero; 118 | vector3 = Vector3.forward; 119 | vector4 = Vector4.one; 120 | color = Color.magenta; 121 | 122 | data = new byte[size]; 123 | bool random = false; 124 | for (int i = 0; i < size; ++i) 125 | { 126 | data[i] = random ? (byte)Random.Range(0, 255) : (byte)(i % 255); 127 | 128 | if (i % 1024 == 0) 129 | random = Random.value < randomness; 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /Demo/TestData.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 237f7478245a8df4b91eb969b7bb4a84 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Martin Bustos Roman 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 35c9862f0c8317947b8c0b3736c1d688 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 |

Async Load/Save Local Data With Compression, Encryption And Integrity Check

3 |
4 | 5 |

6 | 7 | version 8 | 9 | 10 | license 11 | 12 | 13 | top language 14 | 15 | 16 | code quality 17 | 18 |

19 | 20 | '**Local Data**' is a module of '**Game:Work**' dedicated to read and write local files asynchronously. 21 | 22 | ## Features 🎇 23 | 24 | * Fully asynchronous read, load and cancel.
25 | * Integrity check using MD5, SHA-1, SHA-256 or SHA-512 algorithms.
26 | * Compression / decompression using algorithms: GZip, Zip or Brotli.
27 | * Encryption / decryption using algorithms: AES, DES, RC2, DES or TripleDES.
28 | * Supports typical Unity data such as: Vector, Quaternion, Color, etc. 29 | 30 | ## Requisites 🔧 31 | 32 | - Unity 2020.3 or higher. 33 | - [Game:Work Core](https://github.com/FronkonGames/GameWork-Core). 34 | - [Game:Work Foundation](https://github.com/FronkonGames/GameWork-Foundation). 35 | - Test Framework 1.1.31 or higher. 36 | 37 | ## Installation 📦️ 38 | 39 | ### Editing your 'manifest.json' 40 | 41 | - Open the manifest.json file of your Unity project. 42 | - In the section "dependencies" add: 43 | 44 | ```c# 45 | { 46 | ... 47 | "dependencies": 48 | { 49 | ... 50 | "FronkonGames.GameWork.Modules.LocalData": "git+https://github.com/FronkonGames/GameWork-Local-Data.git", 51 | "FronkonGames.GameWork.Core": "git+https://github.com/FronkonGames/GameWork-Core.git", 52 | "FronkonGames.GameWork.Foundation": "git+https://github.com/FronkonGames/GameWork-Foundation.git" 53 | } 54 | ... 55 | } 56 | ``` 57 | 58 | ### Git 59 | 60 | First clone the dependencies inside your Assets folder: 61 | 62 | ``` 63 | git clone https://github.com/FronkonGames/GameWork-Foundation.git 64 | 65 | git clone https://github.com/FronkonGames/GameWork-Core.git 66 | ``` 67 | 68 | Then clone the repository: 69 | 70 | ``` 71 | git clone https://github.com/FronkonGames/GameWork-Local-Data.git 72 | ``` 73 | 74 | ## Use 🚀 75 | 76 | Create a class inheriting from ILocalData and add the attribute _Serializable_: 77 | 78 | ```c# 79 | [Serializable] 80 | public class MyLocalData : ILocalData 81 | { 82 | public string Signature => "MySignature"; 83 | 84 | public string playerName = "Guybrush Threepwood"; 85 | 86 | public Vector3 position = new(0.0f, -10.0f, 0.0f); 87 | } 88 | ``` 89 | 90 | To serialize it in the file '_Guy.brush_': 91 | 92 | ```c# 93 | localDataModule.Write(myLocalData, "Guy.brush", null, (result) => 94 | { 95 | if (result == FileResult.Ok) 96 | Debug.Log("Guybrush Threepwood saved!"); 97 | else 98 | Debug.Error($"{result} writing 'Guy.brush'."); 99 | }); 100 | ``` 101 | 102 | To deserialise the file '_Guy.brush_' into an object: 103 | 104 | ```c# 105 | MyLocalData myLocaldata = null; 106 | 107 | localDataModule.Read("Guy.brush", null, (result, file) => 108 | { 109 | if (result == FileResult.Ok) 110 | myLocalData = file; 111 | else 112 | Debug.Error($"{result} reading 'Guy.brush'."); 113 | }); 114 | ``` 115 | 116 | ## License 📜 117 | 118 | Code released under [MIT License](https://github.com/FronkonGames/GameWork-Scene-Module/blob/main/LICENSE). -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 517bbd41ae149c7449fa252b2cbfa527 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 249985a927d6f524185714afcd81c0b6 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Compressor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e781f60b9e9f4d4a88bcc4a86e323d70 3 | timeCreated: 1658621212 -------------------------------------------------------------------------------- /Runtime/Compressor/BrotliCompressor.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System.IO; 18 | using System.IO.Compression; 19 | using System.Threading; 20 | 21 | namespace FronkonGames.GameWork.Modules.LocalData 22 | { 23 | /// 24 | /// Brotli compressor. 25 | /// 26 | public sealed class BrotliCompressor : CompressorBase 27 | { 28 | /// 29 | /// Constructor. 30 | /// 31 | /// Buffer size, in kB. 32 | /// Compression level. 33 | /// Cancellation token. 34 | public BrotliCompressor(int bufferSize, CompressionLevel compressionLevel, CancellationToken cancellationToken) 35 | : base(bufferSize, compressionLevel, cancellationToken) 36 | { 37 | } 38 | 39 | protected override Stream CreateCompressorStream(MemoryStream stream) => new BrotliStream(stream, compressionLevel, true); 40 | 41 | protected override Stream CreateDecompressorStream(MemoryStream stream) => new BrotliStream(stream, CompressionMode.Decompress, true); 42 | } 43 | } -------------------------------------------------------------------------------- /Runtime/Compressor/BrotliCompressor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8d57a967024e9f3479cde43379016496 3 | timeCreated: 1658631523 -------------------------------------------------------------------------------- /Runtime/Compressor/CompressorBase.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System; 18 | using System.IO; 19 | using System.IO.Compression; 20 | using System.Threading; 21 | using System.Threading.Tasks; 22 | using FronkonGames.GameWork.Foundation; 23 | 24 | namespace FronkonGames.GameWork.Modules.LocalData 25 | { 26 | /// 27 | /// File compression / decompression base. 28 | /// 29 | public abstract class CompressorBase : ICompressor 30 | { 31 | private readonly byte[] buffer; 32 | 33 | protected readonly CompressionLevel compressionLevel; 34 | 35 | private readonly CancellationToken cancellationToken; 36 | 37 | protected CompressorBase(int bufferSize, CompressionLevel compressionLevel, CancellationToken cancellationToken) 38 | { 39 | Check.Greater(bufferSize, 1); 40 | 41 | buffer = new byte[bufferSize * 1024]; 42 | 43 | this.compressionLevel = compressionLevel; 44 | this.cancellationToken = cancellationToken; 45 | } 46 | 47 | /// 48 | /// Compresses a stream. 49 | /// 50 | /// Memory stream. 51 | /// Progress of the compression, from 0 to 1. 52 | /// Compressed stream. 53 | public async Task Compress(MemoryStream stream, Action progress) 54 | { 55 | Check.IsNotNull(stream); 56 | 57 | int bytesRead, bytesReadTotal = 0; 58 | stream.Position = 0; 59 | 60 | MemoryStream outStream = new(); 61 | Stream compressorStream = CreateCompressorStream(outStream); 62 | do 63 | { 64 | bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken); 65 | if (bytesRead > 0) 66 | { 67 | await compressorStream.WriteAsync(buffer, 0, buffer.Length, cancellationToken); 68 | await compressorStream.FlushAsync(cancellationToken); 69 | 70 | bytesReadTotal += bytesRead; 71 | progress?.Invoke((float)bytesReadTotal / stream.Length); 72 | } 73 | } while (bytesRead > 0 && cancellationToken.IsCancellationRequested == false); 74 | 75 | compressorStream.Close(); 76 | progress?.Invoke(1.0f); 77 | outStream.Position = 0; 78 | 79 | return outStream; 80 | } 81 | 82 | /// 83 | /// Descompresses a stream. 84 | /// 85 | /// Compressed memory stream. 86 | /// Size of the uncompressed stream. 87 | /// Progress of the decompression, from 0 to 1. 88 | /// Decompressed stream. 89 | public async Task Decompress(MemoryStream stream, int originalSize, Action progress) 90 | { 91 | Check.IsNotNull(stream); 92 | Check.Greater(originalSize, 0); 93 | 94 | int bytesRead, bytesReadTotal = 0; 95 | stream.Position = 0; 96 | 97 | MemoryStream outStream = new(originalSize); 98 | Stream decompressorStream = CreateDecompressorStream(stream); 99 | do 100 | { 101 | bytesRead = await decompressorStream.ReadAsync(buffer, 0, buffer.Length, cancellationToken); 102 | if (bytesRead > 0) 103 | { 104 | await outStream.WriteAsync(buffer, 0, buffer.Length, cancellationToken); 105 | await outStream.FlushAsync(cancellationToken); 106 | 107 | bytesReadTotal += bytesRead; 108 | progress?.Invoke((float)bytesReadTotal / originalSize); 109 | } 110 | } while (bytesRead > 0 && cancellationToken.IsCancellationRequested == false); 111 | 112 | decompressorStream.Close(); 113 | progress?.Invoke(1.0f); 114 | outStream.Position = 0; 115 | 116 | return outStream; 117 | } 118 | 119 | protected abstract Stream CreateCompressorStream(MemoryStream stream); 120 | 121 | protected abstract Stream CreateDecompressorStream(MemoryStream stream); 122 | } 123 | } -------------------------------------------------------------------------------- /Runtime/Compressor/CompressorBase.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ab4f67bfe3d29354192c172c0f9517ff 3 | timeCreated: 1658631523 -------------------------------------------------------------------------------- /Runtime/Compressor/FileCompression.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | 18 | namespace FronkonGames.GameWork.Modules.LocalData 19 | { 20 | /// 21 | /// Compression algorithms supported. 22 | /// 23 | public enum FileCompression 24 | { 25 | None, 26 | Zip, 27 | GZip, 28 | Brotli, 29 | } 30 | } -------------------------------------------------------------------------------- /Runtime/Compressor/FileCompression.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5f6180bfc2774cd1b701312597878f0e 3 | timeCreated: 1658350791 -------------------------------------------------------------------------------- /Runtime/Compressor/GZipCompressor.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System.IO; 18 | using System.IO.Compression; 19 | using System.Threading; 20 | 21 | namespace FronkonGames.GameWork.Modules.LocalData 22 | { 23 | /// 24 | /// GZip compressor. 25 | /// 26 | public sealed class GZipCompressor : CompressorBase 27 | { 28 | /// 29 | /// Constructor. 30 | /// 31 | /// Buffer size, in kB. 32 | /// Compression level. 33 | /// Cancellation token. 34 | public GZipCompressor(int bufferSize, CompressionLevel compressionLevel, CancellationToken cancellationToken) 35 | : base(bufferSize, compressionLevel, cancellationToken) 36 | { 37 | } 38 | 39 | protected override Stream CreateCompressorStream(MemoryStream stream) => new GZipStream(stream, compressionLevel, true); 40 | 41 | protected override Stream CreateDecompressorStream(MemoryStream stream) => new GZipStream(stream, CompressionMode.Decompress, true); 42 | } 43 | } -------------------------------------------------------------------------------- /Runtime/Compressor/GZipCompressor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ee2670d7fcf843c3bdd7b2a3578aee0b 3 | timeCreated: 1658631523 -------------------------------------------------------------------------------- /Runtime/Compressor/ICompressor.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System; 18 | using System.IO; 19 | using System.Threading.Tasks; 20 | 21 | namespace FronkonGames.GameWork.Modules.LocalData 22 | { 23 | /// 24 | /// Compression interface. 25 | /// 26 | public interface ICompressor 27 | { 28 | /// 29 | /// Compresses a stream. 30 | /// 31 | /// Memory stream. 32 | /// Progress of the compression, from 0 to 1. 33 | /// Compressed stream. 34 | public Task Compress(MemoryStream stream, Action progress); 35 | 36 | /// 37 | /// Descompresses a stream. 38 | /// 39 | /// Compressed memory stream. 40 | /// Size of the uncompressed stream. 41 | /// Progress of the decompression, from 0 to 1. 42 | /// Decompressed stream. 43 | public Task Decompress(MemoryStream stream, int originalSize, Action progress); 44 | } 45 | } -------------------------------------------------------------------------------- /Runtime/Compressor/ICompressor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 02c4f3e2b5924725ba6c489a7214fe48 3 | timeCreated: 1658621263 -------------------------------------------------------------------------------- /Runtime/Compressor/NullCompressor.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System; 18 | using System.IO; 19 | using System.Threading.Tasks; 20 | 21 | namespace FronkonGames.GameWork.Modules.LocalData 22 | { 23 | /// 24 | /// It does not make any kind of compression. 25 | /// 26 | public sealed class NullCompressor : ICompressor 27 | { 28 | /// 29 | /// Compresses a stream. 30 | /// 31 | /// Memory stream. 32 | /// Progress of the compression, from 0 to 1. 33 | /// Same stream. 34 | public Task Compress(MemoryStream stream, Action progress) 35 | { 36 | progress?.Invoke(0.0f); 37 | 38 | return Task.FromResult(stream); 39 | } 40 | 41 | /// 42 | /// Compresses a stream. 43 | /// 44 | /// Memory stream. 45 | /// Progress of the compression, from 0 to 1. 46 | /// Same stream. 47 | public Task Decompress(MemoryStream stream, int originalSize, Action progress) 48 | { 49 | progress?.Invoke(0.0f); 50 | 51 | return Task.FromResult(stream); 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /Runtime/Compressor/NullCompressor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 66011ebfbd1a4cb0af859bf28b621d0d 3 | timeCreated: 1658630290 -------------------------------------------------------------------------------- /Runtime/Compressor/ZipCompressor.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System.IO; 18 | using System.IO.Compression; 19 | using System.Threading; 20 | 21 | namespace FronkonGames.GameWork.Modules.LocalData 22 | { 23 | /// 24 | /// ZIP compressor. 25 | /// 26 | public sealed class ZipCompressor : CompressorBase 27 | { 28 | /// 29 | /// Constructor. 30 | /// 31 | /// Buffer size, in kB. 32 | /// Compression level. 33 | /// Cancellation token. 34 | public ZipCompressor(int bufferSize, CompressionLevel compressionLevel, CancellationToken cancellationToken) 35 | : base(bufferSize, compressionLevel, cancellationToken) 36 | { 37 | } 38 | 39 | protected override Stream CreateCompressorStream(MemoryStream stream) => new DeflateStream(stream, compressionLevel, true); 40 | 41 | protected override Stream CreateDecompressorStream(MemoryStream stream) => new DeflateStream(stream, CompressionMode.Decompress, true); 42 | } 43 | } -------------------------------------------------------------------------------- /Runtime/Compressor/ZipCompressor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 20efc587314615545a3f6a85c63e99b0 3 | timeCreated: 1658631523 -------------------------------------------------------------------------------- /Runtime/Encryptor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 778a31b989ca476e90d6ee1f5f06492a 3 | timeCreated: 1658621313 -------------------------------------------------------------------------------- /Runtime/Encryptor/AESEncryptor.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System.Security.Cryptography; 18 | using System.Threading; 19 | 20 | namespace FronkonGames.GameWork.Modules.LocalData 21 | { 22 | /// 23 | /// AES encryptor. 24 | /// 25 | public sealed class AESEncryptor : EncryptorBase 26 | { 27 | /// 28 | /// Constructor. 29 | /// 30 | /// Buffer size, in kB 31 | /// Password, must be 16 characters or greater. 32 | /// Seed. 33 | /// Cancellation token. 34 | public AESEncryptor(int bufferSize, string password, string seed, CancellationToken cancellationToken) 35 | : base(bufferSize, password, seed, cancellationToken) 36 | { 37 | Rfc2898DeriveBytes rfc = new(password, IV); 38 | byte[] key = rfc.GetBytes(16); 39 | byte[] iv = rfc.GetBytes(16); 40 | 41 | AesCryptoServiceProvider aesProvider = new(); 42 | Encryptor = aesProvider.CreateEncryptor(key, iv); 43 | Decryptor = aesProvider.CreateDecryptor(key, iv); 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /Runtime/Encryptor/AESEncryptor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 00827e3f40094bb2a13907ff6040745d 3 | timeCreated: 1658633390 -------------------------------------------------------------------------------- /Runtime/Encryptor/DESEncryptor.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System.Security.Cryptography; 18 | using System.Threading; 19 | using FronkonGames.GameWork.Foundation; 20 | 21 | namespace FronkonGames.GameWork.Modules.LocalData 22 | { 23 | /// 24 | /// DES encryptor. 25 | /// 26 | public sealed class DESEncryptor : EncryptorBase 27 | { 28 | /// 29 | /// Constructor. 30 | /// 31 | /// Buffer size, in kB 32 | /// Password, must be 8 characters. 33 | /// Seed. 34 | /// Cancellation token. 35 | public DESEncryptor(int bufferSize, string password, string seed, CancellationToken cancellationToken) 36 | : base(bufferSize, password, seed, cancellationToken) 37 | { 38 | Check.Equal(password.Length, 8); 39 | 40 | DESCryptoServiceProvider desProvider = new(); 41 | Encryptor = desProvider.CreateEncryptor(key, IV); 42 | Decryptor = desProvider.CreateDecryptor(key, IV); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /Runtime/Encryptor/DESEncryptor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e037c62fd0dc39e4f902ba4c1f4dd1b6 3 | timeCreated: 1658633390 -------------------------------------------------------------------------------- /Runtime/Encryptor/EncryptorBase.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System; 18 | using System.IO; 19 | using System.Security.Cryptography; 20 | using System.Text; 21 | using System.Threading; 22 | using System.Threading.Tasks; 23 | using FronkonGames.GameWork.Foundation; 24 | 25 | namespace FronkonGames.GameWork.Modules.LocalData 26 | { 27 | /// 28 | /// File encryption / decryption base. 29 | /// 30 | public abstract class EncryptorBase : IEncryptor 31 | { 32 | protected ICryptoTransform Encryptor { get; set; } 33 | 34 | protected ICryptoTransform Decryptor { get; set; } 35 | 36 | private readonly byte[] buffer; 37 | 38 | private readonly CancellationToken cancellationToken; 39 | 40 | protected readonly byte[] key; // @TODO: Use SafeByte. 41 | protected readonly byte[] IV; // @TODO: Use SafeByte. 42 | 43 | protected EncryptorBase(int bufferSize, string password, string seed = default, CancellationToken cancellationToken = default) 44 | { 45 | Check.Greater(bufferSize, 1); 46 | Check.IsNotNullOrEmpty(password); 47 | 48 | buffer = new byte[bufferSize * 1024]; 49 | key = Encoding.UTF8.GetBytes(password); 50 | IV = string.IsNullOrEmpty(seed) ? key : Encoding.UTF8.GetBytes(seed); 51 | 52 | this.cancellationToken = cancellationToken; 53 | } 54 | 55 | /// 56 | /// Stream encryption. 57 | /// 58 | /// Memory stream. 59 | /// Progress of the encryption, from 0 to 1. 60 | /// Encrypted stream. 61 | public async Task Encrypt(MemoryStream stream, Action progress) 62 | { 63 | Check.IsNotNull(stream); 64 | 65 | stream.Position = 0; 66 | 67 | MemoryStream encryptedStream = new(); 68 | CryptoStream cryptoStream = new(encryptedStream, Encryptor, CryptoStreamMode.Write); 69 | 70 | int bytesRead; 71 | int bytesReadTotal = 0; 72 | do 73 | { 74 | bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken); 75 | if (bytesRead > 0) 76 | { 77 | await cryptoStream.WriteAsync(buffer, 0, bytesRead, cancellationToken); 78 | 79 | bytesReadTotal += bytesRead; 80 | progress?.Invoke((float)bytesReadTotal / stream.Length); 81 | } 82 | } while (bytesRead > 0 && cancellationToken.IsCancellationRequested == false); 83 | 84 | cryptoStream.FlushFinalBlock(); 85 | 86 | progress?.Invoke(1.0f); 87 | 88 | return encryptedStream; 89 | } 90 | 91 | /// 92 | /// Stream decryption. 93 | /// 94 | /// Encrypted memory stream. 95 | /// Progress of the decryption, from 0 to 1. 96 | /// Decrypted stream. 97 | public async Task Decrypt(MemoryStream stream, Action progress) 98 | { 99 | Check.IsNotNull(stream); 100 | 101 | stream.Position = 0; 102 | 103 | MemoryStream decryptedStream = new(); 104 | await using MemoryStream encryptedStream = new(stream.ToArray()); 105 | using AesCryptoServiceProvider aesProvider = new(); 106 | await using CryptoStream cryptoStream = new(encryptedStream, Decryptor, CryptoStreamMode.Read); 107 | 108 | int bytesRead; 109 | int bytesReadTotal = 0; 110 | do 111 | { 112 | bytesRead = await cryptoStream.ReadAsync(buffer, 0, buffer.Length, cancellationToken); 113 | if (bytesRead > 0) 114 | { 115 | await decryptedStream.WriteAsync(buffer, 0, bytesRead, cancellationToken); 116 | 117 | bytesReadTotal += bytesRead; 118 | progress?.Invoke((float)bytesReadTotal / stream.Length); 119 | } 120 | } while (bytesRead > 0 && cancellationToken.IsCancellationRequested == false); 121 | 122 | progress?.Invoke(1.0f); 123 | 124 | return decryptedStream; 125 | } 126 | } 127 | } -------------------------------------------------------------------------------- /Runtime/Encryptor/EncryptorBase.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 066aa4755fb04607aff3da85aba200e1 3 | timeCreated: 1659543117 -------------------------------------------------------------------------------- /Runtime/Encryptor/FileEncryption.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | 18 | namespace FronkonGames.GameWork.Modules.LocalData 19 | { 20 | /// 21 | /// Encryption algorithms supported. 22 | /// 23 | public enum FileEncryption 24 | { 25 | None, 26 | AES, 27 | RC2, 28 | DES, 29 | TripleDES, 30 | } 31 | } -------------------------------------------------------------------------------- /Runtime/Encryptor/FileEncryption.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9c1e1b2fa40840aa97174118d1a42a6d 3 | timeCreated: 1658350862 -------------------------------------------------------------------------------- /Runtime/Encryptor/IEncryptor.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System; 18 | using System.IO; 19 | using System.Threading.Tasks; 20 | 21 | namespace FronkonGames.GameWork.Modules.LocalData 22 | { 23 | /// 24 | /// Interface for encryption / decryption. 25 | /// 26 | public interface IEncryptor 27 | { 28 | /// 29 | /// Stream encryption. 30 | /// 31 | /// Memory stream. 32 | /// Progress of the encryption, from 0 to 1. 33 | /// Encrypted stream. 34 | public Task Encrypt(MemoryStream stream, Action progress); 35 | 36 | /// 37 | /// Stream decryption. 38 | /// 39 | /// Encrypted memory stream. 40 | /// Progress of the decryption, from 0 to 1. 41 | /// Decrypted stream. 42 | public Task Decrypt(MemoryStream stream, Action progress); 43 | } 44 | } -------------------------------------------------------------------------------- /Runtime/Encryptor/IEncryptor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b818b0337385436087e0a8fb6325c6b6 3 | timeCreated: 1658621313 -------------------------------------------------------------------------------- /Runtime/Encryptor/NullEncryptor.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System; 18 | using System.IO; 19 | using System.Threading.Tasks; 20 | 21 | namespace FronkonGames.GameWork.Modules.LocalData 22 | { 23 | /// 24 | /// It does not make any kind of encryption. 25 | /// 26 | public sealed class NullEncryptor : IEncryptor 27 | { 28 | /// 29 | /// Stream encryption. 30 | /// 31 | /// Memory stream. 32 | /// Progress of the encryption, from 0 to 1. 33 | /// Same stream. 34 | public Task Encrypt(MemoryStream stream, Action progress) 35 | { 36 | progress?.Invoke(0.0f); 37 | 38 | return Task.FromResult(stream); 39 | } 40 | 41 | /// 42 | /// Stream decryption. 43 | /// 44 | /// Memory stream. 45 | /// Progress of the decryption, from 0 to 1. 46 | /// Same stream. 47 | public Task Decrypt(MemoryStream stream, Action progress) 48 | { 49 | progress?.Invoke(0.0f); 50 | 51 | return Task.FromResult(stream); 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /Runtime/Encryptor/NullEncryptor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1206b6e30e7d4304984d0b60018e305c 3 | timeCreated: 1658630359 -------------------------------------------------------------------------------- /Runtime/Encryptor/RC2Encryptor.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System.Threading; 18 | using System.Security.Cryptography; 19 | 20 | namespace FronkonGames.GameWork.Modules.LocalData 21 | { 22 | /// 23 | /// RC2 encryptor. 24 | /// 25 | public sealed class RC2Encryptor : EncryptorBase 26 | { 27 | /// 28 | /// Constructor. 29 | /// 30 | /// Buffer size, in kB 31 | /// Password, must be 16 characters or greater. 32 | /// Cancellation token. 33 | public RC2Encryptor(int bufferSize, string password, string seed, CancellationToken cancellationToken) 34 | : base(bufferSize, password, seed, cancellationToken) 35 | { 36 | RC2CryptoServiceProvider rc2Provider = new(); 37 | Encryptor = rc2Provider.CreateEncryptor(key, IV); 38 | Decryptor = rc2Provider.CreateDecryptor(key, IV); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /Runtime/Encryptor/RC2Encryptor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 15e5bc1c606d27340a27aaf8afc9e47b 3 | timeCreated: 1658633390 -------------------------------------------------------------------------------- /Runtime/Encryptor/TripleDESEncryptor.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System.Security.Cryptography; 18 | using System.Threading; 19 | 20 | namespace FronkonGames.GameWork.Modules.LocalData 21 | { 22 | /// 23 | /// Triple DES encryptor. 24 | /// 25 | public sealed class TripleDESEncryptor : EncryptorBase 26 | { 27 | /// 28 | /// Constructor. 29 | /// 30 | /// Buffer size, in kB 31 | /// Password, must be 16 characters or greater. 32 | /// Cancellation token. 33 | public TripleDESEncryptor(int bufferSize, string password, string seed, CancellationToken cancellationToken) 34 | : base(bufferSize, password, seed, cancellationToken) 35 | { 36 | MD5CryptoServiceProvider md5CryptoServiceProvider = new(); 37 | TripleDESCryptoServiceProvider tripleDESProvider = new() 38 | { 39 | Key = md5CryptoServiceProvider.ComputeHash(key), 40 | Mode = CipherMode.ECB, 41 | Padding = PaddingMode.PKCS7 42 | }; 43 | Encryptor = tripleDESProvider.CreateEncryptor(); 44 | Decryptor = tripleDESProvider.CreateDecryptor(); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /Runtime/Encryptor/TripleDESEncryptor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d7c12f9476300754da9273a5921f46c4 3 | timeCreated: 1658633390 -------------------------------------------------------------------------------- /Runtime/FileResult.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | 18 | namespace FronkonGames.GameWork.Modules.LocalData 19 | { 20 | /// 21 | /// . 22 | /// 23 | public enum FileResult 24 | { 25 | Ok, 26 | Cancelled, 27 | InvalidSignature, 28 | IntegrityFailure, 29 | FileNotFound, 30 | ExceptionRaised 31 | } 32 | } -------------------------------------------------------------------------------- /Runtime/FileResult.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8aa1d62ff6784bd3ab0f934b8cdb4843 3 | timeCreated: 1659386037 -------------------------------------------------------------------------------- /Runtime/FronkonGames.GameWork.Modules.LocalData.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "FronkonGames.GameWork.Modules.LocalData", 3 | "references": 4 | [ 5 | "FronkonGames.GameWork.Core", 6 | "FronkonGames.GameWork.Foundation" 7 | ], 8 | "optionalUnityReferences": [], 9 | "includePlatforms": [], 10 | "excludePlatforms": [], 11 | "allowUnsafeCode": false, 12 | "overrideReferences": false, 13 | "precompiledReferences": [], 14 | "autoReferenced": true, 15 | "defineConstraints": [] 16 | } 17 | -------------------------------------------------------------------------------- /Runtime/FronkonGames.GameWork.Modules.LocalData.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ee42ec2ac72ccc94cacfc773ce504cf3 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime/ILocalData.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | 18 | namespace FronkonGames.GameWork.Modules.LocalData 19 | { 20 | /// 21 | /// Interface for local data file. 22 | /// 23 | public interface ILocalData 24 | { 25 | /// 26 | /// Signature. 27 | /// 28 | public string Signature { get; } 29 | } 30 | } -------------------------------------------------------------------------------- /Runtime/ILocalData.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 50d98904468a401eb55e593cdd82e71c 3 | timeCreated: 1658609446 -------------------------------------------------------------------------------- /Runtime/Integrity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 203463a199ec4a888ea19e77e1c3feef 3 | timeCreated: 1658622831 -------------------------------------------------------------------------------- /Runtime/Integrity/FileIntegrity.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | 18 | namespace FronkonGames.GameWork.Modules.LocalData 19 | { 20 | /// 21 | /// Types of algorithms supported for calculating data integrity. 22 | /// 23 | public enum FileIntegrity 24 | { 25 | None, 26 | MD5, 27 | SHA1, 28 | SHA256, 29 | SHA512, 30 | } 31 | } -------------------------------------------------------------------------------- /Runtime/Integrity/FileIntegrity.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 28c21bc5383d4b9d8d6a65376c7c92a6 3 | timeCreated: 1658764185 -------------------------------------------------------------------------------- /Runtime/Integrity/IIntegrity.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System; 18 | using System.IO; 19 | using System.Threading.Tasks; 20 | 21 | namespace FronkonGames.GameWork.Modules.LocalData 22 | { 23 | /// 24 | /// File integrity calculation interface. 25 | /// 26 | public interface IIntegrity 27 | { 28 | /// 29 | /// Calculation of the integrity of a stream. 30 | /// 31 | /// Memory stream. 32 | /// Progress of the calculation, from 0 to 1. 33 | /// Hash. 34 | public Task Calculate(MemoryStream stream, Action progress); 35 | 36 | /// 37 | /// Checks the integrity of a stream. 38 | /// 39 | /// Memory stream to check. 40 | /// Hash. 41 | /// Progress of the calculation, from 0 to 1. 42 | /// True if the integrity of the stream is correct. 43 | public Task Check(MemoryStream stream, string hash, Action progress); 44 | } 45 | } -------------------------------------------------------------------------------- /Runtime/Integrity/IIntegrity.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0f359852b9ab4f1880eb82e7a6fa25fd 3 | timeCreated: 1658622848 -------------------------------------------------------------------------------- /Runtime/Integrity/IntegrityBase.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System; 18 | using System.IO; 19 | using System.Security.Cryptography; 20 | using System.Threading; 21 | using System.Threading.Tasks; 22 | 23 | namespace FronkonGames.GameWork.Modules.LocalData 24 | { 25 | /// 26 | /// File integrity calculation base. 27 | /// 28 | public abstract class IntegrityBase : IIntegrity 29 | { 30 | private readonly byte[] buffer; 31 | 32 | private readonly CancellationToken cancellationToken; 33 | 34 | /// 35 | /// Calculation of the integrity of a stream. 36 | /// 37 | /// Memory stream. 38 | /// Progress of the calculation, from 0 to 1. 39 | /// Hash. 40 | public async Task Calculate(MemoryStream stream, Action progress) 41 | { 42 | stream.Position = 0; 43 | 44 | int bytesRead, bytesReadTotal = 0; 45 | using HashAlgorithm hashAlgorithm = CreateHashAlgorithm(); 46 | do 47 | { 48 | bytesRead = await stream.ReadAsync(buffer, 0 , buffer.Length, cancellationToken); 49 | if (bytesRead > 0) 50 | { 51 | hashAlgorithm.TransformBlock(buffer, 0, bytesRead, null, 0); 52 | 53 | bytesReadTotal += bytesRead; 54 | progress?.Invoke((float)bytesReadTotal / stream.Length); 55 | } 56 | } while (bytesRead > 0 && cancellationToken.IsCancellationRequested == false); 57 | 58 | hashAlgorithm.TransformFinalBlock(buffer, 0, 0); 59 | 60 | progress?.Invoke(1.0f); 61 | stream.Position = 0; 62 | 63 | return BitConverter.ToString(hashAlgorithm.Hash).Replace("-", "").ToUpperInvariant(); 64 | } 65 | 66 | /// 67 | /// Checks the integrity of a stream. 68 | /// 69 | /// Memory stream to check. 70 | /// Hash. 71 | /// Progress of the calculation, from 0 to 1. 72 | /// True if the integrity of the stream is correct. 73 | public async Task Check(MemoryStream stream, string hash, Action progress) 74 | { 75 | string streamHash = await Calculate(stream, progress); 76 | 77 | return streamHash.Equals(hash); 78 | } 79 | 80 | protected IntegrityBase(int bufferSize, CancellationToken cancellationToken) 81 | { 82 | Foundation.Check.Greater(bufferSize, 1); 83 | 84 | buffer = new byte[bufferSize * 1024]; 85 | 86 | this.cancellationToken = cancellationToken; 87 | } 88 | 89 | protected abstract HashAlgorithm CreateHashAlgorithm(); 90 | 91 | } 92 | } -------------------------------------------------------------------------------- /Runtime/Integrity/IntegrityBase.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3eb52c5d6a7f57d43b7d69b5be274dca 3 | timeCreated: 1658622885 -------------------------------------------------------------------------------- /Runtime/Integrity/MD5Integrity.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System.Security.Cryptography; 18 | using System.Threading; 19 | 20 | namespace FronkonGames.GameWork.Modules.LocalData 21 | { 22 | /// 23 | /// Integrity calculation based on MD5. 24 | /// 25 | public sealed class MD5Integrity : IntegrityBase 26 | { 27 | public MD5Integrity(int bufferSize, CancellationToken cancellationToken) : base(bufferSize, cancellationToken) { } 28 | 29 | protected override HashAlgorithm CreateHashAlgorithm() => MD5.Create(); 30 | } 31 | } -------------------------------------------------------------------------------- /Runtime/Integrity/MD5Integrity.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b5cce817404744719638d82358813577 3 | timeCreated: 1658622885 -------------------------------------------------------------------------------- /Runtime/Integrity/NullIntegrity.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System; 18 | using System.IO; 19 | using System.Threading.Tasks; 20 | 21 | namespace FronkonGames.GameWork.Modules.LocalData 22 | { 23 | /// 24 | /// It does not perform any integrity calculations. 25 | /// 26 | public sealed class NullIntegrity : IIntegrity 27 | { 28 | /// 29 | /// Calculation of the integrity of a stream. 30 | /// 31 | /// Memory stream. 32 | /// Progress of the calculation, from 0 to 1. 33 | /// Empty string. 34 | public Task Calculate(MemoryStream stream, Action progress) 35 | { 36 | progress?.Invoke(0.0f); 37 | 38 | return Task.FromResult(string.Empty); 39 | } 40 | 41 | /// 42 | /// Checks the integrity of a stream. 43 | /// 44 | /// Memory stream to check. 45 | /// Hash. 46 | /// Progress of the calculation, from 0 to 1. 47 | /// Always blue, I mean, true. 48 | public Task Check(MemoryStream stream, string hash, Action progress) 49 | { 50 | progress?.Invoke(0.0f); 51 | 52 | return Task.FromResult(true); 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /Runtime/Integrity/NullIntegrity.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2d9df553221e4360928b78e5ab67e415 3 | timeCreated: 1658764436 -------------------------------------------------------------------------------- /Runtime/Integrity/SHA1Integrity.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System.Security.Cryptography; 18 | using System.Threading; 19 | 20 | namespace FronkonGames.GameWork.Modules.LocalData 21 | { 22 | /// 23 | /// Integrity calculation based on SHA-1. 24 | /// 25 | public sealed class SHA1Integrity : IntegrityBase 26 | { 27 | public SHA1Integrity(int bufferSize, CancellationToken cancellationToken) : base(bufferSize, cancellationToken) { } 28 | 29 | protected override HashAlgorithm CreateHashAlgorithm() => SHA1.Create(); 30 | } 31 | } -------------------------------------------------------------------------------- /Runtime/Integrity/SHA1Integrity.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: afd62e2873e047f45aeeee0f50af6289 3 | timeCreated: 1658622885 -------------------------------------------------------------------------------- /Runtime/Integrity/SHA256Integrity.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System.Security.Cryptography; 18 | using System.Threading; 19 | 20 | namespace FronkonGames.GameWork.Modules.LocalData 21 | { 22 | /// 23 | /// Integrity calculation based on SHA-256. 24 | /// 25 | public sealed class SHA256Integrity : IntegrityBase 26 | { 27 | public SHA256Integrity(int bufferSize, CancellationToken cancellationToken) : base(bufferSize, cancellationToken) { } 28 | 29 | protected override HashAlgorithm CreateHashAlgorithm() => SHA256.Create(); 30 | } 31 | } -------------------------------------------------------------------------------- /Runtime/Integrity/SHA256Integrity.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f53da0409d32dbb4e97fe2427883f45e 3 | timeCreated: 1658622885 -------------------------------------------------------------------------------- /Runtime/Integrity/SHA512Integrity.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System.Security.Cryptography; 18 | using System.Threading; 19 | 20 | namespace FronkonGames.GameWork.Modules.LocalData 21 | { 22 | /// 23 | /// Integrity calculation based on SHA-512. 24 | /// 25 | public sealed class SHA512Integrity : IntegrityBase 26 | { 27 | public SHA512Integrity(int bufferSize, CancellationToken cancellationToken) : base(bufferSize, cancellationToken) { } 28 | 29 | protected override HashAlgorithm CreateHashAlgorithm() => SHA512.Create(); 30 | } 31 | } -------------------------------------------------------------------------------- /Runtime/Integrity/SHA512Integrity.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 42062a9f7a6f8fc49b841bc55fc14f68 3 | timeCreated: 1658622885 -------------------------------------------------------------------------------- /Runtime/LocalData.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System; 18 | 19 | namespace FronkonGames.GameWork.Modules.LocalData 20 | { 21 | /// 22 | /// Local data file. 23 | /// 24 | [Serializable] 25 | public abstract class LocalData : ILocalData 26 | { 27 | /// 28 | /// 'Game:Work' signature. 29 | /// 30 | public string Signature => "GW"; 31 | } 32 | } -------------------------------------------------------------------------------- /Runtime/LocalData.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f4952b05645a471b8d7c07afc97dd860 3 | timeCreated: 1656716010 -------------------------------------------------------------------------------- /Runtime/LocalDataModule.Read.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | //#define ENABLE_PROFILING 18 | using System; 19 | using System.IO; 20 | using System.Threading.Tasks; 21 | using System.Runtime.Serialization.Formatters.Binary; 22 | using System.Threading; 23 | using FronkonGames.GameWork.Core; 24 | using FronkonGames.GameWork.Foundation; 25 | 26 | namespace FronkonGames.GameWork.Modules.LocalData 27 | { 28 | /// 29 | /// Module for asynchronous reading / writing of local files. 30 | /// 31 | public sealed partial class LocalDataModule : MonoBehaviourModule, 32 | IInitializable 33 | { 34 | /// 35 | /// Reads a file asynchronously. 36 | /// 37 | /// File name. 38 | /// Result of the operation, with a code and the object (if the operation was successful). 39 | /// Object if the operation was a success. 40 | public async Task Read(string fileName, Action onEnd = null) where T : LocalData => 41 | await Read(fileName, null, onEnd); 42 | 43 | /// 44 | /// Reads a file asynchronously. 45 | /// 46 | /// File name. 47 | /// Progress of the operation, from 0 to 1. 48 | /// Result of the operation, with a code and the object (if the operation was successful). 49 | /// Object if the operation was a success. 50 | public async Task Read(string fileName, Action onProgress, Action onEnd) where T : LocalData 51 | { 52 | Check.IsNotNullOrEmpty(fileName); 53 | Check.GreaterOrEqual(bufferSize, 4); 54 | 55 | FileResult result = FileResult.Ok; 56 | 57 | T data = null; 58 | MemoryStream stream = new(); 59 | cancellationSource = new CancellationTokenSource(); 60 | CancellationToken cancellationToken = cancellationSource.Token; 61 | 62 | ResetProgress(onProgress); 63 | 64 | try 65 | { 66 | FileInfo fileInfo = GetFileInfo(fileName); 67 | if (fileInfo != null) 68 | { 69 | byte[] buffer = new byte[bufferSize * 1024]; 70 | 71 | await using FileStream fileStream = new(Path + fileName, FileMode.Open, FileAccess.Read, FileShare.Read); 72 | using BinaryReader binaryReader = new(fileStream); 73 | 74 | string fileSignature = binaryReader.ReadString(); 75 | FileIntegrity fileIntegrity = (FileIntegrity)binaryReader.ReadByte(); 76 | FileCompression fileCompression = (FileCompression)binaryReader.ReadByte(); 77 | FileEncryption fileEncryption = (FileEncryption)binaryReader.ReadByte(); 78 | string hash = binaryReader.ReadString(); 79 | int uncompressedSize = binaryReader.ReadInt32(); 80 | 81 | IIntegrity integrity = CreateFileIntegrity(fileIntegrity, cancellationToken); 82 | ICompressor compressor = CreateFileCompressor(fileCompression, cancellationToken); 83 | IEncryptor encryptor = CreateFileEncryptor(fileEncryption, cancellationToken); 84 | 85 | totalSteps += fileIntegrity != FileIntegrity.None ? 1 : 0; 86 | totalSteps += fileCompression != FileCompression.None ? 1 : 0; 87 | totalSteps += fileEncryption != FileEncryption.None ? 1 : 0; 88 | 89 | #if ENABLE_PROFILING 90 | using (Profiling.Time($"Reading {file} data")) 91 | #endif 92 | { 93 | int bytesRead = 0; 94 | do 95 | { 96 | bytesRead = await fileStream.ReadAsync(buffer, 0, buffer.Length, cancellationToken); 97 | if (bytesRead > 0) 98 | await stream.WriteAsync(buffer, 0, bytesRead, cancellationToken); 99 | 100 | CalculateProgress((float)stream.Length / fileStream.Length); 101 | } while (bytesRead > 0); 102 | } 103 | currentStep++; 104 | 105 | #if ENABLE_PROFILING 106 | using (Profiling.Time($"Checking {file} integrity")) 107 | #endif 108 | { 109 | result = await integrity.Check(stream, hash, CalculateProgress) ? FileResult.Ok : FileResult.IntegrityFailure; 110 | } 111 | currentStep += fileIntegrity != FileIntegrity.None ? 1 : 0; 112 | 113 | if (result == FileResult.Ok) 114 | { 115 | #if ENABLE_PROFILING 116 | using (Profiling.Time($"Decrypting {file}")) 117 | #endif 118 | { 119 | stream = await encryptor.Decrypt(stream, CalculateProgress); 120 | } 121 | currentStep += fileEncryption != FileEncryption.None ? 1 : 0; 122 | 123 | #if ENABLE_PROFILING 124 | using (Profiling.Time($"Decompressing {file}")) 125 | #endif 126 | { 127 | stream = await compressor.Decompress(stream, uncompressedSize, CalculateProgress); 128 | } 129 | currentStep += fileCompression != FileCompression.None ? 1 : 0; 130 | 131 | #if ENABLE_PROFILING 132 | using (Profiling.Time($"Deserializing {file}")) 133 | #endif 134 | { 135 | BinaryFormatter binaryFormatter = new(); 136 | AddSerializationSurrogates(binaryFormatter); 137 | 138 | stream.Position = 0; 139 | data = binaryFormatter.Deserialize(stream) as T; 140 | } 141 | 142 | result = data.Signature.Equals(fileSignature) ? FileResult.Ok : FileResult.InvalidSignature; 143 | } 144 | else 145 | Log.Warning($"File '{fileName}' integrity fails"); 146 | } 147 | else 148 | Log.Error($"File '{Path}{fileName}' not found"); 149 | } 150 | catch (OperationCanceledException) 151 | { 152 | result = FileResult.Cancelled; 153 | 154 | Log.Info($"File '{fileName}' reading canceled."); 155 | } 156 | catch (Exception e) 157 | { 158 | result = FileResult.ExceptionRaised; 159 | 160 | Log.Exception(e.ToString()); 161 | } 162 | finally 163 | { 164 | await stream.DisposeAsync(); 165 | 166 | cancellationSource.Dispose(); 167 | cancellationSource = null; 168 | clientProgress = null; 169 | 170 | onProgress?.Invoke(1.0f); 171 | 172 | onEnd?.Invoke(result, data); 173 | } 174 | } 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /Runtime/LocalDataModule.Read.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ace82af8f4e74c94587560a092438b17 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/LocalDataModule.Write.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | //#define ENABLE_PROFILING 18 | using System; 19 | using System.IO; 20 | using System.Runtime.Serialization.Formatters.Binary; 21 | using System.Threading; 22 | using System.Threading.Tasks; 23 | using FronkonGames.GameWork.Core; 24 | using FronkonGames.GameWork.Foundation; 25 | 26 | namespace FronkonGames.GameWork.Modules.LocalData 27 | { 28 | /// 29 | /// Module for asynchronous reading / writing of local files. 30 | /// 31 | public sealed partial class LocalDataModule : MonoBehaviourModule, 32 | IInitializable 33 | { 34 | /// 35 | /// Asynchronous file writing. 36 | /// 37 | /// Object to be serialised. 38 | /// File name. 39 | /// Result of the operation. 40 | /// ILocalData 41 | public async Task Write(T data, string fileName, Action onEnd = null) where T : ILocalData => 42 | await Write(data, fileName, null, onEnd); 43 | 44 | /// 45 | /// Asynchronous file writing. 46 | /// 47 | /// Object to be serialised. 48 | /// File name. 49 | /// Progress of the operation, from 0 to 1. 50 | /// Result of the operation. 51 | /// ILocalData 52 | public async Task Write(T data, string fileName, Action onProgress, Action onEnd) where T : ILocalData 53 | { 54 | Check.IsNotNull(data); 55 | Check.IsNotNullOrEmpty(fileName); 56 | Check.GreaterOrEqual(bufferSize, 4); 57 | 58 | FileResult result = FileResult.Ok; 59 | 60 | MemoryStream stream = new(); 61 | cancellationSource = new(); 62 | CancellationToken cancellationToken = cancellationSource.Token; 63 | 64 | ResetProgress(onProgress); 65 | 66 | try 67 | { 68 | string pathFileName = Path + fileName; 69 | if (CheckPath(pathFileName) == true) 70 | { 71 | await using FileStream fileStream = new(pathFileName, FileMode.Create, FileAccess.Write, FileShare.None); 72 | await using BinaryWriter writer = new(fileStream); 73 | 74 | // Signature : string. 75 | // Integrity : byte. 76 | // Compression : byte. 77 | // Encryption : byte. 78 | // Hash : string. 79 | // Uncompressed size : int. 80 | // Data : byte[]. 81 | 82 | writer.Write(data.Signature); 83 | writer.Write((byte)fileIntegrity); 84 | writer.Write((byte)fileCompression); 85 | writer.Write((byte)fileEncryption); 86 | 87 | IIntegrity integrity = CreateFileIntegrity(fileIntegrity, cancellationToken); 88 | ICompressor compressor = CreateFileCompressor(fileCompression, cancellationToken); 89 | IEncryptor encryptor = CreateFileEncryptor(fileEncryption, cancellationToken); 90 | 91 | totalSteps += fileIntegrity != FileIntegrity.None ? 1 : 0; 92 | totalSteps += fileCompression != FileCompression.None ? 1 : 0; 93 | totalSteps += fileEncryption != FileEncryption.None ? 1 : 0; 94 | 95 | #if ENABLE_PROFILING 96 | using (Profiling.Time($"Serializing {file}")) 97 | #endif 98 | { 99 | BinaryFormatter binaryFormatter = new(); 100 | AddSerializationSurrogates(binaryFormatter); 101 | 102 | binaryFormatter.Serialize(stream, data); 103 | } 104 | 105 | int uncompressedSize = (int)stream.Length; 106 | 107 | #if ENABLE_PROFILING 108 | using (Profiling.Time($"Compressing {file} using {fileCompression}")) 109 | #endif 110 | { 111 | stream = await compressor.Compress(stream, CalculateProgress); 112 | } 113 | currentStep += fileCompression != FileCompression.None ? 1 : 0; 114 | 115 | #if ENABLE_PROFILING 116 | using (Profiling.Time($"Encrypting {file} using {fileEncryption}")) 117 | #endif 118 | { 119 | stream = await encryptor.Encrypt(stream, CalculateProgress); 120 | } 121 | currentStep += fileEncryption != FileEncryption.None ? 1 : 0; 122 | 123 | string hash = string.Empty; 124 | #if ENABLE_PROFILING 125 | using (Profiling.Time($"Calculating {file} integrity")) 126 | #endif 127 | { 128 | hash = await integrity.Calculate(stream, CalculateProgress); 129 | } 130 | currentStep += fileIntegrity != FileIntegrity.None ? 1 : 0; 131 | 132 | writer.Write(hash); 133 | writer.Write(uncompressedSize); 134 | 135 | #if ENABLE_PROFILING 136 | using (Profiling.Time($"Writing {fileName} data")) 137 | #endif 138 | { 139 | byte[] bytes = stream.ToArray(); 140 | for (int offset = 0; offset < bytes.Length; ) 141 | { 142 | int length = Math.Min(bufferSize * 1024, bytes.Length - offset); 143 | await fileStream.WriteAsync(bytes, offset, length, cancellationToken); 144 | offset += length; 145 | 146 | CalculateProgress((float)offset / bytes.Length); 147 | } 148 | } 149 | } 150 | } 151 | catch (OperationCanceledException) 152 | { 153 | result = FileResult.Cancelled; 154 | 155 | if (Exists(fileName) == true) 156 | Delete(fileName); 157 | 158 | Log.Info($"File '{fileName}' writing canceled."); 159 | } 160 | catch (Exception e) 161 | { 162 | result = FileResult.ExceptionRaised; 163 | 164 | Log.Exception(e.ToString()); 165 | } 166 | finally 167 | { 168 | await stream.DisposeAsync(); 169 | 170 | cancellationSource.Dispose(); 171 | cancellationSource = null; 172 | clientProgress = null; 173 | 174 | onProgress?.Invoke(1.0f); 175 | 176 | onEnd?.Invoke(result); 177 | } 178 | } 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /Runtime/LocalDataModule.Write.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 470932e121d1bbf4b814da8009b45c73 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/LocalDataModule.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System; 18 | using System.Collections.Generic; 19 | using System.IO; 20 | using System.Runtime.Serialization; 21 | using System.Runtime.Serialization.Formatters.Binary; 22 | using System.Threading; 23 | using UnityEngine; 24 | using FronkonGames.GameWork.Core; 25 | using FronkonGames.GameWork.Foundation; 26 | using CompressionLevel = System.IO.Compression.CompressionLevel; 27 | 28 | namespace FronkonGames.GameWork.Modules.LocalData 29 | { 30 | /// 31 | /// Module for asynchronous reading / writing of local files. 32 | /// 33 | public sealed partial class LocalDataModule : MonoBehaviourModule, 34 | IInitializable 35 | { 36 | /// 37 | /// Is it initialized? 38 | /// 39 | /// Value 40 | public bool Initialized { get; set; } 41 | 42 | /// 43 | /// Working path. 44 | /// 45 | public string Path { get; private set; } 46 | 47 | /// 48 | /// Hash algorithm to calculate file integrity (default None). 49 | /// 50 | public FileIntegrity Integrity { get => fileIntegrity; set => fileIntegrity = value; } 51 | 52 | /// 53 | /// Algorithm to compress the file (default None). 54 | /// 55 | public FileCompression Compression { get => fileCompression; set => fileCompression = value; } 56 | 57 | /// 58 | /// Algorithm to encrypt the file. 59 | /// 60 | public FileEncryption Encryption { get => fileEncryption; set => fileEncryption = value; } 61 | 62 | /// 63 | /// Any operation in progress? 64 | /// 65 | public bool Busy => cancellationSource != null; 66 | 67 | [Title("Streams")] 68 | 69 | [SerializeField, Label("Buffer size (KB)"), Indent, Range(1, 256)] 70 | private int bufferSize = 32; 71 | 72 | [Title("Integrity")] 73 | 74 | [SerializeField, Label("Algorithm"), Indent] 75 | private FileIntegrity fileIntegrity = FileIntegrity.None; 76 | 77 | [Title("Compression")] 78 | 79 | [SerializeField, Label("Type"), Indent] 80 | private FileCompression fileCompression = FileCompression.None; 81 | 82 | [SerializeField, Label("Level"), Indent] 83 | private CompressionLevel compressionLevel = CompressionLevel.Fastest; 84 | 85 | [Title("Encryption")] 86 | 87 | [SerializeField, Label("Algorithm"), Indent] 88 | private FileEncryption fileEncryption = FileEncryption.None; 89 | 90 | [SerializeField, Indent, Password, OnlyEnableInEdit] 91 | private string password; 92 | 93 | [SerializeField, Indent, Password, OnlyEnableInEdit] 94 | private string seed; 95 | 96 | private CancellationTokenSource cancellationSource; 97 | 98 | private Action clientProgress; 99 | private float currentProgress; 100 | private int totalSteps; 101 | private int currentStep; 102 | 103 | /// 104 | /// When initialize. 105 | /// 106 | public void OnInitialize() 107 | { 108 | cancellationSource = null; 109 | 110 | Path = ComposePath(); 111 | } 112 | 113 | /// 114 | /// At the end of initialization. 115 | /// Called in the first Update frame. 116 | /// 117 | public void OnInitialized() 118 | { 119 | ResetProgress(null); 120 | } 121 | 122 | /// 123 | /// When deinitialize. 124 | /// 125 | public void OnDeinitialize() 126 | { 127 | Cancel(); 128 | } 129 | 130 | /// 131 | /// All files in the working path. 132 | /// 133 | /// Search pattern. 134 | /// Recursive search. 135 | /// List with information on each file. 136 | public List GetFilesInfo(string searchPattern = "*.*", bool recursive = false) 137 | { 138 | List files = new(); 139 | 140 | try 141 | { 142 | if (Directory.Exists(Path) == true) 143 | { 144 | string[] fileNames = Directory.GetFiles(Path, searchPattern, recursive == true ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly); 145 | for (int i = 0; i < fileNames.Length; ++i) 146 | files.Add(new FileInfo(fileNames[i])); 147 | } 148 | } 149 | catch (Exception e) 150 | { 151 | Log.Exception(e.ToString()); 152 | } 153 | 154 | return files; 155 | } 156 | 157 | /// 158 | /// Information about a file in the working directory. 159 | /// 160 | /// File name. 161 | /// File information or null if it does not exist. 162 | public FileInfo GetFileInfo(string fileName) 163 | { 164 | Check.IsNotNullOrEmpty(fileName); 165 | FileInfo fileInfo = null; 166 | 167 | try 168 | { 169 | fileInfo = new FileInfo(Path + fileName); 170 | } 171 | catch (Exception e) 172 | { 173 | Log.Exception(e.ToString()); 174 | } 175 | 176 | return fileInfo.Exists ? fileInfo : null; 177 | } 178 | 179 | /// 180 | /// Does the file exist in the working directory? 181 | /// 182 | /// File name. 183 | /// True / false. 184 | public bool Exists(string fileName) 185 | { 186 | Check.IsNotNullOrEmpty(fileName); 187 | bool exists = false; 188 | 189 | try 190 | { 191 | if (new FileInfo(Path + fileName).Exists == true) 192 | exists = true; 193 | } 194 | catch (Exception e) 195 | { 196 | Log.Exception(e.ToString()); 197 | } 198 | 199 | return exists; 200 | } 201 | 202 | /// 203 | /// Returns the following name for a file that is available, appending three digits if necessary. 204 | /// 205 | /// File name. 206 | /// Separator between name and digits. 207 | /// File name. 208 | public string NextAvailableName(string fileName, string separator = "") 209 | { 210 | string availableName = fileName; 211 | 212 | int index = 0; 213 | try 214 | { 215 | while (Exists(availableName) == true && index < 1000) 216 | { 217 | string name = System.IO.Path.GetFileNameWithoutExtension(fileName); 218 | string extension = System.IO.Path.GetExtension(fileName); 219 | 220 | availableName = $"{name}{separator}{index:000}{extension}"; 221 | index++; 222 | } 223 | } 224 | catch (Exception e) 225 | { 226 | Log.Exception(e.ToString()); 227 | } 228 | 229 | if (index == 1000) 230 | Log.Error($"Index limit reached for file '{fileName}'"); 231 | 232 | return availableName; 233 | } 234 | 235 | /// 236 | /// If it exists, cancels the current file operation. 237 | /// 238 | public void Cancel() => cancellationSource?.Cancel(); 239 | 240 | /// 241 | /// Deletes a file from the working path. 242 | /// 243 | /// 244 | public void Delete(string fileName) 245 | { 246 | Check.IsNotNullOrEmpty(fileName); 247 | 248 | if (Exists(fileName) == true) 249 | { 250 | try 251 | { 252 | File.Delete(Path + fileName); 253 | } 254 | catch (Exception e) 255 | { 256 | Log.Exception(e.ToString()); 257 | } 258 | } 259 | else 260 | Log.Warning($"File '{fileName}' not found"); 261 | } 262 | 263 | private IIntegrity CreateFileIntegrity(FileIntegrity fileIntegrity, CancellationToken cancellationToken) 264 | { 265 | IIntegrity integrity = fileIntegrity switch 266 | { 267 | FileIntegrity.None => new NullIntegrity(), 268 | FileIntegrity.MD5 => new MD5Integrity(bufferSize, cancellationToken), 269 | FileIntegrity.SHA1 => new SHA1Integrity(bufferSize, cancellationToken), 270 | FileIntegrity.SHA256 => new SHA256Integrity(bufferSize, cancellationToken), 271 | FileIntegrity.SHA512 => new SHA512Integrity(bufferSize, cancellationToken), 272 | _ => null 273 | }; 274 | Check.IsNotNull(integrity); 275 | 276 | return integrity; 277 | } 278 | 279 | private ICompressor CreateFileCompressor(FileCompression fileCompression, CancellationToken cancellationToken) 280 | { 281 | ICompressor compressor = fileCompression switch 282 | { 283 | FileCompression.None => new NullCompressor(), 284 | FileCompression.Zip => new ZipCompressor(bufferSize, compressionLevel, cancellationToken), 285 | FileCompression.GZip => new GZipCompressor(bufferSize, compressionLevel, cancellationToken), 286 | FileCompression.Brotli => new BrotliCompressor(bufferSize, compressionLevel, cancellationToken), 287 | _ => null 288 | }; 289 | Check.IsNotNull(compressor); 290 | 291 | return compressor; 292 | } 293 | 294 | private IEncryptor CreateFileEncryptor(FileEncryption fileEncryption, CancellationToken cancellationToken) 295 | { 296 | IEncryptor encryptor = fileEncryption switch 297 | { 298 | FileEncryption.None => new NullEncryptor(), 299 | FileEncryption.AES => new AESEncryptor(bufferSize, password, seed, cancellationToken), 300 | FileEncryption.RC2 => new RC2Encryptor(bufferSize, password, seed, cancellationToken), 301 | FileEncryption.DES => new DESEncryptor(bufferSize, password, seed, cancellationToken), 302 | FileEncryption.TripleDES => new TripleDESEncryptor(bufferSize, password, seed, cancellationToken), 303 | _ => null 304 | }; 305 | Check.IsNotNull(encryptor); 306 | 307 | return encryptor; 308 | } 309 | 310 | private static void AddSerializationSurrogates(IFormatter binaryFormatter) 311 | { 312 | SurrogateSelector surrogateSelector = new(); 313 | surrogateSelector.AddSurrogate(typeof(Bounds), new StreamingContext(StreamingContextStates.All), new BoundsSerializationSurrogate()); 314 | surrogateSelector.AddSurrogate(typeof(Rect), new StreamingContext(StreamingContextStates.All), new RectSerializationSurrogate()); 315 | surrogateSelector.AddSurrogate(typeof(LayerMask), new StreamingContext(StreamingContextStates.All), new LayerMaskSerializationSurrogate()); 316 | surrogateSelector.AddSurrogate(typeof(Color), new StreamingContext(StreamingContextStates.All), new ColorSerializationSurrogate()); 317 | surrogateSelector.AddSurrogate(typeof(Vector2Int), new StreamingContext(StreamingContextStates.All), new Vector2IntSerializationSurrogate()); 318 | surrogateSelector.AddSurrogate(typeof(Vector3Int), new StreamingContext(StreamingContextStates.All), new Vector2IntSerializationSurrogate()); 319 | surrogateSelector.AddSurrogate(typeof(Vector2), new StreamingContext(StreamingContextStates.All), new Vector2SerializationSurrogate()); 320 | surrogateSelector.AddSurrogate(typeof(Vector3), new StreamingContext(StreamingContextStates.All), new Vector3SerializationSurrogate()); 321 | surrogateSelector.AddSurrogate(typeof(Vector4), new StreamingContext(StreamingContextStates.All), new Vector4SerializationSurrogate()); 322 | surrogateSelector.AddSurrogate(typeof(Quaternion), new StreamingContext(StreamingContextStates.All), new QuaternionSerializationSurrogate()); 323 | surrogateSelector.AddSurrogate(typeof(Matrix4x4), new StreamingContext(StreamingContextStates.All), new Matrix4x4SerializationSurrogate()); 324 | 325 | binaryFormatter.SurrogateSelector = surrogateSelector; 326 | } 327 | 328 | private void CalculateProgress(float progress) 329 | { 330 | currentProgress = (progress + currentStep) / totalSteps; 331 | 332 | clientProgress?.Invoke(Mathf.Clamp01(currentProgress)); 333 | } 334 | 335 | private void ResetProgress(Action progress) 336 | { 337 | clientProgress = progress; 338 | currentProgress = 0.0f; 339 | currentStep = 0; 340 | totalSteps = 1; 341 | 342 | progress?.Invoke(0.0f); 343 | } 344 | 345 | private static string ComposePath() 346 | { 347 | string path = string.Empty; 348 | #if (UNITY_ANDROID || UNITY_IOS) 349 | path = $"{Application.persistentDataPath}/"; 350 | #elif UNITY_STANDALONE_OSX 351 | path = $"{Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)}/"; 352 | #elif UNITY_STANDALONE_WIN 353 | path = $"{Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)}/My Games/"; 354 | #else 355 | throw new NotSupportedException("platform not supported."); 356 | #endif 357 | 358 | if (string.IsNullOrEmpty(Application.companyName) == false) 359 | path += Application.companyName.RemoveInvalidFileCharacters(); 360 | 361 | if (string.IsNullOrEmpty(Application.productName) == false) 362 | path += "/" + Application.productName.RemoveInvalidFileCharacters(); 363 | 364 | path += "/"; 365 | path = path.Replace("\\", "/"); 366 | path = path.Replace("//", "/"); 367 | 368 | return path; 369 | } 370 | 371 | private bool CheckPath(string file) 372 | { 373 | bool success = false; 374 | try 375 | { 376 | string path = System.IO.Path.GetDirectoryName(file); 377 | if (Directory.Exists(path) == false) 378 | { 379 | Directory.CreateDirectory(path); 380 | 381 | success = true; 382 | } 383 | else 384 | success = true; 385 | } 386 | catch (Exception e) 387 | { 388 | Log.Exception(e.ToString()); 389 | } 390 | 391 | return success; 392 | } 393 | } 394 | } 395 | -------------------------------------------------------------------------------- /Runtime/LocalDataModule.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 70fac41f51b844543be1dc3745ced385 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/SerializationSurrogates.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2bd7379a3ec43c44abf0d09ac6e3e1c2 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/SerializationSurrogates/BoundsSerializationSurrogate.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System.Runtime.Serialization; 18 | using UnityEngine; 19 | 20 | namespace FronkonGames.GameWork.Modules.LocalData 21 | { 22 | /// 23 | /// Bounds serialization surrogate. 24 | /// 25 | public sealed class BoundsSerializationSurrogate : ISerializationSurrogate 26 | { 27 | public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) 28 | { 29 | Bounds bounds = (Bounds)obj; 30 | info.AddValue("c", bounds.center); 31 | info.AddValue("s", bounds.size); 32 | info.AddValue("x", bounds.extents); 33 | info.AddValue("i", bounds.min); 34 | info.AddValue("a", bounds.max); 35 | } 36 | 37 | public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) 38 | { 39 | Bounds bounds = (Bounds)obj; 40 | bounds.center = (Vector3)info.GetValue("c", typeof(Vector3)); 41 | bounds.size = (Vector3)info.GetValue("s", typeof(Vector3)); 42 | bounds.extents = (Vector3)info.GetValue("x", typeof(Vector3)); 43 | bounds.min = (Vector3)info.GetValue("i", typeof(Vector3)); 44 | bounds.max = (Vector3)info.GetValue("a", typeof(Vector3)); 45 | 46 | return bounds; 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /Runtime/SerializationSurrogates/BoundsSerializationSurrogate.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9cf430beff00ff443ab42b5f7ca116b0 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/SerializationSurrogates/ColorSerializationSurrogate.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System.Runtime.Serialization; 18 | using UnityEngine; 19 | 20 | namespace FronkonGames.GameWork.Modules.LocalData 21 | { 22 | /// 23 | /// Color serialization surrogate. 24 | /// 25 | public sealed class ColorSerializationSurrogate : ISerializationSurrogate 26 | { 27 | public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) 28 | { 29 | Color color = (Color)obj; 30 | info.AddValue("r", color.r); 31 | info.AddValue("g", color.b); 32 | info.AddValue("b", color.b); 33 | info.AddValue("a", color.a); 34 | } 35 | 36 | public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) 37 | { 38 | Color color = (Color)obj; 39 | color.r = info.GetSingle("r"); 40 | color.b = info.GetSingle("g"); 41 | color.b = info.GetSingle("b"); 42 | color.a = info.GetSingle("a"); 43 | 44 | return color; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /Runtime/SerializationSurrogates/ColorSerializationSurrogate.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6906071b1fcdd384196bfa25e9251e7d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/SerializationSurrogates/LayerMaskSerializationSurrogate.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System.Runtime.Serialization; 18 | using UnityEngine; 19 | 20 | namespace FronkonGames.GameWork.Modules.LocalData 21 | { 22 | /// 23 | /// LayerMask serialization surrogate. 24 | /// 25 | public sealed class LayerMaskSerializationSurrogate : ISerializationSurrogate 26 | { 27 | public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) 28 | { 29 | LayerMask layerMask = (LayerMask)obj; 30 | info.AddValue("m", layerMask.value); 31 | } 32 | 33 | public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) 34 | { 35 | LayerMask layerMask = (LayerMask)obj; 36 | layerMask.value = info.GetInt32("m"); 37 | 38 | return layerMask; 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /Runtime/SerializationSurrogates/LayerMaskSerializationSurrogate.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4ba0c35ae8d0b284ab0fc7812357acbb 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/SerializationSurrogates/Matrix4x4SerializationSurrogate.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System.Runtime.Serialization; 18 | using UnityEngine; 19 | 20 | namespace FronkonGames.GameWork.Modules.LocalData 21 | { 22 | /// 23 | /// Matrix4x4 serialization surrogate. 24 | /// 25 | public sealed class Matrix4x4SerializationSurrogate : ISerializationSurrogate 26 | { 27 | public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) 28 | { 29 | Matrix4x4 matrix4X4 = (Matrix4x4)obj; 30 | info.AddValue("00", matrix4X4.m00); 31 | info.AddValue("10", matrix4X4.m10); 32 | info.AddValue("20", matrix4X4.m20); 33 | info.AddValue("30", matrix4X4.m30); 34 | info.AddValue("01", matrix4X4.m01); 35 | info.AddValue("11", matrix4X4.m11); 36 | info.AddValue("21", matrix4X4.m21); 37 | info.AddValue("31", matrix4X4.m31); 38 | info.AddValue("02", matrix4X4.m02); 39 | info.AddValue("12", matrix4X4.m12); 40 | info.AddValue("22", matrix4X4.m22); 41 | info.AddValue("32", matrix4X4.m32); 42 | info.AddValue("03", matrix4X4.m03); 43 | info.AddValue("13", matrix4X4.m13); 44 | info.AddValue("23", matrix4X4.m23); 45 | info.AddValue("33", matrix4X4.m33); 46 | } 47 | 48 | public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) 49 | { 50 | Matrix4x4 matrix4X4 = (Matrix4x4)obj; 51 | matrix4X4.m00 = info.GetSingle("00"); 52 | matrix4X4.m10 = info.GetSingle("10"); 53 | matrix4X4.m20 = info.GetSingle("20"); 54 | matrix4X4.m30 = info.GetSingle("30"); 55 | matrix4X4.m01 = info.GetSingle("01"); 56 | matrix4X4.m11 = info.GetSingle("11"); 57 | matrix4X4.m21 = info.GetSingle("21"); 58 | matrix4X4.m31 = info.GetSingle("31"); 59 | matrix4X4.m02 = info.GetSingle("02"); 60 | matrix4X4.m12 = info.GetSingle("12"); 61 | matrix4X4.m22 = info.GetSingle("22"); 62 | matrix4X4.m32 = info.GetSingle("32"); 63 | matrix4X4.m03 = info.GetSingle("03"); 64 | matrix4X4.m13 = info.GetSingle("13"); 65 | matrix4X4.m23 = info.GetSingle("23"); 66 | matrix4X4.m33 = info.GetSingle("33"); 67 | 68 | return matrix4X4; 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /Runtime/SerializationSurrogates/Matrix4x4SerializationSurrogate.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 85caea7bb2e5b0249a6df1da60213ea4 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/SerializationSurrogates/QuaternionSerializationSurrogate.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System.Runtime.Serialization; 18 | using UnityEngine; 19 | 20 | namespace FronkonGames.GameWork.Modules.LocalData 21 | { 22 | /// 23 | /// Quaternion serialization surrogate. 24 | /// 25 | public sealed class QuaternionSerializationSurrogate : ISerializationSurrogate 26 | { 27 | public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) 28 | { 29 | Quaternion q = (Quaternion)obj; 30 | info.AddValue("x", q.x); 31 | info.AddValue("y", q.y); 32 | info.AddValue("z", q.z); 33 | info.AddValue("w", q.w); 34 | } 35 | 36 | public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) 37 | { 38 | Quaternion q = (Quaternion)obj; 39 | q.x = info.GetSingle("x"); 40 | q.y = info.GetSingle("y"); 41 | q.z = info.GetSingle("z"); 42 | q.w = info.GetSingle("w"); 43 | 44 | return q; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /Runtime/SerializationSurrogates/QuaternionSerializationSurrogate.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 060a70b7f387104418777895f88cb30e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/SerializationSurrogates/RectSerializationSurrogate.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System.Runtime.Serialization; 18 | using UnityEngine; 19 | 20 | namespace FronkonGames.GameWork.Modules.LocalData 21 | { 22 | /// 23 | /// Rect serialization surrogate. 24 | /// 25 | public sealed class RectSerializationSurrogate : ISerializationSurrogate 26 | { 27 | public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) 28 | { 29 | Rect rect = (Rect)obj; 30 | info.AddValue("x", rect.x); 31 | info.AddValue("y", rect.y); 32 | info.AddValue("w", rect.width); 33 | info.AddValue("h", rect.height); 34 | } 35 | 36 | public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) 37 | { 38 | Rect rect = (Rect)obj; 39 | rect.x = info.GetSingle("x"); 40 | rect.y = info.GetSingle("y"); 41 | rect.width = info.GetSingle("w"); 42 | rect.height = info.GetSingle("h"); 43 | 44 | return rect; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /Runtime/SerializationSurrogates/RectSerializationSurrogate.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 09eeaf57ffbaa614f9ff4580e08d8376 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/SerializationSurrogates/Vector2IntSerializationSurrogate.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System.Runtime.Serialization; 18 | using UnityEngine; 19 | 20 | namespace FronkonGames.GameWork.Modules.LocalData 21 | { 22 | /// 23 | /// Vector2Int serialization surrogate. 24 | /// 25 | public sealed class Vector2IntSerializationSurrogate : ISerializationSurrogate 26 | { 27 | public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) 28 | { 29 | Vector2Int v = (Vector2Int)obj; 30 | info.AddValue("x", v.x); 31 | info.AddValue("y", v.y); 32 | } 33 | 34 | public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) 35 | { 36 | Vector2Int v = (Vector2Int)obj; 37 | v.x = info.GetInt32("x"); 38 | v.y = info.GetInt32("y"); 39 | 40 | return v; 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /Runtime/SerializationSurrogates/Vector2IntSerializationSurrogate.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 68896239a5331bc40935cc2b00541e06 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/SerializationSurrogates/Vector2SerializationSurrogate.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System.Runtime.Serialization; 18 | using UnityEngine; 19 | 20 | namespace FronkonGames.GameWork.Modules.LocalData 21 | { 22 | /// 23 | /// Vector2 serialization surrogate. 24 | /// 25 | public sealed class Vector2SerializationSurrogate : ISerializationSurrogate 26 | { 27 | public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) 28 | { 29 | Vector2 v = (Vector2)obj; 30 | info.AddValue("x", v.x); 31 | info.AddValue("y", v.y); 32 | } 33 | 34 | public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) 35 | { 36 | Vector2 v = (Vector2)obj; 37 | v.x = info.GetSingle("x"); 38 | v.y = info.GetSingle("y"); 39 | 40 | return v; 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /Runtime/SerializationSurrogates/Vector2SerializationSurrogate.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: adf4ef88c462acf4e936bbbd93883c8e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/SerializationSurrogates/Vector3IntSerializationSurrogate.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System.Runtime.Serialization; 18 | using UnityEngine; 19 | 20 | namespace FronkonGames.GameWork.Modules.LocalData 21 | { 22 | /// 23 | /// Vector3Int serialization surrogate. 24 | /// 25 | public sealed class Vector3IntSerializationSurrogate : ISerializationSurrogate 26 | { 27 | public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) 28 | { 29 | Vector3Int v = (Vector3Int)obj; 30 | info.AddValue("x", v.x); 31 | info.AddValue("y", v.y); 32 | info.AddValue("z", v.z); 33 | } 34 | 35 | public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) 36 | { 37 | Vector3Int v = (Vector3Int)obj; 38 | v.x = info.GetInt32("x"); 39 | v.y = info.GetInt32("y"); 40 | v.z = info.GetInt32("z"); 41 | 42 | return v; 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /Runtime/SerializationSurrogates/Vector3IntSerializationSurrogate.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f4ea840db32ed08429498c68d770f2e6 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/SerializationSurrogates/Vector3SerializationSurrogate.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System.Runtime.Serialization; 18 | using UnityEngine; 19 | 20 | namespace FronkonGames.GameWork.Modules.LocalData 21 | { 22 | /// 23 | /// Vector3 serialization surrogate. 24 | /// 25 | public sealed class Vector3SerializationSurrogate : ISerializationSurrogate 26 | { 27 | public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) 28 | { 29 | Vector3 v = (Vector3)obj; 30 | info.AddValue("x", v.x); 31 | info.AddValue("y", v.y); 32 | info.AddValue("z", v.z); 33 | } 34 | 35 | public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) 36 | { 37 | Vector3 v = (Vector3)obj; 38 | v.x = info.GetSingle("x"); 39 | v.y = info.GetSingle("y"); 40 | v.z = info.GetSingle("z"); 41 | 42 | return v; 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /Runtime/SerializationSurrogates/Vector3SerializationSurrogate.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 93dce3f3876077f458b1d27fe54bd0bb 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/SerializationSurrogates/Vector4SerializationSurrogate.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System.Runtime.Serialization; 18 | using UnityEngine; 19 | 20 | namespace FronkonGames.GameWork.Modules.LocalData 21 | { 22 | /// 23 | /// Vector4 serialization surrogate. 24 | /// 25 | public sealed class Vector4SerializationSurrogate : ISerializationSurrogate 26 | { 27 | public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) 28 | { 29 | Vector4 v = (Vector4)obj; 30 | info.AddValue("x", v.x); 31 | info.AddValue("y", v.y); 32 | info.AddValue("z", v.z); 33 | info.AddValue("w", v.w); 34 | } 35 | 36 | public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) 37 | { 38 | Vector4 v = (Vector4)obj; 39 | v.x = info.GetSingle("x"); 40 | v.y = info.GetSingle("y"); 41 | v.z = info.GetSingle("z"); 42 | v.w = info.GetSingle("w"); 43 | 44 | return v; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /Runtime/SerializationSurrogates/Vector4SerializationSurrogate.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3356790274400c04c9f68ba4c9d35ded 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Test.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7af7213a78fb9524f9ef3625edf47318 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Test/FronkonGames.GameWork.Modules.LocalData.test.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "FronkonGames.GameWork.Modules.LocalData.test", 3 | "references": [ 4 | "FronkonGames.GameWork.Modules.LocalData", 5 | "FronkonGames.GameWork.Core", 6 | "FronkonGames.GameWork.Foundation" 7 | ], 8 | "optionalUnityReferences": [ "TestAssemblies" ], 9 | "includePlatforms": [ "Editor" ], 10 | "excludePlatforms": [], 11 | "allowUnsafeCode": false 12 | } -------------------------------------------------------------------------------- /Test/FronkonGames.GameWork.Modules.LocalData.test.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 13a9d84fb6700084baef8fdb9f63b028 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Test/LocalData.Compression.Test.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System.Collections; 18 | using UnityEngine.TestTools; 19 | using FronkonGames.GameWork.Modules.LocalData; 20 | using UnityEngine; 21 | 22 | /// 23 | /// Local Data tests. 24 | /// 25 | public partial class LocalDataTests 26 | { 27 | /// 28 | /// Compression test. 29 | /// 30 | [UnityTest] 31 | public IEnumerator Compression() 32 | { 33 | GameObject gameObject = new(); 34 | LocalDataModule localDataModule = gameObject.AddComponent(); 35 | localDataModule.OnInitialize(); 36 | localDataModule.OnInitialized(); 37 | 38 | yield return WriteTest(localDataModule, FileIntegrity.None, FileCompression.Zip, FileEncryption.None); 39 | yield return ReadTest(localDataModule); 40 | IntegrityTest(); 41 | DeleteTest(localDataModule); 42 | 43 | yield return WriteTest(localDataModule, FileIntegrity.None, FileCompression.GZip, FileEncryption.None); 44 | yield return ReadTest(localDataModule); 45 | IntegrityTest(); 46 | DeleteTest(localDataModule); 47 | 48 | yield return WriteTest(localDataModule, FileIntegrity.None, FileCompression.Brotli, FileEncryption.None); 49 | yield return ReadTest(localDataModule); 50 | IntegrityTest(); 51 | DeleteTest(localDataModule); 52 | 53 | localDataModule.OnDeinitialize(); 54 | GameObject.DestroyImmediate(gameObject); 55 | 56 | yield return null; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Test/LocalData.Compression.Test.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4981192f80a4d76428c616365e5da781 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Test/LocalData.Encryption.Test.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System.Collections; 18 | using UnityEngine.TestTools; 19 | using FronkonGames.GameWork.Modules.LocalData; 20 | using UnityEngine; 21 | 22 | /// 23 | /// Local Data tests. 24 | /// 25 | public partial class LocalDataTests 26 | { 27 | /// 28 | /// Encryption test. 29 | /// 30 | [UnityTest] 31 | public IEnumerator Encryption() 32 | { 33 | GameObject gameObject = new(); 34 | LocalDataModule localDataModule = gameObject.AddComponent(); 35 | localDataModule.OnInitialize(); 36 | localDataModule.OnInitialized(); 37 | 38 | SetPassword(localDataModule, "0123456789012345", "0123456789012345"); 39 | 40 | yield return WriteTest(localDataModule, FileIntegrity.None, FileCompression.None, FileEncryption.AES); 41 | yield return ReadTest(localDataModule); 42 | IntegrityTest(); 43 | DeleteTest(localDataModule); 44 | 45 | yield return WriteTest(localDataModule, FileIntegrity.None, FileCompression.None, FileEncryption.TripleDES); 46 | yield return ReadTest(localDataModule); 47 | IntegrityTest(); 48 | DeleteTest(localDataModule); 49 | 50 | yield return WriteTest(localDataModule, FileIntegrity.None, FileCompression.None, FileEncryption.RC2); 51 | yield return ReadTest(localDataModule); 52 | IntegrityTest(); 53 | DeleteTest(localDataModule); 54 | 55 | SetPassword(localDataModule, "01234567", "01234567890"); 56 | 57 | yield return WriteTest(localDataModule, FileIntegrity.None, FileCompression.None, FileEncryption.DES); 58 | yield return ReadTest(localDataModule); 59 | IntegrityTest(); 60 | DeleteTest(localDataModule); 61 | 62 | localDataModule.OnDeinitialize(); 63 | GameObject.DestroyImmediate(gameObject); 64 | 65 | yield return null; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Test/LocalData.Encryption.Test.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ac0c8a98b2297404c8d4e3a7c4ac3691 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Test/LocalData.Integrity.Test.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System.Collections; 18 | using UnityEngine.TestTools; 19 | using FronkonGames.GameWork.Modules.LocalData; 20 | using UnityEngine; 21 | 22 | /// 23 | /// Local Data tests. 24 | /// 25 | public partial class LocalDataTests 26 | { 27 | /// 28 | /// Integrity test. 29 | /// 30 | [UnityTest] 31 | public IEnumerator Integrity() 32 | { 33 | GameObject gameObject = new(); 34 | LocalDataModule localDataModule = gameObject.AddComponent(); 35 | localDataModule.OnInitialize(); 36 | localDataModule.OnInitialized(); 37 | 38 | yield return WriteTest(localDataModule, FileIntegrity.MD5, FileCompression.None, FileEncryption.None); 39 | yield return ReadTest(localDataModule); 40 | IntegrityTest(); 41 | DeleteTest(localDataModule); 42 | 43 | yield return WriteTest(localDataModule, FileIntegrity.SHA1, FileCompression.None, FileEncryption.None); 44 | yield return ReadTest(localDataModule); 45 | IntegrityTest(); 46 | DeleteTest(localDataModule); 47 | 48 | yield return WriteTest(localDataModule, FileIntegrity.SHA256, FileCompression.None, FileEncryption.None); 49 | yield return ReadTest(localDataModule); 50 | IntegrityTest(); 51 | DeleteTest(localDataModule); 52 | 53 | yield return WriteTest(localDataModule, FileIntegrity.SHA512, FileCompression.None, FileEncryption.None); 54 | yield return ReadTest(localDataModule); 55 | IntegrityTest(); 56 | DeleteTest(localDataModule); 57 | 58 | localDataModule.OnDeinitialize(); 59 | GameObject.DestroyImmediate(gameObject); 60 | 61 | yield return null; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Test/LocalData.Integrity.Test.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f41f28f19ea219b499dd3d1339336a25 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Test/LocalData.WriteRead.Test.cs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Copyright (c) Martin Bustos @FronkonGames 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 5 | // documentation files (the "Software"), to deal in the Software without restriction, including without limitation the 6 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | // permit persons to whom the Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of 10 | // the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 13 | // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 14 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 15 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 16 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 17 | using System; 18 | using System.Collections; 19 | using System.Reflection; 20 | using System.Runtime.ExceptionServices; 21 | using System.Threading.Tasks; 22 | using NUnit.Framework; 23 | using UnityEngine.TestTools; 24 | using FronkonGames.GameWork.Modules.LocalData; 25 | using UnityEngine; 26 | 27 | /// 28 | /// Local Data tests. 29 | /// 30 | public partial class LocalDataTests 31 | { 32 | [Serializable] 33 | private class TestLocalFile : LocalData 34 | { 35 | public bool boolValue = false; 36 | 37 | public byte byteValue = 10; 38 | public sbyte sbyteValue = 20; 39 | 40 | public char charValue = 'M'; 41 | 42 | public string stringValue = "All your base are belong to us"; 43 | 44 | public short shortValue = 30; 45 | public ushort ushortValue = 40; 46 | 47 | public int intValue = 50; 48 | public uint uintValue = 60; 49 | 50 | public long longValue = 70; 51 | public ulong ulongValue = 80; 52 | 53 | public float floatValue = Mathf.PI; 54 | public double doubleValue = Math.PI; 55 | public decimal decimalValue = decimal.One; 56 | 57 | public DateTime dateTimeValue = DateTime.Now; 58 | 59 | public Vector2 vector2 = Vector2.down; 60 | public Vector3 vector3 = Vector3.up; 61 | public Vector4 vector4 = Vector4.zero; 62 | public Color color = Color.magenta; 63 | } 64 | 65 | private const string fileName = "test.data"; 66 | 67 | private TestLocalFile localFile; 68 | 69 | /// 70 | /// Write / Read test. 71 | /// 72 | [UnityTest] 73 | public IEnumerator WriteRead() 74 | { 75 | GameObject gameObject = new(); 76 | LocalDataModule localDataModule = gameObject.AddComponent(); 77 | localDataModule.OnInitialize(); 78 | localDataModule.OnInitialized(); 79 | 80 | yield return WriteTest(localDataModule, FileIntegrity.None, FileCompression.None, FileEncryption.None); 81 | yield return ReadTest(localDataModule); 82 | IntegrityTest(); 83 | DeleteTest(localDataModule); 84 | 85 | localDataModule.OnDeinitialize(); 86 | GameObject.DestroyImmediate(gameObject); 87 | 88 | yield return null; 89 | } 90 | 91 | private IEnumerator WriteTest(LocalDataModule localDataModule, FileIntegrity integrity, FileCompression compression, FileEncryption encryption) 92 | { 93 | float progress = 0.0f; 94 | FileResult fileResult = FileResult.Cancelled; 95 | 96 | localDataModule.Integrity = integrity; 97 | localDataModule.Compression = compression; 98 | localDataModule.Encryption = encryption; 99 | 100 | Task task = localDataModule.Write(new TestLocalFile(), fileName, (value) => progress = value, (value) => fileResult = value); 101 | yield return AsIEnumeratorReturnNull(task); 102 | 103 | Assert.IsTrue(localDataModule.Exists(fileName)); 104 | Assert.AreEqual(progress, 1.0f); 105 | Assert.IsTrue(fileResult == FileResult.Ok); 106 | 107 | yield return null; 108 | } 109 | 110 | private IEnumerator ReadTest(LocalDataModule localDataModule) 111 | { 112 | float progress = 0.0f; 113 | FileResult fileResult = FileResult.Cancelled; 114 | localFile = null; 115 | 116 | Task task = localDataModule.Read(fileName, (value) => progress = value, (result, value) => 117 | { 118 | fileResult = result; 119 | localFile = value; 120 | }); 121 | yield return AsIEnumeratorReturnNull(task); 122 | 123 | Assert.IsTrue(localDataModule.Exists(fileName)); 124 | Assert.AreEqual(progress, 1.0f); 125 | Assert.IsTrue(fileResult == FileResult.Ok); 126 | Assert.IsNotNull(localFile); 127 | 128 | yield return null; 129 | } 130 | 131 | private void IntegrityTest() 132 | { 133 | Assert.IsNotNull(localFile); 134 | 135 | Assert.AreEqual(localFile.boolValue, false); 136 | Assert.AreEqual(localFile.byteValue, 10); 137 | Assert.AreEqual(localFile.sbyteValue, 20); 138 | Assert.AreEqual(localFile.charValue, 'M'); 139 | Assert.AreEqual(localFile.stringValue, "All your base are belong to us"); 140 | Assert.AreEqual(localFile.shortValue, 30); 141 | Assert.AreEqual(localFile.ushortValue, 40); 142 | Assert.AreEqual(localFile.intValue, 50); 143 | Assert.AreEqual(localFile.uintValue, 60); 144 | Assert.AreEqual(localFile.longValue, 70); 145 | Assert.AreEqual(localFile.ulongValue, 80); 146 | Assert.AreEqual(localFile.floatValue, Mathf.PI); 147 | Assert.AreEqual(localFile.doubleValue, Math.PI); 148 | Assert.AreEqual(localFile.decimalValue, decimal.One); 149 | Assert.AreEqual(localFile.dateTimeValue.DayOfWeek, DateTime.Now.DayOfWeek); 150 | Assert.AreEqual(localFile.vector2, Vector2.down); 151 | Assert.AreEqual(localFile.vector3, Vector3.up); 152 | Assert.AreEqual(localFile.vector4, Vector4.zero); 153 | Assert.AreEqual(localFile.color, Color.magenta); 154 | } 155 | 156 | private static void DeleteTest(LocalDataModule localDataModule) 157 | { 158 | localDataModule.Delete(fileName); 159 | Assert.IsFalse(localDataModule.Exists(fileName)); 160 | } 161 | 162 | private static void SetPassword(LocalDataModule localDataModule, string password, string seed) 163 | { 164 | // @HACK: Set password and seed. 165 | FieldInfo[] fields = localDataModule.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance); 166 | for (int i = 0; i < fields.Length; ++i) 167 | { 168 | if (fields[i].Name == "password") 169 | fields[i].SetValue(localDataModule, password); 170 | else if (fields[i].Name == "seed") 171 | fields[i].SetValue(localDataModule, seed); 172 | } 173 | } 174 | 175 | private static IEnumerator AsIEnumeratorReturnNull(Task task) 176 | { 177 | while (task.IsCompleted == false) 178 | yield return null; 179 | 180 | if (task.IsFaulted == true) 181 | ExceptionDispatchInfo.Capture(task.Exception).Throw(); 182 | 183 | yield return null; 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /Test/LocalData.WriteRead.Test.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4511141956b639b41828594e4726a87c 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /docs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b557eefe338f01541b22341282e084c5 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /docs/Animation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FronkonGames/GameWork-Local-Data/8b501ab8572148861ed37b19619a733ddda585a6/docs/Animation.gif -------------------------------------------------------------------------------- /docs/Animation.gif.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c5d98eb2f0eda11429e435514ee481a0 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 11 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | ignoreMasterTextureLimit: 0 28 | grayScaleToAlpha: 0 29 | generateCubemap: 6 30 | cubemapConvolution: 0 31 | seamlessCubemap: 0 32 | textureFormat: 1 33 | maxTextureSize: 2048 34 | textureSettings: 35 | serializedVersion: 2 36 | filterMode: 1 37 | aniso: 1 38 | mipBias: 0 39 | wrapU: 0 40 | wrapV: 0 41 | wrapW: 0 42 | nPOTScale: 1 43 | lightmap: 0 44 | compressionQuality: 50 45 | spriteMode: 0 46 | spriteExtrude: 1 47 | spriteMeshType: 1 48 | alignment: 0 49 | spritePivot: {x: 0.5, y: 0.5} 50 | spritePixelsToUnits: 100 51 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 52 | spriteGenerateFallbackPhysicsShape: 1 53 | alphaUsage: 1 54 | alphaIsTransparency: 0 55 | spriteTessellationDetail: -1 56 | textureType: 0 57 | textureShape: 1 58 | singleChannelComponent: 0 59 | flipbookRows: 1 60 | flipbookColumns: 1 61 | maxTextureSizeSet: 0 62 | compressionQualitySet: 0 63 | textureFormatSet: 0 64 | ignorePngGamma: 0 65 | applyGammaDecoding: 0 66 | platformSettings: 67 | - serializedVersion: 3 68 | buildTarget: DefaultTexturePlatform 69 | maxTextureSize: 2048 70 | resizeAlgorithm: 0 71 | textureFormat: -1 72 | textureCompression: 1 73 | compressionQuality: 50 74 | crunchedCompression: 0 75 | allowsAlphaSplitting: 0 76 | overridden: 0 77 | androidETC2FallbackOverride: 0 78 | forceMaximumCompressionQuality_BC6H_BC7: 0 79 | spriteSheet: 80 | serializedVersion: 2 81 | sprites: [] 82 | outline: [] 83 | physicsShape: [] 84 | bones: [] 85 | spriteID: 86 | internalID: 0 87 | vertices: [] 88 | indices: 89 | edges: [] 90 | weights: [] 91 | secondaryTextures: [] 92 | nameFileIdTable: {} 93 | spritePackingTag: 94 | pSDRemoveMatte: 0 95 | pSDShowRemoveMatteOption: 0 96 | userData: 97 | assetBundleName: 98 | assetBundleVariant: 99 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | GAME:WORK LOCAL DATA MODULE 2 | =========================== 3 | 4 | **Table of contents** 5 | 6 | - `Introduction`_ 7 | - `Requirements`_ 8 | - `Installation`_ 9 | * `Editing your 'manifest.json'`_ 10 | * `Git`_ 11 | - `License`_ 12 | 13 | Introduction 14 | ------------ 15 | 16 | '**Local Data**' is a module of '**Game:Work**' dedicated to read and write local files asynchronously. It has these 17 | features: 18 | 19 | 🔀 Fully asynchronous read, load and cancel. 20 | 🧬 Integrity check using MD5, SHA-1, SHA-256 or SHA-512 algorithms. 21 | 🗜️ Compression / decompression using algorithms: GZip, Zip or Brotli. 22 | 🔒 Encryption / decryption using algorithms: AES, DES, RC2, DES or TripleDES. 23 | 👌 Supports typical Unity data such as: Vector, Quaternion, Color, etc. 24 | 25 | Requirements 26 | ------------ 27 | 28 | - Unity 2020.3 or higher. 29 | - [Game:Work Core](https://github.com/FronkonGames/GameWork-Core). 30 | - [Game:Work Foundation](https://github.com/FronkonGames/GameWork-Foundation). 31 | - Test Framework 1.1.31 or higher. 32 | 33 | Installation 34 | ------------ 35 | 36 | Editing your 'manifest.json' 37 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 38 | 39 | - Open the manifest.json file of your Unity project. 40 | - In the section "dependencies" add: 41 | 42 | ```c# 43 | { 44 | ... 45 | "dependencies": 46 | { 47 | ... 48 | "FronkonGames.GameWork.Modules.LocalData": "git+https://github.com/FronkonGames/GameWork-Local-Data.git", 49 | "FronkonGames.GameWork.Core": "git+https://github.com/FronkonGames/GameWork-Core.git", 50 | "FronkonGames.GameWork.Foundation": "git+https://github.com/FronkonGames/GameWork-Foundation.git" 51 | } 52 | ... 53 | } 54 | ``` 55 | 56 | Git 57 | ^^^ 58 | 59 | First clone the dependencies inside your Assets folder: 60 | 61 | ``` 62 | git clone https://github.com/FronkonGames/GameWork-Foundation.git 63 | 64 | git clone https://github.com/FronkonGames/GameWork-Core.git 65 | ``` 66 | 67 | Then clone the repository: 68 | 69 | ``` 70 | git clone https://github.com/FronkonGames/GameWork-Local-Data.git 71 | ``` 72 | 73 | 74 | License 75 | ------- 76 | 77 | `MIT `_ -------------------------------------------------------------------------------- /docs/index.rst.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 680339de592c6e847b8e173073b90804 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.frokongames.gamework.modules.localdata", 3 | "version": "0.9.1", 4 | "displayName": "Game:Work Local Data", 5 | "decription": "Async load/save local data with compression, encryption and integrity check.", 6 | "references": [ ], 7 | "unity": "2020.3", 8 | "unityRelease": "26f1", 9 | "optionalUnityReferences": [], 10 | "includePlatforms": [], 11 | "excludePlatforms": [], 12 | "allowUnsafeCode": false, 13 | "overrideReferences": false, 14 | "precompiledReferences": [], 15 | "autoReferenced": true, 16 | "defineConstraints": [], 17 | "dependencies": { }, 18 | "keywords": [ "unity", "gamedev", "framework", "game development", "gamework", "module", "save", "async", "compression", "emcryption", "integrity", "zip", "AES" ], 19 | "category": "Unity", 20 | "repository": 21 | { 22 | "type": "git", 23 | "url": "git+https://github.com/FronkonGames/GameWork-Local-Data.git" 24 | }, 25 | "author": 26 | { 27 | "name": "Martin Bustos", 28 | "email": "fronkongames@gmail.com", 29 | "url": "https://fronkongames.github.io/" 30 | } 31 | } -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fa0abcd75afb3524ba1fa3faed6bc4f3 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | --------------------------------------------------------------------------------