728x90
VV
서버와의 연결이 성공했으므로 서로 정보를 전달할 수 있어야 한다.
로그인 UI가 있으므로 ID, PW TextBox에 입력한 Text를 로그인 버튼을 누르면 서버로 전송해야 한다.
// LoginWidget.h
UCLASS()
class VERSUSVILLAGE_API ULoginWidget : public UUserWidget
{
GENERATED_BODY()
public:
virtual void NativeConstruct() override;
UFUNCTION()
void OnLoginButtonClicked();
protected:
UPROPERTY(meta = (BindWidget))
class UEditableTextBox* IDTextBox;
UPROPERTY(meta = (BindWidget))
class UEditableTextBox* PWTextBox;
UPROPERTY(meta = (BindWidget))
class UButton* LoginButton;
private:
void SendDataToServer(FString ID, FString PW);
};
//LoginWidget.cpp
void ULoginWidget::NativeConstruct()
{
Super::NativeConstruct();
UE_LOG(LogTemp, Log, TEXT("NativeConstruct Called"));
// Click Login Button
if (LoginButton)
{
LoginButton->OnClicked.AddDynamic(this, &ULoginWidget::OnLoginButtonClicked);
}
}
void ULoginWidget::OnLoginButtonClicked()
{
FString ID = IDTextBox->GetText().ToString();
FString PW = PWTextBox->GetText().ToString();
if (!ID.IsEmpty() && !PW.IsEmpty())
{
SendDataToServer(ID, PW);
}
else
{
UE_LOG(LogTemp, Warning, TEXT("ID 또는 PW가 입력되지 않았습니다."));
}
}
void ULoginWidget::SendDataToServer(FString ID, FString PW)
{
UMyGameInstance* GameInstance = Cast<UMyGameInstance>(GetWorld()->GetGameInstance());
if (GameInstance && GameInstance->NetworkManager)
{
FString DataToSend = FString::Printf(TEXT("ID: %s, PW: %s"), *ID, *PW);
GameInstance->NetworkManager->SendData(DataToSend);
UE_LOG(LogTemp, Log, TEXT("데이터 전송 완료: %s"), *DataToSend);
}
else
{
UE_LOG(LogTemp, Error, TEXT("NetworkManager가 유효하지 않습니다."));
}
}
성공적으로 Log가 찍히고 있는것을 확인할 수 있다.
이제 서버에서 잘 받는지 확인을 해야한다.
서버에서 아무것도 못읽는 것을 중단점을 찍어가면서 확인할 수 있었고, 그 이유를 발견할 수 있었다. 서버에서는 PacketHeader를 토대로 받고 있었기 때문에 잘못된 곳을 참조하고 있어서 읽지 못했다. 그래서 대대적인 수정 작업에 들어갔다.
일단 msgID에 들어갈 프로토콜을 UE5, SERVER에 정의해두었다.
void UNetworkManager::SendLoginRequest(FString ID, FString PW)
{
if (ClientSocket)
{
hbServerEngine::PacketHeader Header;
Header.MsgID = LOGIN_REQUEST_MSG_ID;
Header.TotalSize = sizeof(hbServerEngine::PacketHeader) + ID.Len() + PW.Len() + 2;
Header.Attribute = 0;
FString DataToSend = FString::Printf(TEXT("%s|%s"), *ID, *PW);
TArray<uint8> PacketData;
PacketData.SetNumUninitialized(Header.TotalSize);
FMemory::Memcpy(PacketData.GetData(), &Header, sizeof(hbServerEngine::PacketHeader));
FTCHARToUTF8 Converter(*DataToSend);
FMemory::Memcpy(PacketData.GetData() + sizeof(hbServerEngine::PacketHeader), Converter.Get(), Converter.Length());
int32 Sent = 0;
ClientSocket->Send(PacketData.GetData(), PacketData.Num(), Sent);
UE_LOG(LogTemp, Log, TEXT("Login request sent: ID = %s, PW = %s"), *ID, *PW);
}
}
추가적으로 UE5에서 서버로 보내는 코드를 수정했다.
성공적으로 클라이언트에서 보낸 ID와 PW를 서버에서 받을 수 있었고, 받은 데이터를 토대로 검증을 완료했다.
bool ValidateUserCredentials(const string& ID, const string& PW)
{
char EscapeID[256];
char EscapePW[256];
mysql_real_escape_string(&mysql, EscapeID, ID.c_str(), ID.length());
mysql_real_escape_string(&mysql, EscapePW, PW.c_str(), PW.length());
MYSQL_RES* Res;
MYSQL_ROW Row;
string Query = "SELECT * FROM vv.users WHERE user_nickname='" + std::string(EscapeID) + "' AND user_pw='" + std::string(EscapePW) + "'";
if (mysql_query(&mysql, Query.c_str()))
{
std::cerr << "MySQL query error : " << mysql_error(&mysql) << std::endl;
std::cerr.flush();
return false;
}
Res = mysql_store_result(&mysql);
if (Res == nullptr)
{
return false;
}
Row = mysql_fetch_row(Res);
bool bIsValid = false;
if (Row != nullptr)
{
bIsValid = true;
}
mysql_free_result(Res);
return bIsValid;
}
728x90
'Study > Project' 카테고리의 다른 글
VV 5. 움직임 구현 (Infinity Run), 점프, 슬라이드 (0) | 2024.10.30 |
---|---|
VV 4. 클라이언트 수신 (0) | 2024.10.29 |
VV 트러블 슈팅 1. MSB3073 에러, NewObject with empty name can't be used to create default subobjects 에러 (0) | 2024.10.24 |
VV 2. 서버와의 연결 (0) | 2024.10.24 |
VV 1. 로그인 UI (3) | 2024.10.23 |