dna-api 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of dna-api might be problematic. Click here for more details.

package/dist/index.d.ts CHANGED
@@ -5,9 +5,24 @@ export declare class DNAAPI {
5
5
  dev_code: string;
6
6
  uid: string;
7
7
  token: string;
8
- rsa_public_key: string;
8
+ fetchFn: typeof fetch;
9
9
  is_h5: boolean;
10
- constructor(dev_code: string, uid?: string, token?: string, rsa_public_key?: string, is_h5?: boolean);
10
+ rsa_public_key: string;
11
+ /**
12
+ * 构造函数
13
+ * @param dev_code 设备码
14
+ * @param uid 用户ID
15
+ * @param token 访问令牌
16
+ * @param options 选项
17
+ * @param options.fetchFn 自定义fetch函数
18
+ * @param options.is_h5 是否为H5端
19
+ * @param options.rsa_public_key RSA公钥(base64) 设为空字符串从服务器获取
20
+ */
21
+ constructor(dev_code: string, uid?: string, token?: string, options?: {
22
+ fetchFn?: typeof fetch;
23
+ is_h5?: boolean;
24
+ rsa_public_key?: string;
25
+ });
11
26
  /**
12
27
  * 获取RSA公钥
13
28
  * @returns RSA公钥(base64)
@@ -109,6 +124,7 @@ export interface DNALoginRes {
109
124
  userGameList: UserGame[];
110
125
  isRegister: number;
111
126
  status: number;
127
+ /** 是否完成绑定 0: 未绑定, 1: 已绑定 */
112
128
  isComplete: number;
113
129
  refreshToken: string;
114
130
  }
