com.taptap.sdk.core 4.4.1 → 4.4.3
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/Editor/TapSDKCoreCompile.cs +6 -0
- package/Mobile/Editor/NativeDependencies.xml +2 -2
- package/Mobile/Runtime/TapEventMobile.cs +0 -1
- package/{Standalone/Runtime/Internal/Openlog/Bean.meta → Plugins.meta} +1 -1
- package/Resources/TapMessage.prefab +1 -1
- package/Runtime/Internal/Log/TapLog.cs +1 -1
- package/Runtime/Public/TapTapSDK.cs +11 -3
- package/Runtime/Public/TapTapSdkOptions.cs +0 -4
- package/Standalone/Plugins/macOS/libtapsdkcorecpp.dylib +0 -0
- package/Standalone/Plugins/macOS/libtapsdkcorecpp.dylib.meta +80 -0
- package/Standalone/Plugins/x86/tapsdkcore.dll +0 -0
- package/Standalone/Plugins/x86/tapsdkcore.dll.meta +63 -0
- package/Standalone/{Runtime/Internal/Utils.meta → Plugins/x86.meta} +1 -1
- package/Standalone/Plugins/x86_64/tapsdkcore.dll +0 -0
- package/Standalone/Plugins/x86_64/tapsdkcore.dll.meta +63 -0
- package/{link.xml.meta → Standalone/Plugins/x86_64.meta} +3 -2
- package/Standalone/Runtime/Internal/Http/TapHttp.cs +12 -6
- package/Standalone/Runtime/Internal/Http/TapHttpUtils.cs +22 -6
- package/Standalone/Runtime/Internal/Openlog/TapAppDurationStandalone.cs +121 -0
- package/Standalone/Runtime/Internal/Openlog/{TapOpenlogQueueBase.cs.meta → TapAppDurationStandalone.cs.meta} +1 -1
- package/Standalone/Runtime/Internal/Openlog/TapOpenlogParamConstants.cs +1 -3
- package/Standalone/Runtime/Internal/Openlog/TapOpenlogStandalone.cs +96 -93
- package/Standalone/Runtime/Internal/Openlog/TapOpenlogStartParamConstants.cs +23 -0
- package/Standalone/Runtime/Internal/Openlog/{Bean/TapOpenlogStoreBean.cs.meta → TapOpenlogStartParamConstants.cs.meta} +1 -1
- package/Standalone/Runtime/Internal/Openlog/TapOpenlogWrapper.cs +178 -0
- package/Standalone/Runtime/Internal/Openlog/{Bean/TapOpenlogLogGroup.cs.meta → TapOpenlogWrapper.cs.meta} +1 -1
- package/Standalone/Runtime/Public/TapCoreStandalone.cs +19 -3
- package/Standalone/Runtime/TapSDK.Core.Standalone.Runtime.asmdef +0 -1
- package/package.json +1 -1
- package/Standalone/Runtime/Internal/Openlog/Bean/TapOpenlogLogGroup.cs +0 -39
- package/Standalone/Runtime/Internal/Openlog/Bean/TapOpenlogStoreBean.cs +0 -33
- package/Standalone/Runtime/Internal/Openlog/TapOpenlogHttpClient.cs +0 -153
- package/Standalone/Runtime/Internal/Openlog/TapOpenlogHttpClient.cs.meta +0 -11
- package/Standalone/Runtime/Internal/Openlog/TapOpenlogQueueBase.cs +0 -198
- package/Standalone/Runtime/Internal/Openlog/TapOpenlogQueueBusiness.cs +0 -17
- package/Standalone/Runtime/Internal/Openlog/TapOpenlogQueueBusiness.cs.meta +0 -11
- package/Standalone/Runtime/Internal/Openlog/TapOpenlogQueueTechnology.cs +0 -15
- package/Standalone/Runtime/Internal/Openlog/TapOpenlogQueueTechnology.cs.meta +0 -11
- package/Standalone/Runtime/Internal/Utils/TapProtoBufffer.cs +0 -28
- package/Standalone/Runtime/Internal/Utils/TapProtoBufffer.cs.meta +0 -11
- package/link.xml +0 -4
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
#if UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN
|
|
2
|
-
using System;
|
|
3
|
-
using System.Threading.Tasks;
|
|
4
|
-
using System.Net;
|
|
5
|
-
using System.Net.Http;
|
|
6
|
-
using System.Net.Http.Headers;
|
|
7
|
-
using System.Linq;
|
|
8
|
-
using System.Security.Cryptography;
|
|
9
|
-
using System.Text;
|
|
10
|
-
using TapSDK.Core.Internal.Log;
|
|
11
|
-
using K4os.Compression.LZ4;
|
|
12
|
-
|
|
13
|
-
namespace TapSDK.Core.Standalone.Internal
|
|
14
|
-
{
|
|
15
|
-
public class TapOpenlogHttpClient
|
|
16
|
-
{
|
|
17
|
-
|
|
18
|
-
private static readonly string HOST_CN = "openlog.tapapis.cn";
|
|
19
|
-
private static readonly string HOST_IO = "openlog.tapapis.com";
|
|
20
|
-
|
|
21
|
-
private static string GetHost()
|
|
22
|
-
{
|
|
23
|
-
if (TapCoreStandalone.coreOptions.region == TapTapRegionType.CN)
|
|
24
|
-
{
|
|
25
|
-
return HOST_CN;
|
|
26
|
-
}
|
|
27
|
-
else if (TapCoreStandalone.coreOptions.region == TapTapRegionType.Overseas)
|
|
28
|
-
{
|
|
29
|
-
return HOST_IO;
|
|
30
|
-
}
|
|
31
|
-
else
|
|
32
|
-
{
|
|
33
|
-
return HOST_CN;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
private static TapLog log = new TapLog(module: "Openlog.HttpClient");
|
|
38
|
-
|
|
39
|
-
private static HttpClient client;
|
|
40
|
-
|
|
41
|
-
public TapOpenlogHttpClient()
|
|
42
|
-
{
|
|
43
|
-
client = new HttpClient();
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
public async Task<bool> Post(string path, byte[] content)
|
|
47
|
-
{
|
|
48
|
-
string url = BuildUrl(path);
|
|
49
|
-
var request = new HttpRequestMessage(HttpMethod.Post, url);
|
|
50
|
-
|
|
51
|
-
request.Headers.Add("User-Agent", "TapSDK-Unity/" + TapTapSDK.Version);
|
|
52
|
-
request.Headers.Add("Accept", "*/*");
|
|
53
|
-
request.Headers.Add("x-log-apiversion", "0.6.0");
|
|
54
|
-
request.Headers.Add("x-log-compresstype", "lz4");
|
|
55
|
-
request.Headers.Add("x-log-signaturemethod", "hmac-sha1");
|
|
56
|
-
request.Headers.Add("x-log-timestamp", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString());
|
|
57
|
-
request.Headers.Add("x-log-bodyrawsize", content.Length.ToString());
|
|
58
|
-
|
|
59
|
-
byte[] compressContent = LZ4Compress(content);
|
|
60
|
-
|
|
61
|
-
var contentMD5 = EncryptString(compressContent);
|
|
62
|
-
request.Headers.Add("x-content-md5", contentMD5);
|
|
63
|
-
|
|
64
|
-
string methodPart = request.Method.Method;
|
|
65
|
-
string urlPath = request.RequestUri.LocalPath;
|
|
66
|
-
string headersPart = GetHeadersPart(request.Headers);
|
|
67
|
-
string signParts = methodPart + "\n" + contentMD5 + "\n" + "application/x-protobuf" + "\n" + headersPart + "\n" + urlPath;
|
|
68
|
-
string sign;
|
|
69
|
-
using (var hmac = new HMACSHA1(Encoding.UTF8.GetBytes(TapCoreStandalone.coreOptions.clientToken)))
|
|
70
|
-
{
|
|
71
|
-
byte[] hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(signParts));
|
|
72
|
-
sign = Convert.ToBase64String(hash);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
request.Headers.Add("Authorization", "LOG " + TapCoreStandalone.coreOptions.clientId + ":" + sign);
|
|
76
|
-
|
|
77
|
-
ByteArrayContent requestContent = new ByteArrayContent(compressContent);
|
|
78
|
-
requestContent.Headers.ContentType = new MediaTypeHeaderValue("application/x-protobuf");
|
|
79
|
-
request.Content = requestContent;
|
|
80
|
-
|
|
81
|
-
return await SendRequest(request);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
private static string EncryptString(byte[] str)
|
|
85
|
-
{
|
|
86
|
-
var md5 = MD5.Create();
|
|
87
|
-
byte[] byteOld = str;
|
|
88
|
-
byte[] byteNew = md5.ComputeHash(byteOld);
|
|
89
|
-
var sb = new StringBuilder();
|
|
90
|
-
foreach (byte b in byteNew)
|
|
91
|
-
{
|
|
92
|
-
sb.Append(b.ToString("X2"));
|
|
93
|
-
}
|
|
94
|
-
return sb.ToString();
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
private static byte[] LZ4Compress(byte[] data)
|
|
98
|
-
{
|
|
99
|
-
int maxCompressedLength = LZ4Codec.MaximumOutputSize(data.Length);
|
|
100
|
-
byte[] compressedData = new byte[maxCompressedLength];
|
|
101
|
-
int compressedLength = LZ4Codec.Encode(data, 0, data.Length, compressedData, 0, compressedData.Length);
|
|
102
|
-
|
|
103
|
-
byte[] result = new byte[compressedLength];
|
|
104
|
-
Array.Copy(compressedData, result, compressedLength);
|
|
105
|
-
return result;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
private static string GetHeadersPart(HttpRequestHeaders headers)
|
|
109
|
-
{
|
|
110
|
-
var headerKeys = headers
|
|
111
|
-
.Where(h => h.Key.StartsWith("x-log-", StringComparison.OrdinalIgnoreCase))
|
|
112
|
-
.OrderBy(h => h.Key.ToLowerInvariant())
|
|
113
|
-
.Select(h => $"{h.Key.ToLowerInvariant()}:{string.Join(",", h.Value)}")
|
|
114
|
-
.ToList();
|
|
115
|
-
|
|
116
|
-
return string.Join("\n", headerKeys);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
private async Task<bool> SendRequest(HttpRequestMessage request)
|
|
120
|
-
{
|
|
121
|
-
HttpResponseMessage response;
|
|
122
|
-
try
|
|
123
|
-
{
|
|
124
|
-
response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
|
|
125
|
-
request.Dispose();
|
|
126
|
-
}
|
|
127
|
-
catch (HttpRequestException e)
|
|
128
|
-
{
|
|
129
|
-
log.Warning($"Request error", e.ToString());
|
|
130
|
-
return false;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
if (response.IsSuccessStatusCode || (response.StatusCode >= HttpStatusCode.BadRequest && response.StatusCode < HttpStatusCode.InternalServerError))
|
|
134
|
-
{
|
|
135
|
-
response.Dispose();
|
|
136
|
-
return true;
|
|
137
|
-
}
|
|
138
|
-
else
|
|
139
|
-
{
|
|
140
|
-
log.Warning($"SendOpenlog failed", response.StatusCode.ToString());
|
|
141
|
-
response.Dispose();
|
|
142
|
-
return false;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
private static string BuildUrl(string path)
|
|
147
|
-
{
|
|
148
|
-
string url = $"https://{GetHost()}/{path}?client_id={TapCoreStandalone.coreOptions.clientId}";
|
|
149
|
-
return url;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
#endif
|
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
#if UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN
|
|
3
|
-
using System;
|
|
4
|
-
using System.Collections.Generic;
|
|
5
|
-
using System.IO;
|
|
6
|
-
using System.Linq;
|
|
7
|
-
using System.Threading;
|
|
8
|
-
using TapSDK.Core.Internal.Log;
|
|
9
|
-
using UnityEngine;
|
|
10
|
-
using Newtonsoft.Json;
|
|
11
|
-
using TapSDK.Core.Standalone.Internal.Openlog;
|
|
12
|
-
using ProtoBuf;
|
|
13
|
-
|
|
14
|
-
namespace TapSDK.Core.Standalone.Internal
|
|
15
|
-
{
|
|
16
|
-
public abstract class TapOpenlogQueueBase
|
|
17
|
-
{
|
|
18
|
-
private TapLog log;
|
|
19
|
-
private string module;
|
|
20
|
-
private string persistentDataPath = Application.persistentDataPath;
|
|
21
|
-
private Queue<TapOpenlogStoreBean> queue = new Queue<TapOpenlogStoreBean>();
|
|
22
|
-
private TapOpenlogHttpClient httpClient = new TapOpenlogHttpClient();
|
|
23
|
-
private const int MaxEvents = 50;
|
|
24
|
-
private const int MaxBatchSize = 200;
|
|
25
|
-
private const float SendInterval = 15;
|
|
26
|
-
private Timer timer;
|
|
27
|
-
private int queueCount => queue.Count;
|
|
28
|
-
|
|
29
|
-
protected abstract string GetUrlPath();
|
|
30
|
-
protected abstract string GetEventFilePath();
|
|
31
|
-
|
|
32
|
-
public TapOpenlogQueueBase(string module)
|
|
33
|
-
{
|
|
34
|
-
this.module = module;
|
|
35
|
-
log = new TapLog(module: "Openlog." + module);
|
|
36
|
-
// 加载未发送的事件
|
|
37
|
-
LoadStorageLogs();
|
|
38
|
-
SendEventsAsync();
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
public void Enqueue(TapOpenlogStoreBean bean)
|
|
42
|
-
{
|
|
43
|
-
// 将事件添加到队列
|
|
44
|
-
queue.Enqueue(bean);
|
|
45
|
-
SaveEvents();
|
|
46
|
-
|
|
47
|
-
// 检查队列大小
|
|
48
|
-
if (queueCount >= MaxEvents)
|
|
49
|
-
{
|
|
50
|
-
log.Log("队列大小超过最大值 = " + queueCount);
|
|
51
|
-
SendEventsAsync();
|
|
52
|
-
log.Log("队列大小超过最大值 end");
|
|
53
|
-
}
|
|
54
|
-
else
|
|
55
|
-
{
|
|
56
|
-
ResetTimer();
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
public async void SendEventsAsync()
|
|
61
|
-
{
|
|
62
|
-
if (queueCount == 0)
|
|
63
|
-
{
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
var eventsToSend = new List<TapOpenlogStoreBean>();
|
|
67
|
-
LogGroup logGroup = new LogGroup();
|
|
68
|
-
logGroup.Logs = new List<Log>();
|
|
69
|
-
for (int i = 0; i < MaxBatchSize && queueCount > 0; i++)
|
|
70
|
-
{
|
|
71
|
-
TapOpenlogStoreBean bean = queue.Dequeue();
|
|
72
|
-
eventsToSend.Add(bean);
|
|
73
|
-
|
|
74
|
-
Log log = new Log();
|
|
75
|
-
log.Time = (uint)(bean.timestamp / 1000);
|
|
76
|
-
log.Contents = new List<LogContent>();
|
|
77
|
-
foreach (var kvp in bean.props)
|
|
78
|
-
{
|
|
79
|
-
LogContent logContent = new LogContent
|
|
80
|
-
{
|
|
81
|
-
Key = kvp.Key ?? "",
|
|
82
|
-
Value = kvp.Value ?? ""
|
|
83
|
-
};
|
|
84
|
-
log.Contents.Add(logContent);
|
|
85
|
-
}
|
|
86
|
-
logGroup.Logs.Add(log);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
byte[] bytes;
|
|
90
|
-
using (var stream = new MemoryStream())
|
|
91
|
-
{
|
|
92
|
-
Serializer.Serialize(stream, logGroup);
|
|
93
|
-
bytes = stream.ToArray();
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
var result = await httpClient.Post(GetUrlPath(), content: bytes);
|
|
97
|
-
if (!result)
|
|
98
|
-
{
|
|
99
|
-
foreach (var eventParams in eventsToSend)
|
|
100
|
-
{
|
|
101
|
-
queue.Enqueue(eventParams);
|
|
102
|
-
}
|
|
103
|
-
SaveEvents();
|
|
104
|
-
}
|
|
105
|
-
else
|
|
106
|
-
{
|
|
107
|
-
log.Log("SendEvents success");
|
|
108
|
-
SaveEvents();
|
|
109
|
-
if (queueCount > MaxEvents)
|
|
110
|
-
{
|
|
111
|
-
SendEventsAsync();
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
private void OnTimerElapsed(object state)
|
|
118
|
-
{
|
|
119
|
-
timer.Dispose();
|
|
120
|
-
timer = null;
|
|
121
|
-
SendEventsAsync();
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
private void ResetTimer()
|
|
125
|
-
{
|
|
126
|
-
if (timer == null)
|
|
127
|
-
{
|
|
128
|
-
// 设置计时器,15秒后触发一次
|
|
129
|
-
timer = new Timer(OnTimerElapsed, null, TimeSpan.FromSeconds(SendInterval), Timeout.InfiniteTimeSpan);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
private void LoadStorageLogs()
|
|
134
|
-
{
|
|
135
|
-
string filePath = Path.Combine(persistentDataPath, GetEventFilePath());
|
|
136
|
-
if (File.Exists(filePath))
|
|
137
|
-
{
|
|
138
|
-
string jsonData = File.ReadAllText(filePath);
|
|
139
|
-
if (string.IsNullOrEmpty(jsonData))
|
|
140
|
-
{
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
List<TapOpenlogStoreBean> deserializedData;
|
|
144
|
-
try
|
|
145
|
-
{
|
|
146
|
-
deserializedData = JsonConvert.DeserializeObject<List<TapOpenlogStoreBean>>(jsonData);
|
|
147
|
-
}
|
|
148
|
-
catch (Exception ex)
|
|
149
|
-
{
|
|
150
|
-
log.Warning($"LoadLogs( FileName : {GetEventFilePath()} ) Exception", ex.ToString());
|
|
151
|
-
File.Delete(filePath);
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
if (deserializedData != null && deserializedData.Count > 0)
|
|
155
|
-
{
|
|
156
|
-
foreach (var item in deserializedData)
|
|
157
|
-
{
|
|
158
|
-
queue.Enqueue(item);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
log.Log("LoadStorageLogs end, count = " + queue.Count, JsonConvert.SerializeObject(queue.ToList()));
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
private void SaveEvents()
|
|
166
|
-
{
|
|
167
|
-
try
|
|
168
|
-
{
|
|
169
|
-
if (queue == null)
|
|
170
|
-
{
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
var eventList = queue.ToList();
|
|
175
|
-
string jsonData = JsonConvert.SerializeObject(eventList);
|
|
176
|
-
|
|
177
|
-
if (string.IsNullOrEmpty(GetEventFilePath()))
|
|
178
|
-
{
|
|
179
|
-
log.Log("EventFilePath is null or empty");
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
string filePath = Path.Combine(persistentDataPath, GetEventFilePath());
|
|
184
|
-
if (string.IsNullOrEmpty(filePath))
|
|
185
|
-
{
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
File.WriteAllText(filePath, jsonData);
|
|
190
|
-
}
|
|
191
|
-
catch (Exception ex)
|
|
192
|
-
{
|
|
193
|
-
log.Warning("SaveEvents Exception" + ex.Message);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
#endif
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
#if UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN
|
|
2
|
-
namespace TapSDK.Core.Standalone.Internal
|
|
3
|
-
{
|
|
4
|
-
public class TapOpenlogQueueBusiness : TapOpenlogQueueBase
|
|
5
|
-
{
|
|
6
|
-
private const string eventFilePath = "TapLogBusiness";
|
|
7
|
-
private const string urlPath = "putrecords/tds/tapsdk";
|
|
8
|
-
|
|
9
|
-
public TapOpenlogQueueBusiness() : base("Business")
|
|
10
|
-
{
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
protected override string GetEventFilePath() => eventFilePath;
|
|
14
|
-
protected override string GetUrlPath() => urlPath;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
#endif
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
#if UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN
|
|
2
|
-
namespace TapSDK.Core.Standalone.Internal
|
|
3
|
-
{
|
|
4
|
-
public class TapOpenlogQueueTechnology : TapOpenlogQueueBase
|
|
5
|
-
{
|
|
6
|
-
private const string eventFilePath = "TapLogTechnology";
|
|
7
|
-
private const string urlPath = "putrecords/tds/tapsdk-apm";
|
|
8
|
-
public TapOpenlogQueueTechnology() : base("Technology")
|
|
9
|
-
{
|
|
10
|
-
}
|
|
11
|
-
protected override string GetEventFilePath() => eventFilePath;
|
|
12
|
-
protected override string GetUrlPath() => urlPath;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
#endif
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
// #if UNITY_EDITOR || (!UNITY_ANDROID && !UNITY_IOS)
|
|
2
|
-
// using Google.Protobuf;
|
|
3
|
-
|
|
4
|
-
// namespace TapSDK.Core.Standalone.Internal.Utils
|
|
5
|
-
// {
|
|
6
|
-
|
|
7
|
-
// public class TapProtoBufffer
|
|
8
|
-
// {
|
|
9
|
-
// public static byte[] Serialize(IMessage message)
|
|
10
|
-
// {
|
|
11
|
-
// return message.ToByteArray();
|
|
12
|
-
// }
|
|
13
|
-
|
|
14
|
-
// public static T DeSerialize<T>(byte[] packet) where T : IMessage, new()
|
|
15
|
-
// {
|
|
16
|
-
// IMessage message = new T();
|
|
17
|
-
// try
|
|
18
|
-
// {
|
|
19
|
-
// return (T)message.Descriptor.Parser.ParseFrom(packet);
|
|
20
|
-
// }
|
|
21
|
-
// catch (System.Exception e)
|
|
22
|
-
// {
|
|
23
|
-
// throw;
|
|
24
|
-
// }
|
|
25
|
-
// }
|
|
26
|
-
// }
|
|
27
|
-
// }
|
|
28
|
-
// #endif
|
package/link.xml
DELETED