From 5737e415c9d70ad0e0c0e7dde95692a83a9b994c Mon Sep 17 00:00:00 2001 From: 997146918 <997146918@qq.com> Date: Mon, 7 Jul 2025 09:33:56 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=80=9A=E4=BF=A1=E5=8D=8F?= =?UTF-8?q?=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AIGC/DatabaseHandle.py | 7 +- AIGC/data.db | Bin 0 -> 16384 bytes AIGC/main.py | 119 ++++++++++-------- .../Plugins/AIGC/Source/AIGC/Definations.cpp | 5 + .../AIGC/Source/AIGC/Private/AIGCSetting.cpp | 4 + .../AIGC/Private/Widget/CharacterWindow.cpp | 53 ++++++++ .../AIGC/Source/AIGC/Public/AIGCSetting.h | 19 +++ .../AIGC/Public/Widget/CharacterWindow.h | 23 ++++ 8 files changed, 180 insertions(+), 50 deletions(-) create mode 100644 AIGC/data.db create mode 100644 TestForAIGC/Plugins/AIGC/Source/AIGC/Definations.cpp create mode 100644 TestForAIGC/Plugins/AIGC/Source/AIGC/Private/AIGCSetting.cpp create mode 100644 TestForAIGC/Plugins/AIGC/Source/AIGC/Private/Widget/CharacterWindow.cpp create mode 100644 TestForAIGC/Plugins/AIGC/Source/AIGC/Public/AIGCSetting.h create mode 100644 TestForAIGC/Plugins/AIGC/Source/AIGC/Public/Widget/CharacterWindow.h diff --git a/AIGC/DatabaseHandle.py b/AIGC/DatabaseHandle.py index 9c23d28..02f94e7 100644 --- a/AIGC/DatabaseHandle.py +++ b/AIGC/DatabaseHandle.py @@ -52,7 +52,12 @@ class DatabaseHandle: name, age, personality, profession, characterBackground, chat_style ) VALUES (?, ?, ?, ?, ?, ?) - ON CONFLICT(name) DO NOTHING + ON CONFLICT(name) DO UPDATE SET + age = excluded.age, + personality = excluded.personality, + profession = excluded.profession, + characterBackground = excluded.characterBackground, + chat_style = excluded.chat_style ''', ( data["name"], data["age"], data["personality"], data["profession"], data["characterBackground"], diff --git a/AIGC/data.db b/AIGC/data.db new file mode 100644 index 0000000000000000000000000000000000000000..86548e74aeec9fa01cd406262843dbf0cf387b57 GIT binary patch literal 16384 zcmeI%-%ry(902gPBU4CVCOi;c%n?I^3FsIaBZ<)ol`IaTqf0c#ER|JVfEC*MgSU+V z!+=a9D!-BVYY%MGOtUd&eDF_k*LE?1H{+uR6&)s<#ur2Kz3kfS-F@%Jr|Cnx?u$;J zBB1M{)XyuZg*rgdG<60cilWRUmyx`a7*Z&_rgs`joXymc+Y^$j5yxKQkY7|# zm)q%VEE%P2cP`OK@%0O+o$P^gbh4l^h^}00@8p2!H?xfB*=900@8p z2!H?x>~(<(Q!Qr>LB0J+-Ni2e>bypSG3jDTsokCh~vmZJsP-*jJM?7P4i1QGkq29j>=3H njWU|Hqij~&@h0nuChIX|ZE0<`wjOH^n(6<%5L>H_tmWi)yUikO literal 0 HcmV?d00001 diff --git a/AIGC/main.py b/AIGC/main.py index 591f78d..4c0148f 100644 --- a/AIGC/main.py +++ b/AIGC/main.py @@ -42,14 +42,10 @@ async def heartbeat(websocket: WebSocket): # break # 连接已关闭时退出循环 #statuscode -1 服务器运行错误 0 心跳标志 1 正常 2 输出异常 -async def senddata(websocket: WebSocket, statusCode: int, messages: List[str]): +async def senddata(websocket: WebSocket, protocol: dict): # 将AI响应发送回UE5 if websocket.client_state == WebSocketState.CONNECTED: - data = { - "statuscode": statusCode, - "messages": messages - } - json_string = json.dumps(data, ensure_ascii=False) + json_string = json.dumps(protocol, ensure_ascii=False) await websocket.send_text(json_string) # WebSocket路由处理 @@ -65,15 +61,17 @@ async def websocket_endpoint(websocket: WebSocket, client_id: str): # 接收UE5发来的消息 data = await websocket.receive_text() logger.log(logging.INFO, f"收到UE5消息 [{client_id}]: {data}") - success, prompt = process_prompt(data) - global lastPrompt - lastPrompt = prompt - # 调用AI生成响应 - if(success): - asyncio.create_task(generateAIChat(prompt, websocket)) - await senddata(websocket, 0, []) - else: - await senddata(websocket, -1, []) + await process_protocol_json(data, websocket) + + # success, prompt = process_prompt(data) + # global lastPrompt + # lastPrompt = prompt + # # 调用AI生成响应 + # if(success): + # asyncio.create_task(generateAIChat(prompt, websocket)) + # await senddata(websocket, 0, []) + # else: + # await senddata(websocket, -1, []) @@ -85,6 +83,29 @@ async def websocket_endpoint(websocket: WebSocket, client_id: str): #manager.disconnect(client_id) logger.log(logging.ERROR, f"WebSocket异常 [{client_id}]: {str(e)}") +async def handle_characterlist(client: WebSocket): + ### 获得数据库中的角色信息### + characters = database.get_character_byname("") + protocol = {} + protocol["cmd"] = "CharacterList" + protocol["status"] = 1 + protocol["message"] = "success" + protocol["data"] = json.dumps(characters) + await senddata(client, protocol) + +async def process_protocol_json(json_str: str, client: WebSocket): + ### 处理协议JSON ### + try: + protocol = json.loads(json_str) + cmd = protocol.get("cmd") + data = protocol.get("data") + if cmd == "CharacterList": + await handle_characterlist(client) + + except json.JSONDecodeError as e: + print(f"JSON解析错误: {e}") + + def process_prompt(promptFromUE: str) -> Tuple[bool, str]: try: data = json.loads(promptFromUE) @@ -253,42 +274,42 @@ if __name__ == "__main__": logger.log(logging.ERROR, f"角色 张三已经添加到数据库") # Test AI aicore.getPromptToken("测试功能") - asyncio.run( - generateAIChat(promptStr = f""" - #你是一个游戏NPC对话生成器。请严格按以下要求生成两个角色的日常对话 - #对话的世界观背景是2025年的都市背景 - 1. 生成【2轮完整对话】,每轮包含双方各一次发言(共4句) - 2.角色设定 + # asyncio.run( + # generateAIChat(promptStr = f""" + # #你是一个游戏NPC对话生成器。请严格按以下要求生成两个角色的日常对话 + # #对话的世界观背景是2025年的都市背景 + # 1. 生成【2轮完整对话】,每轮包含双方各一次发言(共4句) + # 2.角色设定 - "张三": {{ - "姓名": "张三", - "年龄": 35, - "性格": "成熟稳重/惜字如金", - "职业": "阿里巴巴算法工程师", - "背景": "浙大计算机系毕业,专注AI优化项目", - "对话场景": "你正在和用户聊天,用户是你的同事", - "语言风格": "请在对话中表现出专业、冷静、惜字如金。用口语化的方式简短回答" - }}, - "李明": {{ - "姓名": "李明", - "年龄": 30, - "职业": "产品经理", - "性格": "活泼健谈" - "背景": "公司资深产品经理", - "对话场景": "你正在和用户聊天,用户是你的同事", - "语言风格": "热情" - }} + # "张三": {{ + # "姓名": "张三", + # "年龄": 35, + # "性格": "成熟稳重/惜字如金", + # "职业": "阿里巴巴算法工程师", + # "背景": "浙大计算机系毕业,专注AI优化项目", + # "对话场景": "你正在和用户聊天,用户是你的同事", + # "语言风格": "请在对话中表现出专业、冷静、惜字如金。用口语化的方式简短回答" + # }}, + # "李明": {{ + # "姓名": "李明", + # "年龄": 30, + # "职业": "产品经理", + # "性格": "活泼健谈" + # "背景": "公司资深产品经理", + # "对话场景": "你正在和用户聊天,用户是你的同事", + # "语言风格": "热情" + # }} - 3.输出格式: - - 张三:[第一轮发言] - 李明:[第一轮回应] - 张三:[第二轮发言] - 李明:[第二轮回应] - - """ - ) - ) + # 3.输出格式: + # + # 张三:[第一轮发言] + # 李明:[第一轮回应] + # 张三:[第二轮发言] + # 李明:[第二轮回应] + # + # """ + # ) + # ) try: # 主线程永久挂起(监听退出信号) diff --git a/TestForAIGC/Plugins/AIGC/Source/AIGC/Definations.cpp b/TestForAIGC/Plugins/AIGC/Source/AIGC/Definations.cpp new file mode 100644 index 0000000..ffe7412 --- /dev/null +++ b/TestForAIGC/Plugins/AIGC/Source/AIGC/Definations.cpp @@ -0,0 +1,5 @@ +#include "Definations.h" + +FString FNetCommand::CharacterList = TEXT("CharacterList"); +FString FNetCommand::AddCharacter = TEXT("AddCharacter"); +FString FNetCommand::AiChatGenerate = TEXT("AiChatGenerate"); \ No newline at end of file diff --git a/TestForAIGC/Plugins/AIGC/Source/AIGC/Private/AIGCSetting.cpp b/TestForAIGC/Plugins/AIGC/Source/AIGC/Private/AIGCSetting.cpp new file mode 100644 index 0000000..35c62b7 --- /dev/null +++ b/TestForAIGC/Plugins/AIGC/Source/AIGC/Private/AIGCSetting.cpp @@ -0,0 +1,4 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "AIGCSetting.h" diff --git a/TestForAIGC/Plugins/AIGC/Source/AIGC/Private/Widget/CharacterWindow.cpp b/TestForAIGC/Plugins/AIGC/Source/AIGC/Private/Widget/CharacterWindow.cpp new file mode 100644 index 0000000..01b4b01 --- /dev/null +++ b/TestForAIGC/Plugins/AIGC/Source/AIGC/Private/Widget/CharacterWindow.cpp @@ -0,0 +1,53 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "Widget/CharacterWindow.h" + +#include "AIGC.h" +#include "WebSocketManager.h" + + +void SCharacterWindow::Construct(const FArguments& InArgs) +{ + + // 注册绘制后回调 + RegisterActiveTimer(0.f, + FWidgetActiveTimerDelegate::CreateSP( + this, + &SCharacterWindow::OnPostPaint + ) + ); +} + +EActiveTimerReturnType SCharacterWindow::OnPostPaint(double X, float Arg) +{ + //init websocket + FAIGCModule* ModulePtr = FModuleManager::GetModulePtr("AIGC"); + if (ModulePtr) + { + UWebSocketManager* WebSocketManager = ModulePtr->GetWebSocketManager(); + if (!WebSocketManager) + { + ModulePtr->InitWebSocketManager(); + WebSocketManager = ModulePtr->GetWebSocketManager(); + } + else + { + WebSocketManager->SendData(FNetCommand::CharacterList, TEXT("")); + } + WebSocketManager->OnDataReceiveDelaget.AddRaw(this, &SCharacterWindow::HandleReceiveData); + WebSocketManager->OnConnectDelegate.AddLambda([this, WebSocketManager](bool bSuccess) + { + WebSocketManager->SendData(FNetCommand::CharacterList, TEXT("")); + }); + } + return EActiveTimerReturnType::Stop; +} + +void SCharacterWindow::HandleReceiveData(FNetProtocol protocol) +{ + if (protocol.cmd == FNetCommand::CharacterList) + { + //刷新角色列表 + } +} diff --git a/TestForAIGC/Plugins/AIGC/Source/AIGC/Public/AIGCSetting.h b/TestForAIGC/Plugins/AIGC/Source/AIGC/Public/AIGCSetting.h new file mode 100644 index 0000000..4306df5 --- /dev/null +++ b/TestForAIGC/Plugins/AIGC/Source/AIGC/Public/AIGCSetting.h @@ -0,0 +1,19 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "UObject/Object.h" +#include "AIGCSetting.generated.h" + +/** + * + */ +UCLASS(Config=AIGCSetting, DefaultConfig) +class AIGC_API UAIGCSetting : public UObject +{ + GENERATED_BODY() +public: + UPROPERTY(Config, EditAnywhere) + FString ServerIP = TEXT("127.0.0.1"); +}; diff --git a/TestForAIGC/Plugins/AIGC/Source/AIGC/Public/Widget/CharacterWindow.h b/TestForAIGC/Plugins/AIGC/Source/AIGC/Public/Widget/CharacterWindow.h new file mode 100644 index 0000000..48b23e5 --- /dev/null +++ b/TestForAIGC/Plugins/AIGC/Source/AIGC/Public/Widget/CharacterWindow.h @@ -0,0 +1,23 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "Definations.h" + +/** + * + */ +class AIGC_API SCharacterWindow: public SCompoundWidget +{ +public: + SLATE_BEGIN_ARGS(SCharacterWindow) + : _CharactersJsons() + {} + SLATE_ARGUMENT(FString, CharactersJsons) + SLATE_END_ARGS() + void Construct(const FArguments& InArgs); + EActiveTimerReturnType OnPostPaint(double X, float Arg); + + void HandleReceiveData(FNetProtocol protocol); +};