diff --git a/manifest.json b/manifest.json
index 0933aa2..9b5d439 100644
--- a/manifest.json
+++ b/manifest.json
@@ -4,7 +4,7 @@
   "name": "LLOneBot",
   "slug": "LLOneBot",
   "description": "LiteLoaderQQNT的OneBotApi",
-  "version": "3.5.0",
+  "version": "3.6.0",
   "thumbnail": "./icon.png",
   "authors": [
     {
diff --git a/src/common/data.ts b/src/common/data.ts
index 6bb5dda..3422cab 100644
--- a/src/common/data.ts
+++ b/src/common/data.ts
@@ -87,4 +87,4 @@ export function getUidByUin(uin: string) {
     }
 }
 
-export const version = "v3.5.0"
+export const version = "v3.6.0"
diff --git a/src/ntqqapi/hook.ts b/src/ntqqapi/hook.ts
index ec29621..a64e60f 100644
--- a/src/ntqqapi/hook.ts
+++ b/src/ntqqapi/hook.ts
@@ -17,7 +17,8 @@ export enum ReceiveCmd {
     USER_INFO = "nodeIKernelProfileListener/onProfileSimpleChanged",
     GROUPS = "nodeIKernelGroupListener/onGroupListUpdate",
     GROUPS_UNIX = "onGroupListUpdate",
-    FRIENDS = "onBuddyListChange"
+    FRIENDS = "onBuddyListChange",
+    MEDIA_DOWNLOAD_COMPLETE = "nodeIKernelMsgListener/onRichMediaDownloadComplete"
 }
 
 interface NTQQApiReturnData<PayloadType = unknown> extends Array<any> {
diff --git a/src/ntqqapi/ntcall.ts b/src/ntqqapi/ntcall.ts
index 70145d1..c417e03 100644
--- a/src/ntqqapi/ntcall.ts
+++ b/src/ntqqapi/ntcall.ts
@@ -3,7 +3,7 @@ import {hookApiCallbacks, ReceiveCmd, registerReceiveHook, removeReceiveHook} fr
 import {log} from "../common/utils";
 import {ChatType, Friend, Group, GroupMember, RawMessage, SelfInfo, SendMessageElement, User} from "./types";
 import * as fs from "fs";
-import {addHistoryMsg, msgHistory, selfInfo, uidMaps} from "../common/data";
+import {addHistoryMsg, msgHistory, selfInfo} from "../common/data";
 import {v4 as uuidv4} from "uuid"
 
 interface IPCReceiveEvent {
@@ -66,14 +66,16 @@ interface NTQQApiParams {
     className?: NTQQApiClass,
     channel?: NTQQApiChannel,
     args?: unknown[],
-    cbCmd?: ReceiveCmd | null
+    cbCmd?: ReceiveCmd | null,
+    cmdCB?: (payload: any) => boolean;
     timeoutSecond?: number,
 }
 
 function callNTQQApi<ReturnType>(params: NTQQApiParams) {
     let {
         className, methodName, channel, args,
-        cbCmd, timeoutSecond: timeout
+        cbCmd, timeoutSecond: timeout,
+        cmdCB
     } = params;
     className = className ?? NTQQApiClass.NT_API;
     channel = channel ?? NTQQApiChannel.IPC_UP_2;
@@ -95,12 +97,20 @@ function callNTQQApi<ReturnType>(params: NTQQApiParams) {
             // 这里的callback比较特殊,QQ后端先返回是否调用成功,再返回一条结果数据
             hookApiCallbacks[uuid] = (result: GeneralCallResult) => {
                 log(`${methodName} callback`, result)
-                if (result.result == 0) {
+                if (result?.result == 0 || result === undefined) {
                     const hookId = registerReceiveHook<ReturnType>(cbCmd, (payload) => {
                         log(methodName, "second callback", cbCmd, payload);
-                        removeReceiveHook(hookId);
-                        success = true
-                        resolve(payload);
+                        if (cmdCB) {
+                            if (cmdCB(payload)) {
+                                removeReceiveHook(hookId);
+                                success = true
+                                resolve(payload);
+                            }
+                        } else {
+                            removeReceiveHook(hookId);
+                            success = true
+                            resolve(payload);
+                        }
                     })
                 } else {
                     success = true
@@ -138,7 +148,7 @@ interface GeneralCallResult {
 export class NTQQApi {
     // static likeFriend = defineNTQQApi<void>(NTQQApiChannel.IPC_UP_2, NTQQApiClass.NT_API, NTQQApiMethod.LIKE_FRIEND)
     static likeFriend(uid: string, count = 1) {
-        return callNTQQApi({
+        return callNTQQApi<GeneralCallResult>({
             methodName: NTQQApiMethod.LIKE_FRIEND,
             args: [{
                 doLikeUserInfo: {
@@ -225,7 +235,7 @@ export class NTQQApi {
             let values = result.result.infos.values()
 
             let members = Array.from(values) as GroupMember[]
-            for(const member of members){
+            for (const member of members) {
                 // uidMaps[member.uid] = member.uin;
             }
             // log(uidMaps);
@@ -328,7 +338,15 @@ export class NTQQApi {
             },
             undefined,
         ]
-        await callNTQQApi({methodName: NTQQApiMethod.DOWNLOAD_MEDIA, args: apiParams})
+        // log("需要下载media", sourcePath);
+        await callNTQQApi({
+            methodName: NTQQApiMethod.DOWNLOAD_MEDIA,
+            args: apiParams,
+            cbCmd: ReceiveCmd.MEDIA_DOWNLOAD_COMPLETE,
+            cmdCB:(payload: {notifyInfo: {filePath: string}})=>{
+                // log("media 下载完成判断", payload.notifyInfo.filePath, sourcePath);
+                return payload.notifyInfo.filePath == sourcePath;
+            }})
         return sourcePath
     }
 
@@ -341,7 +359,7 @@ export class NTQQApi {
         })
     }
 
-    static sendMsg(peer: Peer, msgElements: SendMessageElement[], waitComplete = false, timeout=10000) {
+    static sendMsg(peer: Peer, msgElements: SendMessageElement[], waitComplete = false, timeout = 10000) {
         const sendTimeout = timeout
 
         return new Promise<RawMessage>((resolve, reject) => {
diff --git a/src/onebot11/action/SendLike.ts b/src/onebot11/action/SendLike.ts
new file mode 100644
index 0000000..5ebe89b
--- /dev/null
+++ b/src/onebot11/action/SendLike.ts
@@ -0,0 +1,31 @@
+import BaseAction from "./BaseAction";
+import {getFriend} from "../../common/data";
+import {NTQQApi} from "../../ntqqapi/ntcall";
+import {ActionName} from "./types";
+import { log } from "../../common/utils";
+
+interface Payload {
+    user_id: number,
+    times: number
+}
+
+export default class SendLike extends BaseAction<Payload, null> {
+    actionName = ActionName.SendLike
+
+    protected async _handle(payload: Payload): Promise<null> {
+        const qq = payload.user_id.toString();
+        const friend = await getFriend(qq)
+        if (!friend) {
+            throw (`点赞失败,${qq}不是好友`)
+        }
+        try {
+            let result = await NTQQApi.likeFriend(friend.uid, parseInt(payload.times.toString()) || 1);
+            if (result.result !== 0){
+                throw result.errMsg
+            }
+        } catch (e) {
+            throw `点赞失败 ${e}`
+        }
+        return null
+    }
+}
\ No newline at end of file
diff --git a/src/onebot11/action/go-cqhttp/GetStrangerInfo.ts b/src/onebot11/action/go-cqhttp/GetStrangerInfo.ts
new file mode 100644
index 0000000..f871234
--- /dev/null
+++ b/src/onebot11/action/go-cqhttp/GetStrangerInfo.ts
@@ -0,0 +1,24 @@
+import BaseAction from "../BaseAction";
+import {OB11GroupMember, OB11User} from "../../types";
+import {friends, getFriend, getGroupMember, groups} from "../../../common/data";
+import {OB11Constructor} from "../../constructor";
+import {ActionName} from "../types";
+
+
+export default class GoCQHTTPGetStrangerInfo extends BaseAction<{user_id: number}, OB11User>{
+    actionName = ActionName.GoCQHTTP_GetStrangerInfo
+    protected async _handle(payload: { user_id: number }): Promise<OB11User> {
+        const user_id = payload.user_id.toString()
+        const friend = await getFriend(user_id)
+        if (friend){
+            return OB11Constructor.friend(friend);
+        }
+        for(const group of groups){
+            const member = await getGroupMember(group.groupCode, user_id)
+            if (member){
+                return OB11Constructor.groupMember(group.groupCode, member) as OB11User
+            }
+        }
+        throw ("查无此人")
+    }
+}
\ No newline at end of file
diff --git a/src/onebot11/action/index.ts b/src/onebot11/action/index.ts
index ab78d9b..27faa26 100644
--- a/src/onebot11/action/index.ts
+++ b/src/onebot11/action/index.ts
@@ -15,8 +15,11 @@ import CanSendRecord from "./CanSendRecord";
 import CanSendImage from "./CanSendImage";
 import GetStatus from "./GetStatus";
 import {GoCQHTTPSendGroupForwardMsg, GoCQHTTPSendPrivateForwardMsg} from "./go-cqhttp/SendForwardMsg";
+import GoCQHTTPGetStrangerInfo from "./go-cqhttp/GetStrangerInfo";
+import SendLike from "./SendLike";
 
 export const actionHandlers = [
+    new SendLike(),
     new GetMsg(),
     new GetLoginInfo(),
     new GetFriendList(),
@@ -31,6 +34,7 @@ export const actionHandlers = [
     //以下为go-cqhttp api
     new GoCQHTTPSendGroupForwardMsg(),
     new GoCQHTTPSendPrivateForwardMsg(),
+    new GoCQHTTPGetStrangerInfo()
 
 ]
 
diff --git a/src/onebot11/action/types.ts b/src/onebot11/action/types.ts
index d97ac7e..6ef6da5 100644
--- a/src/onebot11/action/types.ts
+++ b/src/onebot11/action/types.ts
@@ -13,6 +13,7 @@ export interface InvalidCheckResult {
 
 export enum ActionName {
     TestForwardMsg = "test_forward_msg",
+    SendLike = "send_like",
     GetLoginInfo = "get_login_info",
     GetFriendList = "get_friend_list",
     GetGroupInfo = "get_group_info",
@@ -30,5 +31,6 @@ export enum ActionName {
     CanSendImage = "can_send_image",
     // 以下为go-cqhttp api
     GoCQHTTP_SendGroupForwardMsg = "send_group_forward_msg",
-    GoCQHTTP_SendPrivateForwardMsg = "send_private_forward_msg"
+    GoCQHTTP_SendPrivateForwardMsg = "send_private_forward_msg",
+    GoCQHTTP_GetStrangerInfo = "get_stranger_info"
 }
\ No newline at end of file
diff --git a/src/onebot11/constructor.ts b/src/onebot11/constructor.ts
index d24e190..79b155d 100644
--- a/src/onebot11/constructor.ts
+++ b/src/onebot11/constructor.ts
@@ -7,7 +7,17 @@ import {
     OB11MessageDataType,
     OB11User
 } from "./types";
-import {AtType, ChatType, Group, GroupMember, IMAGE_HTTP_HOST, RawMessage, SelfInfo, User} from '../ntqqapi/types';
+import {
+    AtType,
+    ChatType,
+    Friend,
+    Group,
+    GroupMember,
+    IMAGE_HTTP_HOST,
+    RawMessage,
+    SelfInfo,
+    User
+} from '../ntqqapi/types';
 import {getFriend, getGroupMember, getHistoryMsgBySeq, selfInfo} from '../common/data';
 import {file2base64, getConfigUtil, log} from "../common/utils";
 import {NTQQApi} from "../ntqqapi/ntcall";
@@ -131,7 +141,7 @@ export class OB11Constructor {
                 if (!enableLocalFile2Url) {
                     message_data.data.file = "file://" + filePath
                 } else { // 不使用本地路径
-                    if (message_data.data.http_file) {
+                    if (message_data.data.http_file && !message_data.data.http_file.startsWith(IMAGE_HTTP_HOST + "/download")) {
                         message_data.data.file = message_data.data.http_file
                     } else {
                         let {err, data} = await file2base64(filePath);
diff --git a/src/renderer.ts b/src/renderer.ts
index 4814403..36e9f0a 100644
--- a/src/renderer.ts
+++ b/src/renderer.ts
@@ -109,7 +109,7 @@ async function onSettingWindowCreated(view: Element) {
                 <setting-item data-direction="row" class="hostItem vertical-list-item">
                     <div>
                         <div>上报文件不采用本地路径</div>
-                        <div class="tips">开启后,上报图片为http连接,语音为base64编码</div>
+                        <div class="tips">开启后,上报文件(图片语音等)为http链接或base64编码</div>
                     </div>
                     <setting-switch id="switchFileUrl" ${config.enableLocalFile2Url ? "is-active" : ""}></setting-switch>
                 </setting-item>