dna-api 0.2.4 → 0.2.6

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/dist/index.d.ts CHANGED
@@ -4,9 +4,10 @@
4
4
  export declare class DNAAPI {
5
5
  dev_code: string;
6
6
  token: string;
7
- fetchFn: typeof fetch;
7
+ fetchFn?: typeof fetch;
8
8
  is_h5: boolean;
9
- rsa_public_key: string;
9
+ RSA_PUBLIC_KEY: string;
10
+ BASE_URL: string;
10
11
  /**
11
12
  * 构造函数
12
13
  * @param dev_code 设备码
@@ -63,6 +64,8 @@ export declare class DNAAPI {
63
64
  * 签到日历
64
65
  */
65
66
  signCalendar(): Promise<DNAApiResponse<DNACalendarSignRes>>;
67
+ /** ? */
68
+ soulTask(): Promise<DNAApiResponse<any>>;
66
69
  /**
67
70
  * 游戏签到
68
71
  */
@@ -85,9 +88,99 @@ export declare class DNAAPI {
85
88
  * @returns 帖子列表
86
89
  */
87
90
  getPostList(forumId?: number, pageIndex?: number, pageSize?: number, searchType?: number, timeType?: number): Promise<DNAApiResponse<DNAPostListRes>>;
91
+ /** 管理员锁定帖子 */
92
+ lockPost(post: {
93
+ postId: number;
94
+ gameId?: number;
95
+ gameForumId: number;
96
+ operateType: number;
97
+ }): Promise<DNAApiResponse<any>>;
98
+ /** 管理员移动帖子 */
99
+ postDownOrUp(post: {
100
+ postId: number;
101
+ gameId?: number;
102
+ gameForumId: number;
103
+ operateType: number;
104
+ }): Promise<DNAApiResponse<any>>;
105
+ /** 管理员设精 */
106
+ postElite(post: {
107
+ postId: number;
108
+ gameId?: number;
109
+ gameForumId: number;
110
+ operateType: number;
111
+ }): Promise<DNAApiResponse<any>>;
112
+ /** 管理员隐藏帖子 */
113
+ postHide(post: {
114
+ postId: number;
115
+ gameId?: number;
116
+ gameForumId: number;
117
+ operateType: number;
118
+ }): Promise<DNAApiResponse<any>>;
119
+ /** 管理员设置权重 */
120
+ reRank(post: {
121
+ postId: number;
122
+ gameId?: number;
123
+ gameForumId: number;
124
+ }, weight: number): Promise<DNAApiResponse<any>>;
125
+ /** 管理员设置强推 */
126
+ strongRecommend(post: {
127
+ postId: number;
128
+ gameId?: number;
129
+ gameForumId: number;
130
+ }, operateType?: number): Promise<DNAApiResponse<any>>;
131
+ /** 管理员删帖 */
132
+ adminDelete(post: {
133
+ postId: number;
134
+ gameId?: number;
135
+ gameForumId: number;
136
+ }, content: string, reasonCode: number): Promise<DNAApiResponse<any>>;
137
+ /** 管理员移动帖子 */
138
+ adminMovePost(post: {
139
+ postId: number;
140
+ gameId?: number;
141
+ gameForumId: number;
142
+ }, newGameId: number, newForumId: number, newTopicIdStr: string): Promise<DNAApiResponse<any>>;
143
+ /** ? */
144
+ adminRefreshTime(post: {
145
+ postId: number;
146
+ gameId?: number;
147
+ gameForumId: number;
148
+ }, refresh: number): Promise<DNAApiResponse<any>>;
149
+ /** 黑名单 */
150
+ blockList(): Promise<DNAApiResponse<any>>;
151
+ /** 拉黑 */
152
+ blockOther(blockPostId: number, blockUserId: string, type: number): Promise<DNAApiResponse<any>>;
153
+ /** ? */
154
+ viewCommunity(): Promise<DNAApiResponse<any>>;
155
+ /** ? */
156
+ viewCount(): Promise<DNAApiResponse<any>>;
157
+ /** ? */
158
+ receiveLog(periodId: number, pageIndex: number, pageSize: number): Promise<DNAApiResponse<any>>;
159
+ /** 收藏 */
160
+ collect(postId: number, toUserId: string, operateType?: number): Promise<DNAApiResponse<any>>;
161
+ /** 删除评论 */
162
+ commentDelete(comment: {
163
+ id: number;
164
+ gameId: number;
165
+ gameForumId: number;
166
+ }, entityType: number, content: string, reasonCode: number): Promise<DNAApiResponse<any>>;
167
+ /** 推荐列表 */
168
+ recommendList(recIndex: number, newIndex: number, size: number, history: number, gameId?: number): Promise<DNAApiResponse<any>>;
169
+ /** 举报 */
170
+ report({ commentId, postId, replyId }: {
171
+ commentId?: number;
172
+ postId?: number;
173
+ replyId?: number;
174
+ }, reportReason?: number, reportType?: number): Promise<DNAApiResponse<DNAPostListRes>>;
175
+ /** 搜索帖子 */
176
+ searchPost(keyword: number, pageIndex: number, pageSize: number, gameId?: number, searchType?: number): Promise<DNAApiResponse<DNAPostListRes>>;
177
+ /** 搜索帖子 */
178
+ searchTopic(keyword: number, pageIndex: number, pageSize?: number, gameId?: number): Promise<DNAApiResponse<DNAPostListRes>>;
179
+ /** 搜索帖子 */
180
+ searchUser(keyword: number, pageIndex: number, pageSize: number): Promise<DNAApiResponse<DNAPostListRes>>;
88
181
  /**
89
182
  * 获取帖子列表
90
- * @param forumId 论坛ID
183
+ * @param topicId 主题ID
91
184
  * @param pageIndex 页码
92
185
  * @param pageSize 每页数量
93
186
  * @param searchType 搜索类型 1:最新 2:热门
@@ -101,6 +194,10 @@ export declare class DNAAPI {
101
194
  * @returns 帖子详情
102
195
  */
103
196
  getPostDetail(post_id: string): Promise<DNAApiResponse<DNAPostDetailRes>>;
197
+ /** 关注用户 */
198
+ doFollow(userId: string, unfollow?: boolean): Promise<DNAApiResponse<any>>;
199
+ /** 获取关注状态 */
200
+ getFollowState(userId: string): Promise<DNAApiResponse<any>>;
104
201
  /**
105
202
  * 点赞帖子
106
203
  */
@@ -110,8 +207,31 @@ export declare class DNAAPI {
110
207
  postType: string;
111
208
  userId: string;
112
209
  }): Promise<DNAApiResponse<any>>;
210
+ /** 分享帖子 */
113
211
  doShare(): Promise<DNAApiResponse<any>>;
114
- doReply(post: Record<string, any>, content: string): Promise<DNAApiResponse<any>>;
212
+ /** 回复帖子 */
213
+ createComment(post: {
214
+ userId: string;
215
+ postId: string;
216
+ gameForumId: number;
217
+ }, content: string): Promise<DNAApiResponse<any>>;
218
+ /** 回复评论 */
219
+ createReply(post: {
220
+ userId: string;
221
+ postId: string;
222
+ postCommentId: string;
223
+ gameForumId: number;
224
+ }, content: string): Promise<DNAApiResponse<any>>;
225
+ /** 回复评论的评论 */
226
+ createReplyList(post: {
227
+ userId: string;
228
+ postId: string;
229
+ postCommentId: string;
230
+ postCommentReplyId: string;
231
+ gameForumId: number;
232
+ }, content: string): Promise<DNAApiResponse<any>>;
233
+ /** 删 */
234
+ deletePost(deleteType: number, id: number): Promise<DNAApiResponse<any>>;
115
235
  /**
116
236
  * 获取用户信息
117
237
  * @returns 用户信息
@@ -136,12 +256,21 @@ export declare class DNAAPI {
136
256
  }>;
137
257
  private _dna_request;
138
258
  }
259
+ declare enum DNAInstanceMHType {
260
+ "角色" = "role",
261
+ "武器" = "weapon",
262
+ "魔之楔" = "mzx",
263
+ "role" = "\u89D2\u8272",
264
+ "weapon" = "\u6B66\u5668",
265
+ "mzx" = "\u9B54\u4E4B\u6954"
266
+ }
267
+ export declare function getDNAInstanceMHType(key: keyof typeof DNAInstanceMHType): DNAInstanceMHType;
139
268
  export interface DNAMineRes {
140
269
  mine: DNAMine;
141
270
  postList: DNAPost[];
142
271
  hasNext: number;
143
272
  }
144
- interface DNAMine {
273
+ export interface DNAMine {
145
274
  /** 文章数量 */
146
275
  articleCount: number;
147
276
  /** 收藏数量 */
@@ -300,20 +429,9 @@ export interface DNARoleForToolInstance {
300
429
  /** 固定0 */
301
430
  on: number;
302
431
  }
303
- declare enum DNAInstanceMHType {
304
- "角色" = "role",
305
- "武器" = "weapon",
306
- "魔之楔" = "mzx",
307
- "role" = "\u89D2\u8272",
308
- "weapon" = "\u6B66\u5668",
309
- "mzx" = "\u9B54\u4E4B\u6954"
310
- }
311
- export declare function getDNAInstanceMHType(key: keyof typeof DNAInstanceMHType): DNAInstanceMHType;
312
432
  export interface DNARoleForToolInstanceInfo {
313
433
  /** 密函列表 */
314
434
  instances: DNARoleForToolInstance[];
315
- /** 密函类型 */
316
- mh_type?: DNAInstanceMHType;
317
435
  }
318
436
  export interface DraftDoingInfo {
319
437
  draftCompleteNum: number;
@@ -744,7 +862,7 @@ export interface DNAPostDetail {
744
862
  isOfficial: number;
745
863
  isRecommend: number;
746
864
  isTop: number;
747
- lastEditorTime: string;
865
+ lastEditorTime?: string;
748
866
  likeCount: number;
749
867
  postContent: DNAPostContent[];
750
868
  postH5Content: string;
@@ -754,6 +872,8 @@ export interface DNAPostDetail {
754
872
  postUserId: string;
755
873
  refreshHour: number;
756
874
  score: number;
875
+ topics: DNATopicShort[];
876
+ userHeadCode: string;
757
877
  userLevel: number;
758
878
  userModeratorIdentity: number;
759
879
  userName: string;
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import*as B from"node-forge";var W="https://dnabbs-api.yingxiong.com",h=`${W}/user/sdkLogin`,E=`${W}/config/getRsaPublicKey`,D=`${W}/user/login/log`,M=`${W}/role/list`,T=`${W}/role/defaultRoleForTool`,U=`${W}/role/getCharDetail`,c=`${W}/role/getWeaponDetail`,y=`${W}/role/getShortNoteInfo`,N=`${W}/encourage/signin/show`,L=`${W}/encourage/signin/signin`,R=`${W}/user/signIn`,I=`${W}/user/haveSignInNew`,A=`${W}/encourage/level/getTaskProcess`,i=`${W}/forum/list`,n=`${W}/forum/getPostByTopic`,r=`${W}/forum/getPostDetail`,d=`${W}/forum/like`,p=`${W}/encourage/level/shareTask`,_=`${W}/forum/comment/createComment`,o=`${W}/config/getGameConfig`,m=`${W}/user/mine`;var z=268;class s{dev_code;token;fetchFn;is_h5=!1;rsa_public_key="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGpdbezK+eknQZQzPOjp8mr/dP+QHwk8CRkQh6C6qFnfLH3tiyl0pnt3dePuFDnM1PUXGhCkQ157ePJCQgkDU2+mimDmXh0oLFn9zuWSp+U8uLSLX3t3PpJ8TmNCROfUDWvzdbnShqg7JfDmnrOJz49qd234W84nrfTHbzdqeigQIDAQAB";constructor(J,Q="",Z={}){this.dev_code=J;this.token=Q;if(this.fetchFn=Z.fetchFn||fetch.bind(window),Z.is_h5!==void 0)this.is_h5=Z.is_h5;if(Z.rsa_public_key!==void 0)this.rsa_public_key=Z.rsa_public_key}async getRsaPublicKey(){if(this.rsa_public_key)return this.rsa_public_key;let J=await this._dna_request(E);if(J.is_success&&J.data){let Q=J.data.key;if(typeof Q==="string")this.rsa_public_key=Q}return this.rsa_public_key}async login(J,Q){let Z={mobile:J,code:Q,gameList:z},$=await this._dna_request(h,Z,{sign:!0,refer:!0});if($.is_success&&$.data){let j=$.data;if(typeof j.token==="string")this.token=j.token}return $}async loginLog(){return await this._dna_request(D)}async getRoleList(){return await this._dna_request(M)}async getDefaultRoleForTool(){let J={type:1};return await this._dna_request(T,J,{sign:!0,token:!0,tokenSig:!0})}async getCharDetail(J,Q,Z){let $={charId:J,charEid:Q,type:1,otherUserId:Z};return await this._dna_request(U,$)}async getWeaponDetail(J,Q,Z){let $={weaponId:J,weaponEid:Q,type:1,otherUserId:Z};return await this._dna_request(c,$)}async getShortNoteInfo(){return await this._dna_request(y)}async haveSignIn(){let J={gameId:z};return await this._dna_request(I,J)}async signCalendar(){let J={gameId:z};return await this._dna_request(N,J)}async gameSign(J,Q){let Z={dayAwardId:J,periodId:Q,signinType:1};return await this._dna_request(L,Z)}async bbsSign(){let J={gameId:z};return await this._dna_request(R,J)}async getTaskProcess(){let J={gameId:z};return await this._dna_request(A,J)}async getPostList(J=48,Q=1,Z=20,$=1,j=0){let V={forumId:J,gameId:z,pageIndex:Q,pageSize:Z,searchType:$,timeType:j};return await this._dna_request(i,V)}async getPostsByTopic(J=177,Q=1,Z=20,$=1,j=0){let V={topicId:J,gameId:z,pageIndex:Q,pageSize:Z,searchType:$,timeType:j};return await this._dna_request(n,V)}async getPostDetail(J){let Q={postId:J};return await this._dna_request(r,Q)}async doLike(J){let Q={forumId:J.gameForumId,gameId:z,likeType:"1",operateType:"1",postCommentId:"",postCommentReplyId:"",postId:J.postId,postType:J.postType,toUserId:J.userId};return await this._dna_request(d,Q)}async doShare(){let J={gameId:z};return await this._dna_request(p,J)}async doReply(J,Q){let Z=JSON.stringify([{content:Q,contentType:"1",imgHeight:0,imgWidth:0,url:""}]),$={postId:J.postId,forumId:J.gameForumId||47,postType:"1",content:Z};return await this._dna_request(_,$,{sign:!0,refer:!0,params:{toUserId:J.userId}})}async getOtherMine(J="709542994134436647"){let Q={otherUserId:J,searchType:1,type:2};return await this._dna_request(m,Q)}async getMine(){return await this._dna_request(m)}async getGameConfig(){let J={gameId:z};return await this._dna_request(o,J)}async getHeaders(J){let{payload:Q,exparams:Z,dev_code:$=this.dev_code,refer:j,token:V=this.token,tokenSig:q}=J||{},X="application/x-www-form-urlencoded; charset=utf-8",b={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"},O={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"},F={...this.is_h5?O:b};if($)F.devCode=$;if(j)F.origin="https://dnabbs.yingxiong.com",F.refer="https://dnabbs.yingxiong.com/";if(V)F.token=V;if(typeof Q==="object"){let x=jJ(Q,q?V:"");if(Object.assign(Q,{sign:x.s,timestamp:x.t}),Z)Object.assign(Q,Z);let H=new URLSearchParams;Object.entries(Q).forEach(([g,C])=>{H.append(g,String(C))}),Q=H.toString();let Y=x.k,K=await this.getRsaPublicKey(),v=a(Y,K);if(this.is_h5)F.k=v;else F.rk=Y,F.key=v}return{headers:F,payload:Q}}async _dna_request(J,Q,Z){let{method:$="POST",sign:j,refer:V,params:q,max_retries:X=3,retry_delay:b=1,timeout:O=1e4,token:F,tokenSig:x}=Z||{},H;if(j){let{payload:Y,headers:K}=await this.getHeaders({payload:Q,refer:V,exparams:q,token:F?this.token:void 0,tokenSig:x});Q=Y,H=K}else{let{headers:Y}=await this.getHeaders({token:F?this.token:void 0});H=Y}for(let Y=0;Y<X;Y++)try{let K=Q;if(Q&&typeof Q==="object"){let P=new URLSearchParams;Object.entries(Q).forEach(([l,S])=>{if(S!==void 0)P.append(l,String(S))}),K=P.toString()}let v={method:$,headers:H,body:K},g=new AbortController,C=setTimeout(()=>g.abort(),O),u=await this.fetchFn(J,{...v,signal:g.signal});clearTimeout(C);let k=u.headers.get("content-type")||"",f;if(k.includes("text/")){let P=await u.text();f={code:-999,data:P}}else f=await u.json();if(typeof f==="object"&&f!==null)try{if(typeof f.data==="string")f.data=JSON.parse(f.data)}catch(P){}return new w(f)}catch(K){if(console.error(`请求失败: ${K.message}`),Y<X-1)await new Promise((v)=>setTimeout(v,b*Math.pow(2,Y)))}return w.err("请求服务器失败,已达最大重试次数")}}var G;((q)=>{q.角色="role";q.武器="weapon";q.魔之楔="mzx";q.role="角色";q.weapon="武器";q.mzx="魔之楔"})(G||={});function qJ(J){return G[J]}var t;(($)=>{$[$.TEXT=1]="TEXT";$[$.IMAGE=2]="IMAGE";$[$.VIDEO=5]="VIDEO"})(t||={});class w{code=0;msg="";success=!1;data;constructor(J){this.code=J.code||0,this.msg=J.msg||"",this.success=J.success||!1,this.data=J.data}get is_success(){return this.success&&[0,200].includes(this.code)}static err(J,Q=-999){return new w({code:Q,msg:J,data:void 0,success:!1})}}function a(J,Q){try{let Z=[];for(let X=0;X<Q.length;X+=64)Z.push(Q.slice(X,X+64));let $=`-----BEGIN PUBLIC KEY-----
2
- ${Z.join(`
1
+ import*as K from"node-forge";var $=268;class N{dev_code;token;fetchFn;is_h5=!1;RSA_PUBLIC_KEY="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGpdbezK+eknQZQzPOjp8mr/dP+QHwk8CRkQh6C6qFnfLH3tiyl0pnt3dePuFDnM1PUXGhCkQ157ePJCQgkDU2+mimDmXh0oLFn9zuWSp+U8uLSLX3t3PpJ8TmNCROfUDWvzdbnShqg7JfDmnrOJz49qd234W84nrfTHbzdqeigQIDAQAB";BASE_URL="https://dnabbs-api.yingxiong.com/";constructor(J,L="",Q={}){this.dev_code=J;this.token=L;if(this.fetchFn=Q.fetchFn,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 J=await this._dna_request("config/getRsaPublicKey");if(J.is_success&&J.data){let L=J.data.key;if(typeof L==="string")this.RSA_PUBLIC_KEY=L}return this.RSA_PUBLIC_KEY}async login(J,L){let Q={mobile:J,code:L,gameList:$},V=await this._dna_request("user/sdkLogin",Q,{sign:!0,refer:!0});if(V.is_success&&V.data){let W=V.data;if(typeof W.token==="string")this.token=W.token}return V}async loginLog(){return await this._dna_request("user/login/log")}async getRoleList(){return await this._dna_request("role/list")}async getDefaultRoleForTool(){let J={type:1};return await this._dna_request("role/defaultRoleForTool",J,{sign:!0,token:!0,tokenSig:!0})}async getCharDetail(J,L,Q){let V={charId:J,charEid:L,type:1,otherUserId:Q};return await this._dna_request("role/getCharDetail",V)}async getWeaponDetail(J,L,Q){let V={weaponId:J,weaponEid:L,type:1,otherUserId:Q};return await this._dna_request("role/getWeaponDetail",V)}async getShortNoteInfo(){return await this._dna_request("role/getShortNoteInfo")}async haveSignIn(){let J={gameId:$};return await this._dna_request("user/haveSignInNew",J)}async signCalendar(){let J={gameId:$};return await this._dna_request("encourage/signin/show",J)}async soulTask(){return await this._dna_request("role/soul/task")}async gameSign(J,L){let Q={dayAwardId:J,periodId:L,signinType:1};return await this._dna_request("encourage/signin/signin",Q)}async bbsSign(){let J={gameId:$};return await this._dna_request("user/signIn",J)}async getTaskProcess(){let J={gameId:$};return await this._dna_request("encourage/level/getTaskProcess",J)}async getPostList(J=48,L=1,Q=20,V=1,W=0){let Y={forumId:J,gameId:$,pageIndex:L,pageSize:Q,searchType:V,timeType:W};return await this._dna_request("forum/list",Y)}async lockPost(J){let L={postId:J.postId,gameId:J.gameId??$,gameForumId:J.gameForumId,operateType:J.operateType};return await this._dna_request("forum/moderator/postLock",L)}async postDownOrUp(J){let L={postId:J.postId,gameId:J.gameId??$,gameForumId:J.gameForumId,operateType:J.operateType};return await this._dna_request("forum/moderator/postDownOrUp",L)}async postElite(J){let L={postId:J.postId,gameId:J.gameId??$,gameForumId:J.gameForumId,operateType:J.operateType};return await this._dna_request("forum/moderator/postElite",L)}async postHide(J){let L={postId:J.postId,gameId:J.gameId??$,gameForumId:J.gameForumId,operateType:J.operateType};return await this._dna_request("forum/moderator/postHide",L)}async reRank(J,L){let Q={postId:J.postId,gameId:J.gameId??$,gameForumId:J.gameForumId,weight:L};return await this._dna_request("forum/moderator/reRank",Q)}async strongRecommend(J,L=1){let Q={postId:J.postId,gameId:J.gameId??$,gameForumId:J.gameForumId,operateType:L};return await this._dna_request("forum/moderator/setForceRecommend",Q)}async adminDelete(J,L,Q){let V={postId:J.postId,gameId:J.gameId??$,gameForumId:J.gameForumId,content:L,reasonCode:Q};return await this._dna_request("forum/moderator/postDelete",V)}async adminMovePost(J,L,Q,V){let W={postId:J.postId,gameId:J.gameId??$,gameForumId:J.gameForumId,newGameId:L,newForumId:Q,newTopicIdStr:V};return await this._dna_request("forum/moderator/postMove",W)}async adminRefreshTime(J,L){let Q={postId:J.postId,gameId:J.gameId??$,gameForumId:J.gameForumId,refresh:L};return await this._dna_request("forum/moderator/setRefresh",Q)}async blockList(){return await this._dna_request("user/block/list")}async blockOther(J,L,Q){let V={blockPostId:J,blockUserId:L,type:Q};return await this._dna_request("user/block/list",V)}async viewCommunity(){return await this._dna_request("encourage/level/viewCommunity")}async viewCount(){return await this._dna_request("forum/viewCount")}async receiveLog(J,L,Q){let V={periodId:J,pageIndex:L,pageSize:Q};return await this._dna_request("encourage/signin/receiveLog",V)}async collect(J,L,Q=1){let V={operateType:Q,postId:J,toUserId:L};return await this._dna_request("forum/collect",V)}async commentDelete(J,L,Q,V){let W={id:J.id,gameId:J.gameId,gameForumId:J.gameForumId,entityType:L,content:Q,reasonCode:V};return await this._dna_request("forum/collect",W)}async recommendList(J,L,Q,V,W=$){let Y={gameId:W,recIndex:J,newIndex:L,size:Q,history:V};return await this._dna_request("forum/recommend/list",Y)}async report({commentId:J=0,postId:L=0,replyId:Q=0},V=1,W=1){let Y={commentId:J,postId:L,replyId:Q,reportReason:V,reportType:W};return await this._dna_request("forum/recommend/list",Y)}async searchPost(J,L,Q,V=$,W=1){let Y={gameId:V,keyword:J,pageIndex:L,pageSize:Q,searchType:W};return await this._dna_request("forum/searchPost",Y)}async searchTopic(J,L,Q=20,V=$){let W={gameId:V,keyword:J,pageIndex:L,pageSize:Q};return await this._dna_request("config/searchTopic",W)}async searchUser(J,L,Q){let V={keyword:J,pageIndex:L,pageSize:Q};return await this._dna_request("user/searchUser",V)}async getPostsByTopic(J=177,L=1,Q=20,V=1,W=0){let Y={topicId:J,gameId:$,pageIndex:L,pageSize:Q,searchType:V,timeType:W};return await this._dna_request("forum/getPostByTopic",Y)}async getPostDetail(J){let L={postId:J};return await this._dna_request("forum/getPostDetail",L)}async doFollow(J,L){let Q={followUserId:J,operateType:L?0:1};return await this._dna_request("user/followUser",Q,{sign:!0})}async getFollowState(J){let L={followUserId:J};return await this._dna_request("user/isFollow",L)}async doLike(J){let L={forumId:J.gameForumId,gameId:$,likeType:"1",operateType:"1",postCommentId:"",postCommentReplyId:"",postId:J.postId,postType:J.postType,toUserId:J.userId};return await this._dna_request("forum/like",L)}async doShare(){let J={gameId:$};return await this._dna_request("encourage/level/shareTask",J)}async createComment(J,L){let Q=JSON.stringify([{content:L,contentType:"1",imgHeight:0,imgWidth:0,url:""}]),V={postId:J.postId,forumId:J.gameForumId,postType:"1",content:Q};return await this._dna_request("forum/comment/createComment",V,{sign:!0,refer:!0,params:{toUserId:J.userId}})}async createReply(J,L){let V={content:JSON.stringify([{content:L,contentType:"1",imgHeight:0,imgWidth:0,url:""}]),forumId:J.gameForumId,postCommentId:J.postCommentId,postId:J.postId,postType:"1",toUserId:J.userId};return await this._dna_request("forum/comment/createReply",V,{sign:!0,refer:!0,params:{toUserId:J.userId}})}async createReplyList(J,L){let V={content:JSON.stringify([{content:L,contentType:"1",imgHeight:0,imgWidth:0,url:""}]),forumId:J.gameForumId,postCommentId:J.postCommentId,postCommentReplyId:J.postCommentReplyId,postId:J.postId,postType:"1",toUserId:J.userId};return await this._dna_request("forum/comment/createReply",V,{sign:!0,refer:!0,params:{toUserId:J.userId}})}async deletePost(J,L){return await this._dna_request("forum/more/delete",{deleteType:J,id:L},{sign:!0,refer:!0})}async getOtherMine(J="709542994134436647"){let L={otherUserId:J,searchType:1,type:2};return await this._dna_request("user/mine",L)}async getMine(){return await this._dna_request("user/mine")}async getGameConfig(){let J={gameId:$};return await this._dna_request("config/getGameConfig",J)}async getHeaders(J){let{payload:L,exparams:Q,dev_code:V=this.dev_code,refer:W,token:Y=this.token,tokenSig:Z}=J||{},j="application/x-www-form-urlencoded; charset=utf-8",H={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"},S={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"},q={...this.is_h5?S:H};if(V)q.devCode=V;if(W)q.origin="https://dnabbs.yingxiong.com",q.refer="https://dnabbs.yingxiong.com/";if(Y)q.token=Y;if(typeof L==="object"){let f=m(L,Z?Y:"");if(Object.assign(L,{sign:f.s,timestamp:f.t}),Q)Object.assign(L,Q);let O=new URLSearchParams;Object.entries(L).forEach(([z,R])=>{O.append(z,String(R))}),L=O.toString();let X=f.k,F=await this.getRsaPublicKey(),U=T(X,F);if(this.is_h5)q.k=U;else q.rk=X,q.key=U}return{headers:q,payload:L}}async _dna_request(J,L,Q){let{method:V="POST",sign:W,refer:Y,params:Z,max_retries:j=3,retry_delay:H=1,timeout:S=1e4,token:q,tokenSig:f}=Q||{},O;if(W){let{payload:X,headers:F}=await this.getHeaders({payload:L,refer:Y,exparams:Z,token:q?this.token:void 0,tokenSig:f});L=X,O=F}else{let{headers:X}=await this.getHeaders({token:q?this.token:void 0});O=X}for(let X=0;X<j;X++)try{let F=L;if(L&&typeof L==="object"){let P=new URLSearchParams;Object.entries(L).forEach(([M,E])=>{if(E!==void 0)P.append(M,String(E))}),F=P.toString()}let U={method:V,headers:O,body:F},z=new AbortController,R=setTimeout(()=>z.abort(),S),C={...U,signal:z.signal},b=this.fetchFn?await this.fetchFn(`${this.BASE_URL}${J}`,C):await fetch(`${this.BASE_URL}${J}`,C);clearTimeout(R);let x=b.headers.get("content-type")||"",B;if(x.includes("text/")){let P=await b.text();B={code:-999,data:P}}else B=await b.json();if(typeof B==="object"&&B!==null)try{if(typeof B.data==="string")B.data=JSON.parse(B.data)}catch(P){}return new v(B)}catch(F){if(console.error(`请求失败: ${F.message}`),X<j-1)await new Promise((U)=>setTimeout(U,H*Math.pow(2,X)))}return v.err("请求服务器失败,已达最大重试次数")}}var G;((Z)=>{Z.角色="role";Z.武器="weapon";Z.魔之楔="mzx";Z.role="角色";Z.weapon="武器";Z.mzx="魔之楔"})(G||={});function D(J){return G[J]}var u;((V)=>{V[V.TEXT=1]="TEXT";V[V.IMAGE=2]="IMAGE";V[V.VIDEO=5]="VIDEO"})(u||={});class v{code=0;msg="";success=!1;data;constructor(J){this.code=J.code||0,this.msg=J.msg||"",this.success=J.success||!1,this.data=J.data}get is_success(){return this.success&&[0,200].includes(this.code)}static err(J,L=-999){return new v({code:L,msg:J,data:void 0,success:!1})}}function T(J,L){try{let Q=[];for(let j=0;j<L.length;j+=64)Q.push(L.slice(j,j+64));let V=`-----BEGIN PUBLIC KEY-----
2
+ ${Q.join(`
3
3
  `)}
4
- -----END PUBLIC KEY-----`,j=B.pki.publicKeyFromPem($),V=B.util.encodeUtf8(J),q=j.encrypt(V);return B.util.encode64(q)}catch(Z){throw Error(`[DNA] RSA 加密失败: ${Z.message}`)}}function e(J=16){let Z="";for(let $=0;$<J;$++)Z+="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.floor(Math.random()*62));return Z}function JJ(J){let Q=B.md.md5.create();return Q.update(J),Q.digest().toHex().toUpperCase()}function QJ(J){function Q(Z,$){let j=Z.split("");for(let V=1;V<$.length;V+=2){let q=$[V-1],X=$[V];if(q>=0&&q<j.length&&X>=0&&X<j.length)[j[q],j[X]]=[j[X],j[q]]}return j.join("")}return Q(JJ(J),[1,13,5,17,7,23])}function ZJ(J,Q){let Z=[],$=Object.keys(J).sort();for(let V of $){let q=J[V];if(q!==null&&q!==void 0&&q!=="")Z.push(`${V}=${q}`)}let j=Z.join("&");return QJ(`${j}&${Q}`)}function $J(J,Q){let Z=new TextEncoder,$=Z.encode(J),j=Z.encode(Q),V=[];for(let q=0;q<$.length;q++){let b=($[q]&255)+(j[q%j.length]&255);V.push(`@${b}`)}return V.join("")}function jJ(J,Q){let Z=Date.now(),$={...J,timestamp:Z,token:Q},j=e(16),V=ZJ($,j);return{s:$J(V,j),t:Z,k:j}}export{qJ as getDNAInstanceMHType,t as PostContentType,s as DNAAPI};
4
+ -----END PUBLIC KEY-----`,W=K.pki.publicKeyFromPem(V),Y=K.util.encodeUtf8(J),Z=W.encrypt(Y);return K.util.encode64(Z)}catch(Q){throw Error(`[DNA] RSA 加密失败: ${Q.message}`)}}function w(J=16){let Q="";for(let V=0;V<J;V++)Q+="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(Math.floor(Math.random()*62));return Q}function k(J){let L=K.md.md5.create();return L.update(J),L.digest().toHex().toUpperCase()}function g(J){function L(Q,V){let W=Q.split("");for(let Y=1;Y<V.length;Y+=2){let Z=V[Y-1],j=V[Y];if(Z>=0&&Z<W.length&&j>=0&&j<W.length)[W[Z],W[j]]=[W[j],W[Z]]}return W.join("")}return L(k(J),[1,13,5,17,7,23])}function h(J,L){let Q=[],V=Object.keys(J).sort();for(let Y of V){let Z=J[Y];if(Z!==null&&Z!==void 0&&Z!=="")Q.push(`${Y}=${Z}`)}let W=Q.join("&");return g(`${W}&${L}`)}function l(J,L){let Q=new TextEncoder,V=Q.encode(J),W=Q.encode(L),Y=[];for(let Z=0;Z<V.length;Z++){let H=(V[Z]&255)+(W[Z%W.length]&255);Y.push(`@${H}`)}return Y.join("")}function m(J,L){let Q=Date.now(),V={...J,timestamp:Q,token:L},W=w(16),Y=h(V,W);return{s:l(Y,W),t:Q,k:W}}export{D as getDNAInstanceMHType,u as PostContentType,N as DNAAPI};
5
5
 
6
- //# debugId=B51DD8AA6D0912A964756E2164756E21
6
+ //# debugId=5B73BAA9D9E7DDB064756E2164756E21
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}/role/getWeaponDetail`\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_BY_TOPIC_URL = `${MAIN_URL}/forum/getPostByTopic`\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 GET_GAME_CONFIG_URL = `${MAIN_URL}/config/getGameConfig`\r\nconst GET_MINE_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: typeof 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 token = \"\",\r\n options: { fetchFn?: typeof fetch; is_h5?: boolean; rsa_public_key?: string } = {},\r\n ) {\r\n this.fetchFn = options.fetchFn || fetch.bind(window)\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) {\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.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, token: true, tokenSig: true })\r\n }\r\n\r\n /**\r\n * 获取角色详情\r\n */\r\n async getCharDetail(char_id: string, char_eid: string, otherUserId?: string) {\r\n const data = { charId: char_id, charEid: char_eid, type: 1, otherUserId } as any\r\n return await this._dna_request<DNACharDetailRes>(ROLE_DETAIL_URL, data)\r\n }\r\n\r\n /**\r\n * 获取武器详情\r\n */\r\n async getWeaponDetail(weapon_id: string, weapon_eid: string, otherUserId?: string) {\r\n const data = { weaponId: weapon_id, weaponEid: weapon_eid, type: 1, otherUserId }\r\n return await this._dna_request<DNAWeaponDetailRes>(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 * @param forumId 论坛ID\r\n * @param pageIndex 页码\r\n * @param pageSize 每页数量\r\n * @param searchType 搜索类型 1:最新 2:热门\r\n * @param timeType 时间类型 0:全部 1:今日 2:本周 3:本月\r\n * @returns 帖子列表\r\n */\r\n async getPostList(forumId: number = 48, pageIndex: number = 1, pageSize: number = 20, searchType: number = 1, timeType: number = 0) {\r\n const data = {\r\n forumId: forumId,\r\n gameId: DNA_GAME_ID,\r\n pageIndex: pageIndex,\r\n pageSize: pageSize,\r\n searchType: searchType, // 1:最新 2:热门\r\n timeType: timeType, // 0:全部 1:今日 2:本周 3:本月\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 * @param forumId 论坛ID\r\n * @param pageIndex 页码\r\n * @param pageSize 每页数量\r\n * @param searchType 搜索类型 1:最新 2:热门\r\n * @param timeType 时间类型 0:全部 1:今日 2:本周 3:本月\r\n * @returns 帖子列表\r\n */\r\n async getPostsByTopic(\r\n topicId: number = 177,\r\n pageIndex: number = 1,\r\n pageSize: number = 20,\r\n searchType: number = 1,\r\n timeType: number = 0,\r\n ) {\r\n const data = {\r\n topicId: topicId,\r\n gameId: DNA_GAME_ID,\r\n pageIndex: pageIndex,\r\n pageSize: pageSize,\r\n searchType: searchType, // 1:最新 2:热门\r\n timeType: timeType, // 0:全部 1:今日 2:本周 3:本月\r\n }\r\n return await this._dna_request<DNAPostListRes>(GET_POST_BY_TOPIC_URL, data)\r\n }\r\n /**\r\n * 获取帖子详情\r\n * @param post_id 帖子ID\r\n * @returns 帖子详情\r\n */\r\n async getPostDetail(post_id: string) {\r\n const data = { postId: post_id }\r\n return await this._dna_request<DNAPostDetailRes>(GET_POST_DETAIL_URL, data)\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 return await this._dna_request(LIKE_POST_URL, data)\r\n }\r\n\r\n // 分享帖子\r\n async doShare() {\r\n const data = { gameId: DNA_GAME_ID }\r\n return await this._dna_request(SHARE_POST_URL, data)\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 * 获取用户信息\r\n * @returns 用户信息\r\n */\r\n async getOtherMine(userId = \"709542994134436647\") {\r\n const data = {\r\n otherUserId: userId,\r\n searchType: 1,\r\n type: 2,\r\n }\r\n return await this._dna_request<DNAMineRes>(GET_MINE_URL, data)\r\n }\r\n\r\n /**\r\n * 获取用户信息\r\n * @returns 用户信息\r\n */\r\n async getMine() {\r\n return await this._dna_request<DNAMineRes>(GET_MINE_URL)\r\n }\r\n\r\n async getGameConfig() {\r\n const data = { gameId: DNA_GAME_ID }\r\n return await this._dna_request<DNAGameConfigRes[]>(GET_GAME_CONFIG_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 tokenSig?: boolean\r\n }) {\r\n let { payload, exparams, dev_code = this.dev_code, refer, token = this.token, tokenSig } = 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, tokenSig ? token : \"\")\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 tokenSig?: boolean\r\n token?: 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, token, tokenSig } = options || {}\r\n let headers: Record<string, any>\r\n if (sign) {\r\n const { payload: p, headers: h } = await this.getHeaders({\r\n payload: data,\r\n refer,\r\n exparams: params,\r\n token: token ? this.token : undefined,\r\n tokenSig,\r\n })\r\n data = p\r\n headers = h\r\n } else {\r\n const { headers: h } = await this.getHeaders({ token: token ? this.token : undefined })\r\n headers = h\r\n }\r\n\r\n for (let attempt = 0; attempt < max_retries; attempt++) {\r\n try {\r\n let body: string = data\r\n if (data && typeof data === \"object\") {\r\n const p = new URLSearchParams()\r\n Object.entries(data).forEach(([key, value]) => {\r\n if (value !== undefined) p.append(key, String(value))\r\n })\r\n body = p.toString()\r\n }\r\n const fetchOptions: RequestInit = {\r\n method,\r\n headers,\r\n body,\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 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 DNAMineRes {\r\n mine: DNAMine\r\n postList: DNAPost[]\r\n hasNext: number\r\n}\r\n\r\ninterface DNAMine {\r\n /** 文章数量 */\r\n articleCount: number\r\n /** 收藏数量 */\r\n collectCount: number\r\n /** 评论数量 */\r\n commentCount: number\r\n /** 粉丝数量 */\r\n fansCount: number\r\n /** 新粉丝数量 */\r\n fansNewCount: number\r\n /** 关注数量 */\r\n followCount: number\r\n /** 性别 */\r\n gender: number\r\n /** 精华数量 */\r\n goldNum: number\r\n /** 头像 */\r\n headUrl: string\r\n /** 是否关注 */\r\n isFollow: number\r\n /** 是否登录用户 */\r\n isLoginUser: number\r\n /** 是否被禁言 */\r\n isMute: number\r\n /** 等级 */\r\n levelTotal: number\r\n /** 点赞数量 */\r\n likeCount: number\r\n /** 手机号 */\r\n mobile: string\r\n /** 管理员列表 */\r\n moderatorVos: any[]\r\n /** 帖子数量 */\r\n postCount: number\r\n /** 注册时间 */\r\n registerTime: string\r\n /** 状态 */\r\n status: number\r\n /** 趋势数量 */\r\n trendCount: number\r\n /** 用户ID */\r\n userId: string\r\n /** 用户名 */\r\n userName: string\r\n}\r\n\r\nexport interface DNAGameConfigRes {\r\n /** 游戏所有板块列表 */\r\n gameAllForumList: GameForum[]\r\n /** 游戏ID */\r\n gameId: number\r\n /** 游戏板块图片列表 */\r\n gameForumPictureList: any[]\r\n /** 游戏板块列表 */\r\n gameForumList: GameForum[]\r\n /** 签到按钮图片 */\r\n signBtn: string\r\n sort: number\r\n /** 话题列表 */\r\n topicList: GameTopic[]\r\n /** 背景图片 */\r\n drawBackgroundUrl: string\r\n /** 是否默认游戏 */\r\n gameDefault: number\r\n /** 签到颜色 */\r\n signColor: string\r\n /** 游戏名称 */\r\n gameName: string\r\n /** CM图片2 意味不明 */\r\n drawListUrl: string\r\n /** 英文站点 */\r\n configTab: ConfigTab[]\r\n}\r\n\r\nexport interface ConfigTab {\r\n name: string\r\n url: string\r\n}\r\n\r\nexport interface GameTopic {\r\n /** 话题背景图片 */\r\n backgroundUrl: string\r\n gameId: number\r\n /** 话题图标 */\r\n topicIconUrl: string\r\n topicId: number\r\n /** 话题名称 */\r\n topicName: string\r\n sort: number\r\n /** 话题描述 */\r\n topicDesc: string\r\n}\r\n\r\nexport interface GameForum {\r\n /** 全部=1 普通=3 */\r\n forumDataType: number\r\n /** 固定1 */\r\n forumUiType: number\r\n /** 小红点 */\r\n isTrend: number\r\n /** 夜间模式图标 */\r\n iconWhiteUrl: string\r\n /** 固定1 */\r\n forumType: number\r\n /** 板块名称 */\r\n name: string\r\n forumListShowType: number\r\n /** 图标 */\r\n iconUrl: string\r\n id: number\r\n sort: number\r\n /** 官方 */\r\n isOfficial: number\r\n}\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\r\n /** 中文 */\r\n name: string\r\n /** 密函编码 */\r\n code: string\r\n /** 固定0 */\r\n on: number\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 DNARoleWeapon {\r\n weaponId: number\r\n weaponEid: string\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 skillLevel: number\r\n /** 是否解锁 */\r\n unLocked: boolean\r\n}\r\n\r\nexport interface DNARoleChar {\r\n charId: number\r\n charEid: string\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 DNARoleForToolRes {\r\n /** 角色信息 */\r\n roleInfo: DNARoleInfo\r\n /** 密函 */\r\n instanceInfo: DNARoleForToolInstanceInfo[]\r\n}\r\n\r\nexport interface DNARoleShow {\r\n /** 角色列表 */\r\n roleChars: DNARoleChar[]\r\n /** 武器列表 */\r\n langRangeWeapons: DNARoleWeapon[]\r\n /** 武器列表 */\r\n closeWeapons: DNARoleWeapon[]\r\n /** 角色头像 */\r\n headUrl: string\r\n /** 等级 */\r\n level: number\r\n /** 成就列表 */\r\n params: DNARoleAchievement[]\r\n /** 角色id */\r\n roleId: string\r\n /** 角色名称 */\r\n roleName: string\r\n /** 迷津 */\r\n rougeLikeInfo: DNARougeLikeInfo\r\n}\r\n\r\nexport interface DNARoleAchievement {\r\n paramKey: string // paramKey\r\n paramValue: string // paramValue\r\n}\r\n\r\nexport interface DNARoleInfo {\r\n /** 深渊信息 */\r\n abyssInfo: DNAAbyssInfo\r\n /** 角色信息 */\r\n roleShow: DNARoleShow\r\n}\r\n\r\nexport interface DNARougeLikeInfo {\r\n /** 最大通过等级 */\r\n maxPassed: number\r\n /** 最大通过等级名称 */\r\n maxPassedName: string\r\n /** 重置时间 */\r\n resetTime: string\r\n /** 奖励数量 */\r\n rewardCount: number\r\n /** 奖励总数 */\r\n rewardTotal: number\r\n /** 天赋信息 */\r\n talentInfo: DNARougeLikeTalentInfo[]\r\n}\r\n\r\nexport interface DNARougeLikeTalentInfo {\r\n cur: string\r\n max: string\r\n}\r\n\r\nexport interface DNAAbyssInfo {\r\n /** 阵容 */\r\n bestTimeVo1: DNABestTimeVo1\r\n /** 结束时间 */\r\n endTime: string\r\n /** 操作名称 */\r\n operaName: string\r\n /** 进度名称 */\r\n progressName: string\r\n /** 星级 */\r\n stars: string\r\n /** 开始时间 */\r\n startTime: string\r\n}\r\n\r\n/** 深渊阵容 */\r\nexport interface DNABestTimeVo1 {\r\n /** 角色图标 */\r\n charIcon: string\r\n /** 近战武器图标 */\r\n closeWeaponIcon: string\r\n /** 远程武器图标 */\r\n langRangeWeaponIcon: string\r\n /** 魔灵图标 */\r\n petIcon: string\r\n /** 协战角色图标1 */\r\n phantomCharIcon1: string\r\n /** 协战武器图标1 */\r\n phantomWeaponIcon1: string\r\n /** 协战角色图标2 */\r\n phantomCharIcon2: string\r\n /** 协战武器图标2 */\r\n phantomWeaponIcon2: string\r\n}\r\n\r\n/** 角色属性 */\r\nexport interface DNACharAttribute {\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 def: 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\n/** 角色技能 */\r\nexport interface DNARoleSkill {\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\n/** 溯源 */\r\nexport interface DNARoleTrace {\r\n /** 溯源图标 */\r\n icon: string\r\n /** 溯源描述 */\r\n description: string\r\n}\r\n\r\n/** 魔之楔 */\r\nexport interface DNARoleMod {\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 DNACharDetail {\r\n charId: number\r\n /** 角色属性 */\r\n attribute: DNACharAttribute\r\n /** 角色技能 */\r\n skills: DNARoleSkill[]\r\n /** 立绘 */\r\n paint: string\r\n /** 角色名称 */\r\n charName: string\r\n /** 元素图标 */\r\n elementIcon: string\r\n /** 溯源 */\r\n traces: DNARoleTrace[]\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 /** 魔之楔列表 */\r\n modes: DNARoleMod[]\r\n}\r\n\r\nexport interface DNACharDetailRes {\r\n /** 角色详情 */\r\n charDetail: DNACharDetail\r\n}\r\n\r\nexport interface DNAWeaponDetailRes {\r\n /** 武器详情 */\r\n weaponDetail: DNAWeaponDetail\r\n}\r\n\r\nexport interface DNAWeaponDetail {\r\n attribute: DNAWeaponAttribute\r\n currentVolume: number\r\n description: string\r\n elementIcon: string\r\n elementName: string\r\n icon: string\r\n id: number\r\n level: number\r\n modes: DNARoleMod[]\r\n name: string\r\n skillLevel: number\r\n sumVolume: number\r\n}\r\n\r\nexport interface DNAWeaponAttribute {\r\n atk: number\r\n crd: number\r\n cri: number\r\n speed: number\r\n trigger: number\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 DNATopicPostListRes {\r\n postList: DNAPost[]\r\n topic: DNATopicDetail\r\n hasNext: number\r\n}\r\n\r\nexport interface DNATopicDetail {\r\n backgroundUrl: string\r\n gameId: number\r\n sort: number\r\n topicDesc: string\r\n topicIconUrl: string\r\n topicId: number\r\n topicName: string\r\n}\r\n\r\nexport interface DNAPost {\r\n browseCount: string\r\n collectionCount: number\r\n commentCount: number\r\n gameForumId: number\r\n gameId: number\r\n gameName: string\r\n imgContent: DNAPostImgContent[]\r\n imgCount: number\r\n isCollect: number\r\n isCreator: number\r\n isElite: number\r\n isFollow: number\r\n isLike: number\r\n isLock: number\r\n isOfficial: number\r\n isPublisher: number\r\n likeCount: number\r\n postContent: string\r\n postCover: string\r\n postCoverVo: DNAPostCoverVo\r\n postId: string\r\n postStatus: number\r\n postTitle: string\r\n postType: number\r\n showTime: string\r\n topics: DNATopicShort[]\r\n userHeadUrl: string\r\n userId: string\r\n userLevel: number\r\n userModeratorIdentity: number\r\n userName: string\r\n}\r\n\r\nexport interface DNATopicShort {\r\n topicId: number\r\n topicName: string\r\n}\r\n\r\nexport interface DNAPostCoverVo {\r\n imgHeight: number\r\n imgWidth: number\r\n}\r\n\r\nexport interface DNAPostImgContent {\r\n imgHeight: number\r\n imgWidth: number\r\n url: string\r\n isAbnormal?: boolean\r\n}\r\n\r\nexport interface DNAPostListRes {\r\n postList: DNAPost[] // posts\r\n topList: any[]\r\n hasNext: number\r\n}\r\n\r\nexport interface DNAPostDetailRes {\r\n isHotCount: boolean\r\n gameId: number\r\n isFollow: number\r\n isLike: number\r\n postDetail: DNAPostDetail\r\n isCollect: number\r\n hasNext: number\r\n comment: DNAComment[]\r\n}\r\n\r\nexport interface DNAPostDetail {\r\n auditStatus: number\r\n browseCount: string\r\n checkStatus: number\r\n collectionCount: number\r\n commentCount: number\r\n gameForumId: number\r\n gameForumVo: DNAGameForumVo\r\n gameId: number\r\n gameName: string\r\n headCodeUrl: string\r\n id: string\r\n isCreator: number\r\n isElite: number\r\n isForceRecommend: number\r\n isHide: number\r\n isLock: number\r\n isMine: number\r\n isOfficial: number\r\n isRecommend: number\r\n isTop: number\r\n lastEditorTime: string\r\n likeCount: number\r\n postContent: DNAPostContent[]\r\n postH5Content: string\r\n postTime: string\r\n postTitle: string\r\n postType: number\r\n postUserId: string\r\n refreshHour: number\r\n score: number\r\n userLevel: number\r\n userModeratorIdentity: number\r\n userName: string\r\n whiteUrl: any[]\r\n}\r\n\r\nexport interface DNAPostContent {\r\n contentType: PostContentType\r\n imgHeight: number\r\n imgWidth: number\r\n url?: string\r\n content?: string\r\n contentVideo?: DNAPostContentVideo\r\n}\r\n\r\nexport interface DNAComment {\r\n checkStatus: number\r\n commentContent: DNAPostContent[]\r\n commentId: string\r\n commentTime: string\r\n contentTextStatus: number\r\n floor: number\r\n isCreator: number\r\n isLike: number\r\n isMine: number\r\n isOfficial: number\r\n isPublisher: number\r\n likeCount: number\r\n replyCount: number\r\n replyVos: DNAReplyVos[]\r\n userHeadCode?: string\r\n userHeadUrl: string\r\n userId: string\r\n userLevel: number\r\n userModeratorIdentity: number\r\n userName: string\r\n}\r\n\r\nexport interface DNAReplyVos {\r\n checkStatus: number\r\n contentTextStatus: number\r\n createTime: number\r\n isCreator: number\r\n isLike: number\r\n isMine: number\r\n isOfficial: number\r\n isPublisher: number\r\n likeCount: number\r\n postCommentId: string\r\n postCommentReplayId: string\r\n replyContent: DNAPostContent[]\r\n replyContentStr: string\r\n replyId: string\r\n replyTime: string\r\n toUserIsCreator: number\r\n toUserModeratorIdentity: number\r\n toUserName: string\r\n userHeadCode?: string\r\n userHeadUrl: string\r\n userId: string\r\n userLevel: number\r\n userModeratorIdentity: number\r\n userName: string\r\n}\r\n\r\nexport interface DNAGameForumVo {\r\n forumDataType: number\r\n forumListShowType: number\r\n forumType: number\r\n forumUiType: number\r\n iconUrl: string\r\n iconWhiteUrl: string\r\n id: number\r\n isOfficial: number\r\n isTrend: number\r\n name: string\r\n sort: number\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 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 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//#endregion\r\n"
5
+ "import * as forge from \"node-forge\"\r\n//#region const\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?: typeof fetch\r\n public is_h5 = false\r\n public RSA_PUBLIC_KEY =\r\n \"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGpdbezK+eknQZQzPOjp8mr/dP+QHwk8CRkQh6C6qFnfLH3tiyl0pnt3dePuFDnM1PUXGhCkQ157ePJCQgkDU2+mimDmXh0oLFn9zuWSp+U8uLSLX3t3PpJ8TmNCROfUDWvzdbnShqg7JfDmnrOJz49qd234W84nrfTHbzdqeigQIDAQAB\"\r\n public BASE_URL = \"https://dnabbs-api.yingxiong.com/\"\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 token = \"\",\r\n options: { fetchFn?: typeof fetch; is_h5?: boolean; rsa_public_key?: string } = {},\r\n ) {\r\n 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 }>(\"config/getRsaPublicKey\")\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) {\r\n const data = { mobile, code, gameList: DNA_GAME_ID }\r\n const res = await this._dna_request<DNALoginRes>(\"user/sdkLogin\", data, { sign: true, refer: true })\r\n if (res.is_success && res.data) {\r\n const data = res.data\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>(\"user/login/log\")\r\n }\r\n\r\n /**\r\n * 获取角色列表\r\n */\r\n async getRoleList() {\r\n return await this._dna_request<DNARoleListRes>(\"role/list\")\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/defaultRoleForTool\", data, { sign: true, token: true, tokenSig: true })\r\n }\r\n\r\n /**\r\n * 获取角色详情\r\n */\r\n async getCharDetail(char_id: string, char_eid: string, otherUserId?: string) {\r\n const data = { charId: char_id, charEid: char_eid, type: 1, otherUserId } as any\r\n return await this._dna_request<DNACharDetailRes>(\"role/getCharDetail\", data)\r\n }\r\n\r\n /**\r\n * 获取武器详情\r\n */\r\n async getWeaponDetail(weapon_id: string, weapon_eid: string, otherUserId?: string) {\r\n const data = { weaponId: weapon_id, weaponEid: weapon_eid, type: 1, otherUserId }\r\n return await this._dna_request<DNAWeaponDetailRes>(\"role/getWeaponDetail\", data)\r\n }\r\n\r\n /**\r\n * 获取角色简讯\r\n */\r\n async getShortNoteInfo() {\r\n return await this._dna_request<DNARoleShortNoteRes>(\"role/getShortNoteInfo\")\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>(\"user/haveSignInNew\", 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>(\"encourage/signin/show\", data)\r\n }\r\n\r\n /** ? */\r\n async soulTask() {\r\n return await this._dna_request(\"role/soul/task\")\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(\"encourage/signin/signin\", 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(\"user/signIn\", 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>(\"encourage/level/getTaskProcess\", data)\r\n }\r\n\r\n /**\r\n * 获取帖子列表\r\n * @param forumId 论坛ID\r\n * @param pageIndex 页码\r\n * @param pageSize 每页数量\r\n * @param searchType 搜索类型 1:最新 2:热门\r\n * @param timeType 时间类型 0:全部 1:今日 2:本周 3:本月\r\n * @returns 帖子列表\r\n */\r\n async getPostList(forumId: number = 48, pageIndex: number = 1, pageSize: number = 20, searchType: number = 1, timeType: number = 0) {\r\n const data = {\r\n forumId: forumId,\r\n gameId: DNA_GAME_ID,\r\n pageIndex: pageIndex,\r\n pageSize: pageSize,\r\n searchType: searchType, // 1:最新 2:热门\r\n timeType: timeType, // 0:全部 1:今日 2:本周 3:本月\r\n }\r\n return await this._dna_request<DNAPostListRes>(\"forum/list\", data)\r\n }\r\n\r\n /** 管理员锁定帖子 */\r\n async lockPost(post: { postId: number; gameId?: number; gameForumId: number; operateType: number }) {\r\n const data = {\r\n postId: post.postId,\r\n gameId: post.gameId ?? DNA_GAME_ID,\r\n gameForumId: post.gameForumId,\r\n operateType: post.operateType,\r\n }\r\n return await this._dna_request(\"forum/moderator/postLock\", data)\r\n }\r\n\r\n /** 管理员移动帖子 */\r\n async postDownOrUp(post: { postId: number; gameId?: number; gameForumId: number; operateType: number }) {\r\n const data = {\r\n postId: post.postId,\r\n gameId: post.gameId ?? DNA_GAME_ID,\r\n gameForumId: post.gameForumId,\r\n operateType: post.operateType,\r\n }\r\n return await this._dna_request(\"forum/moderator/postDownOrUp\", data)\r\n }\r\n\r\n /** 管理员设精 */\r\n async postElite(post: { postId: number; gameId?: number; gameForumId: number; operateType: number }) {\r\n const data = {\r\n postId: post.postId,\r\n gameId: post.gameId ?? DNA_GAME_ID,\r\n gameForumId: post.gameForumId,\r\n operateType: post.operateType,\r\n }\r\n return await this._dna_request(\"forum/moderator/postElite\", data)\r\n }\r\n\r\n /** 管理员隐藏帖子 */\r\n async postHide(post: { postId: number; gameId?: number; gameForumId: number; operateType: number }) {\r\n const data = {\r\n postId: post.postId,\r\n gameId: post.gameId ?? DNA_GAME_ID,\r\n gameForumId: post.gameForumId,\r\n operateType: post.operateType,\r\n }\r\n return await this._dna_request(\"forum/moderator/postHide\", data)\r\n }\r\n\r\n /** 管理员设置权重 */\r\n async reRank(post: { postId: number; gameId?: number; gameForumId: number }, weight: number) {\r\n const data = {\r\n postId: post.postId,\r\n gameId: post.gameId ?? DNA_GAME_ID,\r\n gameForumId: post.gameForumId,\r\n weight: weight,\r\n }\r\n return await this._dna_request(\"forum/moderator/reRank\", data)\r\n }\r\n\r\n /** 管理员设置强推 */\r\n async strongRecommend(post: { postId: number; gameId?: number; gameForumId: number }, operateType = 1) {\r\n const data = {\r\n postId: post.postId,\r\n gameId: post.gameId ?? DNA_GAME_ID,\r\n gameForumId: post.gameForumId,\r\n operateType: operateType,\r\n }\r\n return await this._dna_request(\"forum/moderator/setForceRecommend\", data)\r\n }\r\n\r\n /** 管理员删帖 */\r\n async adminDelete(post: { postId: number; gameId?: number; gameForumId: number }, content: string, reasonCode: number) {\r\n const data = {\r\n postId: post.postId,\r\n gameId: post.gameId ?? DNA_GAME_ID,\r\n gameForumId: post.gameForumId,\r\n content: content,\r\n reasonCode: reasonCode,\r\n }\r\n return await this._dna_request(\"forum/moderator/postDelete\", data)\r\n }\r\n /** 管理员移动帖子 */\r\n async adminMovePost(\r\n post: { postId: number; gameId?: number; gameForumId: number },\r\n newGameId: number,\r\n newForumId: number,\r\n newTopicIdStr: string,\r\n ) {\r\n const data = {\r\n postId: post.postId,\r\n gameId: post.gameId ?? DNA_GAME_ID,\r\n gameForumId: post.gameForumId,\r\n newGameId: newGameId,\r\n newForumId: newForumId,\r\n newTopicIdStr: newTopicIdStr,\r\n }\r\n return await this._dna_request(\"forum/moderator/postMove\", data)\r\n }\r\n /** ? */\r\n async adminRefreshTime(post: { postId: number; gameId?: number; gameForumId: number }, refresh: number) {\r\n const data = {\r\n postId: post.postId,\r\n gameId: post.gameId ?? DNA_GAME_ID,\r\n gameForumId: post.gameForumId,\r\n refresh: refresh,\r\n }\r\n return await this._dna_request(\"forum/moderator/setRefresh\", data)\r\n }\r\n\r\n /** 黑名单 */\r\n async blockList() {\r\n return await this._dna_request(\"user/block/list\")\r\n }\r\n\r\n /** 拉黑 */\r\n async blockOther(blockPostId: number, blockUserId: string, type: number) {\r\n const data = {\r\n blockPostId: blockPostId,\r\n blockUserId: blockUserId,\r\n type: type,\r\n }\r\n return await this._dna_request(\"user/block/list\", data)\r\n }\r\n\r\n /** ? */\r\n async viewCommunity() {\r\n return await this._dna_request(\"encourage/level/viewCommunity\")\r\n }\r\n\r\n /** ? */\r\n async viewCount() {\r\n return await this._dna_request(\"forum/viewCount\")\r\n }\r\n\r\n /** ? */\r\n async receiveLog(periodId: number, pageIndex: number, pageSize: number) {\r\n const data = {\r\n periodId: periodId,\r\n pageIndex: pageIndex,\r\n pageSize: pageSize,\r\n }\r\n return await this._dna_request(\"encourage/signin/receiveLog\", data)\r\n }\r\n\r\n /** 收藏 */\r\n async collect(postId: number, toUserId: string, operateType = 1) {\r\n const data = {\r\n operateType: operateType,\r\n postId: postId,\r\n toUserId: toUserId,\r\n }\r\n return await this._dna_request(\"forum/collect\", data)\r\n }\r\n\r\n /** 删除评论 */\r\n async commentDelete(\r\n comment: { id: number; gameId: number; gameForumId: number },\r\n entityType: number,\r\n content: string,\r\n reasonCode: number,\r\n ) {\r\n const data = {\r\n id: comment.id,\r\n gameId: comment.gameId,\r\n gameForumId: comment.gameForumId,\r\n entityType: entityType,\r\n content: content,\r\n reasonCode: reasonCode,\r\n }\r\n return await this._dna_request(\"forum/collect\", data)\r\n }\r\n\r\n /** 推荐列表 */\r\n async recommendList(recIndex: number, newIndex: number, size: number, history: number, gameId = DNA_GAME_ID) {\r\n const data = {\r\n gameId: gameId,\r\n recIndex: recIndex,\r\n newIndex: newIndex,\r\n size: size,\r\n history: history,\r\n }\r\n return await this._dna_request(\"forum/recommend/list\", data)\r\n }\r\n\r\n /** 举报 */\r\n async report(\r\n { commentId = 0, postId = 0, replyId = 0 }: { commentId?: number; postId?: number; replyId?: number },\r\n reportReason = 1,\r\n reportType = 1,\r\n ) {\r\n const data = {\r\n commentId: commentId,\r\n postId: postId,\r\n replyId: replyId,\r\n reportReason: reportReason,\r\n reportType: reportType,\r\n }\r\n return await this._dna_request<DNAPostListRes>(\"forum/recommend/list\", data)\r\n }\r\n /** 搜索帖子 */\r\n async searchPost(keyword: number, pageIndex: number, pageSize: number, gameId = DNA_GAME_ID, searchType = 1) {\r\n const data = {\r\n gameId: gameId,\r\n keyword: keyword,\r\n pageIndex: pageIndex,\r\n pageSize: pageSize,\r\n searchType: searchType,\r\n }\r\n return await this._dna_request<DNAPostListRes>(\"forum/searchPost\", data)\r\n }\r\n /** 搜索帖子 */\r\n async searchTopic(keyword: number, pageIndex: number, pageSize = 20, gameId = DNA_GAME_ID) {\r\n const data = {\r\n gameId: gameId,\r\n keyword: keyword,\r\n pageIndex: pageIndex,\r\n pageSize: pageSize,\r\n }\r\n return await this._dna_request<DNAPostListRes>(\"config/searchTopic\", data)\r\n }\r\n\r\n /** 搜索帖子 */\r\n async searchUser(keyword: number, pageIndex: number, pageSize: number) {\r\n const data = {\r\n keyword: keyword,\r\n pageIndex: pageIndex,\r\n pageSize: pageSize,\r\n }\r\n return await this._dna_request<DNAPostListRes>(\"user/searchUser\", data)\r\n }\r\n\r\n /**\r\n * 获取帖子列表\r\n * @param topicId 主题ID\r\n * @param pageIndex 页码\r\n * @param pageSize 每页数量\r\n * @param searchType 搜索类型 1:最新 2:热门\r\n * @param timeType 时间类型 0:全部 1:今日 2:本周 3:本月\r\n * @returns 帖子列表\r\n */\r\n async getPostsByTopic(\r\n topicId: number = 177,\r\n pageIndex: number = 1,\r\n pageSize: number = 20,\r\n searchType: number = 1,\r\n timeType: number = 0,\r\n ) {\r\n const data = {\r\n topicId: topicId,\r\n gameId: DNA_GAME_ID,\r\n pageIndex: pageIndex,\r\n pageSize: pageSize,\r\n searchType: searchType, // 1:最新 2:热门\r\n timeType: timeType, // 0:全部 1:今日 2:本周 3:本月\r\n }\r\n return await this._dna_request<DNAPostListRes>(\"forum/getPostByTopic\", data)\r\n }\r\n\r\n /**\r\n * 获取帖子详情\r\n * @param post_id 帖子ID\r\n * @returns 帖子详情\r\n */\r\n async getPostDetail(post_id: string) {\r\n const data = { postId: post_id }\r\n return await this._dna_request<DNAPostDetailRes>(\"forum/getPostDetail\", data)\r\n }\r\n\r\n /** 关注用户 */\r\n async doFollow(userId: string, unfollow?: boolean) {\r\n const data = {\r\n followUserId: userId,\r\n operateType: unfollow ? 0 : 1,\r\n }\r\n return await this._dna_request(\"user/followUser\", data, { sign: true })\r\n }\r\n\r\n /** 获取关注状态 */\r\n async getFollowState(userId: string) {\r\n const data = {\r\n followUserId: userId,\r\n }\r\n return await this._dna_request(\"user/isFollow\", data)\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 return await this._dna_request(\"forum/like\", data)\r\n }\r\n\r\n /** 分享帖子 */\r\n async doShare() {\r\n const data = { gameId: DNA_GAME_ID }\r\n return await this._dna_request(\"encourage/level/shareTask\", data)\r\n }\r\n\r\n /** 回复帖子 */\r\n async createComment(post: { userId: string; postId: string; gameForumId: number }, 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,\r\n postType: \"1\",\r\n content: content_json,\r\n }\r\n\r\n return await this._dna_request(\"forum/comment/createComment\", data, { sign: true, refer: true, params: { toUserId: post.userId } })\r\n }\r\n\r\n /** 回复评论 */\r\n async createReply(post: { userId: string; postId: string; postCommentId: string; gameForumId: number }, 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 content: content_json,\r\n forumId: post.gameForumId,\r\n postCommentId: post.postCommentId,\r\n postId: post.postId,\r\n postType: \"1\",\r\n toUserId: post.userId,\r\n }\r\n\r\n return await this._dna_request(\"forum/comment/createReply\", data, { sign: true, refer: true, params: { toUserId: post.userId } })\r\n }\r\n\r\n /** 回复评论的评论 */\r\n async createReplyList(\r\n post: { userId: string; postId: string; postCommentId: string; postCommentReplyId: string; gameForumId: number },\r\n content: string,\r\n ) {\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 content: content_json,\r\n forumId: post.gameForumId,\r\n postCommentId: post.postCommentId,\r\n postCommentReplyId: post.postCommentReplyId,\r\n postId: post.postId,\r\n postType: \"1\",\r\n toUserId: post.userId,\r\n }\r\n return await this._dna_request(\"forum/comment/createReply\", data, { sign: true, refer: true, params: { toUserId: post.userId } })\r\n }\r\n\r\n /** 删 */\r\n async deletePost(deleteType: number, id: number) {\r\n return await this._dna_request(\"forum/more/delete\", { deleteType, id }, { sign: true, refer: true })\r\n }\r\n\r\n /**\r\n * 获取用户信息\r\n * @returns 用户信息\r\n */\r\n async getOtherMine(userId = \"709542994134436647\") {\r\n const data = {\r\n otherUserId: userId,\r\n searchType: 1,\r\n type: 2,\r\n }\r\n return await this._dna_request<DNAMineRes>(\"user/mine\", data)\r\n }\r\n\r\n /**\r\n * 获取用户信息\r\n * @returns 用户信息\r\n */\r\n async getMine() {\r\n return await this._dna_request<DNAMineRes>(\"user/mine\")\r\n }\r\n\r\n async getGameConfig() {\r\n const data = { gameId: DNA_GAME_ID }\r\n return await this._dna_request<DNAGameConfigRes[]>(\"config/getGameConfig\", 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 tokenSig?: boolean\r\n }) {\r\n let { payload, exparams, dev_code = this.dev_code, refer, token = this.token, tokenSig } = 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, tokenSig ? token : \"\")\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 tokenSig?: boolean\r\n token?: 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, token, tokenSig } = options || {}\r\n let headers: Record<string, any>\r\n if (sign) {\r\n const { payload: p, headers: h } = await this.getHeaders({\r\n payload: data,\r\n refer,\r\n exparams: params,\r\n token: token ? this.token : undefined,\r\n tokenSig,\r\n })\r\n data = p\r\n headers = h\r\n } else {\r\n const { headers: h } = await this.getHeaders({ token: token ? this.token : undefined })\r\n headers = h\r\n }\r\n\r\n for (let attempt = 0; attempt < max_retries; attempt++) {\r\n try {\r\n let body: string = data\r\n if (data && typeof data === \"object\") {\r\n const p = new URLSearchParams()\r\n Object.entries(data).forEach(([key, value]) => {\r\n if (value !== undefined) p.append(key, String(value))\r\n })\r\n body = p.toString()\r\n }\r\n const fetchOptions: RequestInit = {\r\n method,\r\n headers,\r\n body,\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 initOptions = {\r\n ...fetchOptions,\r\n signal: controller.signal,\r\n }\r\n const response = this.fetchFn\r\n ? await this.fetchFn(`${this.BASE_URL}${url}`, initOptions)\r\n : await fetch(`${this.BASE_URL}${url}`, initOptions)\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 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\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\n//#region 接口定义\r\n\r\nexport interface DNAMineRes {\r\n mine: DNAMine\r\n postList: DNAPost[]\r\n hasNext: number\r\n}\r\n\r\nexport interface DNAMine {\r\n /** 文章数量 */\r\n articleCount: number\r\n /** 收藏数量 */\r\n collectCount: number\r\n /** 评论数量 */\r\n commentCount: number\r\n /** 粉丝数量 */\r\n fansCount: number\r\n /** 新粉丝数量 */\r\n fansNewCount: number\r\n /** 关注数量 */\r\n followCount: number\r\n /** 性别 */\r\n gender: number\r\n /** 精华数量 */\r\n goldNum: number\r\n /** 头像 */\r\n headUrl: string\r\n /** 是否关注 */\r\n isFollow: number\r\n /** 是否登录用户 */\r\n isLoginUser: number\r\n /** 是否被禁言 */\r\n isMute: number\r\n /** 等级 */\r\n levelTotal: number\r\n /** 点赞数量 */\r\n likeCount: number\r\n /** 手机号 */\r\n mobile: string\r\n /** 管理员列表 */\r\n moderatorVos: any[]\r\n /** 帖子数量 */\r\n postCount: number\r\n /** 注册时间 */\r\n registerTime: string\r\n /** 状态 */\r\n status: number\r\n /** 趋势数量 */\r\n trendCount: number\r\n /** 用户ID */\r\n userId: string\r\n /** 用户名 */\r\n userName: string\r\n}\r\n\r\nexport interface DNAGameConfigRes {\r\n /** 游戏所有板块列表 */\r\n gameAllForumList: GameForum[]\r\n /** 游戏ID */\r\n gameId: number\r\n /** 游戏板块图片列表 */\r\n gameForumPictureList: any[]\r\n /** 游戏板块列表 */\r\n gameForumList: GameForum[]\r\n /** 签到按钮图片 */\r\n signBtn: string\r\n sort: number\r\n /** 话题列表 */\r\n topicList: GameTopic[]\r\n /** 背景图片 */\r\n drawBackgroundUrl: string\r\n /** 是否默认游戏 */\r\n gameDefault: number\r\n /** 签到颜色 */\r\n signColor: string\r\n /** 游戏名称 */\r\n gameName: string\r\n /** CM图片2 意味不明 */\r\n drawListUrl: string\r\n /** 英文站点 */\r\n configTab: ConfigTab[]\r\n}\r\n\r\nexport interface ConfigTab {\r\n name: string\r\n url: string\r\n}\r\n\r\nexport interface GameTopic {\r\n /** 话题背景图片 */\r\n backgroundUrl: string\r\n gameId: number\r\n /** 话题图标 */\r\n topicIconUrl: string\r\n topicId: number\r\n /** 话题名称 */\r\n topicName: string\r\n sort: number\r\n /** 话题描述 */\r\n topicDesc: string\r\n}\r\n\r\nexport interface GameForum {\r\n /** 全部=1 普通=3 */\r\n forumDataType: number\r\n /** 固定1 */\r\n forumUiType: number\r\n /** 小红点 */\r\n isTrend: number\r\n /** 夜间模式图标 */\r\n iconWhiteUrl: string\r\n /** 固定1 */\r\n forumType: number\r\n /** 板块名称 */\r\n name: string\r\n forumListShowType: number\r\n /** 图标 */\r\n iconUrl: string\r\n id: number\r\n sort: number\r\n /** 官方 */\r\n isOfficial: number\r\n}\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\r\n /** 中文 */\r\n name: string\r\n /** 密函编码 */\r\n code: string\r\n /** 固定0 */\r\n on: number\r\n}\r\n\r\nexport interface DNARoleForToolInstanceInfo {\r\n /** 密函列表 */\r\n instances: DNARoleForToolInstance[] // instances\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 DNARoleWeapon {\r\n weaponId: number\r\n weaponEid: string\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 skillLevel: number\r\n /** 是否解锁 */\r\n unLocked: boolean\r\n}\r\n\r\nexport interface DNARoleChar {\r\n charId: number\r\n charEid: string\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 DNARoleForToolRes {\r\n /** 角色信息 */\r\n roleInfo: DNARoleInfo\r\n /** 密函 */\r\n instanceInfo: DNARoleForToolInstanceInfo[]\r\n}\r\n\r\nexport interface DNARoleShow {\r\n /** 角色列表 */\r\n roleChars: DNARoleChar[]\r\n /** 武器列表 */\r\n langRangeWeapons: DNARoleWeapon[]\r\n /** 武器列表 */\r\n closeWeapons: DNARoleWeapon[]\r\n /** 角色头像 */\r\n headUrl: string\r\n /** 等级 */\r\n level: number\r\n /** 成就列表 */\r\n params: DNARoleAchievement[]\r\n /** 角色id */\r\n roleId: string\r\n /** 角色名称 */\r\n roleName: string\r\n /** 迷津 */\r\n rougeLikeInfo: DNARougeLikeInfo\r\n}\r\n\r\nexport interface DNARoleAchievement {\r\n paramKey: string // paramKey\r\n paramValue: string // paramValue\r\n}\r\n\r\nexport interface DNARoleInfo {\r\n /** 深渊信息 */\r\n abyssInfo: DNAAbyssInfo\r\n /** 角色信息 */\r\n roleShow: DNARoleShow\r\n}\r\n\r\nexport interface DNARougeLikeInfo {\r\n /** 最大通过等级 */\r\n maxPassed: number\r\n /** 最大通过等级名称 */\r\n maxPassedName: string\r\n /** 重置时间 */\r\n resetTime: string\r\n /** 奖励数量 */\r\n rewardCount: number\r\n /** 奖励总数 */\r\n rewardTotal: number\r\n /** 天赋信息 */\r\n talentInfo: DNARougeLikeTalentInfo[]\r\n}\r\n\r\nexport interface DNARougeLikeTalentInfo {\r\n cur: string\r\n max: string\r\n}\r\n\r\nexport interface DNAAbyssInfo {\r\n /** 阵容 */\r\n bestTimeVo1: DNABestTimeVo1\r\n /** 结束时间 */\r\n endTime: string\r\n /** 操作名称 */\r\n operaName: string\r\n /** 进度名称 */\r\n progressName: string\r\n /** 星级 */\r\n stars: string\r\n /** 开始时间 */\r\n startTime: string\r\n}\r\n\r\n/** 深渊阵容 */\r\nexport interface DNABestTimeVo1 {\r\n /** 角色图标 */\r\n charIcon: string\r\n /** 近战武器图标 */\r\n closeWeaponIcon: string\r\n /** 远程武器图标 */\r\n langRangeWeaponIcon: string\r\n /** 魔灵图标 */\r\n petIcon: string\r\n /** 协战角色图标1 */\r\n phantomCharIcon1: string\r\n /** 协战武器图标1 */\r\n phantomWeaponIcon1: string\r\n /** 协战角色图标2 */\r\n phantomCharIcon2: string\r\n /** 协战武器图标2 */\r\n phantomWeaponIcon2: string\r\n}\r\n\r\n/** 角色属性 */\r\nexport interface DNACharAttribute {\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 def: 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\n/** 角色技能 */\r\nexport interface DNARoleSkill {\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\n/** 溯源 */\r\nexport interface DNARoleTrace {\r\n /** 溯源图标 */\r\n icon: string\r\n /** 溯源描述 */\r\n description: string\r\n}\r\n\r\n/** 魔之楔 */\r\nexport interface DNARoleMod {\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 DNACharDetail {\r\n charId: number\r\n /** 角色属性 */\r\n attribute: DNACharAttribute\r\n /** 角色技能 */\r\n skills: DNARoleSkill[]\r\n /** 立绘 */\r\n paint: string\r\n /** 角色名称 */\r\n charName: string\r\n /** 元素图标 */\r\n elementIcon: string\r\n /** 溯源 */\r\n traces: DNARoleTrace[]\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 /** 魔之楔列表 */\r\n modes: DNARoleMod[]\r\n}\r\n\r\nexport interface DNACharDetailRes {\r\n /** 角色详情 */\r\n charDetail: DNACharDetail\r\n}\r\n\r\nexport interface DNAWeaponDetailRes {\r\n /** 武器详情 */\r\n weaponDetail: DNAWeaponDetail\r\n}\r\n\r\nexport interface DNAWeaponDetail {\r\n attribute: DNAWeaponAttribute\r\n currentVolume: number\r\n description: string\r\n elementIcon: string\r\n elementName: string\r\n icon: string\r\n id: number\r\n level: number\r\n modes: DNARoleMod[]\r\n name: string\r\n skillLevel: number\r\n sumVolume: number\r\n}\r\n\r\nexport interface DNAWeaponAttribute {\r\n atk: number\r\n crd: number\r\n cri: number\r\n speed: number\r\n trigger: number\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 DNATopicPostListRes {\r\n postList: DNAPost[]\r\n topic: DNATopicDetail\r\n hasNext: number\r\n}\r\n\r\nexport interface DNATopicDetail {\r\n backgroundUrl: string\r\n gameId: number\r\n sort: number\r\n topicDesc: string\r\n topicIconUrl: string\r\n topicId: number\r\n topicName: string\r\n}\r\n\r\nexport interface DNAPost {\r\n browseCount: string\r\n collectionCount: number\r\n commentCount: number\r\n gameForumId: number\r\n gameId: number\r\n gameName: string\r\n imgContent: DNAPostImgContent[]\r\n imgCount: number\r\n isCollect: number\r\n isCreator: number\r\n isElite: number\r\n isFollow: number\r\n isLike: number\r\n isLock: number\r\n isOfficial: number\r\n isPublisher: number\r\n likeCount: number\r\n postContent: string\r\n postCover: string\r\n postCoverVo: DNAPostCoverVo\r\n postId: string\r\n postStatus: number\r\n postTitle: string\r\n postType: number\r\n showTime: string\r\n topics: DNATopicShort[]\r\n userHeadUrl: string\r\n userId: string\r\n userLevel: number\r\n userModeratorIdentity: number\r\n userName: string\r\n}\r\n\r\nexport interface DNATopicShort {\r\n topicId: number\r\n topicName: string\r\n}\r\n\r\nexport interface DNAPostCoverVo {\r\n imgHeight: number\r\n imgWidth: number\r\n}\r\n\r\nexport interface DNAPostImgContent {\r\n imgHeight: number\r\n imgWidth: number\r\n url: string\r\n isAbnormal?: boolean\r\n}\r\n\r\nexport interface DNAPostListRes {\r\n postList: DNAPost[] // posts\r\n topList: any[]\r\n hasNext: number\r\n}\r\n\r\nexport interface DNAPostDetailRes {\r\n isHotCount: boolean\r\n gameId: number\r\n isFollow: number\r\n isLike: number\r\n postDetail: DNAPostDetail\r\n isCollect: number\r\n hasNext: number\r\n comment: DNAComment[]\r\n}\r\n\r\nexport interface DNAPostDetail {\r\n auditStatus: number\r\n browseCount: string\r\n checkStatus: number\r\n collectionCount: number\r\n commentCount: number\r\n gameForumId: number\r\n gameForumVo: DNAGameForumVo\r\n gameId: number\r\n gameName: string\r\n headCodeUrl: string\r\n id: string\r\n isCreator: number\r\n isElite: number\r\n isForceRecommend: number\r\n isHide: number\r\n isLock: number\r\n isMine: number\r\n isOfficial: number\r\n isRecommend: number\r\n isTop: number\r\n lastEditorTime?: string\r\n likeCount: number\r\n postContent: DNAPostContent[]\r\n postH5Content: string\r\n postTime: string\r\n postTitle: string\r\n postType: number\r\n postUserId: string\r\n refreshHour: number\r\n score: number\r\n topics: DNATopicShort[]\r\n userHeadCode: string\r\n userLevel: number\r\n userModeratorIdentity: number\r\n userName: string\r\n whiteUrl: any[]\r\n}\r\n\r\nexport interface DNAPostContent {\r\n contentType: PostContentType\r\n imgHeight: number\r\n imgWidth: number\r\n url?: string\r\n content?: string\r\n contentVideo?: DNAPostContentVideo\r\n}\r\n\r\nexport interface DNAComment {\r\n checkStatus: number\r\n commentContent: DNAPostContent[]\r\n commentId: string\r\n commentTime: string\r\n contentTextStatus: number\r\n floor: number\r\n isCreator: number\r\n isLike: number\r\n isMine: number\r\n isOfficial: number\r\n isPublisher: number\r\n likeCount: number\r\n replyCount: number\r\n replyVos: DNAReplyVos[]\r\n userHeadCode?: string\r\n userHeadUrl: string\r\n userId: string\r\n userLevel: number\r\n userModeratorIdentity: number\r\n userName: string\r\n}\r\n\r\nexport interface DNAReplyVos {\r\n checkStatus: number\r\n contentTextStatus: number\r\n createTime: number\r\n isCreator: number\r\n isLike: number\r\n isMine: number\r\n isOfficial: number\r\n isPublisher: number\r\n likeCount: number\r\n postCommentId: string\r\n postCommentReplayId: string\r\n replyContent: DNAPostContent[]\r\n replyContentStr: string\r\n replyId: string\r\n replyTime: string\r\n toUserIsCreator: number\r\n toUserModeratorIdentity: number\r\n toUserName: string\r\n userHeadCode?: string\r\n userHeadUrl: string\r\n userId: string\r\n userLevel: number\r\n userModeratorIdentity: number\r\n userName: string\r\n}\r\n\r\nexport interface DNAGameForumVo {\r\n forumDataType: number\r\n forumListShowType: number\r\n forumType: number\r\n forumUiType: number\r\n iconUrl: string\r\n iconWhiteUrl: string\r\n id: number\r\n isOfficial: number\r\n isTrend: number\r\n name: string\r\n sort: number\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 DNAPostContentVideo {\r\n videoUrl: string // videoUrl\r\n coverUrl?: string // coverUrl\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 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//#endregion\r\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "B51DD8AA6D0912A964756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "5B73BAA9D9E7DDB064756E2164756E21",
9
9
  "names": []
10
10
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dna-api",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "description": "dna bbs api",
5
5
  "author": {
6
6
  "name": "pa001024",
package/src/index.ts CHANGED
@@ -1,28 +1,5 @@
1
1
  import * as forge from "node-forge"
2
2
  //#region const
3
- const MAIN_URL = "https://dnabbs-api.yingxiong.com"
4
- const LOGIN_URL = `${MAIN_URL}/user/sdkLogin`
5
- const GET_RSA_PUBLIC_KEY_URL = `${MAIN_URL}/config/getRsaPublicKey`
6
- const LOGIN_LOG_URL = `${MAIN_URL}/user/login/log`
7
- const ROLE_LIST_URL = `${MAIN_URL}/role/list`
8
- const ROLE_FOR_TOOL_URL = `${MAIN_URL}/role/defaultRoleForTool`
9
- const ROLE_DETAIL_URL = `${MAIN_URL}/role/getCharDetail`
10
- const WEAPON_DETAIL_URL = `${MAIN_URL}/role/getWeaponDetail`
11
- const SHORT_NOTE_URL = `${MAIN_URL}/role/getShortNoteInfo`
12
- const SIGN_CALENDAR_URL = `${MAIN_URL}/encourage/signin/show`
13
- const GAME_SIGN_URL = `${MAIN_URL}/encourage/signin/signin`
14
- const BBS_SIGN_URL = `${MAIN_URL}/user/signIn`
15
- const HAVE_SIGN_IN_URL = `${MAIN_URL}/user/haveSignInNew`
16
- const GET_TASK_PROCESS_URL = `${MAIN_URL}/encourage/level/getTaskProcess`
17
- const GET_POST_LIST_URL = `${MAIN_URL}/forum/list`
18
- const GET_POST_BY_TOPIC_URL = `${MAIN_URL}/forum/getPostByTopic`
19
- const GET_POST_DETAIL_URL = `${MAIN_URL}/forum/getPostDetail`
20
- const LIKE_POST_URL = `${MAIN_URL}/forum/like`
21
- const SHARE_POST_URL = `${MAIN_URL}/encourage/level/shareTask`
22
- const REPLY_POST_URL = `${MAIN_URL}/forum/comment/createComment`
23
- const GET_GAME_CONFIG_URL = `${MAIN_URL}/config/getGameConfig`
24
- const GET_MINE_URL = `${MAIN_URL}/user/mine`
25
-
26
3
  enum RespCode {
27
4
  ERROR = -999,
28
5
  OK_ZERO = 0,
@@ -38,10 +15,11 @@ const DNA_GAME_ID = 268
38
15
  * DNA API类,用于与DNA游戏服务器交互
39
16
  */
40
17
  export class DNAAPI {
41
- public fetchFn: typeof fetch
18
+ public fetchFn?: typeof fetch
42
19
  public is_h5 = false
43
- public rsa_public_key =
20
+ public RSA_PUBLIC_KEY =
44
21
  "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGpdbezK+eknQZQzPOjp8mr/dP+QHwk8CRkQh6C6qFnfLH3tiyl0pnt3dePuFDnM1PUXGhCkQ157ePJCQgkDU2+mimDmXh0oLFn9zuWSp+U8uLSLX3t3PpJ8TmNCROfUDWvzdbnShqg7JfDmnrOJz49qd234W84nrfTHbzdqeigQIDAQAB"
22
+ public BASE_URL = "https://dnabbs-api.yingxiong.com/"
45
23
 
46
24
  /**
47
25
  * 构造函数
@@ -58,9 +36,9 @@ export class DNAAPI {
58
36
  public token = "",
59
37
  options: { fetchFn?: typeof fetch; is_h5?: boolean; rsa_public_key?: string } = {},
60
38
  ) {
61
- this.fetchFn = options.fetchFn || fetch.bind(window)
39
+ this.fetchFn = options.fetchFn
62
40
  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
41
+ if (options.rsa_public_key !== undefined) this.RSA_PUBLIC_KEY = options.rsa_public_key
64
42
  }
65
43
 
66
44
  /**
@@ -68,18 +46,18 @@ export class DNAAPI {
68
46
  * @returns RSA公钥(base64)
69
47
  */
70
48
  async getRsaPublicKey() {
71
- if (this.rsa_public_key) {
72
- return this.rsa_public_key
49
+ if (this.RSA_PUBLIC_KEY) {
50
+ return this.RSA_PUBLIC_KEY
73
51
  }
74
- const res = await this._dna_request<{ key: string }>(GET_RSA_PUBLIC_KEY_URL)
52
+ const res = await this._dna_request<{ key: string }>("config/getRsaPublicKey")
75
53
 
76
54
  if (res.is_success && res.data) {
77
55
  const key = res.data.key
78
56
  if (typeof key === "string") {
79
- this.rsa_public_key = key
57
+ this.RSA_PUBLIC_KEY = key
80
58
  }
81
59
  }
82
- return this.rsa_public_key
60
+ return this.RSA_PUBLIC_KEY
83
61
  }
84
62
 
85
63
  /**
@@ -87,7 +65,7 @@ export class DNAAPI {
87
65
  */
88
66
  async login(mobile: string, code: string) {
89
67
  const data = { mobile, code, gameList: DNA_GAME_ID }
90
- const res = await this._dna_request<DNALoginRes>(LOGIN_URL, data, { sign: true, refer: true })
68
+ const res = await this._dna_request<DNALoginRes>("user/sdkLogin", data, { sign: true, refer: true })
91
69
  if (res.is_success && res.data) {
92
70
  const data = res.data
93
71
  if (typeof data.token === "string") {
@@ -101,14 +79,14 @@ export class DNAAPI {
101
79
  * 获取登录日志
102
80
  */
103
81
  async loginLog() {
104
- return await this._dna_request<DNALoginRes>(LOGIN_LOG_URL)
82
+ return await this._dna_request<DNALoginRes>("user/login/log")
105
83
  }
106
84
 
107
85
  /**
108
86
  * 获取角色列表
109
87
  */
110
88
  async getRoleList() {
111
- return await this._dna_request<DNARoleListRes>(ROLE_LIST_URL)
89
+ return await this._dna_request<DNARoleListRes>("role/list")
112
90
  }
113
91
 
114
92
  /**
@@ -116,7 +94,7 @@ export class DNAAPI {
116
94
  */
117
95
  async getDefaultRoleForTool() {
118
96
  const data = { type: 1 }
119
- return await this._dna_request<DNARoleForToolRes>(ROLE_FOR_TOOL_URL, data, { sign: true, token: true, tokenSig: true })
97
+ return await this._dna_request<DNARoleForToolRes>("role/defaultRoleForTool", data, { sign: true, token: true, tokenSig: true })
120
98
  }
121
99
 
122
100
  /**
@@ -124,7 +102,7 @@ export class DNAAPI {
124
102
  */
125
103
  async getCharDetail(char_id: string, char_eid: string, otherUserId?: string) {
126
104
  const data = { charId: char_id, charEid: char_eid, type: 1, otherUserId } as any
127
- return await this._dna_request<DNACharDetailRes>(ROLE_DETAIL_URL, data)
105
+ return await this._dna_request<DNACharDetailRes>("role/getCharDetail", data)
128
106
  }
129
107
 
130
108
  /**
@@ -132,14 +110,14 @@ export class DNAAPI {
132
110
  */
133
111
  async getWeaponDetail(weapon_id: string, weapon_eid: string, otherUserId?: string) {
134
112
  const data = { weaponId: weapon_id, weaponEid: weapon_eid, type: 1, otherUserId }
135
- return await this._dna_request<DNAWeaponDetailRes>(WEAPON_DETAIL_URL, data)
113
+ return await this._dna_request<DNAWeaponDetailRes>("role/getWeaponDetail", data)
136
114
  }
137
115
 
138
116
  /**
139
117
  * 获取角色简讯
140
118
  */
141
119
  async getShortNoteInfo() {
142
- return await this._dna_request<DNARoleShortNoteRes>(SHORT_NOTE_URL)
120
+ return await this._dna_request<DNARoleShortNoteRes>("role/getShortNoteInfo")
143
121
  }
144
122
 
145
123
  /**
@@ -147,7 +125,7 @@ export class DNAAPI {
147
125
  */
148
126
  async haveSignIn() {
149
127
  const data = { gameId: DNA_GAME_ID }
150
- return await this._dna_request<DNAHaveSignInRes>(HAVE_SIGN_IN_URL, data)
128
+ return await this._dna_request<DNAHaveSignInRes>("user/haveSignInNew", data)
151
129
  }
152
130
 
153
131
  /**
@@ -155,7 +133,12 @@ export class DNAAPI {
155
133
  */
156
134
  async signCalendar() {
157
135
  const data = { gameId: DNA_GAME_ID }
158
- return await this._dna_request<DNACalendarSignRes>(SIGN_CALENDAR_URL, data)
136
+ return await this._dna_request<DNACalendarSignRes>("encourage/signin/show", data)
137
+ }
138
+
139
+ /** ? */
140
+ async soulTask() {
141
+ return await this._dna_request("role/soul/task")
159
142
  }
160
143
 
161
144
  /**
@@ -167,7 +150,7 @@ export class DNAAPI {
167
150
  periodId: period,
168
151
  signinType: 1,
169
152
  }
170
- return await this._dna_request(GAME_SIGN_URL, data)
153
+ return await this._dna_request("encourage/signin/signin", data)
171
154
  }
172
155
 
173
156
  /**
@@ -175,7 +158,7 @@ export class DNAAPI {
175
158
  */
176
159
  async bbsSign() {
177
160
  const data = { gameId: DNA_GAME_ID }
178
- return await this._dna_request(BBS_SIGN_URL, data)
161
+ return await this._dna_request("user/signIn", data)
179
162
  }
180
163
 
181
164
  /**
@@ -183,7 +166,7 @@ export class DNAAPI {
183
166
  */
184
167
  async getTaskProcess() {
185
168
  const data = { gameId: DNA_GAME_ID }
186
- return await this._dna_request<DNATaskProcessRes>(GET_TASK_PROCESS_URL, data)
169
+ return await this._dna_request<DNATaskProcessRes>("encourage/level/getTaskProcess", data)
187
170
  }
188
171
 
189
172
  /**
@@ -204,12 +187,239 @@ export class DNAAPI {
204
187
  searchType: searchType, // 1:最新 2:热门
205
188
  timeType: timeType, // 0:全部 1:今日 2:本周 3:本月
206
189
  }
207
- return await this._dna_request<DNAPostListRes>(GET_POST_LIST_URL, data)
190
+ return await this._dna_request<DNAPostListRes>("forum/list", data)
191
+ }
192
+
193
+ /** 管理员锁定帖子 */
194
+ async lockPost(post: { postId: number; gameId?: number; gameForumId: number; operateType: number }) {
195
+ const data = {
196
+ postId: post.postId,
197
+ gameId: post.gameId ?? DNA_GAME_ID,
198
+ gameForumId: post.gameForumId,
199
+ operateType: post.operateType,
200
+ }
201
+ return await this._dna_request("forum/moderator/postLock", data)
202
+ }
203
+
204
+ /** 管理员移动帖子 */
205
+ async postDownOrUp(post: { postId: number; gameId?: number; gameForumId: number; operateType: number }) {
206
+ const data = {
207
+ postId: post.postId,
208
+ gameId: post.gameId ?? DNA_GAME_ID,
209
+ gameForumId: post.gameForumId,
210
+ operateType: post.operateType,
211
+ }
212
+ return await this._dna_request("forum/moderator/postDownOrUp", data)
213
+ }
214
+
215
+ /** 管理员设精 */
216
+ async postElite(post: { postId: number; gameId?: number; gameForumId: number; operateType: number }) {
217
+ const data = {
218
+ postId: post.postId,
219
+ gameId: post.gameId ?? DNA_GAME_ID,
220
+ gameForumId: post.gameForumId,
221
+ operateType: post.operateType,
222
+ }
223
+ return await this._dna_request("forum/moderator/postElite", data)
224
+ }
225
+
226
+ /** 管理员隐藏帖子 */
227
+ async postHide(post: { postId: number; gameId?: number; gameForumId: number; operateType: number }) {
228
+ const data = {
229
+ postId: post.postId,
230
+ gameId: post.gameId ?? DNA_GAME_ID,
231
+ gameForumId: post.gameForumId,
232
+ operateType: post.operateType,
233
+ }
234
+ return await this._dna_request("forum/moderator/postHide", data)
235
+ }
236
+
237
+ /** 管理员设置权重 */
238
+ async reRank(post: { postId: number; gameId?: number; gameForumId: number }, weight: number) {
239
+ const data = {
240
+ postId: post.postId,
241
+ gameId: post.gameId ?? DNA_GAME_ID,
242
+ gameForumId: post.gameForumId,
243
+ weight: weight,
244
+ }
245
+ return await this._dna_request("forum/moderator/reRank", data)
246
+ }
247
+
248
+ /** 管理员设置强推 */
249
+ async strongRecommend(post: { postId: number; gameId?: number; gameForumId: number }, operateType = 1) {
250
+ const data = {
251
+ postId: post.postId,
252
+ gameId: post.gameId ?? DNA_GAME_ID,
253
+ gameForumId: post.gameForumId,
254
+ operateType: operateType,
255
+ }
256
+ return await this._dna_request("forum/moderator/setForceRecommend", data)
257
+ }
258
+
259
+ /** 管理员删帖 */
260
+ async adminDelete(post: { postId: number; gameId?: number; gameForumId: number }, content: string, reasonCode: number) {
261
+ const data = {
262
+ postId: post.postId,
263
+ gameId: post.gameId ?? DNA_GAME_ID,
264
+ gameForumId: post.gameForumId,
265
+ content: content,
266
+ reasonCode: reasonCode,
267
+ }
268
+ return await this._dna_request("forum/moderator/postDelete", data)
269
+ }
270
+ /** 管理员移动帖子 */
271
+ async adminMovePost(
272
+ post: { postId: number; gameId?: number; gameForumId: number },
273
+ newGameId: number,
274
+ newForumId: number,
275
+ newTopicIdStr: string,
276
+ ) {
277
+ const data = {
278
+ postId: post.postId,
279
+ gameId: post.gameId ?? DNA_GAME_ID,
280
+ gameForumId: post.gameForumId,
281
+ newGameId: newGameId,
282
+ newForumId: newForumId,
283
+ newTopicIdStr: newTopicIdStr,
284
+ }
285
+ return await this._dna_request("forum/moderator/postMove", data)
286
+ }
287
+ /** ? */
288
+ async adminRefreshTime(post: { postId: number; gameId?: number; gameForumId: number }, refresh: number) {
289
+ const data = {
290
+ postId: post.postId,
291
+ gameId: post.gameId ?? DNA_GAME_ID,
292
+ gameForumId: post.gameForumId,
293
+ refresh: refresh,
294
+ }
295
+ return await this._dna_request("forum/moderator/setRefresh", data)
296
+ }
297
+
298
+ /** 黑名单 */
299
+ async blockList() {
300
+ return await this._dna_request("user/block/list")
301
+ }
302
+
303
+ /** 拉黑 */
304
+ async blockOther(blockPostId: number, blockUserId: string, type: number) {
305
+ const data = {
306
+ blockPostId: blockPostId,
307
+ blockUserId: blockUserId,
308
+ type: type,
309
+ }
310
+ return await this._dna_request("user/block/list", data)
311
+ }
312
+
313
+ /** ? */
314
+ async viewCommunity() {
315
+ return await this._dna_request("encourage/level/viewCommunity")
316
+ }
317
+
318
+ /** ? */
319
+ async viewCount() {
320
+ return await this._dna_request("forum/viewCount")
321
+ }
322
+
323
+ /** ? */
324
+ async receiveLog(periodId: number, pageIndex: number, pageSize: number) {
325
+ const data = {
326
+ periodId: periodId,
327
+ pageIndex: pageIndex,
328
+ pageSize: pageSize,
329
+ }
330
+ return await this._dna_request("encourage/signin/receiveLog", data)
331
+ }
332
+
333
+ /** 收藏 */
334
+ async collect(postId: number, toUserId: string, operateType = 1) {
335
+ const data = {
336
+ operateType: operateType,
337
+ postId: postId,
338
+ toUserId: toUserId,
339
+ }
340
+ return await this._dna_request("forum/collect", data)
341
+ }
342
+
343
+ /** 删除评论 */
344
+ async commentDelete(
345
+ comment: { id: number; gameId: number; gameForumId: number },
346
+ entityType: number,
347
+ content: string,
348
+ reasonCode: number,
349
+ ) {
350
+ const data = {
351
+ id: comment.id,
352
+ gameId: comment.gameId,
353
+ gameForumId: comment.gameForumId,
354
+ entityType: entityType,
355
+ content: content,
356
+ reasonCode: reasonCode,
357
+ }
358
+ return await this._dna_request("forum/collect", data)
359
+ }
360
+
361
+ /** 推荐列表 */
362
+ async recommendList(recIndex: number, newIndex: number, size: number, history: number, gameId = DNA_GAME_ID) {
363
+ const data = {
364
+ gameId: gameId,
365
+ recIndex: recIndex,
366
+ newIndex: newIndex,
367
+ size: size,
368
+ history: history,
369
+ }
370
+ return await this._dna_request("forum/recommend/list", data)
371
+ }
372
+
373
+ /** 举报 */
374
+ async report(
375
+ { commentId = 0, postId = 0, replyId = 0 }: { commentId?: number; postId?: number; replyId?: number },
376
+ reportReason = 1,
377
+ reportType = 1,
378
+ ) {
379
+ const data = {
380
+ commentId: commentId,
381
+ postId: postId,
382
+ replyId: replyId,
383
+ reportReason: reportReason,
384
+ reportType: reportType,
385
+ }
386
+ return await this._dna_request<DNAPostListRes>("forum/recommend/list", data)
387
+ }
388
+ /** 搜索帖子 */
389
+ async searchPost(keyword: number, pageIndex: number, pageSize: number, gameId = DNA_GAME_ID, searchType = 1) {
390
+ const data = {
391
+ gameId: gameId,
392
+ keyword: keyword,
393
+ pageIndex: pageIndex,
394
+ pageSize: pageSize,
395
+ searchType: searchType,
396
+ }
397
+ return await this._dna_request<DNAPostListRes>("forum/searchPost", data)
398
+ }
399
+ /** 搜索帖子 */
400
+ async searchTopic(keyword: number, pageIndex: number, pageSize = 20, gameId = DNA_GAME_ID) {
401
+ const data = {
402
+ gameId: gameId,
403
+ keyword: keyword,
404
+ pageIndex: pageIndex,
405
+ pageSize: pageSize,
406
+ }
407
+ return await this._dna_request<DNAPostListRes>("config/searchTopic", data)
408
+ }
409
+
410
+ /** 搜索帖子 */
411
+ async searchUser(keyword: number, pageIndex: number, pageSize: number) {
412
+ const data = {
413
+ keyword: keyword,
414
+ pageIndex: pageIndex,
415
+ pageSize: pageSize,
416
+ }
417
+ return await this._dna_request<DNAPostListRes>("user/searchUser", data)
208
418
  }
209
419
 
210
420
  /**
211
421
  * 获取帖子列表
212
- * @param forumId 论坛ID
422
+ * @param topicId 主题ID
213
423
  * @param pageIndex 页码
214
424
  * @param pageSize 每页数量
215
425
  * @param searchType 搜索类型 1:最新 2:热门
@@ -231,8 +441,9 @@ export class DNAAPI {
231
441
  searchType: searchType, // 1:最新 2:热门
232
442
  timeType: timeType, // 0:全部 1:今日 2:本周 3:本月
233
443
  }
234
- return await this._dna_request<DNAPostListRes>(GET_POST_BY_TOPIC_URL, data)
444
+ return await this._dna_request<DNAPostListRes>("forum/getPostByTopic", data)
235
445
  }
446
+
236
447
  /**
237
448
  * 获取帖子详情
238
449
  * @param post_id 帖子ID
@@ -240,7 +451,24 @@ export class DNAAPI {
240
451
  */
241
452
  async getPostDetail(post_id: string) {
242
453
  const data = { postId: post_id }
243
- return await this._dna_request<DNAPostDetailRes>(GET_POST_DETAIL_URL, data)
454
+ return await this._dna_request<DNAPostDetailRes>("forum/getPostDetail", data)
455
+ }
456
+
457
+ /** 关注用户 */
458
+ async doFollow(userId: string, unfollow?: boolean) {
459
+ const data = {
460
+ followUserId: userId,
461
+ operateType: unfollow ? 0 : 1,
462
+ }
463
+ return await this._dna_request("user/followUser", data, { sign: true })
464
+ }
465
+
466
+ /** 获取关注状态 */
467
+ async getFollowState(userId: string) {
468
+ const data = {
469
+ followUserId: userId,
470
+ }
471
+ return await this._dna_request("user/isFollow", data)
244
472
  }
245
473
 
246
474
  /**
@@ -258,17 +486,17 @@ export class DNAAPI {
258
486
  postType: post.postType,
259
487
  toUserId: post.userId,
260
488
  }
261
- return await this._dna_request(LIKE_POST_URL, data)
489
+ return await this._dna_request("forum/like", data)
262
490
  }
263
491
 
264
- // 分享帖子
492
+ /** 分享帖子 */
265
493
  async doShare() {
266
494
  const data = { gameId: DNA_GAME_ID }
267
- return await this._dna_request(SHARE_POST_URL, data)
495
+ return await this._dna_request("encourage/level/shareTask", data)
268
496
  }
269
497
 
270
- // 回复帖子
271
- async doReply(post: Record<string, any>, content: string) {
498
+ /** 回复帖子 */
499
+ async createComment(post: { userId: string; postId: string; gameForumId: number }, content: string) {
272
500
  const content_json = JSON.stringify([
273
501
  {
274
502
  content,
@@ -280,12 +508,66 @@ export class DNAAPI {
280
508
  ])
281
509
  const data = {
282
510
  postId: post.postId,
283
- forumId: post.gameForumId || 47,
511
+ forumId: post.gameForumId,
284
512
  postType: "1",
285
513
  content: content_json,
286
514
  }
287
515
 
288
- return await this._dna_request(REPLY_POST_URL, data, { sign: true, refer: true, params: { toUserId: post.userId } })
516
+ return await this._dna_request("forum/comment/createComment", data, { sign: true, refer: true, params: { toUserId: post.userId } })
517
+ }
518
+
519
+ /** 回复评论 */
520
+ async createReply(post: { userId: string; postId: string; postCommentId: string; gameForumId: number }, content: string) {
521
+ const content_json = JSON.stringify([
522
+ {
523
+ content,
524
+ contentType: "1",
525
+ imgHeight: 0,
526
+ imgWidth: 0,
527
+ url: "",
528
+ },
529
+ ])
530
+ const data = {
531
+ content: content_json,
532
+ forumId: post.gameForumId,
533
+ postCommentId: post.postCommentId,
534
+ postId: post.postId,
535
+ postType: "1",
536
+ toUserId: post.userId,
537
+ }
538
+
539
+ return await this._dna_request("forum/comment/createReply", data, { sign: true, refer: true, params: { toUserId: post.userId } })
540
+ }
541
+
542
+ /** 回复评论的评论 */
543
+ async createReplyList(
544
+ post: { userId: string; postId: string; postCommentId: string; postCommentReplyId: string; gameForumId: number },
545
+ content: string,
546
+ ) {
547
+ const content_json = JSON.stringify([
548
+ {
549
+ content,
550
+ contentType: "1",
551
+ imgHeight: 0,
552
+ imgWidth: 0,
553
+ url: "",
554
+ },
555
+ ])
556
+ const data = {
557
+ content: content_json,
558
+ forumId: post.gameForumId,
559
+ postCommentId: post.postCommentId,
560
+ postCommentReplyId: post.postCommentReplyId,
561
+ postId: post.postId,
562
+ postType: "1",
563
+ toUserId: post.userId,
564
+ }
565
+ return await this._dna_request("forum/comment/createReply", data, { sign: true, refer: true, params: { toUserId: post.userId } })
566
+ }
567
+
568
+ /** 删 */
569
+ async deletePost(deleteType: number, id: number) {
570
+ return await this._dna_request("forum/more/delete", { deleteType, id }, { sign: true, refer: true })
289
571
  }
290
572
 
291
573
  /**
@@ -298,7 +580,7 @@ export class DNAAPI {
298
580
  searchType: 1,
299
581
  type: 2,
300
582
  }
301
- return await this._dna_request<DNAMineRes>(GET_MINE_URL, data)
583
+ return await this._dna_request<DNAMineRes>("user/mine", data)
302
584
  }
303
585
 
304
586
  /**
@@ -306,12 +588,12 @@ export class DNAAPI {
306
588
  * @returns 用户信息
307
589
  */
308
590
  async getMine() {
309
- return await this._dna_request<DNAMineRes>(GET_MINE_URL)
591
+ return await this._dna_request<DNAMineRes>("user/mine")
310
592
  }
311
593
 
312
594
  async getGameConfig() {
313
595
  const data = { gameId: DNA_GAME_ID }
314
- return await this._dna_request<DNAGameConfigRes[]>(GET_GAME_CONFIG_URL, data)
596
+ return await this._dna_request<DNAGameConfigRes[]>("config/getGameConfig", data)
315
597
  }
316
598
 
317
599
  async getHeaders(options?: {
@@ -428,10 +710,13 @@ export class DNAAPI {
428
710
  const controller = new AbortController()
429
711
  const timeoutId = setTimeout(() => controller.abort(), timeout)
430
712
 
431
- const response = await this.fetchFn(url, {
713
+ const initOptions = {
432
714
  ...fetchOptions,
433
715
  signal: controller.signal,
434
- })
716
+ }
717
+ const response = this.fetchFn
718
+ ? await this.fetchFn(`${this.BASE_URL}${url}`, initOptions)
719
+ : await fetch(`${this.BASE_URL}${url}`, initOptions)
435
720
  clearTimeout(timeoutId)
436
721
 
437
722
  // 获取响应头的 content-type
@@ -472,6 +757,19 @@ export class DNAAPI {
472
757
  }
473
758
  }
474
759
 
760
+ enum DNAInstanceMHType {
761
+ "角色" = "role",
762
+ "武器" = "weapon",
763
+ "魔之楔" = "mzx",
764
+ "role" = "角色",
765
+ "weapon" = "武器",
766
+ "mzx" = "魔之楔",
767
+ }
768
+
769
+ export function getDNAInstanceMHType(key: keyof typeof DNAInstanceMHType) {
770
+ return DNAInstanceMHType[key]
771
+ }
772
+
475
773
  //#region 接口定义
476
774
 
477
775
  export interface DNAMineRes {
@@ -480,7 +778,7 @@ export interface DNAMineRes {
480
778
  hasNext: number
481
779
  }
482
780
 
483
- interface DNAMine {
781
+ export interface DNAMine {
484
782
  /** 文章数量 */
485
783
  articleCount: number
486
784
  /** 收藏数量 */
@@ -650,24 +948,9 @@ export interface DNARoleForToolInstance {
650
948
  on: number
651
949
  }
652
950
 
653
- enum DNAInstanceMHType {
654
- "角色" = "role",
655
- "武器" = "weapon",
656
- "魔之楔" = "mzx",
657
- "role" = "角色",
658
- "weapon" = "武器",
659
- "mzx" = "魔之楔",
660
- }
661
-
662
- export function getDNAInstanceMHType(key: keyof typeof DNAInstanceMHType) {
663
- return DNAInstanceMHType[key]
664
- }
665
-
666
951
  export interface DNARoleForToolInstanceInfo {
667
952
  /** 密函列表 */
668
953
  instances: DNARoleForToolInstance[] // instances
669
- /** 密函类型 */
670
- mh_type?: DNAInstanceMHType // 密函类型
671
954
  }
672
955
 
673
956
  export interface DraftDoingInfo {
@@ -1136,7 +1419,7 @@ export interface DNAPostDetail {
1136
1419
  isOfficial: number
1137
1420
  isRecommend: number
1138
1421
  isTop: number
1139
- lastEditorTime: string
1422
+ lastEditorTime?: string
1140
1423
  likeCount: number
1141
1424
  postContent: DNAPostContent[]
1142
1425
  postH5Content: string
@@ -1146,6 +1429,8 @@ export interface DNAPostDetail {
1146
1429
  postUserId: string
1147
1430
  refreshHour: number
1148
1431
  score: number
1432
+ topics: DNATopicShort[]
1433
+ userHeadCode: string
1149
1434
  userLevel: number
1150
1435
  userModeratorIdentity: number
1151
1436
  userName: string
@@ -1236,14 +1521,6 @@ export interface DNAPostContentVideo {
1236
1521
  coverUrl?: string // coverUrl
1237
1522
  }
1238
1523
 
1239
- // interface DNAWikiDetail {
1240
- // name: string // name
1241
- // }
1242
-
1243
- // interface DNAWikiRes {
1244
- // wikis: DNAWikiDetail[] // wikis
1245
- // }
1246
-
1247
1524
  class DNAApiResponse<T = any> {
1248
1525
  code: number = 0
1249
1526
  msg: string = ""