├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── Config ├── Android │ └── AndroidEngine.ini ├── DefaultEditor.ini ├── DefaultEngine.ini ├── DefaultGame.ini ├── DefaultInput.ini ├── IOS │ └── IOSEngine.ini ├── Linux │ └── LinuxEngine.ini ├── Mac │ └── MacEngine.ini ├── PS4 │ └── PS4Engine.ini ├── Switch │ └── SwitchEngine.ini ├── Windows │ └── WindowsEngine.ini └── XboxOne │ └── XboxOneEngine.ini ├── Content ├── CustomSerialize │ ├── CustomObjA.uasset │ ├── CustomObjB.uasset │ ├── CustomObjC.uasset │ ├── CustomObject1.uasset │ ├── CustomPropObjA.uasset │ ├── CustomPropObjB.uasset │ ├── CustomPropObjC.uasset │ └── CustomSerialize.umap ├── Log │ ├── CaptureMat.uasset │ ├── Log.umap │ └── LogUMG1.uasset ├── MyGameMode.uasset ├── MyPacketRule.uasset ├── MyPlayerController.uasset ├── NewBlueprint.uasset ├── SharedMemory │ ├── BoxActor.uasset │ ├── BoxMat.uasset │ ├── NewTextureRenderTarget2D.uasset │ ├── SharedMemory.umap │ └── Sphere_Blueprint.uasset ├── TCPIP │ ├── MainWidget.uasset │ ├── MainWidget1.uasset │ ├── TCPIP.umap │ ├── TCPIP_BuiltData_2.uasset │ └── TCPSampleObject.uasset ├── TCPServerMultiClient │ ├── TCPServerMClient.umap │ └── TCPServerMClientUMG.uasset ├── Test.umap └── UDP │ ├── UDP.umap │ ├── UDPUMG1.uasset │ └── UDPUMG2.uasset ├── Froola ├── appsettings.json ├── run_create_packages.bat ├── run_tests_all.bat ├── run_tests_linux.bat ├── run_tests_mac.bat └── run_tests_win.bat ├── LICENSE ├── ObjectDelivererTest.uproject ├── Plugins └── ObjectDeliverer │ ├── Config │ └── FilterPlugin.ini │ ├── ObjectDeliverer.uplugin │ ├── Resources │ └── Icon128.png │ └── Source │ ├── ObjectDeliverer │ ├── ObjectDeliverer.Build.cs │ ├── Private │ │ ├── DeliveryBox │ │ │ ├── DeliveryBox.cpp │ │ │ ├── DeliveryBoxFactory.cpp │ │ │ ├── IODConvertPropertyName.cpp │ │ │ ├── ODOverrideJsonSerializer.cpp │ │ │ ├── ObjectDeliveryBoxUsingJson.cpp │ │ │ └── Utf8StringDeliveryBox.cpp │ │ ├── ObjectDeliverer.cpp │ │ ├── ObjectDelivererManager.cpp │ │ ├── PacketRule │ │ │ ├── PacketRule.cpp │ │ │ ├── PacketRuleFactory.cpp │ │ │ ├── PacketRuleFixedLength.cpp │ │ │ ├── PacketRuleNodivision.cpp │ │ │ ├── PacketRuleSizeBody.cpp │ │ │ └── PacketRuleTerminate.cpp │ │ ├── Protocol │ │ │ ├── ObjectDelivererProtocol.cpp │ │ │ ├── ProtocolFactory.cpp │ │ │ ├── ProtocolLogReader.cpp │ │ │ ├── ProtocolLogWriter.cpp │ │ │ ├── ProtocolReflection.cpp │ │ │ ├── ProtocolSharedMemory.cpp │ │ │ ├── ProtocolSocketBase.cpp │ │ │ ├── ProtocolTcpIpClient.cpp │ │ │ ├── ProtocolTcpIpServer.cpp │ │ │ ├── ProtocolTcpIpSocket.cpp │ │ │ ├── ProtocolUdpSocket.cpp │ │ │ ├── ProtocolUdpSocketReceiver.cpp │ │ │ └── ProtocolUdpSocketSender.cpp │ │ └── Utils │ │ │ ├── JsonSerializer │ │ │ ├── ODJsonDeserializer.cpp │ │ │ ├── ODJsonDeserializer.h │ │ │ ├── ODJsonSerializer.cpp │ │ │ ├── ODJsonSerializer.h │ │ │ ├── ODJsonSerializerBase.cpp │ │ │ └── ODJsonSerializerBase.h │ │ │ ├── LogObjectDeliverer.cpp │ │ │ ├── LogObjectDeliverer.h │ │ │ ├── ODFileUtil.cpp │ │ │ ├── ODFileUtil.h │ │ │ ├── ODGrowBuffer.cpp │ │ │ ├── ODMutexLock.cpp │ │ │ ├── ODMutexLock.h │ │ │ ├── ODObjectUtil.cpp │ │ │ ├── ODObjectUtil.h │ │ │ ├── ODStringUtil.cpp │ │ │ ├── ODStringUtil.h │ │ │ ├── ODWorkerThread.cpp │ │ │ └── ODWorkerThread.h │ └── Public │ │ ├── DeliveryBox │ │ ├── DeliveryBox.h │ │ ├── DeliveryBoxFactory.h │ │ ├── IODConvertPropertyName.h │ │ ├── ODOverrideJsonSerializer.h │ │ ├── ObjectDeliveryBoxUsingJson.h │ │ └── Utf8StringDeliveryBox.h │ │ ├── IObjectDeliverer.h │ │ ├── ObjectDelivererManager.h │ │ ├── PacketRule │ │ ├── PacketRule.h │ │ ├── PacketRuleFactory.h │ │ ├── PacketRuleFixedLength.h │ │ ├── PacketRuleNodivision.h │ │ ├── PacketRuleSizeBody.h │ │ └── PacketRuleTerminate.h │ │ ├── Protocol │ │ ├── GetIPV4Info.h │ │ ├── ObjectDelivererProtocol.h │ │ ├── ProtocolFactory.h │ │ ├── ProtocolLogReader.h │ │ ├── ProtocolLogWriter.h │ │ ├── ProtocolReflection.h │ │ ├── ProtocolSharedMemory.h │ │ ├── ProtocolSocketBase.h │ │ ├── ProtocolTcpIpClient.h │ │ ├── ProtocolTcpIpServer.h │ │ ├── ProtocolTcpIpSocket.h │ │ ├── ProtocolUdpSocket.h │ │ ├── ProtocolUdpSocketReceiver.h │ │ └── ProtocolUdpSocketSender.h │ │ └── Utils │ │ └── ODGrowBuffer.h │ └── ObjectDelivererTests │ ├── ObjectDelivererTests.Build.cs │ ├── Private │ ├── DeliveryBoxTests.cpp │ ├── ODGrowBufferTest.cpp │ ├── ODJsonSerializerTests.cpp │ ├── ObjectDelivererManagerTestHelper.cpp │ ├── ObjectDelivererManagerTestHelper.h │ ├── ObjectDelivererTests.cpp │ ├── PacketRuleFixedLengthTest.cpp │ ├── PacketRuleNodivisionTest.cpp │ ├── PacketRuleSizeBodyTest.cpp │ ├── PacketRuleTerminateTest.cpp │ ├── ProtocolLogWriterReaderTest.cpp │ ├── ProtocolSharedMemoryTest.cpp │ ├── ProtocolTcpIpServerClientTest.cpp │ └── ProtocolUdpSocketTest.cpp │ └── Public │ └── ObjectDelivererTests.h ├── README.md └── Source ├── ObjectDelivererTest.Target.cs ├── ObjectDelivererTest ├── MyClass.cpp ├── MyClass.h ├── ObjectDelivererTest.Build.cs ├── ObjectDelivererTest.cpp ├── ObjectDelivererTest.h ├── TextureUtil.cpp └── TextureUtil.h └── ObjectDelivererTestEditor.Target.cs /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Bug report" 3 | about: "Report a bug to help us improve" 4 | title: "[Bug] " 5 | labels: bug 6 | assignees: '' 7 | --- 8 | 9 | ## Summary 10 | A clear and concise description of what the bug is. 11 | 12 | ## Steps to Reproduce 13 | Steps to reproduce the behavior: 14 | 1. Go to '...' 15 | 2. Click on '...' 16 | 3. Scroll down to '...' 17 | 4. See error 18 | 19 | ## Expected Behavior 20 | A clear and concise description of what you expected to happen. 21 | 22 | ## Actual Behavior 23 | What actually happened. 24 | 25 | ## Screenshots 26 | If applicable, add screenshots to help explain your problem. 27 | 28 | ## Logs 29 | If possible, please paste any relevant logs that may help identify the problem. (Please remove any sensitive information.) 30 | 31 | ## Environment 32 | - OS: [e.g. Windows 11] 33 | - Version: [e.g. v1.0.0] 34 | - Other relevant information 35 | 36 | ## Additional Context 37 | Add any other context about the problem here. 38 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Feature request" 3 | about: "Suggest an idea for this project" 4 | title: "[Feature] " 5 | labels: enhancement 6 | assignees: '' 7 | --- 8 | 9 | ## Summary 10 | A clear and concise description of what the feature is. 11 | 12 | ## Motivation 13 | Why is this feature needed? What problem does it solve? 14 | 15 | ## Describe the Solution 16 | A clear and concise description of what you want to happen. 17 | 18 | ## Alternatives 19 | A clear and concise description of any alternative solutions or features you've considered. 20 | 21 | ## Additional Context 22 | Add any other context or screenshots about the feature request here. 23 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Pull Request Description 2 | 3 | ### Overview 4 | 5 | 6 | ### Motivation 7 | 8 | 9 | ### Changes Made 10 | 11 | 12 | ### Testing Status 13 | - [ ] All tests are passing 14 | - [ ] Some tests are failing (explain below) 15 | - [ ] No tests were added or modified 16 | 17 | ### Explanation for Failing Tests (if applicable) 18 | 19 | 20 | ### Additional Information 21 | 22 | 23 | ### Screenshots/Videos (if applicable) 24 | 25 | 26 | ### Checklist 27 | - [ ] I have tested these changes locally 28 | - [ ] I have updated documentation as needed 29 | - [ ] This PR targets the `master` branch 30 | - [ ] I have added/updated tests to cover my changes (if applicable) 31 | 32 | ### Related Issues 33 | 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | Plugins/Developer/ 3 | 4 | # Visual Studio 2015 user specific files 5 | .vs/ 6 | 7 | # Visual Studio 2015 database file 8 | *.VC.db 9 | 10 | # Compiled Object files 11 | *.slo 12 | *.lo 13 | *.o 14 | *.obj 15 | 16 | # Precompiled Headers 17 | *.gch 18 | *.pch 19 | 20 | # Compiled Dynamic libraries 21 | *.so 22 | *.dylib 23 | *.dll 24 | 25 | # Fortran module files 26 | *.mod 27 | 28 | # Compiled Static libraries 29 | *.lai 30 | *.la 31 | *.a 32 | *.lib 33 | 34 | # Executables 35 | *.exe 36 | *.out 37 | *.app 38 | *.ipa 39 | 40 | # These project files can be generated by the engine 41 | *.xcodeproj 42 | *.xcworkspace 43 | *.sln 44 | *.suo 45 | *.opensdf 46 | *.sdf 47 | *.VC.db 48 | *.VC.opendb 49 | *.code-workspace 50 | 51 | # Precompiled Assets 52 | SourceArt/**/*.png 53 | SourceArt/**/*.tga 54 | 55 | # Binary Files 56 | Binaries/* 57 | Plugins/*/Binaries/* 58 | 59 | # Builds 60 | Build/* 61 | 62 | # Whitelist PakBlacklist-.txt files 63 | !Build/*/ 64 | Build/*/** 65 | !Build/*/PakBlacklist*.txt 66 | 67 | # Don't ignore icon files in Build 68 | !Build/**/*.ico 69 | 70 | # Built data for maps 71 | *_BuiltData.uasset 72 | 73 | # Configuration files generated by the Editor 74 | Saved/* 75 | 76 | # Compiled source files for the engine to use 77 | Intermediate/* 78 | Plugins/*/Intermediate/* 79 | 80 | # Cache files for the editor to use 81 | DerivedDataCache/* 82 | /ObjectDelivererTest.sln.DotSettings.user 83 | 84 | .vsconfig 85 | .vscode/* 86 | Config/DefaultEditorSettings.ini 87 | 88 | ObjectDelivererTest.uproject.DotSettings.user 89 | 90 | .DS_Store 91 | 92 | Froola/results/* 93 | Froola/packages/* -------------------------------------------------------------------------------- /Config/Android/AndroidEngine.ini: -------------------------------------------------------------------------------- 1 | [/Script/AndroidRuntimeSettings.AndroidRuntimeSettings] 2 | ;AudioSampleRate=48000 3 | AudioMaxChannels=12 4 | ;AudioCallbackBufferFrameSize=1024 5 | ;AudioNumBuffersToEnqueue=2 6 | ;AudioNumSourceWorkers=0 7 | 8 | -------------------------------------------------------------------------------- /Config/DefaultEditor.ini: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Config/DefaultEditor.ini -------------------------------------------------------------------------------- /Config/DefaultEngine.ini: -------------------------------------------------------------------------------- 1 | 2 | 3 | [/Script/Engine.RendererSettings] 4 | r.DefaultFeature.AutoExposure.ExtendDefaultLuminanceRange=True 5 | 6 | [/Script/HardwareTargeting.HardwareTargetingSettings] 7 | TargetedHardwareClass=Desktop 8 | AppliedTargetedHardwareClass=Desktop 9 | DefaultGraphicsPerformance=Maximum 10 | AppliedDefaultGraphicsPerformance=Maximum 11 | 12 | [/Script/AndroidFileServerEditor.AndroidFileServerRuntimeSettings] 13 | bEnablePlugin=True 14 | bAllowNetworkConnection=True 15 | SecurityToken=F0BAEE0F4EF20A3589CF02928C825ACE 16 | bIncludeInShipping=False 17 | bAllowExternalStartInShipping=False 18 | bCompileAFSProject=False 19 | bUseCompression=False 20 | bLogFiles=False 21 | bReportStats=False 22 | ConnectionType=USBOnly 23 | bUseManualIPAddress=False 24 | ManualIPAddress= 25 | 26 | -------------------------------------------------------------------------------- /Config/DefaultGame.ini: -------------------------------------------------------------------------------- 1 | [/Script/EngineSettings.GeneralProjectSettings] 2 | ProjectID=755F8033416C542ED7E83A85D6A11294 3 | -------------------------------------------------------------------------------- /Config/DefaultInput.ini: -------------------------------------------------------------------------------- 1 | [/Script/Engine.InputSettings] 2 | -AxisConfig=(AxisKeyName="Gamepad_LeftX",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f)) 3 | -AxisConfig=(AxisKeyName="Gamepad_LeftY",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f)) 4 | -AxisConfig=(AxisKeyName="Gamepad_RightX",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f)) 5 | -AxisConfig=(AxisKeyName="Gamepad_RightY",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f)) 6 | -AxisConfig=(AxisKeyName="MouseX",AxisProperties=(DeadZone=0.f,Exponent=1.f,Sensitivity=0.07f)) 7 | -AxisConfig=(AxisKeyName="MouseY",AxisProperties=(DeadZone=0.f,Exponent=1.f,Sensitivity=0.07f)) 8 | -AxisConfig=(AxisKeyName="Mouse2D",AxisProperties=(DeadZone=0.f,Exponent=1.f,Sensitivity=0.07f)) 9 | +AxisConfig=(AxisKeyName="Gamepad_LeftX",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 10 | +AxisConfig=(AxisKeyName="Gamepad_LeftY",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 11 | +AxisConfig=(AxisKeyName="Gamepad_RightX",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 12 | +AxisConfig=(AxisKeyName="Gamepad_RightY",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 13 | +AxisConfig=(AxisKeyName="MouseX",AxisProperties=(DeadZone=0.000000,Sensitivity=0.070000,Exponent=1.000000,bInvert=False)) 14 | +AxisConfig=(AxisKeyName="MouseY",AxisProperties=(DeadZone=0.000000,Sensitivity=0.070000,Exponent=1.000000,bInvert=False)) 15 | +AxisConfig=(AxisKeyName="Mouse2D",AxisProperties=(DeadZone=0.000000,Sensitivity=0.070000,Exponent=1.000000,bInvert=False)) 16 | +AxisConfig=(AxisKeyName="MouseWheelAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 17 | +AxisConfig=(AxisKeyName="Gamepad_LeftTriggerAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 18 | +AxisConfig=(AxisKeyName="Gamepad_RightTriggerAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 19 | +AxisConfig=(AxisKeyName="Gamepad_Special_Left_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 20 | +AxisConfig=(AxisKeyName="Gamepad_Special_Left_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 21 | +AxisConfig=(AxisKeyName="Vive_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 22 | +AxisConfig=(AxisKeyName="Vive_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 23 | +AxisConfig=(AxisKeyName="Vive_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 24 | +AxisConfig=(AxisKeyName="Vive_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 25 | +AxisConfig=(AxisKeyName="Vive_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 26 | +AxisConfig=(AxisKeyName="Vive_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 27 | +AxisConfig=(AxisKeyName="MixedReality_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 28 | +AxisConfig=(AxisKeyName="MixedReality_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 29 | +AxisConfig=(AxisKeyName="MixedReality_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 30 | +AxisConfig=(AxisKeyName="MixedReality_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 31 | +AxisConfig=(AxisKeyName="MixedReality_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 32 | +AxisConfig=(AxisKeyName="MixedReality_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 33 | +AxisConfig=(AxisKeyName="MixedReality_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 34 | +AxisConfig=(AxisKeyName="MixedReality_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 35 | +AxisConfig=(AxisKeyName="MixedReality_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 36 | +AxisConfig=(AxisKeyName="MixedReality_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 37 | +AxisConfig=(AxisKeyName="OculusTouch_Left_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 38 | +AxisConfig=(AxisKeyName="OculusTouch_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 39 | +AxisConfig=(AxisKeyName="OculusTouch_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 40 | +AxisConfig=(AxisKeyName="OculusTouch_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 41 | +AxisConfig=(AxisKeyName="OculusTouch_Right_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 42 | +AxisConfig=(AxisKeyName="OculusTouch_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 43 | +AxisConfig=(AxisKeyName="OculusTouch_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 44 | +AxisConfig=(AxisKeyName="OculusTouch_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 45 | +AxisConfig=(AxisKeyName="ValveIndex_Left_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 46 | +AxisConfig=(AxisKeyName="ValveIndex_Left_Grip_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 47 | +AxisConfig=(AxisKeyName="ValveIndex_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 48 | +AxisConfig=(AxisKeyName="ValveIndex_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 49 | +AxisConfig=(AxisKeyName="ValveIndex_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 50 | +AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 51 | +AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 52 | +AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 53 | +AxisConfig=(AxisKeyName="ValveIndex_Right_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 54 | +AxisConfig=(AxisKeyName="ValveIndex_Right_Grip_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 55 | +AxisConfig=(AxisKeyName="ValveIndex_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 56 | +AxisConfig=(AxisKeyName="ValveIndex_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 57 | +AxisConfig=(AxisKeyName="ValveIndex_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 58 | +AxisConfig=(AxisKeyName="ValveIndex_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 59 | +AxisConfig=(AxisKeyName="ValveIndex_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 60 | +AxisConfig=(AxisKeyName="ValveIndex_Right_Trackpad_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False)) 61 | bAltEnterTogglesFullscreen=True 62 | bF11TogglesFullscreen=True 63 | bUseMouseForTouch=False 64 | bEnableMouseSmoothing=True 65 | bEnableFOVScaling=True 66 | bCaptureMouseOnLaunch=True 67 | bEnableLegacyInputScales=True 68 | bEnableMotionControls=True 69 | bFilterInputByPlatformUser=False 70 | bEnableInputDeviceSubsystem=True 71 | bShouldFlushPressedKeysOnViewportFocusLost=True 72 | bEnableDynamicComponentInputBinding=True 73 | bAlwaysShowTouchInterface=False 74 | bShowConsoleOnFourFingerTap=True 75 | bEnableGestureRecognizer=False 76 | bUseAutocorrect=False 77 | DefaultViewportMouseCaptureMode=CapturePermanently_IncludingInitialMouseDown 78 | DefaultViewportMouseLockMode=LockOnCapture 79 | FOVScale=0.011110 80 | DoubleClickTime=0.200000 81 | DefaultPlayerInputClass=/Script/EnhancedInput.EnhancedPlayerInput 82 | DefaultInputComponentClass=/Script/EnhancedInput.EnhancedInputComponent 83 | DefaultTouchInterface=/Engine/MobileResources/HUD/DefaultVirtualJoysticks.DefaultVirtualJoysticks 84 | -ConsoleKeys=Tilde 85 | +ConsoleKeys=Tilde 86 | 87 | -------------------------------------------------------------------------------- /Config/IOS/IOSEngine.ini: -------------------------------------------------------------------------------- 1 | [/Script/IOSRuntimeSettings.IOSRuntimeSettings] 2 | ;AudioSampleRate=48000 3 | AudioMaxChannels=16 4 | ;AudioCallbackBufferFrameSize=1024 5 | ;AudioNumBuffersToEnqueue=2 6 | ;AudioNumSourceWorkers=0 7 | 8 | -------------------------------------------------------------------------------- /Config/Linux/LinuxEngine.ini: -------------------------------------------------------------------------------- 1 | [/Script/LinuxTargetPlatform.LinuxTargetSettings] 2 | ;AudioSampleRate=48000 3 | AudioMaxChannels=16 4 | ;AudioCallbackBufferFrameSize=1024 5 | ;AudioNumBuffersToEnqueue=2 6 | ;AudioNumSourceWorkers=0 7 | 8 | -------------------------------------------------------------------------------- /Config/Mac/MacEngine.ini: -------------------------------------------------------------------------------- 1 | [/Script/MacTargetPlatform.MacTargetSettings] 2 | ;AudioSampleRate=48000 3 | ;AudioMaxChannels=32 4 | ;AudioCallbackBufferFrameSize=1024 5 | ;AudioNumBuffersToEnqueue=2 6 | ;AudioNumSourceWorkers=0 7 | 8 | -------------------------------------------------------------------------------- /Config/PS4/PS4Engine.ini: -------------------------------------------------------------------------------- 1 | [/Script/PS4PlatformEditor.PS4TargetSettings] 2 | ;AudioSampleRate=48000 3 | ;AudioMaxChannels=32 4 | AudioCallbackBufferFrameSize=256 5 | AudioNumBuffersToEnqueue=7 6 | AudioNumSourceWorkers=4 7 | 8 | -------------------------------------------------------------------------------- /Config/Switch/SwitchEngine.ini: -------------------------------------------------------------------------------- 1 | [/Script/SwitchRuntimeSettings.SwitchRuntimeSettings] 2 | ;AudioSampleRate=48000 3 | AudioMaxChannels=16 4 | ;AudioCallbackBufferFrameSize=1024 5 | ;AudioNumBuffersToEnqueue=2 6 | ;AudioNumSourceWorkers=0 7 | 8 | -------------------------------------------------------------------------------- /Config/Windows/WindowsEngine.ini: -------------------------------------------------------------------------------- 1 | [/Script/WindowsTargetPlatform.WindowsTargetSettings] 2 | ;AudioSampleRate=48000 3 | ;AudioMaxChannels=32 4 | AudioCallbackBufferFrameSize=256 5 | AudioNumBuffersToEnqueue=7 6 | ;AudioNumSourceWorkers=0 7 | 8 | -------------------------------------------------------------------------------- /Config/XboxOne/XboxOneEngine.ini: -------------------------------------------------------------------------------- 1 | [/Script/XboxOnePlatformEditor.XboxOneTargetSettings] 2 | ;AudioSampleRate=48000 3 | ;AudioMaxChannels=32 4 | AudioCallbackBufferFrameSize=256 5 | AudioNumBuffersToEnqueue=7 6 | ;AudioNumSourceWorkers=0 7 | 8 | -------------------------------------------------------------------------------- /Content/CustomSerialize/CustomObjA.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/CustomSerialize/CustomObjA.uasset -------------------------------------------------------------------------------- /Content/CustomSerialize/CustomObjB.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/CustomSerialize/CustomObjB.uasset -------------------------------------------------------------------------------- /Content/CustomSerialize/CustomObjC.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/CustomSerialize/CustomObjC.uasset -------------------------------------------------------------------------------- /Content/CustomSerialize/CustomObject1.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/CustomSerialize/CustomObject1.uasset -------------------------------------------------------------------------------- /Content/CustomSerialize/CustomPropObjA.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/CustomSerialize/CustomPropObjA.uasset -------------------------------------------------------------------------------- /Content/CustomSerialize/CustomPropObjB.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/CustomSerialize/CustomPropObjB.uasset -------------------------------------------------------------------------------- /Content/CustomSerialize/CustomPropObjC.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/CustomSerialize/CustomPropObjC.uasset -------------------------------------------------------------------------------- /Content/CustomSerialize/CustomSerialize.umap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/CustomSerialize/CustomSerialize.umap -------------------------------------------------------------------------------- /Content/Log/CaptureMat.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/Log/CaptureMat.uasset -------------------------------------------------------------------------------- /Content/Log/Log.umap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/Log/Log.umap -------------------------------------------------------------------------------- /Content/Log/LogUMG1.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/Log/LogUMG1.uasset -------------------------------------------------------------------------------- /Content/MyGameMode.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/MyGameMode.uasset -------------------------------------------------------------------------------- /Content/MyPacketRule.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/MyPacketRule.uasset -------------------------------------------------------------------------------- /Content/MyPlayerController.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/MyPlayerController.uasset -------------------------------------------------------------------------------- /Content/NewBlueprint.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/NewBlueprint.uasset -------------------------------------------------------------------------------- /Content/SharedMemory/BoxActor.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/SharedMemory/BoxActor.uasset -------------------------------------------------------------------------------- /Content/SharedMemory/BoxMat.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/SharedMemory/BoxMat.uasset -------------------------------------------------------------------------------- /Content/SharedMemory/NewTextureRenderTarget2D.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/SharedMemory/NewTextureRenderTarget2D.uasset -------------------------------------------------------------------------------- /Content/SharedMemory/SharedMemory.umap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/SharedMemory/SharedMemory.umap -------------------------------------------------------------------------------- /Content/SharedMemory/Sphere_Blueprint.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/SharedMemory/Sphere_Blueprint.uasset -------------------------------------------------------------------------------- /Content/TCPIP/MainWidget.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/TCPIP/MainWidget.uasset -------------------------------------------------------------------------------- /Content/TCPIP/MainWidget1.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/TCPIP/MainWidget1.uasset -------------------------------------------------------------------------------- /Content/TCPIP/TCPIP.umap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/TCPIP/TCPIP.umap -------------------------------------------------------------------------------- /Content/TCPIP/TCPIP_BuiltData_2.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/TCPIP/TCPIP_BuiltData_2.uasset -------------------------------------------------------------------------------- /Content/TCPIP/TCPSampleObject.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/TCPIP/TCPSampleObject.uasset -------------------------------------------------------------------------------- /Content/TCPServerMultiClient/TCPServerMClient.umap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/TCPServerMultiClient/TCPServerMClient.umap -------------------------------------------------------------------------------- /Content/TCPServerMultiClient/TCPServerMClientUMG.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/TCPServerMultiClient/TCPServerMClientUMG.uasset -------------------------------------------------------------------------------- /Content/Test.umap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/Test.umap -------------------------------------------------------------------------------- /Content/UDP/UDP.umap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/UDP/UDP.umap -------------------------------------------------------------------------------- /Content/UDP/UDPUMG1.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/UDP/UDPUMG1.uasset -------------------------------------------------------------------------------- /Content/UDP/UDPUMG2.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Content/UDP/UDPUMG2.uasset -------------------------------------------------------------------------------- /Froola/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Git": { 3 | "GitRepositoryUrl": "", 4 | "GitBranch": "main", 5 | "GitSshKeyPath": "C:\\Users\\ayuma\\.ssh\\id_ed25519" 6 | }, 7 | "InitConfig": { 8 | "OutputPath": "" 9 | }, 10 | "Linux": { 11 | "DockerCommand": "docker", 12 | "DockerImage": "ghcr.io/epicgames/unreal-engine:dev-slim-%v" 13 | }, 14 | "Mac": { 15 | "MacUnrealBasePath": "/Users/Shared/Epic Games", 16 | "SshUser": "ayumax", 17 | "SshPassword": "", 18 | "SshPrivateKeyPath": "C:\\Users\\ayuma\\.ssh\\for_macair_pem", 19 | "SshHost": "192.168.1.30", 20 | "SshPort": 22, 21 | "XcodeNames": { 22 | "5.6": "/Applications/Xcode.app", 23 | "5.5": "/Applications/Xcode.app", 24 | "5.4": "/Applications/Xcode_14.1.app", 25 | "5.3": "/Applications/Xcode_14.1.app" 26 | } 27 | }, 28 | "Plugin": { 29 | "PluginName": "", 30 | "ProjectName": "", 31 | "EditorPlatforms": [ 32 | "Windows", 33 | "Mac", 34 | "Linux" 35 | ], 36 | "EngineVersions": [ 37 | "5.6" 38 | ], 39 | "ResultPath": "C:\\UEPlugins", 40 | "RunTest": false, 41 | "RunPackage": false, 42 | "PackagePlatforms": [ 43 | "Win64", 44 | "Mac", 45 | "Linux", 46 | "Android", 47 | "IOS" 48 | ] 49 | }, 50 | "Windows": { 51 | "WindowsUnrealBasePath": "C:\\Program Files\\Epic Games" 52 | } 53 | } -------------------------------------------------------------------------------- /Froola/run_create_packages.bat: -------------------------------------------------------------------------------- 1 | cd /d %~dp0 2 | Froola.exe plugin -n ObjectDeliverer -p ObjectDelivererTest -v UE_5_5 -u git@github.com:ayumax/ObjectDeliverer.git -b UE5.5 -t -c -o packages 3 | Froola.exe plugin -n ObjectDeliverer -p ObjectDelivererTest -v UE_5_4 -u git@github.com:ayumax/ObjectDeliverer.git -b UE5.4 -t -c -o packages -------------------------------------------------------------------------------- /Froola/run_tests_all.bat: -------------------------------------------------------------------------------- 1 | cd /d %~dp0 2 | Froola.exe plugin -n ObjectDeliverer -p ObjectDelivererTest -l ../ -t -o results -------------------------------------------------------------------------------- /Froola/run_tests_linux.bat: -------------------------------------------------------------------------------- 1 | cd /d %~dp0 2 | Froola.exe plugin -n ObjectDeliverer -p ObjectDelivererTest -l ..\ -t -o results -e Linux -------------------------------------------------------------------------------- /Froola/run_tests_mac.bat: -------------------------------------------------------------------------------- 1 | cd /d %~dp0 2 | Froola.exe plugin -n ObjectDeliverer -p ObjectDelivererTest -l ..\ -t -o results -e Mac -------------------------------------------------------------------------------- /Froola/run_tests_win.bat: -------------------------------------------------------------------------------- 1 | cd /d %~dp0 2 | Froola.exe plugin -n ObjectDeliverer -p ObjectDelivererTest -l ..\ -t -o results -e Windows -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Ayuma Kaminosono 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ObjectDelivererTest.uproject: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "EngineAssociation": "5.6", 4 | "Category": "", 5 | "Description": "", 6 | "Modules": [ 7 | { 8 | "Name": "ObjectDelivererTest", 9 | "Type": "Runtime", 10 | "LoadingPhase": "Default", 11 | "AdditionalDependencies": [ 12 | "Engine" 13 | ] 14 | } 15 | ], 16 | "Plugins": [ 17 | { 18 | "Name": "ObjectDeliverer", 19 | "Enabled": true, 20 | "MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/c2612cff517c48bca7dd080299d97ca8" 21 | } 22 | ] 23 | } -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Config/FilterPlugin.ini: -------------------------------------------------------------------------------- 1 | [FilterPlugin] 2 | ; This section lists additional files which will be packaged along with your plugin. Paths should be listed relative to the root plugin directory, and 3 | ; may include "...", "*", and "?" wildcards to match directories, files, and individual characters respectively. 4 | ; 5 | ; Examples: 6 | ; /README.txt 7 | ; /Extras/... 8 | ; /Binaries/ThirdParty/*.dll 9 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/ObjectDeliverer.uplugin: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "Version": 161, 4 | "VersionName": "1.6.1", 5 | "FriendlyName": "ObjectDeliverer", 6 | "Description": "ObjectDeliverer is a data transmission / reception library for Unreal Engine (C ++, Blueprint).", 7 | "Category": "Programming", 8 | "CreatedBy": "ayumax", 9 | "CreatedByURL": "https://github.com/ayumax", 10 | "DocsURL": "https://github.com/ayumax/ObjectDeliverer", 11 | "MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/c2612cff517c48bca7dd080299d97ca8", 12 | "SupportURL": "https://github.com/ayumax/ObjectDeliverer/issues", 13 | "CanContainContent": false, 14 | "Modules": [ 15 | { 16 | "Name": "ObjectDeliverer", 17 | "Type": "Runtime", 18 | "LoadingPhase": "Default", 19 | "PlatformAllowList": [ 20 | "Android", 21 | "Win64", 22 | "Mac", 23 | "IOS", 24 | "Linux" 25 | ] 26 | }, 27 | { 28 | "Name": "ObjectDelivererTests", 29 | "Type": "DeveloperTool", 30 | "LoadingPhase": "Default", 31 | "WhitelistPlatforms": [ 32 | "Win64", 33 | "Mac", 34 | "Linux" 35 | ] 36 | } 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Resources/Icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ayumax/ObjectDeliverer/a9e012d43078251c59fab6ad8a2fa120dd24339c/Plugins/ObjectDeliverer/Resources/Icon128.png -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/ObjectDeliverer.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | using System.IO; 3 | 4 | namespace UnrealBuildTool.Rules 5 | { 6 | public class ObjectDeliverer : ModuleRules 7 | { 8 | public ObjectDeliverer(ReadOnlyTargetRules Target) : base(Target) 9 | { 10 | PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; 11 | 12 | PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "Private")); 13 | 14 | PublicDependencyModuleNames.AddRange( 15 | new string[] 16 | { 17 | "Core", 18 | "CoreUObject", 19 | "Engine", 20 | "Sockets", 21 | "Networking", 22 | "Json", 23 | "JsonUtilities" 24 | } 25 | ); 26 | 27 | PrivateDependencyModuleNames.AddRange( 28 | new string[] 29 | { 30 | } 31 | ); 32 | 33 | DynamicallyLoadedModuleNames.AddRange( 34 | new string[] 35 | { 36 | } 37 | ); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/DeliveryBox/DeliveryBox.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "DeliveryBox/DeliveryBox.h" 3 | 4 | UDeliveryBox::UDeliveryBox() 5 | { 6 | 7 | } 8 | 9 | UDeliveryBox::~UDeliveryBox() 10 | { 11 | } 12 | 13 | void UDeliveryBox::NotifyReceiveBuffer(const UObjectDelivererProtocol* FromObject, const TArray& buffer) 14 | { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/DeliveryBox/DeliveryBoxFactory.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "DeliveryBox/DeliveryBoxFactory.h" 3 | #include "DeliveryBox/ObjectDeliveryBoxUsingJson.h" 4 | #include "DeliveryBox/Utf8StringDeliveryBox.h" 5 | 6 | UObjectDeliveryBoxUsingJson* UDeliveryBoxFactory::CreateObjectDeliveryBoxUsingJson(UClass* TargetClass) 7 | { 8 | auto deliveryBox = NewObject(); 9 | 10 | deliveryBox->Initialize(TargetClass); 11 | 12 | return deliveryBox; 13 | } 14 | 15 | UObjectDeliveryBoxUsingJson* UDeliveryBoxFactory::CreateDynamicObjectDeliveryBoxUsingJson() 16 | { 17 | auto deliveryBox = NewObject(); 18 | 19 | TMap OverrideObjectSerializerClasses; 20 | deliveryBox->InitializeCustom(EODJsonSerializeType::WriteType, OverrideObjectSerializerClasses, nullptr); 21 | 22 | return deliveryBox; 23 | } 24 | 25 | UObjectDeliveryBoxUsingJson* UDeliveryBoxFactory::CreateCustomObjectDeliveryBoxUsingJson(EODJsonSerializeType DefaultSerializerType, const TMap& ObjectSerializerTypes, UClass* TargetClass/* = nullptr*/) 26 | { 27 | auto deliveryBox = NewObject(); 28 | 29 | deliveryBox->InitializeCustom(DefaultSerializerType, ObjectSerializerTypes, TargetClass); 30 | 31 | return deliveryBox; 32 | } 33 | 34 | UUtf8StringDeliveryBox* UDeliveryBoxFactory::CreateUtf8StringDeliveryBox() 35 | { 36 | return NewObject(); 37 | } -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/DeliveryBox/IODConvertPropertyName.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "DeliveryBox/IODConvertPropertyName.h" 3 | 4 | UODConvertPropertyName::UODConvertPropertyName(const class FObjectInitializer& ObjectInitializer) 5 | : Super(ObjectInitializer) 6 | { 7 | } 8 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/DeliveryBox/ODOverrideJsonSerializer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "DeliveryBox/ODOverrideJsonSerializer.h" 3 | #include "DeliveryBox/IODConvertPropertyName.h" 4 | #include "../Utils/JsonSerializer/ODJsonSerializer.h" 5 | #include "../Utils/JsonSerializer/ODJsonDeserializer.h" 6 | #include "../Utils/ODObjectUtil.h" 7 | 8 | TSharedPtr UODOverrideJsonSerializer::UObjectToJsonObject(UODJsonSerializer* JsonSerializer, const UObject* Obj, int64 CheckFlags, int64 SkipFlags) const 9 | { 10 | // invalid 11 | return TSharedPtr(); 12 | } 13 | 14 | UObject* UODOverrideJsonSerializer::JsonObjectTopUObject(UODJsonDeserializer* JsonDeserializer, const TSharedPtr JsonObject, UClass* TargetClass) const 15 | { 16 | return nullptr; 17 | } 18 | 19 | TSharedPtr UODNoWriteTypeJsonSerializer::UObjectToJsonObject(UODJsonSerializer* JsonSerializer, const UObject* Obj, int64 CheckFlags, int64 SkipFlags) const 20 | { 21 | TSharedPtr JsonObject = MakeShareable(new FJsonObject()); 22 | 23 | if (!Obj) return JsonObject; 24 | 25 | for (TFieldIterator PropIt(Obj->GetClass(), EFieldIteratorFlags::IncludeSuper); PropIt; ++PropIt) 26 | { 27 | JsonSerializer->AddJsonValue(JsonObject, Obj, *PropIt, CheckFlags, SkipFlags); 28 | } 29 | 30 | return JsonObject; 31 | } 32 | 33 | UObject* UODNoWriteTypeJsonSerializer::JsonObjectTopUObject(UODJsonDeserializer* JsonDeserializer, const TSharedPtr JsonObject, UClass* TargetClass) const 34 | { 35 | if (!TargetClass) return nullptr; 36 | 37 | UObject* createdObj = NewObject((UObject*)GetTransientPackage(), TargetClass); 38 | 39 | for (TFieldIterator PropIt(createdObj->GetClass()); PropIt; ++PropIt) 40 | { 41 | JsonDeserializer->JsonPropertyToFProperty(JsonObject, *PropIt, createdObj); 42 | } 43 | 44 | return createdObj; 45 | } 46 | 47 | TSharedPtr UODWriteTypeJsonSerializer::UObjectToJsonObject(UODJsonSerializer* JsonSerializer, const UObject* Obj, int64 CheckFlags, int64 SkipFlags) const 48 | { 49 | TSharedPtr JsonObject = MakeShareable(new FJsonObject()); 50 | 51 | if (!Obj) return JsonObject; 52 | 53 | JsonObject->SetStringField(TEXT("Type"), Obj->GetClass()->GetName()); 54 | 55 | TSharedPtr JsonObjectBody = MakeShareable(new FJsonObject()); 56 | 57 | for (TFieldIterator PropIt(Obj->GetClass(), EFieldIteratorFlags::IncludeSuper); PropIt; ++PropIt) 58 | { 59 | JsonSerializer->AddJsonValue(JsonObjectBody, Obj, *PropIt, CheckFlags, SkipFlags); 60 | } 61 | 62 | JsonObject->SetObjectField(TEXT("Body"), JsonObjectBody); 63 | 64 | return JsonObject; 65 | } 66 | 67 | UObject* UODWriteTypeJsonSerializer::JsonObjectTopUObject(UODJsonDeserializer* JsonDeserializer, const TSharedPtr JsonObject, UClass* TargetClass) const 68 | { 69 | FString typeValue; 70 | if (!JsonObject->TryGetStringField(TEXT("Type"), typeValue)) 71 | { 72 | return nullptr; 73 | } 74 | 75 | UClass* targetType; 76 | if (!UODObjectUtil::FindClass(typeValue, targetType)) 77 | { 78 | return nullptr; 79 | } 80 | 81 | UObject* createdObj = NewObject((UObject*)GetTransientPackage(), targetType); 82 | 83 | const TSharedPtr* bodyJsonObject; 84 | if (!JsonObject->TryGetObjectField(TEXT("Body"), bodyJsonObject)) 85 | { 86 | return nullptr; 87 | } 88 | 89 | for (TFieldIterator PropIt(createdObj->GetClass()); PropIt; ++PropIt) 90 | { 91 | JsonDeserializer->JsonPropertyToFProperty(*bodyJsonObject, *PropIt, createdObj); 92 | } 93 | 94 | return createdObj; 95 | } -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/DeliveryBox/ObjectDeliveryBoxUsingJson.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "DeliveryBox/ObjectDeliveryBoxUsingJson.h" 3 | #include "Utils/ODStringUtil.h" 4 | #include "../Utils/JsonSerializer/ODJsonDeserializer.h" 5 | #include "../Utils/JsonSerializer/ODJsonSerializer.h" 6 | 7 | UObjectDeliveryBoxUsingJson::UObjectDeliveryBoxUsingJson() 8 | { 9 | Serializer = CreateDefaultSubobject(TEXT("UODJsonSerializer")); 10 | Deserializer = CreateDefaultSubobject(TEXT("UODJsonDeserializer")); 11 | } 12 | 13 | UObjectDeliveryBoxUsingJson::~UObjectDeliveryBoxUsingJson() 14 | { 15 | } 16 | 17 | void UObjectDeliveryBoxUsingJson::Initialize(UClass* _TargetClass) 18 | { 19 | TargetClass = _TargetClass; 20 | } 21 | 22 | void UObjectDeliveryBoxUsingJson::InitializeCustom(EODJsonSerializeType DefaultSerializerType, const TMap& ObjectSerializerTypes, UClass* _TargetClass) 23 | { 24 | TargetClass = _TargetClass; 25 | Serializer->AddOverrideJsonSerializers(DefaultSerializerType, ObjectSerializerTypes); 26 | Deserializer->AddOverrideJsonSerializers(DefaultSerializerType, ObjectSerializerTypes); 27 | } 28 | 29 | void UObjectDeliveryBoxUsingJson::Send(const UObject* message, FString& makedJson) 30 | { 31 | SendTo(message, nullptr, makedJson); 32 | } 33 | 34 | void UObjectDeliveryBoxUsingJson::SendTo(const UObject* message, const UObjectDelivererProtocol* Destination, FString& makedJson) 35 | { 36 | auto jsonObject = Serializer->CreateJsonObject(message); 37 | 38 | FString OutputString; 39 | TSharedRef> Writer = TJsonWriterFactory<>::Create(&OutputString); 40 | FJsonSerializer::Serialize(jsonObject.ToSharedRef(), Writer); 41 | 42 | makedJson = OutputString; 43 | 44 | TArray buffer; 45 | UODStringUtil::StringToBuffer(OutputString, buffer); 46 | 47 | RequestSend.ExecuteIfBound(Destination, buffer); 48 | } 49 | 50 | void UObjectDeliveryBoxUsingJson::NotifyReceiveBuffer(const UObjectDelivererProtocol* FromObject, const TArray& buffer) 51 | { 52 | auto jsonString = UODStringUtil::BufferToString(buffer); 53 | 54 | TSharedRef> JsonReader = TJsonReaderFactory::Create(jsonString); 55 | TSharedPtr JsonObject = MakeShareable(new FJsonObject()); 56 | 57 | if (!FJsonSerializer::Deserialize(JsonReader, JsonObject) && JsonObject.IsValid()) return; 58 | 59 | UObject* createdObj = Deserializer->JsonObjectToUObject(JsonObject, TargetClass); 60 | 61 | Received.Broadcast(createdObj, jsonString, FromObject); 62 | } 63 | 64 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/DeliveryBox/Utf8StringDeliveryBox.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "DeliveryBox/Utf8StringDeliveryBox.h" 3 | #include "Utils/ODStringUtil.h" 4 | 5 | UUtf8StringDeliveryBox::UUtf8StringDeliveryBox() 6 | { 7 | 8 | } 9 | 10 | UUtf8StringDeliveryBox::~UUtf8StringDeliveryBox() 11 | { 12 | } 13 | 14 | void UUtf8StringDeliveryBox::Send(const FString& message) 15 | { 16 | SendTo(message, nullptr); 17 | } 18 | 19 | void UUtf8StringDeliveryBox::SendTo(const FString& message, const UObjectDelivererProtocol* Destination) 20 | { 21 | TArray buffer; 22 | UODStringUtil::StringToBuffer(message, buffer); 23 | 24 | RequestSend.ExecuteIfBound(Destination, buffer); 25 | } 26 | 27 | void UUtf8StringDeliveryBox::NotifyReceiveBuffer(const UObjectDelivererProtocol* FromObject, const TArray& buffer) 28 | { 29 | Received.Broadcast(UODStringUtil::BufferToString(buffer), FromObject); 30 | } 31 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/ObjectDeliverer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | 3 | #include "CoreMinimal.h" 4 | #include "Modules/ModuleManager.h" 5 | #include "IObjectDeliverer.h" 6 | 7 | 8 | class FObjectDeliverer : public IObjectDeliverer 9 | { 10 | /** IModuleInterface implementation */ 11 | virtual void StartupModule() override; 12 | virtual void ShutdownModule() override; 13 | }; 14 | 15 | IMPLEMENT_MODULE(FObjectDeliverer, ObjectDeliverer) 16 | 17 | 18 | 19 | void FObjectDeliverer::StartupModule() 20 | { 21 | } 22 | 23 | 24 | void FObjectDeliverer::ShutdownModule() 25 | { 26 | } 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/ObjectDelivererManager.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "ObjectDelivererManager.h" 3 | #include "Protocol/ObjectDelivererProtocol.h" 4 | #include "PacketRule/PacketRule.h" 5 | #include "DeliveryBox/DeliveryBox.h" 6 | #include "Async/Async.h" 7 | #include "Misc/ScopeLock.h" 8 | 9 | static FCriticalSection LockObj; 10 | 11 | UObjectDelivererManager* UObjectDelivererManager::CreateObjectDelivererManager(bool _IsEventWithGameThread /* = true*/) 12 | { 13 | auto manager = NewObject(); 14 | manager->IsEventWithGameThread = _IsEventWithGameThread; 15 | return manager; 16 | } 17 | 18 | UObjectDelivererManager::UObjectDelivererManager() 19 | : IsEventWithGameThread(true) 20 | , IsDestorying(false) 21 | { 22 | 23 | } 24 | 25 | UObjectDelivererManager::~UObjectDelivererManager() 26 | { 27 | } 28 | 29 | void UObjectDelivererManager::Start(UObjectDelivererProtocol* Protocol, UPacketRule* PacketRule, UDeliveryBox* _DeliveryBox) 30 | { 31 | if (!Protocol || !PacketRule) return; 32 | 33 | CurrentProtocol = Protocol; 34 | CurrentProtocol->SetPacketRule(PacketRule); 35 | 36 | DeliveryBox = _DeliveryBox; 37 | if (DeliveryBox) 38 | { 39 | DeliveryBox->RequestSend.BindLambda([this](const UObjectDelivererProtocol* Destination, const TArray& Buffer) 40 | { 41 | if (Destination) 42 | { 43 | SendTo(Buffer, Destination); 44 | } 45 | else 46 | { 47 | Send(Buffer); 48 | } 49 | 50 | }); 51 | } 52 | 53 | CurrentProtocol->Connected.BindLambda([this](const UObjectDelivererProtocol* ConnectedObject) 54 | { 55 | ConnectedList.Add(ConnectedObject); 56 | 57 | DispatchEvent([this, ConnectedObject]() 58 | { 59 | Connected.Broadcast(ConnectedObject); 60 | }); 61 | }); 62 | 63 | CurrentProtocol->Disconnected.BindLambda([this](const UObjectDelivererProtocol* DisconnectedObject) 64 | { 65 | if (ConnectedList.Contains(DisconnectedObject)) 66 | { 67 | ConnectedList.Remove(DisconnectedObject); 68 | } 69 | 70 | DispatchEvent([this, DisconnectedObject]() 71 | { 72 | Disconnected.Broadcast(DisconnectedObject); 73 | }); 74 | }); 75 | 76 | CurrentProtocol->ReceiveData.BindLambda([this](const UObjectDelivererProtocol* FromObject, const TArray& Buffer) 77 | { 78 | DispatchEvent([this, FromObject, Buffer]() { 79 | ReceiveData.Broadcast(FromObject, Buffer); 80 | 81 | if (DeliveryBox) 82 | { 83 | DeliveryBox->NotifyReceiveBuffer(FromObject, Buffer); 84 | } 85 | }); 86 | }); 87 | 88 | ConnectedList.SetNum(0); 89 | 90 | CurrentProtocol->Start(); 91 | } 92 | 93 | void UObjectDelivererManager::DispatchEvent(TFunction EventAction) 94 | { 95 | if (IsDestorying) return; 96 | if (!IsValid(this)) return; 97 | 98 | if (IsEventWithGameThread) 99 | { 100 | AsyncTask(ENamedThreads::GameThread, [this, EventAction]() { 101 | if (IsDestorying) return; 102 | EventAction(); 103 | }); 104 | } 105 | else 106 | { 107 | EventAction(); 108 | } 109 | } 110 | 111 | void UObjectDelivererManager::Close() 112 | { 113 | if (!IsValid(CurrentProtocol)) return; 114 | 115 | if (DeliveryBox) 116 | { 117 | if (DeliveryBox->RequestSend.IsBound()) 118 | { 119 | DeliveryBox->RequestSend.Unbind(); 120 | } 121 | } 122 | 123 | if (CurrentProtocol->Connected.IsBound()) 124 | { 125 | CurrentProtocol->Connected.Unbind(); 126 | } 127 | 128 | if (CurrentProtocol->Disconnected.IsBound()) 129 | { 130 | CurrentProtocol->Disconnected.Unbind(); 131 | } 132 | 133 | if (CurrentProtocol->ReceiveData.IsBound()) 134 | { 135 | CurrentProtocol->ReceiveData.Unbind(); 136 | } 137 | 138 | CurrentProtocol->Close(); 139 | 140 | CurrentProtocol = nullptr; 141 | } 142 | 143 | void UObjectDelivererManager::Send(const TArray& DataBuffer) 144 | { 145 | if (!CurrentProtocol) return; 146 | if (IsDestorying) return; 147 | 148 | CurrentProtocol->Send(DataBuffer); 149 | } 150 | 151 | void UObjectDelivererManager::SendTo(const TArray& DataBuffer, const UObjectDelivererProtocol* Target) 152 | { 153 | if (!CurrentProtocol) return; 154 | if (IsDestorying) return; 155 | 156 | Target->Send(DataBuffer); 157 | } 158 | 159 | bool UObjectDelivererManager::IsConnected() 160 | { 161 | return ConnectedList.Num() > 0; 162 | } 163 | 164 | void UObjectDelivererManager::BeginDestroy() 165 | { 166 | IsDestorying = true; 167 | 168 | Close(); 169 | 170 | Super::BeginDestroy(); 171 | 172 | } -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/PacketRule/PacketRule.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "PacketRule/PacketRule.h" 3 | 4 | UPacketRule::UPacketRule() 5 | { 6 | 7 | } 8 | 9 | UPacketRule::~UPacketRule() 10 | { 11 | } 12 | 13 | void UPacketRule::Initialize() 14 | { 15 | 16 | } 17 | 18 | void UPacketRule::MakeSendPacket(const TArray& BodyBuffer) 19 | { 20 | } 21 | 22 | void UPacketRule::NotifyReceiveData(const TArray& DataBuffer) 23 | { 24 | } 25 | 26 | int32 UPacketRule::GetWantSize() 27 | { 28 | return 0; 29 | } 30 | 31 | UPacketRule* UPacketRule::Clone() 32 | { 33 | 34 | return nullptr; 35 | } 36 | 37 | void UPacketRule::DispatchMadeSendBuffer(const TArray& SendBuffer) 38 | { 39 | MadeSendBuffer.ExecuteIfBound(SendBuffer); 40 | } 41 | 42 | void UPacketRule::DispatchMadeReceiveBuffer(const TArray& ReceiveBuffer) 43 | { 44 | MadeReceiveBuffer.ExecuteIfBound(ReceiveBuffer); 45 | } -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/PacketRule/PacketRuleFactory.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "PacketRule/PacketRuleFactory.h" 3 | #include "PacketRule/PacketRuleFixedLength.h" 4 | #include "PacketRule/PacketRuleSizeBody.h" 5 | #include "PacketRule/PacketRuleTerminate.h" 6 | #include "PacketRule/PacketRuleNodivision.h" 7 | 8 | UPacketRuleFixedLength* UPacketRuleFactory::CreatePacketRuleFixedLength(int32 FixedSize) 9 | { 10 | auto PacketRule = NewObject(); 11 | PacketRule->FixedSize = FixedSize; 12 | return PacketRule; 13 | } 14 | 15 | UPacketRuleSizeBody* UPacketRuleFactory::CreatePacketRuleSizeBody(int32 SizeLength, ECNBufferEndian SizeBufferEndian) 16 | { 17 | auto PacketRule = NewObject(); 18 | PacketRule->SizeLength = SizeLength; 19 | PacketRule->SizeBufferEndian = SizeBufferEndian; 20 | return PacketRule; 21 | } 22 | 23 | UPacketRuleTerminate* UPacketRuleFactory::CreatePacketRuleTerminate(const TArray& Terminate) 24 | { 25 | auto PacketRule = NewObject(); 26 | 27 | if (Terminate.Num() > 0) 28 | { 29 | PacketRule->Terminate = Terminate; 30 | } 31 | return PacketRule; 32 | } 33 | 34 | UPacketRuleNodivision* UPacketRuleFactory::CreatePacketRuleNodivision() 35 | { 36 | return NewObject(); 37 | } -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/PacketRule/PacketRuleFixedLength.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "PacketRule/PacketRuleFixedLength.h" 3 | #include "PacketRule/PacketRuleFactory.h" 4 | 5 | UPacketRuleFixedLength::UPacketRuleFixedLength() 6 | { 7 | 8 | } 9 | 10 | UPacketRuleFixedLength::~UPacketRuleFixedLength() 11 | { 12 | } 13 | 14 | void UPacketRuleFixedLength::Initialize() 15 | { 16 | BufferForSend.SetNum(FixedSize); 17 | } 18 | 19 | void UPacketRuleFixedLength::MakeSendPacket(const TArray& BodyBuffer) 20 | { 21 | FMemory::Memzero(BufferForSend.GetData(), BufferForSend.Num()); 22 | FMemory::Memcpy(BufferForSend.GetData(), BodyBuffer.GetData(), FMath::Min(BodyBuffer.Num(), FixedSize)); 23 | 24 | DispatchMadeSendBuffer(BufferForSend); 25 | } 26 | 27 | void UPacketRuleFixedLength::NotifyReceiveData(const TArray& DataBuffer) 28 | { 29 | DispatchMadeReceiveBuffer(DataBuffer); 30 | } 31 | 32 | int32 UPacketRuleFixedLength::GetWantSize() 33 | { 34 | return FixedSize; 35 | } 36 | 37 | UPacketRule* UPacketRuleFixedLength::Clone() 38 | { 39 | return UPacketRuleFactory::CreatePacketRuleFixedLength(FixedSize); 40 | } -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/PacketRule/PacketRuleNodivision.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "PacketRule/PacketRuleNodivision.h" 3 | #include "PacketRule/PacketRuleFactory.h" 4 | 5 | UPacketRuleNodivision::UPacketRuleNodivision() 6 | { 7 | } 8 | 9 | UPacketRuleNodivision::~UPacketRuleNodivision() 10 | { 11 | } 12 | 13 | void UPacketRuleNodivision::Initialize() 14 | { 15 | } 16 | 17 | void UPacketRuleNodivision::MakeSendPacket(const TArray& BodyBuffer) 18 | { 19 | DispatchMadeSendBuffer(BodyBuffer); 20 | } 21 | 22 | void UPacketRuleNodivision::NotifyReceiveData(const TArray& DataBuffer) 23 | { 24 | DispatchMadeReceiveBuffer(DataBuffer); 25 | } 26 | 27 | int32 UPacketRuleNodivision::GetWantSize() 28 | { 29 | return 0; 30 | } 31 | 32 | UPacketRule* UPacketRuleNodivision::Clone() 33 | { 34 | return UPacketRuleFactory::CreatePacketRuleNodivision(); 35 | } -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/PacketRule/PacketRuleSizeBody.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "PacketRule/PacketRuleSizeBody.h" 3 | #include "PacketRule/PacketRuleFactory.h" 4 | 5 | UPacketRuleSizeBody::UPacketRuleSizeBody() 6 | { 7 | 8 | } 9 | 10 | UPacketRuleSizeBody::~UPacketRuleSizeBody() 11 | { 12 | } 13 | 14 | void UPacketRuleSizeBody::Initialize() 15 | { 16 | BufferForSend.SetNum(1024); 17 | ReceiveMode = EReceiveMode::Size; 18 | BodySize = 0; 19 | } 20 | 21 | void UPacketRuleSizeBody::MakeSendPacket(const TArray& BodyBuffer) 22 | { 23 | const auto BodyBufferNum{ BodyBuffer.Num() }; 24 | BufferForSend.SetNum(BodyBufferNum + SizeLength, EAllowShrinking::No); 25 | 26 | for (decltype(SizeLength) i{ 0u }; i < SizeLength; i++) 27 | if (BufferForSend.IsValidIndex(i)) 28 | BufferForSend[i] = (BodyBufferNum >> (SizeBufferEndian == ECNBufferEndian::Big ? 8 * (SizeLength - i - 1) : 8 * i)) & 0xFF; 29 | 30 | FMemory::Memcpy(BufferForSend.GetData() + SizeLength, BodyBuffer.GetData(), BodyBufferNum); 31 | DispatchMadeSendBuffer(BufferForSend); 32 | } 33 | 34 | void UPacketRuleSizeBody::NotifyReceiveData(const TArray& DataBuffer) 35 | { 36 | if (ReceiveMode == EReceiveMode::Size) 37 | { 38 | OnReceivedSize(DataBuffer); 39 | return; 40 | } 41 | 42 | OnReceivedBody(DataBuffer); 43 | } 44 | 45 | void UPacketRuleSizeBody::OnReceivedSize(const TArray& DataBuffer) 46 | { 47 | BodySize = 0; 48 | for (int i = 0; i < SizeLength; ++i) 49 | { 50 | int32 offset = 0; 51 | if (SizeBufferEndian == ECNBufferEndian::Big) 52 | { 53 | offset = 8 * (SizeLength - i - 1); 54 | } 55 | else 56 | { 57 | offset = 8 * i; 58 | } 59 | BodySize |= (DataBuffer[i] << offset); 60 | } 61 | 62 | ReceiveMode = EReceiveMode::Body; 63 | } 64 | 65 | void UPacketRuleSizeBody::OnReceivedBody(const TArray& DataBuffer) 66 | { 67 | DispatchMadeReceiveBuffer(DataBuffer); 68 | 69 | BodySize = 0; 70 | 71 | ReceiveMode = EReceiveMode::Size; 72 | } 73 | 74 | int32 UPacketRuleSizeBody::GetWantSize() 75 | { 76 | if (ReceiveMode == EReceiveMode::Size) 77 | { 78 | return SizeLength; 79 | } 80 | 81 | return BodySize; 82 | } 83 | 84 | UPacketRule* UPacketRuleSizeBody::Clone() 85 | { 86 | return UPacketRuleFactory::CreatePacketRuleSizeBody(SizeLength, SizeBufferEndian); 87 | } -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/PacketRule/PacketRuleTerminate.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "PacketRule/PacketRuleTerminate.h" 3 | #include "PacketRule/PacketRuleFactory.h" 4 | 5 | UPacketRuleTerminate::UPacketRuleTerminate() 6 | { 7 | Terminate.Add(TEXT('\r')); 8 | Terminate.Add(TEXT('\n')); 9 | } 10 | 11 | UPacketRuleTerminate::~UPacketRuleTerminate() 12 | { 13 | } 14 | 15 | void UPacketRuleTerminate::Initialize() 16 | { 17 | BufferForSend.Reset(1024); 18 | ReceiveTempBuffer.Reset(1024); 19 | BufferForReceive.Reset(1024); 20 | } 21 | 22 | void UPacketRuleTerminate::MakeSendPacket(const TArray& BodyBuffer) 23 | { 24 | const auto BodyCount{ BodyBuffer.Num() }; 25 | const auto TerminateCount{ Terminate.Num() }; 26 | BufferForSend.SetNum(BodyCount + TerminateCount, EAllowShrinking::No); 27 | const auto BufferForSendData{ BufferForSend.GetData() }; 28 | FMemory::Memcpy(BufferForSendData, BodyBuffer.GetData(), BodyCount); 29 | FMemory::Memcpy(BufferForSendData + BodyCount, Terminate.GetData(), TerminateCount); 30 | DispatchMadeSendBuffer(BufferForSend); 31 | } 32 | 33 | void UPacketRuleTerminate::NotifyReceiveData(const TArray& DataBuffer) 34 | { 35 | ReceiveTempBuffer += DataBuffer; 36 | const auto TerminateCount{ Terminate.Num() }; 37 | 38 | while (ReceiveTempBuffer.Num() >= TerminateCount) 39 | { 40 | int32 findIndex{ INDEX_NONE }; 41 | 42 | for (int32 i{ 0 }, count{ ReceiveTempBuffer.Num() - TerminateCount }; i <= count; i++) 43 | { 44 | auto bTerminate{ true }; 45 | 46 | for (decltype(i) j{ 0u }; j < TerminateCount; j++) 47 | { 48 | if (ReceiveTempBuffer[i + j] == Terminate[j]) 49 | continue; 50 | 51 | bTerminate = false; 52 | break; 53 | } 54 | 55 | if (!bTerminate) 56 | continue; 57 | 58 | findIndex = MoveTemp(i); 59 | break; 60 | } 61 | 62 | if (findIndex <= INDEX_NONE) 63 | return; 64 | 65 | BufferForReceive.SetNum(findIndex, EAllowShrinking::No); 66 | FMemory::Memcpy(BufferForReceive.GetData(), ReceiveTempBuffer.GetData(), findIndex); 67 | DispatchMadeReceiveBuffer(BufferForReceive); 68 | ReceiveTempBuffer.RemoveAt(0, findIndex + Terminate.Num()); 69 | } 70 | } 71 | 72 | int32 UPacketRuleTerminate::GetWantSize() 73 | { 74 | return 0; 75 | } 76 | 77 | UPacketRule* UPacketRuleTerminate::Clone() 78 | { 79 | return UPacketRuleFactory::CreatePacketRuleTerminate(Terminate); 80 | } -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Protocol/ObjectDelivererProtocol.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "Protocol/ObjectDelivererProtocol.h" 3 | #include "PacketRule/PacketRule.h" 4 | 5 | UObjectDelivererProtocol::UObjectDelivererProtocol() 6 | { 7 | 8 | } 9 | 10 | UObjectDelivererProtocol::~UObjectDelivererProtocol() 11 | { 12 | } 13 | 14 | void UObjectDelivererProtocol::Start() 15 | { 16 | } 17 | 18 | void UObjectDelivererProtocol::Close() 19 | { 20 | 21 | } 22 | 23 | void UObjectDelivererProtocol::Send(const TArray& DataBuffer) const 24 | { 25 | 26 | } 27 | 28 | void UObjectDelivererProtocol::DispatchConnected(const UObjectDelivererProtocol* ConnectedObject) 29 | { 30 | Connected.ExecuteIfBound(ConnectedObject); 31 | } 32 | 33 | void UObjectDelivererProtocol::DispatchDisconnected(const UObjectDelivererProtocol* DisconnectedObject) 34 | { 35 | Disconnected.ExecuteIfBound(DisconnectedObject); 36 | } 37 | 38 | void UObjectDelivererProtocol::DispatchReceiveData(const UObjectDelivererProtocol* FromObject, const TArray& Buffer) 39 | { 40 | ReceiveData.ExecuteIfBound(FromObject, Buffer); 41 | } 42 | 43 | void UObjectDelivererProtocol::BeginDestroy() 44 | { 45 | Close(); 46 | 47 | Super::BeginDestroy(); 48 | } 49 | 50 | void UObjectDelivererProtocol::SetPacketRule(UPacketRule* _PacketRule) 51 | { 52 | PacketRule = _PacketRule; 53 | PacketRule->Initialize(); 54 | 55 | PacketRule->MadeSendBuffer.BindLambda([this](const TArray& Buffer) 56 | { 57 | RequestSend(Buffer); 58 | }); 59 | 60 | PacketRule->MadeReceiveBuffer.BindLambda([this](const TArray& Buffer) 61 | { 62 | DispatchReceiveData(this, Buffer); 63 | }); 64 | } 65 | 66 | void UObjectDelivererProtocol::RequestSend(const TArray& DataBuffer) 67 | { 68 | 69 | } -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Protocol/ProtocolFactory.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "Protocol/ProtocolFactory.h" 3 | #include "Protocol/ProtocolTcpIpClient.h" 4 | #include "Protocol/ProtocolTcpIpServer.h" 5 | #include "Protocol/ProtocolUdpSocketSender.h" 6 | #include "Protocol/ProtocolUdpSocketReceiver.h" 7 | #include "Protocol/ProtocolSharedMemory.h" 8 | #include "Protocol/ProtocolLogReader.h" 9 | #include "Protocol/ProtocolLogWriter.h" 10 | #include "Protocol/ProtocolReflection.h" 11 | 12 | UProtocolTcpIpClient *UProtocolFactory::CreateProtocolTcpIpClient(const FString &IpAddress /*="localhost"*/, int32 Port /*= 8000*/, bool Retry /*= false*/, bool AutoConnectAfterDisconnect /*= false*/) 13 | { 14 | auto protocol = NewObject(); 15 | protocol->Initialize(IpAddress, Port, Retry, AutoConnectAfterDisconnect); 16 | return protocol; 17 | } 18 | 19 | UProtocolTcpIpServer *UProtocolFactory::CreateProtocolTcpIpServer(int32 Port /*= 8000*/) 20 | { 21 | auto protocol = NewObject(); 22 | protocol->Initialize(Port); 23 | return protocol; 24 | } 25 | 26 | UProtocolUdpSocketSender *UProtocolFactory::CreateProtocolUdpSocketSender(const FString &IpAddress /*="localhost"*/, int32 Port /*= 8000*/) 27 | { 28 | auto protocol = NewObject(); 29 | protocol->Initialize(IpAddress, Port); 30 | return protocol; 31 | } 32 | 33 | UProtocolUdpSocketSender *UProtocolFactory::CreateProtocolUdpSocketSenderWithBroadcast(const FString &IpAddress /*="localhost"*/, int32 Port /*= 8000*/, bool EnableBroadcast /*= true*/) 34 | { 35 | auto protocol = NewObject(); 36 | protocol->Initialize(IpAddress, Port); 37 | protocol->WithBroadcast(EnableBroadcast); 38 | return protocol; 39 | } 40 | 41 | UProtocolUdpSocketReceiver *UProtocolFactory::CreateProtocolUdpSocketReceiver(int32 BoundPort /*= 8000*/) 42 | { 43 | auto protocol = NewObject(); 44 | protocol->InitializeWithReceiver(BoundPort); 45 | return protocol; 46 | } 47 | 48 | UProtocolSharedMemory *UProtocolFactory::CreateProtocolSharedMemory(FString SharedMemoryName /* = "SharedMemory"*/, int32 SharedMemorySize /* = 1024*/) 49 | { 50 | auto protocol = NewObject(); 51 | protocol->Initialize(SharedMemoryName, SharedMemorySize); 52 | return protocol; 53 | } 54 | 55 | UProtocolLogReader *UProtocolFactory::CreateProtocolLogReader(const FString &FilePath /*= "log.bin"*/, bool PathIsAbsolute /*= false*/, bool CutFirstInterval /*= true*/) 56 | { 57 | auto protocol = NewObject(); 58 | protocol->Initialize(FilePath, PathIsAbsolute, CutFirstInterval); 59 | return protocol; 60 | } 61 | 62 | UProtocolLogWriter *UProtocolFactory::CreateProtocolLogWriter(const FString &FilePath /*= "log.bin"*/, bool PathIsAbsolutePath /* = false*/) 63 | { 64 | auto protocol = NewObject(); 65 | protocol->Initialize(FilePath, PathIsAbsolutePath); 66 | return protocol; 67 | } 68 | 69 | UProtocolReflection *UProtocolFactory::CreateProtocolReflection() 70 | { 71 | return NewObject(); 72 | } 73 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Protocol/ProtocolLogReader.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "Protocol/ProtocolLogReader.h" 3 | #include "PacketRule/PacketRule.h" 4 | #include "Utils/ODFileUtil.h" 5 | #include "Utils/ODWorkerThread.h" 6 | #include "HAL/RunnableThread.h" 7 | #include "Misc/Paths.h" 8 | 9 | 10 | UProtocolLogReader::UProtocolLogReader() 11 | : Reader(nullptr) 12 | , CurrentLogTime(-1) 13 | , FilePosition(0) 14 | , IsFirst(true) 15 | { 16 | 17 | } 18 | 19 | UProtocolLogReader::~UProtocolLogReader() 20 | { 21 | 22 | } 23 | 24 | void UProtocolLogReader::Initialize(const FString& _FilePath, bool _PathIsAbsolute, bool _CutFirstInterval) 25 | { 26 | FilePath = _FilePath; 27 | PathIsAbsolute = _PathIsAbsolute; 28 | CutFirstInterval = _CutFirstInterval; 29 | 30 | ReceiveBuffer.SetNum(1024); 31 | } 32 | 33 | void UProtocolLogReader::Start() 34 | { 35 | if (Reader) delete Reader; 36 | 37 | auto readPath = FilePath; 38 | if (!PathIsAbsolute) 39 | { 40 | readPath = FPaths::Combine(FPaths::ProjectLogDir(), FilePath); 41 | } 42 | 43 | Reader = new ODFileReaderUtil(); 44 | Reader->Open(readPath, 0); 45 | 46 | StartTime = FDateTime::Now(); 47 | CurrentLogTime = -1; 48 | IsFirst = true; 49 | 50 | CurrentInnerThread = new FODWorkerThread([this] { return ReadData(); }, [this] { return ReadEnd(); }, 0.001); 51 | CurrentThread = FRunnableThread::Create(CurrentInnerThread, TEXT("ObjectDeliverer ProtocolLogReader PollingThread")); 52 | 53 | DispatchConnected(this); 54 | } 55 | 56 | void UProtocolLogReader::Close() 57 | { 58 | if (!CurrentThread) return; 59 | CurrentThread->Kill(true); 60 | 61 | delete CurrentThread; 62 | CurrentThread = nullptr; 63 | 64 | if (!CurrentInnerThread) return; 65 | delete CurrentInnerThread; 66 | CurrentInnerThread = nullptr; 67 | 68 | if (!Reader) return; 69 | 70 | Reader->Close(); 71 | delete Reader; 72 | Reader = nullptr; 73 | } 74 | 75 | void UProtocolLogReader::Send(const TArray& DataBuffer) const 76 | { 77 | 78 | } 79 | 80 | void UProtocolLogReader::RequestSend(const TArray& DataBuffer) 81 | { 82 | 83 | } 84 | 85 | bool UProtocolLogReader::ReadData() 86 | { 87 | if (!Reader) 88 | return false; 89 | 90 | while (!Reader->IsEnd() || CurrentLogTime >= 0) 91 | { 92 | if (CurrentLogTime >= 0) 93 | { 94 | const auto nowTime{ (FDateTime::Now() - StartTime).GetTotalMilliseconds() }; 95 | 96 | if (CurrentLogTime > nowTime) 97 | break; 98 | 99 | auto Size{ ReadBuffer.Num() }; 100 | auto wantSize{ PacketRule->GetWantSize() }; 101 | 102 | if (wantSize > 0 && Size < wantSize) 103 | return true; 104 | 105 | auto Offset{ 0u }; 106 | 107 | while (Size > 0) 108 | { 109 | wantSize = PacketRule->GetWantSize(); 110 | const auto receiveSize{ wantSize == 0 ? Size : wantSize }; 111 | ReceiveBuffer.SetNum(receiveSize, EAllowShrinking::No); 112 | FMemory::Memcpy(ReceiveBuffer.GetData(), ReadBuffer.GetData() + Offset, receiveSize); 113 | Offset += receiveSize; 114 | Size -= receiveSize; 115 | PacketRule->NotifyReceiveData(ReceiveBuffer); 116 | } 117 | 118 | CurrentLogTime = -1; 119 | } 120 | 121 | if (Reader->RemainSize() < sizeof(double)) 122 | return false; 123 | 124 | CurrentLogTime = Reader->Read(); 125 | 126 | if (IsFirst && CutFirstInterval) 127 | StartTime -= FTimespan::FromMilliseconds(CurrentLogTime); 128 | 129 | IsFirst = false; 130 | 131 | if (Reader->RemainSize() < sizeof(int32)) 132 | return false; 133 | 134 | const auto bufferSize{ Reader->Read() }; 135 | 136 | if (Reader->RemainSize() < bufferSize) 137 | return false; 138 | 139 | ReadBuffer.SetNum(bufferSize, EAllowShrinking::No); 140 | Reader->Read(ReadBuffer, bufferSize); 141 | } 142 | 143 | return true; 144 | } 145 | 146 | void UProtocolLogReader::ReadEnd() 147 | { 148 | DispatchDisconnected(this); 149 | } 150 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Protocol/ProtocolLogWriter.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "Protocol/ProtocolLogWriter.h" 3 | #include "PacketRule/PacketRule.h" 4 | #include "Utils/ODFileUtil.h" 5 | #include "Misc/Paths.h" 6 | 7 | UProtocolLogWriter::UProtocolLogWriter() 8 | : Writer(nullptr) 9 | { 10 | 11 | } 12 | 13 | UProtocolLogWriter::~UProtocolLogWriter() 14 | { 15 | 16 | } 17 | 18 | void UProtocolLogWriter::Initialize(const FString& _FilePath, bool _PathIsAbsolute) 19 | { 20 | FilePath = _FilePath; 21 | PathIsAbsolute = _PathIsAbsolute; 22 | } 23 | 24 | void UProtocolLogWriter::Start() 25 | { 26 | if (Writer) delete Writer; 27 | 28 | auto writePath = FilePath; 29 | if (!PathIsAbsolute) 30 | { 31 | writePath = FPaths::Combine(FPaths::ProjectLogDir(), FilePath); 32 | } 33 | 34 | Writer = new ODFileWriterUtil(); 35 | Writer->Open(writePath, 0); 36 | 37 | StartTime = FDateTime::Now(); 38 | 39 | DispatchConnected(this); 40 | } 41 | 42 | void UProtocolLogWriter::Close() 43 | { 44 | if (!Writer) return; 45 | 46 | Writer->Close(); 47 | delete Writer; 48 | Writer = nullptr; 49 | } 50 | 51 | void UProtocolLogWriter::Send(const TArray& DataBuffer) const 52 | { 53 | PacketRule->MakeSendPacket(DataBuffer); 54 | } 55 | 56 | void UProtocolLogWriter::RequestSend(const TArray& DataBuffer) 57 | { 58 | if (!Writer) return; 59 | 60 | auto time = (FDateTime::Now() - StartTime).GetTotalMilliseconds(); 61 | Writer->Write(time); 62 | Writer->Write(DataBuffer.Num()); 63 | Writer->Write(DataBuffer); 64 | } 65 | 66 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Protocol/ProtocolReflection.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "Protocol/ProtocolReflection.h" 3 | #include "PacketRule/PacketRule.h" 4 | 5 | 6 | UProtocolReflection::UProtocolReflection() 7 | { 8 | 9 | } 10 | 11 | UProtocolReflection::~UProtocolReflection() 12 | { 13 | 14 | } 15 | 16 | void UProtocolReflection::Send(const TArray& DataBuffer) const 17 | { 18 | PacketRule->MakeSendPacket(DataBuffer); 19 | } 20 | 21 | void UProtocolReflection::RequestSend(const TArray& DataBuffer) 22 | { 23 | DispatchReceiveData(this, DataBuffer); 24 | } 25 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Protocol/ProtocolSharedMemory.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "Protocol/ProtocolSharedMemory.h" 3 | #include "Utils/ODWorkerThread.h" 4 | #include "HAL/RunnableThread.h" 5 | #include "PacketRule/PacketRule.h" 6 | 7 | #if PLATFORM_WINDOWS 8 | #include "Utils/ODMutexLock.h" 9 | #include "Windows/WindowsHWrapper.h" 10 | #endif 11 | 12 | UProtocolSharedMemory::UProtocolSharedMemory() 13 | : SharedMemoryHandle(nullptr), SharedMemoryData(nullptr), SharedMemoryMutex(nullptr), NowCounter(0) 14 | { 15 | } 16 | 17 | UProtocolSharedMemory::~UProtocolSharedMemory() 18 | { 19 | } 20 | 21 | void UProtocolSharedMemory::Initialize(const FString &_SharedMemoryName /* = "SharedMemory"*/, int32 _SharedMemorySize /* = 1024*/) 22 | { 23 | SharedMemoryName = _SharedMemoryName; 24 | SharedMemorySize = _SharedMemorySize; 25 | } 26 | 27 | void UProtocolSharedMemory::Start() 28 | { 29 | #if PLATFORM_WINDOWS 30 | /* Create a named mutex for inter-process protection of data */ 31 | FString mutexName = SharedMemoryName + "MUTEX"; 32 | SharedMemoryTotalSize = SharedMemorySize + sizeof(uint8) + sizeof(int32); 33 | 34 | SharedMemoryMutex = CreateMutex(NULL, false, *mutexName); 35 | 36 | if (SharedMemoryMutex == nullptr) 37 | return; 38 | 39 | SharedMemoryHandle = CreateFileMapping((HANDLE)INVALID_HANDLE_VALUE, 40 | NULL, 41 | PAGE_READWRITE, 42 | 0, 43 | SharedMemoryTotalSize, 44 | *SharedMemoryName); 45 | 46 | if (SharedMemoryHandle == nullptr) 47 | { 48 | CloseSharedMemory(); 49 | return; 50 | } 51 | 52 | SharedMemoryData = (unsigned char *)MapViewOfFile(SharedMemoryHandle, 53 | FILE_MAP_ALL_ACCESS, 54 | 0, 0, 55 | SharedMemoryTotalSize); 56 | 57 | if (!SharedMemoryData) 58 | { 59 | CloseSharedMemory(); 60 | return; 61 | } 62 | 63 | ODMutexLock::Lock(SharedMemoryMutex, [this]() 64 | { FMemory::Memset(SharedMemoryData, 0, SharedMemoryTotalSize); }); 65 | 66 | NowCounter = 0; 67 | 68 | #else 69 | return; 70 | #endif 71 | 72 | ReceiveBuffer.SetNum(SharedMemoryTotalSize); 73 | CurrentInnerThread = new FODWorkerThread([this] 74 | { return ReceivedData(); }); 75 | CurrentThread = FRunnableThread::Create(CurrentInnerThread, TEXT("ObjectDeliverer ProtocolSharedMemory PollingThread")); 76 | 77 | DispatchConnected(this); 78 | } 79 | 80 | void UProtocolSharedMemory::Close() 81 | { 82 | #if PLATFORM_WINDOWS 83 | ODMutexLock::Lock(SharedMemoryMutex, [this]() 84 | { 85 | if (!CurrentThread) return; 86 | CurrentThread->Kill(true); 87 | 88 | delete CurrentThread; 89 | CurrentThread = nullptr; 90 | 91 | if (!CurrentInnerThread) return; 92 | delete CurrentInnerThread; 93 | CurrentInnerThread = nullptr; 94 | 95 | CloseSharedMemory(); }); 96 | #endif 97 | } 98 | 99 | bool UProtocolSharedMemory::ReceivedData() 100 | { 101 | #if PLATFORM_WINDOWS 102 | 103 | uint32 Size{0u}; 104 | 105 | ODMutexLock::Lock( 106 | SharedMemoryMutex, 107 | [this, &Size]() noexcept 108 | { 109 | uint8 counter{0u}; 110 | const auto uint8size{sizeof(uint8)}; 111 | FMemory::Memcpy(&counter, SharedMemoryData, uint8size); 112 | 113 | if (counter == NowCounter) 114 | return; 115 | 116 | NowCounter = MoveTemp(counter); 117 | const auto NextSharedMemoryData{SharedMemoryData + uint8size}; 118 | const auto uint32size{sizeof(uint32)}; 119 | FMemory::Memcpy(&Size, NextSharedMemoryData, uint32size); 120 | 121 | // Validate size to prevent buffer overflow or invalid memory allocation 122 | // Check if size is within reasonable limits 123 | const uint32 MaxAllowedSize = static_cast(SharedMemorySize); 124 | if (Size == 0 || Size > MaxAllowedSize) 125 | { 126 | // Invalid size detected, either 0 or exceeds shared memory size 127 | UE_LOG(LogTemp, Warning, TEXT("ProtocolSharedMemory: Invalid data size detected (%u), ignoring packet"), Size); 128 | Size = 0; 129 | return; 130 | } 131 | 132 | TempBuffer.SetNum(Size, EAllowShrinking::No); 133 | FMemory::Memcpy(TempBuffer.GetData(), NextSharedMemoryData + uint32size, FMath::Min(StaticCast(SharedMemorySize), Size)); 134 | }); 135 | 136 | if (Size == 0) 137 | return true; 138 | 139 | auto wantSize{PacketRule->GetWantSize()}; 140 | 141 | if (wantSize > 0 && Size < StaticCast(wantSize)) 142 | return true; 143 | 144 | decltype(Size) Offset{0u}; 145 | 146 | while (Size > 0u) 147 | { 148 | wantSize = PacketRule->GetWantSize(); 149 | const auto receiveSize{wantSize == 0 ? Size : wantSize}; 150 | 151 | // Additional check to prevent overflow 152 | // Use static_cast to ensure proper comparison between signed and unsigned values 153 | if (receiveSize > Size || receiveSize > static_cast(SharedMemorySize)) 154 | { 155 | UE_LOG(LogTemp, Warning, TEXT("ProtocolSharedMemory: Invalid receive size detected, aborting packet processing")); 156 | break; 157 | } 158 | 159 | ReceiveBuffer.SetNum(receiveSize, EAllowShrinking::No); 160 | FMemory::Memcpy(ReceiveBuffer.GetData(), TempBuffer.GetData() + Offset, receiveSize); 161 | Offset += receiveSize; 162 | Size -= receiveSize; 163 | PacketRule->NotifyReceiveData(ReceiveBuffer); 164 | } 165 | 166 | return true; 167 | 168 | #else 169 | 170 | return false; 171 | 172 | #endif 173 | } 174 | 175 | void UProtocolSharedMemory::Send(const TArray &DataBuffer) const 176 | { 177 | #if PLATFORM_WINDOWS 178 | if (!SharedMemoryHandle) 179 | return; 180 | 181 | PacketRule->MakeSendPacket(DataBuffer); 182 | #endif 183 | } 184 | 185 | void UProtocolSharedMemory::RequestSend(const TArray &DataBuffer) 186 | { 187 | #if PLATFORM_WINDOWS 188 | if (DataBuffer.Num() > SharedMemorySize) 189 | return; 190 | 191 | if (SharedMemoryMutex && SharedMemoryData) 192 | { 193 | int32 writeSize = DataBuffer.Num(); 194 | 195 | ODMutexLock::Lock(SharedMemoryMutex, [this, writeSize, &DataBuffer]() 196 | { 197 | NowCounter++; 198 | if (NowCounter == 0) 199 | { 200 | NowCounter = 1; 201 | } 202 | 203 | FMemory::Memcpy(SharedMemoryData, &NowCounter, sizeof(uint8)); 204 | 205 | FMemory::Memcpy(SharedMemoryData + sizeof(uint8), &writeSize, sizeof(int32)); 206 | FMemory::Memcpy(SharedMemoryData + sizeof(uint8) + sizeof(int32), DataBuffer.GetData(), writeSize); 207 | 208 | FlushViewOfFile(SharedMemoryData, sizeof(uint8) + sizeof(int32) + writeSize); }); 209 | } 210 | #endif 211 | } 212 | 213 | void UProtocolSharedMemory::CloseSharedMemory() 214 | { 215 | #if PLATFORM_WINDOWS 216 | if (SharedMemoryMutex != nullptr) 217 | { 218 | ReleaseMutex(SharedMemoryMutex); 219 | CloseHandle(SharedMemoryMutex); 220 | SharedMemoryMutex = nullptr; 221 | } 222 | 223 | if (SharedMemoryData != nullptr) 224 | { 225 | UnmapViewOfFile(SharedMemoryData); 226 | SharedMemoryData = nullptr; 227 | } 228 | 229 | if (SharedMemoryHandle != nullptr) 230 | { 231 | CloseHandle(SharedMemoryHandle); 232 | SharedMemoryHandle = nullptr; 233 | } 234 | #endif 235 | } -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Protocol/ProtocolSocketBase.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "Protocol/ProtocolSocketBase.h" 3 | #include "Misc/OutputDeviceRedirector.h" 4 | #include "Sockets.h" 5 | #include "SocketSubsystem.h" 6 | #include "Interfaces/IPv4/IPv4Address.h" 7 | #include "Interfaces/IPv4/IPv4Endpoint.h" 8 | 9 | UProtocolSocketBase::UProtocolSocketBase() 10 | { 11 | 12 | } 13 | 14 | UProtocolSocketBase::~UProtocolSocketBase() 15 | { 16 | 17 | } 18 | 19 | void UProtocolSocketBase::CloseInnerSocket() 20 | { 21 | if (!InnerSocket) return; 22 | 23 | InnerSocket->Close(); 24 | ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(InnerSocket); 25 | InnerSocket = nullptr; 26 | } 27 | 28 | void UProtocolSocketBase::SendTo(const TArray& DataBuffer, const FIPv4Endpoint& EndPoint) const 29 | { 30 | if (!InnerSocket) return; 31 | 32 | int32 BytesSent; 33 | InnerSocket->SendTo(DataBuffer.GetData(), DataBuffer.Num(), BytesSent, EndPoint.ToInternetAddr().Get()); 34 | } 35 | 36 | void UProtocolSocketBase::SendToConnected(const TArray& DataBuffer) const 37 | { 38 | if (!InnerSocket) return; 39 | 40 | int32 BytesSent; 41 | InnerSocket->Send(DataBuffer.GetData(), DataBuffer.Num(), BytesSent); 42 | } 43 | 44 | 45 | bool UProtocolSocketBase::FormatIP4ToNumber(const FString& IpAddress, uint8(&Out)[4]) 46 | { 47 | auto _ip = IpAddress.ToLower(); 48 | if (_ip == TEXT("localhost")) 49 | { 50 | Out[0] = 127; 51 | Out[1] = 0; 52 | Out[2] = 0; 53 | Out[3] = 1; 54 | return true; 55 | } 56 | 57 | _ip = _ip.Replace(TEXT(" "), TEXT("")); 58 | 59 | const TCHAR* Delims[] = { TEXT(".") }; 60 | TArray Parts; 61 | _ip.ParseIntoArray(Parts, Delims, true); 62 | if (Parts.Num() != 4) 63 | return false; 64 | 65 | for (int32 i = 0; i < 4; ++i) 66 | { 67 | Out[i] = FCString::Atoi(*Parts[i]); 68 | } 69 | 70 | return true; 71 | } 72 | 73 | TTuple UProtocolSocketBase::GetIP4EndPoint(const FString& IpAddress, int32 Port) 74 | { 75 | uint8 IP4Nums[4]; 76 | if (!FormatIP4ToNumber(IpAddress, IP4Nums)) 77 | { 78 | UE_LOG(LogTemp, Error, TEXT("UProtocolTcpIpSocket::ipaddress format violation")); 79 | return MakeTuple(false, FIPv4Endpoint()); 80 | } 81 | 82 | FIPv4Endpoint Endpoint(FIPv4Address(IP4Nums[0], IP4Nums[1], IP4Nums[2], IP4Nums[3]), Port); 83 | 84 | return MakeTuple(true, Endpoint); 85 | } -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Protocol/ProtocolTcpIpClient.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "Protocol/ProtocolTcpIpClient.h" 3 | #include "Common/TcpSocketBuilder.h" 4 | #include "Utils/ODWorkerThread.h" 5 | #include "HAL/RunnableThread.h" 6 | 7 | UProtocolTcpIpClient::UProtocolTcpIpClient() 8 | { 9 | 10 | } 11 | 12 | UProtocolTcpIpClient::~UProtocolTcpIpClient() 13 | { 14 | 15 | } 16 | 17 | void UProtocolTcpIpClient::Initialize(const FString& IpAddress, int32 Port, bool Retry/* = false*/, bool _AutoConnectAfterDisconnect/* = false*/) 18 | { 19 | ISocketSubsystem* SocketSubSystem = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM); 20 | 21 | auto result = SocketSubSystem->GetAddressInfo(*IpAddress, nullptr, EAddressInfoFlags::Default, NAME_None); 22 | if (result.Results.Num() == 0) 23 | { 24 | UE_LOG(LogTemp, Error, TEXT("GetAddressInfo failed")); 25 | return; 26 | } 27 | auto ip = result.Results[0].Address->ToString(false); 28 | 29 | ServerIpAddress = ip; 30 | ServerPort = Port; 31 | RetryConnect = Retry; 32 | AutoConnectAfterDisconnect = _AutoConnectAfterDisconnect; 33 | } 34 | 35 | UProtocolTcpIpClient* UProtocolTcpIpClient::WithReceiveBufferSize(int32 SizeInBytes) 36 | { 37 | ReceiveBufferSize = SizeInBytes; 38 | 39 | return this; 40 | } 41 | 42 | UProtocolTcpIpClient* UProtocolTcpIpClient::WithSendBufferSize(int32 SizeInBytes) 43 | { 44 | SendBufferSize = SizeInBytes; 45 | 46 | return this; 47 | } 48 | 49 | void UProtocolTcpIpClient::Start() 50 | { 51 | CloseSocket(); 52 | 53 | CreateSocket(); 54 | 55 | 56 | auto endPoint = GetIP4EndPoint(ServerIpAddress, ServerPort); 57 | if (!endPoint.Get<0>()) return; 58 | 59 | ConnectEndPoint = endPoint.Get<1>(); 60 | 61 | if (!InnerSocket) 62 | { 63 | UE_LOG(LogTemp, Error, TEXT("TryConnect failed: InnerSocket is null")); 64 | return; 65 | } 66 | 67 | ConnectInnerThread = new FODWorkerThread([this] { return TryConnect(); }, 1.0f); 68 | ConnectThread = FRunnableThread::Create(ConnectInnerThread, TEXT("ObjectDeliverer UProtocolTcpIpClient ConnectThread")); 69 | } 70 | 71 | bool UProtocolTcpIpClient::TryConnect() 72 | { 73 | UE_LOG(LogTemp, Log, TEXT("Start TryConnect")); 74 | 75 | if (!InnerSocket) 76 | { 77 | UE_LOG(LogTemp, Error, TEXT("TryConnect failed: InnerSocket is null")); 78 | return false; 79 | } 80 | 81 | // Check socket state 82 | ESocketConnectionState ConnectionState = InnerSocket->GetConnectionState(); 83 | UE_LOG(LogTemp, Log, TEXT("Socket Connection State before connect: %d"), (int32)ConnectionState); 84 | 85 | // Recreate socket if in error or connected state 86 | if (ConnectionState == ESocketConnectionState::SCS_ConnectionError || 87 | ConnectionState == ESocketConnectionState::SCS_Connected) 88 | { 89 | UE_LOG(LogTemp, Log, TEXT("Recreating socket due to invalid state")); 90 | InnerSocket->Shutdown(ESocketShutdownMode::ReadWrite); 91 | InnerSocket->Close(); 92 | 93 | CreateSocket(); 94 | } 95 | 96 | // ------------------------------------------------------------------------------------- 97 | // Skip state check on Linux due to bug where GetConnectionState() returns Connected immediately after socket creation 98 | // ------------------------------------------------------------------------------------- 99 | #if PLATFORM_WINDOWS || PLATFORM_MAC 100 | // Recheck socket state before attempting connection 101 | ConnectionState = InnerSocket->GetConnectionState(); 102 | if (ConnectionState != ESocketConnectionState::SCS_NotConnected) 103 | { 104 | UE_LOG(LogTemp, Log, TEXT("Socket is not in NotConnected state, skipping connect attempt")); 105 | return RetryConnect; 106 | } 107 | #endif 108 | 109 | if (InnerSocket->Connect(ConnectEndPoint.ToInternetAddr().Get())) 110 | { 111 | UE_LOG(LogTemp, Log, TEXT("TryConnect success")); 112 | DispatchConnected(this); 113 | OnConnected(InnerSocket); 114 | return false; 115 | } 116 | else 117 | { 118 | int32 ErrorCode = FPlatformMisc::GetLastError(); 119 | ConnectionState = InnerSocket->GetConnectionState(); 120 | 121 | bool PendingConnection = false; 122 | InnerSocket->HasPendingConnection(PendingConnection); 123 | 124 | UE_LOG(LogTemp, Log, TEXT("TryConnect failed - Error: %d, ConnectionState: %d, Pending: %d"), 125 | ErrorCode, (int32)ConnectionState, PendingConnection ? 1 : 0); 126 | 127 | if (RetryConnect) 128 | { 129 | UE_LOG(LogTemp, Log, TEXT("RetryConnect is true, retrying...")); 130 | return true; 131 | } 132 | } 133 | 134 | return false; 135 | } 136 | 137 | void UProtocolTcpIpClient::Close() 138 | { 139 | Super::Close(); 140 | 141 | if (!ConnectThread) return; 142 | ConnectThread->Kill(true); 143 | 144 | delete ConnectThread; 145 | ConnectThread = nullptr; 146 | 147 | if (!ConnectInnerThread) return; 148 | delete ConnectInnerThread; 149 | ConnectInnerThread = nullptr; 150 | } 151 | 152 | 153 | void UProtocolTcpIpClient::DispatchDisconnected(const UObjectDelivererProtocol* DisconnectedObject) 154 | { 155 | Super::DispatchDisconnected(DisconnectedObject); 156 | 157 | if (AutoConnectAfterDisconnect) 158 | { 159 | Start(); 160 | } 161 | } 162 | 163 | void UProtocolTcpIpClient::CreateSocket() 164 | { 165 | auto socket = FTcpSocketBuilder(TEXT("ObjectDeliverer TcpIpClient")) 166 | .AsBlocking() 167 | .WithReceiveBufferSize(ReceiveBufferSize) 168 | .WithSendBufferSize(SendBufferSize) 169 | .Build(); 170 | 171 | if (socket == nullptr) 172 | { 173 | UE_LOG(LogTemp, Log, TEXT("Failed to create socket")); 174 | return; 175 | } 176 | 177 | InnerSocket = socket; 178 | } -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Protocol/ProtocolTcpIpServer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "Protocol/ProtocolTcpIpServer.h" 3 | #include "Protocol/ProtocolTcpIpSocket.h" 4 | #include "Common/TcpSocketBuilder.h" 5 | #include "Utils/ODWorkerThread.h" 6 | #include "PacketRule/PacketRule.h" 7 | #include "HAL/RunnableThread.h" 8 | 9 | UProtocolTcpIpServer::UProtocolTcpIpServer() 10 | { 11 | 12 | } 13 | 14 | UProtocolTcpIpServer::~UProtocolTcpIpServer() 15 | { 16 | 17 | } 18 | 19 | void UProtocolTcpIpServer::Initialize(int32 Port) 20 | { 21 | ListenPort = Port; 22 | } 23 | 24 | UProtocolTcpIpServer* UProtocolTcpIpServer::WithReceiveBufferSize(int32 SizeInBytes) 25 | { 26 | ReceiveBufferSize = SizeInBytes; 27 | 28 | return this; 29 | } 30 | 31 | UProtocolTcpIpServer* UProtocolTcpIpServer::WithSendBufferSize(int32 SizeInBytes) 32 | { 33 | SendBufferSize = SizeInBytes; 34 | 35 | return this; 36 | } 37 | 38 | void UProtocolTcpIpServer::Start() 39 | { 40 | Close(); 41 | 42 | IsClosing = false; 43 | 44 | auto socket = FTcpSocketBuilder(TEXT("ObjectDeliverer TcpIpServer")) 45 | .AsBlocking() 46 | .BoundToPort(ListenPort) 47 | .Listening(MaxBacklog) 48 | .Build(); 49 | 50 | if (socket == nullptr) return; 51 | 52 | ListenerSocket = socket; 53 | 54 | ListenInnerThread = new FODWorkerThread([this] { return OnListen(); }); 55 | ListenThread = FRunnableThread::Create(ListenInnerThread, TEXT("ObjectDeliverer TcpIpSocket ListenThread")); 56 | } 57 | 58 | void UProtocolTcpIpServer::Close() 59 | { 60 | IsClosing = true; 61 | 62 | // Iterate backwards to allow safe removal of elements during the loop 63 | for (int32 i = ConnectedSockets.Num() - 1; i >= 0; --i) 64 | { 65 | UProtocolTcpIpSocket* clientSocket = ConnectedSockets[i]; 66 | if (clientSocket) 67 | { 68 | clientSocket->Disconnected.Unbind(); 69 | clientSocket->ReceiveData.Unbind(); 70 | clientSocket->Close(); 71 | } 72 | } 73 | 74 | ConnectedSockets.Reset(); 75 | 76 | if (!ListenerSocket) return; 77 | ListenerSocket->Close(); 78 | ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(ListenerSocket); 79 | 80 | if (!ListenThread) return; 81 | ListenThread->Kill(true); 82 | delete ListenThread; 83 | ListenThread = nullptr; 84 | 85 | if (!ListenInnerThread) return; 86 | delete ListenInnerThread; 87 | ListenInnerThread = nullptr; 88 | 89 | ListenerSocket = nullptr; 90 | 91 | } 92 | 93 | void UProtocolTcpIpServer::Send(const TArray& DataBuffer) const 94 | { 95 | for (auto clientSocket : ConnectedSockets) 96 | { 97 | clientSocket->Send(DataBuffer); 98 | } 99 | } 100 | 101 | bool UProtocolTcpIpServer::OnListen() 102 | { 103 | if (!ListenerSocket) return false; 104 | 105 | if (IsClosing) return false; 106 | 107 | TSharedRef RemoteAddress = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr(); 108 | bool Pending = false; 109 | 110 | if (ListenerSocket->HasPendingConnection(Pending)) 111 | { 112 | auto _clientSocket = ListenerSocket->Accept(*RemoteAddress, TEXT("ObjectDeliverer Received Socket Connection")); 113 | 114 | if (_clientSocket != nullptr) 115 | { 116 | int32 _newReceiveBufferSize; 117 | _clientSocket->SetReceiveBufferSize(ReceiveBufferSize, _newReceiveBufferSize); 118 | int32 _newSendBufferSize; 119 | _clientSocket->SetSendBufferSize(SendBufferSize, _newSendBufferSize); 120 | 121 | auto clientSocket = NewObject(); 122 | clientSocket->Disconnected.BindUObject(this, &UProtocolTcpIpServer::DisconnectedClient); 123 | clientSocket->ReceiveData.BindUObject(this, &UProtocolTcpIpServer::ReceiveDataFromClient); 124 | clientSocket->SetPacketRule(PacketRule->Clone()); 125 | 126 | clientSocket->OnConnected(_clientSocket); 127 | 128 | ConnectedSockets.Add(clientSocket); 129 | 130 | DispatchConnected(clientSocket); 131 | } 132 | } 133 | 134 | return true; 135 | } 136 | 137 | void UProtocolTcpIpServer::DisconnectedClient(const UObjectDelivererProtocol* ClientSocket) 138 | { 139 | if (IsClosing) return; 140 | 141 | auto _clientSocket = (UProtocolTcpIpSocket*)(ClientSocket); 142 | if (!IsValid(_clientSocket)) return; 143 | 144 | auto foundIndex = ConnectedSockets.Find(_clientSocket); 145 | if (foundIndex != INDEX_NONE) 146 | { 147 | _clientSocket->Disconnected.Unbind(); 148 | _clientSocket->ReceiveData.Unbind(); 149 | 150 | ConnectedSockets.RemoveAt(foundIndex); 151 | 152 | DispatchDisconnected(ClientSocket); 153 | } 154 | } 155 | 156 | void UProtocolTcpIpServer::ReceiveDataFromClient(const UObjectDelivererProtocol* ClientSocket, const TArray& Buffer) 157 | { 158 | if (IsClosing) return; 159 | 160 | DispatchReceiveData(ClientSocket, Buffer); 161 | } 162 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Protocol/ProtocolTcpIpSocket.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "Protocol/ProtocolTcpIpSocket.h" 3 | #include "Common/TcpSocketBuilder.h" 4 | #include "Utils/ODWorkerThread.h" 5 | #include "HAL/RunnableThread.h" 6 | #include "PacketRule/PacketRule.h" 7 | 8 | UProtocolTcpIpSocket::UProtocolTcpIpSocket() 9 | { 10 | 11 | } 12 | 13 | UProtocolTcpIpSocket::~UProtocolTcpIpSocket() 14 | { 15 | } 16 | 17 | 18 | void UProtocolTcpIpSocket::Close() 19 | { 20 | CloseSocket(); 21 | } 22 | 23 | 24 | void UProtocolTcpIpSocket::CloseSocket() 25 | { 26 | if (!InnerSocket) return; 27 | 28 | IsSelfClose = true; 29 | 30 | InnerSocket->Close(); 31 | 32 | FScopeLock lock(&ct); 33 | 34 | if (!CurrentThread) return; 35 | CurrentThread->Kill(true); 36 | 37 | delete CurrentThread; 38 | CurrentThread = nullptr; 39 | 40 | if (!CurrentInnerThread) return; 41 | delete CurrentInnerThread; 42 | CurrentInnerThread = nullptr; 43 | 44 | ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(InnerSocket); 45 | InnerSocket = nullptr; 46 | } 47 | 48 | void UProtocolTcpIpSocket::Send(const TArray& DataBuffer) const 49 | { 50 | if (!InnerSocket) return; 51 | 52 | PacketRule->MakeSendPacket(DataBuffer); 53 | } 54 | 55 | void UProtocolTcpIpSocket::OnConnected(FSocket* ConnectionSocket) 56 | { 57 | InnerSocket = ConnectionSocket; 58 | StartPollilng(); 59 | } 60 | 61 | void UProtocolTcpIpSocket::StartPollilng() 62 | { 63 | ReceiveBuffer.SetLength(0); 64 | CurrentInnerThread = new FODWorkerThread([this] 65 | { 66 | FScopeLock lock(&ct); 67 | return ReceivedData(); 68 | }); 69 | CurrentThread = FRunnableThread::Create(CurrentInnerThread, TEXT("ObjectDeliverer TcpIpSocket PollingThread")); 70 | } 71 | 72 | bool UProtocolTcpIpSocket::ReceivedData() 73 | { 74 | if (!InnerSocket) 75 | { 76 | DispatchDisconnected(this); 77 | return false; 78 | } 79 | 80 | // check if the socket has closed 81 | { 82 | int32 BytesRead; 83 | uint8 Dummy; 84 | if (!InnerSocket->Recv(&Dummy, 1, BytesRead, ESocketReceiveFlags::Peek)) 85 | { 86 | if (!IsSelfClose) 87 | { 88 | CloseInnerSocket(); 89 | DispatchDisconnected(this); 90 | } 91 | 92 | return false; 93 | } 94 | } 95 | 96 | // Block waiting for some data 97 | if (!InnerSocket->Wait(ESocketWaitConditions::WaitForRead, FTimespan::FromSeconds(0.1))) 98 | { 99 | if (InnerSocket->GetConnectionState() == SCS_ConnectionError) 100 | { 101 | if (!IsSelfClose) 102 | { 103 | CloseInnerSocket(); 104 | DispatchDisconnected(this); 105 | } 106 | return false; 107 | } 108 | return true; 109 | } 110 | 111 | uint32 Size = 0; 112 | while (InnerSocket->HasPendingData(Size)) 113 | { 114 | ReceiveBuffer.SetLength(Size); 115 | 116 | int32 Read = 0; 117 | if (!InnerSocket->Recv(ReceiveBuffer.AsSpan().Buffer, ReceiveBuffer.GetLength(), Read, ESocketReceiveFlags::WaitAll)) 118 | { 119 | if (!IsSelfClose) 120 | { 121 | CloseInnerSocket(); 122 | DispatchDisconnected(this); 123 | } 124 | return false; 125 | } 126 | 127 | ReceiveBuffer.SetLength(Read); 128 | 129 | while(ReceiveBuffer.GetLength() > 0) 130 | { 131 | const int32 wantSize = PacketRule->GetWantSize(); 132 | 133 | if (wantSize > 0) 134 | { 135 | if (ReceiveBuffer.GetLength() < wantSize) return true; 136 | } 137 | 138 | const auto receiveSize = wantSize == 0 ? ReceiveBuffer.GetLength() : wantSize; 139 | 140 | PacketRule->NotifyReceiveData(ReceiveBuffer.AsSpan(0, receiveSize).ToArray()); 141 | 142 | ReceiveBuffer.RemoveRangeFromStart(0, receiveSize); 143 | } 144 | } 145 | 146 | return true; 147 | } 148 | 149 | void UProtocolTcpIpSocket::RequestSend(const TArray& DataBuffer) 150 | { 151 | SendToConnected(DataBuffer); 152 | } 153 | 154 | bool UProtocolTcpIpSocket::GetIPAddress(TArray& IPAddress) 155 | { 156 | if (InnerSocket == nullptr) return false; 157 | 158 | TSharedPtr Addr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr(); 159 | InnerSocket->GetPeerAddress(*Addr); 160 | IPAddress.SetNum(0); 161 | IPAddress = Addr->GetRawIp(); 162 | 163 | return true; 164 | } 165 | 166 | bool UProtocolTcpIpSocket::GetIPAddressInString(FString& IPAddress) 167 | { 168 | if (InnerSocket == nullptr) return false; 169 | 170 | TSharedPtr Addr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr(); 171 | InnerSocket->GetPeerAddress(*Addr); 172 | 173 | IPAddress = Addr->ToString(false); 174 | 175 | return true; 176 | } 177 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Protocol/ProtocolUdpSocket.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "Protocol/ProtocolUdpSocket.h" 3 | #include "PacketRule/PacketRule.h" 4 | 5 | UProtocolUdpSocket::UProtocolUdpSocket() 6 | { 7 | 8 | } 9 | 10 | UProtocolUdpSocket::~UProtocolUdpSocket() 11 | { 12 | 13 | } 14 | 15 | void UProtocolUdpSocket::Initialize(FIPv4Endpoint IP) 16 | { 17 | IPEndPoint = IP; 18 | ReceiveBuffer.SetLength(0); 19 | } 20 | 21 | void UProtocolUdpSocket::NotifyReceived(const ODByteSpan& data) 22 | { 23 | ReceiveBuffer.Add(data); 24 | 25 | while (ReceiveBuffer.GetLength() > 0) 26 | { 27 | const int32 wantSize = PacketRule->GetWantSize(); 28 | 29 | if (wantSize > 0) 30 | { 31 | if (ReceiveBuffer.GetLength() < wantSize) return; 32 | } 33 | 34 | const auto receiveSize = wantSize == 0 ? ReceiveBuffer.GetLength() : wantSize; 35 | 36 | PacketRule->NotifyReceiveData(ReceiveBuffer.AsSpan(0, receiveSize).ToArray()); 37 | 38 | ReceiveBuffer.RemoveRangeFromStart(0, receiveSize); 39 | } 40 | 41 | } 42 | 43 | 44 | bool UProtocolUdpSocket::GetIPAddress(TArray& IPAddress) 45 | { 46 | IPAddress.SetNum(0); 47 | IPAddress.Add(IPEndPoint.Address.A); 48 | IPAddress.Add(IPEndPoint.Address.B); 49 | IPAddress.Add(IPEndPoint.Address.C); 50 | IPAddress.Add(IPEndPoint.Address.D); 51 | 52 | return true; 53 | } 54 | 55 | bool UProtocolUdpSocket::GetIPAddressInString(FString& IPAddress) 56 | { 57 | IPAddress = IPEndPoint.Address.ToString(); 58 | 59 | return true; 60 | } 61 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Protocol/ProtocolUdpSocketReceiver.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "Protocol/ProtocolUdpSocketReceiver.h" 3 | #include "PacketRule/PacketRule.h" 4 | #include "Protocol/ProtocolUdpSocket.h" 5 | #include "Utils/ODWorkerThread.h" 6 | #include "HAL/RunnableThread.h" 7 | #include "Common/UdpSocketBuilder.h" 8 | 9 | UProtocolUdpSocketReceiver::UProtocolUdpSocketReceiver() 10 | { 11 | 12 | } 13 | 14 | UProtocolUdpSocketReceiver::~UProtocolUdpSocketReceiver() 15 | { 16 | 17 | } 18 | 19 | void UProtocolUdpSocketReceiver::InitializeWithReceiver(int32 _BoundPort) 20 | { 21 | BoundPort = _BoundPort; 22 | } 23 | 24 | UProtocolUdpSocketReceiver* UProtocolUdpSocketReceiver::WithReceiveBufferSize(int32 SizeInBytes) 25 | { 26 | ReceiveBufferSize = SizeInBytes; 27 | 28 | return this; 29 | } 30 | 31 | 32 | void UProtocolUdpSocketReceiver::Start() 33 | { 34 | ReceiveBuffer.SetLength(0); 35 | 36 | InnerSocket = FUdpSocketBuilder(TEXT("ObjectDeliverer UdpSocket")) 37 | .WithReceiveBufferSize(ReceiveBufferSize) 38 | .BoundToPort(BoundPort) 39 | .Build(); 40 | 41 | if (InnerSocket) 42 | { 43 | SocketSubsystem = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM); 44 | 45 | CurrentInnerThread = new FODWorkerThread([this] 46 | { 47 | FScopeLock lock(&ct); 48 | return ReceivedData(); 49 | }); 50 | CurrentThread = FRunnableThread::Create(CurrentInnerThread, TEXT("ObjectDeliverer UDPSocket PollingThread")); 51 | 52 | ConnectedSockets.Reset(); 53 | 54 | DispatchConnected(this); 55 | } 56 | } 57 | 58 | void UProtocolUdpSocketReceiver::Close() 59 | { 60 | if (!InnerSocket) return; 61 | 62 | IsSelfClose = true; 63 | 64 | InnerSocket->Close(); 65 | 66 | FScopeLock lock(&ct); 67 | 68 | if (!CurrentThread) return; 69 | CurrentThread->Kill(true); 70 | 71 | delete CurrentThread; 72 | CurrentThread = nullptr; 73 | 74 | if (!CurrentInnerThread) return; 75 | delete CurrentInnerThread; 76 | CurrentInnerThread = nullptr; 77 | 78 | ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(InnerSocket); 79 | InnerSocket = nullptr; 80 | } 81 | 82 | 83 | bool UProtocolUdpSocketReceiver::ReceivedData() 84 | { 85 | if (!InnerSocket->Wait(ESocketWaitConditions::WaitForRead, FTimespan::FromMilliseconds(10))) 86 | { 87 | return true; 88 | } 89 | 90 | uint32 Size = 0; 91 | while (InnerSocket->HasPendingData(Size)) 92 | { 93 | ReceiveBuffer.SetLength(Size); 94 | 95 | TSharedRef Sender = SocketSubsystem->CreateInternetAddr(); 96 | int32 Read = 0; 97 | 98 | if (!InnerSocket->RecvFrom(ReceiveBuffer.AsSpan().Buffer, ReceiveBuffer.GetLength(), Read, *Sender)) 99 | { 100 | if (!IsSelfClose) 101 | { 102 | CloseInnerSocket(); 103 | DispatchDisconnected(this); 104 | } 105 | return false; 106 | } 107 | 108 | ReceiveBuffer.SetLength(Read); 109 | 110 | if (ReceiveBuffer.GetLength() > 0) 111 | { 112 | auto ip = FIPv4Endpoint(Sender); 113 | 114 | if (!ConnectedSockets.Contains(ip)) 115 | { 116 | auto udpSender = NewObject(this); 117 | udpSender->Initialize(ip); 118 | udpSender->SetPacketRule(PacketRule->Clone()); 119 | udpSender->ReceiveData.BindUObject(this, &UProtocolUdpSocketReceiver::ReceiveDataFromClient); 120 | ConnectedSockets.Add(ip, udpSender); 121 | } 122 | 123 | FScopeLock lock(&ct); 124 | ConnectedSockets[ip]->NotifyReceived(ReceiveBuffer.AsSpan()); 125 | 126 | ReceiveBuffer.Clear(); 127 | } 128 | } 129 | 130 | return true; 131 | } 132 | 133 | 134 | void UProtocolUdpSocketReceiver::ReceiveDataFromClient(const UObjectDelivererProtocol* ClientSocket, const TArray& Buffer) 135 | { 136 | DispatchReceiveData(ClientSocket, Buffer); 137 | } 138 | 139 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Protocol/ProtocolUdpSocketSender.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "Protocol/ProtocolUdpSocketSender.h" 3 | #include "Common/UdpSocketBuilder.h" 4 | #include "HAL/RunnableThread.h" 5 | #include "PacketRule/PacketRule.h" 6 | 7 | UProtocolUdpSocketSender::UProtocolUdpSocketSender() 8 | { 9 | } 10 | 11 | UProtocolUdpSocketSender::~UProtocolUdpSocketSender() 12 | { 13 | } 14 | 15 | void UProtocolUdpSocketSender::Initialize(const FString &IpAddress, int32 Port) 16 | { 17 | DestinationIpAddress = IpAddress; 18 | DestinationPort = Port; 19 | } 20 | 21 | UProtocolUdpSocketSender *UProtocolUdpSocketSender::WithSendBufferSize(int32 SizeInBytes) 22 | { 23 | SendBufferSize = SizeInBytes; 24 | 25 | return this; 26 | } 27 | 28 | UProtocolUdpSocketSender *UProtocolUdpSocketSender::WithBroadcast(bool InEnableBroadcast) 29 | { 30 | bEnableBroadcast = InEnableBroadcast; 31 | 32 | return this; 33 | } 34 | 35 | void UProtocolUdpSocketSender::Start() 36 | { 37 | auto endPoint = GetIP4EndPoint(DestinationIpAddress, DestinationPort); 38 | if (!endPoint.Get<0>()) 39 | return; 40 | 41 | DestinationEndpoint = endPoint.Get<1>(); 42 | 43 | InnerSocket = FUdpSocketBuilder(TEXT("ObjectDeliverer UdpSocket")) 44 | .WithSendBufferSize(SendBufferSize) 45 | .Build(); 46 | 47 | if (InnerSocket) 48 | { 49 | if (bEnableBroadcast) 50 | { 51 | InnerSocket->SetBroadcast(true); 52 | } 53 | 54 | DispatchConnected(this); 55 | } 56 | } 57 | 58 | void UProtocolUdpSocketSender::Close() 59 | { 60 | CloseInnerSocket(); 61 | } 62 | 63 | void UProtocolUdpSocketSender::Send(const TArray &DataBuffer) const 64 | { 65 | PacketRule->MakeSendPacket(DataBuffer); 66 | } 67 | 68 | void UProtocolUdpSocketSender::RequestSend(const TArray &DataBuffer) 69 | { 70 | SendTo(DataBuffer, DestinationEndpoint); 71 | } -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Utils/JsonSerializer/ODJsonDeserializer.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "ODJsonSerializerBase.h" 5 | #include "Dom/JsonObject.h" 6 | #include "ODJsonDeserializer.generated.h" 7 | 8 | UCLASS() 9 | class OBJECTDELIVERER_API UODJsonDeserializer : public UODJsonSerializerBase 10 | { 11 | GENERATED_BODY() 12 | 13 | public: 14 | UODJsonDeserializer(); 15 | 16 | virtual UObject* JsonObjectToUObject(const TSharedPtr& JsonObject, UClass* TargetClass = nullptr); 17 | 18 | virtual bool JsonPropertyToFProperty(const TSharedPtr& JsonObject, FProperty* Property, UObject* OutObject); 19 | 20 | protected: 21 | virtual bool JsonValueToFProperty(const TSharedPtr& JsonValue, FProperty* Property, void* OutValue); 22 | virtual bool ConvertScalarJsonValueToFPropertyWithContainer(const TSharedPtr& JsonValue, FProperty* Property, void* OutValue); 23 | virtual bool JsonValueToFEnumProperty(const TSharedPtr& JsonValue, FEnumProperty* Property, void* OutValue); 24 | virtual bool JsonValueToFNumericProperty(const TSharedPtr& JsonValue, FNumericProperty* NumericProperty, void* OutValue); 25 | virtual bool JsonValueToFBoolProperty(const TSharedPtr& JsonValue, FBoolProperty* BoolProperty, void* OutValue); 26 | virtual bool JsonValueToFStrProperty(const TSharedPtr& JsonValue, FStrProperty* StringProperty, void* OutValue); 27 | virtual bool JsonValueToFArrayProperty(const TSharedPtr& JsonValue, FArrayProperty* ArrayProperty, void* OutValue); 28 | virtual bool JsonValueToFMapProperty(const TSharedPtr& JsonValue, FMapProperty* MapProperty, void* OutValue); 29 | virtual bool JsonValueToFSetProperty(const TSharedPtr& JsonValue, FSetProperty* SetProperty, void* OutValue); 30 | virtual bool JsonValueToFTextProperty(const TSharedPtr& JsonValue, FTextProperty* TextProperty, void* OutValue); 31 | virtual bool JsonValueToFStructProperty(const TSharedPtr& JsonValue, FStructProperty* StructProperty, void* OutValue); 32 | virtual bool JsonValueToFObjectProperty(const TSharedPtr& JsonValue, FObjectProperty* ObjectProperty, void* OutValue); 33 | 34 | virtual bool JsonObjectToUStruct(const TSharedPtr& JsonObject, const UStruct* StructDefinition, void* OutStruct); 35 | 36 | }; 37 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Utils/JsonSerializer/ODJsonSerializer.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "ODJsonSerializerBase.h" 5 | #include "Dom/JsonObject.h" 6 | #include "ODJsonSerializer.generated.h" 7 | 8 | UCLASS() 9 | class OBJECTDELIVERER_API UODJsonSerializer : public UODJsonSerializerBase 10 | { 11 | GENERATED_BODY() 12 | 13 | public: 14 | UODJsonSerializer(); 15 | 16 | TSharedPtr CreateJsonObject(const UObject* Obj, int64 CheckFlags = 0, int64 SkipFlags = 0); 17 | 18 | void AddJsonValue(TSharedPtr JsonObject, const UObject* Obj, FProperty* Property, int64 CheckFlags, int64 SkipFlags); 19 | 20 | private: 21 | TSharedPtr ObjectJsonCallback(FProperty* Property, const void* Value); 22 | 23 | protected: 24 | virtual TSharedPtr UObjectToJsonObject(UClass* ObjectClass, const UObject* Obj, int64 CheckFlags = 0, int64 SkipFlags = 0); 25 | 26 | private: 27 | TArray VisitedObjects; 28 | 29 | }; 30 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Utils/JsonSerializer/ODJsonSerializerBase.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "ODJsonSerializerBase.h" 3 | 4 | UODJsonSerializerBase::UODJsonSerializerBase() 5 | { 6 | DefaultSerializer = CreateDefaultSubobject(TEXT("DefaultObjectSerializer")); 7 | } 8 | 9 | void UODJsonSerializerBase::AddOverrideJsonSerializers(EODJsonSerializeType DefaultSerializerType, const TMap& ObjectSerializerTypes) 10 | { 11 | DefaultSerializer = CreateOverrideJsonSerializer(DefaultSerializerType); 12 | 13 | TArray classKeyes; 14 | ObjectSerializerTypes.GetKeys(classKeyes); 15 | 16 | for (auto classKey : classKeyes) 17 | { 18 | ObjectSerializeres.Add(classKey, CreateOverrideJsonSerializer(ObjectSerializerTypes[classKey])); 19 | } 20 | 21 | } 22 | 23 | UODOverrideJsonSerializer* UODJsonSerializerBase::CreateOverrideJsonSerializer(EODJsonSerializeType jsonSerializeType) 24 | { 25 | UClass* serializeClass = nullptr; 26 | 27 | switch (jsonSerializeType) 28 | { 29 | case EODJsonSerializeType::NoWriteType: 30 | serializeClass = UODNoWriteTypeJsonSerializer::StaticClass(); 31 | break; 32 | case EODJsonSerializeType::WriteType: 33 | serializeClass = UODWriteTypeJsonSerializer::StaticClass(); 34 | break; 35 | default: 36 | serializeClass = UODNoWriteTypeJsonSerializer::StaticClass(); 37 | break; 38 | } 39 | 40 | 41 | return NewObject(this, serializeClass); 42 | } -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Utils/JsonSerializer/ODJsonSerializerBase.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "DeliveryBox/ODOverrideJsonSerializer.h" 6 | #include "ODJsonSerializerBase.generated.h" 7 | 8 | UCLASS() 9 | class OBJECTDELIVERER_API UODJsonSerializerBase : public UObject 10 | { 11 | GENERATED_BODY() 12 | 13 | public: 14 | UODJsonSerializerBase(); 15 | 16 | void AddOverrideJsonSerializers(EODJsonSerializeType DefaultSerializerType, const TMap& ObjectSerializerTypes); 17 | 18 | protected: 19 | UODOverrideJsonSerializer* CreateOverrideJsonSerializer(EODJsonSerializeType jsonSerializeType); 20 | 21 | protected: 22 | UPROPERTY(Transient) 23 | UODOverrideJsonSerializer* DefaultSerializer; 24 | 25 | UPROPERTY(Transient) 26 | TMap ObjectSerializeres; 27 | }; 28 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Utils/LogObjectDeliverer.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Lê Vương Gia Huân */ 2 | 3 | #include "LogObjectDeliverer.h" 4 | 5 | DEFINE_LOG_CATEGORY(LogObjectDeliverer); -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Utils/LogObjectDeliverer.h: -------------------------------------------------------------------------------- 1 | /* Copyright 2023 Lê Vương Gia Huân */ 2 | 3 | #pragma once 4 | #include "CoreMinimal.h" 5 | 6 | DECLARE_LOG_CATEGORY_EXTERN(LogObjectDeliverer, Log, All); -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Utils/ODFileUtil.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "ODFileUtil.h" 3 | #include "HAL/FileManager.h" 4 | 5 | ODFileWriterUtil::ODFileWriterUtil() 6 | : Ar(nullptr) 7 | { 8 | 9 | } 10 | 11 | ODFileWriterUtil::ODFileWriterUtil(const FString& FilePath, uint32 WriteFlags) 12 | { 13 | Open(FilePath, WriteFlags); 14 | } 15 | 16 | ODFileWriterUtil::~ODFileWriterUtil() 17 | { 18 | Close(); 19 | } 20 | 21 | bool ODFileWriterUtil::Open(const FString& FilePath, uint32 WriteFlags) 22 | { 23 | Ar = IFileManager::Get().CreateFileWriter(*FilePath, WriteFlags); 24 | 25 | if (!Ar) 26 | { 27 | return false; 28 | } 29 | 30 | return true; 31 | } 32 | 33 | void ODFileWriterUtil::Write(const TArray Buffer, int32 Length) 34 | { 35 | if (!Ar) return; 36 | 37 | if (Length == 0) 38 | { 39 | Length = Buffer.Num(); 40 | } 41 | 42 | Ar->Serialize(const_cast(Buffer.GetData()), Length); 43 | } 44 | 45 | void ODFileWriterUtil::Close() 46 | { 47 | if (!Ar) return; 48 | 49 | delete Ar; 50 | Ar = nullptr; 51 | } 52 | 53 | /*************************************************************/ 54 | 55 | ODFileReaderUtil::ODFileReaderUtil() 56 | : Ar(nullptr) 57 | { 58 | 59 | } 60 | 61 | ODFileReaderUtil::ODFileReaderUtil(const FString& FilePath, uint32 ReadFlags) 62 | { 63 | Open(FilePath, ReadFlags); 64 | } 65 | 66 | ODFileReaderUtil::~ODFileReaderUtil() 67 | { 68 | Close(); 69 | } 70 | 71 | bool ODFileReaderUtil::Open(const FString& FilePath, uint32 ReadFlags) 72 | { 73 | Ar = IFileManager::Get().CreateFileReader(*FilePath, ReadFlags); 74 | 75 | if (!Ar) 76 | { 77 | if (!(ReadFlags & FILEREAD_Silent)) 78 | { 79 | UE_LOG(LogStreaming, Warning, TEXT("Failed to read file '%s' error."), *FilePath); 80 | } 81 | return false; 82 | } 83 | 84 | FileSize = Ar->TotalSize(); 85 | 86 | return true; 87 | } 88 | 89 | void ODFileReaderUtil::Read(TArray& Buffer, int32 Length) 90 | { 91 | if (!Ar) return; 92 | 93 | Ar->Serialize(Buffer.GetData(), Length); 94 | } 95 | 96 | double ODFileReaderUtil::ReadDouble() 97 | { 98 | if (!Ar) return 0; 99 | 100 | double retValue = 0; 101 | 102 | Ar->Serialize(&retValue, sizeof(double)); 103 | 104 | return retValue; 105 | } 106 | 107 | void ODFileReaderUtil::Close() 108 | { 109 | if (!Ar) return; 110 | 111 | delete Ar; 112 | Ar = nullptr; 113 | } 114 | 115 | bool ODFileReaderUtil::IsEnd() 116 | { 117 | if (!Ar) return true; 118 | 119 | return Ar->AtEnd(); 120 | } 121 | 122 | int64 ODFileReaderUtil::RemainSize() 123 | { 124 | if (!Ar) return 0; 125 | 126 | return Ar->TotalSize() - Ar->Tell(); 127 | } -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Utils/ODFileUtil.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | 6 | class ODFileWriterUtil 7 | { 8 | public: 9 | ODFileWriterUtil(); 10 | ODFileWriterUtil(const FString& FilePath, uint32 WriteFlags = 0); 11 | ~ODFileWriterUtil(); 12 | 13 | bool Open(const FString& FilePath, uint32 WriteFlags = 0); 14 | void Write(const TArray Buffer, int32 Length = 0); 15 | 16 | template 17 | void Write(T Value) 18 | { 19 | if (!Ar) return; 20 | 21 | Ar->Serialize(&Value, sizeof(T)); 22 | } 23 | 24 | 25 | void Close(); 26 | 27 | private: 28 | FArchive* Ar; 29 | }; 30 | 31 | class ODFileReaderUtil 32 | { 33 | public: 34 | ODFileReaderUtil(); 35 | ODFileReaderUtil(const FString& FilePath, uint32 ReadFlags = 0); 36 | ~ODFileReaderUtil(); 37 | 38 | bool Open(const FString& FilePath, uint32 ReadFlags = 0); 39 | void Read(TArray& Buffer, int32 Length); 40 | double ReadDouble(); 41 | 42 | template 43 | T Read() 44 | { 45 | if (!Ar) return 0; 46 | 47 | T Value; 48 | Ar->Serialize(&Value, sizeof(T)); 49 | 50 | return Value; 51 | } 52 | 53 | void Close(); 54 | 55 | bool IsEnd(); 56 | int64 RemainSize(); 57 | 58 | public: 59 | int64 FileSize; 60 | 61 | private: 62 | FArchive* Ar; 63 | }; 64 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Utils/ODGrowBuffer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "Utils/ODGrowBuffer.h" 3 | 4 | ODGrowBuffer::ODGrowBuffer(int32 initialSize /*= 1024*/, int32 packetSize /*= 1024*/) 5 | : currentSize(0) 6 | { 7 | this->packetSize = packetSize; 8 | SetLength(initialSize); 9 | } 10 | 11 | int32 ODGrowBuffer::GetLength() const 12 | { 13 | return currentSize; 14 | } 15 | 16 | int32 ODGrowBuffer::GetInnerBufferSize() const 17 | { 18 | return innerBuffer.Num(); 19 | } 20 | 21 | ODByteSpan ODGrowBuffer::AsSpan() 22 | { 23 | return AsSpan(0, GetLength()); 24 | } 25 | 26 | ODByteSpan ODGrowBuffer::AsSpan(int32 Position, int32 Length) 27 | { 28 | ODByteSpan stSpan; 29 | stSpan.Buffer = innerBuffer.GetData() + Position; 30 | stSpan.Length = Length; 31 | return stSpan; 32 | } 33 | 34 | bool ODGrowBuffer::SetLength(int32 NewSize /*= 0*/) 35 | { 36 | bool isGrow = false; 37 | 38 | if (innerBuffer.Num() < NewSize) 39 | { 40 | auto packetCount = NewSize / packetSize; 41 | if (NewSize % packetSize) 42 | { 43 | ++packetCount; 44 | } 45 | innerBuffer.SetNum(packetSize * packetCount); 46 | 47 | isGrow = true; 48 | } 49 | 50 | currentSize = NewSize; 51 | 52 | return isGrow; 53 | } 54 | 55 | void ODGrowBuffer::Add(ODByteSpan addBuffer) 56 | { 57 | SetLength(GetLength() + addBuffer.Length); 58 | 59 | AsSpan(GetLength() - addBuffer.Length, addBuffer.Length).CopyFrom(addBuffer); 60 | } 61 | 62 | void ODGrowBuffer::CopyFrom(ODByteSpan fromBuffer, int32 myOffset /*= 0*/) 63 | { 64 | auto newSize = FMath::Max(GetLength(), fromBuffer.Length + myOffset); 65 | SetLength(newSize); 66 | 67 | ODByteSpan spanBuffer = AsSpan(myOffset, fromBuffer.Length); 68 | 69 | spanBuffer.CopyFrom(fromBuffer); 70 | } 71 | 72 | void ODGrowBuffer::RemoveRangeFromStart(int32 start, int32 length) 73 | { 74 | auto moveLength = GetLength() - (start + length); 75 | TArray tempBuffer = TArray(); 76 | tempBuffer.SetNum(moveLength); 77 | auto moveSpan = AsSpan(start + length, moveLength); 78 | ODByteSpan(tempBuffer).CopyFrom(moveSpan); 79 | AsSpan(start, moveLength).CopyFrom(tempBuffer); 80 | 81 | currentSize = moveLength; 82 | } 83 | 84 | void ODGrowBuffer::Clear() 85 | { 86 | currentSize = 0; 87 | } -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Utils/ODMutexLock.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "ODMutexLock.h" 3 | #if PLATFORM_WINDOWS 4 | #include "Windows/WindowsHWrapper.h" 5 | #endif 6 | 7 | 8 | void ODMutexLock::Lock(void* Mutex, TFunction InWork) 9 | { 10 | #if PLATFORM_WINDOWS 11 | if (Mutex) 12 | { 13 | WaitForSingleObject(Mutex, INFINITE); 14 | } 15 | 16 | InWork(); 17 | 18 | if (Mutex) 19 | { 20 | ReleaseMutex(Mutex); 21 | } 22 | #endif 23 | } -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Utils/ODMutexLock.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | 6 | class ODMutexLock 7 | { 8 | public: 9 | static void Lock(void* Mutex, TFunction InWork); 10 | 11 | }; 12 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Utils/ODObjectUtil.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "ODObjectUtil.h" 3 | #include "UObject/ObjectMacros.h" 4 | #include "UObject/Class.h" 5 | #include "UObject/UnrealType.h" 6 | #include "UObject/EnumProperty.h" 7 | #include "UObject/TextProperty.h" 8 | #include "UObject/PropertyPortFlags.h" 9 | #include "UObject/Package.h" 10 | #include "UObject/ConstructorHelpers.h" 11 | #include "LogObjectDeliverer.h" 12 | 13 | void UODObjectUtil::EnumProperties(UObject* TargetObject, TFunction EnumFunc) 14 | { 15 | for (TFieldIterator PropIt(TargetObject->GetClass()); PropIt; ++PropIt) 16 | { 17 | if (!EnumFunc(*PropIt)) 18 | { 19 | break; 20 | } 21 | } 22 | } 23 | 24 | bool UODObjectUtil::FindClass(const FString& ClassName, UClass*& Class) 25 | { 26 | // Method 1: Current method using FSoftClassPath 27 | UClass* LoadedClass = FSoftClassPath(ClassName).TryLoadClass(); 28 | 29 | // Method 2: Use FindFirstObjectSafe to directly search for the class 30 | if (!LoadedClass) 31 | { 32 | LoadedClass = FindFirstObjectSafe(*ClassName); 33 | } 34 | 35 | // Method 3: Use StaticLoadObject to load the class 36 | if (!LoadedClass) 37 | { 38 | LoadedClass = StaticLoadClass(UObject::StaticClass(), nullptr, *ClassName); 39 | } 40 | 41 | bool bFound = false; 42 | if (LoadedClass) 43 | { 44 | bFound = true; 45 | Class = LoadedClass; 46 | } 47 | else 48 | { 49 | UE_LOG(LogObjectDeliverer, Error, TEXT("Can't find class: %s"), *ClassName); 50 | } 51 | 52 | return bFound; 53 | } 54 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Utils/ODObjectUtil.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "ODObjectUtil.generated.h" 6 | 7 | UCLASS(BlueprintType) 8 | class OBJECTDELIVERER_API UODObjectUtil : public UObject 9 | { 10 | GENERATED_BODY() 11 | 12 | public: 13 | static void EnumProperties(UObject* TargetObject, TFunction EnumFunc); 14 | static bool FindClass(const FString& ClassName, UClass*& Class); 15 | 16 | }; 17 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Utils/ODStringUtil.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "ODStringUtil.h" 3 | #include 4 | 5 | void UODStringUtil::StringToBuffer(const FString& message, TArray& DataBuffer) 6 | { 7 | std::string _str = TCHAR_TO_UTF8(*message); 8 | 9 | DataBuffer.SetNum(_str.size() + 1); 10 | DataBuffer[DataBuffer.Num() - 1] = 0x00; 11 | 12 | FMemory::Memcpy(DataBuffer.GetData(), _str.c_str(), _str.size()); 13 | 14 | } 15 | 16 | FString UODStringUtil::BufferToString(const TArray& DataBuffer) 17 | { 18 | if (DataBuffer[DataBuffer.Num() - 1] == 0x00) 19 | { 20 | return UTF8_TO_TCHAR(DataBuffer.GetData()); 21 | } 22 | 23 | TArray tempBuffer; 24 | tempBuffer.SetNum(DataBuffer.Num() + 1); 25 | FMemory::Memcpy(tempBuffer.GetData(), DataBuffer.GetData(), DataBuffer.Num()); 26 | tempBuffer[tempBuffer.Num() - 1] = 0x00; 27 | 28 | return UTF8_TO_TCHAR(tempBuffer.GetData()); 29 | } -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Utils/ODStringUtil.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "ODStringUtil.generated.h" 6 | 7 | 8 | UCLASS(BlueprintType) 9 | class OBJECTDELIVERER_API UODStringUtil : public UObject 10 | { 11 | GENERATED_BODY() 12 | 13 | public: 14 | UFUNCTION(BlueprintPure, Category = "ObjectDeliverer") 15 | static void StringToBuffer(const FString& message, TArray& DataBuffer); 16 | 17 | UFUNCTION(BlueprintPure, Category = "ObjectDeliverer") 18 | static FString BufferToString(const TArray& DataBuffer); 19 | 20 | }; 21 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Utils/ODWorkerThread.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "ODWorkerThread.h" 3 | #include "HAL/PlatformProcess.h" 4 | 5 | FODWorkerThread::FODWorkerThread(TFunction InWork, float WaitSeconds) 6 | : Work(InWork) 7 | , End([]() {}) 8 | , Seconds(WaitSeconds) 9 | , ContinueRun(true) 10 | { 11 | 12 | } 13 | 14 | FODWorkerThread::FODWorkerThread(TFunction InWork, TFunction InEnd, float WaitSeconds) 15 | : Work(InWork) 16 | , End(InEnd) 17 | , Seconds(WaitSeconds) 18 | , ContinueRun(true) 19 | { 20 | 21 | } 22 | 23 | FODWorkerThread::~FODWorkerThread() 24 | { 25 | 26 | } 27 | 28 | uint32 FODWorkerThread::Run() 29 | { 30 | while (ContinueRun) 31 | { 32 | if (!Work()) 33 | { 34 | return 0; 35 | } 36 | 37 | 38 | if (ContinueRun) 39 | { 40 | FPlatformProcess::Sleep(Seconds); 41 | } 42 | } 43 | 44 | return 0; 45 | } 46 | 47 | void FODWorkerThread::Stop() 48 | { 49 | ContinueRun = false; 50 | 51 | } 52 | 53 | void FODWorkerThread::Exit() 54 | { 55 | ContinueRun = false; 56 | 57 | End(); 58 | } 59 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Private/Utils/ODWorkerThread.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "HAL/Runnable.h" 6 | #include "HAL/RunnableThread.h" 7 | 8 | 9 | class OBJECTDELIVERER_API FODWorkerThread : public FRunnable 10 | { 11 | public: 12 | FODWorkerThread(TFunction InWork, float WaitSeconds = 0.001f); 13 | FODWorkerThread(TFunction InWork, TFunction InEnd, float WaitSeconds = 0.001f); 14 | ~FODWorkerThread(); 15 | 16 | virtual uint32 Run() override; 17 | virtual void Stop() override; 18 | virtual void Exit() override; 19 | 20 | private: 21 | TFunction Work; 22 | TFunction End; 23 | float Seconds; 24 | volatile bool ContinueRun; 25 | }; 26 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/DeliveryBox/DeliveryBox.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "DeliveryBox.generated.h" 6 | 7 | class UObjectDelivererProtocol; 8 | 9 | DECLARE_DELEGATE_TwoParams(FUDeliveryBoxRequestSend, const UObjectDelivererProtocol*, const TArray&); 10 | 11 | UCLASS(BlueprintType, Blueprintable) 12 | class OBJECTDELIVERER_API UDeliveryBox : public UObject 13 | { 14 | GENERATED_BODY() 15 | 16 | public: 17 | UDeliveryBox(); 18 | ~UDeliveryBox(); 19 | 20 | virtual void NotifyReceiveBuffer(const UObjectDelivererProtocol* FromObject, const TArray& buffer); 21 | 22 | FUDeliveryBoxRequestSend RequestSend; 23 | 24 | }; 25 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/DeliveryBox/DeliveryBoxFactory.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "DeliveryBox/ODOverrideJsonSerializer.h" 6 | #include "DeliveryBoxFactory.generated.h" 7 | 8 | UCLASS(BlueprintType, Blueprintable) 9 | class OBJECTDELIVERER_API UDeliveryBoxFactory : public UObject 10 | { 11 | GENERATED_BODY() 12 | 13 | public: 14 | /** 15 | * create delivery box (object with json serializer) 16 | * @param TargetClass - target object class 17 | */ 18 | UFUNCTION(BlueprintPure, Category = "ObjectDeliverer|DeliveryBox") 19 | static class UObjectDeliveryBoxUsingJson* CreateObjectDeliveryBoxUsingJson(UClass* TargetClass); 20 | 21 | /** 22 | * create delivery box (object with json serializer) 23 | */ 24 | UFUNCTION(BlueprintPure, Category = "ObjectDeliverer|DeliveryBox") 25 | static class UObjectDeliveryBoxUsingJson* CreateDynamicObjectDeliveryBoxUsingJson(); 26 | 27 | /** 28 | * create delivery box (object with json serializer) 29 | * @param DefaultSerializerType - default serialization method 30 | * @param ObjectSerializerTypes - Set the object class and serialization method class of the property as a pair 31 | * @param TargetClass - target object class 32 | */ 33 | UFUNCTION(BlueprintPure, Category = "ObjectDeliverer|DeliveryBox") 34 | static class UObjectDeliveryBoxUsingJson* CreateCustomObjectDeliveryBoxUsingJson(EODJsonSerializeType DefaultSerializerType, const TMap& ObjectSerializerTypes, UClass* TargetClass); 35 | 36 | /** 37 | * create delivery box (utf-8 string) 38 | */ 39 | UFUNCTION(BlueprintPure, Category = "ObjectDeliverer|DeliveryBox") 40 | static class UUtf8StringDeliveryBox* CreateUtf8StringDeliveryBox(); 41 | 42 | }; 43 | 44 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/DeliveryBox/IODConvertPropertyName.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "UObject/Interface.h" 6 | #include "IODConvertPropertyName.generated.h" 7 | 8 | UINTERFACE(BlueprintType) 9 | class OBJECTDELIVERER_API UODConvertPropertyName : public UInterface 10 | { 11 | GENERATED_UINTERFACE_BODY() 12 | }; 13 | 14 | class OBJECTDELIVERER_API IODConvertPropertyName 15 | { 16 | GENERATED_IINTERFACE_BODY() 17 | 18 | public: 19 | UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "ObjectDeliverer") 20 | FString ConvertFPropertyName(const FName& PropertyName) const; 21 | }; -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/DeliveryBox/ODOverrideJsonSerializer.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "Dom/JsonObject.h" 6 | #include "ODOverrideJsonSerializer.generated.h" 7 | 8 | class UODJsonSerializer; 9 | class UODJsonDeserializer; 10 | 11 | UENUM(BlueprintType) 12 | enum class EODJsonSerializeType : uint8 13 | { 14 | /** Do not include the class name */ 15 | NoWriteType, 16 | 17 | /** Include the class name */ 18 | WriteType 19 | }; 20 | 21 | UCLASS(BlueprintType) 22 | class OBJECTDELIVERER_API UODOverrideJsonSerializer : public UObject 23 | { 24 | GENERATED_BODY() 25 | 26 | public: 27 | virtual TSharedPtr UObjectToJsonObject(UODJsonSerializer* JsonSerializer, const UObject* Obj, int64 CheckFlags = 0, int64 SkipFlags = 0) const; 28 | virtual UObject* JsonObjectTopUObject(UODJsonDeserializer* JsonDeserializer, const TSharedPtr JsonObject, UClass* TargetClass = nullptr) const; 29 | }; 30 | 31 | UCLASS(BlueprintType) 32 | class OBJECTDELIVERER_API UODNoWriteTypeJsonSerializer : public UODOverrideJsonSerializer 33 | { 34 | GENERATED_BODY() 35 | 36 | public: 37 | virtual TSharedPtr UObjectToJsonObject(UODJsonSerializer* JsonSerializer, const UObject* Obj, int64 CheckFlags = 0, int64 SkipFlags = 0) const override; 38 | virtual UObject* JsonObjectTopUObject(UODJsonDeserializer* JsonDeserializer, const TSharedPtr JsonObject, UClass* TargetClass = nullptr) const override; 39 | }; 40 | 41 | UCLASS(BlueprintType) 42 | class OBJECTDELIVERER_API UODWriteTypeJsonSerializer : public UODOverrideJsonSerializer 43 | { 44 | GENERATED_BODY() 45 | 46 | public: 47 | virtual TSharedPtr UObjectToJsonObject(UODJsonSerializer* JsonSerializer, const UObject* Obj, int64 CheckFlags = 0, int64 SkipFlags = 0) const override; 48 | virtual UObject* JsonObjectTopUObject(UODJsonDeserializer* JsonDeserializer, const TSharedPtr JsonObject, UClass* TargetClass = nullptr) const override; 49 | }; -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/DeliveryBox/ObjectDeliveryBoxUsingJson.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | #include "CoreMinimal.h" 4 | #include "DeliveryBox/ODOverrideJsonSerializer.h" 5 | #include "DeliveryBox.h" 6 | #include "Serialization/JsonReader.h" 7 | #include "Serialization/JsonSerializer.h" 8 | #include "ObjectDeliveryBoxUsingJson.generated.h" 9 | 10 | DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FCNObjectDeliveryBoxReceived, UObject*, ReceivedObject, const FString&, ReceivedJsonString, const UObjectDelivererProtocol*, FromObject); 11 | 12 | UCLASS(BlueprintType, Blueprintable) 13 | class OBJECTDELIVERER_API UObjectDeliveryBoxUsingJson : public UDeliveryBox 14 | { 15 | GENERATED_BODY() 16 | 17 | public: 18 | UObjectDeliveryBoxUsingJson(); 19 | ~UObjectDeliveryBoxUsingJson(); 20 | 21 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer|DeliveryBox") 22 | void Initialize(UClass* TargetClass); 23 | 24 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer|DeliveryBox") 25 | void InitializeCustom(EODJsonSerializeType DefaultSerializerType, const TMap& ObjectSerializerTypes, UClass* TargetClass); 26 | 27 | 28 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer|DeliveryBox") 29 | virtual void Send(const UObject* message, FString& makedJson); 30 | 31 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer|DeliveryBox") 32 | virtual void SendTo(const UObject* message, const UObjectDelivererProtocol* Destination, FString& makedJson); 33 | 34 | virtual void NotifyReceiveBuffer(const UObjectDelivererProtocol* FromObject, const TArray& buffer) override; 35 | 36 | 37 | 38 | UPROPERTY(BlueprintAssignable, Category = "ObjectDeliverer|DeliveryBox") 39 | FCNObjectDeliveryBoxReceived Received; 40 | 41 | protected: 42 | UPROPERTY() 43 | UClass* TargetClass; 44 | 45 | UPROPERTY() 46 | class UODJsonSerializer* Serializer; 47 | UPROPERTY() 48 | class UODJsonDeserializer* Deserializer; 49 | }; 50 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/DeliveryBox/Utf8StringDeliveryBox.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "DeliveryBox.h" 6 | #include "Utf8StringDeliveryBox.generated.h" 7 | 8 | DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FCNUtf8StringDeliveryBoxReceived, const FString&, ReceivedString, const UObjectDelivererProtocol*, FromObject); 9 | 10 | UCLASS(BlueprintType, Blueprintable) 11 | class OBJECTDELIVERER_API UUtf8StringDeliveryBox : public UDeliveryBox 12 | { 13 | GENERATED_BODY() 14 | 15 | public: 16 | UUtf8StringDeliveryBox(); 17 | ~UUtf8StringDeliveryBox(); 18 | 19 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer|DeliveryBox") 20 | void Send(const FString& message); 21 | 22 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer|DeliveryBox") 23 | void SendTo(const FString& message, const UObjectDelivererProtocol* Destination); 24 | 25 | virtual void NotifyReceiveBuffer(const UObjectDelivererProtocol* FromObject, const TArray& buffer) override; 26 | 27 | UPROPERTY(BlueprintAssignable, Category = "ObjectDeliverer|DeliveryBox") 28 | FCNUtf8StringDeliveryBoxReceived Received; 29 | }; 30 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/IObjectDeliverer.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Modules/ModuleInterface.h" 7 | #include "Modules/ModuleManager.h" 8 | 9 | 10 | class IObjectDeliverer : public IModuleInterface 11 | { 12 | 13 | public: 14 | 15 | static inline IObjectDeliverer& Get() 16 | { 17 | return FModuleManager::LoadModuleChecked< IObjectDeliverer >( "ObjectDeliverer" ); 18 | } 19 | 20 | static inline bool IsAvailable() 21 | { 22 | return FModuleManager::Get().IsModuleLoaded( "ObjectDeliverer" ); 23 | } 24 | }; 25 | 26 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/ObjectDelivererManager.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "PacketRule/PacketRuleFactory.h" 6 | #include "Protocol/ProtocolFactory.h" 7 | #include "DeliveryBox/DeliveryBoxFactory.h" 8 | #include "UObject/GCObject.h" 9 | #include "Delegates/DelegateCombinations.h" 10 | #include "ObjectDelivererManager.generated.h" 11 | 12 | class UObjectDelivererProtocol; 13 | class UPacketRule; 14 | class UDeliveryBox; 15 | 16 | DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FObjectDelivererManagerConnected, const UObjectDelivererProtocol*, ClientSocket); 17 | DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FObjectDelivererManagerDisconnected, const UObjectDelivererProtocol*, ClientSocket); 18 | DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FObjectDelivererManagerReceiveData, const UObjectDelivererProtocol*, ClientSocket, const TArray&, Buffer); 19 | 20 | UCLASS(BlueprintType, Blueprintable) 21 | class OBJECTDELIVERER_API UObjectDelivererManager : public UObject 22 | { 23 | GENERATED_BODY() 24 | 25 | public: 26 | UObjectDelivererManager(); 27 | ~UObjectDelivererManager(); 28 | 29 | /** 30 | * create ObjectDelivererManager 31 | * @param IsEventWithGameThread - Process events with GameThread 32 | */ 33 | UFUNCTION(BlueprintPure, Category = "ObjectDeliverer") 34 | static UObjectDelivererManager* CreateObjectDelivererManager(bool IsEventWithGameThread = true); 35 | 36 | /** 37 | * start communication protocol. 38 | * @param Protocol - Communication protocol 39 | * @param PacketRule - Data division rule 40 | * @param DeliveryBox - Serialization method(optional) 41 | */ 42 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer") 43 | void Start(UObjectDelivererProtocol* Protocol, UPacketRule* PacketRule, UDeliveryBox* DeliveryBox = nullptr); 44 | 45 | /** 46 | * close communication protocol. 47 | */ 48 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer") 49 | void Close(); 50 | 51 | /** 52 | * send the data to the connection destination. 53 | * @param DataBuffer - databuffer 54 | */ 55 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer") 56 | void Send(const TArray& DataBuffer); 57 | 58 | /** 59 | * send the data to the connection destination. 60 | * @param DataBuffer - databuffer 61 | * @param Target - send destination 62 | */ 63 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer") 64 | void SendTo(const TArray& DataBuffer, const UObjectDelivererProtocol* Target); 65 | 66 | /** 67 | * Whether connected 68 | * @return true:connected, false:disconnected 69 | */ 70 | UFUNCTION(BlueprintPure, Category = "ObjectDeliverer") 71 | bool IsConnected(); 72 | 73 | /** 74 | * Preparation for transmission / reception is completed 75 | */ 76 | UPROPERTY(BlueprintAssignable, Category = "ObjectDeliverer") 77 | FObjectDelivererManagerConnected Connected; 78 | 79 | /** 80 | * lost my connection 81 | */ 82 | UPROPERTY(BlueprintAssignable, Category = "ObjectDeliverer") 83 | FObjectDelivererManagerDisconnected Disconnected; 84 | 85 | /** 86 | * Received data 87 | */ 88 | UPROPERTY(BlueprintAssignable, Category = "ObjectDeliverer") 89 | FObjectDelivererManagerReceiveData ReceiveData; 90 | 91 | virtual void BeginDestroy() override; 92 | 93 | /** 94 | * Process events with GameThread 95 | */ 96 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer") 97 | bool IsEventWithGameThread; 98 | 99 | /** 100 | * Connected list 101 | */ 102 | UPROPERTY(BlueprintReadOnly, Category = "ObjectDeliverer") 103 | TArray ConnectedList; 104 | 105 | private: 106 | void DispatchEvent(TFunction EventAction); 107 | 108 | private: 109 | UPROPERTY(Transient) 110 | UObjectDelivererProtocol* CurrentProtocol; 111 | UPROPERTY(Transient) 112 | UDeliveryBox* DeliveryBox; 113 | 114 | bool IsDestorying; 115 | }; 116 | 117 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/PacketRule/PacketRule.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "Utils/ODGrowBuffer.h" 6 | #include "PacketRule.generated.h" 7 | 8 | UENUM(BlueprintType) 9 | enum class ECNBufferEndian : uint8 10 | { 11 | /** Big Endian */ 12 | Big = 0, 13 | /** Little Endian */ 14 | Little 15 | }; 16 | 17 | DECLARE_DELEGATE_OneParam(FCNPacketRuleMadeSendBuffer, const TArray&); 18 | DECLARE_DELEGATE_OneParam(FCNPacketRuleMadeReceiveBuffer, const TArray&); 19 | 20 | UCLASS(BlueprintType, Blueprintable) 21 | class OBJECTDELIVERER_API UPacketRule : public UObject 22 | { 23 | GENERATED_BODY() 24 | 25 | public: 26 | UPacketRule(); 27 | ~UPacketRule(); 28 | 29 | virtual void Initialize(); 30 | virtual void MakeSendPacket(const TArray& BodyBuffer); 31 | virtual void NotifyReceiveData(const TArray& DataBuffer); 32 | virtual int32 GetWantSize(); 33 | virtual UPacketRule* Clone(); 34 | 35 | FCNPacketRuleMadeSendBuffer MadeSendBuffer; 36 | FCNPacketRuleMadeReceiveBuffer MadeReceiveBuffer; 37 | 38 | protected: 39 | void DispatchMadeSendBuffer(const TArray& SendBuffer); 40 | void DispatchMadeReceiveBuffer(const TArray& ReceiveBuffer); 41 | }; 42 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/PacketRule/PacketRuleFactory.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "PacketRule.h" 6 | #include "PacketRuleFactory.generated.h" 7 | 8 | 9 | UCLASS(BlueprintType) 10 | class OBJECTDELIVERER_API UPacketRuleFactory : public UObject 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | /** 16 | * create packet rule (fixed length) 17 | * @param FixedSize - Fixed size buffer length 18 | */ 19 | UFUNCTION(BlueprintPure, Category = "ObjectDeliverer|PacketRule") 20 | static class UPacketRuleFixedLength* CreatePacketRuleFixedLength(int32 FixedSize = 128); 21 | 22 | /** 23 | * create packet rule (A header indicating the size is followed by a body part) 24 | * @param SizeLength - size header length(byte) 25 | * @param SizeBufferEndian - Endian of size header 26 | */ 27 | UFUNCTION(BlueprintPure, Category = "ObjectDeliverer|PacketRule") 28 | static class UPacketRuleSizeBody* CreatePacketRuleSizeBody(int32 SizeLength = 4, ECNBufferEndian SizeBufferEndian = ECNBufferEndian::Big); 29 | 30 | /** 31 | * create packet rule (Separate by terminal symbol) 32 | * @param Terminate - terminate values 33 | */ 34 | UFUNCTION(BlueprintPure, Category = "ObjectDeliverer|PacketRule") 35 | static class UPacketRuleTerminate* CreatePacketRuleTerminate(const TArray& Terminate); 36 | 37 | /** 38 | * create packet rule (no division) 39 | */ 40 | UFUNCTION(BlueprintPure, Category = "ObjectDeliverer|PacketRule") 41 | static class UPacketRuleNodivision* CreatePacketRuleNodivision(); 42 | }; 43 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/PacketRule/PacketRuleFixedLength.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "PacketRule.h" 6 | #include "PacketRuleFixedLength.generated.h" 7 | 8 | 9 | UCLASS(BlueprintType, Blueprintable) 10 | class OBJECTDELIVERER_API UPacketRuleFixedLength : public UPacketRule 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | UPacketRuleFixedLength(); 16 | ~UPacketRuleFixedLength(); 17 | 18 | virtual void Initialize() override; 19 | virtual void MakeSendPacket(const TArray& BodyBuffer) override; 20 | virtual void NotifyReceiveData(const TArray& DataBuffer) override; 21 | virtual int32 GetWantSize() override; 22 | virtual UPacketRule* Clone() override; 23 | 24 | public: 25 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer|PacketRule") 26 | int32 FixedSize = 128; 27 | 28 | private: 29 | UPROPERTY(Transient) 30 | TArray BufferForSend; 31 | }; 32 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/PacketRule/PacketRuleNodivision.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "PacketRule.h" 6 | #include "PacketRuleNodivision.generated.h" 7 | 8 | 9 | UCLASS(BlueprintType, Blueprintable) 10 | class OBJECTDELIVERER_API UPacketRuleNodivision : public UPacketRule 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | UPacketRuleNodivision(); 16 | ~UPacketRuleNodivision(); 17 | 18 | virtual void Initialize() override; 19 | virtual void MakeSendPacket(const TArray& BodyBuffer) override; 20 | virtual void NotifyReceiveData(const TArray& DataBuffer) override; 21 | virtual int32 GetWantSize() override; 22 | virtual UPacketRule* Clone() override; 23 | 24 | }; 25 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/PacketRule/PacketRuleSizeBody.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "PacketRule.h" 6 | #include "PacketRuleSizeBody.generated.h" 7 | 8 | 9 | 10 | UCLASS(BlueprintType, Blueprintable) 11 | class OBJECTDELIVERER_API UPacketRuleSizeBody : public UPacketRule 12 | { 13 | GENERATED_BODY() 14 | 15 | public: 16 | UPacketRuleSizeBody(); 17 | ~UPacketRuleSizeBody(); 18 | 19 | virtual void Initialize() override; 20 | virtual void MakeSendPacket(const TArray& BodyBuffer) override; 21 | virtual void NotifyReceiveData(const TArray& DataBuffer) override; 22 | virtual int32 GetWantSize() override; 23 | virtual UPacketRule* Clone() override; 24 | 25 | private: 26 | void OnReceivedSize(const TArray& DataBuffer); 27 | void OnReceivedBody(const TArray& DataBuffer); 28 | 29 | private: 30 | enum EReceiveMode 31 | { 32 | Size, 33 | Body 34 | } ReceiveMode; 35 | 36 | uint32 BodySize; 37 | int32 ReceiveBufferPosition; 38 | 39 | UPROPERTY(Transient) 40 | TArray BufferForSend; 41 | 42 | public: 43 | 44 | /** 45 | * size buffer length(1 - 4) 46 | */ 47 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer|PacketRule") 48 | int32 SizeLength = 4; 49 | 50 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer|PacketRule") 51 | ECNBufferEndian SizeBufferEndian = ECNBufferEndian::Big; 52 | }; 53 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/PacketRule/PacketRuleTerminate.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "PacketRule.h" 6 | #include "PacketRuleTerminate.generated.h" 7 | 8 | 9 | UCLASS(BlueprintType, Blueprintable) 10 | class OBJECTDELIVERER_API UPacketRuleTerminate : public UPacketRule 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | UPacketRuleTerminate(); 16 | ~UPacketRuleTerminate(); 17 | 18 | virtual void Initialize() override; 19 | virtual void MakeSendPacket(const TArray& BodyBuffer) override; 20 | virtual void NotifyReceiveData(const TArray& DataBuffer) override; 21 | virtual int32 GetWantSize() override; 22 | virtual UPacketRule* Clone() override; 23 | 24 | public: 25 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer|PacketRule") 26 | TArray Terminate; 27 | 28 | private: 29 | UPROPERTY(Transient) 30 | TArray BufferForSend; 31 | UPROPERTY(Transient) 32 | TArray ReceiveTempBuffer; 33 | UPROPERTY(Transient) 34 | TArray BufferForReceive; 35 | 36 | }; 37 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/Protocol/GetIPV4Info.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "UObject/Interface.h" 6 | #include "GetIPV4Info.generated.h" 7 | 8 | UINTERFACE(BlueprintType, meta = (CannotImplementInterfaceInBlueprint)) 9 | class OBJECTDELIVERER_API UGetIPV4Info : public UInterface 10 | { 11 | GENERATED_BODY() 12 | }; 13 | 14 | 15 | class OBJECTDELIVERER_API IGetIPV4Info 16 | { 17 | GENERATED_BODY() 18 | 19 | public: 20 | 21 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer") 22 | virtual bool GetIPAddress(TArray& IPAddress) = 0; 23 | 24 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer") 25 | virtual bool GetIPAddressInString(FString& IPAddress) = 0; 26 | }; 27 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/Protocol/ObjectDelivererProtocol.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "ObjectDelivererProtocol.generated.h" 6 | 7 | class UObjectDelivererProtocol; 8 | 9 | DECLARE_DELEGATE_OneParam(FObjectDelivererProtocolConnected, const UObjectDelivererProtocol*); 10 | DECLARE_DELEGATE_OneParam(FObjectDelivererProtocolDisconnected, const UObjectDelivererProtocol*); 11 | DECLARE_DELEGATE_TwoParams(FObjectDelivererProtocolReceiveData, const UObjectDelivererProtocol*, const TArray&); 12 | 13 | class UPacketRule; 14 | 15 | UCLASS(BlueprintType, Blueprintable) 16 | class OBJECTDELIVERER_API UObjectDelivererProtocol : public UObject 17 | { 18 | GENERATED_BODY() 19 | 20 | public: 21 | UObjectDelivererProtocol(); 22 | ~UObjectDelivererProtocol(); 23 | 24 | /** 25 | * start communication protocol. 26 | */ 27 | virtual void Start(); 28 | 29 | /** 30 | * close communication protocol. 31 | */ 32 | virtual void Close(); 33 | 34 | /** 35 | * send the data to the connection destination. 36 | * @param DataBuffer - databuffer 37 | */ 38 | virtual void Send(const TArray& DataBuffer) const; 39 | 40 | virtual void BeginDestroy() override; 41 | void SetPacketRule(UPacketRule* PacketRule); 42 | virtual void RequestSend(const TArray& DataBuffer); 43 | 44 | protected: 45 | virtual void DispatchConnected(const UObjectDelivererProtocol* ConnectedObject); 46 | virtual void DispatchDisconnected(const UObjectDelivererProtocol* DisconnectedObject); 47 | virtual void DispatchReceiveData(const UObjectDelivererProtocol* FromObject, const TArray& Buffer); 48 | 49 | UPROPERTY(Transient) 50 | UPacketRule* PacketRule; 51 | 52 | public: 53 | FObjectDelivererProtocolConnected Connected; 54 | FObjectDelivererProtocolDisconnected Disconnected; 55 | FObjectDelivererProtocolReceiveData ReceiveData; 56 | }; 57 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/Protocol/ProtocolFactory.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "ProtocolFactory.generated.h" 6 | 7 | UCLASS(BlueprintType) 8 | class OBJECTDELIVERER_API UProtocolFactory : public UObject 9 | { 10 | GENERATED_BODY() 11 | 12 | public: 13 | /** 14 | * create protocol (TCP/IP client) 15 | * @param IpAddress - ip address of server 16 | * @param Port - Connected port number 17 | * @param Retry - true:If connection fails, try retry until connection 18 | * @param AutoConnectAfterDisconnect - true: Automatic connection attempt after disconnection 19 | */ 20 | UFUNCTION(BlueprintPure, Category = "ObjectDeliverer|Protocol") 21 | static class UProtocolTcpIpClient *CreateProtocolTcpIpClient(const FString &IpAddress = "localhost", int32 Port = 8000, bool Retry = false, bool AutoConnectAfterDisconnect = false); 22 | 23 | /** 24 | * create protocol (TCP/IP server) 25 | * @param Port - Port number to listen to 26 | */ 27 | UFUNCTION(BlueprintPure, Category = "ObjectDeliverer|Protocol") 28 | static class UProtocolTcpIpServer *CreateProtocolTcpIpServer(int32 Port = 8000); 29 | 30 | /** 31 | * create protocol (UDP send only) 32 | * @param IpAddress - ip address of the destination 33 | * @param Port - port number of the destination 34 | */ 35 | UFUNCTION(BlueprintPure, Category = "ObjectDeliverer|Protocol") 36 | static class UProtocolUdpSocketSender *CreateProtocolUdpSocketSender(const FString &IpAddress = "localhost", int32 Port = 8000); 37 | 38 | /** 39 | * create protocol (UDP send only with broadcast option) 40 | * @param IpAddress - ip address of the destination 41 | * @param Port - port number of the destination 42 | * @param EnableBroadcast - true:Enable UDP broadcast 43 | */ 44 | UFUNCTION(BlueprintPure, Category = "ObjectDeliverer|Protocol") 45 | static class UProtocolUdpSocketSender *CreateProtocolUdpSocketSenderWithBroadcast(const FString &IpAddress = "localhost", int32 Port = 8000, bool EnableBroadcast = true); 46 | 47 | /** 48 | * create protocol (UDP receive only) 49 | * @param Port - Port number to bind to 50 | */ 51 | UFUNCTION(BlueprintPure, Category = "ObjectDeliverer|Protocol") 52 | static class UProtocolUdpSocketReceiver *CreateProtocolUdpSocketReceiver(int32 BoundPort = 8000); 53 | 54 | /** 55 | * create protocol (shared memory) 56 | * @param SharedMemoryName - shared memory name 57 | * @param SharedMemorySize - shared memory size (byte) 58 | */ 59 | UFUNCTION(BlueprintPure, Category = "ObjectDeliverer|Protocol") 60 | static class UProtocolSharedMemory *CreateProtocolSharedMemory(FString SharedMemoryName = "SharedMemory", int32 SharedMemorySize = 1024); 61 | 62 | /** 63 | * create protocol (Log file write only) 64 | * @param FilePath - log file path 65 | * @param PathIsAbsolute - true:FilePath is absolute path, false:Relative path from "Logs" 66 | */ 67 | UFUNCTION(BlueprintPure, Category = "ObjectDeliverer|Protocol") 68 | static class UProtocolLogWriter *CreateProtocolLogWriter(const FString &FilePath = "log.bin", bool PathIsAbsolute = false); 69 | 70 | /** 71 | * create protocol (Log file read only) 72 | * @param FilePath - log file path 73 | * @param PathIsAbsolute - true:FilePath is absolute path, false:Relative path from "Logs" 74 | */ 75 | UFUNCTION(BlueprintPure, Category = "ObjectDeliverer|Protocol") 76 | static class UProtocolLogReader *CreateProtocolLogReader(const FString &FilePath = "log.bin", bool PathIsAbsolute = false, bool CutFirstInterval = true); 77 | 78 | UFUNCTION(BlueprintPure, Category = "ObjectDeliverer|Protocol") 79 | static class UProtocolReflection *CreateProtocolReflection(); 80 | }; 81 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/Protocol/ProtocolLogReader.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "ObjectDelivererProtocol.h" 6 | #include "ProtocolLogReader.generated.h" 7 | 8 | UCLASS(BlueprintType, Blueprintable) 9 | class OBJECTDELIVERER_API UProtocolLogReader : public UObjectDelivererProtocol 10 | { 11 | GENERATED_BODY() 12 | 13 | public: 14 | UProtocolLogReader(); 15 | ~UProtocolLogReader(); 16 | 17 | /** 18 | * Initialize UDP. 19 | * @param IpAddress - The ip address of the destination. 20 | * @param Port - The port number of the destination. 21 | */ 22 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer|Protocol") 23 | virtual void Initialize(const FString& FilePath = "log.bin", bool PathIsAbsolute = false, bool CutFirstInterval = true); 24 | 25 | virtual void Start() override; 26 | virtual void Close() override; 27 | virtual void Send(const TArray& DataBuffer) const override; 28 | 29 | virtual void RequestSend(const TArray& DataBuffer) override; 30 | 31 | private: 32 | bool ReadData(); 33 | void ReadEnd(); 34 | 35 | public: 36 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer|Protocol") 37 | FString FilePath = "log.bin"; 38 | 39 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer|Protocol") 40 | bool PathIsAbsolute = false; 41 | 42 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer|Protocol") 43 | bool CutFirstInterval = false; 44 | 45 | private: 46 | class ODFileReaderUtil* Reader = nullptr; 47 | 48 | class FODWorkerThread* CurrentInnerThread = nullptr; 49 | class FRunnableThread* CurrentThread = nullptr; 50 | 51 | double CurrentLogTime; 52 | TArray ReadBuffer; 53 | TArray ReceiveBuffer; 54 | 55 | FDateTime StartTime; 56 | 57 | int64 FilePosition; 58 | 59 | bool IsFirst; 60 | }; 61 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/Protocol/ProtocolLogWriter.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "ObjectDelivererProtocol.h" 6 | #include "ProtocolLogWriter.generated.h" 7 | 8 | UCLASS(BlueprintType, Blueprintable) 9 | class OBJECTDELIVERER_API UProtocolLogWriter : public UObjectDelivererProtocol 10 | { 11 | GENERATED_BODY() 12 | 13 | public: 14 | UProtocolLogWriter(); 15 | ~UProtocolLogWriter(); 16 | 17 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer|Protocol") 18 | virtual void Initialize(const FString& FilePath = "log.bin", bool PathIsAbsolute = false); 19 | 20 | virtual void Start() override; 21 | virtual void Close() override; 22 | virtual void Send(const TArray& DataBuffer) const override; 23 | virtual void RequestSend(const TArray& DataBuffer) override; 24 | 25 | 26 | public: 27 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer|Protocol") 28 | FString FilePath = "log.bin"; 29 | 30 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer|Protocol") 31 | bool PathIsAbsolute = false; 32 | 33 | private: 34 | class ODFileWriterUtil* Writer; 35 | FDateTime StartTime; 36 | }; 37 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/Protocol/ProtocolReflection.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "ObjectDelivererProtocol.h" 6 | #include "ProtocolReflection.generated.h" 7 | 8 | 9 | UCLASS(BlueprintType, Blueprintable) 10 | class OBJECTDELIVERER_API UProtocolReflection : public UObjectDelivererProtocol 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | UProtocolReflection(); 16 | ~UProtocolReflection(); 17 | 18 | virtual void Send(const TArray& DataBuffer) const override; 19 | 20 | virtual void RequestSend(const TArray& DataBuffer) override; 21 | }; 22 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/Protocol/ProtocolSharedMemory.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "ObjectDelivererProtocol.h" 6 | #include "ProtocolSharedMemory.generated.h" 7 | 8 | 9 | UCLASS(BlueprintType, Blueprintable) 10 | class OBJECTDELIVERER_API UProtocolSharedMemory : public UObjectDelivererProtocol 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | UProtocolSharedMemory(); 16 | ~UProtocolSharedMemory(); 17 | 18 | /** 19 | * Initialize TCP/IP server. 20 | * @param SharedMemoryName - SharedMemory name. 21 | * @param SharedMemorySize - SharedMemory size. 22 | */ 23 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer|Protocol") 24 | void Initialize(const FString& SharedMemoryName = "SharedMemory", int32 SharedMemorySize = 1024); 25 | 26 | virtual void Start() override; 27 | virtual void Close() override; 28 | virtual void Send(const TArray& DataBuffer) const override; 29 | 30 | virtual void RequestSend(const TArray& DataBuffer) override; 31 | 32 | protected: 33 | bool ReceivedData(); 34 | void CloseSharedMemory(); 35 | 36 | public: 37 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer|Protocol") 38 | FString SharedMemoryName = "SharedMemory"; 39 | 40 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer|Protocol") 41 | int32 SharedMemorySize = 1024; 42 | 43 | protected: 44 | class FODWorkerThread* CurrentInnerThread = nullptr; 45 | class FRunnableThread* CurrentThread = nullptr; 46 | 47 | TArray ReceiveBuffer; 48 | TArray TempBuffer; 49 | 50 | void* SharedMemoryHandle; ///< Mapped memory handle. 51 | unsigned char* SharedMemoryData; ///< Pointer to memory data. 52 | void* SharedMemoryMutex; ///< Mutex handle. 53 | int32 SharedMemoryTotalSize; 54 | uint8 NowCounter; 55 | }; 56 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/Protocol/ProtocolSocketBase.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "Interfaces/IPv4/IPv4Endpoint.h" 6 | #include "Sockets.h" 7 | #include "ObjectDelivererProtocol.h" 8 | #include "ProtocolSocketBase.generated.h" 9 | 10 | UCLASS(BlueprintType, Blueprintable) 11 | class OBJECTDELIVERER_API UProtocolSocketBase : public UObjectDelivererProtocol 12 | { 13 | GENERATED_BODY() 14 | 15 | public: 16 | UProtocolSocketBase(); 17 | ~UProtocolSocketBase(); 18 | 19 | void CloseInnerSocket(); 20 | 21 | void SendTo(const TArray& DataBuffer, const FIPv4Endpoint& EndPoint) const; 22 | 23 | void SendToConnected(const TArray& DataBuffer) const; 24 | 25 | protected: 26 | bool FormatIP4ToNumber(const FString& IpAddress, uint8(&Out)[4]); 27 | TTuple GetIP4EndPoint(const FString& IpAddress, int32 Port); 28 | 29 | protected: 30 | FSocket* InnerSocket = nullptr; 31 | }; 32 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/Protocol/ProtocolTcpIpClient.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "ProtocolTcpIpSocket.h" 6 | #include "ProtocolTcpIpClient.generated.h" 7 | 8 | 9 | UCLASS(BlueprintType, Blueprintable) 10 | class OBJECTDELIVERER_API UProtocolTcpIpClient : public UProtocolTcpIpSocket 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | UProtocolTcpIpClient(); 16 | ~UProtocolTcpIpClient(); 17 | 18 | /** 19 | * Initialize TCP/IP server. 20 | * @param IpAddress - The ip address of the connection destination. 21 | * @param Port - The port number of the connection destination. 22 | * @param Retry - If connection fails, try connection again 23 | */ 24 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer|Protocol") 25 | void Initialize(const FString& IpAddress = "localhost", int32 Port = 8000, bool Retry = false, bool AutoConnectAfterDisconnect = false); 26 | 27 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer|Protocol") 28 | UProtocolTcpIpClient* WithReceiveBufferSize(int32 SizeInBytes); 29 | 30 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer|Protocol") 31 | UProtocolTcpIpClient* WithSendBufferSize(int32 SizeInBytes); 32 | 33 | virtual void Start() override; 34 | virtual void Close() override; 35 | 36 | private: 37 | bool TryConnect(); 38 | void CreateSocket(); 39 | 40 | protected: 41 | virtual void DispatchDisconnected(const UObjectDelivererProtocol* DisconnectedObject) override; 42 | 43 | public: 44 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer|Protocol") 45 | FString ServerIpAddress = "localhost"; 46 | 47 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer|Protocol") 48 | int32 ServerPort = 8000; 49 | 50 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer|Protocol") 51 | bool RetryConnect = false; 52 | 53 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer|Protocol") 54 | bool AutoConnectAfterDisconnect = false; 55 | 56 | 57 | protected: 58 | class FODWorkerThread* ConnectInnerThread = nullptr; 59 | class FRunnableThread* ConnectThread = nullptr; 60 | 61 | FIPv4Endpoint ConnectEndPoint; 62 | }; 63 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/Protocol/ProtocolTcpIpServer.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "Sockets.h" 6 | #include "ObjectDelivererProtocol.h" 7 | #include "ProtocolTcpIpServer.generated.h" 8 | 9 | 10 | class UProtocolTcpIpSocket; 11 | 12 | UCLASS(BlueprintType, Blueprintable) 13 | class OBJECTDELIVERER_API UProtocolTcpIpServer : public UObjectDelivererProtocol 14 | { 15 | GENERATED_BODY() 16 | 17 | public: 18 | UProtocolTcpIpServer(); 19 | ~UProtocolTcpIpServer(); 20 | 21 | /** 22 | * Initialize TCP/IP server. 23 | * @param Port - listen port number. 24 | */ 25 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer|Protocol") 26 | void Initialize(int32 Port); 27 | 28 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer|Protocol") 29 | UProtocolTcpIpServer* WithReceiveBufferSize(int32 SizeInBytes); 30 | 31 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer|Protocol") 32 | UProtocolTcpIpServer* WithSendBufferSize(int32 SizeInBytes); 33 | 34 | virtual void Start() override; 35 | virtual void Close() override; 36 | virtual void Send(const TArray& DataBuffer) const override; 37 | 38 | protected: 39 | bool OnListen(); 40 | 41 | UFUNCTION() 42 | void DisconnectedClient(const UObjectDelivererProtocol* ClientSocket); 43 | 44 | UFUNCTION() 45 | void ReceiveDataFromClient(const UObjectDelivererProtocol* ClientSocket, const TArray& Buffer); 46 | 47 | public: 48 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer|Protocol") 49 | int32 ListenPort = 8000; 50 | 51 | UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "ObjectDeliverer|Protocol") 52 | int32 MaxBacklog = 10; 53 | 54 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer|Protocol") 55 | int32 ReceiveBufferSize = 1024 * 1024; 56 | 57 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer|Protocol") 58 | int32 SendBufferSize = 1024 * 1024; 59 | 60 | protected: 61 | FSocket* ListenerSocket = nullptr; 62 | class FODWorkerThread* ListenInnerThread = nullptr; 63 | class FRunnableThread* ListenThread = nullptr; 64 | 65 | TArray ConnectedSockets; 66 | 67 | bool IsClosing = false; 68 | }; 69 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/Protocol/ProtocolTcpIpSocket.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "ProtocolSocketBase.h" 6 | #include "GetIPV4Info.h" 7 | #include "Utils/ODGrowBuffer.h" 8 | #include "ProtocolTcpIpSocket.generated.h" 9 | 10 | UCLASS(BlueprintType, Blueprintable) 11 | class OBJECTDELIVERER_API UProtocolTcpIpSocket : public UProtocolSocketBase, public IGetIPV4Info 12 | { 13 | GENERATED_BODY() 14 | 15 | public: 16 | UProtocolTcpIpSocket(); 17 | virtual ~UProtocolTcpIpSocket(); 18 | 19 | virtual void Close() override; 20 | virtual void Send(const TArray& DataBuffer) const override; 21 | 22 | void OnConnected(FSocket* ConnectionSocket); 23 | 24 | virtual void RequestSend(const TArray& DataBuffer) override; 25 | 26 | bool GetIPAddress(TArray& IPAddress) override; 27 | bool GetIPAddressInString(FString& IPAddress) override; 28 | 29 | public: 30 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer|Protocol") 31 | int32 ReceiveBufferSize = 1024 * 1024; 32 | 33 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer|Protocol") 34 | int32 SendBufferSize = 1024 * 1024; 35 | 36 | protected: 37 | void CloseSocket(); 38 | void StartPollilng(); 39 | bool ReceivedData(); 40 | 41 | protected: 42 | class FODWorkerThread* CurrentInnerThread = nullptr; 43 | class FRunnableThread* CurrentThread = nullptr; 44 | 45 | ODGrowBuffer ReceiveBuffer; 46 | FCriticalSection ct; 47 | bool IsSelfClose = false; 48 | }; 49 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/Protocol/ProtocolUdpSocket.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "ProtocolSocketBase.h" 6 | #include "GetIPV4Info.h" 7 | #include "Utils/ODGrowBuffer.h" 8 | #include "ProtocolUdpSocket.generated.h" 9 | 10 | 11 | class FSocket; 12 | 13 | UCLASS(BlueprintType, Blueprintable) 14 | class OBJECTDELIVERER_API UProtocolUdpSocket : public UProtocolSocketBase, public IGetIPV4Info 15 | { 16 | GENERATED_BODY() 17 | 18 | public: 19 | UProtocolUdpSocket(); 20 | ~UProtocolUdpSocket(); 21 | 22 | void Initialize(FIPv4Endpoint IP); 23 | void NotifyReceived(const ODByteSpan& data); 24 | 25 | bool GetIPAddress(TArray& IPAddress) override; 26 | bool GetIPAddressInString(FString& IPAddress) override; 27 | 28 | 29 | private: 30 | FIPv4Endpoint IPEndPoint; 31 | ODGrowBuffer ReceiveBuffer; 32 | }; 33 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/Protocol/ProtocolUdpSocketReceiver.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "ProtocolSocketBase.h" 6 | #include "Utils/ODGrowBuffer.h" 7 | #include "ProtocolUdpSocketReceiver.generated.h" 8 | 9 | 10 | class FSocket; 11 | class FUdpSocketReceiver; 12 | class UProtocolUdpSocket; 13 | 14 | UCLASS(BlueprintType, Blueprintable) 15 | class OBJECTDELIVERER_API UProtocolUdpSocketReceiver : public UProtocolSocketBase 16 | { 17 | GENERATED_BODY() 18 | 19 | public: 20 | UProtocolUdpSocketReceiver(); 21 | ~UProtocolUdpSocketReceiver(); 22 | 23 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer|Protocol") 24 | void InitializeWithReceiver(int32 BoundPort = 8000); 25 | 26 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer|Protocol") 27 | UProtocolUdpSocketReceiver* WithReceiveBufferSize(int32 SizeInBytes); 28 | 29 | virtual void Start() override; 30 | virtual void Close() override; 31 | 32 | protected: 33 | UFUNCTION() 34 | void ReceiveDataFromClient(const UObjectDelivererProtocol* ClientSocket, const TArray& Buffer); 35 | 36 | bool ReceivedData(); 37 | 38 | private: 39 | FCriticalSection ct; 40 | TMap ConnectedSockets; 41 | class FODWorkerThread* CurrentInnerThread = nullptr; 42 | class FRunnableThread* CurrentThread = nullptr; 43 | ODGrowBuffer ReceiveBuffer; 44 | bool IsSelfClose = false; 45 | ISocketSubsystem* SocketSubsystem; 46 | 47 | public: 48 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer|Protocol") 49 | int32 BoundPort = 8000; 50 | 51 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer|Protocol") 52 | int32 ReceiveBufferSize = 1024 * 1024; 53 | 54 | }; 55 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/Protocol/ProtocolUdpSocketSender.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "ProtocolSocketBase.h" 6 | #include "ProtocolUdpSocketSender.generated.h" 7 | 8 | UCLASS(BlueprintType, Blueprintable) 9 | class OBJECTDELIVERER_API UProtocolUdpSocketSender : public UProtocolSocketBase 10 | { 11 | GENERATED_BODY() 12 | 13 | public: 14 | UProtocolUdpSocketSender(); 15 | ~UProtocolUdpSocketSender(); 16 | 17 | /** 18 | * Initialize UDP. 19 | * @param IpAddress - The ip address of the destination. 20 | * @param Port - The port number of the destination. 21 | */ 22 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer|Protocol") 23 | virtual void Initialize(const FString &IpAddress = "localhost", int32 Port = 8000); 24 | 25 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer|Protocol") 26 | UProtocolUdpSocketSender *WithSendBufferSize(int32 SizeInBytes); 27 | 28 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer|Protocol") 29 | UProtocolUdpSocketSender *WithBroadcast(bool InEnableBroadcast); 30 | 31 | virtual void Start() override; 32 | virtual void Close() override; 33 | virtual void Send(const TArray &DataBuffer) const override; 34 | 35 | virtual void RequestSend(const TArray &DataBuffer) override; 36 | 37 | public: 38 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer|Protocol") 39 | FString DestinationIpAddress = "localhost"; 40 | 41 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer|Protocol") 42 | int32 DestinationPort = 8000; 43 | 44 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer|Protocol") 45 | int32 SendBufferSize = 1024 * 1024; 46 | 47 | UPROPERTY(BlueprintReadWrite, EditAnywhere, meta = (ExposeOnSpawn = true), Category = "ObjectDeliverer|Protocol") 48 | bool bEnableBroadcast = false; 49 | 50 | protected: 51 | FIPv4Endpoint DestinationEndpoint; 52 | }; 53 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDeliverer/Public/Utils/ODGrowBuffer.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | 6 | struct OBJECTDELIVERER_API ODByteSpan 7 | { 8 | uint8* Buffer; 9 | int32 Length; 10 | 11 | ODByteSpan(){} 12 | ODByteSpan(uint8* RawBuffer, int32 RawBufferLength) 13 | { 14 | Buffer = RawBuffer; 15 | Length = RawBufferLength; 16 | } 17 | ODByteSpan(TArray& FromBuffer) 18 | { 19 | Buffer = FromBuffer.GetData(); 20 | Length = FromBuffer.Num(); 21 | } 22 | 23 | void CopyFrom(const ODByteSpan& FromBuffer) 24 | { 25 | if (Length < FromBuffer.Length) 26 | { 27 | checkf(Length >= FromBuffer.Length, TEXT("ODByteSpan::CopyFrom SizeOver!")); 28 | } 29 | FMemory::Memcpy((void*)Buffer, (const void*)FromBuffer.Buffer, FromBuffer.Length); 30 | } 31 | 32 | TArray ToArray() const 33 | { 34 | return TArray(Buffer, Length); 35 | } 36 | }; 37 | 38 | class OBJECTDELIVERER_API ODGrowBuffer 39 | { 40 | public: 41 | ODGrowBuffer(int32 initialSize = 1024, int32 packetSize = 1024); 42 | 43 | uint8 operator [](int32 index) 44 | { 45 | return innerBuffer[index]; 46 | } 47 | 48 | int32 GetLength() const; 49 | int32 GetInnerBufferSize() const; 50 | 51 | ODByteSpan AsSpan(); 52 | ODByteSpan AsSpan(int32 Position, int32 Length); 53 | 54 | bool SetLength(int32 NewSize = 0); 55 | 56 | void Add(ODByteSpan addBuffer); 57 | 58 | void CopyFrom(ODByteSpan fromBuffer, int32 myOffset = 0); 59 | void RemoveRangeFromStart(int32 start, int32 length); 60 | void Clear(); 61 | 62 | private: 63 | int32 packetSize = 1024; 64 | TArray innerBuffer; 65 | int32 currentSize; 66 | }; 67 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDelivererTests/ObjectDelivererTests.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | 3 | using System.IO; 4 | using UnrealBuildTool; 5 | 6 | public class ObjectDelivererTests : ModuleRules 7 | { 8 | public ObjectDelivererTests(ReadOnlyTargetRules Target) : base(Target) 9 | { 10 | PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; 11 | ShadowVariableWarningLevel = WarningLevel.Warning; 12 | 13 | PublicDependencyModuleNames.AddRange( 14 | new string[] 15 | { 16 | "Core", 17 | "CoreUObject", 18 | "Engine", 19 | "Sockets", 20 | "Networking", 21 | "Json", 22 | "JsonUtilities" 23 | } 24 | ); 25 | 26 | PrivateDependencyModuleNames.AddRange( 27 | new string[] 28 | { 29 | "ObjectDeliverer", 30 | "Slate", 31 | "SlateCore" 32 | } 33 | ); 34 | 35 | if (Target.bBuildEditor) 36 | { 37 | PrivateDependencyModuleNames.AddRange( 38 | new string[] 39 | { 40 | "UnrealEd", 41 | "FunctionalTesting" 42 | } 43 | ); 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDelivererTests/Private/ODGrowBufferTest.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | 3 | #include "Misc/AutomationTest.h" 4 | #include "Utils/ODGrowBuffer.h" 5 | 6 | IMPLEMENT_SIMPLE_AUTOMATION_TEST(ODGrowBuffer_Tests, "ObjectDeliverer.GrowBuffer.Test", EAutomationTestFlags_ApplicationContextMask | EAutomationTestFlags::SmokeFilter) 7 | 8 | bool ODGrowBuffer_Tests::RunTest(const FString& Parameters) 9 | { 10 | const int packetSize = 1024; 11 | 12 | { 13 | auto buffer = ODGrowBuffer(100); 14 | 15 | TestEqual(TEXT("check buffer size"), buffer.GetLength(), 100); 16 | TestEqual(TEXT("check inner buffer size"), buffer.GetInnerBufferSize(), packetSize); 17 | 18 | buffer.SetLength(2000); 19 | 20 | TestEqual(TEXT("check buffer size"), buffer.GetLength(), 2000); 21 | TestEqual(TEXT("check inner buffer size"), buffer.GetInnerBufferSize(), packetSize * 2); 22 | 23 | uint8 testDataArray[] = { 1, 2, 3 }; 24 | buffer.Add(ODByteSpan(testDataArray, sizeof(testDataArray))); 25 | 26 | TestEqual(TEXT("check buffer size"), buffer.GetLength(), 2003); 27 | TestEqual(TEXT("check inner buffer size"), buffer.GetInnerBufferSize(), packetSize * 2); 28 | TestEqual(TEXT("check Add Data1"), buffer[2000], 1); 29 | TestEqual(TEXT("check Add Data2"), buffer[2001], 2); 30 | TestEqual(TEXT("check Add Data3"), buffer[2002], 3); 31 | 32 | buffer.RemoveRangeFromStart(0, 2000); 33 | TestEqual(TEXT("check buffer size"), buffer.GetLength(), 3); 34 | TestEqual(TEXT("check inner buffer size"), buffer.GetInnerBufferSize(), packetSize * 2); 35 | TestEqual(TEXT("check Add Data1"), buffer[0], 1); 36 | TestEqual(TEXT("check Add Data2"), buffer[1], 2); 37 | TestEqual(TEXT("check Add Data3"), buffer[2], 3); 38 | 39 | uint8 testDataArray2[] = { 0xEE, 0xEF }; 40 | buffer.CopyFrom(ODByteSpan(testDataArray2, sizeof(testDataArray2)), 1); 41 | TestEqual(TEXT("check buffer size"), buffer.GetLength(), 3); 42 | TestEqual(TEXT("check inner buffer size"), buffer.GetInnerBufferSize(), packetSize * 2); 43 | TestEqual(TEXT("check Add Data1"), buffer[0], 1); 44 | TestEqual(TEXT("check Add Data2"), buffer[1], 0xEE); 45 | TestEqual(TEXT("check Add Data3"), buffer[2], 0xEF); 46 | 47 | buffer.Clear(); 48 | TestEqual(TEXT("check buffer size"), buffer.GetLength(), 0); 49 | TestEqual(TEXT("check inner buffer size"), buffer.GetInnerBufferSize(), packetSize * 2); 50 | } 51 | 52 | return true; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDelivererTests/Private/ObjectDelivererManagerTestHelper.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "ObjectDelivererManagerTestHelper.h" 3 | #include "Protocol/ObjectDelivererProtocol.h" 4 | 5 | void UObjectDelivererManagerTestHelper::OnConnect(const UObjectDelivererProtocol* ClientSocket) 6 | { 7 | ConnectedSocket.Add(ClientSocket); 8 | } 9 | 10 | void UObjectDelivererManagerTestHelper::OnDisConnect(const UObjectDelivererProtocol* ClientSocket) 11 | { 12 | DisconnectedSocket.Add(ClientSocket); 13 | } 14 | 15 | void UObjectDelivererManagerTestHelper::OnReceive(const UObjectDelivererProtocol* ClientSocket, const TArray& Buffer) 16 | { 17 | ReceiveSocket = ClientSocket; 18 | ReceiveBuffers.Add(Buffer); 19 | } 20 | 21 | void UObjectDelivererManagerTestHelper::OnReceiveString(const FString& StringValue, const UObjectDelivererProtocol* FromObject) 22 | { 23 | ReceiveStrings.Add(StringValue); 24 | } -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDelivererTests/Private/ObjectDelivererManagerTestHelper.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "UObject/GCObject.h" 6 | #include "DeliveryBox/IODConvertPropertyName.h" 7 | #include "ObjectDelivererManagerTestHelper.generated.h" 8 | 9 | class UObjectDelivererProtocol; 10 | 11 | UCLASS() 12 | class OBJECTDELIVERERTESTS_API UObjectDelivererManagerTestHelper : public UObject 13 | { 14 | GENERATED_BODY() 15 | 16 | public: 17 | UFUNCTION() 18 | void OnConnect(const UObjectDelivererProtocol *ClientSocket); 19 | UFUNCTION() 20 | void OnDisConnect(const UObjectDelivererProtocol *ClientSocket); 21 | UFUNCTION() 22 | void OnReceive(const UObjectDelivererProtocol *ClientSocket, const TArray &Buffer); 23 | UFUNCTION() 24 | void OnReceiveString(const FString &StringValue, const UObjectDelivererProtocol *FromObject); 25 | 26 | UPROPERTY() 27 | TArray ConnectedSocket; 28 | 29 | UPROPERTY() 30 | TArray DisconnectedSocket; 31 | 32 | UPROPERTY() 33 | const UObjectDelivererProtocol *ReceiveSocket; 34 | 35 | TArray> ReceiveBuffers; 36 | TArray ReceiveStrings; 37 | }; 38 | 39 | UCLASS() 40 | class OBJECTDELIVERERTESTS_API UJsonSerializerTestArrayElementObject1 : public UObject 41 | { 42 | GENERATED_BODY() 43 | 44 | public: 45 | UPROPERTY() 46 | int32 IntProperty; 47 | }; 48 | 49 | UCLASS() 50 | class OBJECTDELIVERERTESTS_API UJsonSerializerTestArrayElementObject2 : public UJsonSerializerTestArrayElementObject1 51 | { 52 | GENERATED_BODY() 53 | 54 | public: 55 | UPROPERTY() 56 | int32 IntProperty2; 57 | }; 58 | 59 | UCLASS() 60 | class OBJECTDELIVERERTESTS_API UJsonSerializerTestObject : public UObject 61 | { 62 | GENERATED_BODY() 63 | 64 | public: 65 | UPROPERTY() 66 | int32 IntProperty; 67 | 68 | UPROPERTY() 69 | float FloatProperty; 70 | 71 | UPROPERTY() 72 | uint8 Uint8Property; 73 | 74 | UPROPERTY() 75 | bool BoolProperty; 76 | 77 | UPROPERTY() 78 | FString StringProperty; 79 | 80 | UPROPERTY() 81 | FVector VectorProperty; 82 | 83 | UPROPERTY() 84 | FRotator RotateProperty; 85 | 86 | UPROPERTY() 87 | TArray ArrayProperty; 88 | }; 89 | 90 | UCLASS() 91 | class OBJECTDELIVERERTESTS_API UJsonSerializeConvertNameTestObject : public UObject, public IODConvertPropertyName 92 | { 93 | GENERATED_BODY() 94 | 95 | public: 96 | UPROPERTY() 97 | int32 IntProperty; 98 | 99 | UPROPERTY() 100 | float FloatProperty; 101 | 102 | UPROPERTY() 103 | uint8 Uint8Property; 104 | 105 | FString ConvertFPropertyName_Implementation(const FName &PropertyName) const override 106 | { 107 | if (PropertyName == FName(TEXT("IntProperty"))) 108 | { 109 | return TEXT("IntProperty_Converted"); 110 | } 111 | else if (PropertyName == FName(TEXT("FloatProperty"))) 112 | { 113 | return TEXT("FloatProperty_Converted"); 114 | } 115 | else if (PropertyName == FName(TEXT("Uint8Property"))) 116 | { 117 | return TEXT("Uint8Property_Converted"); 118 | } 119 | 120 | return TEXT(""); 121 | } 122 | }; 123 | 124 | UCLASS() 125 | class OBJECTDELIVERERTESTS_API UJsonSerializerNestedObject : public UObject 126 | { 127 | GENERATED_BODY() 128 | 129 | public: 130 | UPROPERTY() 131 | FString Name; 132 | 133 | UPROPERTY() 134 | int32 Value; 135 | }; 136 | 137 | UCLASS() 138 | class OBJECTDELIVERERTESTS_API UJsonSerializerComplexObject : public UObject 139 | { 140 | GENERATED_BODY() 141 | 142 | public: 143 | UPROPERTY() 144 | TMap MapProperty; 145 | 146 | UPROPERTY() 147 | TSet SetProperty; 148 | 149 | UPROPERTY() 150 | UJsonSerializerNestedObject *NestedObject; 151 | 152 | UPROPERTY() 153 | TArray NestedObjectArray; 154 | }; 155 | 156 | // Class for testing inheritance relationships 157 | UCLASS() 158 | class OBJECTDELIVERERTESTS_API UJsonSerializerBaseClass : public UObject 159 | { 160 | GENERATED_BODY() 161 | 162 | public: 163 | UPROPERTY() 164 | int32 BaseValue; 165 | 166 | UPROPERTY() 167 | FString BaseName; 168 | }; 169 | 170 | UCLASS() 171 | class OBJECTDELIVERERTESTS_API UJsonSerializerDerivedClass : public UJsonSerializerBaseClass 172 | { 173 | GENERATED_BODY() 174 | 175 | public: 176 | UPROPERTY() 177 | float DerivedValue; 178 | 179 | UPROPERTY() 180 | bool DerivedFlag; 181 | }; 182 | 183 | // Class for testing UE4 basic types 184 | UCLASS() 185 | class OBJECTDELIVERERTESTS_API UJsonSerializerUE4TypesObject : public UObject 186 | { 187 | GENERATED_BODY() 188 | 189 | public: 190 | UPROPERTY() 191 | FTransform TransformProperty; 192 | 193 | UPROPERTY() 194 | FColor ColorProperty; 195 | 196 | UPROPERTY() 197 | FDateTime DateTimeProperty; 198 | 199 | UPROPERTY() 200 | FGuid GuidProperty; 201 | }; 202 | 203 | // Class for objects with circular references 204 | UCLASS() 205 | class OBJECTDELIVERERTESTS_API UJsonSerializerCircularObject : public UObject 206 | { 207 | GENERATED_BODY() 208 | 209 | public: 210 | UPROPERTY() 211 | FString Name; 212 | 213 | UPROPERTY() 214 | UJsonSerializerCircularObject *Reference; 215 | }; 216 | 217 | UCLASS() 218 | class UUtf8StringDeliveryBoxTestHelper : public UObject 219 | { 220 | GENERATED_BODY() 221 | 222 | public: 223 | UFUNCTION() 224 | void OnReceiveString(const FString &StringValue, const UObjectDelivererProtocol *FromObject) 225 | { 226 | ReceivedStrings.Add(StringValue); 227 | } 228 | 229 | TArray ReceivedStrings; 230 | }; 231 | 232 | UCLASS() 233 | class UObjectDeliveryBoxUsingJsonTestHelper : public UObject 234 | { 235 | GENERATED_BODY() 236 | 237 | public: 238 | UFUNCTION() 239 | void OnReceiveObject(UObject* ReceivedObject, const FString& ReceivedJsonString, const UObjectDelivererProtocol* FromObject) 240 | { 241 | ReceivedObjects.Add(ReceivedObject); 242 | } 243 | 244 | TArray ReceivedObjects; 245 | }; -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDelivererTests/Private/ObjectDelivererTests.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "ObjectDelivererTests.h" 3 | 4 | IMPLEMENT_MODULE(FObjectDelivererTestsModule, ObjectDelivererTests) 5 | 6 | void FObjectDelivererTestsModule::StartupModule() 7 | { 8 | } 9 | 10 | void FObjectDelivererTestsModule::ShutdownModule() 11 | { 12 | } 13 | -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDelivererTests/Private/PacketRuleFixedLengthTest.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | 3 | #include "Misc/AutomationTest.h" 4 | #include "PacketRule/PacketRuleFactory.h" 5 | #include "PacketRule/PacketRuleFixedLength.h" 6 | 7 | IMPLEMENT_SIMPLE_AUTOMATION_TEST(FCNPacketRuleFixedLengthTest_MakeSendPacket, "ObjectDeliverer.PacketRuleTests.MakeSendPacket", EAutomationTestFlags_ApplicationContextMask | EAutomationTestFlags::SmokeFilter) 8 | 9 | bool FCNPacketRuleFixedLengthTest_MakeSendPacket::RunTest(const FString& Parameters) 10 | { 11 | // just size 12 | { 13 | auto packetRule = UPacketRuleFactory::CreatePacketRuleFixedLength(8); 14 | 15 | packetRule->MadeSendBuffer.BindLambda([this](const TArray& Buffer) 16 | { 17 | TestEqual(TEXT("MakeSendPacket check size"), Buffer.Num(), 8); 18 | 19 | for (int i = 0; i < Buffer.Num(); ++i) 20 | { 21 | TestEqual(TEXT("MakeSendPacket check buffer value"), Buffer[i], i); 22 | } 23 | 24 | }); 25 | 26 | packetRule->Initialize(); 27 | 28 | TArray buffer; 29 | buffer.SetNum(8); 30 | for (int i = 0; i < buffer.Num(); ++i) 31 | { 32 | buffer[i] = i; 33 | } 34 | 35 | packetRule->MakeSendPacket(buffer); 36 | } 37 | 38 | // over size 39 | { 40 | auto packetRule = UPacketRuleFactory::CreatePacketRuleFixedLength(8); 41 | 42 | packetRule->MadeSendBuffer.BindLambda([this](const TArray& Buffer) 43 | { 44 | TestEqual(TEXT("MakeSendPacket check size"), Buffer.Num(), 8); 45 | 46 | for (int i = 0; i < Buffer.Num(); ++i) 47 | { 48 | TestEqual(TEXT("MakeSendPacket check buffer value"), Buffer[i], i); 49 | } 50 | 51 | }); 52 | 53 | packetRule->Initialize(); 54 | 55 | TArray buffer; 56 | buffer.SetNum(10); 57 | for (int i = 0; i < buffer.Num(); ++i) 58 | { 59 | buffer[i] = i; 60 | } 61 | 62 | packetRule->MakeSendPacket(buffer); 63 | } 64 | 65 | // under size 66 | { 67 | auto packetRule = UPacketRuleFactory::CreatePacketRuleFixedLength(8); 68 | 69 | packetRule->MadeSendBuffer.BindLambda([this](const TArray& Buffer) 70 | { 71 | TestEqual(TEXT("MakeSendPacket check size"), Buffer.Num(), 8); 72 | 73 | for (int i = 0; i < 6; ++i) 74 | { 75 | TestEqual(TEXT("MakeSendPacket check buffer value"), Buffer[i], i); 76 | } 77 | 78 | for (int i = 6; i < 8; ++i) 79 | { 80 | TestEqual(TEXT("MakeSendPacket check buffer value"), Buffer[i], 0); 81 | } 82 | 83 | }); 84 | 85 | packetRule->Initialize(); 86 | 87 | TArray buffer; 88 | buffer.SetNum(6); 89 | for (int i = 0; i < buffer.Num(); ++i) 90 | { 91 | buffer[i] = i; 92 | } 93 | 94 | packetRule->MakeSendPacket(buffer); 95 | } 96 | 97 | 98 | return true; 99 | } 100 | 101 | IMPLEMENT_SIMPLE_AUTOMATION_TEST(FCNPacketRuleFixedLengthTest_NotifyReceiveData, "ObjectDeliverer.PacketRuleTests.NotifyReceiveData", EAutomationTestFlags_ApplicationContextMask | EAutomationTestFlags::SmokeFilter) 102 | 103 | bool FCNPacketRuleFixedLengthTest_NotifyReceiveData::RunTest(const FString& Parameters) 104 | { 105 | // 106 | { 107 | auto packetRule = UPacketRuleFactory::CreatePacketRuleFixedLength(8); 108 | 109 | bool isReceived = false; 110 | 111 | packetRule->MadeReceiveBuffer.BindLambda([this, &isReceived](const TArray& Buffer) 112 | { 113 | isReceived = true; 114 | 115 | TestEqual(TEXT("NotifyReceiveData check size"), Buffer.Num(), 8); 116 | 117 | for (int i = 0; i < Buffer.Num(); ++i) 118 | { 119 | TestEqual(TEXT("NotifyReceiveData check buffer value"), Buffer[i], i); 120 | } 121 | 122 | }); 123 | 124 | packetRule->Initialize(); 125 | 126 | TArray buffer; 127 | buffer.SetNum(8); 128 | for (int i = 0; i < buffer.Num(); ++i) 129 | { 130 | buffer[i] = i; 131 | } 132 | 133 | packetRule->NotifyReceiveData(buffer); 134 | 135 | TestEqual(TEXT("NotifyReceiveData check receuved"), isReceived, true); 136 | } 137 | 138 | 139 | return true; 140 | } -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDelivererTests/Private/PacketRuleNodivisionTest.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | 3 | #include "Misc/AutomationTest.h" 4 | #include "PacketRule/PacketRuleFactory.h" 5 | #include "PacketRule/PacketRuleNodivision.h" 6 | 7 | IMPLEMENT_SIMPLE_AUTOMATION_TEST(FPacketRuleNodivisionTest_MakeSendPacket, "ObjectDeliverer.PacketRuleTests.PacketRuleNodivisionTest.MakeSendPacket", EAutomationTestFlags_ApplicationContextMask | EAutomationTestFlags::SmokeFilter) 8 | 9 | bool FPacketRuleNodivisionTest_MakeSendPacket::RunTest(const FString& Parameters) 10 | { 11 | { 12 | auto packetRule = UPacketRuleFactory::CreatePacketRuleNodivision(); 13 | 14 | packetRule->MadeSendBuffer.BindLambda([this](const TArray& Buffer) 15 | { 16 | TestEqual(TEXT("MakeSendPacket check size"), Buffer.Num(), 8); 17 | 18 | for (int i = 0; i < 8; ++i) 19 | { 20 | TestEqual(TEXT("MakeSendPacket check buffer value"), Buffer[i], i); 21 | } 22 | }); 23 | 24 | packetRule->Initialize(); 25 | 26 | TArray buffer; 27 | buffer.SetNum(8); 28 | for (int i = 0; i < buffer.Num(); ++i) 29 | { 30 | buffer[i] = i; 31 | } 32 | 33 | packetRule->MakeSendPacket(buffer); 34 | } 35 | 36 | 37 | return true; 38 | } 39 | 40 | IMPLEMENT_SIMPLE_AUTOMATION_TEST(FPacketRuleNodivisionTest_NotifyReceiveData, "ObjectDeliverer.PacketRuleTests.PacketRuleNodivisionTest.NotifyReceiveData", EAutomationTestFlags_ApplicationContextMask | EAutomationTestFlags::SmokeFilter) 41 | 42 | bool FPacketRuleNodivisionTest_NotifyReceiveData::RunTest(const FString& Parameters) 43 | { 44 | { 45 | auto packetRule = UPacketRuleFactory::CreatePacketRuleNodivision(); 46 | 47 | bool isReceived = false; 48 | 49 | packetRule->MadeReceiveBuffer.BindLambda([this, &isReceived](const TArray& Buffer) 50 | { 51 | isReceived = true; 52 | 53 | TestEqual(TEXT("NotifyReceiveData check size"), Buffer.Num(), 8); 54 | 55 | for (int i = 0; i < Buffer.Num(); ++i) 56 | { 57 | TestEqual(TEXT("NotifyReceiveData check buffer value"), Buffer[i], i); 58 | } 59 | 60 | }); 61 | 62 | packetRule->Initialize(); 63 | 64 | TArray buffer; 65 | buffer.SetNum(8); 66 | for (int i = 0; i < 8; ++i) 67 | { 68 | buffer[i] = i; 69 | } 70 | 71 | packetRule->NotifyReceiveData(buffer); 72 | 73 | TestEqual(TEXT("NotifyReceiveData check receuved"), isReceived, true); 74 | } 75 | 76 | 77 | return true; 78 | } -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDelivererTests/Private/PacketRuleSizeBodyTest.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | 3 | #include "Misc/AutomationTest.h" 4 | #include "PacketRule/PacketRuleFactory.h" 5 | #include "PacketRule/PacketRuleSizeBody.h" 6 | 7 | IMPLEMENT_SIMPLE_AUTOMATION_TEST(FPacketRuleSizeBodyTest_MakeSendPacket, "ObjectDeliverer.PacketRuleTests.FPacketRuleSizeBodyTest.MakeSendPacket", EAutomationTestFlags_ApplicationContextMask | EAutomationTestFlags::SmokeFilter) 8 | 9 | bool FPacketRuleSizeBodyTest_MakeSendPacket::RunTest(const FString& Parameters) 10 | { 11 | // size buffer endian is big 12 | { 13 | auto packetRule = UPacketRuleFactory::CreatePacketRuleSizeBody(4, ECNBufferEndian::Big); 14 | packetRule->MadeSendBuffer.BindLambda([this, &packetRule](const TArray& Buffer) 15 | { 16 | TestEqual(TEXT("MakeSendPacket check size"), Buffer.Num(), packetRule->SizeLength + 8); 17 | 18 | TestEqual(TEXT("MakeSendPacket check sizebuffer"), Buffer[0], 0); 19 | TestEqual(TEXT("MakeSendPacket check sizebuffer"), Buffer[1], 0); 20 | TestEqual(TEXT("MakeSendPacket check sizebuffer"), Buffer[2], 0); 21 | TestEqual(TEXT("MakeSendPacket check sizebuffer"), Buffer[3], 8); 22 | 23 | for (int i = packetRule->SizeLength; i < Buffer.Num(); ++i) 24 | { 25 | TestEqual(TEXT("MakeSendPacket check buffer value"), Buffer[i], i - packetRule->SizeLength); 26 | } 27 | 28 | }); 29 | 30 | packetRule->Initialize(); 31 | 32 | TArray buffer; 33 | buffer.SetNum(8); 34 | for (int i = 0; i < buffer.Num(); ++i) 35 | { 36 | buffer[i] = i; 37 | } 38 | 39 | packetRule->MakeSendPacket(buffer); 40 | } 41 | 42 | // size buffer endian is little 43 | { 44 | auto packetRule = UPacketRuleFactory::CreatePacketRuleSizeBody(4, ECNBufferEndian::Little); 45 | 46 | packetRule->MadeSendBuffer.BindLambda([this, &packetRule](const TArray& Buffer) 47 | { 48 | TestEqual(TEXT("MakeSendPacket check size"), Buffer.Num(), packetRule->SizeLength + 8); 49 | 50 | TestEqual(TEXT("MakeSendPacket check sizebuffer"), Buffer[0], 8); 51 | TestEqual(TEXT("MakeSendPacket check sizebuffer"), Buffer[1], 0); 52 | TestEqual(TEXT("MakeSendPacket check sizebuffer"), Buffer[2], 0); 53 | TestEqual(TEXT("MakeSendPacket check sizebuffer"), Buffer[3], 0); 54 | 55 | for (int i = packetRule->SizeLength; i < Buffer.Num(); ++i) 56 | { 57 | TestEqual(TEXT("MakeSendPacket check buffer value"), Buffer[i], i - packetRule->SizeLength); 58 | } 59 | 60 | }); 61 | 62 | packetRule->Initialize(); 63 | 64 | TArray buffer; 65 | buffer.SetNum(8); 66 | for (int i = 0; i < buffer.Num(); ++i) 67 | { 68 | buffer[i] = i; 69 | } 70 | 71 | packetRule->MakeSendPacket(buffer); 72 | } 73 | 74 | 75 | return true; 76 | } 77 | 78 | IMPLEMENT_SIMPLE_AUTOMATION_TEST(FPacketRuleSizeBodyTest_NotifyReceiveData, "ObjectDeliverer.PacketRuleTests.FPacketRuleSizeBodyTest.NotifyReceiveData", EAutomationTestFlags_ApplicationContextMask | EAutomationTestFlags::SmokeFilter) 79 | 80 | bool FPacketRuleSizeBodyTest_NotifyReceiveData::RunTest(const FString& Parameters) 81 | { 82 | // size buffer is big endian 83 | { 84 | auto packetRule = UPacketRuleFactory::CreatePacketRuleSizeBody(4, ECNBufferEndian::Big); 85 | 86 | packetRule->Initialize(); 87 | 88 | TArray buffer; 89 | buffer.SetNum(4); 90 | buffer[0] = 0; 91 | buffer[1] = 0; 92 | buffer[2] = 0; 93 | buffer[3] = 8; 94 | 95 | bool notCall = true; 96 | 97 | packetRule->MadeReceiveBuffer.BindLambda([this, ¬Call](const TArray& Buffer) 98 | { 99 | // must not be called here 100 | notCall = false; 101 | }); 102 | 103 | packetRule->NotifyReceiveData(buffer); 104 | 105 | TestEqual(TEXT("NotifyReceiveData not call"), notCall, true); 106 | 107 | buffer.SetNum(8); 108 | for (int i = 0; i < buffer.Num(); ++i) 109 | { 110 | buffer[i] = i; 111 | } 112 | 113 | bool isReceived = false; 114 | 115 | packetRule->MadeReceiveBuffer.BindLambda([this, &isReceived](const TArray& Buffer) 116 | { 117 | isReceived = true; 118 | 119 | TestEqual(TEXT("NotifyReceiveData check size"), Buffer.Num(), 8); 120 | 121 | for (int i = 0; i < 8; ++i) 122 | { 123 | TestEqual(TEXT("MakeSendPacket check buffer value"), Buffer[i], i); 124 | } 125 | }); 126 | 127 | packetRule->NotifyReceiveData(buffer); 128 | 129 | TestEqual(TEXT("NotifyReceiveData check receuved"), isReceived, true); 130 | } 131 | 132 | // size buffer is little endian 133 | { 134 | auto packetRule = UPacketRuleFactory::CreatePacketRuleSizeBody(4, ECNBufferEndian::Little); 135 | 136 | packetRule->Initialize(); 137 | 138 | TArray buffer; 139 | buffer.SetNum(4); 140 | buffer[0] = 8; 141 | buffer[1] = 0; 142 | buffer[2] = 0; 143 | buffer[3] = 0; 144 | 145 | bool notCall = true; 146 | 147 | packetRule->MadeReceiveBuffer.BindLambda([this, ¬Call](const TArray& Buffer) 148 | { 149 | // must not be called here 150 | notCall = false; 151 | }); 152 | 153 | 154 | packetRule->NotifyReceiveData(buffer); 155 | 156 | TestEqual(TEXT("NotifyReceiveData not call"), notCall, true); 157 | 158 | buffer.SetNum(8); 159 | for (int i = 0; i < buffer.Num(); ++i) 160 | { 161 | buffer[i] = i; 162 | } 163 | 164 | bool isReceived = false; 165 | 166 | packetRule->MadeReceiveBuffer.BindLambda([this, &isReceived](const TArray& Buffer) 167 | { 168 | isReceived = true; 169 | 170 | TestEqual(TEXT("NotifyReceiveData check size"), Buffer.Num(), 8); 171 | 172 | for (int i = 0; i < 8; ++i) 173 | { 174 | TestEqual(TEXT("MakeSendPacket check buffer value"), Buffer[i], i); 175 | } 176 | }); 177 | 178 | packetRule->NotifyReceiveData(buffer); 179 | 180 | TestEqual(TEXT("NotifyReceiveData check receuved"), isReceived, true); 181 | } 182 | 183 | 184 | 185 | return true; 186 | } -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDelivererTests/Private/PacketRuleTerminateTest.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | 3 | #include "Misc/AutomationTest.h" 4 | #include "PacketRule/PacketRuleFactory.h" 5 | #include "PacketRule/PacketRuleTerminate.h" 6 | 7 | IMPLEMENT_SIMPLE_AUTOMATION_TEST(FPacketRuleTerminateTest_MakeSendPacket, "ObjectDeliverer.PacketRuleTests.PacketRuleTerminateTest.MakeSendPacket", EAutomationTestFlags_ApplicationContextMask | EAutomationTestFlags::SmokeFilter) 8 | 9 | bool FPacketRuleTerminateTest_MakeSendPacket::RunTest(const FString& Parameters) 10 | { 11 | // terminater : "\r\n" 12 | { 13 | auto packetRule = UPacketRuleFactory::CreatePacketRuleTerminate({ TEXT('\r'), TEXT('\n') }); 14 | 15 | packetRule->MadeSendBuffer.BindLambda([this](const TArray& Buffer) 16 | { 17 | TestEqual(TEXT("MakeSendPacket check size"), Buffer.Num(), 10); 18 | 19 | for (int i = 0; i < 8; ++i) 20 | { 21 | TestEqual(TEXT("MakeSendPacket check buffer value"), Buffer[i], i); 22 | } 23 | 24 | TestEqual(TEXT("MakeSendPacket check buffer value"), Buffer[8], TEXT('\r')); 25 | TestEqual(TEXT("MakeSendPacket check buffer value"), Buffer[9], TEXT('\n')); 26 | 27 | }); 28 | 29 | packetRule->Initialize(); 30 | 31 | TArray buffer; 32 | buffer.SetNum(8); 33 | for (int i = 0; i < buffer.Num(); ++i) 34 | { 35 | buffer[i] = i; 36 | } 37 | 38 | packetRule->MakeSendPacket(buffer); 39 | } 40 | 41 | // terminater : 0xff 42 | { 43 | auto packetRule = UPacketRuleFactory::CreatePacketRuleTerminate({ 0xFF }); 44 | 45 | packetRule->MadeSendBuffer.BindLambda([this](const TArray& Buffer) 46 | { 47 | TestEqual(TEXT("MakeSendPacket check size"), Buffer.Num(), 9); 48 | 49 | for (int i = 0; i < 8; ++i) 50 | { 51 | TestEqual(TEXT("MakeSendPacket check buffer value"), Buffer[i], i); 52 | } 53 | 54 | TestEqual(TEXT("MakeSendPacket check buffer value"), Buffer[8], 0xFF); 55 | 56 | }); 57 | 58 | packetRule->Initialize(); 59 | 60 | TArray buffer; 61 | buffer.SetNum(8); 62 | for (int i = 0; i < buffer.Num(); ++i) 63 | { 64 | buffer[i] = i; 65 | } 66 | 67 | packetRule->MakeSendPacket(buffer); 68 | } 69 | 70 | return true; 71 | } 72 | 73 | IMPLEMENT_SIMPLE_AUTOMATION_TEST(FPacketRuleTerminateTest_NotifyReceiveData, "ObjectDeliverer.PacketRuleTests.PacketRuleTerminateTest.NotifyReceiveData", EAutomationTestFlags_ApplicationContextMask | EAutomationTestFlags::SmokeFilter) 74 | 75 | bool FPacketRuleTerminateTest_NotifyReceiveData::RunTest(const FString& Parameters) 76 | { 77 | // packet num is 1 78 | { 79 | auto packetRule = UPacketRuleFactory::CreatePacketRuleTerminate({ TEXT('\r'), TEXT('\n') }); 80 | 81 | bool isReceived = false; 82 | 83 | packetRule->MadeReceiveBuffer.BindLambda([this, &isReceived](const TArray& Buffer) 84 | { 85 | isReceived = true; 86 | 87 | TestEqual(TEXT("NotifyReceiveData check size"), Buffer.Num(), 8); 88 | 89 | for (int i = 0; i < Buffer.Num(); ++i) 90 | { 91 | TestEqual(TEXT("NotifyReceiveData check buffer value"), Buffer[i], i); 92 | } 93 | 94 | }); 95 | 96 | packetRule->Initialize(); 97 | 98 | TArray buffer; 99 | buffer.SetNum(10); 100 | for (int i = 0; i < 8; ++i) 101 | { 102 | buffer[i] = i; 103 | } 104 | 105 | buffer[8] = TEXT('\r'); 106 | buffer[9] = TEXT('\n'); 107 | 108 | packetRule->NotifyReceiveData(buffer); 109 | 110 | TestEqual(TEXT("NotifyReceiveData check receuved"), isReceived, true); 111 | } 112 | 113 | // packet num is 2 114 | { 115 | auto packetRule = UPacketRuleFactory::CreatePacketRuleTerminate({ TEXT('\r'), TEXT('\n') }); 116 | 117 | int32 receivedCounter = 0; 118 | 119 | packetRule->MadeReceiveBuffer.BindLambda([this, &receivedCounter](const TArray& Buffer) 120 | { 121 | receivedCounter++; 122 | 123 | TestEqual(TEXT("NotifyReceiveData check size"), Buffer.Num(), 8); 124 | 125 | for (int i = 0; i < Buffer.Num(); ++i) 126 | { 127 | TestEqual(TEXT("NotifyReceiveData check buffer value"), Buffer[i], i); 128 | } 129 | 130 | }); 131 | 132 | packetRule->Initialize(); 133 | 134 | TArray buffer; 135 | buffer.SetNum(20); 136 | for (int i = 0; i < 8; ++i) 137 | { 138 | buffer[i] = i; 139 | } 140 | 141 | buffer[8] = TEXT('\r'); 142 | buffer[9] = TEXT('\n'); 143 | 144 | for (int i = 10; i < 18; ++i) 145 | { 146 | buffer[i] = i - 10; 147 | } 148 | 149 | buffer[18] = TEXT('\r'); 150 | buffer[19] = TEXT('\n'); 151 | 152 | packetRule->NotifyReceiveData(buffer); 153 | 154 | TestEqual(TEXT("NotifyReceiveData check received counter"), receivedCounter, 2); 155 | } 156 | 157 | // When the packet is split 158 | { 159 | auto packetRule = UPacketRuleFactory::CreatePacketRuleTerminate({ TEXT('\r'), TEXT('\n') }); 160 | 161 | int32 receivedCounter = 0; 162 | 163 | packetRule->MadeReceiveBuffer.BindLambda([this, &receivedCounter](const TArray& Buffer) 164 | { 165 | receivedCounter++; 166 | 167 | TestEqual(TEXT("NotifyReceiveData check size"), Buffer.Num(), 8); 168 | 169 | for (int i = 0; i < Buffer.Num(); ++i) 170 | { 171 | TestEqual(TEXT("NotifyReceiveData check buffer value"), Buffer[i], i); 172 | } 173 | 174 | }); 175 | 176 | packetRule->Initialize(); 177 | 178 | TArray buffer; 179 | buffer.SetNum(8); 180 | for (int i = 0; i < 8; ++i) 181 | { 182 | buffer[i] = i; 183 | } 184 | 185 | packetRule->NotifyReceiveData(buffer); 186 | 187 | TestEqual(TEXT("NotifyReceiveData check received counter"), receivedCounter, 0); 188 | 189 | buffer.SetNum(12); 190 | 191 | buffer[0] = TEXT('\r'); 192 | buffer[1] = TEXT('\n'); 193 | 194 | for (int i = 2; i < 10; ++i) 195 | { 196 | buffer[i] = i - 2; 197 | } 198 | 199 | buffer[10] = TEXT('\r'); 200 | buffer[11] = TEXT('\n'); 201 | 202 | packetRule->NotifyReceiveData(buffer); 203 | 204 | TestEqual(TEXT("NotifyReceiveData check received counter"), receivedCounter, 2); 205 | } 206 | 207 | // terminater : 0xFF 208 | { 209 | auto packetRule = UPacketRuleFactory::CreatePacketRuleTerminate({ 0xFF }); 210 | 211 | bool isReceived = false; 212 | 213 | packetRule->MadeReceiveBuffer.BindLambda([this, &isReceived](const TArray& Buffer) 214 | { 215 | isReceived = true; 216 | 217 | TestEqual(TEXT("NotifyReceiveData check size"), Buffer.Num(), 8); 218 | 219 | for (int i = 0; i < Buffer.Num(); ++i) 220 | { 221 | TestEqual(TEXT("NotifyReceiveData check buffer value"), Buffer[i], i); 222 | } 223 | 224 | }); 225 | 226 | packetRule->Initialize(); 227 | 228 | TArray buffer; 229 | buffer.SetNum(9); 230 | for (int i = 0; i < 8; ++i) 231 | { 232 | buffer[i] = i; 233 | } 234 | 235 | buffer[8] = 0xFF; 236 | 237 | packetRule->NotifyReceiveData(buffer); 238 | 239 | TestEqual(TEXT("NotifyReceiveData check receuved"), isReceived, true); 240 | } 241 | 242 | return true; 243 | } -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDelivererTests/Private/ProtocolLogWriterReaderTest.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "CoreMinimal.h" 3 | #include "Misc/AutomationTest.h" 4 | #include "Tests/AutomationCommon.h" 5 | #include "Protocol/ProtocolLogReader.h" 6 | #include "Protocol/ProtocolLogWriter.h" 7 | #include "PacketRule/PacketRuleSizeBody.h" 8 | #include "PacketRule/PacketRuleFactory.h" 9 | #include "Protocol/ProtocolFactory.h" 10 | #include "ObjectDelivererManager.h" 11 | #include "DeliveryBox/Utf8StringDeliveryBox.h" 12 | #include "ObjectDelivererManagerTestHelper.h" 13 | 14 | #if WITH_DEV_AUTOMATION_TESTS 15 | 16 | IMPLEMENT_SIMPLE_AUTOMATION_TEST(FProtocolLogWrierReaderTest, "ObjectDeliverer.ProtocolTest.ProtocolLogWrierReaderTest1", EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter) 17 | 18 | bool FProtocolLogWrierReaderTest::RunTest(const FString& Parameters) 19 | { 20 | auto deliveryBox = NewObject(); 21 | auto ObjectDelivererWriter = NewObject(); 22 | ObjectDelivererWriter->Start(UProtocolFactory::CreateProtocolLogWriter("log.bin", false), UPacketRuleFactory::CreatePacketRuleSizeBody(), deliveryBox); 23 | 24 | 25 | auto deliveryBoxReceive = NewObject(); 26 | auto serverHelper = NewObject(); 27 | auto ObjectDelivererReader = NewObject(); 28 | deliveryBoxReceive->Received.AddDynamic(serverHelper, &UObjectDelivererManagerTestHelper::OnReceiveString); 29 | 30 | ADD_LATENT_AUTOMATION_COMMAND(FFunctionLatentCommand([=]() 31 | { 32 | deliveryBox->Send("AAA"); 33 | return true; 34 | })); 35 | 36 | ADD_LATENT_AUTOMATION_COMMAND(FEngineWaitLatentCommand(0.3f)); 37 | 38 | ADD_LATENT_AUTOMATION_COMMAND(FFunctionLatentCommand([=]() 39 | { 40 | deliveryBox->Send("BBB"); 41 | return true; 42 | })); 43 | 44 | ADD_LATENT_AUTOMATION_COMMAND(FEngineWaitLatentCommand(0.7f)); 45 | 46 | ADD_LATENT_AUTOMATION_COMMAND(FFunctionLatentCommand([=]() 47 | { 48 | deliveryBox->Send("CCC"); 49 | ObjectDelivererWriter->Close(); 50 | 51 | ObjectDelivererReader->Start(UProtocolFactory::CreateProtocolLogReader("log.bin", false, true), UPacketRuleFactory::CreatePacketRuleSizeBody(), deliveryBoxReceive); 52 | 53 | return true; 54 | })); 55 | 56 | ADD_LATENT_AUTOMATION_COMMAND(FEngineWaitLatentCommand(1.5f)); 57 | 58 | ADD_LATENT_AUTOMATION_COMMAND(FFunctionLatentCommand([=, this]() 59 | { 60 | ObjectDelivererReader->Close(); 61 | 62 | TestEqual("check received count", serverHelper->ReceiveStrings.Num(), 3); 63 | 64 | if (serverHelper->ReceiveStrings.Num() == 3) 65 | { 66 | TestEqual("check received data", serverHelper->ReceiveStrings[0], TEXT("AAA")); 67 | TestEqual("check received data", serverHelper->ReceiveStrings[1], TEXT("BBB")); 68 | TestEqual("check received data", serverHelper->ReceiveStrings[2], TEXT("CCC")); 69 | } 70 | 71 | 72 | return true; 73 | })); 74 | 75 | return true; 76 | } 77 | #endif -------------------------------------------------------------------------------- /Plugins/ObjectDeliverer/Source/ObjectDelivererTests/Public/ObjectDelivererTests.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "Modules/ModuleManager.h" 6 | 7 | class FObjectDelivererTestsModule : public IModuleInterface 8 | { 9 | public: 10 | virtual void StartupModule() override; 11 | virtual void ShutdownModule() override; 12 | }; 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ObjectDeliverer 2 | 3 | ObjectDeliverer is a flexible data communication library for Unreal Engine. It's available for both C++ and Blueprint. 4 | 5 | ## Table of Contents 6 | - [Overview](#overview) 7 | - [Supported UE Versions](#supported-ue-versions) 8 | - [How to Obtain](#how-to-obtain) 9 | - [Installation Guide](#installation-guide) 10 | - [Quick Start](#quick-start) 11 | - [Feature Details](#feature-details) 12 | - [Communication Protocols](#communication-protocols) 13 | - [Data Division Rules](#data-division-rules) 14 | - [Serialization Methods](#serialization-methods) 15 | - [Usage Examples](#usage-examples) 16 | - [C++ Example](#c-example) 17 | - [Blueprint Example](#blueprint-example) 18 | - [Detailed Documentation](#detailed-documentation) 19 | - [License](#license) 20 | - [Contributing](#contributing) 21 | 22 | ## Overview 23 | 24 | ObjectDeliverer excels as a data communication library with these key advantages: 25 | 26 | - **Easy Protocol Switching** - Seamlessly switch between TCP/IP, UDP, shared memory, and other protocols 27 | - **Flexible Data Division Rules** - Support for fixed size, header+body, terminal symbol, and more 28 | - **Various Serialization Methods** - Handle byte arrays, UTF-8 strings, JSON objects, and more 29 | - **C++ and Blueprint Support** - Use your preferred development method 30 | 31 | It simplifies network communication logic, allowing you to focus on application development. 32 | 33 | ## Supported UE Versions 34 | 35 | > **Note**: This plugin is updated and maintained only for the latest 3 versions of Unreal Engine. 36 | 37 | | UE Version | Support Status | Branch Name | 38 | |------------|---------------|------------| 39 | | UE 5.6 | ✅ Supported | UE5.6 | 40 | | UE 5.5 | ✅ Supported | UE5.5 | 41 | | UE 5.4 | ✅ Supported | UE5.4 | 42 | | UE 5.3 | ❌ End of Support (v1.6.1+) | UE5.3 | 43 | | Others | 🔄 Check docs | master | 44 | 45 | ### Branch Structure 46 | 47 | ``` 48 | master (latest UE version) ──┐ 49 | ├─ UE5.5 (UE5.5 specific) 50 | ├─ UE5.4 (UE5.4 specific) 51 | └─ UE5.3 (UE5.3 specific) 52 | ``` 53 | 54 | - **master** branch: Always compatible with the latest Unreal Engine version 55 | - **UEX.X** branches: Stable versions for specific UE versions 56 | - **Note**: Older version branches may not include the latest features 57 | 58 | ## How to Obtain 59 | 60 | ### UE Marketplace 61 | 62 | [https://www.fab.com/ja/listings/b6ffd7d7-80da-483f-a7fa-09cb46b72651](https://www.fab.com/ja/listings/b6ffd7d7-80da-483f-a7fa-09cb46b72651) 63 | 64 | If you acquire this plugin through the Marketplace, you will be charged the specified fee. 65 | 66 | ### GitHub 67 | 68 | You can clone this repository and use it for free. 69 | 70 | ## Installation Guide 71 | 72 | ### From Marketplace 73 | 1. Purchase and download the plugin from the Marketplace 74 | 2. Add it to your project from the "Library" section in the UE Launcher 75 | 3. Open your project and enable ObjectDeliverer from "Edit" → "Plugins" 76 | 77 | ### From GitHub 78 | 1. Clone this repository: `git clone https://github.com/ayumax/ObjectDeliverer.git` 79 | 2. Copy the `Plugins` directory from the cloned repository to your project folder 80 | 3. Build the plugin (requires C++ build environment) 81 | 4. Open your project and enable ObjectDeliverer from "Edit" → "Plugins" 82 | 83 | ### Compatibility Check 84 | Choose the appropriate branch based on your UE version: 85 | ```bash 86 | # Example for UE5.4 87 | git checkout UE5.4 88 | ``` 89 | 90 | ## Quick Start 91 | 92 | ### Basic Usage Steps 93 | 1. Create an ObjectDelivererManager 94 | 2. Set up event handlers (connect, disconnect, data receive) 95 | 3. Configure communication protocol and packet rule, then start 96 | 97 | ![Setup Example](https://user-images.githubusercontent.com/8191970/52522481-48075700-2cc9-11e9-92a0-067992f56042.png) 98 | 99 | ## Feature Details 100 | 101 | ### Communication Protocols 102 | The following protocols are available by default (you can also add your own): 103 | 104 | - **TCP/IP Server** - Connects to multiple clients 105 | - **TCP/IP Client** - Connects to a server 106 | - **UDP (Sender)** - Sends UDP data 107 | - **UDP (Receiver)** - Receives UDP data 108 | - **Shared Memory** - Process-to-process communication in Windows 109 | - **File Writer** - Saves data to a file 110 | - **File Reader** - Reads data from a file 111 | 112 | ### Data Division Rules 113 | Rules for appropriate packet division and reconstruction of received data: 114 | 115 | #### FixedSize 116 | Example) When using a fixed size of 1024 bytes 117 | ![Fixed Length](https://user-images.githubusercontent.com/8191970/56475737-7d999f00-64c7-11e9-8e9e-0182f1af8156.png) 118 | 119 | #### Header(BodySize) + Body 120 | Example) When the size area is 4 bytes 121 | ![Size and Body](https://user-images.githubusercontent.com/8191970/56475796-6e672100-64c8-11e9-8cf0-6524f2899be0.png) 122 | 123 | #### Split by terminal symbol 124 | Example) When 0x00 is the end 125 | ![Terminate](https://user-images.githubusercontent.com/8191970/56475740-82f6e980-64c7-11e9-91a6-05d77cfdbd60.png) 126 | 127 | #### No division 128 | Uses the received buffer as-is without any packet splitting or combining operations. 129 | 130 | ### Serialization Methods 131 | - **Byte Array** - Raw binary data 132 | - **UTF-8 String** - Text data 133 | - **Object (JSON)** - Structured data 134 | 135 | ## Usage Examples 136 | 137 | ### C++ Example 138 | 139 | ```cpp 140 | void UMyClass::Start() 141 | { 142 | auto deliverer = UObjectDelivererManager::CreateObjectDelivererManager(); 143 | 144 | // Set up event handlers 145 | deliverer->Connected.AddDynamic(this, &UMyClass::OnConnect); 146 | deliverer->Disconnected.AddDynamic(this, &UMyClass::OnDisConnect); 147 | deliverer->ReceiveData.AddDynamic(this, &UMyClass::OnReceive); 148 | 149 | // Start communication 150 | // Protocol: TCP/IP Server 151 | // Data division rule: Header(Size) + Body 152 | // Serialization method: Byte array 153 | deliverer->Start(UProtocolFactory::CreateProtocolTcpIpServer(9099), 154 | UPacketRuleFactory::CreatePacketRuleSizeBody()); 155 | } 156 | 157 | void UMyClass::OnConnect(UObjectDelivererProtocol* ClientSocket) 158 | { 159 | // Send data 160 | TArray buffer; 161 | deliverer->Send(buffer); 162 | } 163 | 164 | void UMyClass::OnDisConnect(UObjectDelivererProtocol* ClientSocket) 165 | { 166 | // Handle disconnection 167 | UE_LOG(LogTemp, Log, TEXT("closed")); 168 | } 169 | 170 | void UMyClass::OnReceive(UObjectDelivererProtocol* ClientSocket, const TArray& Buffer) 171 | { 172 | // Handle received data 173 | } 174 | ``` 175 | 176 | ### Blueprint Example 177 | 178 | ![Blueprint Example](https://user-images.githubusercontent.com/8191970/52522481-48075700-2cc9-11e9-92a0-067992f56042.png) 179 | 180 | ## Detailed Documentation 181 | 182 | For detailed usage of each feature, please refer to the Wiki: 183 | 184 | [ObjectDeliverer Wiki](https://github.com/ayumax/ObjectDeliverer/wiki) 185 | 186 | ## License 187 | 188 | - This plugin is provided under the MIT License 189 | - However, if you download and use it from the Epic Games Marketplace, the Epic Games license terms will apply 190 | 191 | ## Contributing 192 | 193 | We welcome contributions from everyone who wants to improve ObjectDeliverer! 194 | 195 | ### Contribution Process 196 | 197 | 1. Fork the repository 198 | 2. Create your feature branch from the `master` branch 199 | 3. Make your changes 200 | 4. Submit a pull request targeting the `master` branch 201 | 202 | ### Contribution Guidelines 203 | 204 | - **All pull requests** should be directed to the `master` branch 205 | - For major changes, please open an issue first to discuss what you would like to change(English or Japanese) 206 | - Follow the code style of the existing codebase 207 | - Add or update tests when possible 208 | 209 | ### UE Version Support 210 | 211 | When adding new features, please try to make them work across multiple UE versions when possible. If a feature is specific to a particular UE version, please note this clearly. 212 | 213 | We appreciate all contributions - bug fixes, feature additions, documentation improvements, suggestions, and more! 214 | -------------------------------------------------------------------------------- /Source/ObjectDelivererTest.Target.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | using System.Collections.Generic; 5 | 6 | public class ObjectDelivererTestTarget : TargetRules 7 | { 8 | public ObjectDelivererTestTarget(TargetInfo Target) : base(Target) 9 | { 10 | Type = TargetType.Game; 11 | DefaultBuildSettings = BuildSettingsVersion.Latest; 12 | IncludeOrderVersion = EngineIncludeOrderVersion.Latest; 13 | ExtraModuleNames.Add("ObjectDelivererTest"); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Source/ObjectDelivererTest/MyClass.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | 3 | #include "MyClass.h" 4 | #include "DeliveryBox/Utf8StringDeliveryBox.h" 5 | #include "DeliveryBox/ObjectDeliveryBoxUsingJson.h" 6 | #include "ObjectDelivererManager.h" 7 | #include "Protocol/ProtocolTcpIpClient.h" 8 | #include "Protocol/ProtocolTcpIpServer.h" 9 | #include "PacketRule/PacketRuleSizeBody.h" 10 | #include "Protocol/ProtocolUdpSocketSender.h" 11 | #include "Protocol/ProtocolUdpSocketReceiver.h" 12 | #include "PacketRule/PacketRuleFixedLength.h" 13 | #include "PacketRule/PacketRuleNodivision.h" 14 | #include "PacketRule/PacketRuleTerminate.h" 15 | 16 | USampleObject::USampleObject() 17 | { 18 | } 19 | 20 | USampleObject::~USampleObject() 21 | { 22 | } 23 | 24 | UMyClass::UMyClass() 25 | { 26 | } 27 | 28 | UMyClass::~UMyClass() 29 | { 30 | } 31 | 32 | void UMyClass::Start() 33 | { 34 | auto deliverer = NewObject(); 35 | 36 | // bind connected event 37 | deliverer->Connected.AddDynamic(this, &UMyClass::OnConnect); 38 | // bind disconnected event 39 | deliverer->Disconnected.AddDynamic(this, &UMyClass::OnDisConnect); 40 | // bind receive event 41 | deliverer->ReceiveData.AddDynamic(this, &UMyClass::OnReceive); 42 | 43 | // start deliverer 44 | // + protocol : TCP/IP Server 45 | // + Data division rule : Header(BodySize) + Body 46 | // + Serialization method : Byte Array 47 | deliverer->Start(UProtocolFactory::CreateProtocolTcpIpServer(9099), UPacketRuleFactory::CreatePacketRuleSizeBody()); 48 | 49 | 50 | // Change of communication protocol 51 | // TCP/IP Server 52 | deliverer->Start(UProtocolFactory::CreateProtocolTcpIpServer(9099), UPacketRuleFactory::CreatePacketRuleSizeBody()); 53 | 54 | // TCP/IP Client 55 | deliverer->Start(UProtocolFactory::CreateProtocolTcpIpClient("localhost", 9099, true), UPacketRuleFactory::CreatePacketRuleSizeBody()); 56 | 57 | // UDP Sender 58 | deliverer->Start(UProtocolFactory::CreateProtocolUdpSocketSender("localhost", 9099), UPacketRuleFactory::CreatePacketRuleSizeBody()); 59 | 60 | // UDP Receiver 61 | deliverer->Start(UProtocolFactory::CreateProtocolUdpSocketReceiver(9099), UPacketRuleFactory::CreatePacketRuleSizeBody()); 62 | 63 | // FixedSize 64 | deliverer->Start(UProtocolFactory::CreateProtocolUdpSocketReceiver(9099), UPacketRuleFactory::CreatePacketRuleFixedLength(1024)); 65 | 66 | // Header(BodySize) + Body 67 | deliverer->Start(UProtocolFactory::CreateProtocolUdpSocketReceiver(9099), UPacketRuleFactory::CreatePacketRuleSizeBody(4, ECNBufferEndian::Big)); 68 | 69 | // Split by terminal symbol 70 | deliverer->Start(UProtocolFactory::CreateProtocolUdpSocketReceiver(9099), UPacketRuleFactory::CreatePacketRuleTerminate({ TEXT('\r'), TEXT('\n') })); 71 | 72 | // Nodivision 73 | deliverer->Start(UProtocolFactory::CreateProtocolUdpSocketReceiver(9099), UPacketRuleFactory::CreatePacketRuleNodivision()); 74 | 75 | 76 | // Byte array 77 | deliverer->Start(UProtocolFactory::CreateProtocolTcpIpServer(9099), UPacketRuleFactory::CreatePacketRuleSizeBody()); 78 | 79 | // UTF-8 string 80 | auto deliverybox = NewObject(); 81 | deliverybox->Received.AddDynamic(this, &UMyClass::OnReceiveString); 82 | deliverer->Start(UProtocolFactory::CreateProtocolTcpIpServer(9099), UPacketRuleFactory::CreatePacketRuleSizeBody(), deliverybox); 83 | 84 | deliverybox->Send(TEXT("ABCDEFG")); 85 | 86 | 87 | // Object(Json) 88 | auto deliverybox2 = NewObject(); 89 | deliverybox2->Initialize(USampleObject::StaticClass()); 90 | deliverybox2->Received.AddDynamic(this, &UMyClass::OnReceiveObject); 91 | deliverer->Start(UProtocolFactory::CreateProtocolTcpIpServer(9099), UPacketRuleFactory::CreatePacketRuleSizeBody(), deliverybox); 92 | 93 | auto obj = NewObject(); 94 | FString sendJson; 95 | deliverybox2->Send(obj, sendJson); 96 | } 97 | 98 | void UMyClass::OnConnect(const UObjectDelivererProtocol* ClientSocket) 99 | { 100 | // send data 101 | TArray buffer; 102 | //deliverer->Send(buffer); 103 | } 104 | 105 | void UMyClass::OnDisConnect(const UObjectDelivererProtocol* ClientSocket) 106 | { 107 | // closed 108 | UE_LOG(LogTemp, Log, TEXT("closed")); 109 | } 110 | 111 | void UMyClass::OnReceive(const UObjectDelivererProtocol* ClientSocket, const TArray& Buffer) 112 | { 113 | // received data buffer 114 | } 115 | 116 | void UMyClass::OnReceiveString(const FString& ReceivedString, const UObjectDelivererProtocol* FromObject) 117 | { 118 | // received data string 119 | } 120 | 121 | void UMyClass::OnReceiveObject(UObject* ReceivedObject, const FString& ReceivedString, const UObjectDelivererProtocol* FromObject) 122 | { 123 | // received data object 124 | USampleObject* obj = Cast(ReceivedObject); 125 | } -------------------------------------------------------------------------------- /Source/ObjectDelivererTest/MyClass.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "MyClass.generated.h" 7 | 8 | /** 9 | * 10 | */ 11 | UCLASS() 12 | class OBJECTDELIVERERTEST_API USampleObject : public UObject 13 | { 14 | GENERATED_BODY() 15 | 16 | public: 17 | USampleObject(); 18 | ~USampleObject(); 19 | 20 | 21 | }; 22 | 23 | UCLASS() 24 | class OBJECTDELIVERERTEST_API UMyClass : public UObject 25 | { 26 | GENERATED_BODY() 27 | 28 | public: 29 | UMyClass(); 30 | ~UMyClass(); 31 | 32 | void Start(); 33 | 34 | UFUNCTION() 35 | void OnConnect(const UObjectDelivererProtocol* ClientSocket); 36 | UFUNCTION() 37 | void OnDisConnect(const UObjectDelivererProtocol* ClientSocket); 38 | UFUNCTION() 39 | void OnReceive(const UObjectDelivererProtocol* ClientSocket, const TArray& Buffer); 40 | UFUNCTION() 41 | void OnReceiveString(const FString& ReceivedString, const UObjectDelivererProtocol* FromObject); 42 | UFUNCTION() 43 | void OnReceiveObject(UObject* ReceivedObject, const FString& ReceivedString, const UObjectDelivererProtocol* FromObject); 44 | }; 45 | -------------------------------------------------------------------------------- /Source/ObjectDelivererTest/ObjectDelivererTest.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | 5 | public class ObjectDelivererTest : ModuleRules 6 | { 7 | public ObjectDelivererTest(ReadOnlyTargetRules Target) : base(Target) 8 | { 9 | PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; 10 | 11 | PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "ObjectDeliverer" }); 12 | 13 | 14 | PrivateDependencyModuleNames.AddRange(new string[] { }); 15 | 16 | // Uncomment if you are using Slate UI 17 | // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" }); 18 | 19 | // Uncomment if you are using online features 20 | // PrivateDependencyModuleNames.Add("OnlineSubsystem"); 21 | 22 | // To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Source/ObjectDelivererTest/ObjectDelivererTest.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | 3 | #include "ObjectDelivererTest.h" 4 | #include "Modules/ModuleManager.h" 5 | 6 | IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, ObjectDelivererTest, "ObjectDelivererTest" ); 7 | -------------------------------------------------------------------------------- /Source/ObjectDelivererTest/ObjectDelivererTest.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | 7 | -------------------------------------------------------------------------------- /Source/ObjectDelivererTest/TextureUtil.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | #include "TextureUtil.h" 3 | #include "Engine/Texture2D.h" 4 | #include "Engine/TextureRenderTarget2D.h" 5 | #include "UnrealClient.h" 6 | 7 | UTextureUtil::UTextureUtil() 8 | { 9 | } 10 | 11 | UTextureUtil::~UTextureUtil() 12 | { 13 | } 14 | 15 | UTexture2D* UTextureUtil::CreateTexture(int32 Width, int32 Height) 16 | { 17 | auto Texture = UTexture2D::CreateTransient(Width, Height, PF_B8G8R8A8); 18 | Texture->UpdateResource(); 19 | 20 | return Texture; 21 | } 22 | 23 | void UTextureUtil::UpdateTexture(UTexture2D* Texture, const TArray& PixelsBuffer) 24 | { 25 | auto Region = new FUpdateTextureRegion2D(0, 0, 0, 0, Texture->GetSizeX(), Texture->GetSizeY()); 26 | Texture->UpdateTextureRegions(0, 1, Region, 4 * Texture->GetSizeX(), 4, (uint8*)PixelsBuffer.GetData()); 27 | } 28 | 29 | void UTextureUtil::GetPixelBufferFromRenderTarget(UTextureRenderTarget2D* TextureRenderTarget, TArray& Buffer) 30 | { 31 | TArray SurfData; 32 | FRenderTarget* RenderTarget = TextureRenderTarget->GameThread_GetRenderTargetResource(); 33 | RenderTarget->ReadPixels(SurfData); 34 | 35 | FMemory::Memcpy(Buffer.GetData(), SurfData.GetData(), Buffer.Num()); 36 | } 37 | 38 | -------------------------------------------------------------------------------- /Source/ObjectDelivererTest/TextureUtil.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "UObject/ObjectMacros.h" 7 | #include "TextureUtil.generated.h" 8 | 9 | /** 10 | * 11 | */ 12 | UCLASS() 13 | class OBJECTDELIVERERTEST_API UTextureUtil : public UObject 14 | { 15 | GENERATED_BODY() 16 | 17 | public: 18 | UTextureUtil(); 19 | ~UTextureUtil(); 20 | 21 | UFUNCTION(BlueprintPure, Category = "ObjectDeliverer Test") 22 | static UTexture2D* CreateTexture(int32 Width, int32 Height); 23 | 24 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer Test") 25 | static void UpdateTexture(UTexture2D* Texture, const TArray& PixelsBuffer); 26 | 27 | UFUNCTION(BlueprintCallable, Category = "ObjectDeliverer Test") 28 | static void GetPixelBufferFromRenderTarget(class UTextureRenderTarget2D* TextureRenderTarget, UPARAM(ref)TArray& Buffer); 29 | 30 | }; 31 | -------------------------------------------------------------------------------- /Source/ObjectDelivererTestEditor.Target.cs: -------------------------------------------------------------------------------- 1 | // Copyright 2019 ayumax. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | using System.Collections.Generic; 5 | 6 | public class ObjectDelivererTestEditorTarget : TargetRules 7 | { 8 | public ObjectDelivererTestEditorTarget(TargetInfo Target) : base(Target) 9 | { 10 | Type = TargetType.Editor; 11 | DefaultBuildSettings = BuildSettingsVersion.V5; 12 | IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_5; 13 | CppStandard = CppStandardVersion.Cpp20; 14 | ExtraModuleNames.Add("ObjectDelivererTest"); 15 | } 16 | } 17 | --------------------------------------------------------------------------------