oneRain 2021-04-09 14:24:04 +08:00
parent d109a2d950
commit 71e6699d0a
97 changed files with 388 additions and 484 deletions

View File

@ -11,11 +11,9 @@
<ProjectReference Include="..\..\Libs\Newtonsoft.Json.AOT\LC.Newtonsoft.Json.AOT.csproj" /> <ProjectReference Include="..\..\Libs\Newtonsoft.Json.AOT\LC.Newtonsoft.Json.AOT.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\Common\Common.csproj"> <Compile Include="..\Common\LCCore.cs">
<Link>Common\Common.csproj</Link> <Link>Common\LCCore.cs</Link>
</None> </Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="..\Common\AppRouter\LCAppServer.cs"> <Compile Include="..\Common\AppRouter\LCAppServer.cs">
<Link>Common\AppRouter\LCAppServer.cs</Link> <Link>Common\AppRouter\LCAppServer.cs</Link>
</Compile> </Compile>
@ -31,8 +29,14 @@
<Compile Include="..\Common\Http\LCHttpUtils.cs"> <Compile Include="..\Common\Http\LCHttpUtils.cs">
<Link>Common\Http\LCHttpUtils.cs</Link> <Link>Common\Http\LCHttpUtils.cs</Link>
</Compile> </Compile>
<Compile Include="..\Common\Task\LCTaskExtensions.cs"> <Compile Include="..\Common\Http\LCHttpClient.cs">
<Link>Common\Task\LCTaskExtensions.cs</Link> <Link>Common\Http\LCHttpClient.cs</Link>
</Compile>
<Compile Include="..\Common\Persistence\PersistenceController.cs">
<Link>Common\Persistence\PersistenceController.cs</Link>
</Compile>
<Compile Include="..\Common\Persistence\IPersistence.cs">
<Link>Common\Persistence\IPersistence.cs</Link>
</Compile> </Compile>
<Compile Include="..\Common\Log\LCLogger.cs"> <Compile Include="..\Common\Log\LCLogger.cs">
<Link>Common\Log\LCLogger.cs</Link> <Link>Common\Log\LCLogger.cs</Link>

View File