@@ -130,9 +146,11 @@ export interface DNARole {
130
146
  export interface DNARoleListRes {
131
147
  roles: DNARole[];
132
148
  }
149
+ /** 密函 */
133
150
  export interface DNARoleForToolInstance {
134
151
  id: number;
135
152
  name: string;
153
+ /** 密函编码 */
136
154
  code: string;
137
155
  on: number;
138
156
  }
@@ -146,36 +164,57 @@ declare enum DNAInstanceMHType {
146
164
  }
147
165
  export declare function getDNAInstanceMHType(key: keyof typeof DNAInstanceMHType): DNAInstanceMHType;
148
166
  export interface DNARoleForToolInstanceInfo {
167
+ /** 密函列表 */
149
168
  instances: DNARoleForToolInstance[];
169
+ /** 密函类型 */
150
170
  mh_type?: DNAInstanceMHType;
151
171
  }
152
172
  export interface DraftDoingInfo {
153
173
  draftCompleteNum: number;
154
174
  draftDoingNum: number;
175
+ /** 结束时间 */
155
176
  endTime: string;
177
+ /** 产品id */
156
178
  productId?: number;
179
+ /** 产品名称 */
157
180
  productName: string;
181
+ /** 开始时间 */
158
182
  startTime: string;
159
183
  }
160
184
  export interface DraftInfo {
185
+ /** 正在做的锻造 */
161
186
  draftDoingInfo?: DraftDoingInfo[];
187
+ /** 正在做的锻造数量 */
162
188
  draftDoingNum: number;
189
+ /** 最大锻造数量 */
163
190
  draftMaxNum: number;
164
191
  }
165
192
  export interface DNARoleShortNoteRes {
193
+ /** 迷津进度 */
166
194
  rougeLikeRewardCount: number;
195
+ /** 迷津总数 */
167
196
  rougeLikeRewardTotal: number;
197
+ /** 备忘手记进度 */
168
198
  currentTaskProgress: number;
199
+ /** 备忘手记总数 */
169
200
  maxDailyTaskProgress: number;
201
+ /** 梦魇进度 */
170
202
  hardBossRewardCount: number;
203
+ /** 梦魇总数 */
171
204
  hardBossRewardTotal: number;
205
+ /** 锻造信息 */
172
206
  draftInfo: DraftInfo;
173
207
  }
174
208
  export interface WeaponInsForTool {
209
+ /** 武器类型图标 */
175
210
  elementIcon: string;
211
+ /** 武器图标 */
176
212
  icon: string;
213
+ /** 武器等级 */
177
214
  level: number;
215
+ /** 武器名称 */
178
216
  name: string;
217
+ /** 是否解锁 */
179
218
  unLocked: boolean;
180
219
  weaponEid?: string;
181
220
  weaponId: number;
@@ -183,11 +222,17 @@ export interface WeaponInsForTool {
183
222
  export interface RoleInsForTool {
184
223
  charEid?: string;
185
224
  charId: number;
225
+ /** 元素图标 */
186
226
  elementIcon: string;
227
+ /** 命座等级 */
187
228
  gradeLevel: number;
229
+ /** 角色图标 */
188
230
  icon: string;
231
+ /** 角色等级 */
189
232
  level: number;
233
+ /** 角色名称 */
190
234
  name: string;
235
+ /** 是否解锁 */
191
236
  unLocked: boolean;
192
237
  }
193
238
  export interface RoleAchievement {
@@ -195,67 +240,113 @@ export interface RoleAchievement {
195
240
  paramValue: string;
196
241
  }
197
242
  export interface RoleShowForTool {
243
+ /** 角色列表 */
198
244
  roleChars: RoleInsForTool[];
245
+ /** 武器列表 */
199
246
  langRangeWeapons: WeaponInsForTool[];
247
+ /** 武器列表 */
200
248
  closeWeapons: WeaponInsForTool[];
249
+ /** 等级 */
201
250
  level: number;
251
+ /** 成就列表 */
202
252
  params: RoleAchievement[];
253
+ /** 角色id */
203
254
  roleId: string;
255
+ /** 角色名称 */
204
256
  roleName: string;
205
257
  }
206
258
  export interface RoleInfoForTool {
259
+ /** 角色信息 */
207
260
  roleShow: RoleShowForTool;
208
261
  }
209
262
  export interface DNARoleForToolRes {
263
+ /** 角色信息 */
210
264
  roleInfo: RoleInfoForTool;
265
+ /** 密函 */
211
266
  instanceInfo: DNARoleForToolInstanceInfo[];
212
267
  }
213
268
  export interface RoleAttribute {
269
+ /** 技能范围 */
214
270
  skillRange: string;
271
+ /** 强化值 */
215
272
  strongValue: string;
273
+ /** 技能威力 */
216
274
  skillIntensity: string;
275
+ /** 武器精通 */
217
276
  weaponTags: string[];
277
+ /** 防御 */
218
278
  defense: number;
279
+ /** 仇恨值 */
219
280
  enmityValue: string;
281
+ /** 技能效益 */
220
282
  skillEfficiency: string;
283
+ /** 技能耐久 */
221
284
  skillSustain: string;
285
+ /** 最大生命值 */
222
286
  maxHp: number;
287
+ /** 攻击 */
223
288
  atk: number;
289
+ /** 最大护盾 */
224
290
  maxES: number;
291
+ /** 最大神志 */
225
292
  maxSp: number;
226
293
  }
227
294
  export interface RoleSkill {
295
+ /** 技能id */
228
296
  skillId: number;
297
+ /** 技能图标 */
229
298
  icon: string;
299
+ /** 技能等级 */
230
300
  level: number;
301
+ /** 技能名称 */
231
302
  skillName: string;
232
303
  }
233
304
  export interface RoleTrace {
305
+ /** 溯源图标 */
234
306
  icon: string;
307
+ /** 溯源描述 */
235
308
  description: string;
236
309
  }
237
310
  export interface Mode {
311
+ /** id 没佩戴为-1 */
238
312
  id: number;
313
+ /** 图标 */
239
314
  icon?: string;
315
+ /** 质量 */
240
316
  quality?: number;
317
+ /** 名称 */
241
318
  name?: string;
242
319
  }
243
320
  export interface RoleDetail {
321
+ /** 角色属性 */
244
322
  attribute: RoleAttribute;
323
+ /** 角色技能 */
245
324
  skills: RoleSkill[];
325
+ /** 立绘 */
246
326
  paint: string;
327
+ /** 角色名称 */
247
328
  charName: string;
329
+ /** 元素图标 */
248
330
  elementIcon: string;
331
+ /** 溯源 */
249
332
  traces: RoleTrace[];
333
+ /** 当前魔之楔 */
250
334
  currentVolume: number;
335
+ /** 最大魔之楔 */
251
336
  sumVolume: number;
337
+ /** 角色等级 */
252
338
  level: number;
339
+ /** 角色头像 */
253
340
  icon: string;
341
+ /** 溯源等级 0-6 */
254
342
  gradeLevel: number;
343
+ /** 元素名称 */
255
344
  elementName: string;
345
+ /** mode */
256
346
  modes: Mode[];
257
347
  }
258
348
  export interface DNARoleDetailRes {
349
+ /** 角色详情 */
259
350
  charDetail: RoleDetail;
260
351
  }
261
352
  export interface DNADayAward {
@@ -289,6 +380,7 @@ export interface DNACaSignRoleInfo {
289
380
  roleBoundId: string;
290
381
  }
291
382
  export interface DNAHaveSignInRes {
383
+ /** 已签到天数 */
292
384
  totalSignInDay: number;
293
385
  }
294
386
  export interface DNACalendarSignRes {
@@ -300,13 +392,21 @@ export interface DNACalendarSignRes {
300
392
  roleInfo: DNACaSignRoleInfo;
301
393
  }
302
394
  export interface DNABBSTask {
395
+ /** 备注 */
303
396
  remark: string;
397
+ /** 完成次数 */
304
398
  completeTimes: number;
399
+ /** 需要次数 */
305
400
  times: number;
401
+ /** skipType */
306
402
  skipType: number;
403
+ /** 获取经验 */
307
404
  gainExp: number;
405
+ /** 进度 */
308
406
  process: number;
407
+ /** 获取金币 */
309
408
  gainGold: number;
409
+ /** 任务标识名 */
310
410
  markName?: string;
311
411
  }
312
412
  export interface DNATaskProcessRes {
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import*as g from"node-forge";var F="https://dnabbs-api.yingxiong.com",S=`${F}/user/sdkLogin`,m=`${F}/config/getRsaPublicKey`,w=`${F}/user/login/log`,C=`${F}/role/list`,k=`${F}/role/defaultRoleForTool`,E=`${F}/role/getCharDetail`,h=`${F}/weapon/detail`,l=`${F}/role/getShortNoteInfo`,T=`${F}/encourage/signin/show`,M=`${F}/encourage/signin/signin`,U=`${F}/user/signIn`,D=`${F}/user/haveSignInNew`,y=`${F}/encourage/level/getTaskProcess`,c=`${F}/forum/list`,I=`${F}/forum/getPostDetail`,L=`${F}/forum/like`,N=`${F}/encourage/level/shareTask`,R=`${F}/forum/comment/createComment`,A=`${F}/user/mine`;var K=268;class i{dev_code;uid;token;rsa_public_key;is_h5;constructor(z,J="",Q="",Z="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGpdbezK+eknQZQzPOjp8mr/dP+QHwk8CRkQh6C6qFnfLH3tiyl0pnt3dePuFDnM1PUXGhCkQ157ePJCQgkDU2+mimDmXh0oLFn9zuWSp+U8uLSLX3t3PpJ8TmNCROfUDWvzdbnShqg7JfDmnrOJz49qd234W84nrfTHbzdqeigQIDAQAB",$=!1){this.dev_code=z;this.uid=J;this.token=Q;this.rsa_public_key=Z;this.is_h5=$}async getRsaPublicKey(){if(this.rsa_public_key)return this.rsa_public_key;let z=await this._dna_request(m);if(z.is_success&&z.data){let J=z.data.key;if(typeof J==="string")this.rsa_public_key=J}return this.rsa_public_key}async login(z,J,Q){let Z={mobile:z,code:J,gameList:K},$=await this._dna_request(S,Z,{sign:!0,refer:!0});if($.is_success&&$.data){let q=$.data;if(typeof q.userId==="string")this.uid=q.userId;if(typeof q.token==="string")this.token=q.token}return $}async loginLog(){return await this._dna_request(w)}async getRoleList(){return await this._dna_request(C)}async getDefaultRoleForTool(){let z={type:1};return await this._dna_request(k,z,{sign:!0})}async getRoleDetail(z,J){let Q={charId:z,charEid:J,type:1};return await this._dna_request(E,Q)}async getWeaponDetail(z){let J={weaponId:z,type:1};return await this._dna_request(h,J)}async getShortNoteInfo(){return await this._dna_request(l)}async haveSignIn(){let z={gameId:K};return await this._dna_request(D,z)}async signCalendar(){let z={gameId:K};return await this._dna_request(T,z)}async gameSign(z,J){let Q={dayAwardId:z,periodId:J,signinType:1};return await this._dna_request(M,Q)}async bbsSign(){let z={gameId:K};return await this._dna_request(U,z)}async getTaskProcess(){let z={gameId:K};return await this._dna_request(y,z)}async getPostList(){let z={forumId:46,gameId:K,pageIndex:1,pageSize:20,searchType:1,timeType:0};return await this._dna_request(c,z)}async getPostDetail(z){let J={postId:z};try{return await this._dna_request(I,J)}catch(Q){return console.error("get_post_detail",Q),v.err("请求皎皎角服务失败")}}async doLike(z){let J={forumId:z.gameForumId,gameId:K,likeType:"1",operateType:"1",postCommentId:"",postCommentReplyId:"",postId:z.postId,postType:z.postType,toUserId:z.userId};try{return await this._dna_request(L,J)}catch(Q){return console.error("do_like",Q),v.err("请求皎皎角服务失败")}}async doShare(){let z={gameId:K};try{return await this._dna_request(N,z)}catch(J){return console.error("do_share",J),v.err("请求皎皎角服务失败")}}async doReply(z,J){let Q=JSON.stringify([{content:J,contentType:"1",imgHeight:0,imgWidth:0,url:""}]),Z={postId:z.postId,forumId:z.gameForumId||47,postType:"1",content:Q};return await this._dna_request(R,Z,{sign:!0,refer:!0,params:{toUserId:z.userId}})}async getAnnList(){let z={otherUserId:"709542994134436647",searchType:1,type:2};return await this._dna_request(A,z)}async getHeaders(z){let{payload:J,exparams:Q,dev_code:Z=this.dev_code,refer:$,token:q=this.token}=z||{},j="application/x-www-form-urlencoded; charset=utf-8",V={version:"1.1.3",source:"ios","Content-Type":"application/x-www-form-urlencoded; charset=utf-8","User-Agent":"DoubleHelix/4 CFNetwork/3860.100.1 Darwin/25.0.0"},b={version:"3.11.0",source:"h5","Content-Type":"application/x-www-form-urlencoded; charset=utf-8","User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"},X={...this.is_h5?b:V};if(Z)X.devCode=Z;if($)X.origin="https://dnabbs.yingxiong.com",X.refer="https://dnabbs.yingxiong.com/";if(q)X.token=q;if(typeof J==="object"){let f=t(J);if(Object.assign(J,{sign:f.s,timestamp:f.t}),Q)Object.assign(J,Q);let W=new URLSearchParams;Object.entries(J).forEach(([x,G])=>{W.append(x,String(G))}),J=W.toString();let B=f.k,H=await this.getRsaPublicKey(),P=r(B,H);if(this.is_h5)X.k=P;else X.rk=B,X.key=P}return{headers:X,payload:J}}async _dna_request(z,J,Q){let{method:Z="POST",sign:$,refer:q,params:j,max_retries:V=3,retry_delay:b=1,timeout:X=1e4}=Q||{},f;if($){let{payload:W,headers:B}=await this.getHeaders({payload:J,refer:q,exparams:j});J=W,f=B}else{let{headers:W}=await this.getHeaders();f=W}for(let W=0;W<V;W++)try{let B={method:Z,headers:f,body:J},H=new AbortController,P=setTimeout(()=>H.abort(),X),x=await fetch(z,{...B,signal:H.signal});clearTimeout(P);let G=x.headers.get("content-type")||"",Y;if(G.includes("text/")){let O=await x.text();Y={code:-999,data:O}}else Y=await x.json();if(typeof Y==="object"&&Y!==null)try{if(typeof Y.data==="string")Y.data=JSON.parse(Y.data)}catch(O){}return console.debug(`[DNA] url:[${z}] headers:[${JSON.stringify(f)}] data:[${JSON.stringify(J)}] raw_res:${JSON.stringify(Y)}`),new v(Y)}catch(B){if(console.error(`请求失败: ${B.message}`),W<V-1)await new Promise((H)=>setTimeout(H,b*Math.pow(2,W)))}return v.err("请求服务器失败,已达最大重试次数")}}var u;((j)=>{j.角色="role";j.武器="weapon";j.魔之楔="mzx";j.role="角色";j.weapon="武器";j.mzx="魔之楔"})(u||={});function a(z){return u[z]}var n;((Z)=>{Z[Z.TEXT=1]="TEXT";Z[Z.IMAGE=2]="IMAGE";Z[Z.VIDEO=5]="VIDEO"})(n||={});class v{code=0;msg="";success=!1;data;constructor(z){this.code=z.code||0,this.msg=z.msg||"",this.success=z.success||!1,this.data=z.data}get is_success(){return this.success&&[0,200].includes(this.code)}static err(z,J=-999){return new v({code:J,msg:z,data:void 0,success:!1})}}function r(z,J){try{let Q=[];for(let V=0;V<J.length;V+=64)Q.push(J.slice(V,V+64));let Z=`-----BEGIN PUBLIC KEY-----
2
- ${Q.join(`
1
+ import*as g from"node-forge";var F="https://dnabbs-api.yingxiong.com",S=`${F}/user/sdkLogin`,m=`${F}/config/getRsaPublicKey`,w=`${F}/user/login/log`,C=`${F}/role/list`,k=`${F}/role/defaultRoleForTool`,E=`${F}/role/getCharDetail`,h=`${F}/weapon/detail`,l=`${F}/role/getShortNoteInfo`,T=`${F}/encourage/signin/show`,M=`${F}/encourage/signin/signin`,U=`${F}/user/signIn`,D=`${F}/user/haveSignInNew`,y=`${F}/encourage/level/getTaskProcess`,c=`${F}/forum/list`,I=`${F}/forum/getPostDetail`,L=`${F}/forum/like`,N=`${F}/encourage/level/shareTask`,R=`${F}/forum/comment/createComment`,A=`${F}/user/mine`;var K=268;class i{dev_code;uid;token;fetchFn=fetch;is_h5=!1;rsa_public_key="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGpdbezK+eknQZQzPOjp8mr/dP+QHwk8CRkQh6C6qFnfLH3tiyl0pnt3dePuFDnM1PUXGhCkQ157ePJCQgkDU2+mimDmXh0oLFn9zuWSp+U8uLSLX3t3PpJ8TmNCROfUDWvzdbnShqg7JfDmnrOJz49qd234W84nrfTHbzdqeigQIDAQAB";constructor(z,J="",Z="",Q={}){this.dev_code=z;this.uid=J;this.token=Z;if(Q.fetchFn)this.fetchFn=Q.fetchFn;if(Q.fetchFn)this.fetchFn=Q.fetchFn;if(Q.is_h5!==void 0)this.is_h5=Q.is_h5;if(Q.rsa_public_key!==void 0)this.rsa_public_key=Q.rsa_public_key}async getRsaPublicKey(){if(this.rsa_public_key)return this.rsa_public_key;let z=await this._dna_request(m);if(z.is_success&&z.data){let J=z.data.key;if(typeof J==="string")this.rsa_public_key=J}return this.rsa_public_key}async login(z,J,Z){let Q={mobile:z,code:J,gameList:K},$=await this._dna_request(S,Q,{sign:!0,refer:!0});if($.is_success&&$.data){let q=$.data;if(typeof q.userId==="string")this.uid=q.userId;if(typeof q.token==="string")this.token=q.token}return $}async loginLog(){return await this._dna_request(w)}async getRoleList(){return await this._dna_request(C)}async getDefaultRoleForTool(){let z={type:1};return await this._dna_request(k,z,{sign:!0})}async getRoleDetail(z,J){let Z={charId:z,charEid:J,type:1};return await this._dna_request(E,Z)}async getWeaponDetail(z){let J={weaponId:z,type:1};return await this._dna_request(h,J)}async getShortNoteInfo(){return await this._dna_request(l)}async haveSignIn(){let z={gameId:K};return await this._dna_request(D,z)}async signCalendar(){let z={gameId:K};return await this._dna_request(T,z)}async gameSign(z,J){let Z={dayAwardId:z,periodId:J,signinType:1};return await this._dna_request(M,Z)}async bbsSign(){let z={gameId:K};return await this._dna_request(U,z)}async getTaskProcess(){let z={gameId:K};return await this._dna_request(y,z)}async getPostList(){let z={forumId:46,gameId:K,pageIndex:1,pageSize:20,searchType:1,timeType:0};return await this._dna_request(c,z)}async getPostDetail(z){let J={postId:z};try{return await this._dna_request(I,J)}catch(Z){return console.error("get_post_detail",Z),v.err("请求皎皎角服务失败")}}async doLike(z){let J={forumId:z.gameForumId,gameId:K,likeType:"1",operateType:"1",postCommentId:"",postCommentReplyId:"",postId:z.postId,postType:z.postType,toUserId:z.userId};try{return await this._dna_request(L,J)}catch(Z){return console.error("do_like",Z),v.err("请求皎皎角服务失败")}}async doShare(){let z={gameId:K};try{return await this._dna_request(N,z)}catch(J){return console.error("do_share",J),v.err("请求皎皎角服务失败")}}async doReply(z,J){let Z=JSON.stringify([{content:J,contentType:"1",imgHeight:0,imgWidth:0,url:""}]),Q={postId:z.postId,forumId:z.gameForumId||47,postType:"1",content:Z};return await this._dna_request(R,Q,{sign:!0,refer:!0,params:{toUserId:z.userId}})}async getAnnList(){let z={otherUserId:"709542994134436647",searchType:1,type:2};return await this._dna_request(A,z)}async getHeaders(z){let{payload:J,exparams:Z,dev_code:Q=this.dev_code,refer:$,token:q=this.token}=z||{},j="application/x-www-form-urlencoded; charset=utf-8",V={version:"1.1.3",source:"ios","Content-Type":"application/x-www-form-urlencoded; charset=utf-8","User-Agent":"DoubleHelix/4 CFNetwork/3860.100.1 Darwin/25.0.0"},b={version:"3.11.0",source:"h5","Content-Type":"application/x-www-form-urlencoded; charset=utf-8","User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"},X={...this.is_h5?b:V};if(Q)X.devCode=Q;if($)X.origin="https://dnabbs.yingxiong.com",X.refer="https://dnabbs.yingxiong.com/";if(q)X.token=q;if(typeof J==="object"){let f=s(J);if(Object.assign(J,{sign:f.s,timestamp:f.t}),Z)Object.assign(J,Z);let W=new URLSearchParams;Object.entries(J).forEach(([x,G])=>{W.append(x,String(G))}),J=W.toString();let B=f.k,H=await this.getRsaPublicKey(),P=r(B,H);if(this.is_h5)X.k=P;else X.rk=B,X.key=P}return{headers:X,payload:J}}async _dna_request(z,J,Z){let{method:Q="POST",sign:$,refer:q,params:j,max_retries:V=3,retry_delay:b=1,timeout:X=1e4}=Z||{},f;if($){let{payload:W,headers:B}=await this.getHeaders({payload:J,refer:q,exparams:j});J=W,f=B}else{let{headers:W}=await this.getHeaders();f=W}for(let W=0;W<V;W++)try{let B={method:Q,headers:f,body:J},H=new AbortController,P=setTimeout(()=>H.abort(),X),x=await this.fetchFn(z,{...B,signal:H.signal});clearTimeout(P);let G=x.headers.get("content-type")||"",Y;if(G.includes("text/")){let O=await x.text();Y={code:-999,data:O}}else Y=await x.json();if(typeof Y==="object"&&Y!==null)try{if(typeof Y.data==="string")Y.data=JSON.parse(Y.data)}catch(O){}return console.debug(`[DNA] url:[${z}] headers:[${JSON.stringify(f)}] data:[${JSON.stringify(J)}] raw_res:${JSON.stringify(Y)}`),new v(Y)}catch(B){if(console.error(`请求失败: ${B.message}`),W<V-1)await new Promise((H)=>setTimeout(H,b*Math.pow(2,W)))}return v.err("请求服务器失败,已达最大重试次数")}}var u;((j)=>{j.角色="role";j.武器="weapon";j.魔之楔="mzx";j.role="角色";j.weapon="武器";j.mzx="魔之楔"})(u||={});function t(z){return u[z]}var n;((Q)=>{Q[Q.TEXT=1]="TEXT";Q[Q.IMAGE=2]="IMAGE";Q[Q.VIDEO=5]="VIDEO"})(n||={});class v{code=0;msg="";success=!1;data;constructor(z){this.code=z.code||0,this.msg=z.msg||"",this.success=z.success||!1,this.data=z.data}get is_success(){return this.success&&[0,200].includes(this.code)}static err(z,J=-999){return new v({code:J,msg:z,data:void 0,success:!1})}}function r(z,J){try{let Z=[];for(let V=0;V<J.length;V+=64)Z.push(J.slice(V,V+64));let Q=`-----BEGIN PUBLIC KEY-----
2
+ ${Z.join(`
3
3
  `)}
4
- -----END PUBLIC KEY-----`,$=g.pki.publicKeyFromPem(Z),q=g.util.encodeUtf8(z),j=$.encrypt(q);return g.util.encode64(j)}catch(Q){throw Error(`[DNA] RSA 加密失败: ${Q.message}`)}}function d(z=16){let Q="";for(let Z=0;Z<z;Z++)Q+="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.floor(Math.random()*62));return Q}function p(z){let J=g.md.md5.create();return J.update(z),J.digest().toHex().toUpperCase()}function o(z){function J(Q,Z){let $=Q.split("");for(let q=1;q<Z.length;q+=2){let j=Z[q-1],V=Z[q];if(j>=0&&j<$.length&&V>=0&&V<$.length)[$[j],$[V]]=[$[V],$[j]]}return $.join("")}return J(p(z),[1,13,5,17,7,23])}function _(z,J){let Q=[],Z=Object.keys(z).sort();for(let q of Z){let j=z[q];if(j!==null&&j!==void 0&&j!=="")Q.push(`${q}=${j}`)}let $=Q.join("&");return o(`${$}&${J}`)}function s(z,J){let Q=new TextEncoder,Z=Q.encode(z),$=Q.encode(J),q=[];for(let j=0;j<Z.length;j++){let b=(Z[j]&255)+($[j%$.length]&255);q.push(`@${b}`)}return q.join("")}function t(z,J){let Q=Date.now(),Z={...z,timestamp:Q,token:J},$=d(16),q=_(Z,$);return{s:s(q,$),t:Q,k:$}}export{a as getDNAInstanceMHType,n as PostContentType,i as DNAAPI};
4
+ -----END PUBLIC KEY-----`,$=g.pki.publicKeyFromPem(Q),q=g.util.encodeUtf8(z),j=$.encrypt(q);return g.util.encode64(j)}catch(Z){throw Error(`[DNA] RSA 加密失败: ${Z.message}`)}}function d(z=16){let Z="";for(let Q=0;Q<z;Q++)Z+="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.floor(Math.random()*62));return Z}function _(z){let J=g.md.md5.create();return J.update(z),J.digest().toHex().toUpperCase()}function p(z){function J(Z,Q){let $=Z.split("");for(let q=1;q<Q.length;q+=2){let j=Q[q-1],V=Q[q];if(j>=0&&j<$.length&&V>=0&&V<$.length)[$[j],$[V]]=[$[V],$[j]]}return $.join("")}return J(_(z),[1,13,5,17,7,23])}function o(z,J){let Z=[],Q=Object.keys(z).sort();for(let q of Q){let j=z[q];if(j!==null&&j!==void 0&&j!=="")Z.push(`${q}=${j}`)}let $=Z.join("&");return p(`${$}&${J}`)}function a(z,J){let Z=new TextEncoder,Q=Z.encode(z),$=Z.encode(J),q=[];for(let j=0;j<Q.length;j++){let b=(Q[j]&255)+($[j%$.length]&255);q.push(`@${b}`)}return q.join("")}function s(z,J){let Z=Date.now(),Q={...z,timestamp:Z,token:J},$=d(16),q=o(Q,$);return{s:a(q,$),t:Z,k:$}}export{t as getDNAInstanceMHType,n as PostContentType,i as DNAAPI};
5
5
 
6
- //# debugId=EB6A1CCF9A1F642864756E2164756E21
6
+ //# debugId=47E3A2E533C0FED964756E2164756E21
package/dist/index.js.map CHANGED
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["..\\src\\index.ts"],
4
4
  "sourcesContent": [
5
- "import * as forge from \"node-forge\"\r\n//#region const\r\nconst MAIN_URL = \"https://dnabbs-api.yingxiong.com\"\r\nconst LOGIN_URL = `${MAIN_URL}/user/sdkLogin`\r\nconst GET_RSA_PUBLIC_KEY_URL = `${MAIN_URL}/config/getRsaPublicKey`\r\nconst LOGIN_LOG_URL = `${MAIN_URL}/user/login/log`\r\nconst ROLE_LIST_URL = `${MAIN_URL}/role/list`\r\nconst ROLE_FOR_TOOL_URL = `${MAIN_URL}/role/defaultRoleForTool`\r\nconst ROLE_DETAIL_URL = `${MAIN_URL}/role/getCharDetail`\r\nconst WEAPON_DETAIL_URL = `${MAIN_URL}/weapon/detail`\r\nconst SHORT_NOTE_URL = `${MAIN_URL}/role/getShortNoteInfo`\r\nconst SIGN_CALENDAR_URL = `${MAIN_URL}/encourage/signin/show`\r\nconst GAME_SIGN_URL = `${MAIN_URL}/encourage/signin/signin`\r\nconst BBS_SIGN_URL = `${MAIN_URL}/user/signIn`\r\nconst HAVE_SIGN_IN_URL = `${MAIN_URL}/user/haveSignInNew`\r\nconst GET_TASK_PROCESS_URL = `${MAIN_URL}/encourage/level/getTaskProcess`\r\nconst GET_POST_LIST_URL = `${MAIN_URL}/forum/list`\r\nconst GET_POST_DETAIL_URL = `${MAIN_URL}/forum/getPostDetail`\r\nconst LIKE_POST_URL = `${MAIN_URL}/forum/like`\r\nconst SHARE_POST_URL = `${MAIN_URL}/encourage/level/shareTask`\r\nconst REPLY_POST_URL = `${MAIN_URL}/forum/comment/createComment`\r\nconst ANN_LIST_URL = `${MAIN_URL}/user/mine`\r\n\r\nenum RespCode {\r\n ERROR = -999,\r\n OK_ZERO = 0,\r\n OK_HTTP = 200,\r\n BAD_REQUEST = 400,\r\n SERVER_ERROR = 500,\r\n}\r\n\r\nconst DNA_GAME_ID = 268\r\n//#endregion\r\n\r\n/**\r\n * DNA API类,用于与DNA游戏服务器交互\r\n */\r\nexport class DNAAPI {\r\n constructor(\r\n public dev_code: string,\r\n public uid = \"\",\r\n public token = \"\",\r\n public rsa_public_key = \"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGpdbezK+eknQZQzPOjp8mr/dP+QHwk8CRkQh6C6qFnfLH3tiyl0pnt3dePuFDnM1PUXGhCkQ157ePJCQgkDU2+mimDmXh0oLFn9zuWSp+U8uLSLX3t3PpJ8TmNCROfUDWvzdbnShqg7JfDmnrOJz49qd234W84nrfTHbzdqeigQIDAQAB\",\r\n public is_h5 = false,\r\n ) {}\r\n\r\n /**\r\n * 获取RSA公钥\r\n * @returns RSA公钥(base64)\r\n */\r\n async getRsaPublicKey() {\r\n if (this.rsa_public_key) {\r\n return this.rsa_public_key\r\n }\r\n const res = await this._dna_request<{ key: string }>(GET_RSA_PUBLIC_KEY_URL)\r\n\r\n if (res.is_success && res.data) {\r\n const key = res.data.key\r\n if (typeof key === \"string\") {\r\n this.rsa_public_key = key\r\n }\r\n }\r\n return this.rsa_public_key\r\n }\r\n\r\n /**\r\n * 登录\r\n */\r\n async login(mobile: string, code: string, dev_code: string) {\r\n const data = { mobile, code, gameList: DNA_GAME_ID }\r\n const res = await this._dna_request<DNALoginRes>(LOGIN_URL, data, { sign: true, refer: true })\r\n if (res.is_success && res.data) {\r\n const data = res.data\r\n if (typeof data.userId === \"string\") {\r\n this.uid = data.userId\r\n }\r\n if (typeof data.token === \"string\") {\r\n this.token = data.token\r\n }\r\n }\r\n return res\r\n }\r\n\r\n /**\r\n * 获取登录日志\r\n */\r\n async loginLog() {\r\n return await this._dna_request<DNALoginRes>(LOGIN_LOG_URL)\r\n }\r\n\r\n /**\r\n * 获取角色列表\r\n */\r\n async getRoleList() {\r\n return await this._dna_request<DNARoleListRes>(ROLE_LIST_URL)\r\n }\r\n\r\n /**\r\n * 获取默认角色\r\n */\r\n async getDefaultRoleForTool() {\r\n const data = { type: 1 }\r\n return await this._dna_request<DNARoleForToolRes>(ROLE_FOR_TOOL_URL, data, { sign: true })\r\n }\r\n\r\n /**\r\n * 获取角色详情\r\n */\r\n async getRoleDetail(char_id: string, char_eid: string) {\r\n const data = { charId: char_id, charEid: char_eid, type: 1 }\r\n return await this._dna_request<DNARoleDetailRes>(ROLE_DETAIL_URL, data)\r\n }\r\n\r\n /**\r\n * 获取武器详情\r\n */\r\n async getWeaponDetail(weapon_id: string) {\r\n const data = { weaponId: weapon_id, type: 1 }\r\n return await this._dna_request<DNARoleDetailRes>(WEAPON_DETAIL_URL, data)\r\n }\r\n\r\n /**\r\n * 获取角色简讯\r\n */\r\n async getShortNoteInfo() {\r\n return await this._dna_request<DNARoleShortNoteRes>(SHORT_NOTE_URL)\r\n }\r\n\r\n /**\r\n * 检查是否签到\r\n */\r\n async haveSignIn() {\r\n const data = { gameId: DNA_GAME_ID }\r\n return await this._dna_request<DNAHaveSignInRes>(HAVE_SIGN_IN_URL, data)\r\n }\r\n\r\n /**\r\n * 签到日历\r\n */\r\n async signCalendar() {\r\n const data = { gameId: DNA_GAME_ID }\r\n return await this._dna_request<DNACalendarSignRes>(SIGN_CALENDAR_URL, data)\r\n }\r\n\r\n /**\r\n * 游戏签到\r\n */\r\n async gameSign(day_award_id: number, period: number) {\r\n const data = {\r\n dayAwardId: day_award_id,\r\n periodId: period,\r\n signinType: 1,\r\n }\r\n return await this._dna_request(GAME_SIGN_URL, data)\r\n }\r\n\r\n /**\r\n * 皎皎角签到\r\n */\r\n async bbsSign() {\r\n const data = { gameId: DNA_GAME_ID }\r\n return await this._dna_request(BBS_SIGN_URL, data)\r\n }\r\n\r\n /**\r\n * 获取任务进度\r\n */\r\n async getTaskProcess() {\r\n const data = { gameId: DNA_GAME_ID }\r\n return await this._dna_request<DNATaskProcessRes>(GET_TASK_PROCESS_URL, data)\r\n }\r\n\r\n /**\r\n * 获取帖子列表\r\n */\r\n async getPostList() {\r\n const data = {\r\n forumId: 46, // 全部\r\n gameId: DNA_GAME_ID,\r\n pageIndex: 1,\r\n pageSize: 20,\r\n searchType: 1, // 1:最新 2:热门\r\n timeType: 0,\r\n }\r\n return await this._dna_request<DNAPostListRes>(GET_POST_LIST_URL, data)\r\n }\r\n\r\n /**\r\n * 获取帖子详情\r\n */\r\n async getPostDetail(post_id: string) {\r\n const data = { postId: post_id }\r\n try {\r\n return await this._dna_request<DNAPostDetailRes>(GET_POST_DETAIL_URL, data)\r\n } catch (e) {\r\n console.error(\"get_post_detail\", e as Error)\r\n return DNAApiResponse.err(\"请求皎皎角服务失败\")\r\n }\r\n }\r\n\r\n /**\r\n * 点赞帖子\r\n */\r\n async doLike(post: { gameForumId: string; postId: string; postType: string; userId: string }) {\r\n const data = {\r\n forumId: post.gameForumId,\r\n gameId: DNA_GAME_ID,\r\n likeType: \"1\",\r\n operateType: \"1\",\r\n postCommentId: \"\",\r\n postCommentReplyId: \"\",\r\n postId: post.postId,\r\n postType: post.postType,\r\n toUserId: post.userId,\r\n }\r\n try {\r\n return await this._dna_request(LIKE_POST_URL, data)\r\n } catch (e) {\r\n console.error(\"do_like\", e as Error)\r\n return DNAApiResponse.err(\"请求皎皎角服务失败\")\r\n }\r\n }\r\n\r\n // 分享帖子\r\n async doShare() {\r\n const data = { gameId: DNA_GAME_ID }\r\n try {\r\n return await this._dna_request(SHARE_POST_URL, data)\r\n } catch (e) {\r\n console.error(\"do_share\", e as Error)\r\n return DNAApiResponse.err(\"请求皎皎角服务失败\")\r\n }\r\n }\r\n\r\n // 回复帖子\r\n async doReply(post: Record<string, any>, content: string) {\r\n const content_json = JSON.stringify([\r\n {\r\n content,\r\n contentType: \"1\",\r\n imgHeight: 0,\r\n imgWidth: 0,\r\n url: \"\",\r\n },\r\n ])\r\n const data = {\r\n postId: post.postId,\r\n forumId: post.gameForumId || 47,\r\n postType: \"1\",\r\n content: content_json,\r\n }\r\n\r\n return await this._dna_request(REPLY_POST_URL, data, { sign: true, refer: true, params: { toUserId: post.userId } })\r\n }\r\n\r\n // 获取游戏公告列表\r\n async getAnnList() {\r\n const data = {\r\n otherUserId: \"709542994134436647\",\r\n searchType: 1,\r\n type: 2,\r\n }\r\n return await this._dna_request<DNAPostListRes>(ANN_LIST_URL, data)\r\n }\r\n\r\n async getHeaders(options?: {\r\n payload?: Record<string, any> | string\r\n exparams?: Record<string, any>\r\n dev_code?: string\r\n refer?: boolean\r\n token?: string\r\n }) {\r\n let { payload, exparams, dev_code = this.dev_code, refer, token = this.token } = options || {}\r\n\r\n const CONTENT_TYPE = \"application/x-www-form-urlencoded; charset=utf-8\"\r\n const iosBaseHeader = {\r\n version: \"1.1.3\",\r\n source: \"ios\",\r\n \"Content-Type\": CONTENT_TYPE,\r\n \"User-Agent\": \"DoubleHelix/4 CFNetwork/3860.100.1 Darwin/25.0.0\",\r\n }\r\n const h5BaseHeader = {\r\n version: \"3.11.0\",\r\n source: \"h5\",\r\n \"Content-Type\": CONTENT_TYPE,\r\n \"User-Agent\":\r\n \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36\",\r\n }\r\n // 默认获取ios头\r\n const headers = { ...(this.is_h5 ? h5BaseHeader : iosBaseHeader) } as Record<string, any>\r\n if (dev_code) {\r\n headers.devCode = dev_code\r\n }\r\n if (refer) {\r\n headers.origin = \"https://dnabbs.yingxiong.com\"\r\n headers.refer = \"https://dnabbs.yingxiong.com/\"\r\n }\r\n if (token) {\r\n headers.token = token\r\n }\r\n if (typeof payload === \"object\") {\r\n const si = build_signature(payload)\r\n Object.assign(payload, { sign: si.s, timestamp: si.t })\r\n if (exparams) {\r\n Object.assign(payload, exparams)\r\n }\r\n\r\n const params = new URLSearchParams()\r\n Object.entries(payload).forEach(([key, value]) => {\r\n params.append(key, String(value))\r\n })\r\n payload = params.toString()\r\n\r\n const rk = si.k\r\n const pk = await this.getRsaPublicKey()\r\n const ek = rsa_encrypt(rk, pk)\r\n if (this.is_h5) {\r\n headers.k = ek\r\n } else {\r\n headers.rk = rk\r\n headers.key = ek\r\n }\r\n }\r\n return { headers, payload }\r\n }\r\n\r\n private async _dna_request<T = any>(\r\n url: string,\r\n data?: any,\r\n options?: {\r\n method?: \"GET\" | \"POST\"\r\n sign?: boolean\r\n refer?: boolean\r\n params?: Record<string, any>\r\n max_retries?: number\r\n retry_delay?: number\r\n timeout?: number\r\n },\r\n ): Promise<DNAApiResponse<T>> {\r\n let { method = \"POST\", sign, refer, params, max_retries = 3, retry_delay = 1, timeout = 10000 } = options || {}\r\n let headers: Record<string, any>\r\n if (sign) {\r\n const { payload: p, headers: h } = await this.getHeaders({ payload: data, refer, exparams: params })\r\n data = p\r\n headers = h\r\n } else {\r\n const { headers: h } = await this.getHeaders()\r\n headers = h\r\n }\r\n\r\n for (let attempt = 0; attempt < max_retries; attempt++) {\r\n try {\r\n const fetchOptions: RequestInit = {\r\n method,\r\n headers,\r\n body: data,\r\n }\r\n\r\n // 实现超时控制\r\n const controller = new AbortController()\r\n const timeoutId = setTimeout(() => controller.abort(), timeout)\r\n\r\n const response = await fetch(url, {\r\n ...fetchOptions,\r\n signal: controller.signal,\r\n })\r\n clearTimeout(timeoutId)\r\n\r\n // 获取响应头的 content-type\r\n const contentType = response.headers.get(\"content-type\") || \"\"\r\n let raw_res: any\r\n\r\n // 根据 content-type 处理响应数据\r\n if (contentType.includes(\"text/\")) {\r\n const textData = await response.text()\r\n raw_res = {\r\n code: RespCode.ERROR,\r\n data: textData,\r\n }\r\n } else {\r\n raw_res = await response.json()\r\n }\r\n\r\n if (typeof raw_res === \"object\" && raw_res !== null) {\r\n try {\r\n if (typeof raw_res.data === \"string\") {\r\n raw_res.data = JSON.parse(raw_res.data)\r\n }\r\n } catch (e) {\r\n // 忽略解析错误\r\n }\r\n }\r\n\r\n console.debug(\r\n `[DNA] url:[${url}] headers:[${JSON.stringify(headers)}] data:[${JSON.stringify(data)}] raw_res:${JSON.stringify(raw_res)}`,\r\n )\r\n return new DNAApiResponse<T>(raw_res)\r\n } catch (e) {\r\n console.error(`请求失败: ${(e as Error).message}`)\r\n if (attempt < max_retries - 1) {\r\n await new Promise((resolve) => setTimeout(resolve, retry_delay * Math.pow(2, attempt)))\r\n }\r\n }\r\n }\r\n\r\n return DNAApiResponse.err(\"请求服务器失败,已达最大重试次数\")\r\n }\r\n}\r\n\r\n//#region 接口定义\r\n\r\nexport interface UserGame {\r\n gameId: number // gameId\r\n gameName: string // gameName\r\n}\r\n\r\nexport interface DNALoginRes {\r\n applyCancel?: number // applyCancel\r\n gender?: number // gender\r\n signature?: string // signature\r\n headUrl: string // headUrl\r\n userName: string // userName\r\n userId: string // userId\r\n isOfficial: number // isOfficial\r\n token: string // token\r\n userGameList: UserGame[] // userGameList\r\n isRegister: number // isRegister\r\n status: number // status\r\n isComplete: number // isComplete 是否完成绑定 0: 未绑定, 1: 已绑定\r\n refreshToken: string // refreshToken\r\n}\r\n\r\nexport interface DNARoleShowVo {\r\n roleId: string // roleId\r\n headUrl?: string // headUrl\r\n level?: number // level\r\n roleName?: string // roleName\r\n isDefault?: number // isDefault\r\n roleRegisterTime?: string // roleRegisterTime\r\n boundType?: number // boundType\r\n roleBoundId: string // roleBoundId\r\n}\r\n\r\nexport interface DNARole {\r\n gameName: string // gameName\r\n showVoList: DNARoleShowVo[] // showVoList\r\n gameId: number // gameId\r\n}\r\n\r\nexport interface DNARoleListRes {\r\n roles: DNARole[] // roles\r\n}\r\n\r\nexport interface DNARoleForToolInstance {\r\n id: number // id\r\n name: string // name\r\n code: string // 密函编码\r\n on: number // 0\r\n}\r\n\r\nenum DNAInstanceMHType {\r\n \"角色\" = \"role\",\r\n \"武器\" = \"weapon\",\r\n \"魔之楔\" = \"mzx\",\r\n \"role\" = \"角色\",\r\n \"weapon\" = \"武器\",\r\n \"mzx\" = \"魔之楔\",\r\n}\r\n\r\nexport function getDNAInstanceMHType(key: keyof typeof DNAInstanceMHType) {\r\n return DNAInstanceMHType[key]\r\n}\r\n\r\nexport interface DNARoleForToolInstanceInfo {\r\n instances: DNARoleForToolInstance[] // instances\r\n mh_type?: DNAInstanceMHType // 密函类型\r\n}\r\n\r\nexport interface DraftDoingInfo {\r\n draftCompleteNum: number // draftCompleteNum\r\n draftDoingNum: number // draftDoingNum\r\n endTime: string // 结束时间\r\n productId?: number // productId\r\n productName: string // productName\r\n startTime: string // 开始时间\r\n}\r\n\r\nexport interface DraftInfo {\r\n draftDoingInfo?: DraftDoingInfo[] // draftDoingInfo\r\n draftDoingNum: number // 正在做的锻造\r\n draftMaxNum: number // 最大锻造数量\r\n}\r\n\r\nexport interface DNARoleShortNoteRes {\r\n rougeLikeRewardCount: number // 迷津进度\r\n rougeLikeRewardTotal: number // 迷津总数\r\n currentTaskProgress: number // 备忘手记进度\r\n maxDailyTaskProgress: number // 备忘手记总数\r\n hardBossRewardCount: number // 梦魇进度\r\n hardBossRewardTotal: number // 梦魇总数\r\n draftInfo: DraftInfo // 锻造信息\r\n}\r\n\r\nexport interface WeaponInsForTool {\r\n elementIcon: string // 武器类型图标\r\n icon: string // 武器图标\r\n level: number // 武器等级\r\n name: string // 武器名称\r\n unLocked: boolean // 是否解锁\r\n weaponEid?: string // weaponEid\r\n weaponId: number // weaponId\r\n}\r\n\r\nexport interface RoleInsForTool {\r\n charEid?: string // charEid\r\n charId: number // charId\r\n elementIcon: string // 元素图标\r\n gradeLevel: number // 命座等级\r\n icon: string // 角色图标\r\n level: number // 角色等级\r\n name: string // 角色名称\r\n unLocked: boolean // 是否解锁\r\n}\r\n\r\nexport interface RoleAchievement {\r\n paramKey: string // paramKey\r\n paramValue: string // paramValue\r\n}\r\n\r\nexport interface RoleShowForTool {\r\n roleChars: RoleInsForTool[] // 角色列表\r\n langRangeWeapons: WeaponInsForTool[] // 武器列表\r\n closeWeapons: WeaponInsForTool[] // 武器列表\r\n level: number // 等级\r\n params: RoleAchievement[] // 成就列表\r\n roleId: string // 角色id\r\n roleName: string // 角色名称\r\n}\r\n\r\nexport interface RoleInfoForTool {\r\n roleShow: RoleShowForTool // 角色信息\r\n}\r\n\r\nexport interface DNARoleForToolRes {\r\n roleInfo: RoleInfoForTool // 角色信息\r\n instanceInfo: DNARoleForToolInstanceInfo[] // 密函\r\n}\r\n\r\nexport interface RoleAttribute {\r\n skillRange: string // 技能范围\r\n strongValue: string // strongValue\r\n skillIntensity: string // 技能威力\r\n weaponTags: string[] // 武器精通\r\n defense: number // 防御\r\n enmityValue: string // enmityValue\r\n skillEfficiency: string // 技能效益\r\n skillSustain: string // 技能耐久\r\n maxHp: number // 最大生命值\r\n atk: number // 攻击\r\n maxES: number // 护盾\r\n maxSp: number // 最大神志\r\n}\r\n\r\nexport interface RoleSkill {\r\n skillId: number // 技能id\r\n icon: string // 技能图标\r\n level: number // 技能等级\r\n skillName: string // 技能名称\r\n}\r\n\r\nexport interface RoleTrace {\r\n icon: string // 溯源图标\r\n description: string // 溯源描述\r\n}\r\n\r\nexport interface Mode {\r\n id: number // id 没佩戴为-1\r\n icon?: string // 图标\r\n quality?: number // 质量\r\n name?: string // 名称\r\n}\r\n\r\nexport interface RoleDetail {\r\n attribute: RoleAttribute // 角色属性\r\n skills: RoleSkill[] // 角色技能\r\n paint: string // 立绘\r\n charName: string // 角色名称\r\n elementIcon: string // 元素图标\r\n traces: RoleTrace[] // 溯源\r\n currentVolume: number // 当前魔之楔\r\n sumVolume: number // 最大魔之楔\r\n level: number // 角色等级\r\n icon: string // 角色头像\r\n gradeLevel: number // 溯源等级 0-6\r\n elementName: string // 元素名称\r\n modes: Mode[] // mode\r\n}\r\n\r\nexport interface DNARoleDetailRes {\r\n charDetail: RoleDetail // 角色详情\r\n}\r\n\r\nexport interface DNADayAward {\r\n gameId: number // gameId\r\n periodId: number // periodId\r\n iconUrl: string // iconUrl\r\n id: number // id\r\n dayInPeriod: number // dayInPeriod\r\n updateTime: number // updateTime\r\n awardNum: number // awardNum\r\n thirdProductId: string // thirdProductId\r\n createTime: number // createTime\r\n awardName: string // awardName\r\n}\r\n\r\nexport interface DNACaSignPeriod {\r\n gameId: number // gameId\r\n retryCos: number // retryCos\r\n endDate: number // endDate\r\n id: number // id\r\n startDate: number // startDate\r\n retryTimes: number // retryTimes\r\n overDays: number // overDays\r\n createTime: number // createTime\r\n name: string // name\r\n}\r\n\r\nexport interface DNACaSignRoleInfo {\r\n headUrl: string // headUrl\r\n roleId: string // roleId\r\n roleName: string // roleName\r\n level: number // level\r\n roleBoundId: string // roleBoundId\r\n}\r\n\r\nexport interface DNAHaveSignInRes {\r\n totalSignInDay: number // 已签到天数\r\n}\r\n\r\nexport interface DNACalendarSignRes {\r\n todaySignin: boolean // todaySignin\r\n userGoldNum: number // userGoldNum\r\n dayAward: DNADayAward[] // dayAward\r\n signinTime: number // signinTime\r\n period: DNACaSignPeriod // period\r\n roleInfo: DNACaSignRoleInfo // roleInfo\r\n}\r\n\r\nexport interface DNABBSTask {\r\n remark: string // 备注\r\n completeTimes: number // 完成次数\r\n times: number // 需要次数\r\n skipType: number // skipType\r\n gainExp: number // 获取经验\r\n process: number // 进度\r\n gainGold: number // 获取金币\r\n markName?: string // 任务标识名\r\n}\r\n\r\nexport interface DNATaskProcessRes {\r\n dailyTask: DNABBSTask[] // dailyTask\r\n}\r\n\r\nexport interface DNAPostListRes {\r\n postList: DNAPost[] // posts\r\n}\r\n\r\nexport interface DNAPost {\r\n postId: number // postId\r\n title: string // title\r\n}\r\n\r\nexport interface DNAPostDetailRes {\r\n postDetail: DNAPostDetail // post\r\n}\r\n\r\nexport interface DNAPostDetail {\r\n postId: number // postId\r\n postTime: number // postTime\r\n postContent: DNAPostContent[] // postContent\r\n title: string // title\r\n}\r\n\r\nexport enum PostContentType {\r\n TEXT = 1,\r\n IMAGE = 2,\r\n VIDEO = 5,\r\n}\r\n\r\nexport interface DNAPostContent {\r\n contentType: PostContentType // content\r\n content: string // content\r\n url?: string // url\r\n contentVideo?: DNAPostContentVideo // contentVideo\r\n}\r\n\r\nexport interface DNAPostContentVideo {\r\n videoUrl: string // videoUrl\r\n coverUrl?: string // coverUrl\r\n}\r\n\r\n// interface DNAWikiDetail {\r\n// name: string // name\r\n// }\r\n\r\n// interface DNAWikiRes {\r\n// wikis: DNAWikiDetail[] // wikis\r\n// }\r\n\r\nclass DNAApiResponse<T = any> {\r\n code: number = 0\r\n msg: string = \"\"\r\n success: boolean = false\r\n data?: T\r\n\r\n constructor(raw_data: any) {\r\n this.code = raw_data.code || 0\r\n this.msg = raw_data.msg || \"\"\r\n this.success = raw_data.success || false\r\n this.data = raw_data.data\r\n }\r\n\r\n // 判断是否成功\r\n get is_success() {\r\n return this.success && [RespCode.OK_ZERO, RespCode.OK_HTTP].includes(this.code)\r\n }\r\n\r\n // 错误响应静态方法\r\n static err<T = undefined>(msg: string, code: number = RespCode.ERROR): DNAApiResponse<T> {\r\n return new DNAApiResponse<T>({ code, msg, data: undefined, success: false })\r\n }\r\n}\r\n//#endregion\r\n\r\n//#region utils\r\n\r\n// RSA加密函数\r\nfunction rsa_encrypt(text: string, public_key_b64: string): string {\r\n try {\r\n // 将base64公钥转换为PEM格式\r\n const lines: string[] = []\r\n for (let i = 0; i < public_key_b64.length; i += 64) {\r\n lines.push(public_key_b64.slice(i, i + 64))\r\n }\r\n const pem = `-----BEGIN PUBLIC KEY-----\\n${lines.join(\"\\n\")}\\n-----END PUBLIC KEY-----`\r\n\r\n // 导入PEM格式的RSA公钥\r\n const publicKey = forge.pki.publicKeyFromPem(pem)\r\n\r\n // 执行PKCS1_v1_5加密\r\n const textBytes = forge.util.encodeUtf8(text)\r\n const encrypted = publicKey.encrypt(textBytes)\r\n\r\n return forge.util.encode64(encrypted)\r\n } catch (e) {\r\n throw new Error(`[DNA] RSA 加密失败: ${(e as Error).message}`)\r\n }\r\n}\r\n\r\n// 生成随机字符串\r\nfunction rand_str(length: number = 16): string {\r\n const chars = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\"\r\n let result = \"\"\r\n for (let i = 0; i < length; i++) {\r\n result += chars.charAt(Math.floor(Math.random() * chars.length))\r\n }\r\n return result\r\n}\r\n\r\n// MD5加密并转换为大写\r\nfunction md5_upper(text: string): string {\r\n const md = forge.md.md5.create()\r\n md.update(text)\r\n return md.digest().toHex().toUpperCase()\r\n}\r\n\r\n// 签名哈希函数\r\nfunction signature_hash(text: string): string {\r\n function swap_positions(text: string, positions: number[]): string {\r\n const chars = text.split(\"\")\r\n for (let i = 1; i < positions.length; i += 2) {\r\n const p1 = positions[i - 1]\r\n const p2 = positions[i]\r\n if (p1 >= 0 && p1 < chars.length && p2 >= 0 && p2 < chars.length) {\r\n ;[chars[p1], chars[p2]] = [chars[p2], chars[p1]]\r\n }\r\n }\r\n return chars.join(\"\")\r\n }\r\n\r\n return swap_positions(md5_upper(text), [1, 13, 5, 17, 7, 23])\r\n}\r\n\r\n// 签名函数\r\nfunction sign_fI(data: Record<string, any>, secret: string): string {\r\n const pairs: string[] = []\r\n const sortedKeys = Object.keys(data).sort()\r\n for (const k of sortedKeys) {\r\n const v = data[k]\r\n if (v !== null && v !== undefined && v !== \"\") {\r\n pairs.push(`${k}=${v}`)\r\n }\r\n }\r\n const qs = pairs.join(\"&\")\r\n return signature_hash(`${qs}&${secret}`)\r\n}\r\n\r\n// XOR编码函数\r\nfunction xor_encode(text: string, key: string): string {\r\n const encoder = new TextEncoder()\r\n const tb = encoder.encode(text)\r\n const kb = encoder.encode(key)\r\n const out: string[] = []\r\n for (let i = 0; i < tb.length; i++) {\r\n const b = tb[i]\r\n const e = (b & 255) + (kb[i % kb.length] & 255)\r\n out.push(`@${e}`)\r\n }\r\n return out.join(\"\")\r\n}\r\n\r\n// 构建签名\r\nfunction build_signature(data: Record<string, any>, token?: string): Record<string, any> {\r\n const ts = Date.now()\r\n const sign_data = { ...data, timestamp: ts, token }\r\n const sec = rand_str(16)\r\n const sig = sign_fI(sign_data, sec)\r\n const enc = xor_encode(sig, sec)\r\n return { s: enc, t: ts, k: sec }\r\n}\r\n\r\n//#endregion\r\n"
5
+ "import * as forge from \"node-forge\"\r\n//#region const\r\nconst MAIN_URL = \"https://dnabbs-api.yingxiong.com\"\r\nconst LOGIN_URL = `${MAIN_URL}/user/sdkLogin`\r\nconst GET_RSA_PUBLIC_KEY_URL = `${MAIN_URL}/config/getRsaPublicKey`\r\nconst LOGIN_LOG_URL = `${MAIN_URL}/user/login/log`\r\nconst ROLE_LIST_URL = `${MAIN_URL}/role/list`\r\nconst ROLE_FOR_TOOL_URL = `${MAIN_URL}/role/defaultRoleForTool`\r\nconst ROLE_DETAIL_URL = `${MAIN_URL}/role/getCharDetail`\r\nconst WEAPON_DETAIL_URL = `${MAIN_URL}/weapon/detail`\r\nconst SHORT_NOTE_URL = `${MAIN_URL}/role/getShortNoteInfo`\r\nconst SIGN_CALENDAR_URL = `${MAIN_URL}/encourage/signin/show`\r\nconst GAME_SIGN_URL = `${MAIN_URL}/encourage/signin/signin`\r\nconst BBS_SIGN_URL = `${MAIN_URL}/user/signIn`\r\nconst HAVE_SIGN_IN_URL = `${MAIN_URL}/user/haveSignInNew`\r\nconst GET_TASK_PROCESS_URL = `${MAIN_URL}/encourage/level/getTaskProcess`\r\nconst GET_POST_LIST_URL = `${MAIN_URL}/forum/list`\r\nconst GET_POST_DETAIL_URL = `${MAIN_URL}/forum/getPostDetail`\r\nconst LIKE_POST_URL = `${MAIN_URL}/forum/like`\r\nconst SHARE_POST_URL = `${MAIN_URL}/encourage/level/shareTask`\r\nconst REPLY_POST_URL = `${MAIN_URL}/forum/comment/createComment`\r\nconst ANN_LIST_URL = `${MAIN_URL}/user/mine`\r\n\r\nenum RespCode {\r\n ERROR = -999,\r\n OK_ZERO = 0,\r\n OK_HTTP = 200,\r\n BAD_REQUEST = 400,\r\n SERVER_ERROR = 500,\r\n}\r\n\r\nconst DNA_GAME_ID = 268\r\n//#endregion\r\n\r\n/**\r\n * DNA API类,用于与DNA游戏服务器交互\r\n */\r\nexport class DNAAPI {\r\n public fetchFn = fetch\r\n public is_h5 = false\r\n public rsa_public_key =\r\n \"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGpdbezK+eknQZQzPOjp8mr/dP+QHwk8CRkQh6C6qFnfLH3tiyl0pnt3dePuFDnM1PUXGhCkQ157ePJCQgkDU2+mimDmXh0oLFn9zuWSp+U8uLSLX3t3PpJ8TmNCROfUDWvzdbnShqg7JfDmnrOJz49qd234W84nrfTHbzdqeigQIDAQAB\"\r\n\r\n /**\r\n * 构造函数\r\n * @param dev_code 设备码\r\n * @param uid 用户ID\r\n * @param token 访问令牌\r\n * @param options 选项\r\n * @param options.fetchFn 自定义fetch函数\r\n * @param options.is_h5 是否为H5端\r\n * @param options.rsa_public_key RSA公钥(base64) 设为空字符串从服务器获取\r\n */\r\n constructor(\r\n public dev_code: string,\r\n public uid = \"\",\r\n public token = \"\",\r\n options: { fetchFn?: typeof fetch; is_h5?: boolean; rsa_public_key?: string } = {},\r\n ) {\r\n if (options.fetchFn) this.fetchFn = options.fetchFn\r\n if (options.fetchFn) this.fetchFn = options.fetchFn\r\n if (options.is_h5 !== undefined) this.is_h5 = options.is_h5\r\n if (options.rsa_public_key !== undefined) this.rsa_public_key = options.rsa_public_key\r\n }\r\n\r\n /**\r\n * 获取RSA公钥\r\n * @returns RSA公钥(base64)\r\n */\r\n async getRsaPublicKey() {\r\n if (this.rsa_public_key) {\r\n return this.rsa_public_key\r\n }\r\n const res = await this._dna_request<{ key: string }>(GET_RSA_PUBLIC_KEY_URL)\r\n\r\n if (res.is_success && res.data) {\r\n const key = res.data.key\r\n if (typeof key === \"string\") {\r\n this.rsa_public_key = key\r\n }\r\n }\r\n return this.rsa_public_key\r\n }\r\n\r\n /**\r\n * 登录\r\n */\r\n async login(mobile: string, code: string, dev_code: string) {\r\n const data = { mobile, code, gameList: DNA_GAME_ID }\r\n const res = await this._dna_request<DNALoginRes>(LOGIN_URL, data, { sign: true, refer: true })\r\n if (res.is_success && res.data) {\r\n const data = res.data\r\n if (typeof data.userId === \"string\") {\r\n this.uid = data.userId\r\n }\r\n if (typeof data.token === \"string\") {\r\n this.token = data.token\r\n }\r\n }\r\n return res\r\n }\r\n\r\n /**\r\n * 获取登录日志\r\n */\r\n async loginLog() {\r\n return await this._dna_request<DNALoginRes>(LOGIN_LOG_URL)\r\n }\r\n\r\n /**\r\n * 获取角色列表\r\n */\r\n async getRoleList() {\r\n return await this._dna_request<DNARoleListRes>(ROLE_LIST_URL)\r\n }\r\n\r\n /**\r\n * 获取默认角色\r\n */\r\n async getDefaultRoleForTool() {\r\n const data = { type: 1 }\r\n return await this._dna_request<DNARoleForToolRes>(ROLE_FOR_TOOL_URL, data, { sign: true })\r\n }\r\n\r\n /**\r\n * 获取角色详情\r\n */\r\n async getRoleDetail(char_id: string, char_eid: string) {\r\n const data = { charId: char_id, charEid: char_eid, type: 1 }\r\n return await this._dna_request<DNARoleDetailRes>(ROLE_DETAIL_URL, data)\r\n }\r\n\r\n /**\r\n * 获取武器详情\r\n */\r\n async getWeaponDetail(weapon_id: string) {\r\n const data = { weaponId: weapon_id, type: 1 }\r\n return await this._dna_request<DNARoleDetailRes>(WEAPON_DETAIL_URL, data)\r\n }\r\n\r\n /**\r\n * 获取角色简讯\r\n */\r\n async getShortNoteInfo() {\r\n return await this._dna_request<DNARoleShortNoteRes>(SHORT_NOTE_URL)\r\n }\r\n\r\n /**\r\n * 检查是否签到\r\n */\r\n async haveSignIn() {\r\n const data = { gameId: DNA_GAME_ID }\r\n return await this._dna_request<DNAHaveSignInRes>(HAVE_SIGN_IN_URL, data)\r\n }\r\n\r\n /**\r\n * 签到日历\r\n */\r\n async signCalendar() {\r\n const data = { gameId: DNA_GAME_ID }\r\n return await this._dna_request<DNACalendarSignRes>(SIGN_CALENDAR_URL, data)\r\n }\r\n\r\n /**\r\n * 游戏签到\r\n */\r\n async gameSign(day_award_id: number, period: number) {\r\n const data = {\r\n dayAwardId: day_award_id,\r\n periodId: period,\r\n signinType: 1,\r\n }\r\n return await this._dna_request(GAME_SIGN_URL, data)\r\n }\r\n\r\n /**\r\n * 皎皎角签到\r\n */\r\n async bbsSign() {\r\n const data = { gameId: DNA_GAME_ID }\r\n return await this._dna_request(BBS_SIGN_URL, data)\r\n }\r\n\r\n /**\r\n * 获取任务进度\r\n */\r\n async getTaskProcess() {\r\n const data = { gameId: DNA_GAME_ID }\r\n return await this._dna_request<DNATaskProcessRes>(GET_TASK_PROCESS_URL, data)\r\n }\r\n\r\n /**\r\n * 获取帖子列表\r\n */\r\n async getPostList() {\r\n const data = {\r\n forumId: 46, // 全部\r\n gameId: DNA_GAME_ID,\r\n pageIndex: 1,\r\n pageSize: 20,\r\n searchType: 1, // 1:最新 2:热门\r\n timeType: 0,\r\n }\r\n return await this._dna_request<DNAPostListRes>(GET_POST_LIST_URL, data)\r\n }\r\n\r\n /**\r\n * 获取帖子详情\r\n */\r\n async getPostDetail(post_id: string) {\r\n const data = { postId: post_id }\r\n try {\r\n return await this._dna_request<DNAPostDetailRes>(GET_POST_DETAIL_URL, data)\r\n } catch (e) {\r\n console.error(\"get_post_detail\", e as Error)\r\n return DNAApiResponse.err(\"请求皎皎角服务失败\")\r\n }\r\n }\r\n\r\n /**\r\n * 点赞帖子\r\n */\r\n async doLike(post: { gameForumId: string; postId: string; postType: string; userId: string }) {\r\n const data = {\r\n forumId: post.gameForumId,\r\n gameId: DNA_GAME_ID,\r\n likeType: \"1\",\r\n operateType: \"1\",\r\n postCommentId: \"\",\r\n postCommentReplyId: \"\",\r\n postId: post.postId,\r\n postType: post.postType,\r\n toUserId: post.userId,\r\n }\r\n try {\r\n return await this._dna_request(LIKE_POST_URL, data)\r\n } catch (e) {\r\n console.error(\"do_like\", e as Error)\r\n return DNAApiResponse.err(\"请求皎皎角服务失败\")\r\n }\r\n }\r\n\r\n // 分享帖子\r\n async doShare() {\r\n const data = { gameId: DNA_GAME_ID }\r\n try {\r\n return await this._dna_request(SHARE_POST_URL, data)\r\n } catch (e) {\r\n console.error(\"do_share\", e as Error)\r\n return DNAApiResponse.err(\"请求皎皎角服务失败\")\r\n }\r\n }\r\n\r\n // 回复帖子\r\n async doReply(post: Record<string, any>, content: string) {\r\n const content_json = JSON.stringify([\r\n {\r\n content,\r\n contentType: \"1\",\r\n imgHeight: 0,\r\n imgWidth: 0,\r\n url: \"\",\r\n },\r\n ])\r\n const data = {\r\n postId: post.postId,\r\n forumId: post.gameForumId || 47,\r\n postType: \"1\",\r\n content: content_json,\r\n }\r\n\r\n return await this._dna_request(REPLY_POST_URL, data, { sign: true, refer: true, params: { toUserId: post.userId } })\r\n }\r\n\r\n // 获取游戏公告列表\r\n async getAnnList() {\r\n const data = {\r\n otherUserId: \"709542994134436647\",\r\n searchType: 1,\r\n type: 2,\r\n }\r\n return await this._dna_request<DNAPostListRes>(ANN_LIST_URL, data)\r\n }\r\n\r\n async getHeaders(options?: {\r\n payload?: Record<string, any> | string\r\n exparams?: Record<string, any>\r\n dev_code?: string\r\n refer?: boolean\r\n token?: string\r\n }) {\r\n let { payload, exparams, dev_code = this.dev_code, refer, token = this.token } = options || {}\r\n\r\n const CONTENT_TYPE = \"application/x-www-form-urlencoded; charset=utf-8\"\r\n const iosBaseHeader = {\r\n version: \"1.1.3\",\r\n source: \"ios\",\r\n \"Content-Type\": CONTENT_TYPE,\r\n \"User-Agent\": \"DoubleHelix/4 CFNetwork/3860.100.1 Darwin/25.0.0\",\r\n }\r\n const h5BaseHeader = {\r\n version: \"3.11.0\",\r\n source: \"h5\",\r\n \"Content-Type\": CONTENT_TYPE,\r\n \"User-Agent\":\r\n \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36\",\r\n }\r\n // 默认获取ios头\r\n const headers = { ...(this.is_h5 ? h5BaseHeader : iosBaseHeader) } as Record<string, any>\r\n if (dev_code) {\r\n headers.devCode = dev_code\r\n }\r\n if (refer) {\r\n headers.origin = \"https://dnabbs.yingxiong.com\"\r\n headers.refer = \"https://dnabbs.yingxiong.com/\"\r\n }\r\n if (token) {\r\n headers.token = token\r\n }\r\n if (typeof payload === \"object\") {\r\n const si = build_signature(payload)\r\n Object.assign(payload, { sign: si.s, timestamp: si.t })\r\n if (exparams) {\r\n Object.assign(payload, exparams)\r\n }\r\n\r\n const params = new URLSearchParams()\r\n Object.entries(payload).forEach(([key, value]) => {\r\n params.append(key, String(value))\r\n })\r\n payload = params.toString()\r\n\r\n const rk = si.k\r\n const pk = await this.getRsaPublicKey()\r\n const ek = rsa_encrypt(rk, pk)\r\n if (this.is_h5) {\r\n headers.k = ek\r\n } else {\r\n headers.rk = rk\r\n headers.key = ek\r\n }\r\n }\r\n return { headers, payload }\r\n }\r\n\r\n private async _dna_request<T = any>(\r\n url: string,\r\n data?: any,\r\n options?: {\r\n method?: \"GET\" | \"POST\"\r\n sign?: boolean\r\n refer?: boolean\r\n params?: Record<string, any>\r\n max_retries?: number\r\n retry_delay?: number\r\n timeout?: number\r\n },\r\n ): Promise<DNAApiResponse<T>> {\r\n let { method = \"POST\", sign, refer, params, max_retries = 3, retry_delay = 1, timeout = 10000 } = options || {}\r\n let headers: Record<string, any>\r\n if (sign) {\r\n const { payload: p, headers: h } = await this.getHeaders({ payload: data, refer, exparams: params })\r\n data = p\r\n headers = h\r\n } else {\r\n const { headers: h } = await this.getHeaders()\r\n headers = h\r\n }\r\n\r\n for (let attempt = 0; attempt < max_retries; attempt++) {\r\n try {\r\n const fetchOptions: RequestInit = {\r\n method,\r\n headers,\r\n body: data,\r\n }\r\n\r\n // 实现超时控制\r\n const controller = new AbortController()\r\n const timeoutId = setTimeout(() => controller.abort(), timeout)\r\n\r\n const response = await this.fetchFn(url, {\r\n ...fetchOptions,\r\n signal: controller.signal,\r\n })\r\n clearTimeout(timeoutId)\r\n\r\n // 获取响应头的 content-type\r\n const contentType = response.headers.get(\"content-type\") || \"\"\r\n let raw_res: any\r\n\r\n // 根据 content-type 处理响应数据\r\n if (contentType.includes(\"text/\")) {\r\n const textData = await response.text()\r\n raw_res = {\r\n code: RespCode.ERROR,\r\n data: textData,\r\n }\r\n } else {\r\n raw_res = await response.json()\r\n }\r\n\r\n if (typeof raw_res === \"object\" && raw_res !== null) {\r\n try {\r\n if (typeof raw_res.data === \"string\") {\r\n raw_res.data = JSON.parse(raw_res.data)\r\n }\r\n } catch (e) {\r\n // 忽略解析错误\r\n }\r\n }\r\n\r\n console.debug(\r\n `[DNA] url:[${url}] headers:[${JSON.stringify(headers)}] data:[${JSON.stringify(data)}] raw_res:${JSON.stringify(raw_res)}`,\r\n )\r\n return new DNAApiResponse<T>(raw_res)\r\n } catch (e) {\r\n console.error(`请求失败: ${(e as Error).message}`)\r\n if (attempt < max_retries - 1) {\r\n await new Promise((resolve) => setTimeout(resolve, retry_delay * Math.pow(2, attempt)))\r\n }\r\n }\r\n }\r\n\r\n return DNAApiResponse.err(\"请求服务器失败,已达最大重试次数\")\r\n }\r\n}\r\n\r\n//#region 接口定义\r\n\r\nexport interface UserGame {\r\n gameId: number // gameId\r\n gameName: string // gameName\r\n}\r\n\r\nexport interface DNALoginRes {\r\n applyCancel?: number // applyCancel\r\n gender?: number // gender\r\n signature?: string // signature\r\n headUrl: string // headUrl\r\n userName: string // userName\r\n userId: string // userId\r\n isOfficial: number // isOfficial\r\n token: string // token\r\n userGameList: UserGame[] // userGameList\r\n isRegister: number // isRegister\r\n status: number // status\r\n /** 是否完成绑定 0: 未绑定, 1: 已绑定 */\r\n isComplete: number\r\n refreshToken: string // refreshToken\r\n}\r\n\r\nexport interface DNARoleShowVo {\r\n roleId: string // roleId\r\n headUrl?: string // headUrl\r\n level?: number // level\r\n roleName?: string // roleName\r\n isDefault?: number // isDefault\r\n roleRegisterTime?: string // roleRegisterTime\r\n boundType?: number // boundType\r\n roleBoundId: string // roleBoundId\r\n}\r\n\r\nexport interface DNARole {\r\n gameName: string // gameName\r\n showVoList: DNARoleShowVo[] // showVoList\r\n gameId: number // gameId\r\n}\r\n\r\nexport interface DNARoleListRes {\r\n roles: DNARole[] // roles\r\n}\r\n\r\n/** 密函 */\r\nexport interface DNARoleForToolInstance {\r\n id: number // id\r\n name: string // name\r\n /** 密函编码 */\r\n code: string\r\n on: number // 0\r\n}\r\n\r\nenum DNAInstanceMHType {\r\n \"角色\" = \"role\",\r\n \"武器\" = \"weapon\",\r\n \"魔之楔\" = \"mzx\",\r\n \"role\" = \"角色\",\r\n \"weapon\" = \"武器\",\r\n \"mzx\" = \"魔之楔\",\r\n}\r\n\r\nexport function getDNAInstanceMHType(key: keyof typeof DNAInstanceMHType) {\r\n return DNAInstanceMHType[key]\r\n}\r\n\r\nexport interface DNARoleForToolInstanceInfo {\r\n /** 密函列表 */\r\n instances: DNARoleForToolInstance[] // instances\r\n /** 密函类型 */\r\n mh_type?: DNAInstanceMHType // 密函类型\r\n}\r\n\r\nexport interface DraftDoingInfo {\r\n draftCompleteNum: number // draftCompleteNum\r\n draftDoingNum: number // draftDoingNum\r\n /** 结束时间 */\r\n endTime: string\r\n /** 产品id */\r\n productId?: number\r\n /** 产品名称 */\r\n productName: string\r\n /** 开始时间 */\r\n startTime: string\r\n}\r\n\r\nexport interface DraftInfo {\r\n /** 正在做的锻造 */\r\n draftDoingInfo?: DraftDoingInfo[]\r\n /** 正在做的锻造数量 */\r\n draftDoingNum: number\r\n /** 最大锻造数量 */\r\n draftMaxNum: number\r\n}\r\n\r\nexport interface DNARoleShortNoteRes {\r\n /** 迷津进度 */\r\n rougeLikeRewardCount: number\r\n /** 迷津总数 */\r\n rougeLikeRewardTotal: number\r\n /** 备忘手记进度 */\r\n currentTaskProgress: number\r\n /** 备忘手记总数 */\r\n maxDailyTaskProgress: number\r\n /** 梦魇进度 */\r\n hardBossRewardCount: number\r\n /** 梦魇总数 */\r\n hardBossRewardTotal: number\r\n /** 锻造信息 */\r\n draftInfo: DraftInfo\r\n}\r\n\r\nexport interface WeaponInsForTool {\r\n /** 武器类型图标 */\r\n elementIcon: string\r\n /** 武器图标 */\r\n icon: string\r\n /** 武器等级 */\r\n level: number\r\n /** 武器名称 */\r\n name: string\r\n /** 是否解锁 */\r\n unLocked: boolean\r\n weaponEid?: string\r\n weaponId: number\r\n}\r\n\r\nexport interface RoleInsForTool {\r\n charEid?: string\r\n charId: number\r\n /** 元素图标 */\r\n elementIcon: string\r\n /** 命座等级 */\r\n gradeLevel: number\r\n /** 角色图标 */\r\n icon: string\r\n /** 角色等级 */\r\n level: number\r\n /** 角色名称 */\r\n name: string\r\n /** 是否解锁 */\r\n unLocked: boolean\r\n}\r\n\r\nexport interface RoleAchievement {\r\n paramKey: string // paramKey\r\n paramValue: string // paramValue\r\n}\r\n\r\nexport interface RoleShowForTool {\r\n /** 角色列表 */\r\n roleChars: RoleInsForTool[]\r\n /** 武器列表 */\r\n langRangeWeapons: WeaponInsForTool[]\r\n /** 武器列表 */\r\n closeWeapons: WeaponInsForTool[]\r\n /** 等级 */\r\n level: number\r\n /** 成就列表 */\r\n params: RoleAchievement[]\r\n /** 角色id */\r\n roleId: string\r\n /** 角色名称 */\r\n roleName: string\r\n}\r\n\r\nexport interface RoleInfoForTool {\r\n /** 角色信息 */\r\n roleShow: RoleShowForTool\r\n}\r\n\r\nexport interface DNARoleForToolRes {\r\n /** 角色信息 */\r\n roleInfo: RoleInfoForTool\r\n /** 密函 */\r\n instanceInfo: DNARoleForToolInstanceInfo[]\r\n}\r\n\r\nexport interface RoleAttribute {\r\n /** 技能范围 */\r\n skillRange: string\r\n /** 强化值 */\r\n strongValue: string\r\n /** 技能威力 */\r\n skillIntensity: string\r\n /** 武器精通 */\r\n weaponTags: string[]\r\n /** 防御 */\r\n defense: number\r\n /** 仇恨值 */\r\n enmityValue: string\r\n /** 技能效益 */\r\n skillEfficiency: string\r\n /** 技能耐久 */\r\n skillSustain: string\r\n /** 最大生命值 */\r\n maxHp: number\r\n /** 攻击 */\r\n atk: number\r\n /** 最大护盾 */\r\n maxES: number\r\n /** 最大神志 */\r\n maxSp: number\r\n}\r\n\r\nexport interface RoleSkill {\r\n /** 技能id */\r\n skillId: number\r\n /** 技能图标 */\r\n icon: string\r\n /** 技能等级 */\r\n level: number\r\n /** 技能名称 */\r\n skillName: string\r\n}\r\n\r\nexport interface RoleTrace {\r\n /** 溯源图标 */\r\n icon: string\r\n /** 溯源描述 */\r\n description: string\r\n}\r\n\r\nexport interface Mode {\r\n /** id 没佩戴为-1 */\r\n id: number\r\n /** 图标 */\r\n icon?: string\r\n /** 质量 */\r\n quality?: number\r\n /** 名称 */\r\n name?: string\r\n}\r\n\r\nexport interface RoleDetail {\r\n /** 角色属性 */\r\n attribute: RoleAttribute\r\n /** 角色技能 */\r\n skills: RoleSkill[]\r\n /** 立绘 */\r\n paint: string\r\n /** 角色名称 */\r\n charName: string\r\n /** 元素图标 */\r\n elementIcon: string\r\n /** 溯源 */\r\n traces: RoleTrace[]\r\n /** 当前魔之楔 */\r\n currentVolume: number\r\n /** 最大魔之楔 */\r\n sumVolume: number\r\n /** 角色等级 */\r\n level: number\r\n /** 角色头像 */\r\n icon: string\r\n /** 溯源等级 0-6 */\r\n gradeLevel: number\r\n /** 元素名称 */\r\n elementName: string\r\n /** mode */\r\n modes: Mode[]\r\n}\r\n\r\nexport interface DNARoleDetailRes {\r\n /** 角色详情 */\r\n charDetail: RoleDetail\r\n}\r\n\r\nexport interface DNADayAward {\r\n gameId: number // gameId\r\n periodId: number // periodId\r\n iconUrl: string // iconUrl\r\n id: number // id\r\n dayInPeriod: number // dayInPeriod\r\n updateTime: number // updateTime\r\n awardNum: number // awardNum\r\n thirdProductId: string // thirdProductId\r\n createTime: number // createTime\r\n awardName: string // awardName\r\n}\r\n\r\nexport interface DNACaSignPeriod {\r\n gameId: number // gameId\r\n retryCos: number // retryCos\r\n endDate: number // endDate\r\n id: number // id\r\n startDate: number // startDate\r\n retryTimes: number // retryTimes\r\n overDays: number // overDays\r\n createTime: number // createTime\r\n name: string // name\r\n}\r\n\r\nexport interface DNACaSignRoleInfo {\r\n headUrl: string // headUrl\r\n roleId: string // roleId\r\n roleName: string // roleName\r\n level: number // level\r\n roleBoundId: string // roleBoundId\r\n}\r\n\r\nexport interface DNAHaveSignInRes {\r\n /** 已签到天数 */\r\n totalSignInDay: number\r\n}\r\n\r\nexport interface DNACalendarSignRes {\r\n todaySignin: boolean // todaySignin\r\n userGoldNum: number // userGoldNum\r\n dayAward: DNADayAward[] // dayAward\r\n signinTime: number // signinTime\r\n period: DNACaSignPeriod // period\r\n roleInfo: DNACaSignRoleInfo // roleInfo\r\n}\r\n\r\nexport interface DNABBSTask {\r\n /** 备注 */\r\n remark: string\r\n /** 完成次数 */\r\n completeTimes: number\r\n /** 需要次数 */\r\n times: number\r\n /** skipType */\r\n skipType: number\r\n /** 获取经验 */\r\n gainExp: number\r\n /** 进度 */\r\n process: number\r\n /** 获取金币 */\r\n gainGold: number\r\n /** 任务标识名 */\r\n markName?: string\r\n}\r\n\r\nexport interface DNATaskProcessRes {\r\n dailyTask: DNABBSTask[] // dailyTask\r\n}\r\n\r\nexport interface DNAPostListRes {\r\n postList: DNAPost[] // posts\r\n}\r\n\r\nexport interface DNAPost {\r\n postId: number // postId\r\n title: string // title\r\n}\r\n\r\nexport interface DNAPostDetailRes {\r\n postDetail: DNAPostDetail // post\r\n}\r\n\r\nexport interface DNAPostDetail {\r\n postId: number // postId\r\n postTime: number // postTime\r\n postContent: DNAPostContent[] // postContent\r\n title: string // title\r\n}\r\n\r\nexport enum PostContentType {\r\n TEXT = 1,\r\n IMAGE = 2,\r\n VIDEO = 5,\r\n}\r\n\r\nexport interface DNAPostContent {\r\n contentType: PostContentType // content\r\n content: string // content\r\n url?: string // url\r\n contentVideo?: DNAPostContentVideo // contentVideo\r\n}\r\n\r\nexport interface DNAPostContentVideo {\r\n videoUrl: string // videoUrl\r\n coverUrl?: string // coverUrl\r\n}\r\n\r\n// interface DNAWikiDetail {\r\n// name: string // name\r\n// }\r\n\r\n// interface DNAWikiRes {\r\n// wikis: DNAWikiDetail[] // wikis\r\n// }\r\n\r\nclass DNAApiResponse<T = any> {\r\n code: number = 0\r\n msg: string = \"\"\r\n success: boolean = false\r\n data?: T\r\n\r\n constructor(raw_data: any) {\r\n this.code = raw_data.code || 0\r\n this.msg = raw_data.msg || \"\"\r\n this.success = raw_data.success || false\r\n this.data = raw_data.data\r\n }\r\n\r\n // 判断是否成功\r\n get is_success() {\r\n return this.success && [RespCode.OK_ZERO, RespCode.OK_HTTP].includes(this.code)\r\n }\r\n\r\n // 错误响应静态方法\r\n static err<T = undefined>(msg: string, code: number = RespCode.ERROR): DNAApiResponse<T> {\r\n return new DNAApiResponse<T>({ code, msg, data: undefined, success: false })\r\n }\r\n}\r\n//#endregion\r\n\r\n//#region utils\r\n\r\n// RSA加密函数\r\nfunction rsa_encrypt(text: string, public_key_b64: string): string {\r\n try {\r\n // 将base64公钥转换为PEM格式\r\n const lines: string[] = []\r\n for (let i = 0; i < public_key_b64.length; i += 64) {\r\n lines.push(public_key_b64.slice(i, i + 64))\r\n }\r\n const pem = `-----BEGIN PUBLIC KEY-----\\n${lines.join(\"\\n\")}\\n-----END PUBLIC KEY-----`\r\n\r\n // 导入PEM格式的RSA公钥\r\n const publicKey = forge.pki.publicKeyFromPem(pem)\r\n\r\n // 执行PKCS1_v1_5加密\r\n const textBytes = forge.util.encodeUtf8(text)\r\n const encrypted = publicKey.encrypt(textBytes)\r\n\r\n return forge.util.encode64(encrypted)\r\n } catch (e) {\r\n throw new Error(`[DNA] RSA 加密失败: ${(e as Error).message}`)\r\n }\r\n}\r\n\r\n// 生成随机字符串\r\nfunction rand_str(length: number = 16): string {\r\n const chars = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\"\r\n let result = \"\"\r\n for (let i = 0; i < length; i++) {\r\n result += chars.charAt(Math.floor(Math.random() * chars.length))\r\n }\r\n return result\r\n}\r\n\r\n// MD5加密并转换为大写\r\nfunction md5_upper(text: string): string {\r\n const md = forge.md.md5.create()\r\n md.update(text)\r\n return md.digest().toHex().toUpperCase()\r\n}\r\n\r\n// 签名哈希函数\r\nfunction signature_hash(text: string): string {\r\n function swap_positions(text: string, positions: number[]): string {\r\n const chars = text.split(\"\")\r\n for (let i = 1; i < positions.length; i += 2) {\r\n const p1 = positions[i - 1]\r\n const p2 = positions[i]\r\n if (p1 >= 0 && p1 < chars.length && p2 >= 0 && p2 < chars.length) {\r\n ;[chars[p1], chars[p2]] = [chars[p2], chars[p1]]\r\n }\r\n }\r\n return chars.join(\"\")\r\n }\r\n\r\n return swap_positions(md5_upper(text), [1, 13, 5, 17, 7, 23])\r\n}\r\n\r\n// 签名函数\r\nfunction sign_fI(data: Record<string, any>, secret: string): string {\r\n const pairs: string[] = []\r\n const sortedKeys = Object.keys(data).sort()\r\n for (const k of sortedKeys) {\r\n const v = data[k]\r\n if (v !== null && v !== undefined && v !== \"\") {\r\n pairs.push(`${k}=${v}`)\r\n }\r\n }\r\n const qs = pairs.join(\"&\")\r\n return signature_hash(`${qs}&${secret}`)\r\n}\r\n\r\n// XOR编码函数\r\nfunction xor_encode(text: string, key: string): string {\r\n const encoder = new TextEncoder()\r\n const tb = encoder.encode(text)\r\n const kb = encoder.encode(key)\r\n const out: string[] = []\r\n for (let i = 0; i < tb.length; i++) {\r\n const b = tb[i]\r\n const e = (b & 255) + (kb[i % kb.length] & 255)\r\n out.push(`@${e}`)\r\n }\r\n return out.join(\"\")\r\n}\r\n\r\n// 构建签名\r\nfunction build_signature(data: Record<string, any>, token?: string): Record<string, any> {\r\n const ts = Date.now()\r\n const sign_data = { ...data, timestamp: ts, token }\r\n const sec = rand_str(16)\r\n const sig = sign_fI(sign_data, sec)\r\n const enc = xor_encode(sig, sec)\r\n return { s: enc, t: ts, k: sec }\r\n}\r\n\r\n//#endregion\r\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "EB6A1CCF9A1F642864756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "47E3A2E533C0FED964756E2164756E21",
9
9
  "names": []
10
10
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dna-api",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "dna bbs api",
5
5
  "author": {
6
6
  "name": "pa001024",
package/src/index.ts CHANGED
@@ -36,13 +36,32 @@ const DNA_GAME_ID = 268
36
36
  * DNA API类,用于与DNA游戏服务器交互
37
37
  */
38
38
  export class DNAAPI {
39
+ public fetchFn = fetch
40
+ public is_h5 = false
41
+ public rsa_public_key =
42
+ "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGpdbezK+eknQZQzPOjp8mr/dP+QHwk8CRkQh6C6qFnfLH3tiyl0pnt3dePuFDnM1PUXGhCkQ157ePJCQgkDU2+mimDmXh0oLFn9zuWSp+U8uLSLX3t3PpJ8TmNCROfUDWvzdbnShqg7JfDmnrOJz49qd234W84nrfTHbzdqeigQIDAQAB"
43
+
44
+ /**
45
+ * 构造函数
46
+ * @param dev_code 设备码
47
+ * @param uid 用户ID
48
+ * @param token 访问令牌
49
+ * @param options 选项
50
+ * @param options.fetchFn 自定义fetch函数
51
+ * @param options.is_h5 是否为H5端
52
+ * @param options.rsa_public_key RSA公钥(base64) 设为空字符串从服务器获取
53
+ */
39
54
  constructor(
40
55
  public dev_code: string,
41
56
  public uid = "",
42
57
  public token = "",
43
- public rsa_public_key = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGpdbezK+eknQZQzPOjp8mr/dP+QHwk8CRkQh6C6qFnfLH3tiyl0pnt3dePuFDnM1PUXGhCkQ157ePJCQgkDU2+mimDmXh0oLFn9zuWSp+U8uLSLX3t3PpJ8TmNCROfUDWvzdbnShqg7JfDmnrOJz49qd234W84nrfTHbzdqeigQIDAQAB",
44
- public is_h5 = false,
45
- ) {}
58
+ options: { fetchFn?: typeof fetch; is_h5?: boolean; rsa_public_key?: string } = {},
59
+ ) {
60
+ if (options.fetchFn) this.fetchFn = options.fetchFn
61
+ if (options.fetchFn) this.fetchFn = options.fetchFn
62
+ if (options.is_h5 !== undefined) this.is_h5 = options.is_h5
63
+ if (options.rsa_public_key !== undefined) this.rsa_public_key = options.rsa_public_key
64
+ }
46
65
 
47
66
  /**
48
67
  * 获取RSA公钥
@@ -360,7 +379,7 @@ export class DNAAPI {
360
379
  const controller = new AbortController()
361
380
  const timeoutId = setTimeout(() => controller.abort(), timeout)
362
381
 
363
- const response = await fetch(url, {
382
+ const response = await this.fetchFn(url, {
364
383
  ...fetchOptions,
365
384
  signal: controller.signal,
366
385
  })
@@ -426,7 +445,8 @@ export interface DNALoginRes {
426
445
  userGameList: UserGame[] // userGameList
427
446
  isRegister: number // isRegister
428
447
  status: number // status
429
- isComplete: number // isComplete 是否完成绑定 0: 未绑定, 1: 已绑定
448
+ /** 是否完成绑定 0: 未绑定, 1: 已绑定 */
449
+ isComplete: number
430
450
  refreshToken: string // refreshToken
431
451
  }
432
452
 
@@ -451,10 +471,12 @@ export interface DNARoleListRes {
451
471
  roles: DNARole[] // roles
452
472
  }
453
473
 
474
+ /** 密函 */
454
475
  export interface DNARoleForToolInstance {
455
476
  id: number // id
456
477
  name: string // name
457
- code: string // 密函编码
478
+ /** 密函编码 */
479
+ code: string
458
480
  on: number // 0
459
481
  }
460
482
 
@@ -472,54 +494,81 @@ export function getDNAInstanceMHType(key: keyof typeof DNAInstanceMHType) {
472
494
  }
473
495
 
474
496
  export interface DNARoleForToolInstanceInfo {
497
+ /** 密函列表 */
475
498
  instances: DNARoleForToolInstance[] // instances
499
+ /** 密函类型 */
476
500
  mh_type?: DNAInstanceMHType // 密函类型
477
501
  }
478
502
 
479
503
  export interface DraftDoingInfo {
480
504
  draftCompleteNum: number // draftCompleteNum
481
505
  draftDoingNum: number // draftDoingNum
482
- endTime: string // 结束时间
483
- productId?: number // productId
484
- productName: string // productName
485
- startTime: string // 开始时间
506
+ /** 结束时间 */
507
+ endTime: string
508
+ /** 产品id */
509
+ productId?: number
510
+ /** 产品名称 */
511
+ productName: string
512
+ /** 开始时间 */
513
+ startTime: string
486
514
  }
487
515
 
488
516
  export interface DraftInfo {
489
- draftDoingInfo?: DraftDoingInfo[] // draftDoingInfo
490
- draftDoingNum: number // 正在做的锻造
491
- draftMaxNum: number // 最大锻造数量
517
+ /** 正在做的锻造 */
518
+ draftDoingInfo?: DraftDoingInfo[]
519
+ /** 正在做的锻造数量 */
520
+ draftDoingNum: number
521
+ /** 最大锻造数量 */
522
+ draftMaxNum: number
492
523
  }
493
524
 
494
525
  export interface DNARoleShortNoteRes {
495
- rougeLikeRewardCount: number // 迷津进度
496
- rougeLikeRewardTotal: number // 迷津总数
497
- currentTaskProgress: number // 备忘手记进度
498
- maxDailyTaskProgress: number // 备忘手记总数
499
- hardBossRewardCount: number // 梦魇进度
500
- hardBossRewardTotal: number // 梦魇总数
501
- draftInfo: DraftInfo // 锻造信息
526
+ /** 迷津进度 */
527
+ rougeLikeRewardCount: number
528
+ /** 迷津总数 */
529
+ rougeLikeRewardTotal: number
530
+ /** 备忘手记进度 */
531
+ currentTaskProgress: number
532
+ /** 备忘手记总数 */
533
+ maxDailyTaskProgress: number
534
+ /** 梦魇进度 */
535
+ hardBossRewardCount: number
536
+ /** 梦魇总数 */
537
+ hardBossRewardTotal: number
538
+ /** 锻造信息 */
539
+ draftInfo: DraftInfo
502
540
  }
503
541
 
504
542
  export interface WeaponInsForTool {
505
- elementIcon: string // 武器类型图标
506
- icon: string // 武器图标
507
- level: number // 武器等级
508
- name: string // 武器名称
509
- unLocked: boolean // 是否解锁
510
- weaponEid?: string // weaponEid
511
- weaponId: number // weaponId
543
+ /** 武器类型图标 */
544
+ elementIcon: string
545
+ /** 武器图标 */
546
+ icon: string
547
+ /** 武器等级 */
548
+ level: number
549
+ /** 武器名称 */
550
+ name: string
551
+ /** 是否解锁 */
552
+ unLocked: boolean
553
+ weaponEid?: string
554
+ weaponId: number
512
555
  }
513
556
 
514
557
  export interface RoleInsForTool {
515
- charEid?: string // charEid
516
- charId: number // charId
517
- elementIcon: string // 元素图标
518
- gradeLevel: number // 命座等级
519
- icon: string // 角色图标
520
- level: number // 角色等级
521
- name: string // 角色名称
522
- unLocked: boolean // 是否解锁
558
+ charEid?: string
559
+ charId: number
560
+ /** 元素图标 */
561
+ elementIcon: string
562
+ /** 命座等级 */
563
+ gradeLevel: number
564
+ /** 角色图标 */
565
+ icon: string
566
+ /** 角色等级 */
567
+ level: number
568
+ /** 角色名称 */
569
+ name: string
570
+ /** 是否解锁 */
571
+ unLocked: boolean
523
572
  }
524
573
 
525
574
  export interface RoleAchievement {
@@ -528,76 +577,122 @@ export interface RoleAchievement {
528
577
  }
529
578
 
530
579
  export interface RoleShowForTool {
531
- roleChars: RoleInsForTool[] // 角色列表
532
- langRangeWeapons: WeaponInsForTool[] // 武器列表
533
- closeWeapons: WeaponInsForTool[] // 武器列表
534
- level: number // 等级
535
- params: RoleAchievement[] // 成就列表
536
- roleId: string // 角色id
537
- roleName: string // 角色名称
580
+ /** 角色列表 */
581
+ roleChars: RoleInsForTool[]
582
+ /** 武器列表 */
583
+ langRangeWeapons: WeaponInsForTool[]
584
+ /** 武器列表 */
585
+ closeWeapons: WeaponInsForTool[]
586
+ /** 等级 */
587
+ level: number
588
+ /** 成就列表 */
589
+ params: RoleAchievement[]
590
+ /** 角色id */
591
+ roleId: string
592
+ /** 角色名称 */
593
+ roleName: string
538
594
  }
539
595
 
540
596
  export interface RoleInfoForTool {
541
- roleShow: RoleShowForTool // 角色信息
597
+ /** 角色信息 */
598
+ roleShow: RoleShowForTool
542
599
  }
543
600
 
544
601
  export interface DNARoleForToolRes {
545
- roleInfo: RoleInfoForTool // 角色信息
546
- instanceInfo: DNARoleForToolInstanceInfo[] // 密函
602
+ /** 角色信息 */
603
+ roleInfo: RoleInfoForTool
604
+ /** 密函 */
605
+ instanceInfo: DNARoleForToolInstanceInfo[]
547
606
  }
548
607
 
549
608
  export interface RoleAttribute {
550
- skillRange: string // 技能范围
551
- strongValue: string // strongValue
552
- skillIntensity: string // 技能威力
553
- weaponTags: string[] // 武器精通
554
- defense: number // 防御
555
- enmityValue: string // enmityValue
556
- skillEfficiency: string // 技能效益
557
- skillSustain: string // 技能耐久
558
- maxHp: number // 最大生命值
559
- atk: number // 攻击
560
- maxES: number // 护盾
561
- maxSp: number // 最大神志
609
+ /** 技能范围 */
610
+ skillRange: string
611
+ /** 强化值 */
612
+ strongValue: string
613
+ /** 技能威力 */
614
+ skillIntensity: string
615
+ /** 武器精通 */
616
+ weaponTags: string[]
617
+ /** 防御 */
618
+ defense: number
619
+ /** 仇恨值 */
620
+ enmityValue: string
621
+ /** 技能效益 */
622
+ skillEfficiency: string
623
+ /** 技能耐久 */
624
+ skillSustain: string
625
+ /** 最大生命值 */
626
+ maxHp: number
627
+ /** 攻击 */
628
+ atk: number
629
+ /** 最大护盾 */
630
+ maxES: number
631
+ /** 最大神志 */
632
+ maxSp: number
562
633
  }
563
634
 
564
635
  export interface RoleSkill {
565
- skillId: number // 技能id
566
- icon: string // 技能图标
567
- level: number // 技能等级
568
- skillName: string // 技能名称
636
+ /** 技能id */
637
+ skillId: number
638
+ /** 技能图标 */
639
+ icon: string
640
+ /** 技能等级 */
641
+ level: number
642
+ /** 技能名称 */
643
+ skillName: string
569
644
  }
570
645
 
571
646
  export interface RoleTrace {
572
- icon: string // 溯源图标
573
- description: string // 溯源描述
647
+ /** 溯源图标 */
648
+ icon: string
649
+ /** 溯源描述 */
650
+ description: string
574
651
  }
575
652
 
576
653
  export interface Mode {
577
- id: number // id 没佩戴为-1
578
- icon?: string // 图标
579
- quality?: number // 质量
580
- name?: string // 名称
654
+ /** id 没佩戴为-1 */
655
+ id: number
656
+ /** 图标 */
657
+ icon?: string
658
+ /** 质量 */
659
+ quality?: number
660
+ /** 名称 */
661
+ name?: string
581
662
  }
582
663
 
583
664
  export interface RoleDetail {
584
- attribute: RoleAttribute // 角色属性
585
- skills: RoleSkill[] // 角色技能
586
- paint: string // 立绘
587
- charName: string // 角色名称
588
- elementIcon: string // 元素图标
589
- traces: RoleTrace[] // 溯源
590
- currentVolume: number // 当前魔之楔
591
- sumVolume: number // 最大魔之楔
592
- level: number // 角色等级
593
- icon: string // 角色头像
594
- gradeLevel: number // 溯源等级 0-6
595
- elementName: string // 元素名称
596
- modes: Mode[] // mode
665
+ /** 角色属性 */
666
+ attribute: RoleAttribute
667
+ /** 角色技能 */
668
+ skills: RoleSkill[]
669
+ /** 立绘 */
670
+ paint: string
671
+ /** 角色名称 */
672
+ charName: string
673
+ /** 元素图标 */
674
+ elementIcon: string
675
+ /** 溯源 */
676
+ traces: RoleTrace[]
677
+ /** 当前魔之楔 */
678
+ currentVolume: number
679
+ /** 最大魔之楔 */
680
+ sumVolume: number
681
+ /** 角色等级 */
682
+ level: number
683
+ /** 角色头像 */
684
+ icon: string
685
+ /** 溯源等级 0-6 */
686
+ gradeLevel: number
687
+ /** 元素名称 */
688
+ elementName: string
689
+ /** mode */
690
+ modes: Mode[]
597
691
  }
598
692
 
599
693
  export interface DNARoleDetailRes {
600
- charDetail: RoleDetail // 角色详情
694
+ /** 角色详情 */
695
+ charDetail: RoleDetail
601
696
  }
602
697
 
603
698
  export interface DNADayAward {
@@ -634,7 +729,8 @@ export interface DNACaSignRoleInfo {
634
729
  }
635
730
 
636
731
  export interface DNAHaveSignInRes {
637
- totalSignInDay: number // 已签到天数
732
+ /** 已签到天数 */
733
+ totalSignInDay: number
638
734
  }
639
735
 
640
736
  export interface DNACalendarSignRes {
@@ -647,14 +743,22 @@ export interface DNACalendarSignRes {
647
743
  }
648
744
 
649
745
  export interface DNABBSTask {
650
- remark: string // 备注
651
- completeTimes: number // 完成次数
652
- times: number // 需要次数
653
- skipType: number // skipType
654
- gainExp: number // 获取经验
655
- process: number // 进度
656
- gainGold: number // 获取金币
657
- markName?: string // 任务标识名
746
+ /** 备注 */
747
+ remark: string
748
+ /** 完成次数 */
749
+ completeTimes: number
750
+ /** 需要次数 */
751
+ times: number
752
+ /** skipType */
753
+ skipType: number
754
+ /** 获取经验 */
755
+ gainExp: number
756
+ /** 进度 */
757
+ process: number
758
+ /** 获取金币 */
759
+ gainGold: number
760
+ /** 任务标识名 */
761
+ markName?: string
658
762
  }
659
763
 
660
764
  export interface DNATaskProcessRes {