diff --git a/.gitignore b/Client/.gitignore similarity index 100% rename from .gitignore rename to Client/.gitignore diff --git a/Client/Config/DefaultEditor.ini b/Client/Config/DefaultEditor.ini new file mode 100644 index 0000000..e69de29 diff --git a/Client/Config/DefaultEngine.ini b/Client/Config/DefaultEngine.ini new file mode 100644 index 0000000..31c2030 --- /dev/null +++ b/Client/Config/DefaultEngine.ini @@ -0,0 +1,35 @@ + + +[/Script/EngineSettings.GameMapsSettings] +GameDefaultMap=/Game/TurboLinkTest/Maps/TestMap.TestMap +GameInstanceClass=/Game/TurboLinkTest/Blueprint/BP_GameInstance.BP_GameInstance_C +EditorStartupMap=/Game/TurboLinkTest/Maps/TestMap.TestMap +GlobalDefaultGameMode=/Game/TurboLinkTest/Blueprint/BP_GameMode.BP_GameMode_C +ServerDefaultMap=/Game/TurboLinkTest/Maps/TestMap.TestMap + +[/Script/HardwareTargeting.HardwareTargetingSettings] +TargetedHardwareClass=Desktop +AppliedTargetedHardwareClass=Desktop +DefaultGraphicsPerformance=Maximum +AppliedDefaultGraphicsPerformance=Maximum + +[/Script/Engine.Engine] ++ActiveGameNameRedirects=(OldGameName="TP_Blank",NewGameName="/Script/TurboLinkTest") ++ActiveGameNameRedirects=(OldGameName="/Script/TP_Blank",NewGameName="/Script/TurboLinkTest") ++ActiveClassRedirects=(OldClassName="TP_BlankGameModeBase",NewClassName="TurboLinkTestGameModeBase") + +[/Script/AndroidRuntimeSettings.AndroidRuntimeSettings] +PackageName=com.joyworkshop.turbolink +StoreVersionOffsetArm64=1 +StoreVersionOffsetX8664=2 +ApplicationDisplayName=TurboLink +TargetSDKVersion=31 +bPackageDataInsideApk=True +bBuildForArm64=True +bBuildForX8664=True + +[/Script/IOSRuntimeSettings.IOSRuntimeSettings] +BundleDisplayName=TurboLink +BundleName=turbolink +BundleIdentifier=com.joyworkshop.turbolink + diff --git a/Client/Config/DefaultGame.ini b/Client/Config/DefaultGame.ini new file mode 100644 index 0000000..1bbbcf5 --- /dev/null +++ b/Client/Config/DefaultGame.ini @@ -0,0 +1,8 @@ + +[/Script/EngineSettings.GeneralProjectSettings] +ProjectID=D413C97A4B452488FCA7348D322284BA + +[/Script/TurboLinkGrpc.TurboLinkGrpcConfig] +DefaultEndPoint=grpc.thecodeway.net:5050 +EnableServerSideTLS=True +ServerRootCerts=-----BEGIN CERTIFICATE-----\nMIIDUzCCAjugAwIBAgIJANELcq+JkuytMA0GCSqGSIb3DQEBCwUAMEsxCzAJBgNV\nBAYTAkNOMRAwDgYDVQQHDAdCZWlqaW5nMRIwEAYDVQQKDAlUdXJib0xpbmsxFjAU\nBgNVBAMMDXR1cmJvbGluay5kZXYwHhcNMjIxMTMwMDMwMjA5WhcNMzIxMTI3MDMw\nMjA5WjBLMQswCQYDVQQGEwJDTjEQMA4GA1UEBwwHQmVpamluZzESMBAGA1UECgwJ\ndHVyYm9saW5rMRYwFAYDVQQDDA10dXJib2xpbmsuZGV2MIIBIjANBgkqhkiG9w0B\nAQEFAAOCAQ8AMIIBCgKCAQEAr8vdbsXtLWOEWoygSluR3BtYJcp+1nbDwrytr7WX\nXcnzSB1rQ0lt3yQmQ5BKm6CLbUeKtQd7fIUT1JRn3KJ/dSHXT4qEWWO0XJLJeoAI\nFXprLWolbrBA8QCAs8Hcbm8F/efHphKU4a10HhD6ENa4YqYPnd89vfYgSPGS/UmF\nojWicWjmmT7Np5PBo81mzpbyhGTlOeZj6LLp77w8772MRBDZTn4eDXDuCdfbs2HM\nYFK4OQ2QQjrh2LSCA6VQgi8gGaXtp2k8CwVlXQpOFWmYX0FyXX/4qvkvXl8rG07T\nAvX7iCaG3owAYrDeQUL7NqbTvAMHiqivCwrFzThNq+XSkQIDAQABozowODA2BgNV\nHREELzAtgg8qLnR1cmJvbGluay5kZXaCDyoubGV5b3V0ZWNoLm5ldIIJbG9jYWxo\nb3N0MA0GCSqGSIb3DQEBCwUAA4IBAQB+8r4YO/vozHSa+VFcT8MmgJc8z8MDy6FE\ntD04ImGGWzs0bH+JPRI4gUF6kprHNs06B4UbvXGUO8o8QD7BGN+eSlxQ3GsnOKeu\nfeW5UOD/15q+zIZE6YT8VW3mHpQMJFlP0cVMLj9dUSs43dIwcjj2HhvmY731IZZp\nAXWbD5Vo6qM+8TmGh4ESlRh42yKsbq66Y5vd68oHk1bBcQ1xDPsEZ1GJ3zzj5KxH\nYppLeaZu7T7oSuMjzn8aLFj2Cbclu2nl7GSg1ZLPNBdAxuMC1VKgi5sPIKajWkRR\nlJad7CKjVESSM3ZrVUz/z/+/Yjn8u/jMKEqyMz3uAT0LyUbIu6ua\n-----END CERTIFICATE----- diff --git a/Client/Config/DefaultInput.ini b/Client/Config/DefaultInput.ini new file mode 100644 index 0000000..619385b --- /dev/null +++ b/Client/Config/DefaultInput.ini @@ -0,0 +1,87 @@ +[/Script/Engine.InputSettings] +-AxisConfig=(AxisKeyName="Gamepad_LeftX",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f)) +-AxisConfig=(AxisKeyName="Gamepad_LeftY",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f)) +-AxisConfig=(AxisKeyName="Gamepad_RightX",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f)) +-AxisConfig=(AxisKeyName="Gamepad_RightY",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f)) +-AxisConfig=(AxisKeyName="MouseX",AxisProperties=(DeadZone=0.f,Exponent=1.f,Sensitivity=0.07f)) +-AxisConfig=(AxisKeyName="MouseY",AxisProperties=(DeadZone=0.f,Exponent=1.f,Sensitivity=0.07f)) +-AxisConfig=(AxisKeyName="Mouse2D",AxisProperties=(DeadZone=0.f,Exponent=1.f,Sensitivity=0.07f)) ++AxisConfig=(AxisKeyName="Gamepad_LeftX",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Gamepad_LeftY",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Gamepad_RightX",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Gamepad_RightY",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MouseX",AxisProperties=(DeadZone=0.000000,Sensitivity=0.070000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MouseY",AxisProperties=(DeadZone=0.000000,Sensitivity=0.070000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Mouse2D",AxisProperties=(DeadZone=0.000000,Sensitivity=0.070000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MouseWheelAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Gamepad_LeftTriggerAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Gamepad_RightTriggerAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Gamepad_Special_Left_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Gamepad_Special_Left_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Daydream_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Daydream_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Daydream_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Daydream_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Vive_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Vive_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Vive_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Vive_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Vive_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="Vive_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="MixedReality_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Left_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Right_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="OculusTouch_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Left_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Left_Grip_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_Touch",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Right_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Right_Grip_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) ++AxisConfig=(AxisKeyName="ValveIndex_Right_Trackpad_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) +bAltEnterTogglesFullscreen=True +bF11TogglesFullscreen=True +bUseMouseForTouch=False +bEnableMouseSmoothing=True +bEnableFOVScaling=True +bCaptureMouseOnLaunch=True +bAlwaysShowTouchInterface=False +bShowConsoleOnFourFingerTap=True +bEnableGestureRecognizer=False +bUseAutocorrect=False +DefaultViewportMouseCaptureMode=CapturePermanently_IncludingInitialMouseDown +DefaultViewportMouseLockMode=LockOnCapture +FOVScale=0.011110 +DoubleClickTime=0.200000 ++ActionMappings=(ActionName="LeftShoulder",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Gamepad_LeftShoulder) ++ActionMappings=(ActionName="RightShoulder",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Gamepad_RightShoulder) +DefaultPlayerInputClass=/Script/Engine.PlayerInput +DefaultInputComponentClass=/Script/Engine.InputComponent +DefaultTouchInterface=/Engine/MobileResources/HUD/DefaultVirtualJoysticks.DefaultVirtualJoysticks +-ConsoleKeys=Tilde ++ConsoleKeys=Tilde + diff --git a/Client/Content/TurboLinkTest/Blueprint/BP_GameInstance.uasset b/Client/Content/TurboLinkTest/Blueprint/BP_GameInstance.uasset new file mode 100644 index 0000000..1854e65 Binary files /dev/null and b/Client/Content/TurboLinkTest/Blueprint/BP_GameInstance.uasset differ diff --git a/Client/Content/TurboLinkTest/Blueprint/BP_GameMode.uasset b/Client/Content/TurboLinkTest/Blueprint/BP_GameMode.uasset new file mode 100644 index 0000000..b2ae4f3 Binary files /dev/null and b/Client/Content/TurboLinkTest/Blueprint/BP_GameMode.uasset differ diff --git a/Client/Content/TurboLinkTest/Blueprint/BP_Pawn.uasset b/Client/Content/TurboLinkTest/Blueprint/BP_Pawn.uasset new file mode 100644 index 0000000..48dc480 Binary files /dev/null and b/Client/Content/TurboLinkTest/Blueprint/BP_Pawn.uasset differ diff --git a/Client/Content/TurboLinkTest/Blueprint/BP_PlayerController.uasset b/Client/Content/TurboLinkTest/Blueprint/BP_PlayerController.uasset new file mode 100644 index 0000000..c56d1dc Binary files /dev/null and b/Client/Content/TurboLinkTest/Blueprint/BP_PlayerController.uasset differ diff --git a/Client/Content/TurboLinkTest/Maps/TestMap.umap b/Client/Content/TurboLinkTest/Maps/TestMap.umap new file mode 100644 index 0000000..5d5732c Binary files /dev/null and b/Client/Content/TurboLinkTest/Maps/TestMap.umap differ diff --git a/Client/Content/TurboLinkTest/UI/WBP_ServiceTest.uasset b/Client/Content/TurboLinkTest/UI/WBP_ServiceTest.uasset new file mode 100644 index 0000000..5b460cc Binary files /dev/null and b/Client/Content/TurboLinkTest/UI/WBP_ServiceTest.uasset differ diff --git a/Client/Content/TurboLinkTest/UI/WBP_TimeService.uasset b/Client/Content/TurboLinkTest/UI/WBP_TimeService.uasset new file mode 100644 index 0000000..f8e2776 Binary files /dev/null and b/Client/Content/TurboLinkTest/UI/WBP_TimeService.uasset differ diff --git a/Client/Content/TurboLinkTest/UI/WBP_TimeService_BP.uasset b/Client/Content/TurboLinkTest/UI/WBP_TimeService_BP.uasset new file mode 100644 index 0000000..1dd85ce Binary files /dev/null and b/Client/Content/TurboLinkTest/UI/WBP_TimeService_BP.uasset differ diff --git a/Client/Content/TurboLinkTest/UI/WBP_TimeService_CPP.uasset b/Client/Content/TurboLinkTest/UI/WBP_TimeService_CPP.uasset new file mode 100644 index 0000000..9bab038 Binary files /dev/null and b/Client/Content/TurboLinkTest/UI/WBP_TimeService_CPP.uasset differ diff --git a/Client/Content/TurboLinkTest/UI/WBP_TimeService_DS.uasset b/Client/Content/TurboLinkTest/UI/WBP_TimeService_DS.uasset new file mode 100644 index 0000000..011c352 Binary files /dev/null and b/Client/Content/TurboLinkTest/UI/WBP_TimeService_DS.uasset differ diff --git a/Client/Content/TurboLinkTest/UI/WBP_UserService_BP.uasset b/Client/Content/TurboLinkTest/UI/WBP_UserService_BP.uasset new file mode 100644 index 0000000..7d73fea Binary files /dev/null and b/Client/Content/TurboLinkTest/UI/WBP_UserService_BP.uasset differ diff --git a/Client/Plugins/TurboLink/.gitkeep b/Client/Plugins/TurboLink/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Client/Source/TurboLinkTest.Target.cs b/Client/Source/TurboLinkTest.Target.cs new file mode 100644 index 0000000..1b3d9a1 --- /dev/null +++ b/Client/Source/TurboLinkTest.Target.cs @@ -0,0 +1,14 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +using UnrealBuildTool; +using System.Collections.Generic; + +public class TurboLinkTestTarget : TargetRules +{ + public TurboLinkTestTarget( TargetInfo Target) : base(Target) + { + Type = TargetType.Game; + DefaultBuildSettings = BuildSettingsVersion.V2; + ExtraModuleNames.AddRange( new string[] { "TurboLinkTest" } ); + } +} diff --git a/Client/Source/TurboLinkTest/TimeTestDSWidget.cpp b/Client/Source/TurboLinkTest/TimeTestDSWidget.cpp new file mode 100644 index 0000000..8e9ac66 --- /dev/null +++ b/Client/Source/TurboLinkTest/TimeTestDSWidget.cpp @@ -0,0 +1,170 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "TimeTestDSWidget.h" +#include "TurboLinkTestController.h" + +#include "Components/Button.h" +#include "Components/EditableText.h" +#include "Components/TextBlock.h" + +#include "TurboLinkGrpcManager.h" +#include "TurboLinkGrpcUtilities.h" +#include "TurboLinkGrpcConfig.h" + +void UTimeTestDSWidget::NativeConstruct() +{ + Super::NativeConstruct(); + + Button_ConnectTimeService->OnClicked.AddDynamic(this, &UTimeTestDSWidget::OnConnectServiceButtonClicked); + Button_ShutdownTimeService->OnClicked.AddDynamic(this, &UTimeTestDSWidget::OnShutdownServiceButtonClicked); + + Button_CreateTimeClient->OnClicked.AddDynamic(this, &UTimeTestDSWidget::OnCreateClientButtonClicked); + Button_ShutdownTimeClient->OnClicked.AddDynamic(this, &UTimeTestDSWidget::OnShutdownClientButtonClicked); + + Button_Now->OnClicked.AddDynamic(this, &UTimeTestDSWidget::OnNowButtonClicked); + Button_Now_Cancel->OnClicked.AddDynamic(this, &UTimeTestDSWidget::OnNowCancelButtonClicked); + + Button_Ticktok->OnClicked.AddDynamic(this, &UTimeTestDSWidget::OnTicktokButtonClicked); + Button_Ticktok_Cancel->OnClicked.AddDynamic(this, &UTimeTestDSWidget::OnTicktokCancelButtonClicked); + + Button_Watch->OnClicked.AddDynamic(this, &UTimeTestDSWidget::OnWatchButtonClicked); + Button_Watch_Send->OnClicked.AddDynamic(this, &UTimeTestDSWidget::OnWatchSendButtonClicked); + Button_Watch_Cancel->OnClicked.AddDynamic(this, &UTimeTestDSWidget::OnWatchCancelButtonClicked); + + FString timeServiceEndPoint = UTurboLinkGrpcUtilities::GetTurboLinkGrpcConfig()->GetServiceEndPoint(TEXT("TimeService")); + TimeServiceAddress->SetText(FText::FromString(*timeServiceEndPoint)); + TimeServiceAddress->SetIsReadOnly(true); + + PC = Cast(GetWorld()->GetFirstPlayerController()); + if (PC) { + PC->ClientWidget = this; + } + + UpdateControlState(); +} + +void UTimeTestDSWidget::UpdateControlState() +{ + if (!PC) return; + + bool serviceConnected = (PC->GetTimeServiceState() == EGrpcServiceState::Ready || PC->GetTimeServiceState()== EGrpcServiceState::Idle); + bool clientCreated = PC->IsClientCreated(); + + Button_ConnectTimeService->SetIsEnabled(!serviceConnected); + Button_ShutdownTimeService->SetIsEnabled(serviceConnected || PC->GetTimeServiceState()== EGrpcServiceState::TransientFailure); + + Button_CreateTimeClient->SetIsEnabled(serviceConnected && !clientCreated); + Button_ShutdownTimeClient->SetIsEnabled(clientCreated); + + Button_Now->SetIsEnabled(serviceConnected && clientCreated && PC->GetCtxNowState() == EGrpcContextState::Done); + Button_Now_Cancel->SetIsEnabled(serviceConnected && clientCreated && (PC->GetCtxNowState() == EGrpcContextState::Initialing || PC->GetCtxNowState() == EGrpcContextState::Busy)); + + Button_Ticktok->SetIsEnabled(serviceConnected && clientCreated && PC->GetCtxTicktokState() == EGrpcContextState::Done); + Button_Ticktok_Cancel->SetIsEnabled(serviceConnected && clientCreated && (PC->GetCtxTicktokState() == EGrpcContextState::Initialing || PC->GetCtxTicktokState() == EGrpcContextState::Busy)); + + Button_Watch->SetIsEnabled(serviceConnected && clientCreated && PC->GetCtxWatchState() == EGrpcContextState::Done); + Button_Watch_Send->SetIsEnabled(serviceConnected && clientCreated && PC->GetCtxWatchState() == EGrpcContextState::Busy); + Button_Watch_Cancel->SetIsEnabled(serviceConnected && clientCreated && (PC->GetCtxWatchState() == EGrpcContextState::Initialing || PC->GetCtxWatchState() == EGrpcContextState::Busy)); +} + +void UTimeTestDSWidget::OnConnectServiceButtonClicked() +{ + if (!PC) return; + + bool serviceConnected = (PC->GetTimeServiceState() == EGrpcServiceState::Ready); + if (serviceConnected) return; + + PC->ConnectToTimeService(); +} + +void UTimeTestDSWidget::OnShutdownServiceButtonClicked() +{ + if (!PC) return; + + bool serviceConnected = (PC->GetTimeServiceState() == EGrpcServiceState::Ready); + if (serviceConnected || PC->GetTimeServiceState() == EGrpcServiceState::TransientFailure) + { + PC->ShutdownTimeService(); + } +} + +void UTimeTestDSWidget::OnCreateClientButtonClicked() +{ + if (!PC) return; + if (PC->IsClientCreated()) return; + + PC->CreateTimeClient(); +} + +void UTimeTestDSWidget::OnShutdownClientButtonClicked() +{ + if (!PC) return; + if (!(PC->IsClientCreated())) return; + + PC->ShutdownTimeClient(); +} + +void UTimeTestDSWidget::OnNowButtonClicked() +{ + if (!PC) return; + if (!(PC->IsClientCreated())) return; + if (PC->GetCtxNowState() != EGrpcContextState::Done) return; + + PC->CallTimeNow(); +} + +void UTimeTestDSWidget::OnNowCancelButtonClicked() +{ + if (!PC) return; + if (!(PC->IsClientCreated())) return; + if (PC->GetCtxNowState() == EGrpcContextState::Done) return; + + PC->CancelTimeNow(); +} + +void UTimeTestDSWidget::OnTicktokButtonClicked() +{ + if (!PC) return; + if (!(PC->IsClientCreated())) return; + if (PC->GetCtxTicktokState() != EGrpcContextState::Done) return; + + int32 counts = FCString::Atoi(*(TicktokCounts->GetText().ToString())); + PC->CallTimeTicktok(counts); +} + +void UTimeTestDSWidget::OnTicktokCancelButtonClicked() +{ + if (!PC) return; + if (!(PC->IsClientCreated())) return; + if (PC->GetCtxTicktokState() == EGrpcContextState::Done) return; + + PC->CancelTimeTicktok(); +} + +void UTimeTestDSWidget::OnWatchButtonClicked() +{ + if (!PC) return; + if (!(PC->IsClientCreated())) return; + if (PC->GetCtxWatchState() != EGrpcContextState::Done) return; + + PC->InitTimeWatch(); +} + +void UTimeTestDSWidget::OnWatchSendButtonClicked() +{ + if (!PC) return; + if (!(PC->IsClientCreated())) return; + if (PC->GetCtxWatchState() != EGrpcContextState::Busy) return; + + PC->CallTimeWatch(); +} + +void UTimeTestDSWidget::OnWatchCancelButtonClicked() +{ + if (!PC) return; + if (!(PC->IsClientCreated())) return; + if (PC->GetCtxWatchState() == EGrpcContextState::Done) return; + + PC->CancelTimeWatch(); +} diff --git a/Client/Source/TurboLinkTest/TimeTestDSWidget.h b/Client/Source/TurboLinkTest/TimeTestDSWidget.h new file mode 100644 index 0000000..ab404f2 --- /dev/null +++ b/Client/Source/TurboLinkTest/TimeTestDSWidget.h @@ -0,0 +1,117 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "Blueprint/UserWidget.h" +#include "SGreeter/GreeterService.h" +#include "TimeTestDSWidget.generated.h" + +class ATurboLinkTestController; +/** + * + */ +UCLASS() +class TURBOLINKTEST_API UTimeTestDSWidget : public UUserWidget +{ + GENERATED_BODY() + +public: + virtual void NativeConstruct() override; + +public: + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UEditableText* TimeServiceAddress; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UTextBlock* TimeServiceStatus; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UButton* Button_ConnectTimeService; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UButton* Button_ShutdownTimeService; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UButton* Button_CreateTimeClient; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UButton* Button_ShutdownTimeClient; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UButton* Button_Now; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UTextBlock* TextResultNow; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UButton* Button_Now_Cancel; + + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UButton* Button_Ticktok; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UEditableText* TicktokCounts; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UTextBlock* TextResultTicktok; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UButton* Button_Ticktok_Cancel; + + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UButton* Button_Watch; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UButton* Button_Watch_Send; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UTextBlock* TextResultWatch; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UButton* Button_Watch_Cancel; + +protected: + UFUNCTION() + void OnConnectServiceButtonClicked(); + + UFUNCTION() + void OnShutdownServiceButtonClicked(); + + UFUNCTION() + void OnCreateClientButtonClicked(); + + UFUNCTION() + void OnShutdownClientButtonClicked(); + + + UFUNCTION() + void OnNowButtonClicked(); + + UFUNCTION() + void OnNowCancelButtonClicked(); + + UFUNCTION() + void OnTicktokButtonClicked(); + + UFUNCTION() + void OnTicktokCancelButtonClicked(); + + UFUNCTION() + void OnWatchButtonClicked(); + + UFUNCTION() + void OnWatchSendButtonClicked(); + + UFUNCTION() + void OnWatchCancelButtonClicked(); + +protected: + UPROPERTY(BlueprintReadOnly) + ATurboLinkTestController* PC; + +public: + void UpdateControlState(); +}; diff --git a/Client/Source/TurboLinkTest/TimeTestWidget.cpp b/Client/Source/TurboLinkTest/TimeTestWidget.cpp new file mode 100644 index 0000000..9a75567 --- /dev/null +++ b/Client/Source/TurboLinkTest/TimeTestWidget.cpp @@ -0,0 +1,270 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "TimeTestWidget.h" + +#include "Components/Button.h" +#include "Components/EditableText.h" +#include "Components/TextBlock.h" + +#include "TurboLinkGrpcManager.h" +#include "TurboLinkGrpcUtilities.h" +#include "TurboLinkGrpcConfig.h" + +void UTimeTestWidget::NativeConstruct() +{ + Super::NativeConstruct(); + + Button_ConnectTimeService->OnClicked.AddDynamic(this, &UTimeTestWidget::OnConnectServiceButtonClicked); + Button_ShutdownTimeService->OnClicked.AddDynamic(this, &UTimeTestWidget::OnShutdownServiceButtonClicked); + + Button_CreateTimeClient->OnClicked.AddDynamic(this, &UTimeTestWidget::OnCreateClientButtonClicked); + Button_ShutdownTimeClient->OnClicked.AddDynamic(this, &UTimeTestWidget::OnShutdownClientButtonClicked); + + Button_Now->OnClicked.AddDynamic(this, &UTimeTestWidget::OnNowButtonClicked); + Button_Now_Cancel->OnClicked.AddDynamic(this, &UTimeTestWidget::OnNowCancelButtonClicked); + + Button_Ticktok->OnClicked.AddDynamic(this, &UTimeTestWidget::OnTicktokButtonClicked); + Button_Ticktok_Cancel->OnClicked.AddDynamic(this, &UTimeTestWidget::OnTicktokCancelButtonClicked); + + Button_Watch->OnClicked.AddDynamic(this, &UTimeTestWidget::OnWatchButtonClicked); + Button_Watch_Send->OnClicked.AddDynamic(this, &UTimeTestWidget::OnWatchSendButtonClicked); + Button_Watch_Cancel->OnClicked.AddDynamic(this, &UTimeTestWidget::OnWatchCancelButtonClicked); + + FString timeServiceEndPoint = UTurboLinkGrpcUtilities::GetTurboLinkGrpcConfig()->GetServiceEndPoint(TEXT("TimeService")); + TimeServiceAddress->SetText(FText::FromString(*timeServiceEndPoint)); + TimeServiceAddress->SetIsReadOnly(true); + + UpdateControlState(); +} + +void UTimeTestWidget::UpdateControlState() +{ + bool serviceConnected = (TimeService!=nullptr && (TimeService->GetServiceState()==EGrpcServiceState::Ready || TimeService->GetServiceState() == EGrpcServiceState::Idle)); + bool clientCreated = (TimeServiceClient != nullptr); + + Button_ConnectTimeService->SetIsEnabled(TimeService == nullptr); + Button_ShutdownTimeService->SetIsEnabled(serviceConnected || (TimeService != nullptr && TimeService->GetServiceState() == EGrpcServiceState::TransientFailure)); + + Button_CreateTimeClient->SetIsEnabled(serviceConnected && !clientCreated); + Button_ShutdownTimeClient->SetIsEnabled(clientCreated); + + Button_Now->SetIsEnabled(serviceConnected && clientCreated && TimeServiceClient->GetContextState(CtxNow) == EGrpcContextState::Done); + Button_Now_Cancel->SetIsEnabled(serviceConnected && clientCreated&& (TimeServiceClient->GetContextState(CtxNow) == EGrpcContextState::Initialing || TimeServiceClient->GetContextState(CtxNow) == EGrpcContextState::Busy)); + + Button_Ticktok->SetIsEnabled(serviceConnected && clientCreated && TimeServiceClient->GetContextState(CtxTicktok) == EGrpcContextState::Done); + Button_Ticktok_Cancel->SetIsEnabled(serviceConnected && clientCreated && (TimeServiceClient->GetContextState(CtxTicktok) == EGrpcContextState::Initialing || TimeServiceClient->GetContextState(CtxTicktok) == EGrpcContextState::Busy)); + + Button_Watch->SetIsEnabled(serviceConnected && clientCreated && TimeServiceClient->GetContextState(CtxWatch) == EGrpcContextState::Done); + Button_Watch_Send->SetIsEnabled(serviceConnected && clientCreated && TimeServiceClient->GetContextState(CtxWatch) == EGrpcContextState::Busy); + Button_Watch_Cancel->SetIsEnabled(serviceConnected && clientCreated && (TimeServiceClient->GetContextState(CtxWatch) == EGrpcContextState::Initialing || TimeServiceClient->GetContextState(CtxWatch) == EGrpcContextState::Busy)); +} + +void UTimeTestWidget::OnConnectServiceButtonClicked() +{ + if (TimeService != nullptr) return; + UTurboLinkGrpcManager* turboLinkManager = UTurboLinkGrpcUtilities::GetTurboLinkGrpcManager(); + + //create service adapter + TimeService = Cast(turboLinkManager->MakeService("TimeService")); + if (TimeService==nullptr) + { + UE_LOG(LogTemp, Error, TEXT("Can't find time service!")); + return; + } + TimeService->OnServiceStateChanged.AddUniqueDynamic(this, &UTimeTestWidget::OnTimeServiceStateChanged); + TimeService->Connect(); + + UpdateControlState(); +} + +void UTimeTestWidget::OnShutdownServiceButtonClicked() +{ + if (TimeService != nullptr) + { + if (TimeServiceClient!=nullptr) + { + TimeServiceClient->Shutdown(); + TimeServiceClient = nullptr; + } + + TimeService->Shutdown(); + TimeService = nullptr; + + UpdateControlState(); + } +} + +void UTimeTestWidget::OnCreateClientButtonClicked() +{ + if (TimeService != nullptr && TimeService->GetServiceState() == EGrpcServiceState::Ready) + { + if (TimeServiceClient != nullptr) return; + + //create client + TimeServiceClient = TimeService->MakeClient(); + TimeServiceClient->OnContextStateChange.AddUniqueDynamic(this, &UTimeTestWidget::OnContextStateChange); + TimeServiceClient->OnNowResponse.AddUniqueDynamic(this, &UTimeTestWidget::OnTimeNowResponse); + TimeServiceClient->OnTicktokResponse.AddUniqueDynamic(this, &UTimeTestWidget::OnTimeTicktokResponse); + TimeServiceClient->OnWatchResponse.AddUniqueDynamic(this, &UTimeTestWidget::OnTimeWatchResponse); + + UpdateControlState(); + } +} + +void UTimeTestWidget::OnShutdownClientButtonClicked() +{ + if (TimeServiceClient != nullptr) + { + TimeServiceClient->Shutdown(); + TimeServiceClient = nullptr; + + UpdateControlState(); + } +} + +void UTimeTestWidget::OnTimeServiceStateChanged(EGrpcServiceState NewState) +{ + int preFixLen = FString(TEXT("EGrpcServiceState::")).Len(); + TimeServiceStatus->SetText(FText::FromString(UEnum::GetValueAsString(NewState).RightChop(preFixLen))); + + UpdateControlState(); +} + +void UTimeTestWidget::OnContextStateChange(FGrpcContextHandle Handle, EGrpcContextState State) +{ + UpdateControlState(); +} + +void UTimeTestWidget::OnNowButtonClicked() +{ + if (TimeService == nullptr || + (TimeService->GetServiceState() != EGrpcServiceState::Ready && TimeService->GetServiceState()!= EGrpcServiceState::Idle) || + TimeServiceClient==nullptr) + { + UE_LOG(LogTemp, Warning, TEXT("Connect to time service first!")); + return; + } + + if (TimeServiceClient->GetContextState(CtxNow) != EGrpcContextState::Done) + { + UE_LOG(LogTemp, Warning, TEXT("Busy!")); + return; + } + + CtxNow = TimeServiceClient->InitNow(); + TimeServiceClient->Now(CtxNow, {}); +} + +void UTimeTestWidget::OnNowCancelButtonClicked() +{ + if (TimeServiceClient && TimeServiceClient->GetContextState(CtxNow) != EGrpcContextState::Done) + { + TimeServiceClient->TryCancelContext(CtxNow); + } +} + +void UTimeTestWidget::OnTimeNowResponse(FGrpcContextHandle Handle, const FGrpcResult& Result, const FGrpcGreeterNowResponse& Response) +{ + if (Result.Code == EGrpcResultCode::Ok) + { + FString value = FString::Printf(TEXT("%lld"), Response.Now); + TextResultNow->SetText(FText::FromString(value)); + } + else + { + TextResultNow->SetText(FText::FromString(Result.GetCodeString())); + } +} + +void UTimeTestWidget::OnTicktokButtonClicked() +{ + if (TimeService == nullptr || + (TimeService->GetServiceState() != EGrpcServiceState::Ready && TimeService->GetServiceState() != EGrpcServiceState::Idle) || + TimeServiceClient == nullptr) + { + UE_LOG(LogTemp, Warning, TEXT("Connect to time service first!")); + return; + } + + if (TimeServiceClient->GetContextState(CtxTicktok) != EGrpcContextState::Done) + { + UE_LOG(LogTemp, Warning, TEXT("Busy!")); + return; + } + + CtxTicktok = TimeServiceClient->InitTicktok(); + + FGrpcGreeterTicktokRequest request; + request.Counts = FCString::Atoi(*(TicktokCounts->GetText().ToString())); + TimeServiceClient->Ticktok(CtxTicktok, request); +} + +void UTimeTestWidget::OnTimeTicktokResponse(FGrpcContextHandle Handle, const FGrpcResult& Result, const FGrpcGreeterNowResponse& Response) +{ + if (Result.Code == EGrpcResultCode::Ok) + { + FString value = FString::Printf(TEXT("%lld/%d"), Response.Now, Response.Counts); + TextResultTicktok->SetText(FText::FromString(value)); + } + else + { + TextResultTicktok->SetText(FText::FromString(Result.GetCodeString())); + } +} + +void UTimeTestWidget::OnTicktokCancelButtonClicked() +{ + if (TimeServiceClient && TimeServiceClient->GetContextState(CtxTicktok) != EGrpcContextState::Done) + { + TimeServiceClient->TryCancelContext(CtxTicktok); + } +} + +void UTimeTestWidget::OnWatchButtonClicked() +{ + if (TimeService == nullptr || + (TimeService->GetServiceState() != EGrpcServiceState::Ready && TimeService->GetServiceState() != EGrpcServiceState::Idle) || + TimeServiceClient == nullptr) + { + UE_LOG(LogTemp, Warning, TEXT("Connect to time service first!")); + return; + } + + if (TimeServiceClient->GetContextState(CtxWatch) != EGrpcContextState::Done) + { + UE_LOG(LogTemp, Warning, TEXT("Busy!")); + return; + } + + CtxWatch = TimeServiceClient->InitWatch(); +} + +void UTimeTestWidget::OnWatchSendButtonClicked() +{ + if (TimeServiceClient && TimeServiceClient->GetContextState(CtxWatch) == EGrpcContextState::Busy) + { + TimeServiceClient->Watch(CtxWatch, {}); + } +} + +void UTimeTestWidget::OnWatchCancelButtonClicked() +{ + if (TimeServiceClient && TimeServiceClient->GetContextState(CtxWatch) != EGrpcContextState::Done) + { + TimeServiceClient->TryCancel(CtxWatch); + } +} + +void UTimeTestWidget::OnTimeWatchResponse(FGrpcContextHandle Handle, const FGrpcResult& Result, const FGrpcGreeterNowResponse& Response) +{ + if (Result.Code == EGrpcResultCode::Ok) + { + FString value = FString::Printf(TEXT("%lld"), Response.Now); + TextResultWatch->SetText(FText::FromString(value)); + } + else + { + TextResultWatch->SetText(FText::FromString(Result.GetCodeString())); + } +} diff --git a/Client/Source/TurboLinkTest/TimeTestWidget.h b/Client/Source/TurboLinkTest/TimeTestWidget.h new file mode 100644 index 0000000..a224cb9 --- /dev/null +++ b/Client/Source/TurboLinkTest/TimeTestWidget.h @@ -0,0 +1,141 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "Blueprint/UserWidget.h" +#include "SGreeter/GreeterService.h" +#include "TimeTestWidget.generated.h" + +/** + * + */ +UCLASS() +class TURBOLINKTEST_API UTimeTestWidget : public UUserWidget +{ + GENERATED_BODY() + +public: + virtual void NativeConstruct() override; + +protected: + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UEditableText* TimeServiceAddress; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UTextBlock* TimeServiceStatus; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UButton* Button_ConnectTimeService; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UButton* Button_ShutdownTimeService; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UButton* Button_CreateTimeClient; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UButton* Button_ShutdownTimeClient; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UButton* Button_Now; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UTextBlock* TextResultNow; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UButton* Button_Now_Cancel; + + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UButton* Button_Ticktok; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UEditableText* TicktokCounts; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UTextBlock* TextResultTicktok; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UButton* Button_Ticktok_Cancel; + + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UButton* Button_Watch; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UButton* Button_Watch_Send; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UTextBlock* TextResultWatch; + + UPROPERTY(BlueprintReadOnly, meta = (BindWidget)) + class UButton* Button_Watch_Cancel; + +protected: + UPROPERTY(BlueprintReadOnly) + UTimeService* TimeService; + + UPROPERTY(BlueprintReadOnly) + UTimeServiceClient* TimeServiceClient; + + FGrpcContextHandle CtxNow; + + UFUNCTION() + void OnTimeNowResponse(FGrpcContextHandle Handle, const FGrpcResult& Result, const FGrpcGreeterNowResponse& Response); + + FGrpcContextHandle CtxTicktok; + + UFUNCTION() + void OnTimeTicktokResponse(FGrpcContextHandle Handle, const FGrpcResult& Result, const FGrpcGreeterNowResponse& Response); + + FGrpcContextHandle CtxWatch; + + UFUNCTION() + void OnTimeWatchResponse(FGrpcContextHandle Handle, const FGrpcResult& Result, const FGrpcGreeterNowResponse& Response); + +protected: + UFUNCTION() + void OnTimeServiceStateChanged(EGrpcServiceState NewState); + + UFUNCTION() + void OnContextStateChange(FGrpcContextHandle Handle, EGrpcContextState State); + + + UFUNCTION() + void OnConnectServiceButtonClicked(); + + UFUNCTION() + void OnShutdownServiceButtonClicked(); + + UFUNCTION() + void OnCreateClientButtonClicked(); + + UFUNCTION() + void OnShutdownClientButtonClicked(); + + + UFUNCTION() + void OnNowButtonClicked(); + + UFUNCTION() + void OnNowCancelButtonClicked(); + + UFUNCTION() + void OnTicktokButtonClicked(); + + UFUNCTION() + void OnTicktokCancelButtonClicked(); + + UFUNCTION() + void OnWatchButtonClicked(); + + UFUNCTION() + void OnWatchSendButtonClicked(); + + UFUNCTION() + void OnWatchCancelButtonClicked(); + +protected: + void UpdateControlState(); +}; diff --git a/Client/Source/TurboLinkTest/TurboLinkTest.Build.cs b/Client/Source/TurboLinkTest/TurboLinkTest.Build.cs new file mode 100644 index 0000000..8e760de --- /dev/null +++ b/Client/Source/TurboLinkTest/TurboLinkTest.Build.cs @@ -0,0 +1,30 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +using UnrealBuildTool; + +public class TurboLinkTest : ModuleRules +{ + public TurboLinkTest(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; + + PublicDependencyModuleNames.AddRange(new string[] { + "Core", + "CoreUObject", + "Engine", + "InputCore" + }); + + PrivateDependencyModuleNames.AddRange(new string[] { + "TurboLinkGrpc" + }); + + // Uncomment if you are using Slate UI + // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" }); + + // Uncomment if you are using online features + // PrivateDependencyModuleNames.Add("OnlineSubsystem"); + + // To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true + } +} diff --git a/Client/Source/TurboLinkTest/TurboLinkTest.cpp b/Client/Source/TurboLinkTest/TurboLinkTest.cpp new file mode 100644 index 0000000..33be864 --- /dev/null +++ b/Client/Source/TurboLinkTest/TurboLinkTest.cpp @@ -0,0 +1,6 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include "TurboLinkTest.h" +#include "Modules/ModuleManager.h" + +IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, TurboLinkTest, "TurboLinkTest" ); diff --git a/Client/Source/TurboLinkTest/TurboLinkTest.h b/Client/Source/TurboLinkTest/TurboLinkTest.h new file mode 100644 index 0000000..677c8e2 --- /dev/null +++ b/Client/Source/TurboLinkTest/TurboLinkTest.h @@ -0,0 +1,6 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" + diff --git a/Client/Source/TurboLinkTest/TurboLinkTestController.cpp b/Client/Source/TurboLinkTest/TurboLinkTestController.cpp new file mode 100644 index 0000000..b94dc96 --- /dev/null +++ b/Client/Source/TurboLinkTest/TurboLinkTestController.cpp @@ -0,0 +1,304 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "TurboLinkTestController.h" +#include "TurboLinkGrpcManager.h" +#include "TurboLinkGrpcUtilities.h" +#include "TimeTestDSWidget.h" + +#include "Net/UnrealNetwork.h" +#include "Components/TextBlock.h" + +void ATurboLinkTestController::GetLifetimeReplicatedProps(TArray & OutLifetimeProps) const +{ + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + + //Replicate current health. + DOREPLIFETIME(ATurboLinkTestController, TimeServiceState); + DOREPLIFETIME(ATurboLinkTestController, bIsClientCreated); + + DOREPLIFETIME(ATurboLinkTestController, CtxNowState); + DOREPLIFETIME(ATurboLinkTestController, NowResult); + + DOREPLIFETIME(ATurboLinkTestController, CtxTicktokState); + DOREPLIFETIME(ATurboLinkTestController, TicktokResult); + + DOREPLIFETIME(ATurboLinkTestController, CtxWatchState); + DOREPLIFETIME(ATurboLinkTestController, WatchResult); +} + +void ATurboLinkTestController::ConnectToTimeService_Implementation() +{ + if (TimeService != nullptr) return; + UTurboLinkGrpcManager* turboLinkManager = UTurboLinkGrpcUtilities::GetTurboLinkGrpcManager(); + + //create service adapter + TimeService = Cast(turboLinkManager->MakeService("TimeService")); + if (TimeService == nullptr) + { + UE_LOG(LogTemp, Error, TEXT("Can't find time service!")); + return; + } + TimeService->OnServiceStateChanged.AddUniqueDynamic(this, &ATurboLinkTestController::OnTimeServiceStateChanged); + + UE_LOG(LogTemp, Warning, TEXT("[DS]Connect to time service")); + TimeService->Connect(); +} + +void ATurboLinkTestController::ShutdownTimeService_Implementation() +{ + if (TimeService != nullptr) + { + if (TimeServiceClient != nullptr) + { + TimeServiceClient->Shutdown(); + TimeServiceClient = nullptr; + } + + TimeService->Shutdown(); + TimeService = nullptr; + + bIsClientCreated = false; + TimeServiceState = EGrpcServiceState::Shutdown; + } +} + +void ATurboLinkTestController::CreateTimeClient_Implementation() +{ + if (TimeService != nullptr && TimeService->GetServiceState() == EGrpcServiceState::Ready) + { + if (TimeServiceClient != nullptr) return; + + //create client + TimeServiceClient = TimeService->MakeClient(); + TimeServiceClient->OnContextStateChange.AddUniqueDynamic(this, &ATurboLinkTestController::OnContextStateChange); + TimeServiceClient->OnNowResponse.AddUniqueDynamic(this, &ATurboLinkTestController::OnTimeNowResponse); + TimeServiceClient->OnTicktokResponse.AddUniqueDynamic(this, &ATurboLinkTestController::OnTimeTicktokResponse); + TimeServiceClient->OnWatchResponse.AddUniqueDynamic(this, &ATurboLinkTestController::OnTimeWatchResponse); + + bIsClientCreated = true; + } +} + +void ATurboLinkTestController::ShutdownTimeClient_Implementation() +{ + if (TimeServiceClient != nullptr) + { + TimeServiceClient->Shutdown(); + TimeServiceClient = nullptr; + + bIsClientCreated = false; + } +} + +void ATurboLinkTestController::OnTimeServiceStateChanged(EGrpcServiceState NewState) +{ + TimeServiceState = NewState; +} + +void ATurboLinkTestController::OnRep_TimeServiceState() +{ + int preFixLen = FString(TEXT("EGrpcServiceState::")).Len(); + FString timeServiceStateString = UEnum::GetValueAsString(TimeServiceState).RightChop(preFixLen); + + UE_LOG(LogTemp, Warning, TEXT("[Client]Time service state:%s"), *timeServiceStateString); + if (ClientWidget && ClientWidget->TimeServiceStatus) + { + ClientWidget->TimeServiceStatus->SetText(FText::FromString(timeServiceStateString)); + ClientWidget->UpdateControlState(); + } +} + +void ATurboLinkTestController::OnRep_ClientCreated() +{ + if (ClientWidget) + { + ClientWidget->UpdateControlState(); + } +} + +void ATurboLinkTestController::CallTimeNow_Implementation() +{ + if (TimeService == nullptr || + (TimeService->GetServiceState() != EGrpcServiceState::Ready && TimeService->GetServiceState() != EGrpcServiceState::Idle) || + TimeServiceClient == nullptr) + { + UE_LOG(LogTemp, Error, TEXT("[DS]Connect to time service first!")); + return; + } + + if (TimeServiceClient->GetContextState(CtxNow) != EGrpcContextState::Done) + { + UE_LOG(LogTemp, Error, TEXT("[DS] Busy!")); + return; + } + + UE_LOG(LogTemp, Warning, TEXT("[DS] Call Time Now!")); + CtxNow = TimeServiceClient->InitNow(); + TimeServiceClient->Now(CtxNow, {}); +} + +void ATurboLinkTestController::CancelTimeNow_Implementation() +{ + if (TimeServiceClient && TimeServiceClient->GetContextState(CtxNow) != EGrpcContextState::Done) + { + UE_LOG(LogTemp, Warning, TEXT("[DS] Cancel Time Now!")); + TimeServiceClient->TryCancelContext(CtxNow); + } +} + +void ATurboLinkTestController::CallTimeTicktok_Implementation(int32 Counts) +{ + if (TimeService == nullptr || + (TimeService->GetServiceState() != EGrpcServiceState::Ready && TimeService->GetServiceState() != EGrpcServiceState::Idle) || + TimeServiceClient == nullptr) + { + UE_LOG(LogTemp, Error, TEXT("[DS]Connect to time service first!")); + return; + } + + if (TimeServiceClient->GetContextState(CtxTicktok) != EGrpcContextState::Done) + { + UE_LOG(LogTemp, Error, TEXT("[DS] Busy!")); + return; + } + + UE_LOG(LogTemp, Warning, TEXT("[DS] Call Time Clock(%d)!"), Counts); + + CtxTicktok = TimeServiceClient->InitTicktok(); + + FGrpcGreeterTicktokRequest request; + request.Counts = Counts; + TimeServiceClient->Ticktok(CtxTicktok, request); +} + +void ATurboLinkTestController::CancelTimeTicktok_Implementation() +{ + if (TimeServiceClient && TimeServiceClient->GetContextState(CtxTicktok) != EGrpcContextState::Done) + { + UE_LOG(LogTemp, Warning, TEXT("[DS] Cancel Time Clock!")); + TimeServiceClient->TryCancelContext(CtxTicktok); + } +} + +void ATurboLinkTestController::InitTimeWatch_Implementation() +{ + if (TimeService == nullptr || + (TimeService->GetServiceState() != EGrpcServiceState::Ready && TimeService->GetServiceState() != EGrpcServiceState::Idle) || + TimeServiceClient == nullptr) + { + UE_LOG(LogTemp, Error, TEXT("[DS]Connect to time service first!")); + return; + } + + if (TimeServiceClient->GetContextState(CtxWatch) != EGrpcContextState::Done) + { + UE_LOG(LogTemp, Error, TEXT("[DS] Busy!")); + return; + } + + UE_LOG(LogTemp, Warning, TEXT("[DS] Init Time Watch!")); + CtxWatch = TimeServiceClient->InitWatch(); +} + +void ATurboLinkTestController::CallTimeWatch_Implementation() +{ + if (TimeServiceClient && TimeServiceClient->GetContextState(CtxWatch) == EGrpcContextState::Busy) + { + UE_LOG(LogTemp, Warning, TEXT("[DS] Send Time Watch!")); + TimeServiceClient->Watch(CtxWatch, {}); + } +} + +void ATurboLinkTestController::CancelTimeWatch_Implementation() +{ + if (TimeServiceClient && TimeServiceClient->GetContextState(CtxWatch) != EGrpcContextState::Done) + { + UE_LOG(LogTemp, Warning, TEXT("[DS] Cancel Time Watch!")); + TimeServiceClient->TryCancel(CtxWatch); + } +} + +void ATurboLinkTestController::OnContextStateChange(FGrpcContextHandle Handle, EGrpcContextState State) +{ + CtxNowState = TimeServiceClient->GetContextState(CtxNow); + CtxTicktokState = TimeServiceClient->GetContextState(CtxTicktok); + CtxWatchState = TimeServiceClient->GetContextState(CtxWatch); +} + +void ATurboLinkTestController::OnRep_TimeContextState() +{ + if (ClientWidget) + { + ClientWidget->UpdateControlState(); + } +} + +void ATurboLinkTestController::OnTimeNowResponse(FGrpcContextHandle Handle, const FGrpcResult& Result, const FGrpcGreeterNowResponse& Response) +{ + if (Result.Code == EGrpcResultCode::Ok) + { + NowResult = FString::Printf(TEXT("%lld"), Response.Now); + } + else + { + NowResult = Result.GetCodeString(); + } + + UE_LOG(LogTemp, Warning, TEXT("[DS] On Time Now Response: %s"), *NowResult); +} + +void ATurboLinkTestController::OnRep_TimeNowResult() +{ + if (ClientWidget && ClientWidget->TextResultNow) + { + ClientWidget->TextResultNow->SetText(FText::FromString(NowResult)); + ClientWidget->UpdateControlState(); + } +} + +void ATurboLinkTestController::OnTimeTicktokResponse(FGrpcContextHandle Handle, const FGrpcResult& Result, const FGrpcGreeterNowResponse& Response) +{ + if (Result.Code == EGrpcResultCode::Ok) + { + TicktokResult = FString::Printf(TEXT("%lld/%d"), Response.Now, Response.Counts); + } + else + { + TicktokResult = Result.GetCodeString(); + } + + UE_LOG(LogTemp, Warning, TEXT("[DS] On Time Clock Response: %s"), *TicktokResult); +} + +void ATurboLinkTestController::OnRep_TimeTicktokResult() +{ + if (ClientWidget && ClientWidget->TextResultTicktok) + { + ClientWidget->TextResultTicktok->SetText(FText::FromString(TicktokResult)); + ClientWidget->UpdateControlState(); + } +} + +void ATurboLinkTestController::OnTimeWatchResponse(FGrpcContextHandle Handle, const FGrpcResult& Result, const FGrpcGreeterNowResponse& Response) +{ + if (Result.Code == EGrpcResultCode::Ok) + { + WatchResult = FString::Printf(TEXT("%lld"), Response.Now); + } + else + { + WatchResult = Result.GetCodeString(); + } + + UE_LOG(LogTemp, Warning, TEXT("[DS] On Time Watch Response: %s"), *WatchResult); +} + +void ATurboLinkTestController::OnRep_TimeWatchResult() +{ + if (ClientWidget && ClientWidget->TextResultWatch) + { + ClientWidget->TextResultWatch->SetText(FText::FromString(WatchResult)); + ClientWidget->UpdateControlState(); + } +} diff --git a/Client/Source/TurboLinkTest/TurboLinkTestController.h b/Client/Source/TurboLinkTest/TurboLinkTestController.h new file mode 100644 index 0000000..3836e47 --- /dev/null +++ b/Client/Source/TurboLinkTest/TurboLinkTestController.h @@ -0,0 +1,149 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "GameFramework/PlayerController.h" +#include "SGreeter/GreeterService.h" +#include "TurboLinkTestController.generated.h" + +class UTimeTestDSWidget; +/** + * + */ +UCLASS() +class TURBOLINKTEST_API ATurboLinkTestController : public APlayerController +{ + GENERATED_BODY() + +public: + UFUNCTION(BlueprintCallable, Server, Reliable) + void ConnectToTimeService(); + + UFUNCTION(BlueprintCallable, Server, Reliable) + void ShutdownTimeService(); + + UFUNCTION(BlueprintCallable, Server, Reliable) + void CreateTimeClient(); + + UFUNCTION(BlueprintCallable, Server, Reliable) + void ShutdownTimeClient(); + + + UFUNCTION(BlueprintCallable, Server, Reliable) + void CallTimeNow(); + + UFUNCTION(BlueprintCallable, Server, Reliable) + void CancelTimeNow(); + + UFUNCTION(BlueprintCallable, Server, Reliable) + void CallTimeTicktok(int32 Counts); + + UFUNCTION(BlueprintCallable, Server, Reliable) + void CancelTimeTicktok(); + + UFUNCTION(BlueprintCallable, Server, Reliable) + void InitTimeWatch(); + + UFUNCTION(BlueprintCallable, Server, Reliable) + void CallTimeWatch(); + + UFUNCTION(BlueprintCallable, Server, Reliable) + void CancelTimeWatch(); + +protected: + UPROPERTY(BlueprintReadOnly) + UTimeService* TimeService; + + UFUNCTION() + void OnTimeServiceStateChanged(EGrpcServiceState NewState); + + UPROPERTY(BlueprintReadOnly) + UTimeServiceClient* TimeServiceClient; + + UFUNCTION() + void OnContextStateChange(FGrpcContextHandle Handle, EGrpcContextState State); + + FGrpcContextHandle CtxNow; + + UFUNCTION() + void OnTimeNowResponse(FGrpcContextHandle Handle, const FGrpcResult& Result, const FGrpcGreeterNowResponse& Response); + + FGrpcContextHandle CtxTicktok; + + UFUNCTION() + void OnTimeTicktokResponse(FGrpcContextHandle Handle, const FGrpcResult& Result, const FGrpcGreeterNowResponse& Response); + + FGrpcContextHandle CtxWatch; + + UFUNCTION() + void OnTimeWatchResponse(FGrpcContextHandle Handle, const FGrpcResult& Result, const FGrpcGreeterNowResponse& Response); + +public: + EGrpcServiceState GetTimeServiceState() const { + return TimeServiceState; + } + + bool IsClientCreated() const { + return bIsClientCreated; + } + + EGrpcContextState GetCtxNowState() const { + return CtxNowState; + } + + EGrpcContextState GetCtxTicktokState() const { + return CtxTicktokState; + } + + EGrpcContextState GetCtxWatchState() const { + return CtxWatchState; + } + + UPROPERTY(BlueprintReadOnly) + UTimeTestDSWidget* ClientWidget; + +protected: + UPROPERTY(ReplicatedUsing = OnRep_TimeServiceState) + EGrpcServiceState TimeServiceState; + + UFUNCTION() + void OnRep_TimeServiceState(); + + UPROPERTY(ReplicatedUsing = OnRep_ClientCreated) + bool bIsClientCreated = false; + + UFUNCTION() + void OnRep_ClientCreated(); + +protected: + UFUNCTION() + void OnRep_TimeContextState(); + + UPROPERTY(ReplicatedUsing = OnRep_TimeContextState) + EGrpcContextState CtxNowState = EGrpcContextState::Done; + + UPROPERTY(ReplicatedUsing = OnRep_TimeContextState) + EGrpcContextState CtxTicktokState = EGrpcContextState::Done; + + UPROPERTY(ReplicatedUsing = OnRep_TimeContextState) + EGrpcContextState CtxWatchState = EGrpcContextState::Done; + + UPROPERTY(ReplicatedUsing = OnRep_TimeNowResult) + FString NowResult; + + UFUNCTION() + void OnRep_TimeNowResult(); + + UPROPERTY(ReplicatedUsing = OnRep_TimeTicktokResult) + FString TicktokResult; + + UFUNCTION() + void OnRep_TimeTicktokResult(); + + UPROPERTY(ReplicatedUsing = OnRep_TimeWatchResult) + FString WatchResult; + + UFUNCTION() + void OnRep_TimeWatchResult(); +}; diff --git a/Client/Source/TurboLinkTest/TurboLinkTestGameInstance.cpp b/Client/Source/TurboLinkTest/TurboLinkTestGameInstance.cpp new file mode 100644 index 0000000..ef57122 --- /dev/null +++ b/Client/Source/TurboLinkTest/TurboLinkTestGameInstance.cpp @@ -0,0 +1,21 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "TurboLinkTestGameInstance.h" +#include "TurboLinkGrpcManager.h" +#include "TurboLinkGrpcUtilities.h" + +void UTurboLinkTestGameInstance::Init() +{ + Super::Init(); + + TurboLinkManager = UTurboLinkGrpcUtilities::GetTurboLinkGrpcManager(); + TurboLinkManager->InitManager(); +} + +void UTurboLinkTestGameInstance::Shutdown() +{ + // Unregister ticker delegate + TurboLinkManager->Shutdown(); + TurboLinkManager = nullptr; +} diff --git a/Client/Source/TurboLinkTest/TurboLinkTestGameInstance.h b/Client/Source/TurboLinkTest/TurboLinkTestGameInstance.h new file mode 100644 index 0000000..48798f5 --- /dev/null +++ b/Client/Source/TurboLinkTest/TurboLinkTestGameInstance.h @@ -0,0 +1,25 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "Engine/GameInstance.h" +#include "TurboLinkTestGameInstance.generated.h" + +class UTurboLinkGrpcManager; +/** + * + */ +UCLASS() +class TURBOLINKTEST_API UTurboLinkTestGameInstance : public UGameInstance +{ + GENERATED_BODY() + +public: + void Init() override; + void Shutdown() override; + +protected: + UPROPERTY() + UTurboLinkGrpcManager* TurboLinkManager; +}; diff --git a/Client/Source/TurboLinkTest/TurboLinkTestGameModeBase.cpp b/Client/Source/TurboLinkTest/TurboLinkTestGameModeBase.cpp new file mode 100644 index 0000000..769d8f1 --- /dev/null +++ b/Client/Source/TurboLinkTest/TurboLinkTestGameModeBase.cpp @@ -0,0 +1,5 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + + +#include "TurboLinkTestGameModeBase.h" + diff --git a/Client/Source/TurboLinkTest/TurboLinkTestGameModeBase.h b/Client/Source/TurboLinkTest/TurboLinkTestGameModeBase.h new file mode 100644 index 0000000..69ab914 --- /dev/null +++ b/Client/Source/TurboLinkTest/TurboLinkTestGameModeBase.h @@ -0,0 +1,17 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "GameFramework/GameModeBase.h" +#include "TurboLinkTestGameModeBase.generated.h" + +/** + * + */ +UCLASS() +class TURBOLINKTEST_API ATurboLinkTestGameModeBase : public AGameModeBase +{ + GENERATED_BODY() + +}; diff --git a/Client/Source/TurboLinkTest/TurboLinkTestPawn.cpp b/Client/Source/TurboLinkTest/TurboLinkTestPawn.cpp new file mode 100644 index 0000000..48629bd --- /dev/null +++ b/Client/Source/TurboLinkTest/TurboLinkTestPawn.cpp @@ -0,0 +1,34 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "TurboLinkTestPawn.h" + +// Sets default values +ATurboLinkTestPawn::ATurboLinkTestPawn() +{ + // Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it. + PrimaryActorTick.bCanEverTick = true; + +} + +// Called when the game starts or when spawned +void ATurboLinkTestPawn::BeginPlay() +{ + Super::BeginPlay(); + +} + +// Called every frame +void ATurboLinkTestPawn::Tick(float DeltaTime) +{ + Super::Tick(DeltaTime); + +} + +// Called to bind functionality to input +void ATurboLinkTestPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) +{ + Super::SetupPlayerInputComponent(PlayerInputComponent); + +} + diff --git a/Client/Source/TurboLinkTest/TurboLinkTestPawn.h b/Client/Source/TurboLinkTest/TurboLinkTestPawn.h new file mode 100644 index 0000000..da51f89 --- /dev/null +++ b/Client/Source/TurboLinkTest/TurboLinkTestPawn.h @@ -0,0 +1,29 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "GameFramework/Pawn.h" +#include "TurboLinkTestPawn.generated.h" + +UCLASS() +class TURBOLINKTEST_API ATurboLinkTestPawn : public APawn +{ + GENERATED_BODY() + +public: + // Sets default values for this pawn's properties + ATurboLinkTestPawn(); + +protected: + // Called when the game starts or when spawned + virtual void BeginPlay() override; + +public: + // Called every frame + virtual void Tick(float DeltaTime) override; + + // Called to bind functionality to input + virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override; + +}; diff --git a/Client/Source/TurboLinkTestEditor.Target.cs b/Client/Source/TurboLinkTestEditor.Target.cs new file mode 100644 index 0000000..1ad2e23 --- /dev/null +++ b/Client/Source/TurboLinkTestEditor.Target.cs @@ -0,0 +1,14 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +using UnrealBuildTool; +using System.Collections.Generic; + +public class TurboLinkTestEditorTarget : TargetRules +{ + public TurboLinkTestEditorTarget( TargetInfo Target) : base(Target) + { + Type = TargetType.Editor; + DefaultBuildSettings = BuildSettingsVersion.V2; + ExtraModuleNames.AddRange( new string[] { "TurboLinkTest" } ); + } +} diff --git a/Client/Source/TurboLinkTestServer.Target.cs b/Client/Source/TurboLinkTestServer.Target.cs new file mode 100644 index 0000000..e4b5713 --- /dev/null +++ b/Client/Source/TurboLinkTestServer.Target.cs @@ -0,0 +1,21 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +using UnrealBuildTool; +using System.Collections.Generic; + +[SupportedPlatforms(UnrealPlatformClass.Server)] +public class TurboLinkTestServerTarget : TargetRules +{ + public TurboLinkTestServerTarget( TargetInfo Target) : base(Target) + { + Type = TargetType.Server; + + ExtraModuleNames.AddRange( new string[] { "TurboLinkTest" } ); + + //These configurations are invalid for a Linux server build. + DisablePlugins.Add("WMFMediaPlayer"); + DisablePlugins.Add("AsyncLoadingScreen"); //if you are using this plugin + DisablePlugins.Add("WindowsMoviePlayer"); + DisablePlugins.Add("MediaFoundationMediaPlayer"); + } +} diff --git a/Client/TurboLinkTest.uproject b/Client/TurboLinkTest.uproject new file mode 100644 index 0000000..be407e8 --- /dev/null +++ b/Client/TurboLinkTest.uproject @@ -0,0 +1,18 @@ +{ + "FileVersion": 3, + "EngineAssociation": "4.27", + "Category": "", + "Description": "", + "Modules": [ + { + "Name": "TurboLinkTest", + "Type": "Runtime", + "LoadingPhase": "Default", + "AdditionalDependencies": [ + "Engine", + "UMG", + "CoreUObject" + ] + } + ] +} \ No newline at end of file diff --git a/Common/certs/ca.crt b/Common/certs/ca.crt new file mode 100644 index 0000000..7b5d462 --- /dev/null +++ b/Common/certs/ca.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDaTCCAlGgAwIBAgIJALg9FEgTMGPaMA0GCSqGSIb3DQEBCwUAMEsxCzAJBgNV +BAYTAkNOMRAwDgYDVQQHDAdCZWlqaW5nMRIwEAYDVQQKDAlUdXJib0xpbmsxFjAU +BgNVBAMMDXR1cmJvbGluay5kZXYwHhcNMjIxMTMwMDI1NTE2WhcNMzIxMTI3MDI1 +NTE2WjBLMQswCQYDVQQGEwJDTjEQMA4GA1UEBwwHQmVpamluZzESMBAGA1UECgwJ +VHVyYm9MaW5rMRYwFAYDVQQDDA10dXJib2xpbmsuZGV2MIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAqLjDp7Xh4TVyMZnajYTm73U0I0k7WRkR0TqxHeyO +sUQ/yKk9Bv6XNxAEsJj7ofIwMDG7VWI6uuzCWdRD11HIf/fuEDOYqK46LFf+yQXf ++P6Y0I2t2vvMS/FntSzzkuz1veRWfFa0ssGV3Iv8jEgSvAfV1xU5rvnlULhVcevz +CMOvmesu5DSeEo9EIeugaUasiS2RR+TRJb4gflCPLZu0rL0+/mDNhsd3BXuRp/jE +h63F47/eFv3Us9jZ0D/hzmXnmJVzkVbyRwMYKZ8BnDuVhdBzT1yPjbL2A0Q9OIh6 +IuGlHnbo907ZZgheGxyqSpDq794J5lWhHn5KY/fmpMPZiwIDAQABo1AwTjAdBgNV +HQ4EFgQUeRpYmEkuEnGbhwF66uNSmjVzgRkwHwYDVR0jBBgwFoAUeRpYmEkuEnGb +hwF66uNSmjVzgRkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAeOuJ +nKz5/Ez1CiwMT4FwZoJPtjJw4ONSzbxMsekb/aubzNYY0T3w693DqZwVFmM573yq +d96ghHBfvVanPMJyHOJFRayZNgrDRKHHW75Jth03cAbQ6MahgVyys0VUrCsAFdAj +Zo2q504vVxBtq2pHzYetNDTF6SVjZp/XrMtgepggEtU6Zf1sDpk0Si694rksrO2p +3C+zkPtgVFd5cT2fihZ5imjUNqu/iRP95mjoKwtPRRGBUhJjN8UOuRyS08L/eUSf +IbN7ogcp6Y+WL6rmNvSVoXBl7wIWhGEWTscyzm66bWisZxGUFTicezL56CpkHdbo +NzR3/aU8S0eIDHSaiQ== +-----END CERTIFICATE----- diff --git a/Common/certs/ca.csr b/Common/certs/ca.csr new file mode 100644 index 0000000..8fb0f1b --- /dev/null +++ b/Common/certs/ca.csr @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICkDCCAXgCAQAwSzELMAkGA1UEBhMCQ04xEDAOBgNVBAcMB0JlaWppbmcxEjAQ +BgNVBAoMCVR1cmJvTGluazEWMBQGA1UEAwwNdHVyYm9saW5rLmRldjCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBAKi4w6e14eE1cjGZ2o2E5u91NCNJO1kZ +EdE6sR3sjrFEP8ipPQb+lzcQBLCY+6HyMDAxu1ViOrrswlnUQ9dRyH/37hAzmKiu +OixX/skF3/j+mNCNrdr7zEvxZ7Us85Ls9b3kVnxWtLLBldyL/IxIErwH1dcVOa75 +5VC4VXHr8wjDr5nrLuQ0nhKPRCHroGlGrIktkUfk0SW+IH5Qjy2btKy9Pv5gzYbH +dwV7kaf4xIetxeO/3hb91LPY2dA/4c5l55iVc5FW8kcDGCmfAZw7lYXQc09cj42y +9gNEPTiIeiLhpR526PdO2WYIXhscqkqQ6u/eCeZVoR5+SmP35qTD2YsCAwEAAaAA +MA0GCSqGSIb3DQEBCwUAA4IBAQAuyGqqQmOE/ccKoCsvF3b/GuAPWCNcfJZhK7vr +Uje970+xuXqRboFEvHuw7SifKxkoAW2d6+nlwMWsS/cLht+8Z9Sul2p5CA67LVMo +Y0FmWxO8blzeGXDg6In5s3WXNTeIKMGRfIIQwS5TdHrb2cR/y0hnfHkysfyQ4BBy +MvCWDhXMfx37ahCeGPzf0G7Gwv76ZtkGU4cbffv0AFFoaMDUVOhz5MXipDDeFfvy +gYfi0OB+V3RZlAJ9hRev+rTkn+QRKLUmV26YSIJxmBzmu2cv5A/gC2yYSipKQTIG +TdAEwqMhBUVpwjltXHqBd63O85OmQvF67jTMobgJa0HxSxUx +-----END CERTIFICATE REQUEST----- diff --git a/Common/certs/ca.key b/Common/certs/ca.key new file mode 100644 index 0000000..3d672d4 --- /dev/null +++ b/Common/certs/ca.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAqLjDp7Xh4TVyMZnajYTm73U0I0k7WRkR0TqxHeyOsUQ/yKk9 +Bv6XNxAEsJj7ofIwMDG7VWI6uuzCWdRD11HIf/fuEDOYqK46LFf+yQXf+P6Y0I2t +2vvMS/FntSzzkuz1veRWfFa0ssGV3Iv8jEgSvAfV1xU5rvnlULhVcevzCMOvmesu +5DSeEo9EIeugaUasiS2RR+TRJb4gflCPLZu0rL0+/mDNhsd3BXuRp/jEh63F47/e +Fv3Us9jZ0D/hzmXnmJVzkVbyRwMYKZ8BnDuVhdBzT1yPjbL2A0Q9OIh6IuGlHnbo +907ZZgheGxyqSpDq794J5lWhHn5KY/fmpMPZiwIDAQABAoIBAG+Cfb1wFjO0ER77 +Ilj6B28ntSfFFLZUPVRdSAYQ/FXoV4eVYsImrWY07gSRd22XFYYkuD08SLiWFfUs +txGt+aeqAusuTqzdSZFZLwlJGrgD/JeJq+fZFzLx/6rcZLcsaVXxfb97xr2F+Dfl +RSqpz8f6HbijTJZ6jraEveQnH18gczjFu5Bo5qXd+P8lLDMfegReALCGcj9GXYLR +hDd4f3HUMYLqsEPF4s5ZWZQFN0Nq1iuBTCf1G37Xixrk09PYTt5U70zE1XIAvV7I +OQLCafN9b6Ajpeu5tlwyuaICzFAm8fRQrB/Ux0qKVR/vXgwDhnvPlv2LeLLQqDaS +H4CK4DECgYEA1OVPgHh9hM8nm+pUK8f2E7e/D1/sM8nr/T9v8PDor/yUSjKpgGXP +0Uqw/3azyoGDpyZEEVfta2O4C4z403jq1S3aBbnJqCsDBKii/z2BiNtwMRuExMI/ +wTypmQrNmA5g3S6K097r8km8ZKLsagCRChnFmOtG40pJ+7RY1WTk2N8CgYEAyuHa +Gq9x4eoYnntt6/I0nFdxPlwaN1wf46rIOdmpXgPRIfS4gACN4nBtNkFOLWedCv9m +E07p/1pYzOyrAdjp8gxVYi1AOrbEX63SlD4zH9DI8pTAw+Ii0z57luZRoUwZmQyM +UhY90JKTlgVM86jNwXfcWij9bD21H3GDfUZJmNUCgYAn+PopY/YlRoPoWWH+amgA +ocJkz5zYyHPfs9Z/xavaxzDMkaCTtAoGAOEkxhPR1Ol0K9Ih84FnZWy79ncNtalZ +52cFJjH/ujux1zvrco/ss07oWYNfMh2oWYx6aLXbc++p98AnMbbZYhDWUGTVLlAN +NnOMV7iSmnMzqFP5lR0GvwKBgQCfdYBtdPP3cn1DIxQ0XLwJHZk+QDnCxT+zO2oA +PhmmcS2QmL3irYzXKzJLcGy3tzZxjGd4SZAVSbd96Y5G92x4+ESr05EmFLynzwEx +zulz2i/2qgAQdc6VZgjRg9kpA50i8//eDOks4+foA+aFpGmD5Gdm3czBpIaVXizQ +68uwuQKBgQC1GzYqpNyYT6wB5yBMQJ3qUjWumQ2r1uzhyQNgG73QZUZlo9xNJimY +4qulWv8oTT0MLzDeYTKri6kLPBuHxZpwc7wLcQegGthnBqdWCGMzOl8kmcxil0aD +NWBgtCkZMrLmg0I4YviWvCCJPtTLEn2vjINlDAuCX06YnUfoIoVMnA== +-----END RSA PRIVATE KEY----- diff --git a/Common/certs/server.crt b/Common/certs/server.crt new file mode 100644 index 0000000..ffd3508 --- /dev/null +++ b/Common/certs/server.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDZTCCAk2gAwIBAgIJAOFO3+DpMNlLMA0GCSqGSIb3DQEBCwUAMEsxCzAJBgNV +BAYTAkNOMRAwDgYDVQQHDAdCZWlqaW5nMRIwEAYDVQQKDAlUdXJib0xpbmsxFjAU +BgNVBAMMDXR1cmJvbGluay5kZXYwHhcNMjIxMjA5MTQwNjI4WhcNMzIxMjA2MTQw +NjI4WjBLMQswCQYDVQQGEwJDTjEQMA4GA1UEBwwHQmVpamluZzESMBAGA1UECgwJ +dHVyYm9saW5rMRYwFAYDVQQDDA10dXJib2xpbmsuZGV2MIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAr8vdbsXtLWOEWoygSluR3BtYJcp+1nbDwrytr7WX +XcnzSB1rQ0lt3yQmQ5BKm6CLbUeKtQd7fIUT1JRn3KJ/dSHXT4qEWWO0XJLJeoAI +FXprLWolbrBA8QCAs8Hcbm8F/efHphKU4a10HhD6ENa4YqYPnd89vfYgSPGS/UmF +ojWicWjmmT7Np5PBo81mzpbyhGTlOeZj6LLp77w8772MRBDZTn4eDXDuCdfbs2HM +YFK4OQ2QQjrh2LSCA6VQgi8gGaXtp2k8CwVlXQpOFWmYX0FyXX/4qvkvXl8rG07T +AvX7iCaG3owAYrDeQUL7NqbTvAMHiqivCwrFzThNq+XSkQIDAQABo0wwSjBIBgNV +HREEQTA/gg8qLnR1cmJvbGluay5kZXaCECoudGhlY29kZXdheS5jb22CDyoubGV5 +b3V0ZWNoLm5ldIIJbG9jYWxob3N0MA0GCSqGSIb3DQEBCwUAA4IBAQCUlziOgdSF ++GrN2PxrZmRP9bhbLEc1GAWGzStN4xsZFcPIesrDbf74tua65idKvSL4vyx6lpPb +ino6mwIgP8ZUV3jdkgKTUMzeqJJY8hoH5Sza93kOZX0oDFyuEJ7LS9kPrLIqEkdp +Myc690q5GqNLdSWZqONjAp1S3dezQoKRV/YC6PqMr+1Dq/oRIz83NYWan0vpnHFC +gRlK5Rb37ueI+Pe+d6Wg9JSwdo0mFJ5hGfT5Ler4AoA9HMss1k9lJ18iFoSyBCcn +wIg5gcxJe6P7DKXnOknt1Sa0Us/li8ux5J8bVgqImkqx2nagDugcW0BfQYcoFilH +pgulZBZZCO3S +-----END CERTIFICATE----- diff --git a/Common/certs/server.csr b/Common/certs/server.csr new file mode 100644 index 0000000..e65a1b5 --- /dev/null +++ b/Common/certs/server.csr @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIC6zCCAdMCAQAwSzELMAkGA1UEBhMCQ04xEDAOBgNVBAcMB0JlaWppbmcxEjAQ +BgNVBAoMCXR1cmJvbGluazEWMBQGA1UEAwwNdHVyYm9saW5rLmRldjCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBAK/L3W7F7S1jhFqMoEpbkdwbWCXKftZ2 +w8K8ra+1l13J80gda0NJbd8kJkOQSpugi21HirUHe3yFE9SUZ9yif3Uh10+KhFlj +tFySyXqACBV6ay1qJW6wQPEAgLPB3G5vBf3nx6YSlOGtdB4Q+hDWuGKmD53fPb32 +IEjxkv1JhaI1onFo5pk+zaeTwaPNZs6W8oRk5TnmY+iy6e+8PO+9jEQQ2U5+Hg1w +7gnX27NhzGBSuDkNkEI64di0ggOlUIIvIBml7adpPAsFZV0KThVpmF9Bcl1/+Kr5 +L15fKxtO0wL1+4gmht6MAGKw3kFC+zam07wDB4qorwsKxc04Tavl0pECAwEAAaBb +MFkGCSqGSIb3DQEJDjFMMEowSAYDVR0RBEEwP4IPKi50dXJib2xpbmsuZGV2ghAq +LnRoZWNvZGV3YXkuY29tgg8qLmxleW91dGVjaC5uZXSCCWxvY2FsaG9zdDANBgkq +hkiG9w0BAQsFAAOCAQEAF4Ed0iL0NO3rHjBDn1Nbo0HGIuUBRsEN8hgdsCybZUue +4fEoyP83Zky8r6caUdnfY6RaBCMRICroRWHK3XxbWnVjzb0Si2erIE9V61cFNzcZ +qB4d2H8jR+I+rrgRLKYMQfJ+6qA7MTSTTG1pD80VlKQdWFacoXIwXo8PfbQzbiA2 +OOJRTsw6pQdbo+l0tH4qkT1QIOD9AB54wWrP49sZ6o1ULizhnZTPd/LtwSO7REVj +xBJkAjreNLQwvv36WLDvfIQba8COZQSnuIw8TdZjCKl+kmnGpLJdGUv/GABJcGwO +U8vJG0lJoAIZs0RCX3I6s47pDW3jpdYpHP5DUjQu8Q== +-----END CERTIFICATE REQUEST----- diff --git a/Common/certs/server.key b/Common/certs/server.key new file mode 100644 index 0000000..2af98b4 --- /dev/null +++ b/Common/certs/server.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAr8vdbsXtLWOEWoygSluR3BtYJcp+1nbDwrytr7WXXcnzSB1r +Q0lt3yQmQ5BKm6CLbUeKtQd7fIUT1JRn3KJ/dSHXT4qEWWO0XJLJeoAIFXprLWol +brBA8QCAs8Hcbm8F/efHphKU4a10HhD6ENa4YqYPnd89vfYgSPGS/UmFojWicWjm +mT7Np5PBo81mzpbyhGTlOeZj6LLp77w8772MRBDZTn4eDXDuCdfbs2HMYFK4OQ2Q +Qjrh2LSCA6VQgi8gGaXtp2k8CwVlXQpOFWmYX0FyXX/4qvkvXl8rG07TAvX7iCaG +3owAYrDeQUL7NqbTvAMHiqivCwrFzThNq+XSkQIDAQABAoIBAQCqrwa0+elZi2lD +PYyYBaZuDgKc1qol8rQJTIZatrZbsqvKFf5CG3ZZFFEugldeGRemp7KuJ7Cm6tKh +MOJS31dfU9cofHYaEGtbAo4qqUqwB+ct9gSYHvs+w90yKwSqGJO5vaQjw6DYKUA3 +vQX++WuXJGK/RrQ8z07zY9HyqMLeBRcnZVvqRa/neowa3luBfl9bqbfZY4Sac1X/ +1HD2+ffE6Y3nnf3OD6PFeHfqBqIZuQebwIOj2myLSL6nyCoWJJQCinlRzOnH4Dkk +Jb6kVwmAGoB/8qD84sKa5XlW+TqiH4HpRoxiGoHj2HeawTv2QAxsVfOV/s4pmjEO +Sg710xGNAoGBANrqb8rFNiicndZX+agxCGhMvYLJqCOUC7cBEd3JOVYELiaopyTb +LdbjTR8lwXK8JyJ+lagbi+sYyIHNc7KF8xnwd5DFpLaT0DwqqENcd83dUeqadnUf +WgzHBcO030CP0JpaJEAtemK6rvq+U4xE+4XuFeXDsCOyCqA+Xw5qF3qbAoGBAM2T +f87euZmqH97kGWaUmgXQWZT3IJzIqo9/UFE5eFIDnNwjaorla9eRSM+WyPStgOhR +Q+zx/cv68vUJg08ESk5IwuEyGAdLiCW3Gsq7sIoaih18wWPor+0MQUSOtbKtnltj +HwwhpXXVUK9rEPnUsrU6Jx1T6fe4BuxTe1xcf/RDAoGAcvia28B1MCEI2BB+IrIV +u0lKYkzsTDstZ+Bc9MEApsctQcpjdfzSd0ALOeeHUG22k+wtRwuokUED1QAE2mZ1 +BVOAR/01A1pgC6lPk4kVtn2czvxuaBaeIYXI5j6w3WRqZxYeYcJAu2dWDIQ2tr1n +56/hujjq4eRYpk37eEOJry8CgYBxSQ4OXvhicLi9aG+C8vLpr0YebAzhuUccaqlF +CWl/sJP5T97/iavjECHSm6JEC3TVEStgYH5esPzAAa0FlzSnbTtPQ/6vznTJa9zs +yX9gq31fAIfF2c1Q0QcKk6YXP8vbSoUqd0Qp6hJbiKHDOu38Jn61j6+IHjZadyqs +3CB65wKBgH9PKZ2CZ86qCLwlZ3Uj/hFR9CQCsTuns/lbzjVszw057vny57kf6fma +3+a0oV4pOyEkDip46ObgBaOQDdRt0XuUpUFVNuohmpxdkf0qoqPF6paqhDA5dRvi +F90g0bTXJRO5hKpKMn7L9HAE54aXJWzFem2UgwYAfIuxyhEv6q8j +-----END RSA PRIVATE KEY----- diff --git a/Common/proto/generate-code.cmd b/Common/proto/generate-code.cmd new file mode 100644 index 0000000..0fceb56 --- /dev/null +++ b/Common/proto/generate-code.cmd @@ -0,0 +1,32 @@ +@echo off + +:: Install golang protoc plugin with follow command first +:: +:: go install google.golang.org/protobuf/cmd/protoc-gen-go@latest +:: go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest +:: + +set CURRENT_DIR=%CD% + +pushd ..\..\Client\Plugins\TurboLink +set TL_UE_PLUGIN_PATH=%CD% +popd + +set PROTOC_EXE_PATH=%TL_UE_PLUGIN_PATH%\ThirdParty\protobuf\bin\protoc.exe + +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:: generate client code +set CLIENT_OUTPUT_DIR=%CURRENT_DIR%\output\client +if not exist %CLIENT_OUTPUT_DIR% mkdir %CLIENT_OUTPUT_DIR% + +call "%TL_UE_PLUGIN_PATH%\Tools\generate_code.cmd" hello.proto Greeter %CLIENT_OUTPUT_DIR% +call "%TL_UE_PLUGIN_PATH%\Tools\generate_code.cmd" user.proto User %CLIENT_OUTPUT_DIR% + +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:: generate server code +set SERVER_OUTPUT_DIR=%CURRENT_DIR%\output\server +if not exist %SERVER_OUTPUT_DIR% mkdir %SERVER_OUTPUT_DIR% + +"%PROTOC_EXE_PATH%" --go_out="%SERVER_OUTPUT_DIR%" --go-grpc_out=%SERVER_OUTPUT_DIR% hello.proto +"%PROTOC_EXE_PATH%" --go_out="%SERVER_OUTPUT_DIR%" --go-grpc_out=%SERVER_OUTPUT_DIR% user.proto + diff --git a/Common/proto/hello.proto b/Common/proto/hello.proto new file mode 100644 index 0000000..31ea8de --- /dev/null +++ b/Common/proto/hello.proto @@ -0,0 +1,39 @@ +syntax = "proto3"; + +package Greeter; +option go_package = "./Greeter"; + +message HelloRequest { + string name = 1; +} + +message HelloResponse { + string reply_message = 1; +} + +service GreeterService { + rpc Hello (HelloRequest) returns (HelloResponse); +} + +message Nothing { + +} + +message TicktokRequest { + int32 counts = 1; +} + +message WatchRequest { + +} + +message NowResponse { + uint64 now = 1; + int32 counts=2; +} + +service TimeService { + rpc Now (Nothing) returns (NowResponse); + rpc Ticktok (TicktokRequest) returns (stream NowResponse); + rpc Watch (stream WatchRequest) returns (stream NowResponse); +} \ No newline at end of file diff --git a/Common/proto/user.proto b/Common/proto/user.proto new file mode 100644 index 0000000..318e43e --- /dev/null +++ b/Common/proto/user.proto @@ -0,0 +1,42 @@ +syntax = "proto3"; + +package User; +option go_package = "./User"; + + +message Address { + string address = 1; + string postal_code = 2; +} + +enum GENDER_ENUM { + GE_MALE=0; + GE_FEMALE=1; +} + +message RegisterRequest { + string name = 1; + GENDER_ENUM gender = 2; + repeated Address address = 3; +} + +message RegisterResponse { + uint64 id = 1; + string msg = 2; +} + +message QueryRequest { + uint64 id = 1; +} + +message QueryResponse { + string name = 1; + GENDER_ENUM gender = 2; + repeated Address address = 3; +} + +service UserService { + rpc Register (RegisterRequest) returns (RegisterResponse); + rpc Query(QueryRequest) returns(QueryResponse); +} + diff --git a/Server/certs/ca.crt b/Server/certs/ca.crt new file mode 100644 index 0000000..7b5d462 --- /dev/null +++ b/Server/certs/ca.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDaTCCAlGgAwIBAgIJALg9FEgTMGPaMA0GCSqGSIb3DQEBCwUAMEsxCzAJBgNV +BAYTAkNOMRAwDgYDVQQHDAdCZWlqaW5nMRIwEAYDVQQKDAlUdXJib0xpbmsxFjAU +BgNVBAMMDXR1cmJvbGluay5kZXYwHhcNMjIxMTMwMDI1NTE2WhcNMzIxMTI3MDI1 +NTE2WjBLMQswCQYDVQQGEwJDTjEQMA4GA1UEBwwHQmVpamluZzESMBAGA1UECgwJ +VHVyYm9MaW5rMRYwFAYDVQQDDA10dXJib2xpbmsuZGV2MIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAqLjDp7Xh4TVyMZnajYTm73U0I0k7WRkR0TqxHeyO +sUQ/yKk9Bv6XNxAEsJj7ofIwMDG7VWI6uuzCWdRD11HIf/fuEDOYqK46LFf+yQXf ++P6Y0I2t2vvMS/FntSzzkuz1veRWfFa0ssGV3Iv8jEgSvAfV1xU5rvnlULhVcevz +CMOvmesu5DSeEo9EIeugaUasiS2RR+TRJb4gflCPLZu0rL0+/mDNhsd3BXuRp/jE +h63F47/eFv3Us9jZ0D/hzmXnmJVzkVbyRwMYKZ8BnDuVhdBzT1yPjbL2A0Q9OIh6 +IuGlHnbo907ZZgheGxyqSpDq794J5lWhHn5KY/fmpMPZiwIDAQABo1AwTjAdBgNV +HQ4EFgQUeRpYmEkuEnGbhwF66uNSmjVzgRkwHwYDVR0jBBgwFoAUeRpYmEkuEnGb +hwF66uNSmjVzgRkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAeOuJ +nKz5/Ez1CiwMT4FwZoJPtjJw4ONSzbxMsekb/aubzNYY0T3w693DqZwVFmM573yq +d96ghHBfvVanPMJyHOJFRayZNgrDRKHHW75Jth03cAbQ6MahgVyys0VUrCsAFdAj +Zo2q504vVxBtq2pHzYetNDTF6SVjZp/XrMtgepggEtU6Zf1sDpk0Si694rksrO2p +3C+zkPtgVFd5cT2fihZ5imjUNqu/iRP95mjoKwtPRRGBUhJjN8UOuRyS08L/eUSf +IbN7ogcp6Y+WL6rmNvSVoXBl7wIWhGEWTscyzm66bWisZxGUFTicezL56CpkHdbo +NzR3/aU8S0eIDHSaiQ== +-----END CERTIFICATE----- diff --git a/Server/certs/server.crt b/Server/certs/server.crt new file mode 100644 index 0000000..ffd3508 --- /dev/null +++ b/Server/certs/server.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDZTCCAk2gAwIBAgIJAOFO3+DpMNlLMA0GCSqGSIb3DQEBCwUAMEsxCzAJBgNV +BAYTAkNOMRAwDgYDVQQHDAdCZWlqaW5nMRIwEAYDVQQKDAlUdXJib0xpbmsxFjAU +BgNVBAMMDXR1cmJvbGluay5kZXYwHhcNMjIxMjA5MTQwNjI4WhcNMzIxMjA2MTQw +NjI4WjBLMQswCQYDVQQGEwJDTjEQMA4GA1UEBwwHQmVpamluZzESMBAGA1UECgwJ +dHVyYm9saW5rMRYwFAYDVQQDDA10dXJib2xpbmsuZGV2MIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAr8vdbsXtLWOEWoygSluR3BtYJcp+1nbDwrytr7WX +XcnzSB1rQ0lt3yQmQ5BKm6CLbUeKtQd7fIUT1JRn3KJ/dSHXT4qEWWO0XJLJeoAI +FXprLWolbrBA8QCAs8Hcbm8F/efHphKU4a10HhD6ENa4YqYPnd89vfYgSPGS/UmF +ojWicWjmmT7Np5PBo81mzpbyhGTlOeZj6LLp77w8772MRBDZTn4eDXDuCdfbs2HM +YFK4OQ2QQjrh2LSCA6VQgi8gGaXtp2k8CwVlXQpOFWmYX0FyXX/4qvkvXl8rG07T +AvX7iCaG3owAYrDeQUL7NqbTvAMHiqivCwrFzThNq+XSkQIDAQABo0wwSjBIBgNV +HREEQTA/gg8qLnR1cmJvbGluay5kZXaCECoudGhlY29kZXdheS5jb22CDyoubGV5 +b3V0ZWNoLm5ldIIJbG9jYWxob3N0MA0GCSqGSIb3DQEBCwUAA4IBAQCUlziOgdSF ++GrN2PxrZmRP9bhbLEc1GAWGzStN4xsZFcPIesrDbf74tua65idKvSL4vyx6lpPb +ino6mwIgP8ZUV3jdkgKTUMzeqJJY8hoH5Sza93kOZX0oDFyuEJ7LS9kPrLIqEkdp +Myc690q5GqNLdSWZqONjAp1S3dezQoKRV/YC6PqMr+1Dq/oRIz83NYWan0vpnHFC +gRlK5Rb37ueI+Pe+d6Wg9JSwdo0mFJ5hGfT5Ler4AoA9HMss1k9lJ18iFoSyBCcn +wIg5gcxJe6P7DKXnOknt1Sa0Us/li8ux5J8bVgqImkqx2nagDugcW0BfQYcoFilH +pgulZBZZCO3S +-----END CERTIFICATE----- diff --git a/Server/certs/server.key b/Server/certs/server.key new file mode 100644 index 0000000..2af98b4 --- /dev/null +++ b/Server/certs/server.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAr8vdbsXtLWOEWoygSluR3BtYJcp+1nbDwrytr7WXXcnzSB1r +Q0lt3yQmQ5BKm6CLbUeKtQd7fIUT1JRn3KJ/dSHXT4qEWWO0XJLJeoAIFXprLWol +brBA8QCAs8Hcbm8F/efHphKU4a10HhD6ENa4YqYPnd89vfYgSPGS/UmFojWicWjm +mT7Np5PBo81mzpbyhGTlOeZj6LLp77w8772MRBDZTn4eDXDuCdfbs2HMYFK4OQ2Q +Qjrh2LSCA6VQgi8gGaXtp2k8CwVlXQpOFWmYX0FyXX/4qvkvXl8rG07TAvX7iCaG +3owAYrDeQUL7NqbTvAMHiqivCwrFzThNq+XSkQIDAQABAoIBAQCqrwa0+elZi2lD +PYyYBaZuDgKc1qol8rQJTIZatrZbsqvKFf5CG3ZZFFEugldeGRemp7KuJ7Cm6tKh +MOJS31dfU9cofHYaEGtbAo4qqUqwB+ct9gSYHvs+w90yKwSqGJO5vaQjw6DYKUA3 +vQX++WuXJGK/RrQ8z07zY9HyqMLeBRcnZVvqRa/neowa3luBfl9bqbfZY4Sac1X/ +1HD2+ffE6Y3nnf3OD6PFeHfqBqIZuQebwIOj2myLSL6nyCoWJJQCinlRzOnH4Dkk +Jb6kVwmAGoB/8qD84sKa5XlW+TqiH4HpRoxiGoHj2HeawTv2QAxsVfOV/s4pmjEO +Sg710xGNAoGBANrqb8rFNiicndZX+agxCGhMvYLJqCOUC7cBEd3JOVYELiaopyTb +LdbjTR8lwXK8JyJ+lagbi+sYyIHNc7KF8xnwd5DFpLaT0DwqqENcd83dUeqadnUf +WgzHBcO030CP0JpaJEAtemK6rvq+U4xE+4XuFeXDsCOyCqA+Xw5qF3qbAoGBAM2T +f87euZmqH97kGWaUmgXQWZT3IJzIqo9/UFE5eFIDnNwjaorla9eRSM+WyPStgOhR +Q+zx/cv68vUJg08ESk5IwuEyGAdLiCW3Gsq7sIoaih18wWPor+0MQUSOtbKtnltj +HwwhpXXVUK9rEPnUsrU6Jx1T6fe4BuxTe1xcf/RDAoGAcvia28B1MCEI2BB+IrIV +u0lKYkzsTDstZ+Bc9MEApsctQcpjdfzSd0ALOeeHUG22k+wtRwuokUED1QAE2mZ1 +BVOAR/01A1pgC6lPk4kVtn2czvxuaBaeIYXI5j6w3WRqZxYeYcJAu2dWDIQ2tr1n +56/hujjq4eRYpk37eEOJry8CgYBxSQ4OXvhicLi9aG+C8vLpr0YebAzhuUccaqlF +CWl/sJP5T97/iavjECHSm6JEC3TVEStgYH5esPzAAa0FlzSnbTtPQ/6vznTJa9zs +yX9gq31fAIfF2c1Q0QcKk6YXP8vbSoUqd0Qp6hJbiKHDOu38Jn61j6+IHjZadyqs +3CB65wKBgH9PKZ2CZ86qCLwlZ3Uj/hFR9CQCsTuns/lbzjVszw057vny57kf6fma +3+a0oV4pOyEkDip46ObgBaOQDdRt0XuUpUFVNuohmpxdkf0qoqPF6paqhDA5dRvi +F90g0bTXJRO5hKpKMn7L9HAE54aXJWzFem2UgwYAfIuxyhEv6q8j +-----END RSA PRIVATE KEY----- diff --git a/Server/go.mod b/Server/go.mod new file mode 100644 index 0000000..90ddae4 --- /dev/null +++ b/Server/go.mod @@ -0,0 +1,16 @@ +module tldemo + +go 1.19 + +require ( + google.golang.org/grpc v1.50.1 + google.golang.org/protobuf v1.28.1 +) + +require ( + github.com/golang/protobuf v1.5.2 // indirect + golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect + golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 // indirect + golang.org/x/text v0.3.3 // indirect + google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect +) diff --git a/Server/go.sum b/Server/go.sum new file mode 100644 index 0000000..619d333 --- /dev/null +++ b/Server/go.sum @@ -0,0 +1,83 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY= +google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/Server/main.go b/Server/main.go new file mode 100644 index 0000000..ec7c7b0 --- /dev/null +++ b/Server/main.go @@ -0,0 +1,59 @@ +package main + +import ( + "fmt" + "flag" + "log" + "net" + "os" + + "google.golang.org/grpc" + "google.golang.org/grpc/reflection" + "google.golang.org/grpc/credentials" + + "tldemo/services" +) + +var ( + port = flag.Int("port", 50051, "The server port") + crt_file = "certs/server.crt" + key_file = "certs/server.key" +) + +func main() { + fmt.Println("==== TurboLink Test Server =====") + + logFileName := "./log/services.log" + logFile, err := os.OpenFile(logFileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0766) + if err != nil { + log.Fatalf("could not load TLS keys: %s", err) + return + } + log.SetOutput(logFile) + log.SetFlags(log.LstdFlags | log.Lshortfile | log.Ltime) + + flag.Parse() + lis, err := net.Listen("tcp",":5050") + + if err != nil { + log.Fatalf("failed to listen: %v", err) + } + + // server-side tls + // Create the TLS credentials + creds, err := credentials.NewServerTLSFromFile(crt_file, key_file) + if err != nil { + log.Fatalf("could not load TLS keys: %s", err) + } + s := grpc.NewServer(grpc.Creds(creds)) + + //register all server + services.RegisterGreeterServer(s) + services.RegisterUserServer(s) + + reflection.Register(s) + log.Printf("server listening at %v", lis.Addr()) + if err := s.Serve(lis); err != nil { + log.Fatalf("failed to serve: %v", err) + } +} diff --git a/Server/services/greeter_server.go b/Server/services/greeter_server.go new file mode 100644 index 0000000..435c088 --- /dev/null +++ b/Server/services/greeter_server.go @@ -0,0 +1,109 @@ +package services + +import ( + "fmt" + "context" + "log" + "time" + + "google.golang.org/grpc" + pb "tldemo/services/Greeter" +) + +type GreeterServer struct { + pb.UnimplementedGreeterServiceServer +} + +func (s *GreeterServer) Hello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloResponse, error) { + currentTime := time.Now() + replyMessage := fmt.Sprintf("Hello %s, time is %s", in.Name, currentTime.Format("15:04:05")) + log.Printf("[Hello User] %s", in.Name) + result := &pb.HelloResponse{ReplyMessage: replyMessage} + return result, nil +} + +type TimeServer struct { + pb.UnimplementedTimeServiceServer +} + +func (s *TimeServer) Now(ctx context.Context, in *pb.Nothing) (*pb.NowResponse, error) { + currentTime := uint64(time.Now().UTC().UnixMilli()) + log.Printf("[Now]send time: %d", currentTime) + + result := &pb.NowResponse{Now: currentTime} + return result, nil +} + +func (s *TimeServer) Ticktok(in *pb.TicktokRequest, stream pb.TimeService_TicktokServer) error { + ctx := stream.Context() + response := &pb.NowResponse{} + + sendNow := func(counts int32) { + response.Now = uint64(time.Now().UTC().UnixMilli()) + response.Counts = counts + log.Printf("[Ticktok]send time %d/%d", response.Now, counts) + if err := stream.Send(response); err != nil { + return + } + } + counts := int32(in.Counts) + if(counts < 0) { + counts=0 + } + + for { + sendNow(counts) + + if(in.Counts>0) { + counts-=1 + + if(counts <= 0) { + return nil + } + } + + select { + case <-ctx.Done(): + return nil + default: + time.Sleep(1.0 * time.Second) + } + } + return nil +} + +func (s *TimeServer) Watch(stream pb.TimeService_WatchServer) error { + ctx := stream.Context() + response := &pb.NowResponse{} + + sendNow := func() error { + response.Now = uint64(time.Now().UTC().UnixMilli()) + log.Printf("[Watch]send time %d", response.Now) + return stream.Send(response) + } + + for { + select { + case <-ctx.Done(): + return nil + default: + } + + if _, err := stream.Recv(); err != nil { + return err + } else if err := sendNow(); err != nil { + return err + } + } +} + + +func RegisterGreeterServer(s *grpc.Server) { + greeterServer := &GreeterServer{} + pb.RegisterGreeterServiceServer(s, greeterServer) + + timeServer := &TimeServer{} + pb.RegisterTimeServiceServer(s, timeServer) +} + + diff --git a/Server/services/user_server.go b/Server/services/user_server.go new file mode 100644 index 0000000..f4a4e67 --- /dev/null +++ b/Server/services/user_server.go @@ -0,0 +1,74 @@ +package services + +import ( + "fmt" + "context" + "log" + "errors" + + "google.golang.org/grpc" + pb "tldemo/services/User" +) + +type UserAddress struct { + Address string + PostalCode string +} + +type UserData struct { + Id int + Name string + Gender pb.GENDER_ENUM + Addresses [] *UserAddress +} + +type UserServer struct { + pb.UnimplementedUserServiceServer + UserArray []*UserData +} + +func (s *UserServer) Register(ctx context.Context, in *pb.RegisterRequest) (*pb.RegisterResponse, error) { + userData := &UserData{Id:len(s.UserArray), Name:in.Name, Gender:in.Gender} + userData.Addresses = make([]*UserAddress, 0) + for i:=0; i=len(s.UserArray)) { + return nil, errors.New("Out of range!") + } + + var userData = s.UserArray[int(in.Id)] + + address := make([]*pb.Address, 0) + for i:=0; i