com.backnd.database 0.0.9 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Client.cs +47 -5
- package/Editor/PackageAssetInstaller.cs +16 -33
- package/Internal/NullableHelper.cs +45 -0
- package/Internal/NullableHelper.cs.meta +11 -0
- package/link.xml +6 -0
- package/link.xml.meta +7 -0
- package/package.json +2 -2
package/Client.cs
CHANGED
|
@@ -2,6 +2,7 @@ using System;
|
|
|
2
2
|
using System.Collections.Generic;
|
|
3
3
|
using System.Linq;
|
|
4
4
|
using System.Text;
|
|
5
|
+
using System.Text.RegularExpressions;
|
|
5
6
|
using System.Threading;
|
|
6
7
|
|
|
7
8
|
using BACKND.Database.Exceptions;
|
|
@@ -19,6 +20,12 @@ namespace BACKND.Database
|
|
|
19
20
|
|
|
20
21
|
private readonly Dictionary<Type, bool> createdTables = new Dictionary<Type, bool>();
|
|
21
22
|
|
|
23
|
+
// HTTP 헤더 유효성 검사용 정규식 (RFC 7230 준수)
|
|
24
|
+
// 헤더 키: 토큰 형식 (영문자, 숫자, !#$%&'*+-.^_`|~)
|
|
25
|
+
private static readonly Regex ValidHeaderKeyRegex = new Regex(@"^[A-Za-z0-9!\#\$%&'\*\+\-\.\^_`\|~]+$", RegexOptions.Compiled);
|
|
26
|
+
// 헤더 값: ASCII 인쇄 가능 문자만 허용 (32~126)
|
|
27
|
+
private static readonly Regex ValidHeaderValueRegex = new Regex(@"^[\x20-\x7E]*$", RegexOptions.Compiled);
|
|
28
|
+
|
|
22
29
|
private readonly Queue<QueuedRequest> requestQueue = new Queue<QueuedRequest>();
|
|
23
30
|
private readonly Queue<QueuedRequest> highPriorityQueue = new Queue<QueuedRequest>();
|
|
24
31
|
private readonly object queueLock = new object();
|
|
@@ -28,11 +35,37 @@ namespace BACKND.Database
|
|
|
28
35
|
|
|
29
36
|
public Client(string uuid)
|
|
30
37
|
{
|
|
31
|
-
|
|
38
|
+
SetHeader("database_uuid", uuid);
|
|
32
39
|
|
|
33
40
|
this.queueCancellationSource = new CancellationTokenSource();
|
|
34
41
|
}
|
|
35
42
|
|
|
43
|
+
private static bool IsValidHeaderKey(string key)
|
|
44
|
+
{
|
|
45
|
+
return !string.IsNullOrEmpty(key) && ValidHeaderKeyRegex.IsMatch(key);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private static bool IsValidHeaderValue(string value)
|
|
49
|
+
{
|
|
50
|
+
return string.IsNullOrEmpty(value) || ValidHeaderValueRegex.IsMatch(value);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private bool SetHeader(string key, string value)
|
|
54
|
+
{
|
|
55
|
+
if (!IsValidHeaderKey(key))
|
|
56
|
+
{
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (!IsValidHeaderValue(value))
|
|
61
|
+
{
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
headers[key] = value;
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
|
|
36
69
|
public async BTask Initialize()
|
|
37
70
|
{
|
|
38
71
|
if (initialized)
|
|
@@ -48,15 +81,24 @@ namespace BACKND.Database
|
|
|
48
81
|
}
|
|
49
82
|
|
|
50
83
|
var json = Newtonsoft.Json.Linq.JObject.Parse(userInfoResult.ReturnValue);
|
|
51
|
-
|
|
84
|
+
var gamerId = json["row"]["gamerId"]?.ToString();
|
|
85
|
+
if (!SetHeader("x-gamerid", gamerId))
|
|
86
|
+
{
|
|
87
|
+
UnityEngine.Debug.LogError("please check backnd login state - invalid gamerId");
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
52
90
|
|
|
53
91
|
var settings = BackEnd.Backend.GetBackndChatSettings();
|
|
54
92
|
foreach (var header in settings)
|
|
55
93
|
{
|
|
56
|
-
headers
|
|
57
|
-
|
|
94
|
+
if (headers.ContainsKey(header.Key) && !string.IsNullOrEmpty(headers[header.Key]))
|
|
95
|
+
continue;
|
|
58
96
|
|
|
59
|
-
|
|
97
|
+
if (string.IsNullOrEmpty(header.Value))
|
|
98
|
+
continue;
|
|
99
|
+
|
|
100
|
+
SetHeader(header.Key, header.Value);
|
|
101
|
+
}
|
|
60
102
|
|
|
61
103
|
StartQueueProcessing();
|
|
62
104
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
using UnityEngine;
|
|
2
2
|
using UnityEditor;
|
|
3
|
-
using UnityEditor.PackageManager;
|
|
4
3
|
using UnityEditor.Build;
|
|
4
|
+
|
|
5
5
|
using System.IO;
|
|
6
6
|
|
|
7
7
|
namespace BACKND.Database.Editor
|
|
@@ -23,24 +23,20 @@ namespace BACKND.Database.Editor
|
|
|
23
23
|
{
|
|
24
24
|
string targetPath = Path.Combine("Assets", TargetFolderName);
|
|
25
25
|
|
|
26
|
-
// 이미 설치 완료된 경우
|
|
27
26
|
if (IsAlreadyInstalled(targetPath))
|
|
28
27
|
{
|
|
29
|
-
// 파일은 있지만 심볼이 없는 경우 심볼만 추가
|
|
30
28
|
EnsureScriptingDefineSymbol();
|
|
31
29
|
return;
|
|
32
30
|
}
|
|
33
31
|
|
|
34
|
-
// 패키지 경로에서 소스 폴더 찾기
|
|
35
32
|
string sourcePath = FindSourcePath();
|
|
36
33
|
|
|
37
34
|
if (string.IsNullOrEmpty(sourcePath))
|
|
38
35
|
{
|
|
39
|
-
Debug.LogWarning("[BACKND Database]
|
|
36
|
+
Debug.LogWarning("[BACKND Database] Could not find TheBackend~ folder.");
|
|
40
37
|
return;
|
|
41
38
|
}
|
|
42
39
|
|
|
43
|
-
// 자동 설치
|
|
44
40
|
InstallAssets(sourcePath, targetPath);
|
|
45
41
|
}
|
|
46
42
|
|
|
@@ -85,12 +81,9 @@ namespace BACKND.Database.Editor
|
|
|
85
81
|
|
|
86
82
|
private static string FindSourcePath()
|
|
87
83
|
{
|
|
88
|
-
// 1. PackageInfo API를 사용하여 패키지 경로 찾기 (npm 패키지로 설치된 경우)
|
|
89
|
-
// Unity 공식 권장 방식: PackageInfo.FindForPackageName() + resolvedPath
|
|
90
84
|
var packageInfo = UnityEditor.PackageManager.PackageInfo.FindForPackageName(PackageName);
|
|
91
85
|
if (packageInfo != null)
|
|
92
86
|
{
|
|
93
|
-
// resolvedPath = 실제 디스크 경로 (예: Library/PackageCache/com.backnd.database@0.0.1)
|
|
94
87
|
string packageSourcePath = Path.Combine(packageInfo.resolvedPath, SourceFolderName);
|
|
95
88
|
if (Directory.Exists(packageSourcePath))
|
|
96
89
|
{
|
|
@@ -98,7 +91,6 @@ namespace BACKND.Database.Editor
|
|
|
98
91
|
}
|
|
99
92
|
}
|
|
100
93
|
|
|
101
|
-
// 2. Assets 폴더에서 찾기 (개발 중인 경우)
|
|
102
94
|
string assetsSourcePath = Path.Combine("Assets", "BACKND", "Database", SourceFolderName);
|
|
103
95
|
if (Directory.Exists(assetsSourcePath))
|
|
104
96
|
{
|
|
@@ -112,37 +104,34 @@ namespace BACKND.Database.Editor
|
|
|
112
104
|
{
|
|
113
105
|
try
|
|
114
106
|
{
|
|
115
|
-
EditorUtility.DisplayProgressBar("BACKND Database", "
|
|
107
|
+
EditorUtility.DisplayProgressBar("BACKND Database", "Installing plugins...", 0f);
|
|
116
108
|
|
|
117
|
-
// 대상 폴더 생성
|
|
118
109
|
if (!Directory.Exists(targetPath))
|
|
119
110
|
{
|
|
120
111
|
Directory.CreateDirectory(targetPath);
|
|
121
112
|
}
|
|
122
113
|
|
|
123
|
-
// 재귀적으로 복사
|
|
124
114
|
CopyDirectory(sourcePath, targetPath);
|
|
125
115
|
|
|
126
|
-
EditorUtility.DisplayProgressBar("BACKND Database", "
|
|
116
|
+
EditorUtility.DisplayProgressBar("BACKND Database", "Refreshing asset database...", 0.9f);
|
|
127
117
|
|
|
128
118
|
AssetDatabase.Refresh();
|
|
129
119
|
|
|
130
|
-
// 스크립팅 심볼 추가 (BACKND.Database 어셈블리 컴파일 활성화)
|
|
131
120
|
AddScriptingDefineSymbol();
|
|
132
121
|
|
|
133
122
|
EditorUtility.ClearProgressBar();
|
|
134
123
|
|
|
135
|
-
Debug.Log($"[BACKND Database]
|
|
124
|
+
Debug.Log($"[BACKND Database] Plugin installed successfully: {targetPath}");
|
|
136
125
|
}
|
|
137
126
|
catch (System.Exception e)
|
|
138
127
|
{
|
|
139
128
|
EditorUtility.ClearProgressBar();
|
|
140
|
-
Debug.LogError($"[BACKND Database]
|
|
129
|
+
Debug.LogError($"[BACKND Database] Plugin installation failed: {e.Message}");
|
|
141
130
|
|
|
142
131
|
EditorUtility.DisplayDialog(
|
|
143
132
|
"BACKND Database",
|
|
144
|
-
$"
|
|
145
|
-
"
|
|
133
|
+
$"An error occurred during plugin installation.\n\n{e.Message}",
|
|
134
|
+
"OK"
|
|
146
135
|
);
|
|
147
136
|
}
|
|
148
137
|
}
|
|
@@ -164,7 +153,7 @@ namespace BACKND.Database.Editor
|
|
|
164
153
|
}
|
|
165
154
|
|
|
166
155
|
PlayerSettings.SetScriptingDefineSymbols(buildTarget, defines);
|
|
167
|
-
Debug.Log($"[BACKND Database]
|
|
156
|
+
Debug.Log($"[BACKND Database] Scripting define symbol added: {DefineSymbol}");
|
|
168
157
|
}
|
|
169
158
|
}
|
|
170
159
|
|
|
@@ -172,10 +161,8 @@ namespace BACKND.Database.Editor
|
|
|
172
161
|
{
|
|
173
162
|
var dir = new DirectoryInfo(sourceDir);
|
|
174
163
|
|
|
175
|
-
// 하위 폴더 복사
|
|
176
164
|
foreach (var subDir in dir.GetDirectories())
|
|
177
165
|
{
|
|
178
|
-
// 숨김 폴더 제외
|
|
179
166
|
if (subDir.Name.StartsWith("."))
|
|
180
167
|
continue;
|
|
181
168
|
|
|
@@ -184,16 +171,13 @@ namespace BACKND.Database.Editor
|
|
|
184
171
|
CopyDirectory(subDir.FullName, targetSubDir);
|
|
185
172
|
}
|
|
186
173
|
|
|
187
|
-
// 파일 복사
|
|
188
174
|
foreach (var file in dir.GetFiles())
|
|
189
175
|
{
|
|
190
|
-
// 숨김 파일 및 .meta 파일 제외
|
|
191
176
|
if (file.Name.StartsWith(".") || file.Extension == ".meta")
|
|
192
177
|
continue;
|
|
193
178
|
|
|
194
179
|
string targetFile = Path.Combine(targetDir, file.Name);
|
|
195
180
|
|
|
196
|
-
// 이미 존재하는 파일은 덮어쓰지 않음
|
|
197
181
|
if (!File.Exists(targetFile))
|
|
198
182
|
{
|
|
199
183
|
file.CopyTo(targetFile);
|
|
@@ -201,7 +185,6 @@ namespace BACKND.Database.Editor
|
|
|
201
185
|
}
|
|
202
186
|
}
|
|
203
187
|
|
|
204
|
-
// 메뉴에서 수동 설치
|
|
205
188
|
[MenuItem("The Backend/Database/Install Plugins")]
|
|
206
189
|
private static void ManualInstall()
|
|
207
190
|
{
|
|
@@ -211,9 +194,9 @@ namespace BACKND.Database.Editor
|
|
|
211
194
|
{
|
|
212
195
|
EditorUtility.DisplayDialog(
|
|
213
196
|
"BACKND Database",
|
|
214
|
-
"
|
|
215
|
-
"
|
|
216
|
-
"
|
|
197
|
+
"Could not find TheBackend~ folder.\n\n" +
|
|
198
|
+
"Please verify that the package is properly installed.",
|
|
199
|
+
"OK"
|
|
217
200
|
);
|
|
218
201
|
return;
|
|
219
202
|
}
|
|
@@ -224,10 +207,10 @@ namespace BACKND.Database.Editor
|
|
|
224
207
|
{
|
|
225
208
|
bool overwrite = EditorUtility.DisplayDialog(
|
|
226
209
|
"BACKND Database",
|
|
227
|
-
$"Assets/{TargetFolderName}
|
|
228
|
-
"
|
|
229
|
-
"
|
|
230
|
-
"
|
|
210
|
+
$"Assets/{TargetFolderName} folder already exists.\n\n" +
|
|
211
|
+
"Only new files will be added. (Existing files will be preserved)",
|
|
212
|
+
"Continue",
|
|
213
|
+
"Cancel"
|
|
231
214
|
);
|
|
232
215
|
|
|
233
216
|
if (!overwrite) return;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using UnityEngine.Scripting;
|
|
3
|
+
|
|
4
|
+
namespace BACKND.Database.Internal
|
|
5
|
+
{
|
|
6
|
+
[Preserve]
|
|
7
|
+
public static class NullableHelper
|
|
8
|
+
{
|
|
9
|
+
// DateTime
|
|
10
|
+
[Preserve]
|
|
11
|
+
public static DateTime? CreateNullableDateTime(DateTime value) => value;
|
|
12
|
+
|
|
13
|
+
// Int32
|
|
14
|
+
[Preserve]
|
|
15
|
+
public static int? CreateNullableInt32(int value) => value;
|
|
16
|
+
|
|
17
|
+
// Int64
|
|
18
|
+
[Preserve]
|
|
19
|
+
public static long? CreateNullableInt64(long value) => value;
|
|
20
|
+
|
|
21
|
+
// Boolean
|
|
22
|
+
[Preserve]
|
|
23
|
+
public static bool? CreateNullableBoolean(bool value) => value;
|
|
24
|
+
|
|
25
|
+
// Single (float)
|
|
26
|
+
[Preserve]
|
|
27
|
+
public static float? CreateNullableSingle(float value) => value;
|
|
28
|
+
|
|
29
|
+
// Double
|
|
30
|
+
[Preserve]
|
|
31
|
+
public static double? CreateNullableDouble(double value) => value;
|
|
32
|
+
|
|
33
|
+
// UInt32
|
|
34
|
+
[Preserve]
|
|
35
|
+
public static uint? CreateNullableUInt32(uint value) => value;
|
|
36
|
+
|
|
37
|
+
// UInt64
|
|
38
|
+
[Preserve]
|
|
39
|
+
public static ulong? CreateNullableUInt64(ulong value) => value;
|
|
40
|
+
|
|
41
|
+
// Guid
|
|
42
|
+
[Preserve]
|
|
43
|
+
public static Guid? CreateNullableGuid(Guid value) => value;
|
|
44
|
+
}
|
|
45
|
+
}
|
package/link.xml
ADDED
package/link.xml.meta
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "com.backnd.database",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.11",
|
|
4
4
|
"displayName": "BACKND Database",
|
|
5
5
|
"description": "BACKND Database is a Unity SDK for seamless integration with BACKND cloud database services.\n\nEasily manage and synchronize game data such as player profiles, game states, and leaderboards across multiple platforms.\nIdeal for Unity developers looking to implement robust database solutions without complex backend setups.",
|
|
6
6
|
"unity": "2021.3",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
],
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"com.unity.nuget.newtonsoft-json": "3.2.2",
|
|
16
|
-
"com.backnd.tools": "0.0.
|
|
16
|
+
"com.backnd.tools": "0.0.5"
|
|
17
17
|
},
|
|
18
18
|
"category": "SDK",
|
|
19
19
|
"author": {
|