@ -9,8 +9,8 @@
<ItemGroup> <ItemGroup>
<Folder Include="Log\" /> <Folder Include="Log\" />
<Folder Include="Http\" /> <Folder Include="Http\" />
<Folder Include="Task\" />
<Folder Include="Exception\" /> <Folder Include="Exception\" />
<Folder Include="Persistence\" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -8,9 +8,8 @@ using System.Net.Http.Headers;
using System.Text; using System.Text;
using System.Security.Cryptography; using System.Security.Cryptography;
using LC.Newtonsoft.Json; using LC.Newtonsoft.Json;
using LeanCloud.Common;
namespace LeanCloud.Storage.Internal.Http { namespace LeanCloud.Common {
public class LCHttpClient { public class LCHttpClient {
private readonly string appId; private readonly string appId;
@ -26,6 +25,8 @@ namespace LeanCloud.Storage.Internal.Http {
readonly MD5 md5; readonly MD5 md5;
private Dictionary<string, Func<Task<string>>> runtimeHeaderTasks = new Dictionary<string, Func<Task<string>>>();
public LCHttpClient(string appId, string appKey, string server, string sdkVersion, string apiVersion) { public LCHttpClient(string appId, string appKey, string server, string sdkVersion, string apiVersion) {
this.appId = appId; this.appId = appId;
this.appKey = appKey; this.appKey = appKey;
@ -42,6 +43,16 @@ namespace LeanCloud.Storage.Internal.Http {
md5 = MD5.Create(); md5 = MD5.Create();
} }
public void AddRuntimeHeaderTask(string key, Func<Task<string>> task) {
if (key == null) {
return;
}
if (task == null) {
return;
}
runtimeHeaderTasks[key] = task;
}
public Task<T> Get<T>(string path, public Task<T> Get<T>(string path,
Dictionary<string, object> headers = null, Dictionary<string, object> headers = null,
Dictionary<string, object> queryParams = null) { Dictionary<string, object> queryParams = null) {
@ -120,7 +131,7 @@ namespace LeanCloud.Storage.Internal.Http {
} }
async Task<string> BuildUrl(string path, Dictionary<string, object> queryParams = null) { async Task<string> BuildUrl(string path, Dictionary<string, object> queryParams = null) {
string apiServer = await LCInternalApplication.AppRouter.GetApiServer(); string apiServer = await LCCore.AppRouter.GetApiServer();
string url = $"{apiServer}/{apiVersion}/{path}"; string url = $"{apiServer}/{apiVersion}/{path}";
if (queryParams != null) { if (queryParams != null) {
IEnumerable<string> queryPairs = queryParams.Select(kv => $"{kv.Key}={kv.Value}"); IEnumerable<string> queryPairs = queryParams.Select(kv => $"{kv.Key}={kv.Value}");
@ -137,9 +148,9 @@ namespace LeanCloud.Storage.Internal.Http {
headers.Add(kv.Key, kv.Value.ToString()); headers.Add(kv.Key, kv.Value.ToString());
} }
} }
if (LCInternalApplication.UseMasterKey && !string.IsNullOrEmpty(LCInternalApplication.MasterKey)) { if (LCCore.UseMasterKey && !string.IsNullOrEmpty(LCCore.MasterKey)) {
// Master Key // Master Key
headers.Add("X-LC-Key", $"{LCInternalApplication.MasterKey},master"); headers.Add("X-LC-Key", $"{LCCore.MasterKey},master");
} else { } else {
// 签名 // 签名
long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); long timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
@ -148,15 +159,21 @@ namespace LeanCloud.Storage.Internal.Http {
string sign = $"{hash},{timestamp}"; string sign = $"{hash},{timestamp}";
headers.Add("X-LC-Sign", sign); headers.Add("X-LC-Sign", sign);
} }
if (LCInternalApplication.AdditionalHeaders.Count > 0) { if (LCCore.AdditionalHeaders.Count > 0) {
foreach (KeyValuePair<string, string> kv in LCInternalApplication.AdditionalHeaders) { foreach (KeyValuePair<string, string> kv in LCCore.AdditionalHeaders) {
headers.Add(kv.Key, kv.Value); headers.Add(kv.Key, kv.Value);
} }
} }
// 当前用户 Session Token // 服务额外 headers
LCUser currentUser = await LCUser.GetCurrent(); foreach (KeyValuePair<string, Func<Task<string>>> kv in runtimeHeaderTasks) {
if (!headers.Contains("X-LC-Session") && currentUser != null) { if (headers.Contains(kv.Key)) {
headers.Add("X-LC-Session", currentUser.SessionToken); continue;
}
string value = await kv.Value.Invoke();
if (value == null) {
continue;
}
headers.Add(kv.Key, value);
} }
} }

View File

@ -1,20 +1,16 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using LeanCloud.Common;
using LeanCloud.Storage;
using LeanCloud.Storage.Internal.Http;
using LeanCloud.Storage.Internal.Storage;
namespace LeanCloud { namespace LeanCloud.Common {
/// <summary> /// <summary>
/// LeanCloud Application /// LeanCloud Application
/// </summary> /// </summary>
public class LCInternalApplication { public class LCCore {
// SDK 版本号,用于 User-Agent 统计 // SDK 版本号,用于 User-Agent 统计
public const string SDKVersion = "0.7.3"; public const string SDKVersion = "0.7.3";
// 接口版本号,用于接口版本管理 // 接口版本号,用于接口版本管理
internal const string APIVersion = "1.1"; public const string APIVersion = "1.1";
public static string AppId { public static string AppId {
get; private set; get; private set;
@ -44,7 +40,7 @@ namespace LeanCloud {
get; set; get; set;
} }
public static StorageController StorageController { public static PersistenceController PersistenceController {
get; set; get; set;
} }
@ -67,13 +63,6 @@ namespace LeanCloud {
AppKey = appKey; AppKey = appKey;
MasterKey = masterKey; MasterKey = masterKey;
// 注册 LeanCloud 内部子类化类型
LCObject.RegisterSubclass(LCUser.CLASS_NAME, () => new LCUser());
LCObject.RegisterSubclass(LCRole.CLASS_NAME, () => new LCRole());
LCObject.RegisterSubclass(LCFile.CLASS_NAME, () => new LCFile());
LCObject.RegisterSubclass(LCStatus.CLASS_NAME, () => new LCStatus());
LCObject.RegisterSubclass(LCFriendshipRequest.CLASS_NAME, () => new LCFriendshipRequest());
AppRouter = new LCAppRouter(appId, server); AppRouter = new LCAppRouter(appId, server);
HttpClient = new LCHttpClient(appId, appKey, server, SDKVersion, APIVersion); HttpClient = new LCHttpClient(appId, appKey, server, SDKVersion, APIVersion);

View File

@ -0,0 +1,5 @@
namespace LeanCloud.Common {
public interface IPersistence {
string GetPersistencePath();
}
}

View File

@ -1,23 +1,20 @@
using System; using System;
using System.Reflection;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.IO; using System.IO;
using System.Text; using System.Text;
using System.Collections.Generic;
using IOFile = System.IO.File; using IOFile = System.IO.File;
namespace LeanCloud.Storage.Internal.Storage { namespace LeanCloud.Common {
public class StorageController { public class PersistenceController {
private readonly IStorage storage; private readonly IPersistence persistence;
public StorageController(IStorage storage) { public PersistenceController(IPersistence persistence) {
this.storage = storage; this.persistence = persistence;
} }
public async Task WriteText(string filename, string text) { public async Task WriteText(string filename, string text) {
if (storage == null) { if (persistence == null) {
return; return;
} }
@ -31,7 +28,7 @@ namespace LeanCloud.Storage.Internal.Storage {
} }
public async Task<string> ReadText(string filename) { public async Task<string> ReadText(string filename) {
if (storage == null) { if (persistence == null) {
return null; return null;
} }
@ -51,7 +48,7 @@ namespace LeanCloud.Storage.Internal.Storage {
} }
public Task Delete(string filename) { public Task Delete(string filename) {
if (storage == null) { if (persistence == null) {
return Task.CompletedTask; return Task.CompletedTask;
} }
@ -62,10 +59,10 @@ namespace LeanCloud.Storage.Internal.Storage {
} }
private string GetFileFullPath(string filename) { private string GetFileFullPath(string filename) {
if (storage == null) { if (persistence == null) {
throw new Exception("no IStrorage."); throw new Exception("no IStrorage.");
} }
return Path.Combine(storage.GetStoragePath(), filename); return Path.Combine(persistence.GetPersistencePath(), filename);
} }
} }
} }

View File

@ -1,148 +0,0 @@
// Copyright (c) 2015-present, Parse, LLC. All rights reserved. This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. An additional grant of patent rights can be found in the PATENTS file in the same directory.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.ExceptionServices;
using System.Threading.Tasks;
namespace LeanCloud.Common {
/// <summary>
/// Provides helper methods that allow us to use terser code elsewhere.
/// </summary>
public static class LCTaskExtensions {
/// <summary>
/// Ensures a task (even null) is awaitable.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="task"></param>
/// <returns></returns>
public static Task<T> Safe<T>(this Task<T> task) {
return task ?? Task.FromResult<T>(default);
}
/// <summary>
/// Ensures a task (even null) is awaitable.
/// </summary>
/// <param name="task"></param>
/// <returns></returns>
public static Task Safe(this Task task) {
return task ?? Task.FromResult<object>(null);
}
public delegate void PartialAccessor<T>(ref T arg);
public static TValue GetOrDefault<TKey, TValue>(this IDictionary<TKey, TValue> self,
TKey key,
TValue defaultValue) {
if (self.TryGetValue(key, out TValue value)) {
return value;
}
return defaultValue;
}
public static bool CollectionsEqual<T>(this IEnumerable<T> a, IEnumerable<T> b) {
return Equals(a, b) ||
(a != null && b != null &&
a.SequenceEqual(b));
}
public static Task<TResult> OnSuccess<TResult>(this Task task,
Func<Task, TResult> continuation) {
return task.ContinueWith(t => {
if (t.IsFaulted) {
var ex = t.Exception.Flatten();
if (ex.InnerExceptions.Count == 1) {
ExceptionDispatchInfo.Capture(ex.InnerExceptions[0]).Throw();
} else {
ExceptionDispatchInfo.Capture(ex).Throw();
}
// Unreachable
return Task.FromResult(default(TResult));
} else if (t.IsCanceled) {
var tcs = new TaskCompletionSource<TResult>();
tcs.SetCanceled();
return tcs.Task;
} else {
return Task.FromResult(continuation(t));
}
}).Unwrap();
}
public static Task<TResult> OnSuccess<TIn, TResult>(this Task<TIn> task,
Func<Task<TIn>, TResult> continuation) {
return ((Task)task).OnSuccess(t => continuation((Task<TIn>)t));
}
public static Task OnSuccess<TIn>(this Task<TIn> task, Action<Task<TIn>> continuation) {
return task.OnSuccess((Func<Task<TIn>, object>)(t => {
continuation(t);
return null;
}));
}
public static Task OnSuccess(this Task task, Action<Task> continuation) {
return task.OnSuccess((Func<Task, object>)(t => {
continuation(t);
return null;
}));
}
// TaskScheduler
public static Task<TResult> OnSuccess<TResult>(this Task task,
Func<Task, TResult> continuation, TaskScheduler scheduler) {
return task.ContinueWith(t => {
if (t.IsFaulted) {
var ex = t.Exception.Flatten();
if (ex.InnerExceptions.Count == 1) {
ExceptionDispatchInfo.Capture(ex.InnerExceptions[0]).Throw();
} else {
ExceptionDispatchInfo.Capture(ex).Throw();
}
// Unreachable
return Task.FromResult(default(TResult));
} else if (t.IsCanceled) {
var tcs = new TaskCompletionSource<TResult>();
tcs.SetCanceled();
return tcs.Task;
} else {
return Task.FromResult(continuation(t));
}
}, scheduler).Unwrap();
}
public static Task<TResult> OnSuccess<TIn, TResult>(this Task<TIn> task,
Func<Task<TIn>, TResult> continuation, TaskScheduler scheduler) {
return ((Task)task).OnSuccess(t => continuation((Task<TIn>)t), scheduler);
}
public static Task OnSuccess<TIn>(this Task<TIn> task,
Action<Task<TIn>> continuation, TaskScheduler scheduler) {
return task.OnSuccess((Func<Task<TIn>, object>)(t => {
continuation(t);
return null;
}), scheduler);
}
public static Task OnSuccess(this Task task,
Action<Task> continuation, TaskScheduler scheduler) {
return task.OnSuccess((Func<Task, object>)(t => {
continuation(t);
return null;
}), scheduler);
}
public static Task WhileAsync(Func<Task<bool>> predicate, Func<Task> body) {
Func<Task> iterate = null;
iterate = () => {
return predicate().OnSuccess(t => {
if (!t.Result) {
return Task.FromResult(0);
}
return body().OnSuccess(_ => iterate()).Unwrap();
}).Unwrap();
};
return iterate();
}
}
}

View File

@ -6,7 +6,7 @@ OUTPUT_DIRECTORY = ./Doc/
EXTRACT_ALL = yes EXTRACT_ALL = yes
EXTRACT_PRIVATE = no EXTRACT_PRIVATE = no
EXTRACT_STATIC = yes EXTRACT_STATIC = yes
INPUT = ./Storage/Storage/ ./Realtime/Realtime/ ./LiveQuery/LiveQuery/ ./Engine/ INPUT = ./Storage/Storage/Public ./Storage/Storage.Unity/Public ./Realtime/Realtime/Public ./LiveQuery/LiveQuery/Public ./Engine/Public
#Do not add anything here unless you need to. Doxygen already covers all #Do not add anything here unless you need to. Doxygen already covers all
#common formats like .c/.cc/.cxx/.c++/.cpp/.inl/.h/.hpp #common formats like .c/.cc/.cxx/.c++/.cpp/.inl/.h/.hpp
FILE_PATTERNS = FILE_PATTERNS =

View File

@ -14,6 +14,9 @@
<FrameworkReference Include="Microsoft.AspNetCore.App" /> <FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Controllers\" /> <Folder Include="Public\" />
<Folder Include="Public\Attributes\" />
<Folder Include="Internal\" />
<Folder Include="Internal\Controllers\" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Cors; using Microsoft.AspNetCore.Cors;
using LeanCloud.Common;
namespace LeanCloud.Engine { namespace LeanCloud.Engine {
[ApiController] [ApiController]
@ -14,7 +15,7 @@ namespace LeanCloud.Engine {
return new Dictionary<string, string> { return new Dictionary<string, string> {
{ "runtime", $"dotnet-{Environment.Version}" }, { "runtime", $"dotnet-{Environment.Version}" },
{ "version", LCInternalApplication.SDKVersion } { "version", LCCore.SDKVersion }
}; };
} }
} }

View File

@ -99,7 +99,7 @@ namespace LeanCloud.Engine {
LCApplication.Initialize(Environment.GetEnvironmentVariable("LEANCLOUD_APP_ID"), LCApplication.Initialize(Environment.GetEnvironmentVariable("LEANCLOUD_APP_ID"),
Environment.GetEnvironmentVariable("LEANCLOUD_APP_KEY"), Environment.GetEnvironmentVariable("LEANCLOUD_APP_KEY"),
Environment.GetEnvironmentVariable("LEANCLOUD_API_SERVER")); Environment.GetEnvironmentVariable("LEANCLOUD_API_SERVER"));
LCInternalApplication.AddHeader(LCHookKeyName, Environment.GetEnvironmentVariable("LEANCLOUD_APP_HOOK_KEY")); LCCore.AddHeader(LCHookKeyName, Environment.GetEnvironmentVariable("LEANCLOUD_APP_HOOK_KEY"));
Assembly assembly = Assembly.GetCallingAssembly(); Assembly assembly = Assembly.GetCallingAssembly();
ClassHooks = assembly.GetTypes() ClassHooks = assembly.GetTypes()

View File

@ -11,22 +11,17 @@
<ProjectReference Include="..\..\Realtime\Realtime.AOT\Realtime.AOT.csproj" /> <ProjectReference Include="..\..\Realtime\Realtime.AOT\Realtime.AOT.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\LiveQuery\LiveQuery.csproj">
<Link>LiveQuery\LiveQuery.csproj</Link>
</None>
</ItemGroup>
<ItemGroup>
<Compile Include="..\LiveQuery\LCLiveQuery.cs">
<Link>LiveQuery\LCLiveQuery.cs</Link>
</Compile>
<Compile Include="..\LiveQuery\LCQueryExtension.cs">
<Link>LiveQuery\LCQueryExtension.cs</Link>
</Compile>
<Compile Include="..\LiveQuery\Internal\LCLiveQueryHeartBeat.cs"> <Compile Include="..\LiveQuery\Internal\LCLiveQueryHeartBeat.cs">
<Link>LiveQuery\Internal\LCLiveQueryHeartBeat.cs</Link> <Link>LiveQuery\Internal\LCLiveQueryHeartBeat.cs</Link>
</Compile> </Compile>
<Compile Include="..\LiveQuery\Internal\LCLiveQueryConnection.cs"> <Compile Include="..\LiveQuery\Internal\LCLiveQueryConnection.cs">
<Link>LiveQuery\Internal\LCLiveQueryConnection.cs</Link> <Link>LiveQuery\Internal\LCLiveQueryConnection.cs</Link>
</Compile> </Compile>
<Compile Include="..\LiveQuery\Public\LCLiveQuery.cs">
<Link>LiveQuery\Public\LCLiveQuery.cs</Link>
</Compile>
<Compile Include="..\LiveQuery\Public\LCQueryExtension.cs">
<Link>LiveQuery\Public\LCQueryExtension.cs</Link>
</Compile>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -11,5 +11,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Internal\" /> <Folder Include="Internal\" />
<Folder Include="Public\" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -3,6 +3,7 @@ using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Threading.Tasks; using System.Threading.Tasks;
using LeanCloud.Common;
using LeanCloud.Storage; using LeanCloud.Storage;
using LeanCloud.Storage.Internal.Object; using LeanCloud.Storage.Internal.Object;
using LeanCloud.LiveQuery.Internal; using LeanCloud.LiveQuery.Internal;
@ -80,7 +81,7 @@ namespace LeanCloud.LiveQuery {
data.Add("sessionToken", user.SessionToken); data.Add("sessionToken", user.SessionToken);
} }
string path = "LiveQuery/subscribe"; string path = "LiveQuery/subscribe";
Dictionary<string, object> result = await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>(path, Dictionary<string, object> result = await LCCore.HttpClient.Post<Dictionary<string, object>>(path,
data: data); data: data);
if (result.TryGetValue("query_id", out object id)) { if (result.TryGetValue("query_id", out object id)) {
Id = id as string; Id = id as string;
@ -95,7 +96,7 @@ namespace LeanCloud.LiveQuery {
{ "query_id", Id } { "query_id", Id }
}; };
string path = "LiveQuery/unsubscribe"; string path = "LiveQuery/unsubscribe";
await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>(path, await LCCore.HttpClient.Post<Dictionary<string, object>>(path,
data: data); data: data);
// 移除 // 移除
liveQueries.Remove(Id); liveQueries.Remove(Id);
@ -104,7 +105,7 @@ namespace LeanCloud.LiveQuery {
private static async Task Login() { private static async Task Login() {
Dictionary<string, object> data = new Dictionary<string, object> { Dictionary<string, object> data = new Dictionary<string, object> {
{ "cmd", "login" }, { "cmd", "login" },
{ "appId", LCInternalApplication.AppId }, { "appId", LCCore.AppId },
{ "installationId", DeviceId }, { "installationId", DeviceId },
{ "clientTs", DateTimeOffset.Now.ToUnixTimeMilliseconds() }, { "clientTs", DateTimeOffset.Now.ToUnixTimeMilliseconds() },
{ "service", 1 } { "service", 1 }

View File

@ -12,83 +12,83 @@
<ProjectReference Include="..\..\Libs\Google.Protobuf\LC.Google.Protobuf.csproj" /> <ProjectReference Include="..\..\Libs\Google.Protobuf\LC.Google.Protobuf.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="..\Realtime\LCIMClient.cs"> <Compile Include="..\Realtime\Public\LCIMClient.cs">
<Link>Realtime\LCIMClient.cs</Link> <Link>Realtime\Public\LCIMClient.cs</Link>
</Compile> </Compile>
<Compile Include="..\Realtime\LCRealtime.cs"> <Compile Include="..\Realtime\Public\LCRealtime.cs">
<Link>Realtime\LCRealtime.cs</Link> <Link>Realtime\Public\LCRealtime.cs</Link>
</Compile> </Compile>
<Compile Include="..\Realtime\Result\LCIMOperationFailure.cs"> <Compile Include="..\Realtime\Public\Result\LCIMOperationFailure.cs">
<Link>Realtime\Result\LCIMOperationFailure.cs</Link> <Link>Realtime\Public\Result\LCIMOperationFailure.cs</Link>
</Compile> </Compile>
<Compile Include="..\Realtime\Result\LCIMPageResult.cs"> <Compile Include="..\Realtime\Public\Result\LCIMPageResult.cs">
<Link>Realtime\Result\LCIMPageResult.cs</Link> <Link>Realtime\Public\Result\LCIMPageResult.cs</Link>
</Compile> </Compile>
<Compile Include="..\Realtime\Result\LCIMPartiallySuccessResult.cs"> <Compile Include="..\Realtime\Public\Result\LCIMPartiallySuccessResult.cs">
<Link>Realtime\Result\LCIMPartiallySuccessResult.cs</Link> <Link>Realtime\Public\Result\LCIMPartiallySuccessResult.cs</Link>
</Compile> </Compile>
<Compile Include="..\Realtime\Signature\LCIMSignature.cs"> <Compile Include="..\Realtime\Public\Signature\LCIMSignature.cs">
<Link>Realtime\Signature\LCIMSignature.cs</Link> <Link>Realtime\Public\Signature\LCIMSignature.cs</Link>
</Compile> </Compile>
<Compile Include="..\Realtime\Signature\ILCIMSignatureFactory.cs"> <Compile Include="..\Realtime\Public\Signature\ILCIMSignatureFactory.cs">
<Link>Realtime\Signature\ILCIMSignatureFactory.cs</Link> <Link>Realtime\Public\Signature\ILCIMSignatureFactory.cs</Link>
</Compile> </Compile>
<Compile Include="..\Realtime\Signature\LCIMSignatureAction.cs"> <Compile Include="..\Realtime\Public\Signature\LCIMSignatureAction.cs">
<Link>Realtime\Signature\LCIMSignatureAction.cs</Link> <Link>Realtime\Public\Signature\LCIMSignatureAction.cs</Link>
</Compile> </Compile>
<Compile Include="..\Realtime\Message\LCIMVideoMessage.cs"> <Compile Include="..\Realtime\Public\Message\LCIMVideoMessage.cs">
<Link>Realtime\Message\LCIMVideoMessage.cs</Link> <Link>Realtime\Public\Message\LCIMVideoMessage.cs</Link>
</Compile> </Compile>
<Compile Include="..\Realtime\Message\LCIMMessageSendOptions.cs"> <Compile Include="..\Realtime\Public\Message\LCIMMessageSendOptions.cs">
<Link>Realtime\Message\LCIMMessageSendOptions.cs</Link> <Link>Realtime\Public\Message\LCIMMessageSendOptions.cs</Link>
</Compile> </Compile>
<Compile Include="..\Realtime\Message\LCIMBinaryMessage.cs"> <Compile Include="..\Realtime\Public\Message\LCIMBinaryMessage.cs">
<Link>Realtime\Message\LCIMBinaryMessage.cs</Link> <Link>Realtime\Public\Message\LCIMBinaryMessage.cs</Link>
</Compile> </Compile>
<Compile Include="..\Realtime\Message\LCIMFileMessage.cs"> <Compile Include="..\Realtime\Public\Message\LCIMFileMessage.cs">
<Link>Realtime\Message\LCIMFileMessage.cs</Link> <Link>Realtime\Public\Message\LCIMFileMessage.cs</Link>
</Compile> </Compile>
<Compile Include="..\Realtime\Message\LCIMRecalledMessage.cs"> <Compile Include="..\Realtime\Public\Message\LCIMRecalledMessage.cs">
<Link>Realtime\Message\LCIMRecalledMessage.cs</Link> <Link>Realtime\Public\Message\LCIMRecalledMessage.cs</Link>
</Compile> </Compile>
<Compile Include="..\Realtime\Message\LCIMMessage.cs"> <Compile Include="..\Realtime\Public\Message\LCIMMessage.cs">
<Link>Realtime\Message\LCIMMessage.cs</Link> <Link>Realtime\Public\Message\LCIMMessage.cs</Link>
</Compile> </Compile>
<Compile Include="..\Realtime\Message\LCIMTextMessage.cs"> <Compile Include="..\Realtime\Public\Message\LCIMTextMessage.cs">
<Link>Realtime\Message\LCIMTextMessage.cs</Link> <Link>Realtime\Public\Message\LCIMTextMessage.cs</Link>
</Compile> </Compile>
<Compile Include="..\Realtime\Message\LCIMImageMessage.cs"> <Compile Include="..\Realtime\Public\Message\LCIMImageMessage.cs">
<Link>Realtime\Message\LCIMImageMessage.cs</Link> <Link>Realtime\Public\Message\LCIMImageMessage.cs</Link>
</Compile> </Compile>
<Compile Include="..\Realtime\Message\LCIMAudioMessage.cs"> <Compile Include="..\Realtime\Public\Message\LCIMAudioMessage.cs">
<Link>Realtime\Message\LCIMAudioMessage.cs</Link> <Link>Realtime\Public\Message\LCIMAudioMessage.cs</Link>
</Compile> </Compile>
<Compile Include="..\Realtime\Message\LCIMLocationMessage.cs"> <Compile Include="..\Realtime\Public\Message\LCIMLocationMessage.cs">
<Link>Realtime\Message\LCIMLocationMessage.cs</Link> <Link>Realtime\Public\Message\LCIMLocationMessage.cs</Link>
</Compile> </Compile>
<Compile Include="..\Realtime\Message\LCIMTypedMessage.cs"> <Compile Include="..\Realtime\Public\Message\LCIMTypedMessage.cs">
<Link>Realtime\Message\LCIMTypedMessage.cs</Link> <Link>Realtime\Public\Message\LCIMTypedMessage.cs</Link>
</Compile> </Compile>
<Compile Include="..\Realtime\Conversation\LCIMConversation.cs"> <Compile Include="..\Realtime\Public\Conversation\LCIMConversation.cs">
<Link>Realtime\Conversation\LCIMConversation.cs</Link> <Link>Realtime\Public\Conversation\LCIMConversation.cs</Link>
</Compile> </Compile>
<Compile Include="..\Realtime\Conversation\LCIMServiceConversation.cs"> <Compile Include="..\Realtime\Public\Conversation\LCIMServiceConversation.cs">
<Link>Realtime\Conversation\LCIMServiceConversation.cs</Link> <Link>Realtime\Public\Conversation\LCIMServiceConversation.cs</Link>
</Compile> </Compile>
<Compile Include="..\Realtime\Conversation\LCIMConversationMemberInfo.cs"> <Compile Include="..\Realtime\Public\Conversation\LCIMConversationMemberInfo.cs">
<Link>Realtime\Conversation\LCIMConversationMemberInfo.cs</Link> <Link>Realtime\Public\Conversation\LCIMConversationMemberInfo.cs</Link>
</Compile> </Compile>
<Compile Include="..\Realtime\Conversation\LCIMConversationQuery.cs"> <Compile Include="..\Realtime\Public\Conversation\LCIMConversationQuery.cs">
<Link>Realtime\Conversation\LCIMConversationQuery.cs</Link> <Link>Realtime\Public\Conversation\LCIMConversationQuery.cs</Link>
</Compile> </Compile>
<Compile Include="..\Realtime\Conversation\LCIMChatRoom.cs"> <Compile Include="..\Realtime\Public\Conversation\LCIMChatRoom.cs">
<Link>Realtime\Conversation\LCIMChatRoom.cs</Link> <Link>Realtime\Public\Conversation\LCIMChatRoom.cs</Link>
</Compile> </Compile>
<Compile Include="..\Realtime\Conversation\LCIMMessageQueryOptions.cs"> <Compile Include="..\Realtime\Public\Conversation\LCIMMessageQueryOptions.cs">
<Link>Realtime\Conversation\LCIMMessageQueryOptions.cs</Link> <Link>Realtime\Public\Conversation\LCIMMessageQueryOptions.cs</Link>
</Compile> </Compile>
<Compile Include="..\Realtime\Conversation\LCIMTemporaryConversation.cs"> <Compile Include="..\Realtime\Public\Conversation\LCIMTemporaryConversation.cs">
<Link>Realtime\Conversation\LCIMTemporaryConversation.cs</Link> <Link>Realtime\Public\Conversation\LCIMTemporaryConversation.cs</Link>
</Compile> </Compile>
<Compile Include="..\Realtime\Internal\WebSocket\LCWebSocketClient.cs"> <Compile Include="..\Realtime\Internal\WebSocket\LCWebSocketClient.cs">
<Link>Realtime\Internal\WebSocket\LCWebSocketClient.cs</Link> <Link>Realtime\Internal\WebSocket\LCWebSocketClient.cs</Link>
@ -121,9 +121,4 @@
<Link>Realtime\Internal\Router\LCRTMRouter.cs</Link> <Link>Realtime\Internal\Router\LCRTMRouter.cs</Link>
</Compile> </Compile>
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="..\Realtime\Realtime.csproj">
<Link>Realtime\Realtime.csproj</Link>
</None>
</ItemGroup>
</Project> </Project>

View File

@ -5,7 +5,7 @@ using System.Threading.Tasks;
using System.Collections.Generic; using System.Collections.Generic;
using System.Security.Cryptography; using System.Security.Cryptography;
using LeanCloud.Realtime; using LeanCloud.Realtime;
using LeanCloud; using LeanCloud.Common;
namespace Realtime.Test { namespace Realtime.Test {
public class LocalSignatureFactory : ILCIMSignatureFactory { public class LocalSignatureFactory : ILCIMSignatureFactory {
@ -14,7 +14,7 @@ namespace Realtime.Test {
public Task<LCIMSignature> CreateConnectSignature(string clientId) { public Task<LCIMSignature> CreateConnectSignature(string clientId) {
long timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); long timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
string nonce = NewNonce(); string nonce = NewNonce();
string signature = GenerateSignature(LCInternalApplication.AppId, clientId, string.Empty, timestamp.ToString(), nonce); string signature = GenerateSignature(LCCore.AppId, clientId, string.Empty, timestamp.ToString(), nonce);
return Task.FromResult(new LCIMSignature { return Task.FromResult(new LCIMSignature {
Signature = signature, Signature = signature,
Timestamp = timestamp, Timestamp = timestamp,
@ -31,7 +31,7 @@ namespace Realtime.Test {
} }
long timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); long timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
string nonce = NewNonce(); string nonce = NewNonce();
string signature = GenerateSignature(LCInternalApplication.AppId, clientId, sortedMemberIds, timestamp.ToString(), nonce); string signature = GenerateSignature(LCCore.AppId, clientId, sortedMemberIds, timestamp.ToString(), nonce);
return Task.FromResult(new LCIMSignature { return Task.FromResult(new LCIMSignature {
Signature = signature, Signature = signature,
Timestamp = timestamp, Timestamp = timestamp,
@ -48,7 +48,7 @@ namespace Realtime.Test {
} }
long timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); long timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
string nonce = NewNonce(); string nonce = NewNonce();
string signature = GenerateSignature(LCInternalApplication.AppId, clientId, conversationId, sortedMemberIds, timestamp.ToString(), nonce, action); string signature = GenerateSignature(LCCore.AppId, clientId, conversationId, sortedMemberIds, timestamp.ToString(), nonce, action);
return Task.FromResult(new LCIMSignature { return Task.FromResult(new LCIMSignature {
Signature = signature, Signature = signature,
Timestamp = timestamp, Timestamp = timestamp,
@ -65,7 +65,7 @@ namespace Realtime.Test {
} }
long timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); long timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
string nonce = NewNonce(); string nonce = NewNonce();
string signature = GenerateSignature(LCInternalApplication.AppId, clientId, conversationId, sortedMemberIds, timestamp.ToString(), nonce, action); string signature = GenerateSignature(LCCore.AppId, clientId, conversationId, sortedMemberIds, timestamp.ToString(), nonce, action);
return Task.FromResult(new LCIMSignature { return Task.FromResult(new LCIMSignature {
Signature = signature, Signature = signature,
Timestamp = timestamp, Timestamp = timestamp,

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using LeanCloud.Common;
using LeanCloud.Realtime.Internal.Protocol; using LeanCloud.Realtime.Internal.Protocol;
namespace LeanCloud.Realtime.Internal.Connection { namespace LeanCloud.Realtime.Internal.Connection {
@ -56,7 +57,7 @@ namespace LeanCloud.Realtime.Internal.Connection {
// 发送 ping 包 // 发送 ping 包
GenericCommand command = new GenericCommand { GenericCommand command = new GenericCommand {
Cmd = CommandType.Echo, Cmd = CommandType.Echo,
AppId = LCInternalApplication.AppId, AppId = LCCore.AppId,
PeerId = connection.id PeerId = connection.id
}; };
try { try {

View File

@ -1,4 +1,5 @@
using LeanCloud.Realtime.Internal.Protocol; using LeanCloud.Common;
using LeanCloud.Realtime.Internal.Protocol;
using LeanCloud.Realtime.Internal.Connection; using LeanCloud.Realtime.Internal.Connection;
namespace LeanCloud.Realtime.Internal.Controller { namespace LeanCloud.Realtime.Internal.Controller {
@ -15,7 +16,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
protected LCConnection Connection { protected LCConnection Connection {
get { get {
return LCRealtime.GetConnection(LCInternalApplication.AppId); return LCRealtime.GetConnection(LCCore.AppId);
} }
} }
@ -28,7 +29,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
protected GenericCommand NewCommand(CommandType cmd) { protected GenericCommand NewCommand(CommandType cmd) {
return new GenericCommand { return new GenericCommand {
Cmd = cmd, Cmd = cmd,
AppId = LCInternalApplication.AppId, AppId = LCCore.AppId,
PeerId = Client.Id, PeerId = Client.Id,
}; };
} }

View File

@ -284,7 +284,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
{ "client_id", Client.Id }, { "client_id", Client.Id },
{ "cid", convId } { "cid", convId }
}; };
Dictionary<string, object> response = await LCInternalApplication.HttpClient.Get<Dictionary<string, object>>(path, Dictionary<string, object> response = await LCCore.HttpClient.Get<Dictionary<string, object>>(path,
headers: headers, queryParams: queryParams); headers: headers, queryParams: queryParams);
List<object> results = response["results"] as List<object>; List<object> results = response["results"] as List<object>;
return results.Select(item => { return results.Select(item => {
@ -341,7 +341,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
GenericCommand command = new GenericCommand { GenericCommand command = new GenericCommand {
Cmd = CommandType.Conv, Cmd = CommandType.Conv,
Op = OpType.Query, Op = OpType.Query,
AppId = LCInternalApplication.AppId, AppId = LCCore.AppId,
PeerId = Client.Id, PeerId = Client.Id,
}; };
ConvCommand convMessage = new ConvCommand(); ConvCommand convMessage = new ConvCommand();

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using LeanCloud.Common;
using LeanCloud.Realtime.Internal.Protocol; using LeanCloud.Realtime.Internal.Protocol;
namespace LeanCloud.Realtime.Internal.Controller { namespace LeanCloud.Realtime.Internal.Controller {
@ -83,7 +84,7 @@ namespace LeanCloud.Realtime.Internal.Controller {
signature = await Client.SignatureFactory.CreateConnectSignature(Client.Id); signature = await Client.SignatureFactory.CreateConnectSignature(Client.Id);
} }
if (signature == null && !string.IsNullOrEmpty(Client.SessionToken)) { if (signature == null && !string.IsNullOrEmpty(Client.SessionToken)) {
Dictionary<string, object> ret = await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>("rtm/sign", data: new Dictionary<string, object> { Dictionary<string, object> ret = await LCCore.HttpClient.Post<Dictionary<string, object>>("rtm/sign", data: new Dictionary<string, object> {
{ "session_token", Client.SessionToken } { "session_token", Client.SessionToken }
}); });
signature = new LCIMSignature { signature = new LCIMSignature {

View File

@ -22,8 +22,8 @@ namespace LeanCloud.Realtime.Internal.Router {
} }
async Task<LCRTMServer> Fetch() { async Task<LCRTMServer> Fetch() {
string server = await LCInternalApplication.AppRouter.GetRealtimeServer(); string server = await LCCore.AppRouter.GetRealtimeServer();
string url = $"{server}/v1/route?appId={LCInternalApplication.AppId}&secure=1"; string url = $"{server}/v1/route?appId={LCCore.AppId}&secure=1";
HttpRequestMessage request = new HttpRequestMessage { HttpRequestMessage request = new HttpRequestMessage {
RequestUri = new Uri(url), RequestUri = new Uri(url),

View File

@ -10,14 +10,15 @@
<ItemGroup> <ItemGroup>
<Folder Include="Internal\" /> <Folder Include="Internal\" />
<Folder Include="Internal\Router\" /> <Folder Include="Internal\Router\" />
<Folder Include="Conversation\" />
<Folder Include="Message\" />
<Folder Include="Internal\WebSocket\" /> <Folder Include="Internal\WebSocket\" />
<Folder Include="Signature\" />
<Folder Include="Internal\Controller\" /> <Folder Include="Internal\Controller\" />
<Folder Include="Internal\Connection\" /> <Folder Include="Internal\Connection\" />
<Folder Include="Internal\Protocol\" /> <Folder Include="Internal\Protocol\" />
<Folder Include="Result\" /> <Folder Include="Public\" />
<Folder Include="Public\Conversation\" />
<Folder Include="Public\Message\" />
<Folder Include="Public\Result\" />
<Folder Include="Public\Signature\" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\Common\Common\Common.csproj" /> <ProjectReference Include="..\..\Common\Common\Common.csproj" />

View File

@ -11,77 +11,77 @@
<ProjectReference Include="..\..\Common\Common.AOT\Common.AOT.csproj" /> <ProjectReference Include="..\..\Common\Common.AOT\Common.AOT.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="..\Storage\LCCloud.cs"> <Compile Include="..\Storage\Public\LCCloud.cs">
<Link>Storage\LCCloud.cs</Link> <Link>Storage\Public\LCCloud.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\LCQuery.cs"> <Compile Include="..\Storage\Public\LCQuery.cs">
<Link>Storage\LCQuery.cs</Link> <Link>Storage\Public\LCQuery.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\LCFile.cs"> <Compile Include="..\Storage\Public\LCFile.cs">
<Link>Storage\LCFile.cs</Link> <Link>Storage\Public\LCFile.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\LCACL.cs"> <Compile Include="..\Storage\Public\LCACL.cs">
<Link>Storage\LCACL.cs</Link> <Link>Storage\Public\LCACL.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\LCCaptchaClient.cs"> <Compile Include="..\Storage\Public\LCCaptchaClient.cs">
<Link>Storage\LCCaptchaClient.cs</Link> <Link>Storage\Public\LCCaptchaClient.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\LCStatusQuery.cs"> <Compile Include="..\Storage\Public\LCStatusQuery.cs">
<Link>Storage\LCStatusQuery.cs</Link> <Link>Storage\Public\LCStatusQuery.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\LCHookObject.cs"> <Compile Include="..\Storage\Public\LCHookObject.cs">
<Link>Storage\LCHookObject.cs</Link> <Link>Storage\Public\LCHookObject.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\LCFriendshipRequest.cs"> <Compile Include="..\Storage\Public\LCFriendshipRequest.cs">
<Link>Storage\LCFriendshipRequest.cs</Link> <Link>Storage\Public\LCFriendshipRequest.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\LCFriendship.cs"> <Compile Include="..\Storage\Public\LCFriendship.cs">
<Link>Storage\LCFriendship.cs</Link> <Link>Storage\Public\LCFriendship.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\LCStatus.cs"> <Compile Include="..\Storage\Public\LCStatus.cs">
<Link>Storage\LCStatus.cs</Link> <Link>Storage\Public\LCStatus.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\LCInternalApplication.cs"> <Compile Include="..\Storage\Public\LCUser.cs">
<Link>Storage\LCInternalApplication.cs</Link> <Link>Storage\Public\LCUser.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\LCUser.cs"> <Compile Include="..\Storage\Public\LCObject.cs">
<Link>Storage\LCUser.cs</Link> <Link>Storage\Public\LCObject.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\LCObject.cs"> <Compile Include="..\Storage\Public\LCSMSClient.cs">
<Link>Storage\LCObject.cs</Link> <Link>Storage\Public\LCSMSClient.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\LCSMSClient.cs"> <Compile Include="..\Storage\Public\LCRelation.cs">
<Link>Storage\LCSMSClient.cs</Link> <Link>Storage\Public\LCRelation.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\LCRelation.cs"> <Compile Include="..\Storage\Public\LCGeoPoint.cs">
<Link>Storage\LCRelation.cs</Link> <Link>Storage\Public\LCGeoPoint.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\LCGeoPoint.cs"> <Compile Include="..\Storage\Public\LCStorage.cs">
<Link>Storage\LCGeoPoint.cs</Link> <Link>Storage\Public\LCStorage.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\LCUserAuthDataLoginOption.cs"> <Compile Include="..\Storage\Public\LCUserAuthDataLoginOption.cs">
<Link>Storage\LCUserAuthDataLoginOption.cs</Link> <Link>Storage\Public\LCUserAuthDataLoginOption.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\LCRole.cs"> <Compile Include="..\Storage\Public\LCRole.cs">
<Link>Storage\LCRole.cs</Link> <Link>Storage\Public\LCRole.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\LCFollowersAndFollowees.cs"> <Compile Include="..\Storage\Public\LCFollowersAndFollowees.cs">
<Link>Storage\LCFollowersAndFollowees.cs</Link> <Link>Storage\Public\LCFollowersAndFollowees.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\LCStatusCount.cs"> <Compile Include="..\Storage\Public\LCStatusCount.cs">
<Link>Storage\LCStatusCount.cs</Link> <Link>Storage\Public\LCStatusCount.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\Leaderboard\LCLeaderboardArchive.cs"> <Compile Include="..\Storage\Public\Leaderboard\LCLeaderboardArchive.cs">
<Link>Storage\Leaderboard\LCLeaderboardArchive.cs</Link> <Link>Storage\Public\Leaderboard\LCLeaderboardArchive.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\Leaderboard\LCStatistic.cs"> <Compile Include="..\Storage\Public\Leaderboard\LCStatistic.cs">
<Link>Storage\Leaderboard\LCStatistic.cs</Link> <Link>Storage\Public\Leaderboard\LCStatistic.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\Leaderboard\LCLeaderboard.cs"> <Compile Include="..\Storage\Public\Leaderboard\LCLeaderboard.cs">
<Link>Storage\Leaderboard\LCLeaderboard.cs</Link> <Link>Storage\Public\Leaderboard\LCLeaderboard.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\Leaderboard\LCRanking.cs"> <Compile Include="..\Storage\Public\Leaderboard\LCRanking.cs">
<Link>Storage\Leaderboard\LCRanking.cs</Link> <Link>Storage\Public\Leaderboard\LCRanking.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\Internal\Operation\LCNumberOperation.cs"> <Compile Include="..\Storage\Internal\Operation\LCNumberOperation.cs">
<Link>Storage\Internal\Operation\LCNumberOperation.cs</Link> <Link>Storage\Internal\Operation\LCNumberOperation.cs</Link>
@ -140,9 +140,6 @@
<Compile Include="..\Storage\Internal\Object\LCObjectData.cs"> <Compile Include="..\Storage\Internal\Object\LCObjectData.cs">
<Link>Storage\Internal\Object\LCObjectData.cs</Link> <Link>Storage\Internal\Object\LCObjectData.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\Internal\Http\LCHttpClient.cs">
<Link>Storage\Internal\Http\LCHttpClient.cs</Link>
</Compile>
<Compile Include="..\Storage\Internal\Query\LCEqualCondition.cs"> <Compile Include="..\Storage\Internal\Query\LCEqualCondition.cs">
<Link>Storage\Internal\Query\LCEqualCondition.cs</Link> <Link>Storage\Internal\Query\LCEqualCondition.cs</Link>
</Compile> </Compile>
@ -158,16 +155,5 @@
<Compile Include="..\Storage\Internal\Query\LCCompositionalCondition.cs"> <Compile Include="..\Storage\Internal\Query\LCCompositionalCondition.cs">
<Link>Storage\Internal\Query\LCCompositionalCondition.cs</Link> <Link>Storage\Internal\Query\LCCompositionalCondition.cs</Link>
</Compile> </Compile>
<Compile Include="..\Storage\Internal\Storage\StorageController.cs">
<Link>Storage\Internal\Storage\StorageController.cs</Link>
</Compile>
<Compile Include="..\Storage\Internal\Storage\IStorage.cs">
<Link>Storage\Internal\Storage\IStorage.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="..\Storage\Storage.csproj">
<Link>Storage\Storage.csproj</Link>
</None>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,16 +0,0 @@
using LeanCloud.Storage.Internal.Storage;
namespace LeanCloud {
public class LCApplication {
public static void Initialize(string appId,
string appKey,
string server = null,
string masterKey = null) {
LCLogger.Debug("Application Initializes on Standard.");
LCInternalApplication.Initialize(appId, appKey, server, masterKey);
LCInternalApplication.StorageController = new StorageController(null);
}
}
}

View File

@ -0,0 +1,24 @@
using LeanCloud.Common;
using LeanCloud.Storage;
namespace LeanCloud {
public class LCApplication {
public static bool UseMasterKey {
get => LCCore.UseMasterKey;
set {
LCCore.UseMasterKey = value;
}
}
public static void Initialize(string appId,
string appKey,
string server = null,
string masterKey = null) {
LCLogger.Debug("Application Initializes on Standard.");
LCStorage.Initialize(appId, appKey, server, masterKey);
LCCore.PersistenceController = new PersistenceController(null);
}
}
}

View File

@ -1,9 +0,0 @@
using System;
namespace LeanCloud.Storage.Internal.Storage {
public class StandardStorage : IStorage {
public string GetStoragePath() {
throw new NotImplementedException();
}
}
}

View File

@ -11,4 +11,7 @@
<ProjectReference Include="..\Storage\Storage.csproj" /> <ProjectReference Include="..\Storage\Storage.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Public\" />
</ItemGroup>
</Project> </Project>

View File

@ -48,8 +48,12 @@ namespace Storage.Test {
Assert.NotNull(result.ObjectId); Assert.NotNull(result.ObjectId);
await LCUser.Logout(); await LCUser.Logout();
result = await query.Get(account.ObjectId);
Assert.IsNull(result); try {
await query.Get(account.ObjectId);
} catch (LCException e) {
Assert.AreEqual(e.Code, 403);
}
} }
[Test] [Test]

View File

@ -71,7 +71,7 @@ namespace Storage.Test {
[Test] [Test]
public async Task AWS() { public async Task AWS() {
LCInternalApplication.Initialize("UlCpyvLm8aMzQsW6KnP6W3Wt-MdYXbMMI", "PyCTYoNoxCVoKKg394PBeS4r"); LCApplication.Initialize("UlCpyvLm8aMzQsW6KnP6W3Wt-MdYXbMMI", "PyCTYoNoxCVoKKg394PBeS4r");
LCFile file = new LCFile("avatar", AvatarFilePath); LCFile file = new LCFile("avatar", AvatarFilePath);
await file.Save((count, total) => { await file.Save((count, total) => {
TestContext.WriteLine($"progress: {count}/{total}"); TestContext.WriteLine($"progress: {count}/{total}");

View File

@ -15,13 +15,13 @@ namespace Storage.Test {
[SetUp] [SetUp]
public void SetUp() { public void SetUp() {
LCApplication.Initialize(Utils.AppId, Utils.AppKey, Utils.AppServer, Utils.MasterKey); LCApplication.Initialize(Utils.AppId, Utils.AppKey, Utils.AppServer, Utils.MasterKey);
LCInternalApplication.UseMasterKey = true; LCApplication.UseMasterKey = true;
leaderboardName = $"Leaderboard_{DateTimeOffset.Now.DayOfYear}"; leaderboardName = $"Leaderboard_{DateTimeOffset.Now.DayOfYear}";
} }
[TearDown] [TearDown]
public void TearDown() { public void TearDown() {
LCInternalApplication.UseMasterKey = false; LCApplication.UseMasterKey = false;
Utils.TearDown(); Utils.TearDown();
} }

View File

@ -0,0 +1,10 @@
using UnityEngine;
using LeanCloud.Common;
namespace LeanCloud.Storage.Internal.Persistence {
public class UnityPersistence : IPersistence {
public string GetPersistencePath() {
return Application.persistentDataPath;
}
}
}

View File

@ -1,16 +0,0 @@
using LeanCloud.Storage.Internal.Storage;
namespace LeanCloud {
public class LCApplication {
public static void Initialize(string appId,
string appKey,
string server = null,
string masterKey = null) {
LCLogger.Debug("Application Initializes on Unity.");
LCInternalApplication.Initialize(appId, appKey, server, masterKey);
LCInternalApplication.StorageController = new StorageController(new UnityStorage());
}
}
}

View File

@ -0,0 +1,25 @@
using LeanCloud.Common;
using LeanCloud.Storage;
using LeanCloud.Storage.Internal.Persistence;
namespace LeanCloud {
public class LCApplication {
public static bool UseMasterKey {
get => LCCore.UseMasterKey;
set {
LCCore.UseMasterKey = value;
}
}
public static void Initialize(string appId,
string appKey,
string server = null,
string masterKey = null) {
LCLogger.Debug("Application Initializes on Unity.");
LCStorage.Initialize(appId, appKey, server, masterKey);
LCCore.PersistenceController = new PersistenceController(new UnityPersistence());
}
}
}

View File

@ -15,4 +15,8 @@
<HintPath>..\..\Unity\UnityEngine.dll</HintPath> <HintPath>..\..\Unity\UnityEngine.dll</HintPath>
</Reference> </Reference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Public\" />
<Folder Include="Internal\" />
</ItemGroup>
</Project> </Project>

View File

@ -1,9 +0,0 @@
using UnityEngine;
namespace LeanCloud.Storage.Internal.Storage {
public class UnityStorage : IStorage {
public string GetStoragePath() {
return Application.persistentDataPath;
}
}
}

View File

@ -1,7 +0,0 @@
using System;
namespace LeanCloud.Storage.Internal.Storage {
public interface IStorage {
string GetStoragePath();
}
}

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using LeanCloud.Common;
namespace LeanCloud.Storage { namespace LeanCloud.Storage {
/// <summary> /// <summary>
@ -33,7 +34,7 @@ namespace LeanCloud.Storage {
{ "width", width }, { "width", width },
{ "height", height } { "height", height }
}; };
Dictionary<string, object> response = await LCInternalApplication.HttpClient.Get<Dictionary<string, object>>(path, queryParams: queryParams); Dictionary<string, object> response = await LCCore.HttpClient.Get<Dictionary<string, object>>(path, queryParams: queryParams);
return new LCCapture { return new LCCapture {
Url = response["captcha_url"] as string, Url = response["captcha_url"] as string,
Token = response["captcha_token"] as string Token = response["captcha_token"] as string
@ -60,7 +61,7 @@ namespace LeanCloud.Storage {
{ "captcha_code", code }, { "captcha_code", code },
{ "captcha_token", token } { "captcha_token", token }
}; };
await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>(path, data: data); await LCCore.HttpClient.Post<Dictionary<string, object>>(path, data: data);
} }
} }
} }

View File

@ -1,5 +1,6 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Collections.Generic; using System.Collections.Generic;
using LeanCloud.Common;
using LeanCloud.Storage.Internal.Codec; using LeanCloud.Storage.Internal.Codec;
using LeanCloud.Storage.Internal.Object; using LeanCloud.Storage.Internal.Object;
@ -30,7 +31,7 @@ namespace LeanCloud.Storage {
{ PRODUCTION_KEY, IsProduction ? 1 : 0 } { PRODUCTION_KEY, IsProduction ? 1 : 0 }
}; };
object encodeParams = LCEncoder.Encode(parameters); object encodeParams = LCEncoder.Encode(parameters);
Dictionary<string, object> response = await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>(path, Dictionary<string, object> response = await LCCore.HttpClient.Post<Dictionary<string, object>>(path,
headers: headers, headers: headers,
data: encodeParams); data: encodeParams);
return response; return response;
@ -57,7 +58,7 @@ namespace LeanCloud.Storage {
{ PRODUCTION_KEY, IsProduction ? 1 : 0 } { PRODUCTION_KEY, IsProduction ? 1 : 0 }
}; };
object encodeParams = Encode(parameters); object encodeParams = Encode(parameters);
Dictionary<string, object> response = await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>(path, Dictionary<string, object> response = await LCCore.HttpClient.Post<Dictionary<string, object>>(path,
headers: headers, headers: headers,
data: encodeParams); data: encodeParams);
return LCDecoder.Decode(response["result"]); return LCDecoder.Decode(response["result"]);

View File

@ -2,6 +2,7 @@
using System.IO; using System.IO;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using LeanCloud.Common;
using LeanCloud.Storage.Internal.File; using LeanCloud.Storage.Internal.File;
using LeanCloud.Storage.Internal.Object; using LeanCloud.Storage.Internal.Object;
@ -92,12 +93,12 @@ namespace LeanCloud.Storage {
} }
LCObjectData objectData = LCObjectData.Decode(uploadToken); LCObjectData objectData = LCObjectData.Decode(uploadToken);
Merge(objectData); Merge(objectData);
_ = LCInternalApplication.HttpClient.Post<Dictionary<string, object>>("fileCallback", data: new Dictionary<string, object> { _ = LCCore.HttpClient.Post<Dictionary<string, object>>("fileCallback", data: new Dictionary<string, object> {
{ "result", true }, { "result", true },
{ "token", token } { "token", token }
}); });
} catch (Exception e) { } catch (Exception e) {
_ = LCInternalApplication.HttpClient.Post<Dictionary<string, object>>("fileCallback", data: new Dictionary<string, object> { _ = LCCore.HttpClient.Post<Dictionary<string, object>>("fileCallback", data: new Dictionary<string, object> {
{ "result", false }, { "result", false },
{ "token", token } { "token", token }
}); });
@ -112,7 +113,7 @@ namespace LeanCloud.Storage {
return; return;
} }
string path = $"files/{ObjectId}"; string path = $"files/{ObjectId}";
await LCInternalApplication.HttpClient.Delete(path); await LCCore.HttpClient.Delete(path);
} }
public string GetThumbnailUrl(int width, int height, int quality = 100, bool scaleToFit = true, string format = "png") { public string GetThumbnailUrl(int width, int height, int quality = 100, bool scaleToFit = true, string format = "png") {
@ -128,7 +129,7 @@ namespace LeanCloud.Storage {
{ "mime_type", MimeType }, { "mime_type", MimeType },
{ "metaData", MetaData } { "metaData", MetaData }
}; };
return await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>("fileTokens", data: data); return await LCCore.HttpClient.Post<Dictionary<string, object>>("fileTokens", data: data);
} }
public static LCQuery<LCFile> GetQuery() { public static LCQuery<LCFile> GetQuery() {

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Collections.Generic; using System.Collections.Generic;
using LeanCloud.Common;
using LeanCloud.Storage.Internal.Codec; using LeanCloud.Storage.Internal.Codec;
namespace LeanCloud.Storage { namespace LeanCloud.Storage {
@ -19,7 +20,7 @@ namespace LeanCloud.Storage {
if (attributes != null) { if (attributes != null) {
data["friendship"] = attributes; data["friendship"] = attributes;
} }
await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>(path, data: data); await LCCore.HttpClient.Post<Dictionary<string, object>>(path, data: data);
} }
public static async Task AcceptRequest(LCFriendshipRequest request, Dictionary<string, object> attributes = null) { public static async Task AcceptRequest(LCFriendshipRequest request, Dictionary<string, object> attributes = null) {
@ -33,7 +34,7 @@ namespace LeanCloud.Storage {
{ "friendship", attributes } { "friendship", attributes }
}; };
} }
await LCInternalApplication.HttpClient.Put<Dictionary<string, object>>(path, data: data); await LCCore.HttpClient.Put<Dictionary<string, object>>(path, data: data);
} }
public static async Task DeclineRequest(LCFriendshipRequest request) { public static async Task DeclineRequest(LCFriendshipRequest request) {
@ -41,7 +42,7 @@ namespace LeanCloud.Storage {
throw new ArgumentNullException(nameof(request)); throw new ArgumentNullException(nameof(request));
} }
string path = $"users/friendshipRequests/{request.ObjectId}/decline"; string path = $"users/friendshipRequests/{request.ObjectId}/decline";
await LCInternalApplication.HttpClient.Put<Dictionary<string, object>>(path); await LCCore.HttpClient.Put<Dictionary<string, object>>(path);
} }
} }
} }

View File

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using LC.Newtonsoft.Json; using LC.Newtonsoft.Json;
using LeanCloud.Common;
using LeanCloud.Storage.Internal.Object; using LeanCloud.Storage.Internal.Object;
using LeanCloud.Storage.Internal.Operation; using LeanCloud.Storage.Internal.Operation;
using LeanCloud.Storage.Internal.Codec; using LeanCloud.Storage.Internal.Codec;
@ -304,7 +305,7 @@ namespace LeanCloud.Storage {
{ "requests", LCEncoder.Encode(requestList) } { "requests", LCEncoder.Encode(requestList) }
}; };
List<Dictionary<string, object>> results = await LCInternalApplication.HttpClient.Post<List<Dictionary<string, object>>>("batch", data: data); List<Dictionary<string, object>> results = await LCCore.HttpClient.Post<List<Dictionary<string, object>>>("batch", data: data);
List<LCObjectData> resultList = results.Select(item => { List<LCObjectData> resultList = results.Select(item => {
if (item.TryGetValue("error", out object error)) { if (item.TryGetValue("error", out object error)) {
Dictionary<string, object> err = error as Dictionary<string, object>; Dictionary<string, object> err = error as Dictionary<string, object>;
@ -342,8 +343,8 @@ namespace LeanCloud.Storage {
queryParams["where"] = query.BuildWhere(); queryParams["where"] = query.BuildWhere();
} }
Dictionary<string, object> response = ObjectId == null ? Dictionary<string, object> response = ObjectId == null ?
await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>(path, data: LCEncoder.Encode(operationDict) as Dictionary<string, object>, queryParams: queryParams) : await LCCore.HttpClient.Post<Dictionary<string, object>>(path, data: LCEncoder.Encode(operationDict) as Dictionary<string, object>, queryParams: queryParams) :
await LCInternalApplication.HttpClient.Put<Dictionary<string, object>>(path, data: LCEncoder.Encode(operationDict) as Dictionary<string, object>, queryParams: queryParams); await LCCore.HttpClient.Put<Dictionary<string, object>>(path, data: LCEncoder.Encode(operationDict) as Dictionary<string, object>, queryParams: queryParams);
LCObjectData data = LCObjectData.Decode(response); LCObjectData data = LCObjectData.Decode(response);
Merge(data); Merge(data);
return this; return this;
@ -368,7 +369,7 @@ namespace LeanCloud.Storage {
return; return;
} }
string path = $"classes/{ClassName}/{ObjectId}"; string path = $"classes/{ClassName}/{ObjectId}";
await LCInternalApplication.HttpClient.Delete(path); await LCCore.HttpClient.Delete(path);
} }
public static async Task DeleteAll(IEnumerable<LCObject> objects) { public static async Task DeleteAll(IEnumerable<LCObject> objects) {
@ -377,7 +378,7 @@ namespace LeanCloud.Storage {
} }
HashSet<LCObject> objectSet = new HashSet<LCObject>(objects.Where(item => item.ObjectId != null)); HashSet<LCObject> objectSet = new HashSet<LCObject>(objects.Where(item => item.ObjectId != null));
List<Dictionary<string, object>> requestList = objectSet.Select(item => { List<Dictionary<string, object>> requestList = objectSet.Select(item => {
string path = $"/{LCInternalApplication.APIVersion}/classes/{item.ClassName}/{item.ObjectId}"; string path = $"/{LCCore.APIVersion}/classes/{item.ClassName}/{item.ObjectId}";
return new Dictionary<string, object> { return new Dictionary<string, object> {
{ "path", path }, { "path", path },
{ "method", "DELETE" } { "method", "DELETE" }
@ -386,7 +387,7 @@ namespace LeanCloud.Storage {
Dictionary<string, object> data = new Dictionary<string, object> { Dictionary<string, object> data = new Dictionary<string, object> {
{ "requests", LCEncoder.Encode(requestList) } { "requests", LCEncoder.Encode(requestList) }
}; };
await LCInternalApplication.HttpClient.Post<List<object>>("batch", data: data); await LCCore.HttpClient.Post<List<object>>("batch", data: data);
} }
public async Task<LCObject> Fetch(IEnumerable<string> keys = null, IEnumerable<string> includes = null) { public async Task<LCObject> Fetch(IEnumerable<string> keys = null, IEnumerable<string> includes = null) {
@ -398,7 +399,7 @@ namespace LeanCloud.Storage {
queryParams["include"] = string.Join(",", includes); queryParams["include"] = string.Join(",", includes);
} }
string path = $"classes/{ClassName}/{ObjectId}"; string path = $"classes/{ClassName}/{ObjectId}";
Dictionary<string, object> response = await LCInternalApplication.HttpClient.Get<Dictionary<string, object>>(path, queryParams: queryParams); Dictionary<string, object> response = await LCCore.HttpClient.Get<Dictionary<string, object>>(path, queryParams: queryParams);
LCObjectData objectData = LCObjectData.Decode(response); LCObjectData objectData = LCObjectData.Decode(response);
Merge(objectData); Merge(objectData);
return this; return this;
@ -411,7 +412,7 @@ namespace LeanCloud.Storage {
IEnumerable<LCObject> uniqueObjects = objects.Where(item => item.ObjectId != null); IEnumerable<LCObject> uniqueObjects = objects.Where(item => item.ObjectId != null);
List<Dictionary<string, object>> requestList = uniqueObjects.Select(item => { List<Dictionary<string, object>> requestList = uniqueObjects.Select(item => {
string path = $"/{LCInternalApplication.APIVersion}/classes/{item.ClassName}/{item.ObjectId}"; string path = $"/{LCCore.APIVersion}/classes/{item.ClassName}/{item.ObjectId}";
return new Dictionary<string, object> { return new Dictionary<string, object> {
{ "path", path }, { "path", path },
{ "method", "GET" } { "method", "GET" }
@ -421,7 +422,7 @@ namespace LeanCloud.Storage {
Dictionary<string, object> data = new Dictionary<string, object> { Dictionary<string, object> data = new Dictionary<string, object> {
{ "requests", LCEncoder.Encode(requestList) } { "requests", LCEncoder.Encode(requestList) }
}; };
List<Dictionary<string, object>> results = await LCInternalApplication.HttpClient.Post<List<Dictionary<string, object>>>("batch", List<Dictionary<string, object>> results = await LCCore.HttpClient.Post<List<Dictionary<string, object>>>("batch",
data: data); data: data);
Dictionary<string, LCObjectData> dict = new Dictionary<string, LCObjectData>(); Dictionary<string, LCObjectData> dict = new Dictionary<string, LCObjectData>();
foreach (Dictionary<string, object> item in results) { foreach (Dictionary<string, object> item in results) {

View File

@ -4,6 +4,7 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Threading.Tasks; using System.Threading.Tasks;
using LeanCloud.Common;
using LeanCloud.Storage.Internal.Query; using LeanCloud.Storage.Internal.Query;
using LeanCloud.Storage.Internal.Object; using LeanCloud.Storage.Internal.Object;
@ -342,7 +343,7 @@ namespace LeanCloud.Storage {
Dictionary<string, object> parameters = BuildParams(); Dictionary<string, object> parameters = BuildParams();
parameters["limit"] = 0; parameters["limit"] = 0;
parameters["count"] = 1; parameters["count"] = 1;
Dictionary<string, object> ret = await LCInternalApplication.HttpClient.Get<Dictionary<string, object>>(path, queryParams: parameters); Dictionary<string, object> ret = await LCCore.HttpClient.Get<Dictionary<string, object>>(path, queryParams: parameters);
return (int)ret["count"]; return (int)ret["count"];
} }
@ -358,14 +359,14 @@ namespace LeanCloud.Storage {
{ "include", includes } { "include", includes }
}; };
} }
Dictionary<string, object> response = await LCInternalApplication.HttpClient.Get<Dictionary<string, object>>(path, queryParams: queryParams); Dictionary<string, object> response = await LCCore.HttpClient.Get<Dictionary<string, object>>(path, queryParams: queryParams);
return DecodeLCObject(response); return DecodeLCObject(response);
} }
public async Task<ReadOnlyCollection<T>> Find() { public async Task<ReadOnlyCollection<T>> Find() {
string path = $"classes/{ClassName}"; string path = $"classes/{ClassName}";
Dictionary<string, object> parameters = BuildParams(); Dictionary<string, object> parameters = BuildParams();
Dictionary<string, object> response = await LCInternalApplication.HttpClient.Get<Dictionary<string, object>>(path, queryParams: parameters); Dictionary<string, object> response = await LCCore.HttpClient.Get<Dictionary<string, object>>(path, queryParams: parameters);
List<object> results = response["results"] as List<object>; List<object> results = response["results"] as List<object>;
List<T> list = new List<T>(); List<T> list = new List<T>();
foreach (object item in results) { foreach (object item in results) {

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using LeanCloud.Common;
namespace LeanCloud.Storage { namespace LeanCloud.Storage {
/// <summary> /// <summary>
@ -43,7 +44,7 @@ namespace LeanCloud.Storage {
data[kv.Key] = kv.Value; data[kv.Key] = kv.Value;
} }
} }
await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>(path, data: data); await LCCore.HttpClient.Post<Dictionary<string, object>>(path, data: data);
} }
/// <summary> /// <summary>
@ -57,7 +58,7 @@ namespace LeanCloud.Storage {
{ "mobilePhoneNumber", mobile }, { "mobilePhoneNumber", mobile },
{ "smsType", "voice" } { "smsType", "voice" }
}; };
await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>(path, data: data); await LCCore.HttpClient.Post<Dictionary<string, object>>(path, data: data);
} }
public static async Task VerifyMobilePhone(string mobile, string code) { public static async Task VerifyMobilePhone(string mobile, string code) {
@ -65,7 +66,7 @@ namespace LeanCloud.Storage {
Dictionary<string, object> data = new Dictionary<string, object> { Dictionary<string, object> data = new Dictionary<string, object> {
{ "mobilePhoneNumber", mobile } { "mobilePhoneNumber", mobile }
}; };
await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>(path, data: data); await LCCore.HttpClient.Post<Dictionary<string, object>>(path, data: data);
} }
} }
} }

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Collections.Generic; using System.Collections.Generic;
using LeanCloud.Common;
using LeanCloud.Storage.Internal.Codec; using LeanCloud.Storage.Internal.Codec;
using LeanCloud.Storage.Internal.Object; using LeanCloud.Storage.Internal.Object;
using LC.Newtonsoft.Json; using LC.Newtonsoft.Json;
@ -109,7 +110,7 @@ namespace LeanCloud.Storage {
} }
formData["query"] = queryData; formData["query"] = queryData;
} }
Dictionary<string, object> response = await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>("statuses", Dictionary<string, object> response = await LCCore.HttpClient.Post<Dictionary<string, object>>("statuses",
data: formData); data: formData);
LCObjectData objectData = LCObjectData.Decode(response); LCObjectData objectData = LCObjectData.Decode(response);
Merge(objectData); Merge(objectData);
@ -125,14 +126,14 @@ namespace LeanCloud.Storage {
LCUser source = (Data[SourceKey] ?? this[SourceKey]) as LCUser; LCUser source = (Data[SourceKey] ?? this[SourceKey]) as LCUser;
if (source != null && source.ObjectId == user.ObjectId) { if (source != null && source.ObjectId == user.ObjectId) {
await LCInternalApplication.HttpClient.Delete($"statuses/{ObjectId}"); await LCCore.HttpClient.Delete($"statuses/{ObjectId}");
} else { } else {
Dictionary<string, object> data = new Dictionary<string, object> { Dictionary<string, object> data = new Dictionary<string, object> {
{ OwnerKey, JsonConvert.SerializeObject(LCEncoder.Encode(user)) }, { OwnerKey, JsonConvert.SerializeObject(LCEncoder.Encode(user)) },
{ InboxTypeKey, InboxType }, { InboxTypeKey, InboxType },
{ MessageIdKey, MessageId } { MessageIdKey, MessageId }
}; };
await LCInternalApplication.HttpClient.Delete("subscribe/statuses/inbox", queryParams: data); await LCCore.HttpClient.Delete("subscribe/statuses/inbox", queryParams: data);
} }
} }
@ -148,7 +149,7 @@ namespace LeanCloud.Storage {
if (!string.IsNullOrEmpty(inboxType)) { if (!string.IsNullOrEmpty(inboxType)) {
queryParams[InboxTypeKey] = inboxType; queryParams[InboxTypeKey] = inboxType;
} }
Dictionary<string, object> response = await LCInternalApplication.HttpClient.Get<Dictionary<string, object>>("subscribe/statuses/count", Dictionary<string, object> response = await LCCore.HttpClient.Get<Dictionary<string, object>>("subscribe/statuses/count",
queryParams: queryParams); queryParams: queryParams);
LCStatusCount statusCount = new LCStatusCount { LCStatusCount statusCount = new LCStatusCount {
Total = (int)response["total"], Total = (int)response["total"],
@ -169,7 +170,7 @@ namespace LeanCloud.Storage {
if (!string.IsNullOrEmpty(inboxType)) { if (!string.IsNullOrEmpty(inboxType)) {
queryParams[InboxTypeKey] = inboxType; queryParams[InboxTypeKey] = inboxType;
} }
await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>("subscribe/statuses/resetUnreadCount", await LCCore.HttpClient.Post<Dictionary<string, object>>("subscribe/statuses/resetUnreadCount",
queryParams:queryParams); queryParams:queryParams);
} }
} }

View File

@ -4,6 +4,7 @@ using System.Collections;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Collections.Generic; using System.Collections.Generic;
using LC.Newtonsoft.Json; using LC.Newtonsoft.Json;
using LeanCloud.Common;
using LeanCloud.Storage.Internal.Codec; using LeanCloud.Storage.Internal.Codec;
using LeanCloud.Storage.Internal.Object; using LeanCloud.Storage.Internal.Object;
@ -41,7 +42,7 @@ namespace LeanCloud.Storage {
{ "maxId", MaxId }, { "maxId", MaxId },
{ "limit", Condition.Limit } { "limit", Condition.Limit }
}; };
Dictionary<string, object> response = await LCInternalApplication.HttpClient.Get<Dictionary<string, object>>("subscribe/statuses", Dictionary<string, object> response = await LCCore.HttpClient.Get<Dictionary<string, object>>("subscribe/statuses",
queryParams: queryParams); queryParams: queryParams);
List<object> results = response["results"] as List<object>; List<object> results = response["results"] as List<object>;
List<LCStatus> statuses = new List<LCStatus>(); List<LCStatus> statuses = new List<LCStatus>();

View File

@ -0,0 +1,31 @@
using System;
using LeanCloud.Common;
namespace LeanCloud.Storage {
public class LCStorage {
private const string SessionHeaderKey = "X-LC-Session";
public static void Initialize(string appId,
string appKey,
string server = null,
string masterKey = null) {
LCCore.Initialize(appId, appKey, server, masterKey);
LCCore.HttpClient.AddRuntimeHeaderTask(SessionHeaderKey, async () => {
LCUser currentUser = await LCUser.GetCurrent();
if (currentUser == null) {
return null;
}
return currentUser.SessionToken;
});
// 注册 LeanCloud 内部子类化类型
LCObject.RegisterSubclass(LCUser.CLASS_NAME, () => new LCUser());
LCObject.RegisterSubclass(LCRole.CLASS_NAME, () => new LCRole());
LCObject.RegisterSubclass(LCFile.CLASS_NAME, () => new LCFile());
LCObject.RegisterSubclass(LCStatus.CLASS_NAME, () => new LCStatus());
LCObject.RegisterSubclass(LCFriendshipRequest.CLASS_NAME, () => new LCFriendshipRequest());
}
}
}

View File

@ -2,6 +2,7 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using LeanCloud.Common;
using LeanCloud.Storage.Internal.Object; using LeanCloud.Storage.Internal.Object;
namespace LeanCloud.Storage { namespace LeanCloud.Storage {
@ -83,13 +84,13 @@ namespace LeanCloud.Storage {
return currentUser; return currentUser;
} }
string data = await LCInternalApplication.StorageController.ReadText(USER_DATA); string data = await LCCore.PersistenceController.ReadText(USER_DATA);
if (!string.IsNullOrEmpty(data)) { if (!string.IsNullOrEmpty(data)) {
try { try {
currentUser = ParseObject(data) as LCUser; currentUser = ParseObject(data) as LCUser;
} catch (Exception e) { } catch (Exception e) {
LCLogger.Error(e); LCLogger.Error(e);
await LCInternalApplication.StorageController.Delete(USER_DATA); await LCCore.PersistenceController.Delete(USER_DATA);
} }
} }
return currentUser; return currentUser;
@ -137,7 +138,7 @@ namespace LeanCloud.Storage {
Dictionary<string, object> data = new Dictionary<string, object> { Dictionary<string, object> data = new Dictionary<string, object> {
{ "mobilePhoneNumber", mobile } { "mobilePhoneNumber", mobile }
}; };
await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>("requestLoginSmsCode", data: data); await LCCore.HttpClient.Post<Dictionary<string, object>>("requestLoginSmsCode", data: data);
} }
/// <summary> /// <summary>
@ -157,7 +158,7 @@ namespace LeanCloud.Storage {
{ "mobilePhoneNumber", mobile }, { "mobilePhoneNumber", mobile },
{ "smsCode", code } { "smsCode", code }
}; };
Dictionary<string, object> response = await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>("usersByMobilePhone", data: data); Dictionary<string, object> response = await LCCore.HttpClient.Post<Dictionary<string, object>>("usersByMobilePhone", data: data);
LCObjectData objectData = LCObjectData.Decode(response); LCObjectData objectData = LCObjectData.Decode(response);
currentUser = new LCUser(objectData); currentUser = new LCUser(objectData);
@ -370,7 +371,7 @@ namespace LeanCloud.Storage {
Dictionary<string, object> data = new Dictionary<string, object> { Dictionary<string, object> data = new Dictionary<string, object> {
{ "email", email } { "email", email }
}; };
await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>("requestEmailVerify", data: data); await LCCore.HttpClient.Post<Dictionary<string, object>>("requestEmailVerify", data: data);
} }
/// <summary> /// <summary>
@ -385,7 +386,7 @@ namespace LeanCloud.Storage {
Dictionary<string, object> data = new Dictionary<string, object> { Dictionary<string, object> data = new Dictionary<string, object> {
{ "mobilePhoneNumber", mobile } { "mobilePhoneNumber", mobile }
}; };
await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>("requestMobilePhoneVerify", data: data); await LCCore.HttpClient.Post<Dictionary<string, object>>("requestMobilePhoneVerify", data: data);
} }
/// <summary> /// <summary>
@ -405,7 +406,7 @@ namespace LeanCloud.Storage {
Dictionary<string, object> data = new Dictionary<string, object> { Dictionary<string, object> data = new Dictionary<string, object> {
{ "mobilePhoneNumber", mobile } { "mobilePhoneNumber", mobile }
}; };
await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>(path, data: data); await LCCore.HttpClient.Post<Dictionary<string, object>>(path, data: data);
} }
/// <summary> /// <summary>
@ -420,7 +421,7 @@ namespace LeanCloud.Storage {
Dictionary<string, object> headers = new Dictionary<string, object> { Dictionary<string, object> headers = new Dictionary<string, object> {
{ "X-LC-Session", sessionToken } { "X-LC-Session", sessionToken }
}; };
Dictionary<string, object> response = await LCInternalApplication.HttpClient.Get<Dictionary<string, object>>("users/me", Dictionary<string, object> response = await LCCore.HttpClient.Get<Dictionary<string, object>>("users/me",
headers: headers); headers: headers);
LCObjectData objectData = LCObjectData.Decode(response); LCObjectData objectData = LCObjectData.Decode(response);
currentUser = new LCUser(objectData); currentUser = new LCUser(objectData);
@ -439,7 +440,7 @@ namespace LeanCloud.Storage {
Dictionary<string, object> data = new Dictionary<string, object> { Dictionary<string, object> data = new Dictionary<string, object> {
{ "email", email } { "email", email }
}; };
await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>("requestPasswordReset", await LCCore.HttpClient.Post<Dictionary<string, object>>("requestPasswordReset",
data: data); data: data);
} }
@ -455,7 +456,7 @@ namespace LeanCloud.Storage {
Dictionary<string, object> data = new Dictionary<string, object> { Dictionary<string, object> data = new Dictionary<string, object> {
{ "mobilePhoneNumber", mobile } { "mobilePhoneNumber", mobile }
}; };
await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>("requestPasswordResetBySmsCode", await LCCore.HttpClient.Post<Dictionary<string, object>>("requestPasswordResetBySmsCode",
data: data); data: data);
} }
@ -480,7 +481,7 @@ namespace LeanCloud.Storage {
{ "mobilePhoneNumber", mobile }, { "mobilePhoneNumber", mobile },
{ "password", newPassword } { "password", newPassword }
}; };
await LCInternalApplication.HttpClient.Put<Dictionary<string, object>>($"resetPasswordBySmsCode/{code}", await LCCore.HttpClient.Put<Dictionary<string, object>>($"resetPasswordBySmsCode/{code}",
data: data); data: data);
} }
@ -501,7 +502,7 @@ namespace LeanCloud.Storage {
{ "old_password", oldPassword }, { "old_password", oldPassword },
{ "new_password", newPassword } { "new_password", newPassword }
}; };
Dictionary<string, object> response = await LCInternalApplication.HttpClient.Put<Dictionary<string, object>>( Dictionary<string, object> response = await LCCore.HttpClient.Put<Dictionary<string, object>>(
$"users/{ObjectId}/updatePassword", data:data); $"users/{ObjectId}/updatePassword", data:data);
LCObjectData objectData = LCObjectData.Decode(response); LCObjectData objectData = LCObjectData.Decode(response);
Merge(objectData); Merge(objectData);
@ -513,7 +514,7 @@ namespace LeanCloud.Storage {
public static Task Logout() { public static Task Logout() {
currentUser = null; currentUser = null;
// 清理持久化数据 // 清理持久化数据
return LCInternalApplication.StorageController.Delete(USER_DATA); return LCCore.PersistenceController.Delete(USER_DATA);
} }
/// <summary> /// <summary>
@ -525,7 +526,7 @@ namespace LeanCloud.Storage {
return false; return false;
} }
try { try {
await LCInternalApplication.HttpClient.Get<Dictionary<string, object>>("users/me"); await LCCore.HttpClient.Get<Dictionary<string, object>>("users/me");
return true; return true;
} catch (Exception) { } catch (Exception) {
return false; return false;
@ -578,7 +579,7 @@ namespace LeanCloud.Storage {
} }
static async Task<LCUser> Login(Dictionary<string, object> data) { static async Task<LCUser> Login(Dictionary<string, object> data) {
Dictionary<string, object> response = await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>("login", data: data); Dictionary<string, object> response = await LCCore.HttpClient.Post<Dictionary<string, object>>("login", data: data);
LCObjectData objectData = LCObjectData.Decode(response); LCObjectData objectData = LCObjectData.Decode(response);
currentUser = new LCUser(objectData); currentUser = new LCUser(objectData);
@ -592,7 +593,7 @@ namespace LeanCloud.Storage {
{ authType, data } { authType, data }
}; };
string path = failOnNotExist ? "users?failOnNotExist=true" : "users"; string path = failOnNotExist ? "users?failOnNotExist=true" : "users";
Dictionary<string, object> response = await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>(path, data: new Dictionary<string, object> { Dictionary<string, object> response = await LCCore.HttpClient.Post<Dictionary<string, object>>(path, data: new Dictionary<string, object> {
{ "authData", authData } { "authData", authData }
}); });
LCObjectData objectData = LCObjectData.Decode(response); LCObjectData objectData = LCObjectData.Decode(response);
@ -612,7 +613,7 @@ namespace LeanCloud.Storage {
private static async Task SaveToLocal() { private static async Task SaveToLocal() {
try { try {
string json = currentUser.ToString(); string json = currentUser.ToString();
await LCInternalApplication.StorageController.WriteText(USER_DATA, json); await LCCore.PersistenceController.WriteText(USER_DATA, json);
} catch (Exception e) { } catch (Exception e) {
LCLogger.Error(e.Message); LCLogger.Error(e.Message);
} }
@ -634,7 +635,7 @@ namespace LeanCloud.Storage {
if (!string.IsNullOrEmpty(captchaToken)) { if (!string.IsNullOrEmpty(captchaToken)) {
data["validate_token"] = captchaToken; data["validate_token"] = captchaToken;
} }
await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>(path, data: data); await LCCore.HttpClient.Post<Dictionary<string, object>>(path, data: data);
} }
/// <summary> /// <summary>
@ -649,7 +650,7 @@ namespace LeanCloud.Storage {
{ "mobilePhoneNumber", mobile }, { "mobilePhoneNumber", mobile },
{ "code", code } { "code", code }
}; };
await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>(path, data: data); await LCCore.HttpClient.Post<Dictionary<string, object>>(path, data: data);
} }
/// <summary> /// <summary>
@ -663,7 +664,7 @@ namespace LeanCloud.Storage {
throw new ArgumentNullException(nameof(targetId)); throw new ArgumentNullException(nameof(targetId));
} }
string path = $"users/self/friendship/{targetId}"; string path = $"users/self/friendship/{targetId}";
await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>(path, data: attrs); await LCCore.HttpClient.Post<Dictionary<string, object>>(path, data: attrs);
} }
/// <summary> /// <summary>
@ -676,7 +677,7 @@ namespace LeanCloud.Storage {
throw new ArgumentNullException(nameof(targetId)); throw new ArgumentNullException(nameof(targetId));
} }
string path = $"users/self/friendship/{targetId}"; string path = $"users/self/friendship/{targetId}";
await LCInternalApplication.HttpClient.Delete(path); await LCCore.HttpClient.Delete(path);
} }
/// <summary> /// <summary>
@ -716,7 +717,7 @@ namespace LeanCloud.Storage {
queryParams["include"] = string.Join(",", includes); queryParams["include"] = string.Join(",", includes);
} }
string path = $"users/{ObjectId}/followersAndFollowees"; string path = $"users/{ObjectId}/followersAndFollowees";
Dictionary<string, object> response = await LCInternalApplication.HttpClient.Get<Dictionary<string, object>>(path, Dictionary<string, object> response = await LCCore.HttpClient.Get<Dictionary<string, object>>(path,
queryParams: queryParams); queryParams: queryParams);
LCFollowersAndFollowees result = new LCFollowersAndFollowees(); LCFollowersAndFollowees result = new LCFollowersAndFollowees();
if (response.TryGetValue("followers", out object followersObj) && if (response.TryGetValue("followers", out object followersObj) &&

View File

@ -1,7 +1,7 @@
/// <summary> namespace LeanCloud.Storage {
/// <summary>
/// LCUser UnionID login parameters. /// LCUser UnionID login parameters.
/// </summary> /// </summary>
namespace LeanCloud.Storage {
public class LCUserAuthDataLoginOption { public class LCUserAuthDataLoginOption {
/// <summary> /// <summary>
/// The platform of the UnionID. /// The platform of the UnionID.

View File

@ -4,6 +4,7 @@ using System.Linq;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Collections.Generic; using System.Collections.Generic;
using LeanCloud.Common;
using LeanCloud.Storage.Internal.Codec; using LeanCloud.Storage.Internal.Codec;
namespace LeanCloud.Storage { namespace LeanCloud.Storage {
@ -68,7 +69,7 @@ namespace LeanCloud.Storage {
{ "updateStrategy", updateStrategy.ToString().ToLower() }, { "updateStrategy", updateStrategy.ToString().ToLower() },
}; };
string path = "leaderboard/leaderboards"; string path = "leaderboard/leaderboards";
Dictionary<string, object> result = await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>(path, Dictionary<string, object> result = await LCCore.HttpClient.Post<Dictionary<string, object>>(path,
data:data); data:data);
LCLeaderboard leaderboard = new LCLeaderboard(); LCLeaderboard leaderboard = new LCLeaderboard();
leaderboard.Merge(result); leaderboard.Merge(result);
@ -112,7 +113,7 @@ namespace LeanCloud.Storage {
if (overwrite) { if (overwrite) {
path = $"{path}?overwrite=1"; path = $"{path}?overwrite=1";
} }
Dictionary<string, object> result = await LCInternalApplication.HttpClient.Post<Dictionary<string, object>>(path, Dictionary<string, object> result = await LCCore.HttpClient.Post<Dictionary<string, object>>(path,
data: data); data: data);
if (result.TryGetValue("results", out object results) && if (result.TryGetValue("results", out object results) &&
results is List<object> list) { results is List<object> list) {
@ -137,7 +138,7 @@ namespace LeanCloud.Storage {
string names = string.Join(",", statisticNames); string names = string.Join(",", statisticNames);
path = $"{path}?statistics={names}"; path = $"{path}?statistics={names}";
} }
Dictionary<string, object> result = await LCInternalApplication.HttpClient.Get<Dictionary<string, object>>(path); Dictionary<string, object> result = await LCCore.HttpClient.Get<Dictionary<string, object>>(path);
if (result.TryGetValue("results", out object results) && if (result.TryGetValue("results", out object results) &&
results is List<object> list) { results is List<object> list) {
List<LCStatistic> statistics = new List<LCStatistic>(); List<LCStatistic> statistics = new List<LCStatistic>();
@ -161,7 +162,7 @@ namespace LeanCloud.Storage {
} }
string names = string.Join(",", statisticNames); string names = string.Join(",", statisticNames);
string path = $"leaderboard/users/{user.ObjectId}/statistics?statistics={names}"; string path = $"leaderboard/users/{user.ObjectId}/statistics?statistics={names}";
await LCInternalApplication.HttpClient.Delete(path); await LCCore.HttpClient.Delete(path);
} }
/// <summary> /// <summary>
@ -179,7 +180,7 @@ namespace LeanCloud.Storage {
throw new ArgumentOutOfRangeException(nameof(limit)); throw new ArgumentOutOfRangeException(nameof(limit));
} }
string path = $"leaderboard/leaderboards/{StatisticName}/archives?skip={skip}&limit={limit}"; string path = $"leaderboard/leaderboards/{StatisticName}/archives?skip={skip}&limit={limit}";
Dictionary<string, object> result = await LCInternalApplication.HttpClient.Get<Dictionary<string, object>>(path); Dictionary<string, object> result = await LCCore.HttpClient.Get<Dictionary<string, object>>(path);
if (result.TryGetValue("results", out object results) && if (result.TryGetValue("results", out object results) &&
results is List<object> list) { results is List<object> list) {
List<LCLeaderboardArchive> archives = new List<LCLeaderboardArchive>(); List<LCLeaderboardArchive> archives = new List<LCLeaderboardArchive>();
@ -235,7 +236,7 @@ namespace LeanCloud.Storage {
string statistics = string.Join(",", includeStatistics); string statistics = string.Join(",", includeStatistics);
path = $"{path}&includeStatistics={statistics}"; path = $"{path}&includeStatistics={statistics}";
} }
Dictionary<string, object> result = await LCInternalApplication.HttpClient.Get<Dictionary<string, object>>(path); Dictionary<string, object> result = await LCCore.HttpClient.Get<Dictionary<string, object>>(path);
if (result.TryGetValue("results", out object results) && if (result.TryGetValue("results", out object results) &&
results is List<object> list) { results is List<object> list) {
List<LCRanking> rankings = new List<LCRanking>(); List<LCRanking> rankings = new List<LCRanking>();
@ -254,7 +255,7 @@ namespace LeanCloud.Storage {
{ "updateStrategy", updateStrategy.ToString().ToLower() } { "updateStrategy", updateStrategy.ToString().ToLower() }
}; };
string path = $"leaderboard/leaderboards/{StatisticName}"; string path = $"leaderboard/leaderboards/{StatisticName}";
Dictionary<string, object> result = await LCInternalApplication.HttpClient.Put<Dictionary<string, object>>(path, Dictionary<string, object> result = await LCCore.HttpClient.Put<Dictionary<string, object>>(path,
data: data); data: data);
if (result.TryGetValue("updateStrategy", out object strategy) && if (result.TryGetValue("updateStrategy", out object strategy) &&
Enum.TryParse(strategy as string, true, out LCLeaderboardUpdateStrategy s)) { Enum.TryParse(strategy as string, true, out LCLeaderboardUpdateStrategy s)) {
@ -269,7 +270,7 @@ namespace LeanCloud.Storage {
{ "versionChangeInterval", versionChangeInterval.ToString().ToLower() } { "versionChangeInterval", versionChangeInterval.ToString().ToLower() }
}; };
string path = $"leaderboard/leaderboards/{StatisticName}"; string path = $"leaderboard/leaderboards/{StatisticName}";
Dictionary<string, object> result = await LCInternalApplication.HttpClient.Put<Dictionary<string, object>>(path, Dictionary<string, object> result = await LCCore.HttpClient.Put<Dictionary<string, object>>(path,
data: data); data: data);
if (result.TryGetValue("versionChangeInterval", out object interval) && if (result.TryGetValue("versionChangeInterval", out object interval) &&
Enum.TryParse(interval as string, true, out LCLeaderboardVersionChangeInterval i)) { Enum.TryParse(interval as string, true, out LCLeaderboardVersionChangeInterval i)) {
@ -284,7 +285,7 @@ namespace LeanCloud.Storage {
/// <returns></returns> /// <returns></returns>
public async Task<LCLeaderboard> Fetch() { public async Task<LCLeaderboard> Fetch() {
string path = $"leaderboard/leaderboards/{StatisticName}"; string path = $"leaderboard/leaderboards/{StatisticName}";
Dictionary<string, object> result = await LCInternalApplication.HttpClient.Get<Dictionary<string, object>>(path); Dictionary<string, object> result = await LCCore.HttpClient.Get<Dictionary<string, object>>(path);
Merge(result); Merge(result);
return this; return this;
} }
@ -295,7 +296,7 @@ namespace LeanCloud.Storage {
/// <returns></returns> /// <returns></returns>
public async Task<LCLeaderboard> Reset() { public async Task<LCLeaderboard> Reset() {
string path = $"leaderboard/leaderboards/{StatisticName}/incrementVersion"; string path = $"leaderboard/leaderboards/{StatisticName}/incrementVersion";
Dictionary<string, object> result = await LCInternalApplication.HttpClient.Put<Dictionary<string, object>>(path); Dictionary<string, object> result = await LCCore.HttpClient.Put<Dictionary<string, object>>(path);
Merge(result); Merge(result);
return this; return this;
} }
@ -306,7 +307,7 @@ namespace LeanCloud.Storage {
/// <returns></returns> /// <returns></returns>
public async Task Destroy() { public async Task Destroy() {
string path = $"leaderboard/leaderboards/{StatisticName}"; string path = $"leaderboard/leaderboards/{StatisticName}";
await LCInternalApplication.HttpClient.Delete(path); await LCCore.HttpClient.Delete(path);
} }
private void Merge(Dictionary<string, object> data) { private void Merge(Dictionary<string, object> data) {

View File

@ -11,12 +11,11 @@
<Folder Include="Internal\" /> <Folder Include="Internal\" />
<Folder Include="Internal\Codec\" /> <Folder Include="Internal\Codec\" />
<Folder Include="Internal\File\" /> <Folder Include="Internal\File\" />
<Folder Include="Internal\Http\" />
<Folder Include="Internal\Object\" /> <Folder Include="Internal\Object\" />
<Folder Include="Internal\Operation\" /> <Folder Include="Internal\Operation\" />
<Folder Include="Internal\Query\" /> <Folder Include="Internal\Query\" />
<Folder Include="Leaderboard\" /> <Folder Include="Public\" />
<Folder Include="Internal\Storage\" /> <Folder Include="Public\Leaderboard\" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\Common\Common\Common.csproj"> <ProjectReference Include="..\..\Common\Common\Common.csproj">